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

Building in VS from aspnetcore repo, .razor files failing with CS0649 (Field is never assigned to) and RZ9991 (Attribute names could not be inferred) #31023

Closed
SteveSandersonMS opened this issue Mar 18, 2021 · 15 comments · Fixed by #32581
Assignees
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed
Milestone

Comments

@SteveSandersonMS
Copy link
Member

This seems to be a new issue since yesterday, as far as I can tell. Note that it works fine when building from the command line.

Repro: Open ComponentsNoDeps.slnf in Visual Studio and try to build BasicTestApp

2>------ Build started: Project: BasicTestApp, Configuration: Debug Any CPU ------
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\FormsTest\InputFileComponent.razor(8,170,8,182): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\FormsTest\InputFileComponent.razor(13,283,13,299): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\VirtualizationComponent.razor(3,87,3,95): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\GlobalizationBindCases.razor(15,640,15,660): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\GlobalizationBindCases.razor(27,1126,27,1153): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\GlobalizationBindCases.razor(39,1612,39,1634): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\GlobalizationBindCases.razor(52,2217,52,2244): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(22,1131,22,1161): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(24,1366,24,1396): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(37,1894,37,1917): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(67,3213,67,3230): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(91,4297,91,4316): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(136,6411,136,6439): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(166,8113,166,8139): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(178,8819,178,8852): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(283,14378,283,14419): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(297,15089,297,15122): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(311,15740,311,15772): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\BindCasesComponent.razor(325,16455,325,16491): error RZ9991: The attribute names could not be inferred from bind attribute 'bind-value'. Bind attributes should be of the form 'bind' or 'bind-value' along with their corresponding optional parameters like 'bind-value:event', 'bind:format' etc.
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\SignalRClientComponent.razor(31,31,31,44): error CS0649: Field 'SignalRClientComponent.transportType' is never assigned to, and will always have its default value
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\MultipleChildContent.razor(24,10,24,20): error CS0649: Field 'MultipleChildContent.ShowFooter' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\EventCustomArgsComponent.razor(80,10,80,38): error CS0649: Field 'EventCustomArgsComponent.customKeyDownStopPropagation' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\EventBubblingComponent.razor(81,10,81,31): error CS0649: Field 'EventBubblingComponent.targetStopPropagation' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\EventBubblingComponent.razor(83,10,83,26): error CS0649: Field 'EventBubblingComponent.preventOnKeyDown' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\HttpClientTest\CookieCounterComponent.razor(19,12,19,29): error CS0649: Field 'CookieCounterComponent.testServerBaseUrl' is never assigned to, and will always have its default value null
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\EventBubblingComponent.razor(80,10,80,37): error CS0649: Field 'EventBubblingComponent.intermediateStopPropagation' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\EventBubblingComponent.razor(82,10,82,32): error CS0649: Field 'EventBubblingComponent.ancestorPreventDefault' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\CascadingValueTest\CascadingValueSupplier.razor(26,10,26,27): error CS0649: Field 'CascadingValueSupplier.currentFlagValue2' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\RouterTest\PreventDefaultCases.razor(36,10,36,30): error CS0649: Field 'PreventDefaultCases.targetPreventDefault' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\CascadingValueTest\CascadingValueSupplier.razor(25,10,25,27): error CS0649: Field 'CascadingValueSupplier.currentFlagValue1' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\RouterTest\PreventDefaultCases.razor(37,10,37,34): error CS0649: Field 'PreventDefaultCases.descendantPreventDefault' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\DynamicComponentRendering.razor(31,20,31,35): error CS0649: Field 'DynamicComponentRendering.currentCaseName' is never assigned to, and will always have its default value null
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\SignalRClientComponent.razor(30,20,30,26): error CS0649: Field 'SignalRClientComponent.hubUrl' is never assigned to, and will always have its default value null
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\EventCustomArgsComponent.razor(79,10,79,37): error CS0649: Field 'EventCustomArgsComponent.customKeyDownPreventDefault' is never assigned to, and will always have its default value false
2>C:\dir\aspnetcore\src\Components\test\testassets\BasicTestApp\RouterTest\PreventDefaultCases.razor(35,10,35,32): error CS0649: Field 'PreventDefaultCases.ancestorPreventDefault' is never assigned to, and will always have its default value false
2>Done building project "BasicTestApp.csproj" -- FAILED.
========== Build: 1 succeeded, 1 failed, 6 up-to-date, 0 skipped ==========

