-
Notifications
You must be signed in to change notification settings - Fork 196
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
[FUSE] Provide intellisense for @inject directives #10771
Conversation
@@ -1,42 +1,42 @@ | |||
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "844eb91b909a14b78feddd5e6866563b5a75e021" | |||
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "c83d1c26cf039a87fc6aedc860fd9d28a34d96dfb2e405e6af3918602ca27755" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These files existed, because apparently the test did at one point, too, but they were super out of date, so I would just review these as newly added.
1d7e136
to
025684c
Compare
@dotnet/razor-compiler for review please :) |
…id c# identifier so we get intellisense
@@ -650,10 +646,13 @@ private string GetContent(HtmlContentIntermediateNode node) | |||
// Internal for testing | |||
internal static string GetDeterministicId(CodeRenderingContext context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be moved somewhere else? It's not used for tag helpers only anymore.
|
||
public void Configure(RazorCodeGenerationOptionsBuilder options) | ||
{ | ||
options.SuppressUniqueIds = "test"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider making this something more recognizable like "TestSuppressedUniqueId"
public void SupportsIncompleteInjectDirectives() | ||
{ | ||
var component = CompileToComponent(""" | ||
@inject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me how this resolves the issue. The issue talks about IntelliSense on the type part and when user writes @inject
and space we still don't generate anything, i.e., nothing has really changed for this sceario, how could the issue be fixed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also confused here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's always been true. You don't get IntelliSense until you type the first character today. Once you type the first character, you get it, but in fuse you never get it until you start typing the name:
Not-fuse:
Fuse (broken):
Fuse (fixed):
Note, this is same behavior you get today in C#, if you're e.g. writing a new property:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In C#, can't you manually bring up completion though? What's the equivalent behavior in razor currently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, so if you invoke IntelliSense in either the C# or non-fuse razor case, you just get an empty IntelliSense box.
In the PR right now you get nothing, because we have nothing emitted. In design time that works by mapping to just a totally empty space. We can probably do that here too to get exactly the same behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, actually this is proving much harder than expected. Not necessarily in generating the code but trying to figure out what exactly we should generate to make IntelliSense happy. I'll chat with @davidwengier next week and try and figure it out.
Should we just take this PR as-is as it makes most of the scenario better, and file a follow up issue to fix the empty space part?
Lol, wrote this then almost immediately figured it out. Update incoming.
defaultValue: true); | ||
var memberName = MemberName ?? "Member_" + DefaultTagHelperTargetExtension.GetDeterministicId(context); | ||
|
||
if (!context.Options.DesignTime || !IsMalformed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will it mess up the existing design-time experience if we just unconditionally write this property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it shouldn't, I've just been avoiding making any changes to the design time where possible.
public void SupportsIncompleteInjectDirectives() | ||
{ | ||
var component = CompileToComponent(""" | ||
@inject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also confused here.
@@ -36,6 +36,14 @@ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Incomplete | |||
#line default | |||
#line hidden | |||
Member_test { get; private set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this test
and not __UniqueIdSuppressedForTesting__
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wen have two places where we set it. A whole bunch of other places were using the other one, so it made the diff huge. I'll submit a follow up PR to make them consistent.
With fuse enabled, it was noticed that typing
@inject
was not providing IntelliSense on the type.The directive is
@inject <type> <name>
with type and name being two differentDirectiveToken
s. Due to this structure, it's effectively malformed until you begin typing the name. Previously in runtime we don't emit anything for a malformed inject directive. Until you start typing the name, there is no C# to actually map back to the razor document and provide IntelliSense with. Design time works around this by emitting the two tokens as separate design time only elements, so there is always some C# even when the directive is incomplete.This PR handles malformed
@inject
directives, and effectively generates an 'error token' that means we can emit valid C# code in these cases. When the user has not yet typed a member name, but started the type name, we begin emitting the full code with a member calledMember_<randomGeneratedId>
. We still provide an RZ diagnostic, so the code will not compile, but we can still emit something that is valid so we can provide IntelliSense to the user.I tried adding a malformed Component integration test, but design time is failing with missing pragmas. I tried the test on main, and it failed there too, so nothing to do with these changes. Will try and figure it out, but don't want to block on it.
Fixes https://devdiv.visualstudio.com/DevDiv/_queries/edit/2172170/