Don't load generators that target net framework explicitly.#47100
Don't load generators that target net framework explicitly.#47100chsienki merged 4 commits intodotnet:masterfrom
Conversation
| if (reference.Name?.Equals("mscorlib", StringComparison.OrdinalIgnoreCase) == true) | ||
| { | ||
| var publicKeyToken = reference.GetPublicKeyToken(); | ||
| if (publicKeyToken is object && BitConverter.ToString(publicKeyToken).Equals(ExpectedPublicKey, StringComparison.OrdinalIgnoreCase)) |
There was a problem hiding this comment.
@jaredpar Not sure who else to ask. Does this seem like a sensible way to check for mscorlib references? (Or do we have a utility that does it in the code already?)
There was a problem hiding this comment.
Rather than checking for mscorlib references I would look at the TargetFrameworkAttribute on the assembly. If the moniker begins with .NETFRamework when we should reject.
There was a problem hiding this comment.
Ok, and we're ok that you can create .NET Framework referencing assemblies without a TargetFrameworkAttribute? A default csc.exe Generator.cs invocation will target framework, but not add the attribute.
There was a problem hiding this comment.
Yes. Any check here is imprecise. The majority case is that they use our build infra,n not the raw compiler, which will add this attribute.
|
@dotnet/roslyn-compiler for a fairly small review please :) |
|
|
||
| var builder = ImmutableArray.CreateBuilder<ISourceGenerator>(); | ||
| reference.AddGenerators(builder, LanguageNames.CSharp); | ||
| var analyzers = builder.ToImmutable(); |
There was a problem hiding this comment.
var analyzers = builder.ToImmutable(); [](start = 16, length = 38)
The statement appears to be unused. Should we Assert.Equal(1, analyzers.Length)? #Closed
There was a problem hiding this comment.
Honestly, that was just left over from copy paste, but it seems sensible to assert that we did actually load a generator, so will add.
|
|
||
| Debug.Assert(type != null); | ||
|
|
||
| // check if this references net framework, and issue a diagnostic if we don't allow that |
There was a problem hiding this comment.
| // check if this references net framework, and issue a diagnostic if we don't allow that | |
| // check if this references net framework, and issue a diagnostic that this isn't supported |
| // check if this references net framework, and issue a diagnostic if we don't allow that | ||
| if (!_allowNetFramework) | ||
| { | ||
| var targetFrameworkAttribute = analyzerAssembly.GetCustomAttribute<TargetFrameworkAttribute>(); |
There was a problem hiding this comment.
GetCustomAttribute<T> will throw when dealing with invalid metadata (basically multiple copies of TargetFarmeworkAttribute even though it has AllowMultiple = false). Looked around a bit and seems like we are okay with this type of invalid IL breaking the compiler though. So think we can leave as is.
There was a problem hiding this comment.
I did look at the source code to see how it handled those cases and it seems to just take the first one, rather than throwing?
There was a problem hiding this comment.
The comment I saw said it threw. Either way though, seems like there is lots of precedenc for this.
Mostyl I commented because it took me ten minutes to figure out where this call was coming from. I wanted to write something down to make me feel better about all the time I spent looking into it.
| <comment>'SourceText' is not localizable.</comment> | ||
| </data> | ||
| <data name="TypeReferencesNetFramework" xml:space="preserve"> | ||
| <value>The type '{0}' references .NET Framework, which is not supported.</value> |
There was a problem hiding this comment.
This isn't about the type though, it's about the assembly. I would phrase it as
The assembly containing type '{0}' ...
| public static byte[] NetStandardGenerator => ResourceLoader.GetOrCreateResource(ref s_netStandardGenerator, "Generators.NetStandardGenerator.dll"); | ||
|
|
||
| private static byte[] s_noTargetGenerator; | ||
| public static byte[] NoTargetGenerator => ResourceLoader.GetOrCreateResource(ref s_noTargetGenerator, "Generators.NoTargetGenerator.dll"); |
There was a problem hiding this comment.
Rather than checking in DLLs, which continue to inflate our repo size, why not just build them as a part of the tests that need them?
There was a problem hiding this comment.
Ah yeah didn't think of that, plus now we're not actually dealing with references this is much simpler to do.
|
|
||
| _diagnosticAnalyzers = new Extensions<DiagnosticAnalyzer>(this, IsDiagnosticAnalyzerAttribute, GetDiagnosticsAnalyzerSupportedLanguages); | ||
| _generators = new Extensions<ISourceGenerator>(this, IsGeneratorAttribute, GetGeneratorsSupportedLanguages); | ||
| _diagnosticAnalyzers = new Extensions<DiagnosticAnalyzer>(this, IsDiagnosticAnalyzerAttribute, GetDiagnosticsAnalyzerSupportedLanguages, allowNetFramework: true); |
There was a problem hiding this comment.
allowNetFramework: true [](start = 149, length = 23)
Why are analyzers allowed to target .NET Framework but generators are not? #Closed
There was a problem hiding this comment.
They were never supported, we just failed to enforce that fact. Now the fact that we didn't enforce is one of the hurdles for us movign fully to .NET Core. This change is an attempt to not make the same mistake, and create the same hurdle, for source generators,
- Remove test resources and create generators on the fly - Reword some text
| <ProjectReference Include="..\..\..\Test\Utilities\Portable\Roslyn.Test.Utilities.csproj" /> | ||
| <ProjectReference Include="..\..\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj" /> | ||
| <ProjectReference Include="..\..\Test\Resources\Core\Microsoft.CodeAnalysis.Compiler.Test.Resources.csproj" /> | ||
| <ProjectReference Include="..\..\Test\Utilities\CSharp\Microsoft.CodeAnalysis.CSharp.Test.Utilities.csproj" /> |
There was a problem hiding this comment.
....\Test\Utilities\CSharp\Microsoft.CodeAnalysis.CSharp.Test.Utilities.csproj [](start = 31, length = 79)
Do we need this project reference? If it's just to create a CSharpCompilation, we should use new CSharpCompilation(...) directly instead. #Closed
There was a problem hiding this comment.
Ah, yeah that was why I added it. I originally started by calling CSharpCompilation directly, but it was proving tricky to get all the references right. I'll switch back to that way of doing it.
* upstream/master: (220 commits) Don't load generators that target net framework explicitly. (dotnet#47100) Update src/Features/Core/Portable/UnifiedSuggestions/UnifiedSuggestedActionsSource.cs Clean up redundant code action filtering Remove IActiveStatementSpanTracker (dotnet#46826) Disable API analysis if telemetry is disabled Update src/Workspaces/Remote/ServiceHub/Services/CodeAnalysis/CodeAnalysisService_SemanticClassificationCache.cs Doc Compress two values. PR feedback Revert Revert Lint Fix formatting Fire and forget Fix mangling Ensure that local functions are also marked as invalid if their containing methods are generic. Fix dependency graph for AnalyzerRunner Add AnalyzerRunner target for net5.0 Make VerifyForwardedTypes asynchronous Fix bug when "End statement" is used in single-line if (dotnet#47062) ...
Issue a diagnostic and don't load generator if it has references to mscorlib