From 54f4e4a2d2f3fe8f301163519b65ccbf1593b0b8 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 11 Jun 2019 13:40:26 -0700 Subject: [PATCH] Add nullability support to use local function Fixes https://github.com/dotnet/roslyn/issues/30322 --- .../UseLocalFunction/UseLocalFunctionTests.cs | 29 +++++++++++++++++++ .../CSharpUseLocalFunctionCodeFixProvider.cs | 2 +- .../Extensions/TypeSyntaxExtensions.cs | 8 +++-- .../CodeGenerationAbstractMethodSymbol.cs | 6 ++-- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs index 58f2148fe275c..3143a326baec6 100644 --- a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs +++ b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.UseLocalFunction; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; @@ -3660,5 +3661,33 @@ void M() } }", parseOptions: CSharp8ParseOptions); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)] + public async Task TestWithNullableParameterAndReturn() + { + await TestInRegularAndScriptAsync( +@"#nullable enable + +using System; + +class Program +{ + static void Main(string[] args) + { + Func [||]f = s => s; + } +}", +@"#nullable enable + +using System; + +class Program +{ + static void Main(string[] args) + { + static string? f(string? s) => s; + } +}", parseOptions: TestOptions.Regular8WithNullableAnalysis); + } } } diff --git a/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs b/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs index 8259dacfe9c33..15b1844b8859d 100644 --- a/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs @@ -245,7 +245,7 @@ ParameterSyntax PromoteParameter(ParameterSyntax parameterNode, IParameterSymbol if (parameterNode.Type == null) { - parameterNode = parameterNode.WithType(delegateParameter?.Type.GenerateTypeSyntax() ?? s_objectType); + parameterNode = parameterNode.WithType(delegateParameter?.Type.WithNullability(delegateParameter.NullableAnnotation).GenerateTypeSyntax() ?? s_objectType); } if (delegateParameter?.HasExplicitDefaultValue == true) diff --git a/src/Workspaces/CSharp/Portable/Extensions/TypeSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/TypeSyntaxExtensions.cs index adcc44659d562..323864939818d 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/TypeSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/TypeSyntaxExtensions.cs @@ -93,17 +93,19 @@ public static bool IsTypeInferred(this TypeSyntax typeSyntax, SemanticModel sema public static TypeSyntax GenerateReturnTypeSyntax(this IMethodSymbol method) { + var returnType = method.ReturnType.WithNullability(method.ReturnNullableAnnotation); + if (method.ReturnsByRef) { - return method.ReturnType.GenerateRefTypeSyntax(); + return returnType.GenerateRefTypeSyntax(); } else if (method.ReturnsByRefReadonly) { - return method.ReturnType.GenerateRefReadOnlyTypeSyntax(); + return returnType.GenerateRefReadOnlyTypeSyntax(); } else { - return method.ReturnType.GenerateTypeSyntax(); + return returnType.GenerateTypeSyntax(); } } diff --git a/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationAbstractMethodSymbol.cs b/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationAbstractMethodSymbol.cs index e48af2ea59ac3..9e0ec1413df37 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationAbstractMethodSymbol.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationAbstractMethodSymbol.cs @@ -48,9 +48,9 @@ protected CodeGenerationAbstractMethodSymbol( public abstract IMethodSymbol PartialDefinitionPart { get; } public abstract IMethodSymbol PartialImplementationPart { get; } - public NullableAnnotation ReceiverNullableAnnotation => throw new NotImplementedException(); - public NullableAnnotation ReturnNullableAnnotation => throw new NotImplementedException(); - public ImmutableArray TypeArgumentsNullableAnnotations => throw new NotImplementedException(); + public NullableAnnotation ReceiverNullableAnnotation => ReceiverType.GetNullability(); + public NullableAnnotation ReturnNullableAnnotation => ReturnType.GetNullability(); + public ImmutableArray TypeArgumentsNullableAnnotations => TypeArguments.SelectAsArray(a => a.GetNullability()); public virtual ITypeSymbol ReceiverType {