未验证 提交 b83993a7 编写于 作者: F Fred Silberberg 提交者: GitHub

Merge pull request #24134 from 333fred/unified-conversions

Unified conversions
...@@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.CSharp ...@@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.CSharp
/// Summarizes whether a conversion is allowed, and if so, which kind of conversion (and in some cases, the /// Summarizes whether a conversion is allowed, and if so, which kind of conversion (and in some cases, the
/// associated symbol). /// associated symbol).
/// </summary> /// </summary>
public struct Conversion : IEquatable<Conversion> public struct Conversion : IEquatable<Conversion>, IConvertibleConversion
{ {
private readonly ConversionKind _kind; private readonly ConversionKind _kind;
private readonly UncommonData _uncommonData; private readonly UncommonData _uncommonData;
......
...@@ -694,9 +694,9 @@ public static Conversion GetConversion(this SemanticModel semanticModel, SyntaxN ...@@ -694,9 +694,9 @@ public static Conversion GetConversion(this SemanticModel semanticModel, SyntaxN
/// <exception cref="InvalidCastException">If the <see cref="IConversionOperation"/> was not created from CSharp code.</exception> /// <exception cref="InvalidCastException">If the <see cref="IConversionOperation"/> was not created from CSharp code.</exception>
public static Conversion GetConversion(this IConversionOperation conversionExpression) public static Conversion GetConversion(this IConversionOperation conversionExpression)
{ {
if (conversionExpression is BaseCSharpConversionExpression csharpConversionExpression) if (conversionExpression.Language == LanguageNames.CSharp)
{ {
return csharpConversionExpression.ConversionInternal; return (Conversion)((BaseConversionExpression)conversionExpression).ConvertibleConversion;
} }
else else
{ {
...@@ -720,9 +720,9 @@ public static Conversion GetInConversion(this ICompoundAssignmentOperation compo ...@@ -720,9 +720,9 @@ public static Conversion GetInConversion(this ICompoundAssignmentOperation compo
throw new ArgumentNullException(nameof(compoundAssignment)); throw new ArgumentNullException(nameof(compoundAssignment));
} }
if (compoundAssignment is BaseCSharpCompoundAssignmentOperation csharpCompoundAssignment) if (compoundAssignment.Language == LanguageNames.CSharp)
{ {
return csharpCompoundAssignment.InConversionInternal; return (Conversion)((BaseCompoundAssignmentExpression)compoundAssignment).InConversionConvertible;
} }
else else
{ {
...@@ -746,9 +746,9 @@ public static Conversion GetOutConversion(this ICompoundAssignmentOperation comp ...@@ -746,9 +746,9 @@ public static Conversion GetOutConversion(this ICompoundAssignmentOperation comp
throw new ArgumentNullException(nameof(compoundAssignment)); throw new ArgumentNullException(nameof(compoundAssignment));
} }
if (compoundAssignment is BaseCSharpCompoundAssignmentOperation csharpCompoundAssignemnt) if (compoundAssignment.Language == LanguageNames.CSharp)
{ {
return csharpCompoundAssignemnt.OutConversionInternal; return (Conversion)((BaseCompoundAssignmentExpression)compoundAssignment).OutConversionConvertible;
} }
else else
{ {
......
...@@ -474,11 +474,6 @@ internal virtual IOperation GetOperationWorker(CSharpSyntaxNode node, Cancellati ...@@ -474,11 +474,6 @@ internal virtual IOperation GetOperationWorker(CSharpSyntaxNode node, Cancellati
return null; return null;
} }
internal override IOperation CloneOperationCore(IOperation operation)
{
return CSharpOperationCloner.Instance.Visit(operation);
}
#region GetSymbolInfo #region GetSymbolInfo
/// <summary> /// <summary>
......
// 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.Operations;
namespace Microsoft.CodeAnalysis.CSharp
{
internal abstract class BaseCSharpArgument : BaseArgument
{
public BaseCSharpArgument(ArgumentKind argumentKind, IParameterSymbol parameter, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) :
base(argumentKind, parameter, semanticModel, syntax, constantValue, isImplicit)
{
}
public override CommonConversion InConversion => new CommonConversion(exists:true, isIdentity:true, isNumeric:false, isReference:false, methodSymbol:null);
public override CommonConversion OutConversion => new CommonConversion(exists: true, isIdentity: true, isNumeric: false, isReference: false, methodSymbol: null);
}
internal sealed class CSharpArgument : BaseCSharpArgument
{
public CSharpArgument(ArgumentKind argumentKind, IParameterSymbol parameter, IOperation value, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) :
base(argumentKind, parameter, semanticModel, syntax, constantValue, isImplicit)
{
ValueImpl = value;
}
protected override IOperation ValueImpl { get; }
}
internal sealed class LazyCSharpArgument : BaseCSharpArgument
{
private readonly Lazy<IOperation> _lazyValue;
public LazyCSharpArgument(ArgumentKind argumentKind, IParameterSymbol parameter, Lazy<IOperation> value, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) :
base(argumentKind, parameter, semanticModel, syntax, constantValue, isImplicit)
{
_lazyValue = value ?? throw new ArgumentNullException(nameof(value));
}
protected override IOperation ValueImpl => _lazyValue.Value;
}
}
using System;
using Microsoft.CodeAnalysis.Operations;
namespace Microsoft.CodeAnalysis.CSharp
{
internal abstract class BaseCSharpCompoundAssignmentOperation : BaseCompoundAssignmentExpression
{
protected BaseCSharpCompoundAssignmentOperation(Conversion inConversion, Conversion outConversion, Operations.BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
{
InConversionInternal = inConversion;
OutConversionInternal = outConversion;
}
internal Conversion InConversionInternal { get; }
internal Conversion OutConversionInternal { get; }
public override CommonConversion InConversion => InConversionInternal.ToCommonConversion();
public override CommonConversion OutConversion => OutConversionInternal.ToCommonConversion();
}
internal sealed class CSharpCompoundAssignmentOperation : BaseCSharpCompoundAssignmentOperation
{
public CSharpCompoundAssignmentOperation(IOperation target, IOperation value, Conversion inConversion, Conversion outConversion, Operations.BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
{
TargetImpl = target;
ValueImpl = value;
}
protected override IOperation TargetImpl { get; }
protected override IOperation ValueImpl { get; }
}
internal sealed class LazyCSharpCompoundAssignmentOperation : BaseCSharpCompoundAssignmentOperation
{
private readonly Lazy<IOperation> _lazyTarget;
private readonly Lazy<IOperation> _lazyValue;
public LazyCSharpCompoundAssignmentOperation(Lazy<IOperation> target, Lazy<IOperation> value, Conversion inConversion, Conversion outConversion, Operations.BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyTarget = target;
_lazyValue = value;
}
protected override IOperation TargetImpl => _lazyTarget.Value;
protected override IOperation ValueImpl => _lazyValue.Value;
}
}
// 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.Operations;
namespace Microsoft.CodeAnalysis.CSharp
{
internal abstract class BaseCSharpConversionExpression : BaseConversionExpression
{
protected BaseCSharpConversionExpression(Conversion conversion, bool isTryCast, bool isChecked, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
{
ConversionInternal = conversion;
}
internal Conversion ConversionInternal { get; }
public override CommonConversion Conversion => ConversionInternal.ToCommonConversion();
}
internal sealed partial class CSharpConversionExpression : BaseCSharpConversionExpression
{
public CSharpConversionExpression(IOperation operand, Conversion conversion, bool isTryCast, bool isChecked, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(conversion, isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
{
OperandImpl = operand;
}
public override IOperation OperandImpl { get; }
}
internal sealed partial class LazyCSharpConversionExpression : BaseCSharpConversionExpression
{
private readonly Lazy<IOperation> _operand;
public LazyCSharpConversionExpression(Lazy<IOperation> operand, Conversion conversion, bool isTryCast, bool isChecked, SemanticModel semanticModel,SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(conversion, isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
{
_operand = operand;
}
public override IOperation OperandImpl => _operand.Value;
}
}
// 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 Microsoft.CodeAnalysis.Operations;
namespace Microsoft.CodeAnalysis.CSharp
{
internal class CSharpOperationCloner : OperationCloner
{
public static OperationCloner Instance { get; } = new CSharpOperationCloner();
public override IOperation VisitArgument(IArgumentOperation operation, object argument)
{
return new CSharpArgument(operation.ArgumentKind, operation.Parameter, Visit(operation.Value), ((Operation)operation).SemanticModel, operation.Syntax, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitConversion(IConversionOperation operation, object argument)
{
return new CSharpConversionExpression(Visit(operation.Operand), operation.GetConversion(), operation.IsTryCast, operation.IsChecked, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitCompoundAssignment(ICompoundAssignmentOperation operation, object argument)
{
var compoundAssignment = (BaseCSharpCompoundAssignmentOperation)operation;
return new CSharpCompoundAssignmentOperation(Visit(operation.Target), Visit(operation.Value), compoundAssignment.InConversionInternal, compoundAssignment.OutConversionInternal, operation.OperatorKind, operation.IsLifted, operation.IsChecked, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
}
}
...@@ -36,7 +36,7 @@ public IOperation Create(BoundNode boundNode) ...@@ -36,7 +36,7 @@ public IOperation Create(BoundNode boundNode)
// always return cloned one // always return cloned one
if (boundNode.Kind == BoundKind.ImplicitReceiver) if (boundNode.Kind == BoundKind.ImplicitReceiver)
{ {
return _semanticModel.CloneOperation(CreateInternal(boundNode)); return OperationCloner.CloneOperation(CreateInternal(boundNode));
} }
return _cache.GetOrAdd(boundNode, n => CreateInternal(n)); return _cache.GetOrAdd(boundNode, n => CreateInternal(n));
...@@ -855,7 +855,7 @@ private IOperation CreateBoundConversionOperation(BoundConversion boundConversio ...@@ -855,7 +855,7 @@ private IOperation CreateBoundConversionOperation(BoundConversion boundConversio
bool isTryCast = false; bool isTryCast = false;
// Checked conversions only matter if the conversion is a Numeric conversion. Don't have true unless the conversion is actually numeric. // Checked conversions only matter if the conversion is a Numeric conversion. Don't have true unless the conversion is actually numeric.
bool isChecked = conversion.IsNumeric && boundConversion.Checked; bool isChecked = conversion.IsNumeric && boundConversion.Checked;
return new LazyCSharpConversionExpression(operand, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit); return new LazyConversionOperation(operand, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit);
} }
} }
} }
...@@ -870,7 +870,7 @@ private IConversionOperation CreateBoundAsOperatorOperation(BoundAsOperator boun ...@@ -870,7 +870,7 @@ private IConversionOperation CreateBoundAsOperatorOperation(BoundAsOperator boun
ITypeSymbol type = boundAsOperator.Type; ITypeSymbol type = boundAsOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundAsOperator.ConstantValue); Optional<object> constantValue = ConvertToOptional(boundAsOperator.ConstantValue);
bool isImplicit = boundAsOperator.WasCompilerGenerated; bool isImplicit = boundAsOperator.WasCompilerGenerated;
return new LazyCSharpConversionExpression(operand, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit); return new LazyConversionOperation(operand, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit);
} }
private IDelegateCreationOperation CreateBoundDelegateCreationExpressionOperation(BoundDelegateCreationExpression boundDelegateCreationExpression) private IDelegateCreationOperation CreateBoundDelegateCreationExpressionOperation(BoundDelegateCreationExpression boundDelegateCreationExpression)
...@@ -1041,7 +1041,7 @@ private ICompoundAssignmentOperation CreateBoundCompoundAssignmentOperatorOperat ...@@ -1041,7 +1041,7 @@ private ICompoundAssignmentOperation CreateBoundCompoundAssignmentOperatorOperat
ITypeSymbol type = boundCompoundAssignmentOperator.Type; ITypeSymbol type = boundCompoundAssignmentOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundCompoundAssignmentOperator.ConstantValue); Optional<object> constantValue = ConvertToOptional(boundCompoundAssignmentOperator.ConstantValue);
bool isImplicit = boundCompoundAssignmentOperator.WasCompilerGenerated; bool isImplicit = boundCompoundAssignmentOperator.WasCompilerGenerated;
return new LazyCSharpCompoundAssignmentOperation(target, value, inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit); return new LazyCompoundAssignmentOperation(target, value, inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
} }
private IIncrementOrDecrementOperation CreateBoundIncrementOperatorOperation(BoundIncrementOperator boundIncrementOperator) private IIncrementOrDecrementOperation CreateBoundIncrementOperatorOperation(BoundIncrementOperator boundIncrementOperator)
......
...@@ -13,6 +13,8 @@ namespace Microsoft.CodeAnalysis.Operations ...@@ -13,6 +13,8 @@ namespace Microsoft.CodeAnalysis.Operations
{ {
internal sealed partial class CSharpOperationFactory internal sealed partial class CSharpOperationFactory
{ {
private static readonly IConvertibleConversion s_boxedIdentityConversion = Conversion.Identity;
private static Optional<object> ConvertToOptional(ConstantValue value) private static Optional<object> ConvertToOptional(ConstantValue value)
{ {
return value != null && !value.IsBad ? new Optional<object>(value.Value) : default(Optional<object>); return value != null && !value.IsBad ? new Optional<object>(value.Value) : default(Optional<object>);
...@@ -41,9 +43,11 @@ internal IArgumentOperation CreateArgumentOperation(ArgumentKind kind, IParamete ...@@ -41,9 +43,11 @@ internal IArgumentOperation CreateArgumentOperation(ArgumentKind kind, IParamete
var argument = value.Syntax?.Parent as ArgumentSyntax; var argument = value.Syntax?.Parent as ArgumentSyntax;
// if argument syntax doesn't exist, this operation is implicit // if argument syntax doesn't exist, this operation is implicit
return new CSharpArgument(kind, return new ArgumentOperation(value,
kind,
parameter, parameter,
value, s_boxedIdentityConversion,
s_boxedIdentityConversion,
semanticModel: _semanticModel, semanticModel: _semanticModel,
syntax: argument ?? value.Syntax, syntax: argument ?? value.Syntax,
constantValue: default, constantValue: default,
......
...@@ -86,13 +86,6 @@ public IOperation GetOperation(SyntaxNode node, CancellationToken cancellationTo ...@@ -86,13 +86,6 @@ public IOperation GetOperation(SyntaxNode node, CancellationToken cancellationTo
protected abstract IOperation GetOperationCore(SyntaxNode node, CancellationToken cancellationToken); protected abstract IOperation GetOperationCore(SyntaxNode node, CancellationToken cancellationToken);
/// <summary>
/// Deep Clone given IOperation
/// </summary>
internal T CloneOperation<T>(T operation) where T : IOperation => (T)CloneOperationCore(operation);
internal abstract IOperation CloneOperationCore(IOperation operation);
/// <summary> /// <summary>
/// Returns true if this is a SemanticModel that ignores accessibility rules when answering semantic questions. /// Returns true if this is a SemanticModel that ignores accessibility rules when answering semantic questions.
/// </summary> /// </summary>
......
...@@ -201,11 +201,13 @@ internal sealed partial class LazyThrowExpression : BaseThrowExpression, IThrowO ...@@ -201,11 +201,13 @@ internal sealed partial class LazyThrowExpression : BaseThrowExpression, IThrowO
/// </summary> /// </summary>
internal abstract partial class BaseArgument : Operation, IArgumentOperation internal abstract partial class BaseArgument : Operation, IArgumentOperation
{ {
protected BaseArgument(ArgumentKind argumentKind, IParameterSymbol parameter, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) : protected BaseArgument(ArgumentKind argumentKind, IParameterSymbol parameter, IConvertibleConversion inConversion, IConvertibleConversion outConversion, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.Argument, semanticModel, syntax, type: null, constantValue: constantValue, isImplicit: isImplicit) base(OperationKind.Argument, semanticModel, syntax, type: null, constantValue: constantValue, isImplicit: isImplicit)
{ {
ArgumentKind = argumentKind; ArgumentKind = argumentKind;
Parameter = parameter; Parameter = parameter;
InConversionConvertible = inConversion;
OutConversionConvertible = outConversion;
} }
/// <summary> /// <summary>
/// Kind of argument. /// Kind of argument.
...@@ -216,8 +218,10 @@ internal abstract partial class BaseArgument : Operation, IArgumentOperation ...@@ -216,8 +218,10 @@ internal abstract partial class BaseArgument : Operation, IArgumentOperation
/// </summary> /// </summary>
public IParameterSymbol Parameter { get; } public IParameterSymbol Parameter { get; }
protected abstract IOperation ValueImpl { get; } protected abstract IOperation ValueImpl { get; }
public abstract CommonConversion InConversion { get; } internal IConvertibleConversion InConversionConvertible { get; }
public abstract CommonConversion OutConversion { get; } internal IConvertibleConversion OutConversionConvertible { get; }
public CommonConversion InConversion => InConversionConvertible.ToCommonConversion();
public CommonConversion OutConversion => OutConversionConvertible.ToCommonConversion();
public override IEnumerable<IOperation> Children public override IEnumerable<IOperation> Children
{ {
get get
...@@ -242,6 +246,28 @@ public override void Accept(OperationVisitor visitor) ...@@ -242,6 +246,28 @@ public override void Accept(OperationVisitor visitor)
} }
} }
internal sealed partial class ArgumentOperation : BaseArgument
{
public ArgumentOperation(IOperation value, ArgumentKind argumentKind, IParameterSymbol parameter, IConvertibleConversion inConversion, IConvertibleConversion outConversion, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) : base(argumentKind, parameter, inConversion, outConversion, semanticModel, syntax, constantValue, isImplicit)
{
ValueImpl = value;
}
protected override IOperation ValueImpl { get; }
}
internal sealed partial class LazyArgumentOperation : BaseArgument
{
private readonly Lazy<IOperation> _lazyValue;
public LazyArgumentOperation(Lazy<IOperation> value, ArgumentKind argumentKind, IConvertibleConversion inConversion, IConvertibleConversion outConversion, IParameterSymbol parameter, SemanticModel semanticModel, SyntaxNode syntax, Optional<object> constantValue, bool isImplicit) : base(argumentKind, parameter, inConversion, outConversion, semanticModel, syntax, constantValue, isImplicit)
{
_lazyValue = value;
}
protected override IOperation ValueImpl => _lazyValue.Value;
}
/// <summary> /// <summary>
/// Represents the creation of an array instance. /// Represents the creation of an array instance.
/// </summary> /// </summary>
...@@ -1103,13 +1129,15 @@ public LazyCatchClause(Lazy<IOperation> exceptionDeclarationOrExpression, ITypeS ...@@ -1103,13 +1129,15 @@ public LazyCatchClause(Lazy<IOperation> exceptionDeclarationOrExpression, ITypeS
/// </summary> /// </summary>
internal abstract partial class BaseCompoundAssignmentExpression : AssignmentExpression, ICompoundAssignmentOperation internal abstract partial class BaseCompoundAssignmentExpression : AssignmentExpression, ICompoundAssignmentOperation
{ {
protected BaseCompoundAssignmentExpression(BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : protected BaseCompoundAssignmentExpression(IConvertibleConversion inConversionConvertible, IConvertibleConversion outConversionConvertible, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.CompoundAssignment, semanticModel, syntax, type, constantValue, isImplicit) base(OperationKind.CompoundAssignment, semanticModel, syntax, type, constantValue, isImplicit)
{ {
OperatorKind = operatorKind; OperatorKind = operatorKind;
IsLifted = isLifted; IsLifted = isLifted;
IsChecked = isChecked; IsChecked = isChecked;
OperatorMethod = operatorMethod; OperatorMethod = operatorMethod;
InConversionConvertible = inConversionConvertible;
OutConversionConvertible = outConversionConvertible;
} }
/// <summary> /// <summary>
/// Kind of binary operation. /// Kind of binary operation.
...@@ -1127,8 +1155,10 @@ internal abstract partial class BaseCompoundAssignmentExpression : AssignmentExp ...@@ -1127,8 +1155,10 @@ internal abstract partial class BaseCompoundAssignmentExpression : AssignmentExp
/// Operator method used by the operation, null if the operation does not use an operator method. /// Operator method used by the operation, null if the operation does not use an operator method.
/// </summary> /// </summary>
public IMethodSymbol OperatorMethod { get; } public IMethodSymbol OperatorMethod { get; }
public abstract CommonConversion InConversion { get; } internal IConvertibleConversion InConversionConvertible { get; }
public abstract CommonConversion OutConversion { get; } internal IConvertibleConversion OutConversionConvertible { get; }
public CommonConversion InConversion => InConversionConvertible.ToCommonConversion();
public CommonConversion OutConversion => OutConversionConvertible.ToCommonConversion();
public override void Accept(OperationVisitor visitor) public override void Accept(OperationVisitor visitor)
{ {
...@@ -1140,6 +1170,33 @@ public override void Accept(OperationVisitor visitor) ...@@ -1140,6 +1170,33 @@ public override void Accept(OperationVisitor visitor)
} }
} }
internal sealed partial class CompoundAssignmentOperation : BaseCompoundAssignmentExpression
{
public CompoundAssignmentOperation(IOperation target, IOperation value, IConvertibleConversion inConversionConvertible, IConvertibleConversion outConversionConvertible, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(inConversionConvertible, outConversionConvertible, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
{
TargetImpl = target;
ValueImpl = value;
}
protected override IOperation TargetImpl { get; }
protected override IOperation ValueImpl { get; }
}
internal sealed partial class LazyCompoundAssignmentOperation : BaseCompoundAssignmentExpression
{
private readonly Lazy<IOperation> _lazyTarget;
private readonly Lazy<IOperation> _lazyValue;
public LazyCompoundAssignmentOperation(Lazy<IOperation> target, Lazy<IOperation> value, IConvertibleConversion inConversionConvertible, IConvertibleConversion outConversionConvertible, BinaryOperatorKind operatorKind, bool isLifted, bool isChecked, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(inConversionConvertible, outConversionConvertible, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyTarget = target;
_lazyValue = value;
}
protected override IOperation TargetImpl => _lazyTarget.Value;
protected override IOperation ValueImpl => _lazyValue.Value;
}
/// <summary> /// <summary>
/// Represents an expression that includes a ? or ?. conditional access instance expression. /// Represents an expression that includes a ? or ?. conditional access instance expression.
/// </summary> /// </summary>
...@@ -1368,15 +1425,17 @@ internal sealed partial class LazyConditionalOperation : BaseConditionalOperatio ...@@ -1368,15 +1425,17 @@ internal sealed partial class LazyConditionalOperation : BaseConditionalOperatio
/// </summary> /// </summary>
internal abstract partial class BaseConversionExpression : Operation, IConversionOperation internal abstract partial class BaseConversionExpression : Operation, IConversionOperation
{ {
protected BaseConversionExpression(bool isTryCast, bool isChecked, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : protected BaseConversionExpression(IConvertibleConversion convertibleConversion, bool isTryCast, bool isChecked, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.Conversion, semanticModel, syntax, type, constantValue, isImplicit) base(OperationKind.Conversion, semanticModel, syntax, type, constantValue, isImplicit)
{ {
IsTryCast = isTryCast; IsTryCast = isTryCast;
IsChecked = isChecked; IsChecked = isChecked;
ConvertibleConversion = convertibleConversion;
} }
public abstract IOperation OperandImpl { get; } public abstract IOperation OperandImpl { get; }
public abstract CommonConversion Conversion { get; } internal IConvertibleConversion ConvertibleConversion { get; }
public CommonConversion Conversion => ConvertibleConversion.ToCommonConversion();
public bool IsTryCast { get; } public bool IsTryCast { get; }
public bool IsChecked { get; } public bool IsChecked { get; }
public IMethodSymbol OperatorMethod => Conversion.MethodSymbol; public IMethodSymbol OperatorMethod => Conversion.MethodSymbol;
...@@ -1404,6 +1463,28 @@ public override void Accept(OperationVisitor visitor) ...@@ -1404,6 +1463,28 @@ public override void Accept(OperationVisitor visitor)
} }
} }
internal sealed partial class ConversionOperation : BaseConversionExpression
{
public ConversionOperation(IOperation operand, IConvertibleConversion convertibleConversion, bool isTryCast, bool isChecked, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(convertibleConversion, isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
{
OperandImpl = operand;
}
public override IOperation OperandImpl { get; }
}
internal sealed partial class LazyConversionOperation : BaseConversionExpression
{
private readonly Lazy<IOperation> _lazyOperand;
public LazyConversionOperation(Lazy<IOperation> lazyOperand, IConvertibleConversion convertibleConversion, bool isTryCast, bool isChecked, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(convertibleConversion, isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyOperand = lazyOperand;
}
public override IOperation OperandImpl => _lazyOperand.Value;
}
/// <remarks> /// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to /// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future. /// change it in the future.
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Operations
{
internal interface IConvertibleConversion
{
CommonConversion ToCommonConversion();
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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 System.Collections.Immutable;
using Roslyn.Utilities; using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Operations namespace Microsoft.CodeAnalysis.Operations
{ {
internal abstract class OperationCloner : OperationVisitor<object, IOperation> internal sealed class OperationCloner : OperationVisitor<object, IOperation>
{ {
protected T Visit<T>(T node) where T : IOperation private static readonly OperationCloner s_instance = new OperationCloner();
/// <summary>
/// Deep clone given IOperation
/// </summary>
public static T CloneOperation<T>(T operation) where T : IOperation
{
return s_instance.Visit(operation);
}
private OperationCloner()
{
}
private T Visit<T>(T node) where T : IOperation
{ {
return (T)Visit(node, argument: null); return (T)Visit(node, argument: null);
} }
...@@ -54,6 +69,11 @@ public override IOperation VisitVariableDeclaration(IVariableDeclarationOperatio ...@@ -54,6 +69,11 @@ public override IOperation VisitVariableDeclaration(IVariableDeclarationOperatio
return new VariableDeclaration(VisitArray(operation.Declarators), Visit(operation.Initializer), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); return new VariableDeclaration(VisitArray(operation.Declarators), Visit(operation.Initializer), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
} }
public override IOperation VisitConversion(IConversionOperation operation, object argument)
{
return new ConversionOperation(Visit(operation.Operand), ((BaseConversionExpression)operation).ConvertibleConversion, operation.IsTryCast, operation.IsChecked, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitSwitch(ISwitchOperation operation, object argument) public override IOperation VisitSwitch(ISwitchOperation operation, object argument)
{ {
return new SwitchStatement(Visit(operation.Value), VisitArray(operation.Cases), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); return new SwitchStatement(Visit(operation.Value), VisitArray(operation.Cases), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
...@@ -175,6 +195,12 @@ public override IOperation VisitInvocation(IInvocationOperation operation, objec ...@@ -175,6 +195,12 @@ public override IOperation VisitInvocation(IInvocationOperation operation, objec
return new InvocationExpression(operation.TargetMethod, Visit(operation.Instance), operation.IsVirtual, VisitArray(operation.Arguments), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); return new InvocationExpression(operation.TargetMethod, Visit(operation.Instance), operation.IsVirtual, VisitArray(operation.Arguments), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
} }
public override IOperation VisitArgument(IArgumentOperation operation, object argument)
{
var baseArgument = (BaseArgument)operation;
return new ArgumentOperation(Visit(operation.Value), operation.ArgumentKind, operation.Parameter, baseArgument.InConversionConvertible, baseArgument.OutConversionConvertible, ((Operation)operation).SemanticModel, operation.Syntax, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitOmittedArgument(IOmittedArgumentOperation operation, object argument) public override IOperation VisitOmittedArgument(IOmittedArgumentOperation operation, object argument)
{ {
return new OmittedArgumentExpression(((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); return new OmittedArgumentExpression(((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
...@@ -255,6 +281,12 @@ public override IOperation VisitBinaryOperator(IBinaryOperation operation, objec ...@@ -255,6 +281,12 @@ public override IOperation VisitBinaryOperator(IBinaryOperation operation, objec
return new BinaryOperatorExpression(operation.OperatorKind, Visit(operation.LeftOperand), Visit(operation.RightOperand), operation.IsLifted, operation.IsChecked, operation.IsCompareText, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); return new BinaryOperatorExpression(operation.OperatorKind, Visit(operation.LeftOperand), Visit(operation.RightOperand), operation.IsLifted, operation.IsChecked, operation.IsCompareText, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
} }
public override IOperation VisitCompoundAssignment(ICompoundAssignmentOperation operation, object argument)
{
var compoundAssignment = (BaseCompoundAssignmentExpression)operation;
return new CompoundAssignmentOperation(Visit(operation.Target), Visit(operation.Value), compoundAssignment.InConversionConvertible, compoundAssignment.OutConversionConvertible, operation.OperatorKind, operation.IsLifted, operation.IsChecked, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitConditional(IConditionalOperation operation, object argument) public override IOperation VisitConditional(IConditionalOperation operation, object argument)
{ {
return new ConditionalOperation(Visit(operation.Condition), Visit(operation.WhenTrue), Visit(operation.WhenFalse), operation.IsRef, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit); return new ConditionalOperation(Visit(operation.Condition), Visit(operation.WhenTrue), Visit(operation.WhenFalse), operation.IsRef, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
......
...@@ -143,10 +143,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -143,10 +143,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Nothing Return Nothing
End Function End Function
Friend Overrides Function CloneOperationCore(operation As IOperation) As IOperation
Return VisualBasicOperationCloner.Instance.Visit(operation)
End Function
''' <summary> ''' <summary>
''' Returns what symbol(s), if any, the given expression syntax bound to in the program. ''' Returns what symbol(s), if any, the given expression syntax bound to in the program.
''' '''
......
' 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.Operations
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, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(argumentKind, parameter, semanticModel, syntax, constantValue, isImplicit)
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, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(argumentKind, parameter, inConversion, outConversion, semanticModel, syntax, constantValue, isImplicit)
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, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(argumentKind, parameter, inConversion, outConversion, semanticModel, syntax, constantValue, isImplicit)
_valueLazy = valueLazy
End Sub
Protected Overrides ReadOnly Property ValueImpl As IOperation
Get
Return _valueLazy.Value
End Get
End Property
End Class
End Namespace
' 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 System.Runtime.CompilerServices
Imports Microsoft.CodeAnalysis.Operations
Namespace Microsoft.CodeAnalysis.VisualBasic
Friend MustInherit Class BaseVisualBasicCompoundAssignmentOperation
Inherits BaseCompoundAssignmentExpression
Protected Sub New(inConversion As Conversion, outConversion As Conversion, operatorKind As Operations.BinaryOperatorKind, isLifted As Boolean, isChecked As Boolean, operatorMethod As IMethodSymbol, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
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 VisualBasicCompoundAssignmentOperation
Inherits BaseVisualBasicCompoundAssignmentOperation
Public Sub New(target As IOperation, value As IOperation, inConversion As Conversion, outConversion As Conversion, operatorKind As Operations.BinaryOperatorKind, isLifted As Boolean, isChecked As Boolean, operatorMethod As IMethodSymbol, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
TargetImpl = target
ValueImpl = value
End Sub
Protected Overrides ReadOnly Property TargetImpl As IOperation
Protected Overrides ReadOnly Property ValueImpl As IOperation
End Class
Friend NotInheritable Class LazyVisualBasicCompoundAssignmentOperation
Inherits BaseVisualBasicCompoundAssignmentOperation
Private ReadOnly _lazyTarget As Lazy(Of IOperation)
Private ReadOnly _lazyValue As Lazy(Of IOperation)
Public Sub New(target As Lazy(Of IOperation), value As Lazy(Of IOperation), inConversion As Conversion, outConversion As Conversion, operatorKind As Operations.BinaryOperatorKind, isLifted As Boolean, isChecked As Boolean, operatorMethod As IMethodSymbol, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(inConversion, outConversion, operatorKind, isLifted, isChecked, operatorMethod, semanticModel, syntax, type, constantValue, isImplicit)
_lazyTarget = target
_lazyValue = value
End Sub
Protected Overrides ReadOnly Property TargetImpl As IOperation
Get
Return _lazyTarget.Value
End Get
End Property
Protected Overrides ReadOnly Property ValueImpl As IOperation
Get
Return _lazyValue.Value
End Get
End Property
End Class
End Namespace
' 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 System.Runtime.CompilerServices
Imports Microsoft.CodeAnalysis.Operations
Namespace Microsoft.CodeAnalysis.VisualBasic
Friend MustInherit Class BaseVisualBasicConversionExpression
Inherits BaseConversionExpression
Protected Sub New(conversion As Conversion, isTryCast As Boolean, isChecked As Boolean, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
ConversionInternal = conversion
End Sub
Friend ReadOnly Property ConversionInternal As Conversion
Public Overrides ReadOnly Property Conversion As CommonConversion
Get
Return ConversionInternal.ToCommonConversion()
End Get
End Property
End Class
Friend NotInheritable Class VisualBasicConversionExpression
Inherits BaseVisualBasicConversionExpression
Public Sub New(operand As IOperation, conversion As Conversion, isTryCast As Boolean, isChecked As Boolean, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(conversion, isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
Me.OperandImpl = operand
End Sub
Public Overrides ReadOnly Property OperandImpl As IOperation
End Class
Friend NotInheritable Class LazyVisualBasicConversionExpression
Inherits BaseVisualBasicConversionExpression
Private ReadOnly _operandLazy As Lazy(Of IOperation)
Public Sub New(operandLazy As Lazy(Of IOperation), conversion As Conversion, isTryCast As Boolean, isChecked As Boolean, semanticModel As SemanticModel, syntax As SyntaxNode, type As ITypeSymbol, constantValue As [Optional](Of Object), isImplicit As Boolean)
MyBase.New(conversion, isTryCast, isChecked, semanticModel, syntax, type, constantValue, isImplicit)
_operandLazy = operandLazy
End Sub
Public Overrides ReadOnly Property OperandImpl As IOperation
Get
Return _operandLazy.Value
End Get
End Property
End Class
End Namespace
' 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.Operations
Namespace Microsoft.CodeAnalysis.VisualBasic
Friend Class VisualBasicOperationCloner
Inherits OperationCloner
Public Shared ReadOnly Property Instance As OperationCloner = New VisualBasicOperationCloner()
Public Overrides Function VisitArgument(operation As IArgumentOperation, 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.ConstantValue, operation.IsImplicit)
End Function
Public Overrides Function VisitConversion(operation As IConversionOperation, argument As Object) As IOperation
Return New VisualBasicConversionExpression(Visit(operation.Operand), operation.GetConversion(), operation.IsTryCast, operation.IsChecked, DirectCast(operation, Operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit)
End Function
Public Overrides Function VisitCompoundAssignment(operation As ICompoundAssignmentOperation, argument As Object) As IOperation
Dim baseType = DirectCast(operation, BaseVisualBasicCompoundAssignmentOperation)
Return New VisualBasicCompoundAssignmentOperation(Visit(operation.Target), Visit(operation.Value), baseType.InConversionInternal, baseType.OutConversionInternal, operation.OperatorKind, operation.IsLifted, operation.IsChecked, operation.OperatorMethod, DirectCast(operation, Operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit)
End Function
End Class
End Namespace
...@@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.Operations ...@@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.Operations
' since same bound node appears in multiple places in the tree ' since same bound node appears in multiple places in the tree
' we can't use bound node to operation map. ' we can't use bound node to operation map.
' for now, we will just create new operation and return cloned ' for now, we will just create new operation and return cloned
Return _semanticModel.CloneOperation(CreateInternal(boundNode)) Return OperationCloner.CloneOperation(CreateInternal(boundNode))
End If End If
' A BoundUserDefined conversion is always the operand of a BoundConversion, and is handled ' A BoundUserDefined conversion is always the operand of a BoundConversion, and is handled
...@@ -557,7 +557,7 @@ Namespace Microsoft.CodeAnalysis.Operations ...@@ -557,7 +557,7 @@ Namespace Microsoft.CodeAnalysis.Operations
If conversionInfo.IsDelegateCreation Then If conversionInfo.IsDelegateCreation Then
Return New LazyDelegateCreationExpression(operand, _semanticModel, syntax, type, constantValue, isImplicit) Return New LazyDelegateCreationExpression(operand, _semanticModel, syntax, type, constantValue, isImplicit)
Else Else
Return New LazyVisualBasicConversionExpression(operand, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit) Return New LazyConversionOperation(operand, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit)
End If End If
End Function End Function
......
...@@ -69,9 +69,9 @@ Namespace Microsoft.CodeAnalysis.Operations ...@@ -69,9 +69,9 @@ Namespace Microsoft.CodeAnalysis.Operations
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignment.ConstantValueOpt) Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignment.ConstantValueOpt)
Dim isImplicit As Boolean = boundAssignment.WasCompilerGenerated Dim isImplicit As Boolean = boundAssignment.WasCompilerGenerated
Return New LazyVisualBasicCompoundAssignmentOperation(leftOperand, rightOperand, inConversion, outConversion, operatorInfo.OperatorKind, Return New LazyCompoundAssignmentOperation(leftOperand, rightOperand, inConversion, outConversion, operatorInfo.OperatorKind,
operatorInfo.IsLifted, operatorInfo.IsChecked, operatorInfo.OperatorMethod, operatorInfo.IsLifted, operatorInfo.IsChecked, operatorInfo.OperatorMethod,
_semanticModel, syntax, type, constantValue, isImplicit) _semanticModel, syntax, type, constantValue, isImplicit)
End Function End Function
Private Structure BinaryOperatorInfo Private Structure BinaryOperatorInfo
...@@ -222,12 +222,12 @@ Namespace Microsoft.CodeAnalysis.Operations ...@@ -222,12 +222,12 @@ Namespace Microsoft.CodeAnalysis.Operations
Dim argument = If(value.Syntax.Kind = SyntaxKind.OmittedArgument, value.Syntax, TryCast(value.Syntax?.Parent, ArgumentSyntax)) Dim argument = If(value.Syntax.Kind = SyntaxKind.OmittedArgument, value.Syntax, TryCast(value.Syntax?.Parent, ArgumentSyntax))
' if argument syntax doesn't exist, then this operation is implicit ' if argument syntax doesn't exist, then this operation is implicit
Return New VisualBasicArgument( Return New ArgumentOperation(
value,
kind, kind,
parameter, parameter,
value, inConversion,
inConversion:=inConversion, outConversion,
outConversion:=outConversion,
semanticModel:=_semanticModel, semanticModel:=_semanticModel,
syntax:=If(argument, value.Syntax), syntax:=If(argument, value.Syntax),
constantValue:=Nothing, constantValue:=Nothing,
......
...@@ -14,7 +14,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -14,7 +14,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' associated symbol). ''' associated symbol).
''' </summary> ''' </summary>
Public Structure Conversion Public Structure Conversion
Implements IEquatable(Of Conversion) Implements IEquatable(Of Conversion), IConvertibleConversion
Private ReadOnly _convKind As ConversionKind Private ReadOnly _convKind As ConversionKind
Private ReadOnly _method As MethodSymbol Private ReadOnly _method As MethodSymbol
...@@ -236,7 +236,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -236,7 +236,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' This is a lossy conversion; it is not possible to recover the original <see cref="Conversion"/> ''' This is a lossy conversion; it is not possible to recover the original <see cref="Conversion"/>
''' from the <see cref="CommonConversion"/> struct. ''' from the <see cref="CommonConversion"/> struct.
''' </remarks> ''' </remarks>
Public Function ToCommonConversion() As CommonConversion Public Function ToCommonConversion() As CommonConversion Implements IConvertibleConversion.ToCommonConversion
Return New CommonConversion(Exists, IsIdentity, IsNumeric, IsReference, MethodSymbol) Return New CommonConversion(Exists, IsIdentity, IsNumeric, IsReference, MethodSymbol)
End Function End Function
......
...@@ -1369,9 +1369,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1369,9 +1369,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' <exception cref="InvalidCastException">If the <see cref="IConversionOperation"/> was not created from Visual Basic code.</exception> ''' <exception cref="InvalidCastException">If the <see cref="IConversionOperation"/> was not created from Visual Basic code.</exception>
<Extension> <Extension>
Public Function GetConversion(conversionExpression As IConversionOperation) As Conversion Public Function GetConversion(conversionExpression As IConversionOperation) As Conversion
Dim basicConversionExpression = TryCast(conversionExpression, BaseVisualBasicConversionExpression) If conversionExpression.Language = LanguageNames.VisualBasic Then
If basicConversionExpression IsNot Nothing Then Return DirectCast(DirectCast(conversionExpression, BaseConversionExpression).ConvertibleConversion, Conversion)
Return basicConversionExpression.ConversionInternal
Else Else
Throw New ArgumentException(String.Format(VBResources.IConversionExpressionIsNotVisualBasicConversion, Throw New ArgumentException(String.Format(VBResources.IConversionExpressionIsNotVisualBasicConversion,
NameOf(IConversionOperation)), NameOf(IConversionOperation)),
...@@ -1387,9 +1386,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1387,9 +1386,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' <exception cref="ArgumentException">If the <see cref="IArgumentOperation"/> was not created from Visual Basic code.</exception> ''' <exception cref="ArgumentException">If the <see cref="IArgumentOperation"/> was not created from Visual Basic code.</exception>
<Extension> <Extension>
Public Function GetInConversion(argument As IArgumentOperation) As Conversion Public Function GetInConversion(argument As IArgumentOperation) As Conversion
Dim basicArgument = TryCast(argument, BaseVisualBasicArgument) If argument.Language = LanguageNames.VisualBasic Then
If basicArgument IsNot Nothing Then Return DirectCast(DirectCast(argument, BaseArgument).InConversionConvertible, Conversion)
Return basicArgument.InConversionInternal
Else Else
Throw New ArgumentException(String.Format(VBResources.IArgumentIsNotVisualBasicArgument, Throw New ArgumentException(String.Format(VBResources.IArgumentIsNotVisualBasicArgument,
NameOf(IArgumentOperation)), NameOf(IArgumentOperation)),
...@@ -1405,9 +1403,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1405,9 +1403,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' <exception cref="ArgumentException">If the <see cref="IArgumentOperation"/> was not created from Visual Basic code.</exception> ''' <exception cref="ArgumentException">If the <see cref="IArgumentOperation"/> was not created from Visual Basic code.</exception>
<Extension> <Extension>
Public Function GetOutConversion(argument As IArgumentOperation) As Conversion Public Function GetOutConversion(argument As IArgumentOperation) As Conversion
Dim basicArgument = TryCast(argument, BaseVisualBasicArgument) If argument.Language = LanguageNames.VisualBasic Then
If basicArgument IsNot Nothing Then Return DirectCast(DirectCast(argument, BaseArgument).OutConversionConvertible, Conversion)
Return basicArgument.OutConversionInternal
Else Else
Throw New ArgumentException(String.Format(VBResources.IArgumentIsNotVisualBasicArgument, Throw New ArgumentException(String.Format(VBResources.IArgumentIsNotVisualBasicArgument,
NameOf(IArgumentOperation)), NameOf(IArgumentOperation)),
...@@ -1428,9 +1425,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1428,9 +1425,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Throw New ArgumentNullException(NameOf(compoundAssignment)) Throw New ArgumentNullException(NameOf(compoundAssignment))
End If End If
Dim basicCompoundOperation = TryCast(compoundAssignment, BaseVisualBasicCompoundAssignmentOperation) If compoundAssignment.Language = LanguageNames.VisualBasic Then
If basicCompoundOperation IsNot Nothing Then Return DirectCast(DirectCast(compoundAssignment, BaseCompoundAssignmentExpression).InConversionConvertible, Conversion)
Return basicCompoundOperation.InConversionInternal
Else Else
Throw New ArgumentException(String.Format(VBResources.ICompoundAssignmentOperationIsNotVisualBasicCompoundAssignment, Throw New ArgumentException(String.Format(VBResources.ICompoundAssignmentOperationIsNotVisualBasicCompoundAssignment,
NameOf(compoundAssignment)), NameOf(compoundAssignment)),
...@@ -1451,9 +1447,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1451,9 +1447,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Throw New ArgumentNullException(NameOf(compoundAssignment)) Throw New ArgumentNullException(NameOf(compoundAssignment))
End If End If
Dim basicCompoundOperation = TryCast(compoundAssignment, BaseVisualBasicCompoundAssignmentOperation) If compoundAssignment.Language = LanguageNames.VisualBasic Then
If basicCompoundOperation IsNot Nothing Then Return DirectCast(DirectCast(compoundAssignment, BaseCompoundAssignmentExpression).OutConversionConvertible, Conversion)
Return basicCompoundOperation.OutConversionInternal
Else Else
Throw New ArgumentException(String.Format(VBResources.ICompoundAssignmentOperationIsNotVisualBasicCompoundAssignment, Throw New ArgumentException(String.Format(VBResources.ICompoundAssignmentOperationIsNotVisualBasicCompoundAssignment,
NameOf(compoundAssignment)), NameOf(compoundAssignment)),
......
...@@ -618,7 +618,7 @@ internal static void VerifyClone(SemanticModel model) ...@@ -618,7 +618,7 @@ internal static void VerifyClone(SemanticModel model)
continue; continue;
} }
var clonedOperation = model.CloneOperation(operation); var clonedOperation = OperationCloner.CloneOperation(operation);
// check whether cloned IOperation is same as original one // check whether cloned IOperation is same as original one
var original = OperationTreeVerifier.GetOperationTree(model.Compilation, operation); var original = OperationTreeVerifier.GetOperationTree(model.Compilation, operation);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册