dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.06k stars 4.04k forks source link

Comparing types #33078

Closed olmobrutall closed 5 years ago

olmobrutall commented 5 years ago

Trying to update a custom Roslyn Analyzer to C# 8 with NullableContext enable, while comparing two types that where equals, now they are not anymore.

Version Used: VS2019 Preview 2.1 and

<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.1.0-beta1-19102-01" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.1.0-beta1-19102-01" />

Steps to Reproduce: Compare two ConstructedNamedTypeSymbol in C#8 with NullableContext enabled:

 .AddProject( projectId, TestProjectName, TestProjectName, language)
                .WithProjectParseOptions(projectId, new CSharpParseOptions(LanguageVersion.CSharp8))
                .WithProjectCompilationOptions(projectId, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithNullableContextOptions(NullableContextOptions.Enable))

Expected Behavior:

The two types are equal, or, better, there is a way to construct a generic type with TypeSymbolWithAnnotations (I'm doing it like this)

Actual Behavior:

https://github.com/signumsoftware/framework/blob/master/Signum.Analyzer/Signum.Analyzer/ExpressionFieldAnalyzer.cs#L93 The constructed type (expressionType) lacks nullability information but the one from the member (?(fieldSymbol.Type) does have it, being not equal.

NamedType System.Linq.Expressions.Expression<System.Func<Signum.Entities.Entity, System.Int32>>
NamedType System.Linq.Expressions.Expression<System.Func<Signum.Entities.Entity!, System.Int32>!>

I understand that they are not equal but I'm not aware of any public API to construct the type providing nullability information, amd TypeSymbolWithAnnotations is internal https://github.com/dotnet/roslyn/blob/c8e0e7f29853eb5775da2187991e68fa5077f7af/src/Compilers/CSharp/Portable/Symbols/TypeSymbolWithAnnotations.cs#L289.

Thanks!

jinujoseph commented 5 years ago

cc @mavasani

mavasani commented 5 years ago

I am not aware or familiar with any Nullability related APIs. Tagging @333fred and also marking as Area-Compilers as this is really a compiler API question.

333fred commented 5 years ago

The public API for nullability analysis by the compiler is currently in design/implementation, and is not available publicly. The current design for these APIs is that nullability will not be available directly on ITypeSymbols: it'll be available on the containing context. So, for example, if you have a variable a of type string?, then calling GetTypeInfo on that reference will return a TypeInfo with both the ITypeSymbol and Nullability of the reference. See the current design doc: https://github.com/dotnet/roslyn/blob/master/docs/compilers/CSharp/Nullability%20Public%20API%20Design%20Notes.md

333fred commented 5 years ago

We're going to use this issue to track making sure that this question can be answered: our PublicAPI should support answering this question by the time that C# 8.0 is finalized, but it's unlikely to be finished immediately.

chsienki commented 5 years ago

This should be fixed via the new symbol overload: https://github.com/dotnet/roslyn/blob/1228c9578a2c8a2847166c34adec4f91a2c9ad39/src/Compilers/Core/Portable/Symbols/ISymbol.cs#L298

Please feel free to re-open if you believe it isn't.