From 48f8854779e3f98f136ff5be20524db11edb53af Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Tue, 7 Feb 2017 13:35:15 -0800 Subject: [PATCH] Support ref-returns with GenerateMethod. --- ...EventHookupCommandHandler_TabKeyCommand.cs | 1 + .../GenerateMethod/GenerateMethodTests.cs | 28 +++++++++++++ .../NavigationBar/GenerateEventHandlerItem.vb | 1 + .../NavigationBar/GenerateFinalizerItem.vb | 1 + ...harpMethodExtractor.CSharpCodeGenerator.cs | 1 + .../CSharpGenerateConversionService.cs | 25 ++++++----- .../CSharpGenerateMethodService.cs | 22 +++------- ...SharpGenerateParameterizedMemberService.cs | 5 ++- ...AbstractPartialMethodCompletionProvider.cs | 1 + .../AbstractExtractInterfaceService.cs | 1 + .../AbstractGenerateMethodService.State.cs | 8 ++-- .../AbstractGenerateMethodService.cs | 2 +- ...erizedMemberService.MethodSignatureInfo.cs | 32 +++++---------- ...arameterizedMemberService.SignatureInfo.cs | 4 ++ ...ethodExtractor.VisualBasicCodeGenerator.vb | 1 + .../VisualBasicGenerateConversionService.vb | 31 +++++++------- .../VisualBasicGenerateMethodService.vb | 2 +- ...BasicGenerateParameterizedMemberService.vb | 6 ++- .../Venus/ContainedLanguageCodeSupport.cs | 1 + .../AbstractCodeModelObject_CodeGen.cs | 5 +++ ...CSharpTypeInferenceService.TypeInferrer.cs | 10 ++++- .../CodeGenerationSymbolFactory.cs | 41 +++++++++++++++++-- ...ionFactoryExtensions_CreateEqualsMethod.cs | 1 + ...ctoryExtensions_CreateGetHashCodeMethod.cs | 1 + .../Extensions/IMethodSymbolExtensions.cs | 6 ++- 25 files changed, 159 insertions(+), 78 deletions(-) diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs index 0da6c2af501..a2374b07fe8 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs @@ -277,6 +277,7 @@ private void GenerateAndAddEventHandler(ITextView textView, ITextBuffer subjectB accessibility: Accessibility.Private, modifiers: new DeclarationModifiers(isStatic: eventHookupExpression.IsInStaticContext()), returnType: delegateType.DelegateInvokeMethod.ReturnType, + returnsByRef: delegateType.DelegateInvokeMethod.ReturnsByRef, explicitInterfaceSymbol: null, name: eventHandlerMethodName, typeParameters: null, diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs index 73d6679a85c..361440fbe08 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs @@ -7358,6 +7358,34 @@ private object Issue(int i) { throw new NotImplementedException(); } +}"); + } + + [WorkItem(16398, "https://github.com/dotnet/roslyn/issues/16398")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] + public async Task TestRefReturnType1() + { + await TestAsync( +@"class Class +{ + void Method(int i) + { + ref int v = ref [|Issue|](i); + } +}", +@"using System; + +class Class +{ + void Method(int i) + { + ref int v = ref Issue(i); + } + + private ref int Issue(int i) + { + throw new NotImplementedException(); + } }"); } } diff --git a/src/EditorFeatures/VisualBasic/NavigationBar/GenerateEventHandlerItem.vb b/src/EditorFeatures/VisualBasic/NavigationBar/GenerateEventHandlerItem.vb index f94dd802c6a..92afa717ee2 100644 --- a/src/EditorFeatures/VisualBasic/NavigationBar/GenerateEventHandlerItem.vb +++ b/src/EditorFeatures/VisualBasic/NavigationBar/GenerateEventHandlerItem.vb @@ -55,6 +55,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar accessibility:=Accessibility.Private, modifiers:=New DeclarationModifiers(), returnType:=delegateInvokeMethod.ReturnType, + returnsByRef:=delegateInvokeMethod.ReturnsByRef, explicitInterfaceSymbol:=Nothing, name:=methodName, typeParameters:=Nothing, diff --git a/src/EditorFeatures/VisualBasic/NavigationBar/GenerateFinalizerItem.vb b/src/EditorFeatures/VisualBasic/NavigationBar/GenerateFinalizerItem.vb index 10d3b021c9f..89b12a9d63b 100644 --- a/src/EditorFeatures/VisualBasic/NavigationBar/GenerateFinalizerItem.vb +++ b/src/EditorFeatures/VisualBasic/NavigationBar/GenerateFinalizerItem.vb @@ -44,6 +44,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar accessibility:=Accessibility.Protected, modifiers:=New DeclarationModifiers(isOverride:=True), returnType:=compilation.GetSpecialType(SpecialType.System_Void), + returnsByRef:=False, explicitInterfaceSymbol:=Nothing, name:=WellKnownMemberNames.DestructorName, typeParameters:=Nothing, diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs index 4dc06018fd0..725008b269d 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs @@ -93,6 +93,7 @@ protected override OperationStatus GenerateMethodDefinition(Cance accessibility: Accessibility.Private, modifiers: CreateMethodModifiers(), returnType: this.AnalyzerResult.ReturnType, + returnsByRef: false, explicitInterfaceSymbol: null, name: _methodName.ToString(), typeParameters: CreateMethodTypeParameters(cancellationToken), diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs index d05bb3439f0..0550be1f52d 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs @@ -38,7 +38,8 @@ protected override bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol c return containingType.ContainingTypesOrSelfHasUnsafeKeyword(); } - protected override AbstractInvocationInfo CreateInvocationMethodInfo(SemanticDocument document, AbstractGenerateParameterizedMemberService.State state) + protected override AbstractInvocationInfo CreateInvocationMethodInfo( + SemanticDocument document, AbstractGenerateParameterizedMemberService.State state) { return new CSharpGenerateParameterizedMemberService.InvocationExpressionInfo(document, state); } @@ -196,7 +197,8 @@ protected override bool IsValidSymbol(ISymbol symbol, SemanticModel semanticMode return true; } - private static IMethodSymbol GenerateMethodSymbol(INamedTypeSymbol typeToGenerateIn, INamedTypeSymbol parameterSymbol) + private static IMethodSymbol GenerateMethodSymbol( + INamedTypeSymbol typeToGenerateIn, INamedTypeSymbol parameterSymbol) { // Remove any generic parameters if (typeToGenerateIn.IsGenericType) @@ -205,15 +207,16 @@ private static IMethodSymbol GenerateMethodSymbol(INamedTypeSymbol typeToGenerat } return CodeGenerationSymbolFactory.CreateMethodSymbol( - attributes: SpecializedCollections.EmptyList(), - accessibility: default(Accessibility), - modifiers: default(DeclarationModifiers), - returnType: typeToGenerateIn, - explicitInterfaceSymbol: null, - name: null, - typeParameters: SpecializedCollections.EmptyList(), - parameters: new[] { CodeGenerationSymbolFactory.CreateParameterSymbol(parameterSymbol, "v") }, - methodKind: MethodKind.Conversion); + attributes: SpecializedCollections.EmptyList(), + accessibility: default(Accessibility), + modifiers: default(DeclarationModifiers), + returnType: typeToGenerateIn, + returnsByRef: false, + explicitInterfaceSymbol: null, + name: null, + typeParameters: SpecializedCollections.EmptyList(), + parameters: new[] { CodeGenerationSymbolFactory.CreateParameterSymbol(parameterSymbol, "v") }, + methodKind: MethodKind.Conversion); } protected override string GetImplicitConversionDisplayText(AbstractGenerateParameterizedMemberService.State state) diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs index e20a5b24058..86108a242f3 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateMethodService.cs @@ -21,19 +21,13 @@ internal partial class CSharpGenerateMethodService : AbstractGenerateMethodService { protected override bool IsExplicitInterfaceGeneration(SyntaxNode node) - { - return node is MethodDeclarationSyntax; - } + => node is MethodDeclarationSyntax; protected override bool IsSimpleNameGeneration(SyntaxNode node) - { - return node is SimpleNameSyntax; - } + => node is SimpleNameSyntax; protected override bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol containingType) - { - return containingType.ContainingTypesOrSelfHasUnsafeKeyword(); - } + => containingType.ContainingTypesOrSelfHasUnsafeKeyword(); protected override AbstractInvocationInfo CreateInvocationMethodInfo(SemanticDocument document, AbstractGenerateParameterizedMemberService.State state) { @@ -41,14 +35,10 @@ protected override AbstractInvocationInfo CreateInvocationMethodInfo(SemanticDoc } protected override bool AreSpecialOptionsActive(SemanticModel semanticModel) - { - return CSharpCommonGenerationServiceMethods.AreSpecialOptionsActive(semanticModel); - } + => CSharpCommonGenerationServiceMethods.AreSpecialOptionsActive(semanticModel); protected override bool IsValidSymbol(ISymbol symbol, SemanticModel semanticModel) - { - return CSharpCommonGenerationServiceMethods.IsValidSymbol(symbol, semanticModel); - } + => CSharpCommonGenerationServiceMethods.IsValidSymbol(symbol, semanticModel); protected override bool TryInitializeExplicitInterfaceState( SemanticDocument document, @@ -154,7 +144,7 @@ protected override bool IsValidSymbol(ISymbol symbol, SemanticModel semanticMode return false; } - protected override ITypeSymbol CanGenerateMethodForSimpleNameOrMemberAccessExpression( + protected override ITypeSymbol DetermineReturnTypeForSimpleNameOrMemberAccessExpression( ITypeInferenceService typeInferenceService, SemanticModel semanticModel, ExpressionSyntax expression, diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs index aaf2c1578a9..0e4c2d2f24a 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs @@ -36,11 +36,14 @@ protected override IList DetermineParameterNames(CancellationToke _invocationExpression.ArgumentList); } + protected override bool DetermineReturnsByRef(CancellationToken cancellationToken) + => _invocationExpression.IsParentKind(SyntaxKind.RefExpression); + protected override ITypeSymbol DetermineReturnTypeWorker(CancellationToken cancellationToken) { // Defer to the type inferrer to figure out what the return type of this new method // should be. - var typeInference = this.Document.Project.LanguageServices.GetService(); + var typeInference = this.Document.Document.GetLanguageService(); var inferredType = typeInference.InferType( this.Document.SemanticModel, _invocationExpression, objectAsDefault: true, nameOpt: this.State.IdentifierToken.ValueText, cancellationToken: cancellationToken); diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs index 9441e82afca..b0a026fbb46 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs @@ -65,6 +65,7 @@ protected override async Task GenerateMemberAsync(ISymbol member, IName accessibility: Accessibility.NotApplicable, modifiers: MemberInsertionCompletionItem.GetModifiers(item), returnType: semanticModel.Compilation.GetSpecialType(SpecialType.System_Void), + returnsByRef: false, explicitInterfaceSymbol: null, name: member.Name, typeParameters: ((IMethodSymbol)member).TypeParameters, diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index 9480c36b5f7..a9cb2a66e5f 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -347,6 +347,7 @@ private IList CreateInterfaceMembers(IEnumerable includedMembe accessibility: Accessibility.Public, modifiers: new DeclarationModifiers(isAbstract: true, isUnsafe: method.IsUnsafe()), returnType: method.ReturnType, + returnsByRef: method.ReturnsByRef, explicitInterfaceSymbol: null, name: method.Name, typeParameters: method.TypeParameters, diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs index 065e55fa165..265e737f60f 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs @@ -150,7 +150,7 @@ internal new class State : AbstractGenerateParameterizedMemberService(); + var typeInference = document.Document.GetLanguageService(); var delegateType = typeInference.InferDelegateType(semanticModel, this.SimpleNameOrMemberAccessExpression, cancellationToken); if (delegateType != null && delegateType.DelegateInvokeMethod != null) { @@ -160,7 +160,7 @@ internal new class State : AbstractGenerateParameterizedMemberService(), accessibility: default(Accessibility), modifiers: default(DeclarationModifiers), returnType: expressionType, + returnsByRef: false, explicitInterfaceSymbol: null, name: null, typeParameters: SpecializedCollections.EmptyList(), diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs index 02da4ef7d57..7ae900e0aa4 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs @@ -22,7 +22,7 @@ internal abstract partial class AbstractGenerateMethodService> GenerateMethodAsync( Document document, diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.MethodSignatureInfo.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.MethodSignatureInfo.cs index b6ab90028e7..b469f00b785 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.MethodSignatureInfo.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.MethodSignatureInfo.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Utilities; using Roslyn.Utilities; @@ -27,36 +26,27 @@ protected class MethodSignatureInfo : SignatureInfo protected override ITypeSymbol DetermineReturnTypeWorker(CancellationToken cancellationToken) => _methodSymbol.ReturnType; + protected override bool DetermineReturnsByRef(CancellationToken cancellationToken) + => _methodSymbol.ReturnsByRef; + protected override IList DetermineTypeParametersWorker(CancellationToken cancellationToken) - { - return _methodSymbol.TypeParameters; - } + => _methodSymbol.TypeParameters; protected override IList DetermineParameterModifiers(CancellationToken cancellationToken) - { - return _methodSymbol.Parameters.Select(p => p.RefKind).ToList(); - } + => _methodSymbol.Parameters.Select(p => p.RefKind).ToList(); protected override IList DetermineParameterOptionality(CancellationToken cancellationToken) - { - return _methodSymbol.Parameters.Select(p => p.IsOptional).ToList(); - } + => _methodSymbol.Parameters.Select(p => p.IsOptional).ToList(); protected override IList DetermineParameterTypes(CancellationToken cancellationToken) - { - return _methodSymbol.Parameters.Select(p => p.Type).ToList(); - } + => _methodSymbol.Parameters.Select(p => p.Type).ToList(); protected override IList DetermineParameterNames(CancellationToken cancellationToken) - { - return _methodSymbol.Parameters.Select(p => new ParameterName(p.Name, isFixed: true)) - .ToList(); - } + => _methodSymbol.Parameters.Select(p => new ParameterName(p.Name, isFixed: true)) + .ToList(); protected override IList DetermineTypeArguments(CancellationToken cancellationToken) - { - return SpecializedCollections.EmptyList(); - } + => SpecializedCollections.EmptyList(); } } -} +} \ No newline at end of file diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs index 0dc5403bce6..c01caab34c1 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs @@ -53,6 +53,7 @@ public ITypeSymbol DetermineReturnType(CancellationToken cancellationToken) protected abstract IList DetermineTypeArguments(CancellationToken cancellationToken); protected abstract ITypeSymbol DetermineReturnTypeWorker(CancellationToken cancellationToken); + protected abstract bool DetermineReturnsByRef(CancellationToken cancellationToken); protected abstract IList DetermineParameterModifiers(CancellationToken cancellationToken); protected abstract IList DetermineParameterTypes(CancellationToken cancellationToken); protected abstract IList DetermineParameterOptionality(CancellationToken cancellationToken); @@ -90,6 +91,8 @@ public ITypeSymbol DetermineReturnType(CancellationToken cancellationToken) { var parameters = DetermineParameters(cancellationToken); var returnType = DetermineReturnType(cancellationToken); + var returnsByRef = DetermineReturnsByRef(cancellationToken); + var isUnsafe = (parameters .Any(p => p.Type.IsUnsafe()) || returnType.IsUnsafe()) && !State.IsContainedInUnsafeType; @@ -98,6 +101,7 @@ public ITypeSymbol DetermineReturnType(CancellationToken cancellationToken) accessibility: DetermineAccessibility(isAbstract), modifiers: new DeclarationModifiers(isStatic: State.IsStatic, isAbstract: isAbstract, isUnsafe: isUnsafe), returnType: returnType, + returnsByRef: returnsByRef, explicitInterfaceSymbol: null, name: this.State.IdentifierToken.ValueText, typeParameters: DetermineTypeParameters(cancellationToken), diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb index 32f45dc5d4f..d1d31abadbe 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb @@ -66,6 +66,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod accessibility:=Accessibility.Private, modifiers:=CreateMethodModifiers(), returnType:=Me.AnalyzerResult.ReturnType, + returnsByRef:=False, explicitInterfaceSymbol:=Nothing, name:=_methodName.ToString(), typeParameters:=CreateMethodTypeParameters(cancellationToken), diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb index 0a325d4b04a..b6c8a64d5b6 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb @@ -8,7 +8,6 @@ Imports Microsoft.CodeAnalysis.GenerateMember.GenerateParameterizedMember Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.VisualBasic.Syntax - Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Partial Friend Class VisualBasicGenerateConversionService @@ -138,18 +137,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod typeToGenerateIn = typeToGenerateIn.ConstructUnboundGenericType.ConstructedFrom End If Return CodeGenerationSymbolFactory.CreateMethodSymbol( - attributes:=SpecializedCollections.EmptyList(Of AttributeData), - accessibility:=Nothing, - modifiers:=Nothing, - returnType:=typeToGenerateIn, - explicitInterfaceSymbol:=Nothing, - name:=Nothing, - typeParameters:=SpecializedCollections.EmptyList(Of ITypeParameterSymbol), - parameters:={CodeGenerationSymbolFactory.CreateParameterSymbol(parameterSymbol, "v")}, - statements:=Nothing, - handlesExpressions:=Nothing, - returnTypeAttributes:=Nothing, - methodKind:=MethodKind.Conversion) + attributes:=SpecializedCollections.EmptyList(Of AttributeData), + accessibility:=Nothing, + modifiers:=Nothing, + returnType:=typeToGenerateIn, + returnsByRef:=False, + explicitInterfaceSymbol:=Nothing, + name:=Nothing, + typeParameters:=SpecializedCollections.EmptyList(Of ITypeParameterSymbol), + parameters:={CodeGenerationSymbolFactory.CreateParameterSymbol(parameterSymbol, "v")}, + statements:=Nothing, + handlesExpressions:=Nothing, + returnTypeAttributes:=Nothing, + methodKind:=MethodKind.Conversion) End Function Protected Overrides Function GetExplicitConversionDisplayText(state As AbstractGenerateParameterizedMemberService(Of VisualBasicGenerateConversionService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax).State) As String @@ -160,7 +160,4 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Return String.Format(VBFeaturesResources.Generate_widening_conversion_in_0, state.TypeToGenerateIn.Name) End Function End Class -End Namespace - - - +End Namespace \ No newline at end of file diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb index ee50d980595..1884ccd8101 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateMethodService.vb @@ -152,7 +152,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Return New VisualBasicGenerateParameterizedMemberService(Of VisualBasicGenerateMethodService).InvocationExpressionInfo(document, state) End Function - Protected Overrides Function CanGenerateMethodForSimpleNameOrMemberAccessExpression(typeInferenceService As ITypeInferenceService, semanticModel As SemanticModel, expression As ExpressionSyntax, cancellationToken As CancellationToken) As ITypeSymbol + Protected Overrides Function DetermineReturnTypeForSimpleNameOrMemberAccessExpression(typeInferenceService As ITypeInferenceService, semanticModel As SemanticModel, expression As ExpressionSyntax, cancellationToken As CancellationToken) As ITypeSymbol Return typeInferenceService.InferType(semanticModel, expression, True, cancellationToken) End Function End Class diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb index b6958b17f21..77063fd53dd 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb @@ -30,8 +30,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Me.InvocationExpression.ArgumentList, reservedNames:=typeParametersNames) End Function + Protected Overrides Function DetermineReturnsByRef(cancellationToken As CancellationToken) As Boolean + Return False + End Function + Protected Overrides Function DetermineReturnTypeWorker(cancellationToken As CancellationToken) As ITypeSymbol - Select Case CType(Me.State.IdentifierToken, SyntaxToken).GetTypeCharacter() + Select Case Me.State.IdentifierToken.GetTypeCharacter() Case TypeCharacter.Integer Return Me.Document.SemanticModel.Compilation.GetSpecialType(SpecialType.System_Int32) Case TypeCharacter.Long diff --git a/src/VisualStudio/Core/Def/Implementation/Venus/ContainedLanguageCodeSupport.cs b/src/VisualStudio/Core/Def/Implementation/Venus/ContainedLanguageCodeSupport.cs index da3a293e237..a17b6b33592 100644 --- a/src/VisualStudio/Core/Def/Implementation/Venus/ContainedLanguageCodeSupport.cs +++ b/src/VisualStudio/Core/Def/Implementation/Venus/ContainedLanguageCodeSupport.cs @@ -187,6 +187,7 @@ public static string GetEventHandlerMemberId(Document document, string className accessibility: Accessibility.Protected, modifiers: new DeclarationModifiers(), returnType: targetDocument.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult_Venus(cancellationToken).GetSpecialType(SpecialType.System_Void), + returnsByRef: false, explicitInterfaceSymbol: null, name: eventHandlerName, typeParameters: null, diff --git a/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelObject_CodeGen.cs b/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelObject_CodeGen.cs index 1ff77454b9f..199155187bb 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelObject_CodeGen.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelObject_CodeGen.cs @@ -80,6 +80,7 @@ protected SyntaxNode CreateEventDeclaration(SyntaxNode containerNode, string nam accessibility: Accessibility.NotApplicable, modifiers: new DeclarationModifiers(), returnType: null, + returnsByRef: false, explicitInterfaceSymbol: null, name: "add_" + name, typeParameters: null, @@ -90,6 +91,7 @@ protected SyntaxNode CreateEventDeclaration(SyntaxNode containerNode, string nam accessibility: Accessibility.NotApplicable, modifiers: new DeclarationModifiers(), returnType: null, + returnsByRef: false, explicitInterfaceSymbol: null, name: "remove_" + name, typeParameters: null, @@ -136,6 +138,7 @@ protected SyntaxNode CreateMethodDeclaration(SyntaxNode containerNode, string na accessibility: CodeModelService.GetAccessibility(access, SymbolKind.Method, destination), modifiers: new DeclarationModifiers(), returnType: returnType, + returnsByRef: false, explicitInterfaceSymbol: null, name: name, typeParameters: null, @@ -158,6 +161,7 @@ protected SyntaxNode CreatePropertyDeclaration(SyntaxNode containerNode, string accessibility: Accessibility.NotApplicable, modifiers: new DeclarationModifiers(), returnType: null, + returnsByRef: false, explicitInterfaceSymbol: null, name: "get_" + name, typeParameters: null, @@ -173,6 +177,7 @@ protected SyntaxNode CreatePropertyDeclaration(SyntaxNode containerNode, string accessibility: Accessibility.NotApplicable, modifiers: new DeclarationModifiers(), returnType: null, + returnsByRef: false, explicitInterfaceSymbol: null, name: "set_" + name, typeParameters: null, diff --git a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index 7d621a56e4f..d41bc46d500 100644 --- a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -87,7 +87,11 @@ private IEnumerable GetTypesComplex(ExpressionSyntax expressi private IEnumerable GetTypesSimple(ExpressionSyntax expression) { - if (expression != null) + if (expression is RefTypeSyntax refType) + { + return GetTypes(refType.Type); + } + else if (expression != null) { var typeInfo = SemanticModel.GetTypeInfo(expression, CancellationToken); var symbolInfo = SemanticModel.GetSymbolInfo(expression, CancellationToken); @@ -154,6 +158,7 @@ private IEnumerable GetTypesSimple(ExpressionSyntax expressio case ParenthesizedLambdaExpressionSyntax parenthesizedLambdaExpression: return InferTypeInParenthesizedLambdaExpression(parenthesizedLambdaExpression); case PostfixUnaryExpressionSyntax postfixUnary: return InferTypeInPostfixUnaryExpression(postfixUnary); case PrefixUnaryExpressionSyntax prefixUnary: return InferTypeInPrefixUnaryExpression(prefixUnary); + case RefExpressionSyntax refExpression: return InferTypeInRefExpression(refExpression); case ReturnStatementSyntax returnStatement: return InferTypeForReturnStatement(returnStatement); case SimpleLambdaExpressionSyntax simpleLambdaExpression: return InferTypeInSimpleLambdaExpression(simpleLambdaExpression); case SwitchLabelSyntax switchLabel: return InferTypeInSwitchLabel(switchLabel); @@ -1802,6 +1807,9 @@ private static ITypeSymbol GetMemberType(ISymbol memberSymbol) return null; } + private IEnumerable InferTypeInRefExpression(RefExpressionSyntax refExpression) + => InferTypes(refExpression); + private IEnumerable InferTypeForReturnStatement(ReturnStatementSyntax returnStatement, SyntaxToken? previousToken = null) { InferTypeForReturnStatement(returnStatement, previousToken, diff --git a/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationSymbolFactory.cs b/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationSymbolFactory.cs index 7daf69852c1..1710dee4571 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationSymbolFactory.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/CodeGenerationSymbolFactory.cs @@ -116,7 +116,21 @@ public static IMethodSymbol CreateDestructorSymbol(IList attribut return result; } - internal static IMethodSymbol CreateMethodSymbol(INamedTypeSymbol containingType, IList attributes, Accessibility accessibility, DeclarationModifiers modifiers, ITypeSymbol returnType, IMethodSymbol explicitInterfaceSymbol, string name, IList typeParameters, IList parameters, IList statements = null, IList handlesExpressions = null, IList returnTypeAttributes = null, MethodKind methodKind = MethodKind.Ordinary, bool returnsByRef = false) + internal static IMethodSymbol CreateMethodSymbol( + INamedTypeSymbol containingType, + IList attributes, + Accessibility accessibility, + DeclarationModifiers modifiers, + ITypeSymbol returnType, + bool returnsByRef, + IMethodSymbol explicitInterfaceSymbol, + string name, + IList typeParameters, + IList parameters, + IList statements = null, + IList handlesExpressions = null, + IList returnTypeAttributes = null, + MethodKind methodKind = MethodKind.Ordinary) { var result = new CodeGenerationMethodSymbol(containingType, attributes, accessibility, modifiers, returnType, returnsByRef, explicitInterfaceSymbol, name, typeParameters, parameters, returnTypeAttributes, methodKind); CodeGenerationMethodInfo.Attach(result, modifiers.IsNew, modifiers.IsUnsafe, modifiers.IsPartial, modifiers.IsAsync, statements, handlesExpressions); @@ -126,9 +140,25 @@ internal static IMethodSymbol CreateMethodSymbol(INamedTypeSymbol containingType /// /// Creates a method symbol that can be used to describe a method declaration. /// - public static IMethodSymbol CreateMethodSymbol(IList attributes, Accessibility accessibility, DeclarationModifiers modifiers, ITypeSymbol returnType, IMethodSymbol explicitInterfaceSymbol, string name, IList typeParameters, IList parameters, IList statements = null, IList handlesExpressions = null, IList returnTypeAttributes = null, MethodKind methodKind = MethodKind.Ordinary) + public static IMethodSymbol CreateMethodSymbol( + IList attributes, + Accessibility accessibility, + DeclarationModifiers modifiers, + ITypeSymbol returnType, + bool returnsByRef, + IMethodSymbol explicitInterfaceSymbol, + string name, + IList typeParameters, + IList parameters, + IList statements = null, + IList handlesExpressions = null, + IList returnTypeAttributes = null, + MethodKind methodKind = MethodKind.Ordinary) { - return CreateMethodSymbol(null, attributes, accessibility, modifiers, returnType, explicitInterfaceSymbol, name, typeParameters, parameters, statements, handlesExpressions, returnTypeAttributes, methodKind); + return CreateMethodSymbol( + null, attributes, accessibility, modifiers, returnType, returnsByRef, + explicitInterfaceSymbol, name, typeParameters, parameters, + statements, handlesExpressions, returnTypeAttributes, methodKind); } /// @@ -223,6 +253,7 @@ public static IArrayTypeSymbol CreateArrayTypeSymbol(ITypeSymbol elementType, in accessibility ?? accessor.DeclaredAccessibility, accessor.GetSymbolModifiers().WithIsAbstract(statements == null), accessor.ReturnType, + false, explicitInterfaceSymbol ?? accessor.ExplicitInterfaceImplementations.FirstOrDefault(), accessor.Name, accessor.TypeParameters, @@ -243,7 +274,7 @@ public static IArrayTypeSymbol CreateArrayTypeSymbol(ITypeSymbol elementType, in attributes, accessibility, new DeclarationModifiers(isAbstract: statements == null), - null, null, + null, false, null, string.Empty, null, null, statements: statements); @@ -292,6 +323,7 @@ public static INamedTypeSymbol CreateNamedTypeSymbol(IList attrib accessibility: Accessibility.Public, modifiers: new DeclarationModifiers(), returnType: returnType, + returnsByRef: false, explicitInterfaceSymbol: null, name: "Invoke", typeParameters: null, @@ -337,6 +369,7 @@ public static INamespaceSymbol CreateNamespaceSymbol(string name, IList accessibility ?? method.DeclaredAccessibility, modifiers ?? method.GetSymbolModifiers(), method.ReturnType, + method.ReturnsByRef, explicitInterfaceSymbol, name ?? method.Name, method.TypeParameters, diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateEqualsMethod.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateEqualsMethod.cs index 249e2742a69..050e25f2780 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateEqualsMethod.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateEqualsMethod.cs @@ -31,6 +31,7 @@ internal static partial class ICodeDefinitionFactoryExtensions accessibility: Accessibility.Public, modifiers: new DeclarationModifiers(isOverride: true), returnType: compilation.GetSpecialType(SpecialType.System_Boolean), + returnsByRef: false, explicitInterfaceSymbol: null, name: EqualsName, typeParameters: null, diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateGetHashCodeMethod.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateGetHashCodeMethod.cs index 1f8c280be4e..41a08d74c66 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateGetHashCodeMethod.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ICodeDefinitionFactoryExtensions_CreateGetHashCodeMethod.cs @@ -25,6 +25,7 @@ internal static partial class ICodeDefinitionFactoryExtensions accessibility: Accessibility.Public, modifiers: new DeclarationModifiers(isOverride: true), returnType: compilation.GetSpecialType(SpecialType.System_Int32), + returnsByRef: false, explicitInterfaceSymbol: null, name: GetHashCodeName, typeParameters: null, diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/IMethodSymbolExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/IMethodSymbolExtensions.cs index 491c8acef82..48aa51b392e 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/IMethodSymbolExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/IMethodSymbolExtensions.cs @@ -76,6 +76,7 @@ public static IMethodSymbol RenameTypeParameters(this IMethodSymbol method, ILis method.DeclaredAccessibility, method.GetSymbolModifiers(), method.ReturnType.SubstituteTypes(mapping, typeGenerator), + method.ReturnsByRef, method.ExplicitInterfaceImplementations.FirstOrDefault(), method.Name, updatedTypeParameters, @@ -84,7 +85,8 @@ public static IMethodSymbol RenameTypeParameters(this IMethodSymbol method, ILis p.HasExplicitDefaultValue, p.HasExplicitDefaultValue ? p.ExplicitDefaultValue : null)).ToList()); } - public static IMethodSymbol RenameParameters(this IMethodSymbol method, IList parameterNames) + public static IMethodSymbol RenameParameters( + this IMethodSymbol method, IList parameterNames) { var parameterList = method.Parameters; if (parameterList.Select(p => p.Name).SequenceEqual(parameterNames)) @@ -100,6 +102,7 @@ public static IMethodSymbol RenameParameters(this IMethodSymbol method, IList