diff --git a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs index 58f2148fe275c64d9e1239f1554ed13d39a67f62..3143a326baec61ecd4fbba11932bc8920e83cdd6 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 8259dacfe9c339131f7088c9395fb6c091247555..15b1844b8859d5bdd7b563cc2dca112b21ff51ed 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 adcc44659d5624a1ff28f4e92955af410e8f55c7..323864939818d546dac6f3a804e8708df79aac54 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 e48af2ea59ac3227a57576efcd3135ebb1d9aa32..9e0ec1413df37d8ca5a7714f1189d3b7ef3bdd7c 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationAbstractMethodSymbol.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/Symbols/CodeGenerationAbstractMethodSymbol.cs @@ -48,9 +48,9 @@ public virtual ImmutableArray GetReturnTypeAttributes() 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 {