提交 85ec5300 编写于 作者: G Gen Lu

Make InConversion and OutConversion CommonConversion

上级 77260eb5
// 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 Microsoft.CodeAnalysis.Semantics;
namespace Microsoft.CodeAnalysis.CSharp
{
internal abstract class BaseCSharpArgument : BaseArgument, IArgument
{
public BaseCSharpArgument(ArgumentKind argumentKind, IParameterSymbol parameter, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(argumentKind, parameter, semanticModel, syntax, type, constantValue)
{
}
public override CommonConversion InConversion => default(CommonConversion);
public override CommonConversion OutConversion => default(CommonConversion);
}
internal sealed partial class CSharpArgument : BaseCSharpArgument
{
public CSharpArgument(ArgumentKind argumentKind, IParameterSymbol parameter, IOperation value, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(argumentKind, parameter, semanticModel, syntax, type, constantValue)
{
ValueImpl = value;
}
protected override IOperation ValueImpl { get; }
}
internal sealed partial class LazyCSharpArgument : BaseCSharpArgument
{
private readonly Lazy<IOperation> _lazyValue;
public LazyCSharpArgument(ArgumentKind argumentKind, IParameterSymbol parameter, Lazy<IOperation> value, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(argumentKind, parameter, semanticModel, syntax, type, constantValue)
{
_lazyValue = value ?? throw new ArgumentNullException(nameof(value));
}
protected override IOperation ValueImpl => _lazyValue.Value;
}
}
......@@ -8,6 +8,11 @@ internal class CSharpOperationCloner : OperationCloner
{
public static OperationCloner Instance { get; } = new CSharpOperationCloner();
public override IOperation VisitArgument(IArgument operation, object argument)
{
return new CSharpArgument(operation.ArgumentKind, operation.Parameter, Visit(operation.Value), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
}
public override IOperation VisitConversionExpression(IConversionExpression operation, object argument)
{
return new CSharpConversionExpression(Visit(operation.Operand), operation.GetConversion(), operation.IsExplicitInCode, operation.IsTryCast, operation.IsChecked, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
......
......@@ -36,11 +36,9 @@ internal IArgument CreateArgumentOperation(ArgumentKind kind, IParameterSymbol p
{
var value = Create(expression);
return new Argument(kind,
return new CSharpArgument(kind,
parameter,
value,
inConversion: null,
outConversion: null,
semanticModel: _semanticModel,
syntax: value.Syntax,
type: value.Type,
......
......@@ -206,29 +206,19 @@ internal abstract partial class BaseArgument : Operation, IArgument
/// </summary>
public IParameterSymbol Parameter { get; }
protected abstract IOperation ValueImpl { get; }
protected abstract IOperation InConversionImpl { get; }
protected abstract IOperation OutConversionImpl { get; }
public abstract CommonConversion InConversion { get; }
public abstract CommonConversion OutConversion { get; }
public override IEnumerable<IOperation> Children
{
get
{
yield return Value;
yield return InConversion;
yield return OutConversion;
}
}
/// <summary>
/// Value supplied for the argument.
/// </summary>
public IOperation Value => Operation.SetParentOperation(ValueImpl, this);
/// <summary>
/// Conversion applied to the argument value passing it into the target method. Applicable only to VB Reference arguments.
/// </summary>
public IOperation InConversion => Operation.SetParentOperation(InConversionImpl, this);
/// <summary>
/// Conversion applied to the argument value after the invocation. Applicable only to VB Reference arguments.
/// </summary>
public IOperation OutConversion => Operation.SetParentOperation(OutConversionImpl, this);
public override void Accept(OperationVisitor visitor)
{
visitor.VisitArgument(this);
......@@ -239,47 +229,6 @@ public override void Accept(OperationVisitor visitor)
}
}
/// <summary>
/// Represents an argument in a method invocation.
/// </summary>
internal sealed partial class Argument : BaseArgument, IArgument
{
public Argument(ArgumentKind argumentKind, IParameterSymbol parameter, IOperation value, IOperation inConversion, IOperation outConversion, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(argumentKind, parameter, semanticModel, syntax, type, constantValue)
{
ValueImpl = value;
InConversionImpl = inConversion;
OutConversionImpl = outConversion;
}
protected override IOperation ValueImpl { get; }
protected override IOperation InConversionImpl { get; }
protected override IOperation OutConversionImpl { get; }
}
/// <summary>
/// Represents an argument in a method invocation.
/// </summary>
internal sealed partial class LazyArgument : BaseArgument, IArgument
{
private readonly Lazy<IOperation> _lazyValue;
private readonly Lazy<IOperation> _lazyInConversion;
private readonly Lazy<IOperation> _lazyOutConversion;
public LazyArgument(ArgumentKind argumentKind, IParameterSymbol parameter, Lazy<IOperation> value, Lazy<IOperation> inConversion, Lazy<IOperation> outConversion, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) : base(argumentKind, parameter, semanticModel, syntax, type, constantValue)
{
_lazyValue = value ?? throw new System.ArgumentNullException(nameof(value));
_lazyInConversion = inConversion ?? throw new System.ArgumentNullException(nameof(inConversion));
_lazyOutConversion = outConversion ?? throw new System.ArgumentNullException(nameof(outConversion));
}
protected override IOperation ValueImpl => _lazyValue.Value;
protected override IOperation InConversionImpl => _lazyInConversion.Value;
protected override IOperation OutConversionImpl => _lazyOutConversion.Value;
}
/// <summary>
/// Represents the creation of an array instance.
/// </summary>
......
......@@ -26,11 +26,11 @@ public interface IArgument : IOperation
/// <summary>
/// Conversion applied to the argument value passing it into the target method. Applicable only to VB Reference arguments.
/// </summary>
IOperation InConversion { get; }
CommonConversion InConversion { get; }
/// <summary>
/// Conversion applied to the argument value after the invocation. Applicable only to VB Reference arguments.
/// </summary>
IOperation OutConversion { get; }
CommonConversion OutConversion { get; }
}
}
......@@ -179,11 +179,6 @@ public override IOperation VisitInvocationExpression(IInvocationExpression opera
return new InvocationExpression(operation.TargetMethod, Visit(operation.Instance), operation.IsVirtual, VisitArray(operation.ArgumentsInEvaluationOrder), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
}
public override IOperation VisitArgument(IArgument operation, object argument)
{
return new Argument(operation.ArgumentKind, operation.Parameter, Visit(operation.Value), Visit(operation.InConversion), Visit(operation.OutConversion), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
}
public override IOperation VisitOmittedArgumentExpression(IOmittedArgumentExpression operation, object argument)
{
return new OmittedArgumentExpression(((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
......
......@@ -345,8 +345,8 @@ Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression
Microsoft.CodeAnalysis.Semantics.IAnonymousObjectCreationExpression.Initializers.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IArgument
Microsoft.CodeAnalysis.Semantics.IArgument.ArgumentKind.get -> Microsoft.CodeAnalysis.Semantics.ArgumentKind
Microsoft.CodeAnalysis.Semantics.IArgument.InConversion.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IArgument.OutConversion.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IArgument.InConversion.get -> Microsoft.CodeAnalysis.Semantics.CommonConversion
Microsoft.CodeAnalysis.Semantics.IArgument.OutConversion.get -> Microsoft.CodeAnalysis.Semantics.CommonConversion
Microsoft.CodeAnalysis.Semantics.IArgument.Parameter.get -> Microsoft.CodeAnalysis.IParameterSymbol
Microsoft.CodeAnalysis.Semantics.IArgument.Value.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IArrayCreationExpression
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Semantics
Namespace Microsoft.CodeAnalysis.VisualBasic
Friend MustInherit Class BaseVisualBasicArgument
Inherits BaseArgument
Protected Sub New(argumentKind As ArgumentKind, parameter As IParameterSymbol, inConversion As Conversion, outConversion As Conversion, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object))
MyBase.New(argumentKind, parameter, semanticModel, syntax, type, constantValue)
InConversionInternal = inConversion
OutConversionInternal = outConversion
End Sub
Friend ReadOnly Property InConversionInternal As Conversion
Friend ReadOnly Property OutConversionInternal As Conversion
Public Overrides ReadOnly Property InConversion As CommonConversion
Get
Return InConversionInternal.ToCommonConversion()
End Get
End Property
Public Overrides ReadOnly Property OutConversion As CommonConversion
Get
Return OutConversionInternal.ToCommonConversion()
End Get
End Property
End Class
Friend NotInheritable Class VisualBasicArgument
Inherits BaseVisualBasicArgument
Public Sub New(argumentKind As ArgumentKind, parameter As IParameterSymbol, value As IOperation, inConversion As Conversion, outConversion As Conversion, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object))
MyBase.New(argumentKind, parameter, inConversion, outConversion, semanticModel, syntax, type, constantValue)
Me.ValueImpl = value
End Sub
Protected Overrides ReadOnly Property ValueImpl As IOperation
End Class
Friend NotInheritable Class LazyVisualBasicArgument
Inherits BaseVisualBasicArgument
Private ReadOnly _valueLazy As Lazy(Of IOperation)
Public Sub New(argumentKind As ArgumentKind, parameter As IParameterSymbol, valueLazy As Lazy(Of IOperation), inConversion As Conversion, outConversion As Conversion, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object))
MyBase.New(argumentKind, parameter, inConversion, outConversion, semanticModel, syntax, type, constantValue)
_valueLazy = valueLazy
End Sub
Protected Overrides ReadOnly Property ValueImpl As IOperation
Get
Return _valueLazy.Value
End Get
End Property
End Class
End Namespace
......@@ -7,6 +7,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Shared ReadOnly Property Instance As OperationCloner = New VisualBasicOperationCloner()
Public Overrides Function VisitArgument(operation As IArgument, argument As Object) As IOperation
Return New VisualBasicArgument(operation.ArgumentKind, operation.Parameter, Visit(operation.Value), operation.GetInConversion(), operation.GetOutConversion(), DirectCast(operation, Operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue)
End Function
Public Overrides Function VisitConversionExpression(operation As IConversionExpression, argument As Object) As IOperation
Return New VisualBasicConversionExpression(Visit(operation.Operand), operation.GetConversion(), operation.IsExplicitInCode, operation.IsTryCast, operation.IsChecked, DirectCast(operation, Operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue)
End Function
......
......@@ -71,18 +71,31 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return arguments.ToImmutableAndFree()
End Function
Private Function CreateConversion(expression As BoundExpression) As Conversion
If expression.Kind = BoundKind.Conversion Then
Dim conversion = DirectCast(expression, BoundConversion)
Dim method As MethodSymbol = Nothing
If conversion.Operand.Kind = BoundKind.UserDefinedConversion Then
method = DirectCast(conversion.Operand, BoundUserDefinedConversion).Call.Method
End If
Return New Conversion(KeyValuePair.Create(conversion.ConversionKind, method))
End If
Return New Conversion(Nothing) 'NoConversion
End Function
Private Function DeriveArgument(index As Integer, argument As BoundExpression, parameters As ImmutableArray(Of VisualBasic.Symbols.ParameterSymbol)) As IArgument
Select Case argument.Kind
Case BoundKind.ByRefArgumentWithCopyBack
Dim byRefArgument = DirectCast(argument, BoundByRefArgumentWithCopyBack)
Dim parameter = parameters(index)
Dim value = Create(byRefArgument.OriginalArgument)
Return New Argument(
Return New VisualBasicArgument(
ArgumentKind.Explicit,
parameter,
value,
Create(byRefArgument.InConversion),
Create(byRefArgument.OutConversion),
CreateConversion(byRefArgument.InConversion),
CreateConversion(byRefArgument.OutConversion),
_semanticModel,
value.Syntax,
type:=Nothing,
......@@ -98,12 +111,12 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim parameter = parameters(lastParameterIndex)
Dim value = Create(argument)
Return New Argument(
Return New VisualBasicArgument(
kind,
parameter,
value,
inConversion:=Nothing,
outConversion:=Nothing,
inConversion:=New Conversion(Nothing), 'NoConversion,
outConversion:=New Conversion(Nothing), 'NoConversion,
semanticModel:=_semanticModel,
syntax:=value.Syntax,
type:=Nothing,
......@@ -117,12 +130,12 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim parameter = parameters(index)
Dim value = Create(argument)
Return New Argument(
Return New VisualBasicArgument(
kind,
parameter,
value,
inConversion:=Nothing,
outConversion:=Nothing,
inConversion:=New Conversion(Nothing), 'NoConversion,
outConversion:=New Conversion(Nothing), 'NoConversion,
semanticModel:=_semanticModel,
syntax:=value.Syntax,
type:=Nothing,
......
Microsoft.CodeAnalysis.VisualBasic.Conversion.ToCommonConversion() -> Microsoft.CodeAnalysis.Semantics.CommonConversion
Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions.GetConversion(conversionExpression As Microsoft.CodeAnalysis.Semantics.IConversionExpression) -> Microsoft.CodeAnalysis.VisualBasic.Conversion
Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions.GetInConversion(argument As Microsoft.CodeAnalysis.Semantics.IArgument) -> Microsoft.CodeAnalysis.VisualBasic.Conversion
Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions.GetOutConversion(argument As Microsoft.CodeAnalysis.Semantics.IArgument) -> Microsoft.CodeAnalysis.VisualBasic.Conversion
Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.VisualBasic15_5 = 1505 -> Microsoft.CodeAnalysis.VisualBasic.LanguageVersion
\ No newline at end of file
......@@ -12234,6 +12234,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to {0} is not a valid Visual Basic argument.
'''</summary>
Friend ReadOnly Property IArgumentIsNotVisualBasicArgument() As String
Get
Return ResourceManager.GetString("IArgumentIsNotVisualBasicArgument", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to {0} is not a valid Visual Basic conversion expression.
'''</summary>
......
......@@ -5503,4 +5503,7 @@
<data name="IConversionExpressionIsNotVisualBasicConversion" xml:space="preserve">
<value>{0} is not a valid Visual Basic conversion expression</value>
</data>
<data name="IArgumentIsNotVisualBasicArgument" xml:space="preserve">
<value>{0} is not a valid Visual Basic argument</value>
</data>
</root>
\ No newline at end of file
......@@ -1379,6 +1379,42 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
End Function
''' <summary>
''' Gets the underlying <see cref="Conversion"/> information for InConversion of <see cref="IArgument"/> that was created from Visual Basic code.
''' </summary>
''' <param name="argument">The argument to get original info from.</param>
''' <returns>The underlying <see cref="Conversion"/> of the InConversion.</returns>
''' <exception cref="InvalidCastException">If the <see cref="IArgument"/> was not created from Visual Basic code.</exception>
<Extension>
Public Function GetInConversion(argument As IArgument) As Conversion
Dim basicArgument = TryCast(argument, BaseVisualBasicArgument)
If basicArgument IsNot Nothing Then
Return basicArgument.InConversionInternal
Else
Throw New ArgumentException(String.Format(VBResources.IArgumentIsNotVisualBasicArgument,
NameOf(IArgument)),
NameOf(argument))
End If
End Function
''' <summary>
''' Gets the underlying <see cref="Conversion"/> information for OutConversion of <see cref="IArgument"/> that was created from Visual Basic code.
''' </summary>
''' <param name="argument">The argument to get original info from.</param>
''' <returns>The underlying <see cref="Conversion"/> of the OutConversion.</returns>
''' <exception cref="InvalidCastException">If the <see cref="IArgument"/> was not created from Visual Basic code.</exception>
<Extension>
Public Function GetOutConversion(argument As IArgument) As Conversion
Dim basicArgument = TryCast(argument, BaseVisualBasicArgument)
If basicArgument IsNot Nothing Then
Return basicArgument.OutConversionInternal
Else
Throw New ArgumentException(String.Format(VBResources.IArgumentIsNotVisualBasicArgument,
NameOf(IArgument)),
NameOf(argument))
End If
End Function
<Extension>
Public Function GetSpeculativeConversion(semanticModel As SemanticModel, position As Integer, expression As ExpressionSyntax, bindingOption As SpeculativeBindingOption) As Conversion
Dim vbmodel = TryCast(semanticModel, VBSemanticModel)
......
......@@ -623,9 +623,17 @@ public override void VisitArgument(IArgument operation)
LogString(")");
LogCommonPropertiesAndNewLine(operation);
Indent();
LogConversion(operation.InConversion, "InConversion");
Unindent();
LogNewLine();
Indent();
LogConversion(operation.OutConversion, "OutConversion");
Unindent();
LogNewLine();
Visit(operation.Value);
Visit(operation.InConversion, "InConversion");
Visit(operation.OutConversion, "OutConversion");
}
public override void VisitOmittedArgumentExpression(IOmittedArgumentExpression operation)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册