This happens in other sample projects too if I add a [Parameter] property.

I'm unsure why this would only affect building inside VS and not the command line. Might it be something to do with source generator changes? I tried the following VS versions:

  • 16.10.0 Preview 1.0
  • 16.10.0 Preview 2.0 [31117.304.main]

... with the same results on both.

@SteveSandersonMS SteveSandersonMS added the area-blazor Includes: Blazor, Razor Components label Mar 18, 2021
@SteveSandersonMS
Copy link
Member Author

cc @pranavkm and @captainsafia for opinions on whether this might be related to source generator work, or @NTaylorMullen in case this is a known issue in the VS Razor tooling

@SteveSandersonMS
Copy link
Member Author

Update It's not only on VS. It happens in command line builds too, but only sometimes! What I'm getting at the moment is:

  • When running build.cmd from src\Components, it's all OK
  • When running dotnet build inside a specific sample project on the command line (e.g., BasicTestApp), it sometimes succeeds and sometimes fails with the errors above. It's not purely random, since if you immediately re-run dotnet build then whatever it did last time it will do again this time, but I'm not sure what causes it to transition between the "works" and "doesn't work" states.

@captainsafia
Copy link
Member

captainsafia commented Mar 18, 2021

@SteveSandersonMS It looks like you might've run into #30720.

I'd marked that as investigate until I could get a reliable repro out of it, but it looks like it's reproing reliably now for you.

Can you share the SDK version you're on? The delta between the version I last tried to repro on and the current one might have made the repro more reliable.

Edit: Nevermind. Just saw that you're doing this on the aspnetcore repo so I can pull out the SDK version.

@pranavkm
Copy link
Contributor

Dupe of #30720. I think it's got something to do with the compiler that gets used. Killing the compiler seems to fix it at times, but don't quote me on it.

@SteveSandersonMS
Copy link
Member Author

Can you share the SDK version you're on? The delta between the version I last tried to repro on and the current one might have made the repro more reliable.
Edit: Nevermind. Just saw that you're doing this on the aspnetcore repo so I can pull out the SDK version.

Yeah, it's currently 6.0.100-preview.3.21160.5 for me.

@SteveSandersonMS
Copy link
Member Author

SteveSandersonMS commented Mar 18, 2021

Dupe of #30720

Ah, thanks! I did search for an existing issue but none came up. Perhaps... because... in #30720, somebody put the error message in a screenshot instead of pasting the text 😆

@ghost
Copy link

ghost commented Mar 18, 2021

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@SteveSandersonMS
Copy link
Member Author

A further data point. I got into this state again just now, this time on the command line. I tried following @pranavkm's suggestion to kill all running .NET Core processes on the machine (including by closing all VS + VS Code instances, and terminating related processes like rzls). However, the errors still happened. It was only after I killed all the .NET processes and removed the bin/obj directories from artifacts that the problem went away. So maybe there's some aspect of this where the bad state is held in files on disk.

@captainsafia
Copy link
Member

This reproduces around 50% of the time when executing the following script on the CLI.

# in src/Components
for i in {0..9}; do ./build.sh ; done

However, the same behavior doesn't repro when using the activated build in the BasicTestApp directory. That might have something to do with the "same behavior repros on the next step" but that seems weird.

# in src/Components/test/testassets/BasicTestApp
for i in {0..9}; do dotnet build; done

Furthermore, the same behavior doesn't repro when invoking the compiler directly.

cd test/testassets/BasicTestApp
for i in {0..9}
do
  /Users/captainsafia/github.com/dotnet/aspnetcore/.dotnet/dotnet exec "/Users/captainsafia/.nuget/packages/microsoft.net.compilers.toolset/3.8.0-5.20519.18/tasks/netcoreapp3.1/bincore/csc.dll" {args here}
done

I'm wondering if something in particular about the way we setup our build scripts is causing thing.

