提交 f09e6d9e 编写于 作者: C CyrusNajmabadi

Merge branch 'generateMethodRefReturns2' into generateMethodRefReturns

......@@ -7361,6 +7361,7 @@ private object Issue(int i)
}");
}
[WorkItem(16398, "https://github.com/dotnet/roslyn/issues/16398")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)]
public async Task TestReturnsByRef()
{
......
......@@ -38,7 +38,8 @@ protected override bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol c
return containingType.ContainingTypesOrSelfHasUnsafeKeyword();
}
protected override AbstractInvocationInfo CreateInvocationMethodInfo(SemanticDocument document, AbstractGenerateParameterizedMemberService<CSharpGenerateConversionService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax>.State state)
protected override AbstractInvocationInfo CreateInvocationMethodInfo(
SemanticDocument document, AbstractGenerateParameterizedMemberService<CSharpGenerateConversionService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax>.State state)
{
return new CSharpGenerateParameterizedMemberService<CSharpGenerateConversionService>.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,16 +207,16 @@ private static IMethodSymbol GenerateMethodSymbol(INamedTypeSymbol typeToGenerat
}
return CodeGenerationSymbolFactory.CreateMethodSymbol(
attributes: SpecializedCollections.EmptyList<AttributeData>(),
accessibility: default(Accessibility),
modifiers: default(DeclarationModifiers),
returnType: typeToGenerateIn,
returnsByRef: false,
explicitInterfaceSymbol: null,
name: null,
typeParameters: SpecializedCollections.EmptyList<ITypeParameterSymbol>(),
parameters: new[] { CodeGenerationSymbolFactory.CreateParameterSymbol(parameterSymbol, "v") },
methodKind: MethodKind.Conversion);
attributes: SpecializedCollections.EmptyList<AttributeData>(),
accessibility: default(Accessibility),
modifiers: default(DeclarationModifiers),
returnType: typeToGenerateIn,
returnsByRef: false,
explicitInterfaceSymbol: null,
name: null,
typeParameters: SpecializedCollections.EmptyList<ITypeParameterSymbol>(),
parameters: new[] { CodeGenerationSymbolFactory.CreateParameterSymbol(parameterSymbol, "v") },
methodKind: MethodKind.Conversion);
}
protected override string GetImplicitConversionDisplayText(AbstractGenerateParameterizedMemberService<CSharpGenerateConversionService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax>.State state)
......
......@@ -21,19 +21,13 @@ internal partial class CSharpGenerateMethodService :
AbstractGenerateMethodService<CSharpGenerateMethodService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax>
{
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<CSharpGenerateMethodService, SimpleNameSyntax, ExpressionSyntax, InvocationExpressionSyntax>.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,
......
......@@ -37,20 +37,20 @@ protected override ImmutableArray<ParameterName> DetermineParameterNames(Cancell
_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<ITypeInferenceService>();
var typeInference = this.Document.Document.GetLanguageService<ITypeInferenceService>();
var inferredType = typeInference.InferType(
this.Document.SemanticModel, _invocationExpression, objectAsDefault: true,
nameOpt: this.State.IdentifierToken.ValueText, cancellationToken: cancellationToken);
return inferredType;
}
protected override bool DetermineReturnsByRef()
=> _invocationExpression.IsParentKind(SyntaxKind.RefExpression);
protected override ImmutableArray<ITypeParameterSymbol> GetCapturedTypeParameters(CancellationToken cancellationToken)
{
var result = new List<ITypeParameterSymbol>();
......
......@@ -150,7 +150,7 @@ internal new class State : AbstractGenerateParameterizedMemberService<TService,
}
else
{
var typeInference = document.Project.LanguageServices.GetService<ITypeInferenceService>();
var typeInference = document.Document.GetLanguageService<ITypeInferenceService>();
var delegateType = typeInference.InferDelegateType(semanticModel, this.SimpleNameOrMemberAccessExpression, cancellationToken);
if (delegateType != null && delegateType.DelegateInvokeMethod != null)
{
......@@ -160,7 +160,7 @@ internal new class State : AbstractGenerateParameterizedMemberService<TService,
{
// We don't have and invocation expression or a delegate, but we may have a special expression without parenthesis. Lets see
// if the type inference service can directly infer the type for our expression.
var expressionType = service.CanGenerateMethodForSimpleNameOrMemberAccessExpression(typeInference, semanticModel, this.SimpleNameOrMemberAccessExpression, cancellationToken);
var expressionType = service.DetermineReturnTypeForSimpleNameOrMemberAccessExpression(typeInference, semanticModel, this.SimpleNameOrMemberAccessExpression, cancellationToken);
if (expressionType == null)
{
return false;
......@@ -212,7 +212,8 @@ internal new class State : AbstractGenerateParameterizedMemberService<TService,
return true;
}
private static IMethodSymbol CreateMethodSymbolWithReturnType(ITypeSymbol expressionType)
private static IMethodSymbol CreateMethodSymbolWithReturnType(
ITypeSymbol expressionType)
{
return CodeGenerationSymbolFactory.CreateMethodSymbol(
attributes: SpecializedCollections.EmptyList<AttributeData>(),
......
......@@ -22,7 +22,7 @@ internal abstract partial class AbstractGenerateMethodService<TService, TSimpleN
protected abstract bool IsExplicitInterfaceGeneration(SyntaxNode node);
protected abstract bool TryInitializeExplicitInterfaceState(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken, out SyntaxToken identifierToken, out IMethodSymbol methodSymbol, out INamedTypeSymbol typeToGenerateIn);
protected abstract bool TryInitializeSimpleNameState(SemanticDocument document, TSimpleNameSyntax simpleName, CancellationToken cancellationToken, out SyntaxToken identifierToken, out TExpressionSyntax simpleNameOrMemberAccessExpression, out TInvocationExpressionSyntax invocationExpressionOpt, out bool isInConditionalExpression);
protected abstract ITypeSymbol CanGenerateMethodForSimpleNameOrMemberAccessExpression(ITypeInferenceService typeInferenceService, SemanticModel semanticModel, TExpressionSyntax expression, CancellationToken cancellationToken);
protected abstract ITypeSymbol DetermineReturnTypeForSimpleNameOrMemberAccessExpression(ITypeInferenceService typeInferenceService, SemanticModel semanticModel, TExpressionSyntax expression, CancellationToken cancellationToken);
public async Task<ImmutableArray<CodeAction>> GenerateMethodAsync(
Document document,
......
......@@ -26,7 +26,7 @@ protected class MethodSignatureInfo : SignatureInfo
protected override ITypeSymbol DetermineReturnTypeWorker(CancellationToken cancellationToken)
=> _methodSymbol.ReturnType;
protected override bool DetermineReturnsByRef()
protected override bool DetermineReturnsByRef(CancellationToken cancellationToken)
=> _methodSymbol.ReturnsByRef;
protected override ImmutableArray<ITypeParameterSymbol> DetermineTypeParametersWorker(CancellationToken cancellationToken)
......
......@@ -41,7 +41,7 @@ public ImmutableArray<ITypeParameterSymbol> DetermineTypeParameters(Cancellation
}
protected abstract ImmutableArray<ITypeParameterSymbol> DetermineTypeParametersWorker(CancellationToken cancellationToken);
protected abstract bool DetermineReturnsByRef();
protected abstract bool DetermineReturnsByRef(CancellationToken cancellationToken);
public ITypeSymbol DetermineReturnType(CancellationToken cancellationToken)
{
......@@ -79,7 +79,7 @@ public ITypeSymbol DetermineReturnType(CancellationToken cancellationToken)
accessibility: accessibility,
modifiers: new DeclarationModifiers(isStatic: State.IsStatic, isAbstract: isAbstract),
type: DetermineReturnType(cancellationToken),
returnsByRef: DetermineReturnsByRef(),
returnsByRef: DetermineReturnsByRef(cancellationToken),
explicitInterfaceSymbol: null,
name: this.State.IdentifierToken.ValueText,
parameters: DetermineParameters(cancellationToken),
......@@ -100,12 +100,14 @@ public ITypeSymbol DetermineReturnType(CancellationToken cancellationToken)
isUnsafe = returnType.IsUnsafe() || parameters.Any(p => p.Type.IsUnsafe());
}
var returnsByRef = DetermineReturnsByRef(cancellationToken);
var method = CodeGenerationSymbolFactory.CreateMethodSymbol(
attributes: null,
accessibility: DetermineAccessibility(isAbstract),
modifiers: new DeclarationModifiers(isStatic: State.IsStatic, isAbstract: isAbstract, isUnsafe: isUnsafe),
returnType: returnType,
returnsByRef: DetermineReturnsByRef(),
returnsByRef: returnsByRef,
explicitInterfaceSymbol: null,
name: this.State.IdentifierToken.ValueText,
typeParameters: DetermineTypeParameters(cancellationToken),
......
......@@ -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
<ExportLanguageService(GetType(IGenerateConversionService), LanguageNames.VisualBasic), [Shared]>
Partial Friend Class VisualBasicGenerateConversionService
......@@ -138,19 +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,
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)
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
......@@ -161,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
......@@ -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
......
......@@ -31,12 +31,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod
Me.InvocationExpression.ArgumentList, reservedNames:=typeParametersNames)
End Function
Protected Overrides Function DetermineReturnsByRef() As Boolean
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
......
......@@ -87,7 +87,11 @@ private IEnumerable<TypeInferenceInfo> GetTypesComplex(ExpressionSyntax expressi
private IEnumerable<TypeInferenceInfo> 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);
......@@ -1804,9 +1808,7 @@ private static ITypeSymbol GetMemberType(ISymbol memberSymbol)
}
private IEnumerable<TypeInferenceInfo> InferTypeInRefExpression(RefExpressionSyntax refExpression)
{
return InferTypes(refExpression);
}
=> InferTypes(refExpression);
private IEnumerable<TypeInferenceInfo> InferTypeForReturnStatement(ReturnStatementSyntax returnStatement, SyntaxToken? previousToken = null)
{
......
......@@ -85,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<string> parameterNames)
public static IMethodSymbol RenameParameters(
this IMethodSymbol method, IList<string> parameterNames)
{
var parameterList = method.Parameters;
if (parameterList.Select(p => p.Name).SequenceEqual(parameterNames))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册