Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Support QuickInfo and GotoDefinition in LINQ query syntax #23394

Closed
33 tasks done
MaStr11 opened this issue Nov 27, 2017 · 0 comments
Closed
33 tasks done

Proposal: Support QuickInfo and GotoDefinition in LINQ query syntax #23394

MaStr11 opened this issue Nov 27, 2017 · 0 comments
Labels
Area-IDE Feature Specification Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented
Milestone

Comments

@MaStr11
Copy link
Contributor

MaStr11 commented Nov 27, 2017

Implementation started #23049 (This proposal is extracted from the discussion there. Remarks by @sharwell are incorporated)

Objective: Enhance the support for GotoDefinition and QuickInfo for LINQ query syntax by exposing the underlying transformations (QuickInfo and GotoDefinition are already working for a limited set of clauses. This proposal describes a coherent behavior for all clauses and transformations).

As a general guidance for the proposal I tried to stay close to the query expressions section of the C# spec. That means quick info should show the actual method mapping after all the transformations are completed.

Some general rules:

  • Quick info for parameter info is kept as is
  • Quick info for clauses that directly map to methods is enhanced
  • For those clauses that don't directly map to a method a hint is shown: "This clause isn't mapped to an method call due to optimizations." or if this is not possible no quick info is shown.
  • Goto definition is only supported for clauses that directly map to a method

These clauses map directly to method calls (bold are the clauses that show quick info).

ID Topic Example Quick info Goto definition
1 SelectMany from l1 in l
from l2 in l1
SelectMany method yes
2 Where from l1 in l
where true
Where method yes
3 Group by from l1 in l
group l1 by l.Item1 into g
Group method yes
4 Join from l1 in l
join n in numbers on l1 equals n into g
Join or GroupJoin method Yes
5 Select (only if mapped to a Select method) from l1 in l
select l1
Select method (see also below) Yes
6 Select for let from l1 in l
let v=true
select v
Select method (see also below) Yes
7 From variable types from double d in l1 Cast method Yes
8 Join variable types join T x in e on k1 equals k2 Cast method (The clauses join, on, equals are mapped to GroupJoin) Yes
9 From variable types for SelectMany from l1 in l
from T l2 in l1
Cast method (The from clause is mapped to SelectMany) Yes

Degenerated methods

e.g.

from i in l
where true
select i

Quick info for select shows "This clause isn't mapped to an method call due to optimizations." or nothing at all. Goto definition is not available.

select clause preceded by a join clause and other similar clauses

e.g.

from x1 in e1
join x2 in e2 on k1 equals k2
select v

Quick info for select shows "This clause isn't mapped to an method call due to optimizations." or nothing at all. Goto definition is not available.

orderby clause

Quick info and goto definition are available for parameters with an corresponding orderby, ascending or descending clause. If no ascending or descending clause is present then

  • if it is the first parameter the orderby clause is used for the mapping
  • otherwise the separating comma left to the parameter is used for the mapping
Clause This method call mapping is shown
orderby a mapping for parameter a
orderby a ascending mapping for parameter a
orderby a , b mapping for parameter a, mapping for parameter b to ThenBy is available on the comma
orderby a, b ascending mapping for parameter a and b
orderby a ascending, b ascending mapping for parameter a and b

let clause

Quick info reveals some transformation internals here (See also Transparent identifiers below). On the one hand side this is a bad thing because it unveils some intermediate types that are not really useful for the end user. But on the other side it illustrates that the let clause is nothing but a fancy select. (I do remember searching for a Let extension method on Enumerable when I used let for the first time.) Quick info would lighten up what is going on under the hood.

Explicit range variable types (see cases 7, 8 and 9)

Explicit range variable are translated into a call to Cast. The mapping to the Cast method interferes with other mappings. The following table shows how the Cast method is mapped to the in clause in overlapping cases:

Variation Mapping Bold mapping Italic mapping Remarks
Simple from from T i in l Cast method - The from clause is not mapped to another method and the Cast can be mapped
SelectMany from i1 in l
from T i2 in i1
Cast method SelectMany method The from clause is mapped to SelectMany and the in token is used to show the mapping to Cast
Join from i1 in l1
join T i2 in l2 on i1 equals i2
Cast method Join method All token are used to map to the Join method except in

Transparent identifiers

Transparent identifiers are leaking through. While the names of the transparent identifiers are not revealed they leave traces as there are anonymous types visible in quick info and so the end user gets a glimpse at the magic that is going on. In the (slightly altered) sample from the spec:

var lookup = new int[][] { };
var q = from i1 in lookup
        from i2 in i1
        orderby i2.ToString().Length
        select new { i1.Length, i2 };

The anonymous type a { int[] i1, int i2 } returned from SelectMany is visible in quick info on several occasions:

2017-11-21 16_16_35-

2017-11-21 16_17_15-

Implementation status

  • select (mappable)
  • select (unmappable)
  • let
  • where
  • orderby, ascending, descending
  • orderby mapping on comma
  • from, in (SelectMany)
  • group, by
  • join, in, on, equals
  • from in (Simple range variable)
  • Range variables with overlapping clauses (SelectMany and Join)

Test coverage C# Quick info

  • select (mappable)
  • select (unmappable)
  • let
  • where
  • orderby, ascending, descending
  • orderby mapping on comma
  • from, in (SelectMany)
  • group, by
  • join, in, on, equals
  • from in (Simple range variable)
  • Range variables with overlapping clauses (SelectMany and Join)

Test coverage C# Goto definition

  • select (mappable)
  • select (unmappable)
  • let
  • where
  • orderby, ascending, descending
  • orderby mapping on comma
  • from, in (SelectMany)
  • group, by
  • join, in, on, equals
  • from in (Simple range variable)
  • Range variables with overlapping clauses (SelectMany and Join)

Status VB:
No proposal, implementation and tests. Support for VB should be addressed in a follow up proposal.

@jcouv jcouv added the Area-IDE label Nov 27, 2017
@jinujoseph jinujoseph added the 4 - In Review A fix for the issue is submitted for review. label Jan 8, 2018
@jinujoseph jinujoseph added this to the Unknown milestone Jan 8, 2018
@sharwell sharwell added Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented and removed 4 - In Review A fix for the issue is submitted for review. labels Mar 21, 2018
@sharwell sharwell modified the milestones: Unknown, 15.7 Mar 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Feature Specification Resolution-Fixed The bug has been fixed and/or the requested behavior has been implemented
Projects
None yet
Development

No branches or pull requests

4 participants