diff --git a/.editorconfig b/.editorconfig index 3c48835c71c59..43703592faa10 100644 --- a/.editorconfig +++ b/.editorconfig @@ -66,7 +66,7 @@ dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field -dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected internal, private protected +dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected dotnet_naming_symbols.non_private_static_fields.required_modifiers = static dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case @@ -77,7 +77,7 @@ dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = n dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_readonly_field_style dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field -dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected internal, private protected +dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 4f99d68ccfee5..24808806b6c47 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -8278,6 +8278,7 @@ private StatementSyntax ParseLocalDeclarationStatement(SyntaxToken awaitKeywordO { usingKeyword = CheckFeatureAvailability(usingKeyword, MessageID.IDS_FeatureUsingDeclarations); } + bool canParseAsLocalFunction = usingKeyword == default; var mods = _pool.Allocate(); this.ParseDeclarationModifiers(mods); @@ -8288,7 +8289,7 @@ private StatementSyntax ParseLocalDeclarationStatement(SyntaxToken awaitKeywordO TypeSyntax type; LocalFunctionStatementSyntax localFunction; this.ParseLocalDeclaration(variables, - allowLocalFunctions: usingKeyword == default, + allowLocalFunctions: canParseAsLocalFunction, mods: mods.ToList(), type: out type, localFunction: out localFunction); @@ -8301,7 +8302,8 @@ private StatementSyntax ParseLocalDeclarationStatement(SyntaxToken awaitKeywordO // If we find an accessibility modifier but no local function it's likely // the user forgot a closing brace. Let's back out of statement parsing. - if (mods.Count > 0 && + if (canParseAsLocalFunction && + mods.Count > 0 && IsAccessibilityModifier(((SyntaxToken)mods[0]).ContextualKind)) { return null; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UsingDeclarationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UsingDeclarationTests.cs index cde05864c8f36..e89eb59f61f71 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UsingDeclarationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UsingDeclarationTests.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.UnitTests; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.Semantics @@ -769,5 +770,29 @@ static void Main() Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "using S3 S3 = new S3();").WithArguments("S3.Dispose()").WithLocation(40, 9) ); } + + [Fact] + [WorkItem(36413, "https://github.com/dotnet/roslyn/issues/36413")] + public void UsingDeclarationsWithInvalidModifiers() + { + var source = @" +using System; +class C +{ + static void Main() + { + using public readonly var x = (IDisposable)null; + } +} +"; + CreateCompilation(source, parseOptions: TestOptions.RegularPreview).VerifyDiagnostics( + // (7,15): error CS0106: The modifier 'public' is not valid for this item + // using public readonly var x = (IDisposable)null; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "public").WithArguments("public").WithLocation(7, 15), + // (7,22): error CS0106: The modifier 'readonly' is not valid for this item + // using public readonly var x = (IDisposable)null; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(7, 22) + ); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs index aac802c4268c7..3f821cc8767e2 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs @@ -2508,6 +2508,44 @@ public void TestUsingVarWithVarDeclaration() Assert.Equal("b", us.Declaration.Variables[0].Initializer.Value.ToString()); } + [Fact] + [WorkItem(36413, "https://github.com/dotnet/roslyn/issues/36413")] + public void TestUsingVarWithInvalidDeclaration() + { + var text = "using public readonly var a = b;"; + var statement = this.ParseStatement(text, options: TestOptions.Regular8); + + Assert.NotNull(statement); + Assert.Equal(SyntaxKind.LocalDeclarationStatement, statement.Kind()); + Assert.Equal(text, statement.ToString()); + Assert.Equal(2, statement.Errors().Length); + Assert.Equal((int)ErrorCode.ERR_BadMemberFlag, statement.Errors()[0].Code); + Assert.Equal("public", statement.Errors()[0].Arguments[0]); + Assert.Equal((int)ErrorCode.ERR_BadMemberFlag, statement.Errors()[1].Code); + Assert.Equal("readonly", statement.Errors()[1].Arguments[0]); + + var us = (LocalDeclarationStatementSyntax)statement; + Assert.NotNull(us.UsingKeyword); + Assert.Equal(SyntaxKind.UsingKeyword, us.UsingKeyword.Kind()); + + Assert.NotNull(us.Declaration); + Assert.NotNull(us.Declaration.Type); + Assert.Equal("var", us.Declaration.Type.ToString()); + Assert.Equal(SyntaxKind.IdentifierName, us.Declaration.Type.Kind()); + Assert.Equal(SyntaxKind.IdentifierToken, ((IdentifierNameSyntax)us.Declaration.Type).Identifier.Kind()); + Assert.Equal(2, us.Modifiers.Count); + Assert.Equal("public", us.Modifiers[0].ToString()); + Assert.Equal("readonly", us.Modifiers[1].ToString()); + Assert.Equal(1, us.Declaration.Variables.Count); + Assert.NotNull(us.Declaration.Variables[0].Identifier); + Assert.Equal("a", us.Declaration.Variables[0].Identifier.ToString()); + Assert.Null(us.Declaration.Variables[0].ArgumentList); + Assert.NotNull(us.Declaration.Variables[0].Initializer); + Assert.NotNull(us.Declaration.Variables[0].Initializer.EqualsToken); + Assert.NotNull(us.Declaration.Variables[0].Initializer.Value); + Assert.Equal("b", us.Declaration.Variables[0].Initializer.Value.ToString()); + } + [Fact] public void TestUsingVarWithVarDeclarationTree() { diff --git a/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs b/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs index 3602acb5933c6..998225eec8521 100644 --- a/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs +++ b/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs @@ -1,10 +1,14 @@ // Copyright(c) Microsoft.All Rights Reserved.Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Collections.Immutable; +using System.Linq; +using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.CSharp.MoveToNamespace; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.MoveToNamespace; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.MoveToNamespace; using Microsoft.VisualStudio.Composition; @@ -16,14 +20,15 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MoveToNamespace [UseExportProvider] public class MoveToNamespaceTests : AbstractMoveToNamespaceTests { - private static readonly IExportProviderFactory CSharpExportProviderFactory = + private static readonly IExportProviderFactory ExportProviderFactory = ExportProviderCache.GetOrCreateExportProviderFactory( - TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic - .WithPart(typeof(TestMoveToNamespaceOptionsService)) - .WithPart(typeof(TestSymbolRenamedCodeActionOperationFactoryWorkspaceService))); + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestMoveToNamespaceOptionsService))); protected override TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters) - => TestWorkspace.CreateCSharp(initialMarkup, parameters.parseOptions, parameters.compilationOptions, exportProvider: CSharpExportProviderFactory.CreateExportProvider()); + => CreateWorkspaceFromFile(initialMarkup, parameters, ExportProviderFactory); + + protected TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters, IExportProviderFactory exportProviderFactory) + => TestWorkspace.CreateCSharp(initialMarkup, parameters.parseOptions, parameters.compilationOptions, exportProvider: exportProviderFactory.CreateExportProvider()); protected override ParseOptions GetScriptOptions() => Options.Script; @@ -1080,5 +1085,34 @@ class C2 { {"Two.C2", "Three.C2" } }); + + [WpfFact, Trait(Traits.Feature, Traits.Features.MoveToNamespace)] + [WorkItem(35577, "https://github.com/dotnet/roslyn/issues/35577")] + public async Task MoveToNamespace_WithoutOptionsService() + { + var code = @"namespace A[||] +{ +class MyClass +{ + void Method() { } +} +}"; + + var exportProviderWithoutOptionsService = ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithoutPartsOfType(typeof(IMoveToNamespaceOptionsService))); + + using (var workspace = CreateWorkspaceFromFile(code, new TestParameters(), exportProviderWithoutOptionsService)) + using (var testState = new TestState(workspace)) + { + Assert.Null(testState.TestMoveToNamespaceOptionsService); + + var actions = await testState.MoveToNamespaceService.GetCodeActionsAsync( + testState.InvocationDocument, + testState.TestInvocationDocument.SelectedSpans.Single(), + CancellationToken.None); + + Assert.Empty(actions); + } + } } } diff --git a/src/EditorFeatures/CSharpTest/UseCompoundAssignment/UseCompoundAssignmentTests.cs b/src/EditorFeatures/CSharpTest/UseCompoundAssignment/UseCompoundAssignmentTests.cs index 2a6cb320e04e2..0ec0a4812693c 100644 --- a/src/EditorFeatures/CSharpTest/UseCompoundAssignment/UseCompoundAssignmentTests.cs +++ b/src/EditorFeatures/CSharpTest/UseCompoundAssignment/UseCompoundAssignmentTests.cs @@ -251,6 +251,23 @@ void M(int? a) new TestParameters(parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7_3))); } + [Fact] + [WorkItem(36467, "https://github.com/dotnet/roslyn/issues/36467")] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseCompoundAssignment)] + public async Task TestNotSuggestedWhenRightHandIsThrowExpression() + { + await TestMissingAsync( +@"using System; +public class C +{ + void M(int? a) + { + a [||]= a ?? throw new Exception(); + } +}", + new TestParameters(parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8))); + } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseCompoundAssignment)] public async Task TestField() { 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/EditorFeatures/TestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.TestState.cs b/src/EditorFeatures/TestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.TestState.cs index 9bf45d18dfa8a..0d4d31fb3d3eb 100644 --- a/src/EditorFeatures/TestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.TestState.cs +++ b/src/EditorFeatures/TestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.TestState.cs @@ -27,7 +27,7 @@ public void Dispose() public Document InvocationDocument => Workspace.CurrentSolution.GetDocument(TestInvocationDocument.Id); public TestMoveToNamespaceOptionsService TestMoveToNamespaceOptionsService - => (TestMoveToNamespaceOptionsService)Workspace.Services.GetService(); + => (TestMoveToNamespaceOptionsService)MoveToNamespaceService.OptionsService; public IMoveToNamespaceService MoveToNamespaceService => InvocationDocument.GetLanguageService(); diff --git a/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs b/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs index 98d7eec8c8ce2..c25eb381951f5 100644 --- a/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs +++ b/src/EditorFeatures/TestUtilities/MoveToNamespace/TestMoveToNamespaceOptionsService.cs @@ -1,14 +1,13 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.MoveToNamespace; -using Microsoft.CodeAnalysis.Host.Mef; using System.Composition; namespace Microsoft.CodeAnalysis.Test.Utilities.MoveToNamespace { - [ExportWorkspaceService(typeof(IMoveToNamespaceOptionsService)), Shared] + [Export(typeof(IMoveToNamespaceOptionsService)), Shared] + [PartNotDiscoverable] class TestMoveToNamespaceOptionsService : IMoveToNamespaceOptionsService { internal static readonly MoveToNamespaceOptionsResult DefaultOptions = new MoveToNamespaceOptionsResult("TestNewNamespaceValue"); diff --git a/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs b/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs index bc61a2555685d..43cde39f7e42f 100644 --- a/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs +++ b/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs @@ -13,7 +13,10 @@ internal class CSharpMoveToNamespaceService : AbstractMoveToNamespaceService { [ImportingConstructor] - public CSharpMoveToNamespaceService() + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CSharpMoveToNamespaceService( + [Import(AllowDefault = true)] IMoveToNamespaceOptionsService optionsService) + : base(optionsService) { } 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/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs index 6e8dbe3791e1e..8dbacc64c46ef 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs @@ -12,7 +12,6 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.LanguageServices; -using System.Text; using System.Diagnostics; namespace Microsoft.CodeAnalysis.MoveToNamespace @@ -23,6 +22,7 @@ internal interface IMoveToNamespaceService : ILanguageService Task AnalyzeTypeAtPositionAsync(Document document, int position, CancellationToken cancellationToken); Task MoveToNamespaceAsync(MoveToNamespaceAnalysisResult analysisResult, string targetNamespace, CancellationToken cancellationToken); MoveToNamespaceOptionsResult GetChangeNamespaceOptions(Document document, string defaultNamespace, ImmutableArray namespaces); + IMoveToNamespaceOptionsService OptionsService { get; } } internal abstract class AbstractMoveToNamespaceService @@ -35,16 +35,28 @@ internal abstract class AbstractMoveToNamespaceService> GetCodeActionsAsync( Document document, TextSpan span, CancellationToken cancellationToken) { - var typeAnalysisResult = await AnalyzeTypeAtPositionAsync(document, span.Start, cancellationToken).ConfigureAwait(false); - - if (typeAnalysisResult.CanPerform) + // Code actions cannot be completed without the options needed + // to fill in missing information. + if (OptionsService != null) { - return ImmutableArray.Create(AbstractMoveToNamespaceCodeAction.Generate(this, typeAnalysisResult)); + var typeAnalysisResult = await AnalyzeTypeAtPositionAsync(document, span.Start, cancellationToken).ConfigureAwait(false); + + if (typeAnalysisResult.CanPerform) + { + return ImmutableArray.Create(AbstractMoveToNamespaceCodeAction.Generate(this, typeAnalysisResult)); + } } return ImmutableArray.Empty; @@ -237,14 +249,8 @@ public MoveToNamespaceOptionsResult GetChangeNamespaceOptions( ImmutableArray namespaces) { var syntaxFactsService = document.GetLanguageService(); - var moveToNamespaceOptionsService = document.Project.Solution.Workspace.Services.GetService(); - - if (moveToNamespaceOptionsService == null) - { - return MoveToNamespaceOptionsResult.Cancelled; - } - return moveToNamespaceOptionsService.GetChangeNamespaceOptions( + return OptionsService.GetChangeNamespaceOptions( defaultNamespace, namespaces, syntaxFactsService); diff --git a/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs b/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs index 9114a166f4a24..e9934d1806d92 100644 --- a/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs +++ b/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs @@ -19,8 +19,8 @@ public MoveToNamespaceCodeActionProvider() public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { - var service = context.Document.GetLanguageService(); - var actions = await service.GetCodeActionsAsync(context.Document, context.Span, context.CancellationToken).ConfigureAwait(false); + var moveToNamespaceService = context.Document.GetLanguageService(); + var actions = await moveToNamespaceService.GetCodeActionsAsync(context.Document, context.Span, context.CancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/Core/Portable/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs index 7e8fec4251587..e9f0c4f4b6a81 100644 --- a/src/Features/Core/Portable/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseCompoundAssignment/AbstractUseCompoundAssignmentDiagnosticAnalyzer.cs @@ -94,7 +94,7 @@ private void AnalyzeAssignment(SyntaxNodeAnalysisContext context) } _syntaxFacts.GetPartsOfBinaryExpression(binaryExpression, - out var binaryLeft, out _); + out var binaryLeft, out var binaryRight); // has to be of the form: expr = expr op ... if (!_syntaxFacts.AreEquivalent(assignmentLeft, binaryLeft)) @@ -109,6 +109,12 @@ private void AnalyzeAssignment(SyntaxNodeAnalysisContext context) return; } + // Don't offer if this is `x = x ?? throw new Exception()` + if (_syntaxFacts.IsThrowExpression(binaryRight)) + { + return; + } + // Syntactically looks promising. But we can only safely do this if 'expr' // is side-effect-free since we will be changing the number of times it is // executed from twice to once. diff --git a/src/VisualStudio/Core/Def/Implementation/MoveToNamespace/VisualStudioMoveToNamespaceOptionsService.cs b/src/VisualStudio/Core/Def/Implementation/MoveToNamespace/VisualStudioMoveToNamespaceOptionsService.cs index b567f1172c858..c4c44422d3542 100644 --- a/src/VisualStudio/Core/Def/Implementation/MoveToNamespace/VisualStudioMoveToNamespaceOptionsService.cs +++ b/src/VisualStudio/Core/Def/Implementation/MoveToNamespace/VisualStudioMoveToNamespaceOptionsService.cs @@ -2,13 +2,12 @@ using System.Collections.Immutable; using System.Composition; -using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.MoveToNamespace; namespace Microsoft.VisualStudio.LanguageServices.Implementation.MoveToNamespace { - [ExportWorkspaceService(typeof(IMoveToNamespaceOptionsService), layer: ServiceLayer.Host), Shared] + [Export(typeof(IMoveToNamespaceOptionsService)), Shared] internal class VisualStudioMoveToNamespaceOptionsService : IMoveToNamespaceOptionsService { [ImportingConstructor] 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 {