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

Merge pull request #33178 from 333fred/rpatterns-33018

Make IPropertySubpattern Internal
......@@ -1996,6 +1996,7 @@ private IOperation CreateBoundDiscardPatternOperation(BoundDiscardPattern boundN
boundNode.Syntax,
isImplicit: boundNode.WasCompilerGenerated);
}
private IOperation CreateUsingLocalDeclarationsOperation(BoundUsingLocalDeclarations boundNode)
{
//TODO: Implement UsingLocalDeclaration operations correctly.
......@@ -2007,5 +2008,40 @@ private IOperation CreateUsingLocalDeclarationsOperation(BoundUsingLocalDeclarat
getChildren: () => ImmutableArray.Create<IOperation>(CreateBoundMultipleLocalDeclarationsOperation((BoundMultipleLocalDeclarations)boundNode)),
isImplicit: false);
}
internal IPropertySubpatternOperation CreatePropertySubpattern(BoundSubpattern subpattern, ITypeSymbol matchedType)
{
SyntaxNode syntax = subpattern.Syntax;
return new CSharpLazyPropertySubpatternOperation(this, subpattern, matchedType, syntax, _semanticModel);
}
internal IOperation CreatePropertySubpatternMember(Symbol symbol, ITypeSymbol matchedType, SyntaxNode syntax)
{
var nameSyntax = (syntax is SubpatternSyntax subpatSyntax ? subpatSyntax.NameColon?.Name : null) ?? syntax;
bool isImplicit = nameSyntax == syntax;
switch (symbol)
{
case FieldSymbol field:
{
var constantValue = field.ConstantValue is null ? default(Optional<object>) : new Optional<object>(field.ConstantValue);
var receiver = new InstanceReferenceOperation(
InstanceReferenceKind.PatternInput, _semanticModel, nameSyntax, matchedType, constantValue, isImplicit: true);
return new FieldReferenceOperation(
field, isDeclaration: false, receiver, _semanticModel, nameSyntax, field.Type.TypeSymbol, constantValue, isImplicit: isImplicit);
}
case PropertySymbol property:
{
var receiver = new InstanceReferenceOperation(
InstanceReferenceKind.PatternInput, _semanticModel, nameSyntax, matchedType, constantValue: default, isImplicit: true);
return new PropertyReferenceOperation(
property, receiver, ImmutableArray<IArgumentOperation>.Empty, _semanticModel, nameSyntax, property.Type.TypeSymbol,
constantValue: default, isImplicit: isImplicit);
}
default:
// We should expose the symbol in this case somehow:
// https://github.com/dotnet/roslyn/issues/33175
return OperationFactory.CreateInvalidOperation(_semanticModel, nameSyntax, ImmutableArray<IOperation>.Empty, isImplicit);
}
}
}
}
......@@ -14,7 +14,7 @@ internal sealed partial class CSharpOperationFactory
{
private static readonly IConvertibleConversion s_boxedIdentityConversion = Conversion.Identity;
private static Optional<object> ConvertToOptional(ConstantValue value)
internal static Optional<object> ConvertToOptional(ConstantValue value)
{
return value != null && !value.IsBad ? new Optional<object>(value.Value) : default(Optional<object>);
}
......
......@@ -1492,7 +1492,10 @@ internal sealed partial class CSharpLazyRecursivePatternOperation : LazyRecursiv
private readonly CSharpOperationFactory _operationFactory;
private readonly BoundRecursivePattern _boundRecursivePattern;
public CSharpLazyRecursivePatternOperation(CSharpOperationFactory operationFactory, BoundRecursivePattern boundRecursivePattern, SemanticModel semanticModel)
public CSharpLazyRecursivePatternOperation(
CSharpOperationFactory operationFactory,
BoundRecursivePattern boundRecursivePattern,
SemanticModel semanticModel)
: base(inputType: boundRecursivePattern.InputType,
matchedType: boundRecursivePattern.DeclaredType?.Type ?? boundRecursivePattern.InputType.StrippedType(),
deconstructSymbol: boundRecursivePattern.DeconstructMethod,
......@@ -1501,8 +1504,8 @@ public CSharpLazyRecursivePatternOperation(CSharpOperationFactory operationFacto
syntax: boundRecursivePattern.Syntax,
isImplicit: boundRecursivePattern.WasCompilerGenerated)
{
this._operationFactory = operationFactory;
this._boundRecursivePattern = boundRecursivePattern;
_operationFactory = operationFactory;
_boundRecursivePattern = boundRecursivePattern;
}
public override ImmutableArray<IPatternOperation> CreateDeconstructionSubpatterns()
......@@ -1510,15 +1513,44 @@ public override ImmutableArray<IPatternOperation> CreateDeconstructionSubpattern
return _boundRecursivePattern.Deconstruction.IsDefault ? ImmutableArray<IPatternOperation>.Empty :
_boundRecursivePattern.Deconstruction.SelectAsArray((p, fac) => (IPatternOperation)fac.Create(p.Pattern), _operationFactory);
}
public override ImmutableArray<(ISymbol, IPatternOperation)> CreatePropertySubpatterns()
public override ImmutableArray<IPropertySubpatternOperation> CreatePropertySubpatterns()
{
return _boundRecursivePattern.Properties.IsDefault ? ImmutableArray<IPropertySubpatternOperation>.Empty :
_boundRecursivePattern.Properties.SelectAsArray((p, recursivePattern) => recursivePattern._operationFactory.CreatePropertySubpattern(p, recursivePattern.MatchedType), this);
}
}
internal sealed partial class CSharpLazyPropertySubpatternOperation : LazyPropertySubpatternOperation
{
private readonly BoundSubpattern _subpattern;
private readonly CSharpOperationFactory _operationFactory;
private readonly ITypeSymbol _matchedType;
public CSharpLazyPropertySubpatternOperation(
CSharpOperationFactory operationFactory,
BoundSubpattern subpattern,
ITypeSymbol matchedType,
SyntaxNode syntax,
SemanticModel semanticModel)
: base(semanticModel, syntax, isImplicit: false)
{
_subpattern = subpattern;
_operationFactory = operationFactory;
_matchedType = matchedType;
}
public override IOperation CreateMember()
{
return _operationFactory.CreatePropertySubpatternMember(_subpattern.Symbol, _matchedType, Syntax);
}
public override IPatternOperation CreatePattern()
{
return _boundRecursivePattern.Properties.IsDefault ? ImmutableArray<(ISymbol, IPatternOperation)>.Empty :
_boundRecursivePattern.Properties.SelectAsArray((p, fac) => ((ISymbol)p.Symbol, (IPatternOperation)fac.Create(p.Pattern)), _operationFactory);
return (IPatternOperation)_operationFactory.Create(_subpattern.Pattern);
}
}
/// <summary>
/// Represents a C# recursive pattern.
/// Represents a C# recursive pattern using ITuple.
/// </summary>
internal sealed partial class CSharpLazyITuplePatternOperation : LazyRecursivePatternOperation
{
......@@ -1534,8 +1566,8 @@ public CSharpLazyITuplePatternOperation(CSharpOperationFactory operationFactory,
syntax: boundITuplePattern.Syntax,
isImplicit: boundITuplePattern.WasCompilerGenerated)
{
this._operationFactory = operationFactory;
this._boundITuplePattern = boundITuplePattern;
_operationFactory = operationFactory;
_boundITuplePattern = boundITuplePattern;
}
public override ImmutableArray<IPatternOperation> CreateDeconstructionSubpatterns()
......@@ -1543,9 +1575,9 @@ public override ImmutableArray<IPatternOperation> CreateDeconstructionSubpattern
return _boundITuplePattern.Subpatterns.IsDefault ? ImmutableArray<IPatternOperation>.Empty :
_boundITuplePattern.Subpatterns.SelectAsArray((p, fac) => (IPatternOperation)fac.Create(p.Pattern), _operationFactory);
}
public override ImmutableArray<(ISymbol, IPatternOperation)> CreatePropertySubpatterns()
public override ImmutableArray<IPropertySubpatternOperation> CreatePropertySubpatterns()
{
return ImmutableArray<(ISymbol, IPatternOperation)>.Empty;
return ImmutableArray<IPropertySubpatternOperation>.Empty;
}
}
......@@ -1603,8 +1635,8 @@ internal sealed class CSharpLazySwitchExpressionOperation : LazySwitchExpression
public CSharpLazySwitchExpressionOperation(CSharpOperationFactory operationFactory, BoundSwitchExpression boundSwitchExpression, SemanticModel semanticModel)
: base(boundSwitchExpression.Type, semanticModel, boundSwitchExpression.Syntax, boundSwitchExpression.WasCompilerGenerated)
{
this._operationFactory = operationFactory;
this._switchExpression = boundSwitchExpression;
_operationFactory = operationFactory;
_switchExpression = boundSwitchExpression;
}
protected override IOperation CreateValue()
......@@ -1625,8 +1657,8 @@ internal sealed class CSharpLazySwitchExpressionArmOperation : LazySwitchExpress
public CSharpLazySwitchExpressionArmOperation(CSharpOperationFactory operationFactory, BoundSwitchExpressionArm boundSwitchExpressionArm, SemanticModel semanticModel)
: base(boundSwitchExpressionArm.Locals.Cast<CSharp.Symbols.LocalSymbol, ILocalSymbol>(), semanticModel, boundSwitchExpressionArm.Syntax, boundSwitchExpressionArm.WasCompilerGenerated)
{
this._operationFactory = operationFactory;
this._switchExpressionArm = boundSwitchExpressionArm;
_operationFactory = operationFactory;
_switchExpressionArm = boundSwitchExpressionArm;
}
protected override IOperation CreateGuard()
......
......@@ -6547,20 +6547,30 @@ public override IOperation VisitDeclarationPattern(IDeclarationPatternOperation
operation.Syntax, IsImplicit(operation));
}
public override IOperation VisitRecursivePattern(IRecursivePatternOperation operation, int? argument)
internal override IOperation VisitRecursivePattern(IRecursivePatternOperation operation, int? argument)
{
return new RecursivePatternOperation(
inputType: operation.InputType,
matchedType: operation.MatchedType,
operation.DeconstructSymbol,
operation.DeconstructionSubpatterns.SelectAsArray(p => (IPatternOperation)Visit(p)),
operation.PropertySubpatterns.SelectAsArray(p => (p.Item1, (IPatternOperation)Visit(p.Item2))),
operation.PropertySubpatterns.SelectAsArray(p => (IPropertySubpatternOperation)Visit(p)),
operation.DeclaredSymbol,
semanticModel: null,
operation.Syntax,
IsImplicit(operation));
}
internal override IOperation VisitPropertySubpattern(IPropertySubpatternOperation operation, int? argument)
{
return new PropertySubpatternOperation(
semanticModel: null,
operation.Syntax,
IsImplicit(operation),
Visit(operation.Member),
(IPatternOperation)Visit(operation.Pattern));
}
public override IOperation VisitDelegateCreation(IDelegateCreationOperation operation, int? captureIdForResult)
{
return new DelegateCreationOperation(Visit(operation.Target), semanticModel: null,
......
// 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
{
/// <summary>
/// Represents an element of a property subpattern, which identifies a member to be matched and the
/// pattern to match it against.
/// </summary>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
internal interface IPropertySubpatternOperation : IOperation
{
/// <summary>
/// The member being matched in a property subpattern. This can be a <see cref="IMemberReferenceOperation"/>
/// in non-error cases, or an <see cref="IInvalidOperation"/> in error cases.
/// </summary>
// The symbol should be exposed for error cases somehow:
// https://github.com/dotnet/roslyn/issues/33175
IOperation Member { get; }
/// <summary>
/// The pattern to which the member is matched in a property subpattern.
/// </summary>
IPatternOperation Pattern { get; }
}
}
......@@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.Operations
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
public interface IRecursivePatternOperation : IPatternOperation
internal interface IRecursivePatternOperation : IPatternOperation
{
/// <summary>
/// The type accepted for the recursive pattern.
......@@ -33,7 +33,7 @@ public interface IRecursivePatternOperation : IPatternOperation
/// <summary>
/// This contains the (symbol, property) pairs within a property subpattern.
/// </summary>
ImmutableArray<(ISymbol, IPatternOperation)> PropertySubpatterns { get; }
ImmutableArray<IPropertySubpatternOperation> PropertySubpatterns { get; }
/// <summary>
/// Symbol declared by the pattern.
......
......@@ -17,5 +17,9 @@ public enum InstanceReferenceKind
/// anonymous type creation initializer, or to the object being referred to in a VB With statement.
/// </summary>
ImplicitReceiver,
/// <summary>
/// Reference to the value being matching in a property subpattern.
/// </summary>
PatternInput,
}
}
......@@ -535,7 +535,7 @@ public override IOperation VisitDeclarationPattern(IDeclarationPatternOperation
((Operation)operation).OwningSemanticModel, operation.Syntax, operation.IsImplicit);
}
public override IOperation VisitRecursivePattern(IRecursivePatternOperation operation, object argument)
internal override IOperation VisitRecursivePattern(IRecursivePatternOperation operation, object argument)
{
return new RecursivePatternOperation(
operation.InputType,
......@@ -549,6 +549,16 @@ public override IOperation VisitRecursivePattern(IRecursivePatternOperation oper
operation.IsImplicit);
}
internal override IOperation VisitPropertySubpattern(IPropertySubpatternOperation operation, object argument)
{
return new PropertySubpatternOperation(
semanticModel: ((Operation)operation).OwningSemanticModel,
operation.Syntax,
operation.IsImplicit,
Visit(operation.Member),
Visit(operation.Pattern));
}
public override IOperation VisitPatternCaseClause(IPatternCaseClauseOperation operation, object argument)
{
return new PatternCaseClauseOperation(operation.Label, Visit(operation.Pattern), Visit(operation.Guard), ((Operation)operation).OwningSemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
......
......@@ -7965,7 +7965,8 @@ internal abstract partial class BaseRecursivePatternOperation : Operation, IRecu
ITypeSymbol inputType,
ITypeSymbol matchedType,
ISymbol deconstructSymbol,
ISymbol declaredSymbol, SemanticModel semanticModel,
ISymbol declaredSymbol,
SemanticModel semanticModel,
SyntaxNode syntax,
bool isImplicit)
: base(OperationKind.RecursivePattern, semanticModel, syntax, type: default, constantValue: default, isImplicit)
......@@ -7979,7 +7980,7 @@ internal abstract partial class BaseRecursivePatternOperation : Operation, IRecu
public ITypeSymbol MatchedType { get; }
public ISymbol DeconstructSymbol { get; }
public abstract ImmutableArray<IPatternOperation> DeconstructionSubpatterns { get; }
public abstract ImmutableArray<(ISymbol, IPatternOperation)> PropertySubpatterns { get; }
public abstract ImmutableArray<IPropertySubpatternOperation> PropertySubpatterns { get; }
public ISymbol DeclaredSymbol { get; }
public override IEnumerable<IOperation> Children
{
......@@ -7992,7 +7993,7 @@ public override IEnumerable<IOperation> Children
foreach (var p in PropertySubpatterns)
{
yield return p.Item2;
yield return p;
}
}
}
......@@ -8017,7 +8018,7 @@ internal sealed partial class RecursivePatternOperation : BaseRecursivePatternOp
ITypeSymbol matchedType,
ISymbol deconstructSymbol,
ImmutableArray<IPatternOperation> deconstructionSubpatterns,
ImmutableArray<(ISymbol, IPatternOperation)> propertySubpatterns,
ImmutableArray<IPropertySubpatternOperation> propertySubpatterns,
ISymbol declaredSymbol, SemanticModel semanticModel,
SyntaxNode syntax,
bool isImplicit)
......@@ -8025,32 +8026,30 @@ internal sealed partial class RecursivePatternOperation : BaseRecursivePatternOp
{
SetParentOperation(deconstructionSubpatterns, this);
DeconstructionSubpatterns = deconstructionSubpatterns;
foreach (var p in propertySubpatterns)
{
SetParentOperation(p.Item2, this);
}
SetParentOperation(propertySubpatterns, this);
PropertySubpatterns = propertySubpatterns;
}
public override ImmutableArray<IPatternOperation> DeconstructionSubpatterns { get; }
public override ImmutableArray<(ISymbol, IPatternOperation)> PropertySubpatterns { get; }
public override ImmutableArray<IPropertySubpatternOperation> PropertySubpatterns { get; }
}
internal abstract partial class LazyRecursivePatternOperation : BaseRecursivePatternOperation
{
private ImmutableArray<IPatternOperation> _lazyDeconstructionSubpatterns;
private ImmutableArray<(ISymbol, IPatternOperation)> _lazyPropertySubpatterns;
private ImmutableArray<IPropertySubpatternOperation> _lazyPropertySubpatterns;
public LazyRecursivePatternOperation(
ITypeSymbol inputType,
ITypeSymbol matchedType,
ISymbol deconstructSymbol,
ISymbol declaredSymbol, SemanticModel semanticModel,
ISymbol declaredSymbol,
SemanticModel semanticModel,
SyntaxNode syntax,
bool isImplicit)
: base(inputType, matchedType, deconstructSymbol, declaredSymbol, semanticModel, syntax, isImplicit)
{
}
public abstract ImmutableArray<IPatternOperation> CreateDeconstructionSubpatterns();
public abstract ImmutableArray<(ISymbol, IPatternOperation)> CreatePropertySubpatterns();
public abstract ImmutableArray<IPropertySubpatternOperation> CreatePropertySubpatterns();
public override ImmutableArray<IPatternOperation> DeconstructionSubpatterns
{
get
......@@ -8069,7 +8068,7 @@ public override ImmutableArray<IPatternOperation> DeconstructionSubpatterns
return _lazyDeconstructionSubpatterns;
}
}
public override ImmutableArray<(ISymbol, IPatternOperation)> PropertySubpatterns
public override ImmutableArray<IPropertySubpatternOperation> PropertySubpatterns
{
get
{
......@@ -8078,7 +8077,7 @@ public override ImmutableArray<IPatternOperation> DeconstructionSubpatterns
var propertySubpatterns = CreatePropertySubpatterns();
foreach (var propertySubpattern in propertySubpatterns)
{
SetParentOperation(propertySubpattern.Item2, this);
SetParentOperation(propertySubpattern, this);
}
ImmutableInterlocked.InterlockedInitialize(ref _lazyPropertySubpatterns, propertySubpatterns);
......@@ -8089,6 +8088,100 @@ public override ImmutableArray<IPatternOperation> DeconstructionSubpatterns
}
}
internal abstract partial class BasePropertySubpatternOperation : Operation, IPropertySubpatternOperation
{
public BasePropertySubpatternOperation(
SemanticModel semanticModel,
SyntaxNode syntax,
bool isImplicit)
: base(OperationKind.None, semanticModel, syntax, type: default, constantValue: default, isImplicit)
{
}
public abstract IOperation Member { get; }
public abstract IPatternOperation Pattern { get; }
public override IEnumerable<IOperation> Children
{
get
{
if (Member != null)
yield return Member;
if (Pattern != null)
yield return Pattern;
}
}
public override void Accept(OperationVisitor visitor)
{
visitor.VisitPropertySubpattern(this);
}
public override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitPropertySubpattern(this, argument);
}
}
internal sealed partial class PropertySubpatternOperation : BasePropertySubpatternOperation
{
public PropertySubpatternOperation(
SemanticModel semanticModel,
SyntaxNode syntax,
bool isImplicit,
IOperation member,
IPatternOperation pattern)
: base(semanticModel, syntax, isImplicit)
{
SetParentOperation(member, this);
Member = member;
SetParentOperation(pattern, this);
Pattern = pattern;
}
public override IOperation Member { get; }
public override IPatternOperation Pattern { get; }
}
internal abstract partial class LazyPropertySubpatternOperation : BasePropertySubpatternOperation
{
private IOperation _lazyMember = s_unset;
private IPatternOperation _lazyPattern = s_unsetPattern;
public LazyPropertySubpatternOperation(
SemanticModel semanticModel,
SyntaxNode syntax,
bool isImplicit)
: base(semanticModel, syntax, isImplicit)
{
}
public abstract IOperation CreateMember();
public abstract IPatternOperation CreatePattern();
public override IOperation Member
{
get
{
if (_lazyMember == s_unset)
{
var member = CreateMember();
SetParentOperation(member, this);
Interlocked.CompareExchange(ref _lazyMember, member, s_unset);
}
return _lazyMember;
}
}
public override IPatternOperation Pattern
{
get
{
if (_lazyPattern == s_unsetPattern)
{
var pattern = CreatePattern();
SetParentOperation(pattern, this);
Interlocked.CompareExchange(ref _lazyPattern, pattern, s_unsetPattern);
}
return _lazyPattern;
}
}
}
/// <summary>
/// Represents a C# pattern case clause.
/// </summary>
......
......@@ -505,7 +505,12 @@ public virtual void VisitDeclarationPattern(IDeclarationPatternOperation operati
DefaultVisit(operation);
}
public virtual void VisitRecursivePattern(IRecursivePatternOperation operation)
internal virtual void VisitRecursivePattern(IRecursivePatternOperation operation)
{
DefaultVisit(operation);
}
internal virtual void VisitPropertySubpattern(IPropertySubpatternOperation operation)
{
DefaultVisit(operation);
}
......@@ -1113,7 +1118,12 @@ public virtual TResult VisitDeclarationPattern(IDeclarationPatternOperation oper
return DefaultVisit(operation, argument);
}
public virtual TResult VisitRecursivePattern(IRecursivePatternOperation operation, TArgument argument)
internal virtual TResult VisitRecursivePattern(IRecursivePatternOperation operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
internal virtual TResult VisitPropertySubpattern(IPropertySubpatternOperation operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
......
......@@ -16,15 +16,10 @@ Microsoft.CodeAnalysis.Operations.IDeclarationPatternOperation.MatchedType.get -
Microsoft.CodeAnalysis.Operations.IDeclarationPatternOperation.MatchesNull.get -> bool
Microsoft.CodeAnalysis.Operations.IDiscardPatternOperation
Microsoft.CodeAnalysis.Operations.IPatternOperation.InputType.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.Operations.InstanceReferenceKind.PatternInput = 2 -> Microsoft.CodeAnalysis.Operations.InstanceReferenceKind
Microsoft.CodeAnalysis.SymbolDisplayPartKind.ConstantName = 30 -> Microsoft.CodeAnalysis.SymbolDisplayPartKind
Microsoft.CodeAnalysis.SymbolDisplayPartKind.EnumMemberName = 28 -> Microsoft.CodeAnalysis.SymbolDisplayPartKind
Microsoft.CodeAnalysis.SymbolDisplayPartKind.ExtensionMethodName = 29 -> Microsoft.CodeAnalysis.SymbolDisplayPartKind
Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation
Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation.DeclaredSymbol.get -> Microsoft.CodeAnalysis.ISymbol
Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation.DeconstructSymbol.get -> Microsoft.CodeAnalysis.ISymbol
Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation.DeconstructionSubpatterns.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Operations.IPatternOperation>
Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation.MatchedType.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation.PropertySubpatterns.get -> System.Collections.Immutable.ImmutableArray<(Microsoft.CodeAnalysis.ISymbol, Microsoft.CodeAnalysis.Operations.IPatternOperation)>
Microsoft.CodeAnalysis.Operations.ISwitchExpressionArmOperation
Microsoft.CodeAnalysis.Operations.ISwitchExpressionArmOperation.Guard.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Operations.ISwitchExpressionArmOperation.Locals.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
......@@ -212,7 +207,6 @@ virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitIsNull(Microsoft
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitRangeOperation(Microsoft.CodeAnalysis.Operations.IRangeOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitReDim(Microsoft.CodeAnalysis.Operations.IReDimOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitReDimClause(Microsoft.CodeAnalysis.Operations.IReDimClauseOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitRecursivePattern(Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitStaticLocalInitializationSemaphore(Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitSwitchExpression(Microsoft.CodeAnalysis.Operations.ISwitchExpressionOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitSwitchExpressionArm(Microsoft.CodeAnalysis.Operations.ISwitchExpressionArmOperation operation) -> void
......@@ -226,7 +220,6 @@ virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.V
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitRangeOperation(Microsoft.CodeAnalysis.Operations.IRangeOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitReDim(Microsoft.CodeAnalysis.Operations.IReDimOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitReDimClause(Microsoft.CodeAnalysis.Operations.IReDimClauseOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitRecursivePattern(Microsoft.CodeAnalysis.Operations.IRecursivePatternOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitStaticLocalInitializationSemaphore(Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitSwitchExpression(Microsoft.CodeAnalysis.Operations.ISwitchExpressionOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitSwitchExpressionArm(Microsoft.CodeAnalysis.Operations.ISwitchExpressionArmOperation operation, TArgument argument) -> TResult
......@@ -1728,14 +1728,16 @@ private static bool CanBeInControlFlowGraph(IOperation n)
case OperationKind.InstanceReference:
// Implicit instance receivers, except for anonymous type creations, are expected to have been removed when dealing with creations.
return ((IInstanceReferenceOperation)n).ReferenceKind == InstanceReferenceKind.ContainingTypeInstance ||
((IInstanceReferenceOperation)n).ReferenceKind == InstanceReferenceKind.ImplicitReceiver &&
n.Type.IsAnonymousType &&
n.Parent is IPropertyReferenceOperation propertyReference &&
propertyReference.Instance == n &&
propertyReference.Parent is ISimpleAssignmentOperation simpleAssignment &&
simpleAssignment.Target == propertyReference &&
simpleAssignment.Parent.Kind == OperationKind.AnonymousObjectCreation;
var instanceReference = (IInstanceReferenceOperation)n;
return instanceReference.ReferenceKind == InstanceReferenceKind.ContainingTypeInstance ||
instanceReference.ReferenceKind == InstanceReferenceKind.PatternInput ||
(instanceReference.ReferenceKind == InstanceReferenceKind.ImplicitReceiver &&
n.Type.IsAnonymousType &&
n.Parent is IPropertyReferenceOperation propertyReference &&
propertyReference.Instance == n &&
propertyReference.Parent is ISimpleAssignmentOperation simpleAssignment &&
simpleAssignment.Target == propertyReference &&
simpleAssignment.Parent.Kind == OperationKind.AnonymousObjectCreation);
case OperationKind.None:
return !(n is IPlaceholderOperation);
......
......@@ -1762,7 +1762,7 @@ public override void VisitDeclarationPattern(IDeclarationPatternOperation operat
LogNewLine();
}
public override void VisitRecursivePattern(IRecursivePatternOperation operation)
internal override void VisitRecursivePattern(IRecursivePatternOperation operation)
{
LogString(nameof(IRecursivePatternOperation));
LogPatternProperties(operation);
......@@ -1773,11 +1773,17 @@ public override void VisitRecursivePattern(IRecursivePatternOperation operation)
LogNewLine();
VisitArray(operation.DeconstructionSubpatterns, $"{nameof(operation.DeconstructionSubpatterns)} ", true, true);
VisitArrayCommon(operation.PropertySubpatterns, $"{nameof(operation.PropertySubpatterns)} ", true, true, subpat =>
{
LogSymbol(subpat.Item1, "MatchedSymbol");
Visit(subpat.Item2, ", Pattern");
});
VisitArray(operation.PropertySubpatterns, $"{nameof(operation.PropertySubpatterns)} ", true, true);
}
internal override void VisitPropertySubpattern(IPropertySubpatternOperation operation)
{
LogString(nameof(IPropertySubpatternOperation));
LogCommonProperties(operation);
LogNewLine();
Visit(operation.Member, $"{nameof(operation.Member)}");
Visit(operation.Pattern, $"{nameof(operation.Pattern)}");
}
public override void VisitIsPattern(IIsPatternOperation operation)
......
......@@ -1151,7 +1151,7 @@ public override void VisitDeclarationPattern(IDeclarationPatternOperation operat
Assert.Empty(operation.Children);
}
public override void VisitRecursivePattern(IRecursivePatternOperation operation)
internal override void VisitRecursivePattern(IRecursivePatternOperation operation)
{
Assert.Equal(OperationKind.RecursivePattern, operation.Kind);
VisitPatternCommon(operation);
......@@ -1186,25 +1186,38 @@ public override void VisitRecursivePattern(IRecursivePatternOperation operation)
foreach (var subpat in operation.PropertySubpatterns)
{
var (symbol, pattern) = subpat;
switch (symbol)
{
case null: // error case
break;
case IFieldSymbol field:
case IPropertySymbol prop:
case IErrorTypeSymbol error:
break;
default:
Assert.True(false, $"Unexpected symbol {symbol}");
break;
}
Assert.True(subpat is IPropertySubpatternOperation);
}
IEnumerable<IOperation> children = operation.DeconstructionSubpatterns.Cast<IOperation>();
children = children.Concat(operation.PropertySubpatterns.Select(x => x.Item2));
children = children.Concat(operation.PropertySubpatterns);
AssertEx.Equal(children, operation.Children);
}
internal override void VisitPropertySubpattern(IPropertySubpatternOperation operation)
{
Assert.NotNull(operation.Pattern);
var children = new IOperation[] { operation.Member, operation.Pattern };
AssertEx.Equal(children, operation.Children);
if (operation.Member.Kind == OperationKind.Invalid)
{
return;
}
Assert.True(operation.Member is IMemberReferenceOperation);
var member = (IMemberReferenceOperation)operation.Member;
switch (member.Member)
{
case IFieldSymbol field:
case IPropertySymbol prop:
case IErrorTypeSymbol error:
break;
case var symbol:
Assert.True(false, $"Unexpected symbol {symbol}");
break;
}
}
public override void VisitSwitchExpression(ISwitchExpressionOperation operation)
......
// 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.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Operations;
namespace Microsoft.CodeAnalysis
......@@ -57,7 +58,7 @@ public static ValueUsageInfo GetValueUsageInfo(this IOperation operation)
//
return ValueUsageInfo.Write;
case IRecursivePatternOperation _:
case IOperation iop when iop.GetType().GetInterfaces().Any(i => i.Name == "IRecursivePatternOperation"):
// A declaration pattern within a recursive pattern is a
// write for the declared local.
// For example, 'x' is defined and assigned the value from 'obj' below:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册