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

Remove the nullable wrappers from the Workspaces layer #40030

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -8931,6 +8931,48 @@ class Blah
}");
}

[WorkItem(9090, "https://github.com/dotnet/roslyn/issues/9090")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public async Task TestPropertyPatternInIsPatternWithNullablePattern()
{
await TestInRegularAndScriptAsync(
@"#nullable enable

class C
{
void M2()
{
object? o = null;
object? zToMatch = null;
if (o is Blah { [|X|]: (y: 1, z: zToMatch) })
{
}
}

class Blah
{
}
}",
@"#nullable enable

class C
{
void M2()
{
object? o = null;
object? zToMatch = null;
if (o is Blah { X: (y: 1, z: zToMatch) })
{
}
}

class Blah
{
public (int y, object? z) X { get; internal set; }
}
}");
}

[WorkItem(9090, "https://github.com/dotnet/roslyn/issues/9090")]
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/30794")]
[Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private static bool DoesExpressionReturnTask(ExpressionSyntax expression, Semant
}

return TryGetExpressionType(expression, semanticModel, out var returnType) &&
semanticModel.Compilation.ClassifyConversion(taskType.WithoutNullability(), returnType.WithoutNullability()).Exists;
semanticModel.Compilation.ClassifyConversion(taskType, returnType).Exists;
}

private static bool DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(ExpressionSyntax expression, SemanticModel semanticModel, Project project, CancellationToken cancellationToken)
Expand All @@ -119,7 +119,7 @@ private static bool DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(E
}

var compilation = semanticModel.Compilation;
if (!compilation.ClassifyConversion(taskType.WithoutNullability(), rightSideType.WithoutNullability()).Exists)
if (!compilation.ClassifyConversion(taskType, rightSideType).Exists)
{
return false;
}
Expand All @@ -132,7 +132,7 @@ private static bool DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(E
var typeArguments = rightSideType.TypeArguments;
var typeInferer = project.LanguageServices.GetService<ITypeInferenceService>();
var inferredTypes = typeInferer.InferTypes(semanticModel, expression, cancellationToken);
return typeArguments.Any(ta => inferredTypes.Any(it => compilation.ClassifyConversion(it.WithoutNullability(), ta.WithoutNullability()).Exists));
return typeArguments.Any(ta => inferredTypes.Any(it => compilation.ClassifyConversion(it, ta).Exists));
}

private static bool IsInAsyncFunction(ExpressionSyntax expression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ private bool IsCorrectTypeForYieldReturn(ITypeSymbol typeArgument, ITypeSymbol r
return false;
}

ienumerableGenericSymbol = ienumerableGenericSymbol.ConstructWithNullability(typeArgument);
ienumeratorGenericSymbol = ienumeratorGenericSymbol.ConstructWithNullability(typeArgument);
ienumerableGenericSymbol = ienumerableGenericSymbol.Construct(typeArgument);
ienumeratorGenericSymbol = ienumeratorGenericSymbol.Construct(typeArgument);

if (!CanConvertTypes(typeArgument, returnExpressionType, model))
{
Expand All @@ -137,7 +137,7 @@ private bool IsCorrectTypeForYieldReturn(ITypeSymbol typeArgument, ITypeSymbol r
private bool CanConvertTypes(ITypeSymbol typeArgument, ITypeSymbol returnExpressionType, SemanticModel model)
{
// return false if there is no conversion for the top level type
if (!model.Compilation.ClassifyConversion(typeArgument.WithoutNullability(), returnExpressionType.WithoutNullability()).Exists)
if (!model.Compilation.ClassifyConversion(typeArgument, returnExpressionType).Exists)
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ protected override async Task<CodeAction> GetCodeFixAsync(SyntaxNode root, Synta
if (arity == 1)
{
var typeArg = type.GetTypeArguments().First();
ienumerableGenericSymbol = ienumerableGenericSymbol.ConstructWithNullability(typeArg);
ienumerableGenericSymbol = ienumerableGenericSymbol.Construct(typeArg);
}
else if (arity == 0 && type is IArrayTypeSymbol)
{
ienumerableGenericSymbol = ienumerableGenericSymbol.ConstructWithNullability((type as IArrayTypeSymbol).ElementType);
ienumerableGenericSymbol = ienumerableGenericSymbol.Construct((type as IArrayTypeSymbol).ElementType);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ protected override (string displayText, string suffix, string insertionText) Get

if (symbol is ITypeSymbol typeSymbol)
{
return base.GetDisplayAndSuffixAndInsertionText(typeSymbol.WithNullability(NullableAnnotation.None), context);
// typeSymbol may be a symbol that is nullable if the place we are assigning to is null, for example
//
// object? o = new |
//
// We strip the top-level nullability so we don't end up suggesting "new object?" here. Nested nullability would still
// be generated.
return base.GetDisplayAndSuffixAndInsertionText(typeSymbol.WithNullableAnnotation(NullableAnnotation.NotAnnotated), context);
}

return base.GetDisplayAndSuffixAndInsertionText(symbol, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ protected override ITypeSymbol GetSymbolType(SemanticModel semanticModel, ISymbo

if (AreAllReferencesNotNull(references))
{
return base.GetSymbolType(semanticModel, symbol).WithNullability(NullableAnnotation.NotAnnotated);
return base.GetSymbolType(semanticModel, symbol).WithNullableAnnotation(NullableAnnotation.NotAnnotated);
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved
}

return base.GetSymbolType(semanticModel, symbol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ protected override async Task<SemanticDocument> UpdateMethodAfterGenerationAsync
CancellationToken cancellationToken)
{
// Only need to update for nullable reference types in return
if (methodSymbolResult.Data.ReturnType.GetNullability() != NullableAnnotation.Annotated)
if (methodSymbolResult.Data.ReturnType.NullableAnnotation != NullableAnnotation.Annotated)
{
return await base.UpdateMethodAfterGenerationAsync(originalDocument, methodSymbolResult, cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -768,7 +768,7 @@ static async Task<Document> GenerateNewDocument(
CancellationToken cancellationToken)
{
// Return type can be updated to not be null
var newType = methodSymbolResult.Data.ReturnType.WithNullability(NullableAnnotation.NotAnnotated);
var newType = methodSymbolResult.Data.ReturnType.WithNullableAnnotation(NullableAnnotation.NotAnnotated);

var oldRoot = await originalDocument.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var newRoot = oldRoot.ReplaceNode(returnType, newType.GenerateTypeSyntax());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ protected override async Task<OperationStatus> CheckTypeAsync(
{
var typeName = SyntaxFactory.ParseTypeName(typeParameter.Name);
var currentType = semanticModel.GetSpeculativeTypeInfo(contextNode.SpanStart, typeName, SpeculativeBindingOption.BindAsTypeOrNamespace).Type;
if (currentType == null || !AllNullabilityIgnoringSymbolComparer.Instance.Equals(currentType, typeParameter))
if (currentType == null || !SymbolEqualityComparer.Default.Equals(currentType, typeParameter))
{
return new OperationStatus(OperationStatusFlag.BestEffort,
string.Format(FeaturesResources.Type_parameter_0_is_hidden_by_another_type_parameter_1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#nullable enable
#nullable enable

using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Extensions;
Expand Down Expand Up @@ -46,7 +46,7 @@ public override bool ContainingScopeHasAsyncKeyword()
return firstToken.GetCommonRoot(lastToken).GetAncestorOrThis<ExpressionSyntax>();
}

public override ITypeSymbol GetContainingScopeType()
public override ITypeSymbol? GetContainingScopeType()
{
var node = this.GetContainingScope();
var model = this.SemanticDocument.SemanticModel;
Expand Down Expand Up @@ -88,7 +88,7 @@ public override ITypeSymbol GetContainingScopeType()
return GetRegularExpressionType(model, node);
}

private static ITypeSymbol GetRegularExpressionType(SemanticModel semanticModel, SyntaxNode node)
private static ITypeSymbol? GetRegularExpressionType(SemanticModel semanticModel, SyntaxNode node)
{
// regular case. always use ConvertedType to get implicit conversion right.
var expression = node.GetUnparenthesizedExpression();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ protected override ITypeSymbol GetAttributeArgumentType(

protected override bool IsConversionImplicit(Compilation compilation, ITypeSymbol sourceType, ITypeSymbol targetType)
{
return compilation.ClassifyConversion(sourceType.WithoutNullability(), targetType.WithoutNullability()).IsImplicit;
return compilation.ClassifyConversion(sourceType, targetType).IsImplicit;
}

internal override IMethodSymbol GetDelegatingConstructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private ITypeParameterSymbol GetUniqueTypeParameter(
CancellationToken cancellationToken)
{
var methodTypeParameter = GetMethodTypeParameter(type, cancellationToken);
return methodTypeParameter ?? CodeGenerationSymbolFactory.CreateTypeParameterSymbol(NameGenerator.GenerateUniqueName("T", isUnique)).WithNullability(NullableAnnotation.None);
return methodTypeParameter ?? CodeGenerationSymbolFactory.CreateTypeParameterSymbol(NameGenerator.GenerateUniqueName("T", isUnique));
}

private ITypeParameterSymbol GetMethodTypeParameter(TypeSyntax type, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ protected override ITypeSymbol DetermineArgumentType(SemanticModel semanticModel

protected override bool IsConversionImplicit(Compilation compilation, ITypeSymbol sourceType, ITypeSymbol targetType)
{
return compilation.ClassifyConversion(sourceType.WithoutNullability(), targetType.WithoutNullability()).IsImplicit;
return compilation.ClassifyConversion(sourceType, targetType).IsImplicit;
}

public override async Task<Tuple<INamespaceSymbol, INamespaceOrTypeSymbol, Location>> GetOrGenerateEnclosingNamespaceSymbolAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ private static TypeSyntax FixMethodReturnType(
{
newReturnType = knownTypes._iAsyncEnumerableOfTTypeOpt is null
? MakeGenericType("IAsyncEnumerable", methodSymbol.ReturnType)
: knownTypes._iAsyncEnumerableOfTTypeOpt.ConstructWithNullability(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
: knownTypes._iAsyncEnumerableOfTTypeOpt.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}
else if (IsIEnumerator(returnType, knownTypes) && IsIterator(methodSymbol))
{
newReturnType = knownTypes._iAsyncEnumeratorOfTTypeOpt is null
? MakeGenericType("IAsyncEnumerator", methodSymbol.ReturnType)
: knownTypes._iAsyncEnumeratorOfTTypeOpt.ConstructWithNullability(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
: knownTypes._iAsyncEnumeratorOfTTypeOpt.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}
else if (IsIAsyncEnumerableOrEnumerator(returnType, knownTypes))
{
Expand All @@ -118,7 +118,7 @@ private static TypeSyntax FixMethodReturnType(
{
// If it's not already Task-like, then wrap the existing return type
// in Task<>.
newReturnType = knownTypes._taskOfTType.ConstructWithNullability(methodSymbol.GetReturnTypeWithAnnotatedNullability()).GenerateTypeSyntax();
newReturnType = knownTypes._taskOfTType.Construct(methodSymbol.ReturnType).GenerateTypeSyntax();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ private static TypeSyntax FixMethodReturnType(IMethodSymbol methodSymbol, TypeSy
else if (returnType.OriginalDefinition.Equals(knownTypes._iAsyncEnumerableOfTTypeOpt))
{
// If the return type is IAsyncEnumerable<T>, then make the new return type IEnumerable<T>.
newReturnType = knownTypes._iEnumerableOfTType.ConstructWithNullability(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
newReturnType = knownTypes._iEnumerableOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}
else if (returnType.OriginalDefinition.Equals(knownTypes._iAsyncEnumeratorOfTTypeOpt))
{
// If the return type is IAsyncEnumerator<T>, then make the new return type IEnumerator<T>.
newReturnType = knownTypes._iEnumeratorOfTType.ConstructWithNullability(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
newReturnType = knownTypes._iEnumeratorOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax();
}

return newReturnType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ private bool TryGetIndexers(
?? semanticModel.GetSymbolInfo(expression).GetAnySymbol().GetSymbolType();
}

indexers = semanticModel.LookupSymbols(position, expressionType.WithoutNullability(), WellKnownMemberNames.Indexer)
indexers = semanticModel.LookupSymbols(position, expressionType, WellKnownMemberNames.Indexer)
.OfType<IPropertySymbol>()
.ToImmutableArray();
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,11 @@ private IEnumerable<SignatureHelpParameter> ConvertTupleMembers(INamedTypeSymbol
var result = new List<SignatureHelpParameter>();
foreach (var element in tupleType.TupleElements)
{
var type = element.GetTypeWithAnnotatedNullability();

// The display name for each element.
// Empty strings for elements not explicitly declared
var elementName = element.IsImplicitlyDeclared ? string.Empty : element.Name;

var typeParts = type.ToMinimalDisplayParts(semanticModel, position).ToList();
var typeParts = element.Type.ToMinimalDisplayParts(semanticModel, position).ToList();
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved
if (!string.IsNullOrEmpty(elementName))
{
typeParts.Add(spacePart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ static ParameterSyntax PromoteParameter(ParameterSyntax parameterNode, IParamete

if (parameterNode.Type == null)
{
parameterNode = parameterNode.WithType(delegateParameter?.Type.WithNullability(delegateParameter.NullableAnnotation).GenerateTypeSyntax() ?? s_objectType);
parameterNode = parameterNode.WithType(delegateParameter?.Type.GenerateTypeSyntax() ?? s_objectType);
}

if (delegateParameter?.HasExplicitDefaultValue == true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var enclosing = semanticModel.GetEnclosingNamedType(position, cancellationToken);

// Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members.
IEnumerable<ISymbol> members = semanticModel.LookupSymbols(position, initializedType.WithoutNullability());
IEnumerable<ISymbol> members = semanticModel.LookupSymbols(position, initializedType);
members = members.Where(m => IsInitializable(m, enclosing) &&
m.CanBeReferencedByName &&
IsLegalFieldOrProperty(m) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected override Task<ISymbol> GenerateMemberAsync(ISymbol newOverriddenMember
methodSymbol.Name == "ToString" &&
methodSymbol.Parameters.Length == 0)
{
newOverriddenMember = CodeGenerationSymbolFactory.CreateMethodSymbol(methodSymbol, returnType: methodSymbol.ReturnType.WithNullability(NullableAnnotation.NotAnnotated));
newOverriddenMember = CodeGenerationSymbolFactory.CreateMethodSymbol(methodSymbol, returnType: methodSymbol.ReturnType.WithNullableAnnotation(NullableAnnotation.NotAnnotated));
}

// Figure out what to insert, and do it. Throw if we've somehow managed to get this far and can't.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected override async Task<ImmutableArray<ISymbol>> GetPreselectedSymbolsWork

// Don't preselect intrinsic type symbols so we can preselect their keywords instead. We will also ignore nullability for purposes of preselection
// -- if a method is returning a string? but we've inferred we're assigning to a string or vice versa we'll still count those as the same.
return symbols.WhereAsArray(s => inferredTypes.Contains(GetSymbolType(s), AllNullabilityIgnoringSymbolComparer.Instance) && !IsInstrinsic(s));
return symbols.WhereAsArray(s => inferredTypes.Contains(GetSymbolType(s), SymbolEqualityComparer.Default) && !IsInstrinsic(s));
}

private ITypeSymbol GetSymbolType(ISymbol symbol)
Expand Down
Loading