As a next step, I'm going to see if I can repeat the same issue with a fresh Blazor WASM template that includes some of the components triggering the error here.

@captainsafia
Copy link
Member

Some other things I tried:

  • Checking to see if this happens via an incremental build via
    for i in {0..9}; do echo "$(date)" >> Pages/Index.razor && ~/.dotnet/dotnet build; done. No dice.
  • Checking to see if this happens on a clean build via for i in {0..9}; do rm -rf obj bin && ~/.dotnet/dotnet build; done. No dice.

I did both of these while the project was open in VS Code in case the bug has something to do with O#/the language server.

Next thing is to try the minimal project used above in Visual Studio in case the bug is specific to that.

@captainsafia
Copy link
Member

Alright -- it doesn't look like this is particular to VS at all (but maybe specific to our build scripts).

It looks like the offending state is stored in the intermediate directory.

@captainsafia
Copy link
Member

OK -- it looks like this is actually a variant of #20137 but somehow the RSG has exasperated the issue.

@captainsafia
Copy link
Member

Dumping some notes on this.

So, because I can't have nice things, getting a good debugging setup for this is fairly annoying. I set up the goal of wanting to be able to debug this end-to-end from the Execute entrypoint in the Razor source generator through the Execute entrypoint in the EventTagHelperDescriptorProvider. I set this goal because I wanted to:

  • Understand what tag helpers were cached by the source generator and verify that the bind/event tag helpers weren't running into any funkiness
  • Evaluate whether there was something funky happening in the tag helper discovery for those particular tag types

I spent some time (probably way more than necessary) trying to get this dream E2E debugging setup working. It included:

  • Building the 6.0.0-dev version of the packages out of our aspnetcore repo and using them in the sdk repo then using the dotnet layout produced from the SDK repo to build

Then I stepped back and tried to focus on what particular aspect of the problem. The tag helpers that we care about are defined in the Microsoft.AspNetCore.Components.Web assembly -- so is there something particular going on with resolving tag helpers from this assembly?

I hacked together a test scenario to validate this:

        [Fact]
        public void Execute_EventHandler_CreatesDescriptor()
        {
            // Arrange
            var compilation = BaseCompilation.AddSyntaxTrees(Parse(@"
using System;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

namespace Test
{
    [EventHandler(""onclick"", typeof(Action<MouseEventArgs>))]
    public class EventHandlers
    {
    }
}
"));

            Assert.Empty(compilation.GetDiagnostics());

            var context = TagHelperDescriptorProviderContext.Create();
            

            var location = "/Users/captainsafia/aspnetcore/artifacts/bin/Microsoft.AspNetCore.Components.Web/Debug/net6.0/ref/Microsoft.AspNetCore.Components.Web.dll";
            var reference = MetadataReference.CreateFromFile(location);
            var compilation2 = compilation.AddReferences(new[] { reference });
            context.Items.SetTargetAssembly((IAssemblySymbol) compilation.GetAssemblyOrModuleSymbol(reference));

            context.SetCompilation(compilation2);

            var provider = new EventHandlerTagHelperDescriptorProvider();

            // Act
            provider.Execute(context);

        }

When debugging through this, I discovered that this check tends to fail in the test scenario

if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, eventHandlerAttribute))

Because eventHandlerAttribute and attribute.AttributeClass are defined in two different assemblies. In this case, the eventHandlerAttribute is defined in the Microsoft.AspNetCore.Component.Shim assembly that we use specifically in the Razor tests where as attribute.AttributeClass for the event handler tag helpers defined in the Micorosoft.AspNetCore.Components.Web assembly above.

MicrosoftTeams-image

This was an interesting lead and I decided to see if the same thing could possibly be happening in some occasions when we we build on the CLI. On Pranav's recommendation, I ended up just copying the required assemblies we build in our repo to the installed SDK.

$ cp ./artifacts/bin/Microsoft.AspNetCore.Mvc.Razor.Extensions/Debug/netstandard2.0/*.dll ./.dotnet/sdk/<version-number>/Sdks/Microsoft.NET.Sdk.Razor/tools/*.dll

Weirdly enough, the issue did not repro with the development assemblies. I chatted with Pranav about this and he mentioned that perhaps the distinction is caused by the difference in configuration between the assemblies that actually get used in the SDK (Release) and the configuration used when building the assemblies (Development).

I had debated this originally but I found this to be extremely unlikely. Unless we're dealing with an extremely opaque issue that difference in configuration shouldn't be causing the behavior we see here. Then again, maybe there's an ifdef buried deep in the Razor compiler that is resulting on this. In any case, it doesn't hurt to try. So I built the Razor dependencies in a release configuration:

$ cd src/Razor
$ ./build.sh -c Release

Copied over the assemblies into the locally installed .dotnet and tried again.

No dice, the issue still didn't repro.

On a whim, I decided to remove a modification that I had made inside the EventHandlerTagHelperDescriptorProvider to enable debugging:

- while (!System.Diagnostics.Debugger.IsAttached)
- {
-  System.Console.WriteLine($"Waiting to attach on ${System.Diagnostics.Process.GetCurrentProcess().Id}");
-  System.Threading.Thread.Sleep(1000);
- }

Maybe suspending the thread in the code above was removing whatever factor caused the issue to repro. Doesn't hurt to try.

I removed this and the issue reproed. Aha! I still needed to be able to debug though so I added the following property to the BasicTestApp.csproj which causes the source generator to wait for a debugger to attach when compiling sources in the BasicTestApp.

<_RazorSourceGeneratorDebug>true</_RazorSourceGeneratorDebug>

Alongside this, I added a function breakpoint at Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator.GetTagHelperDescriptorsFromReferences.

https://github.com/dotnet/sdk/blob/234a65c6398d8d3335553bdea9d06e0e47c89d69/src/RazorSdk/SourceGenerators/RazorSourceGenerator.cs#L223

I stepped through until we were discovering descriptors in the Microsoft.AspNetCore.Components.Web assembly:

https://github.com/dotnet/sdk/blob/234a65c6398d8d3335553bdea9d06e0e47c89d69/src/RazorSdk/SourceGenerators/RazorSourceGenerator.cs#L228-L232

The descriptors are resolved from the cache.

https://github.com/dotnet/sdk/blob/234a65c6398d8d3335553bdea9d06e0e47c89d69/src/RazorSdk/SourceGenerators/RazorSourceGenerator.cs#L237

And the correct descriptors are resolved from the cache.

image

Perhaps attaching via the debugger was causing the issue not to repro?

I disabled the attach to debug code and managed to get a repro once, but wasn't able to reproduce after I added some file logging in EventHandlerTagHelperDescriptorProvider as an alternative to attaching via the debugger.

Once again, running:

# in src/Components
$ for i in {0..9}; do ./build.sh ; done

doesn't surface any exceptions when using the locally built packages.

So, the issue deepens. So far:

  • The issue that appears when running the EventHandlerTagHelperDescriptorProvider in a test context does not repro in our build.
  • The issue doesn't appear to repro when using development versions of the package
    • Sidenote: I'm unable to repro with an unmodified SDK at f7e8896.

@captainsafia
Copy link
Member

Thanks to @HaoK and @javiercn for the help rubber ducking this.

The issue seems to be related to the caching implementation that we use to cache tag helper descriptors in the Razor source generator. This implementation is temporary and will be usurped by the work that we do in #31244 to migrate to the new incremental source generator API.

Another hunch we had is that the issue might not repro on CI because of the --ci flag although I invalidated this locally. It appears that this issue doesn't repro when you run the top-level build script which is why we don't see it in CI.

Sooooooo, for now, I say we wait to see how things shake out when we migrate to the incremental source generator API.

@captainsafia
Copy link
Member

Update: I've added a way to support override the _UseRazorSourceGenerator flag and falling back to the old model. When we pick up the next version of the SDK, I'll disable the RSG for this project until we replat on the new source generators API.

@ghost ghost added the Working label May 13, 2021
@ghost ghost added Done This issue has been fixed and removed Working labels May 14, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 13, 2021
@mkArtakMSFT mkArtakMSFT added bug This issue describes a behavior which is not expected - a bug. and removed investigate labels Oct 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants