diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props
index ddb10ff6c6988..f853bdb36475d 100644
--- a/eng/targets/Settings.props
+++ b/eng/targets/Settings.props
@@ -207,7 +207,8 @@
and hence suppress this warning until we get closer to release and a more
thorough documentation story
-->
- $(NoWarn);1573;1591;1701
+
+ $(NoWarn);1573;1591;1701;RS0016
$(DefineConstants);$(InitialDefineConstants)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 539c4c0801cd7..674b9140fd428 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6606,4 +6606,13 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Inheriting from a record with a sealed 'Object.ToString' is not supported in C# {0}. Please use language version '{1}' or greater.
+
+ list pattern
+
+
+ slice pattern
+
+
+ length pattern
+
diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
index a3bf13c2fb869..17d0394518890 100644
--- a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs
@@ -4418,6 +4418,7 @@ private SymbolInfo GetNamedArgumentSymbolInfo(IdentifierNameSyntax identifierNam
return (object)tupleElement == null ? SymbolInfo.None : new SymbolInfo(tupleElement, ImmutableArray.Empty, CandidateReason.None);
}
+ // PROTOTYPE(list-patterns) SyntaxKind.ListPatternClause
if (parent3.IsKind(SyntaxKind.PropertyPatternClause) || parent3.IsKind(SyntaxKind.PositionalPatternClause))
{
return GetSymbolInfoWorker(identifierNameSyntax, SymbolInfoOptions.DefaultOptions, cancellationToken);
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
index a999ea580e0de..be149388722dd 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
@@ -191,6 +191,11 @@ internal enum MessageID
IDS_FeatureExternLocalFunctions = MessageBase + 12767,
IDS_FeatureMemberNotNull = MessageBase + 12768,
+ // PROTOTYPE(list-patterns) To reduce conflicts with upstream. Should be moved eventually.
+ IDS_FeatureListPattern = MessageBase + 12800,
+ IDS_FeatureSlicePattern,
+ IDS_FeatureLengthPattern,
+
IDS_FeatureNativeInt = MessageBase + 12769,
IDS_FeatureImplicitObjectCreation = MessageBase + 12770,
IDS_FeatureTypePattern = MessageBase + 12771,
@@ -491,6 +496,12 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
default:
throw ExceptionUtilities.UnexpectedValue(feature);
+
+ // PROTOTYPE(list-patterns)
+ case MessageID.IDS_FeatureListPattern:
+ case MessageID.IDS_FeatureSlicePattern:
+ case MessageID.IDS_FeatureLengthPattern:
+ return LanguageVersion.Preview;
}
}
}
diff --git a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4
index e40f3eaedb827..dcf98ead9c9d9 100644
--- a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4
+++ b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4
@@ -550,6 +550,7 @@ pattern
| parenthesized_pattern
| recursive_pattern
| relational_pattern
+ | slice_pattern
| type_pattern
| unary_pattern
| var_pattern
@@ -594,7 +595,7 @@ parenthesized_pattern
;
recursive_pattern
- : type? positional_pattern_clause? property_pattern_clause? variable_designation?
+ : type? positional_pattern_clause? length_pattern_clause? property_pattern_clause? variable_designation?
;
positional_pattern_clause
@@ -605,6 +606,10 @@ subpattern
: name_colon? pattern
;
+length_pattern_clause
+ : '[' pattern ']'
+ ;
+
property_pattern_clause
: '{' (subpattern (',' subpattern)* ','?)? '}'
;
@@ -618,6 +623,10 @@ relational_pattern
| '>=' expression
;
+slice_pattern
+ : '..' pattern?
+ ;
+
type_pattern
: type
;
diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs
index 7a4108972ee84..393f4e5c9d45d 100644
--- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs
@@ -10460,13 +10460,14 @@ internal sealed partial class RecursivePatternSyntax : PatternSyntax
{
internal readonly TypeSyntax? type;
internal readonly PositionalPatternClauseSyntax? positionalPatternClause;
+ internal readonly LengthPatternClauseSyntax? lengthPatternClause;
internal readonly PropertyPatternClauseSyntax? propertyPatternClause;
internal readonly VariableDesignationSyntax? designation;
- internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations)
+ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations)
: base(kind, diagnostics, annotations)
{
- this.SlotCount = 4;
+ this.SlotCount = 5;
if (type != null)
{
this.AdjustFlagsAndWidth(type);
@@ -10477,6 +10478,11 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
this.AdjustFlagsAndWidth(positionalPatternClause);
this.positionalPatternClause = positionalPatternClause;
}
+ if (lengthPatternClause != null)
+ {
+ this.AdjustFlagsAndWidth(lengthPatternClause);
+ this.lengthPatternClause = lengthPatternClause;
+ }
if (propertyPatternClause != null)
{
this.AdjustFlagsAndWidth(propertyPatternClause);
@@ -10489,11 +10495,11 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
}
}
- internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation, SyntaxFactoryContext context)
+ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation, SyntaxFactoryContext context)
: base(kind)
{
this.SetFactoryContext(context);
- this.SlotCount = 4;
+ this.SlotCount = 5;
if (type != null)
{
this.AdjustFlagsAndWidth(type);
@@ -10504,6 +10510,11 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
this.AdjustFlagsAndWidth(positionalPatternClause);
this.positionalPatternClause = positionalPatternClause;
}
+ if (lengthPatternClause != null)
+ {
+ this.AdjustFlagsAndWidth(lengthPatternClause);
+ this.lengthPatternClause = lengthPatternClause;
+ }
if (propertyPatternClause != null)
{
this.AdjustFlagsAndWidth(propertyPatternClause);
@@ -10516,10 +10527,10 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
}
}
- internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
: base(kind)
{
- this.SlotCount = 4;
+ this.SlotCount = 5;
if (type != null)
{
this.AdjustFlagsAndWidth(type);
@@ -10530,6 +10541,11 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
this.AdjustFlagsAndWidth(positionalPatternClause);
this.positionalPatternClause = positionalPatternClause;
}
+ if (lengthPatternClause != null)
+ {
+ this.AdjustFlagsAndWidth(lengthPatternClause);
+ this.lengthPatternClause = lengthPatternClause;
+ }
if (propertyPatternClause != null)
{
this.AdjustFlagsAndWidth(propertyPatternClause);
@@ -10544,6 +10560,7 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
public TypeSyntax? Type => this.type;
public PositionalPatternClauseSyntax? PositionalPatternClause => this.positionalPatternClause;
+ public LengthPatternClauseSyntax? LengthPatternClause => this.lengthPatternClause;
public PropertyPatternClauseSyntax? PropertyPatternClause => this.propertyPatternClause;
public VariableDesignationSyntax? Designation => this.designation;
@@ -10552,8 +10569,9 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
{
0 => this.type,
1 => this.positionalPatternClause,
- 2 => this.propertyPatternClause,
- 3 => this.designation,
+ 2 => this.lengthPatternClause,
+ 3 => this.propertyPatternClause,
+ 4 => this.designation,
_ => null,
};
@@ -10562,11 +10580,11 @@ internal RecursivePatternSyntax(SyntaxKind kind, TypeSyntax? type, PositionalPat
public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitRecursivePattern(this);
public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitRecursivePattern(this);
- public RecursivePatternSyntax Update(TypeSyntax type, PositionalPatternClauseSyntax positionalPatternClause, PropertyPatternClauseSyntax propertyPatternClause, VariableDesignationSyntax designation)
+ public RecursivePatternSyntax Update(TypeSyntax type, PositionalPatternClauseSyntax positionalPatternClause, LengthPatternClauseSyntax lengthPatternClause, PropertyPatternClauseSyntax propertyPatternClause, VariableDesignationSyntax designation)
{
- if (type != this.Type || positionalPatternClause != this.PositionalPatternClause || propertyPatternClause != this.PropertyPatternClause || designation != this.Designation)
+ if (type != this.Type || positionalPatternClause != this.PositionalPatternClause || lengthPatternClause != this.LengthPatternClause || propertyPatternClause != this.PropertyPatternClause || designation != this.Designation)
{
- var newNode = SyntaxFactory.RecursivePattern(type, positionalPatternClause, propertyPatternClause, designation);
+ var newNode = SyntaxFactory.RecursivePattern(type, positionalPatternClause, lengthPatternClause, propertyPatternClause, designation);
var diags = GetDiagnostics();
if (diags?.Length > 0)
newNode = newNode.WithDiagnosticsGreen(diags);
@@ -10580,15 +10598,15 @@ public RecursivePatternSyntax Update(TypeSyntax type, PositionalPatternClauseSyn
}
internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics)
- => new RecursivePatternSyntax(this.Kind, this.type, this.positionalPatternClause, this.propertyPatternClause, this.designation, diagnostics, GetAnnotations());
+ => new RecursivePatternSyntax(this.Kind, this.type, this.positionalPatternClause, this.lengthPatternClause, this.propertyPatternClause, this.designation, diagnostics, GetAnnotations());
internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
- => new RecursivePatternSyntax(this.Kind, this.type, this.positionalPatternClause, this.propertyPatternClause, this.designation, GetDiagnostics(), annotations);
+ => new RecursivePatternSyntax(this.Kind, this.type, this.positionalPatternClause, this.lengthPatternClause, this.propertyPatternClause, this.designation, GetDiagnostics(), annotations);
internal RecursivePatternSyntax(ObjectReader reader)
: base(reader)
{
- this.SlotCount = 4;
+ this.SlotCount = 5;
var type = (TypeSyntax?)reader.ReadValue();
if (type != null)
{
@@ -10601,6 +10619,12 @@ internal RecursivePatternSyntax(ObjectReader reader)
AdjustFlagsAndWidth(positionalPatternClause);
this.positionalPatternClause = positionalPatternClause;
}
+ var lengthPatternClause = (LengthPatternClauseSyntax?)reader.ReadValue();
+ if (lengthPatternClause != null)
+ {
+ AdjustFlagsAndWidth(lengthPatternClause);
+ this.lengthPatternClause = lengthPatternClause;
+ }
var propertyPatternClause = (PropertyPatternClauseSyntax?)reader.ReadValue();
if (propertyPatternClause != null)
{
@@ -10620,6 +10644,7 @@ internal override void WriteTo(ObjectWriter writer)
base.WriteTo(writer);
writer.WriteValue(this.type);
writer.WriteValue(this.positionalPatternClause);
+ writer.WriteValue(this.lengthPatternClause);
writer.WriteValue(this.propertyPatternClause);
writer.WriteValue(this.designation);
}
@@ -10630,6 +10655,119 @@ static RecursivePatternSyntax()
}
}
+ internal sealed partial class LengthPatternClauseSyntax : CSharpSyntaxNode
+ {
+ internal readonly SyntaxToken openBracketToken;
+ internal readonly PatternSyntax pattern;
+ internal readonly SyntaxToken closeBracketToken;
+
+ internal LengthPatternClauseSyntax(SyntaxKind kind, SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations)
+ : base(kind, diagnostics, annotations)
+ {
+ this.SlotCount = 3;
+ this.AdjustFlagsAndWidth(openBracketToken);
+ this.openBracketToken = openBracketToken;
+ this.AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ this.AdjustFlagsAndWidth(closeBracketToken);
+ this.closeBracketToken = closeBracketToken;
+ }
+
+ internal LengthPatternClauseSyntax(SyntaxKind kind, SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken, SyntaxFactoryContext context)
+ : base(kind)
+ {
+ this.SetFactoryContext(context);
+ this.SlotCount = 3;
+ this.AdjustFlagsAndWidth(openBracketToken);
+ this.openBracketToken = openBracketToken;
+ this.AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ this.AdjustFlagsAndWidth(closeBracketToken);
+ this.closeBracketToken = closeBracketToken;
+ }
+
+ internal LengthPatternClauseSyntax(SyntaxKind kind, SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken)
+ : base(kind)
+ {
+ this.SlotCount = 3;
+ this.AdjustFlagsAndWidth(openBracketToken);
+ this.openBracketToken = openBracketToken;
+ this.AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ this.AdjustFlagsAndWidth(closeBracketToken);
+ this.closeBracketToken = closeBracketToken;
+ }
+
+ public SyntaxToken OpenBracketToken => this.openBracketToken;
+ public PatternSyntax Pattern => this.pattern;
+ public SyntaxToken CloseBracketToken => this.closeBracketToken;
+
+ internal override GreenNode? GetSlot(int index)
+ => index switch
+ {
+ 0 => this.openBracketToken,
+ 1 => this.pattern,
+ 2 => this.closeBracketToken,
+ _ => null,
+ };
+
+ internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.LengthPatternClauseSyntax(this, parent, position);
+
+ public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitLengthPatternClause(this);
+ public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitLengthPatternClause(this);
+
+ public LengthPatternClauseSyntax Update(SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken)
+ {
+ if (openBracketToken != this.OpenBracketToken || pattern != this.Pattern || closeBracketToken != this.CloseBracketToken)
+ {
+ var newNode = SyntaxFactory.LengthPatternClause(openBracketToken, pattern, closeBracketToken);
+ var diags = GetDiagnostics();
+ if (diags?.Length > 0)
+ newNode = newNode.WithDiagnosticsGreen(diags);
+ var annotations = GetAnnotations();
+ if (annotations?.Length > 0)
+ newNode = newNode.WithAnnotationsGreen(annotations);
+ return newNode;
+ }
+
+ return this;
+ }
+
+ internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics)
+ => new LengthPatternClauseSyntax(this.Kind, this.openBracketToken, this.pattern, this.closeBracketToken, diagnostics, GetAnnotations());
+
+ internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
+ => new LengthPatternClauseSyntax(this.Kind, this.openBracketToken, this.pattern, this.closeBracketToken, GetDiagnostics(), annotations);
+
+ internal LengthPatternClauseSyntax(ObjectReader reader)
+ : base(reader)
+ {
+ this.SlotCount = 3;
+ var openBracketToken = (SyntaxToken)reader.ReadValue();
+ AdjustFlagsAndWidth(openBracketToken);
+ this.openBracketToken = openBracketToken;
+ var pattern = (PatternSyntax)reader.ReadValue();
+ AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ var closeBracketToken = (SyntaxToken)reader.ReadValue();
+ AdjustFlagsAndWidth(closeBracketToken);
+ this.closeBracketToken = closeBracketToken;
+ }
+
+ internal override void WriteTo(ObjectWriter writer)
+ {
+ base.WriteTo(writer);
+ writer.WriteValue(this.openBracketToken);
+ writer.WriteValue(this.pattern);
+ writer.WriteValue(this.closeBracketToken);
+ }
+
+ static LengthPatternClauseSyntax()
+ {
+ ObjectBinder.RegisterTypeReader(typeof(LengthPatternClauseSyntax), r => new LengthPatternClauseSyntax(r));
+ }
+ }
+
internal sealed partial class PositionalPatternClauseSyntax : CSharpSyntaxNode
{
internal readonly SyntaxToken openParenToken;
@@ -10829,7 +10967,7 @@ public PropertyPatternClauseSyntax Update(SyntaxToken openBraceToken, Microsoft.
{
if (openBraceToken != this.OpenBraceToken || subpatterns != this.Subpatterns || closeBraceToken != this.CloseBraceToken)
{
- var newNode = SyntaxFactory.PropertyPatternClause(openBraceToken, subpatterns, closeBraceToken);
+ var newNode = SyntaxFactory.PropertyPatternClause(this.Kind, openBraceToken, subpatterns, closeBraceToken);
var diags = GetDiagnostics();
if (diags?.Length > 0)
newNode = newNode.WithDiagnosticsGreen(diags);
@@ -11587,6 +11725,118 @@ static UnaryPatternSyntax()
}
}
+ internal sealed partial class SlicePatternSyntax : PatternSyntax
+ {
+ internal readonly SyntaxToken dotDotToken;
+ internal readonly PatternSyntax? pattern;
+
+ internal SlicePatternSyntax(SyntaxKind kind, SyntaxToken dotDotToken, PatternSyntax? pattern, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations)
+ : base(kind, diagnostics, annotations)
+ {
+ this.SlotCount = 2;
+ this.AdjustFlagsAndWidth(dotDotToken);
+ this.dotDotToken = dotDotToken;
+ if (pattern != null)
+ {
+ this.AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ }
+ }
+
+ internal SlicePatternSyntax(SyntaxKind kind, SyntaxToken dotDotToken, PatternSyntax? pattern, SyntaxFactoryContext context)
+ : base(kind)
+ {
+ this.SetFactoryContext(context);
+ this.SlotCount = 2;
+ this.AdjustFlagsAndWidth(dotDotToken);
+ this.dotDotToken = dotDotToken;
+ if (pattern != null)
+ {
+ this.AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ }
+ }
+
+ internal SlicePatternSyntax(SyntaxKind kind, SyntaxToken dotDotToken, PatternSyntax? pattern)
+ : base(kind)
+ {
+ this.SlotCount = 2;
+ this.AdjustFlagsAndWidth(dotDotToken);
+ this.dotDotToken = dotDotToken;
+ if (pattern != null)
+ {
+ this.AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ }
+ }
+
+ public SyntaxToken DotDotToken => this.dotDotToken;
+ public PatternSyntax? Pattern => this.pattern;
+
+ internal override GreenNode? GetSlot(int index)
+ => index switch
+ {
+ 0 => this.dotDotToken,
+ 1 => this.pattern,
+ _ => null,
+ };
+
+ internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.SlicePatternSyntax(this, parent, position);
+
+ public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSlicePattern(this);
+ public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSlicePattern(this);
+
+ public SlicePatternSyntax Update(SyntaxToken dotDotToken, PatternSyntax pattern)
+ {
+ if (dotDotToken != this.DotDotToken || pattern != this.Pattern)
+ {
+ var newNode = SyntaxFactory.SlicePattern(dotDotToken, pattern);
+ var diags = GetDiagnostics();
+ if (diags?.Length > 0)
+ newNode = newNode.WithDiagnosticsGreen(diags);
+ var annotations = GetAnnotations();
+ if (annotations?.Length > 0)
+ newNode = newNode.WithAnnotationsGreen(annotations);
+ return newNode;
+ }
+
+ return this;
+ }
+
+ internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics)
+ => new SlicePatternSyntax(this.Kind, this.dotDotToken, this.pattern, diagnostics, GetAnnotations());
+
+ internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
+ => new SlicePatternSyntax(this.Kind, this.dotDotToken, this.pattern, GetDiagnostics(), annotations);
+
+ internal SlicePatternSyntax(ObjectReader reader)
+ : base(reader)
+ {
+ this.SlotCount = 2;
+ var dotDotToken = (SyntaxToken)reader.ReadValue();
+ AdjustFlagsAndWidth(dotDotToken);
+ this.dotDotToken = dotDotToken;
+ var pattern = (PatternSyntax?)reader.ReadValue();
+ if (pattern != null)
+ {
+ AdjustFlagsAndWidth(pattern);
+ this.pattern = pattern;
+ }
+ }
+
+ internal override void WriteTo(ObjectWriter writer)
+ {
+ base.WriteTo(writer);
+ writer.WriteValue(this.dotDotToken);
+ writer.WriteValue(this.pattern);
+ }
+
+ static SlicePatternSyntax()
+ {
+ ObjectBinder.RegisterTypeReader(typeof(SlicePatternSyntax), r => new SlicePatternSyntax(r));
+ }
+ }
+
internal abstract partial class InterpolatedStringContentSyntax : CSharpSyntaxNode
{
internal InterpolatedStringContentSyntax(SyntaxKind kind, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations)
@@ -33042,6 +33292,7 @@ internal partial class CSharpSyntaxVisitor
public virtual TResult VisitDeclarationPattern(DeclarationPatternSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitVarPattern(VarPatternSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitRecursivePattern(RecursivePatternSyntax node) => this.DefaultVisit(node);
+ public virtual TResult VisitLengthPatternClause(LengthPatternClauseSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitPositionalPatternClause(PositionalPatternClauseSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitPropertyPatternClause(PropertyPatternClauseSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitSubpattern(SubpatternSyntax node) => this.DefaultVisit(node);
@@ -33051,6 +33302,7 @@ internal partial class CSharpSyntaxVisitor
public virtual TResult VisitTypePattern(TypePatternSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitBinaryPattern(BinaryPatternSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitUnaryPattern(UnaryPatternSyntax node) => this.DefaultVisit(node);
+ public virtual TResult VisitSlicePattern(SlicePatternSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitInterpolatedStringText(InterpolatedStringTextSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitInterpolation(InterpolationSyntax node) => this.DefaultVisit(node);
public virtual TResult VisitInterpolationAlignmentClause(InterpolationAlignmentClauseSyntax node) => this.DefaultVisit(node);
@@ -33277,6 +33529,7 @@ internal partial class CSharpSyntaxVisitor
public virtual void VisitDeclarationPattern(DeclarationPatternSyntax node) => this.DefaultVisit(node);
public virtual void VisitVarPattern(VarPatternSyntax node) => this.DefaultVisit(node);
public virtual void VisitRecursivePattern(RecursivePatternSyntax node) => this.DefaultVisit(node);
+ public virtual void VisitLengthPatternClause(LengthPatternClauseSyntax node) => this.DefaultVisit(node);
public virtual void VisitPositionalPatternClause(PositionalPatternClauseSyntax node) => this.DefaultVisit(node);
public virtual void VisitPropertyPatternClause(PropertyPatternClauseSyntax node) => this.DefaultVisit(node);
public virtual void VisitSubpattern(SubpatternSyntax node) => this.DefaultVisit(node);
@@ -33286,6 +33539,7 @@ internal partial class CSharpSyntaxVisitor
public virtual void VisitTypePattern(TypePatternSyntax node) => this.DefaultVisit(node);
public virtual void VisitBinaryPattern(BinaryPatternSyntax node) => this.DefaultVisit(node);
public virtual void VisitUnaryPattern(UnaryPatternSyntax node) => this.DefaultVisit(node);
+ public virtual void VisitSlicePattern(SlicePatternSyntax node) => this.DefaultVisit(node);
public virtual void VisitInterpolatedStringText(InterpolatedStringTextSyntax node) => this.DefaultVisit(node);
public virtual void VisitInterpolation(InterpolationSyntax node) => this.DefaultVisit(node);
public virtual void VisitInterpolationAlignmentClause(InterpolationAlignmentClauseSyntax node) => this.DefaultVisit(node);
@@ -33682,7 +33936,10 @@ public override CSharpSyntaxNode VisitVarPattern(VarPatternSyntax node)
=> node.Update((SyntaxToken)Visit(node.VarKeyword), (VariableDesignationSyntax)Visit(node.Designation));
public override CSharpSyntaxNode VisitRecursivePattern(RecursivePatternSyntax node)
- => node.Update((TypeSyntax)Visit(node.Type), (PositionalPatternClauseSyntax)Visit(node.PositionalPatternClause), (PropertyPatternClauseSyntax)Visit(node.PropertyPatternClause), (VariableDesignationSyntax)Visit(node.Designation));
+ => node.Update((TypeSyntax)Visit(node.Type), (PositionalPatternClauseSyntax)Visit(node.PositionalPatternClause), (LengthPatternClauseSyntax)Visit(node.LengthPatternClause), (PropertyPatternClauseSyntax)Visit(node.PropertyPatternClause), (VariableDesignationSyntax)Visit(node.Designation));
+
+ public override CSharpSyntaxNode VisitLengthPatternClause(LengthPatternClauseSyntax node)
+ => node.Update((SyntaxToken)Visit(node.OpenBracketToken), (PatternSyntax)Visit(node.Pattern), (SyntaxToken)Visit(node.CloseBracketToken));
public override CSharpSyntaxNode VisitPositionalPatternClause(PositionalPatternClauseSyntax node)
=> node.Update((SyntaxToken)Visit(node.OpenParenToken), VisitList(node.Subpatterns), (SyntaxToken)Visit(node.CloseParenToken));
@@ -33711,6 +33968,9 @@ public override CSharpSyntaxNode VisitBinaryPattern(BinaryPatternSyntax node)
public override CSharpSyntaxNode VisitUnaryPattern(UnaryPatternSyntax node)
=> node.Update((SyntaxToken)Visit(node.OperatorToken), (PatternSyntax)Visit(node.Pattern));
+ public override CSharpSyntaxNode VisitSlicePattern(SlicePatternSyntax node)
+ => node.Update((SyntaxToken)Visit(node.DotDotToken), (PatternSyntax)Visit(node.Pattern));
+
public override CSharpSyntaxNode VisitInterpolatedStringText(InterpolatedStringTextSyntax node)
=> node.Update((SyntaxToken)Visit(node.TextToken));
@@ -36016,12 +36276,35 @@ public VarPatternSyntax VarPattern(SyntaxToken varKeyword, VariableDesignationSy
return result;
}
- public RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ public RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
{
#if DEBUG
#endif
- return new RecursivePatternSyntax(SyntaxKind.RecursivePattern, type, positionalPatternClause, propertyPatternClause, designation, this.context);
+ return new RecursivePatternSyntax(SyntaxKind.RecursivePattern, type, positionalPatternClause, lengthPatternClause, propertyPatternClause, designation, this.context);
+ }
+
+ public LengthPatternClauseSyntax LengthPatternClause(SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken)
+ {
+#if DEBUG
+ if (openBracketToken == null) throw new ArgumentNullException(nameof(openBracketToken));
+ if (openBracketToken.Kind != SyntaxKind.OpenBracketToken) throw new ArgumentException(nameof(openBracketToken));
+ if (pattern == null) throw new ArgumentNullException(nameof(pattern));
+ if (closeBracketToken == null) throw new ArgumentNullException(nameof(closeBracketToken));
+ if (closeBracketToken.Kind != SyntaxKind.CloseBracketToken) throw new ArgumentException(nameof(closeBracketToken));
+#endif
+
+ int hash;
+ var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.LengthPatternClause, openBracketToken, pattern, closeBracketToken, this.context, out hash);
+ if (cached != null) return (LengthPatternClauseSyntax)cached;
+
+ var result = new LengthPatternClauseSyntax(SyntaxKind.LengthPatternClause, openBracketToken, pattern, closeBracketToken, this.context);
+ if (hash >= 0)
+ {
+ SyntaxNodeCache.AddNode(result, hash);
+ }
+
+ return result;
}
public PositionalPatternClauseSyntax PositionalPatternClause(SyntaxToken openParenToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList subpatterns, SyntaxToken closeParenToken)
@@ -36046,8 +36329,14 @@ public PositionalPatternClauseSyntax PositionalPatternClause(SyntaxToken openPar
return result;
}
- public PropertyPatternClauseSyntax PropertyPatternClause(SyntaxToken openBraceToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
+ public PropertyPatternClauseSyntax PropertyPatternClause(SyntaxKind kind, SyntaxToken openBraceToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
{
+ switch (kind)
+ {
+ case SyntaxKind.PropertyPatternClause:
+ case SyntaxKind.ListPatternClause: break;
+ default: throw new ArgumentException(nameof(kind));
+ }
#if DEBUG
if (openBraceToken == null) throw new ArgumentNullException(nameof(openBraceToken));
if (openBraceToken.Kind != SyntaxKind.OpenBraceToken) throw new ArgumentException(nameof(openBraceToken));
@@ -36056,10 +36345,10 @@ public PropertyPatternClauseSyntax PropertyPatternClause(SyntaxToken openBraceTo
#endif
int hash;
- var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.PropertyPatternClause, openBraceToken, subpatterns.Node, closeBraceToken, this.context, out hash);
+ var cached = CSharpSyntaxNodeCache.TryGetNode((int)kind, openBraceToken, subpatterns.Node, closeBraceToken, this.context, out hash);
if (cached != null) return (PropertyPatternClauseSyntax)cached;
- var result = new PropertyPatternClauseSyntax(SyntaxKind.PropertyPatternClause, openBraceToken, subpatterns.Node, closeBraceToken, this.context);
+ var result = new PropertyPatternClauseSyntax(kind, openBraceToken, subpatterns.Node, closeBraceToken, this.context);
if (hash >= 0)
{
SyntaxNodeCache.AddNode(result, hash);
@@ -36232,6 +36521,26 @@ public UnaryPatternSyntax UnaryPattern(SyntaxToken operatorToken, PatternSyntax
return result;
}
+ public SlicePatternSyntax SlicePattern(SyntaxToken dotDotToken, PatternSyntax? pattern)
+ {
+#if DEBUG
+ if (dotDotToken == null) throw new ArgumentNullException(nameof(dotDotToken));
+ if (dotDotToken.Kind != SyntaxKind.DotDotToken) throw new ArgumentException(nameof(dotDotToken));
+#endif
+
+ int hash;
+ var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.SlicePattern, dotDotToken, pattern, this.context, out hash);
+ if (cached != null) return (SlicePatternSyntax)cached;
+
+ var result = new SlicePatternSyntax(SyntaxKind.SlicePattern, dotDotToken, pattern, this.context);
+ if (hash >= 0)
+ {
+ SyntaxNodeCache.AddNode(result, hash);
+ }
+
+ return result;
+ }
+
public InterpolatedStringTextSyntax InterpolatedStringText(SyntaxToken textToken)
{
#if DEBUG
@@ -40885,12 +41194,35 @@ public static VarPatternSyntax VarPattern(SyntaxToken varKeyword, VariableDesign
return result;
}
- public static RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ public static RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ {
+#if DEBUG
+#endif
+
+ return new RecursivePatternSyntax(SyntaxKind.RecursivePattern, type, positionalPatternClause, lengthPatternClause, propertyPatternClause, designation);
+ }
+
+ public static LengthPatternClauseSyntax LengthPatternClause(SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken)
{
#if DEBUG
+ if (openBracketToken == null) throw new ArgumentNullException(nameof(openBracketToken));
+ if (openBracketToken.Kind != SyntaxKind.OpenBracketToken) throw new ArgumentException(nameof(openBracketToken));
+ if (pattern == null) throw new ArgumentNullException(nameof(pattern));
+ if (closeBracketToken == null) throw new ArgumentNullException(nameof(closeBracketToken));
+ if (closeBracketToken.Kind != SyntaxKind.CloseBracketToken) throw new ArgumentException(nameof(closeBracketToken));
#endif
- return new RecursivePatternSyntax(SyntaxKind.RecursivePattern, type, positionalPatternClause, propertyPatternClause, designation);
+ int hash;
+ var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.LengthPatternClause, openBracketToken, pattern, closeBracketToken, out hash);
+ if (cached != null) return (LengthPatternClauseSyntax)cached;
+
+ var result = new LengthPatternClauseSyntax(SyntaxKind.LengthPatternClause, openBracketToken, pattern, closeBracketToken);
+ if (hash >= 0)
+ {
+ SyntaxNodeCache.AddNode(result, hash);
+ }
+
+ return result;
}
public static PositionalPatternClauseSyntax PositionalPatternClause(SyntaxToken openParenToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList subpatterns, SyntaxToken closeParenToken)
@@ -40915,8 +41247,14 @@ public static PositionalPatternClauseSyntax PositionalPatternClause(SyntaxToken
return result;
}
- public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxToken openBraceToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
+ public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxKind kind, SyntaxToken openBraceToken, Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
{
+ switch (kind)
+ {
+ case SyntaxKind.PropertyPatternClause:
+ case SyntaxKind.ListPatternClause: break;
+ default: throw new ArgumentException(nameof(kind));
+ }
#if DEBUG
if (openBraceToken == null) throw new ArgumentNullException(nameof(openBraceToken));
if (openBraceToken.Kind != SyntaxKind.OpenBraceToken) throw new ArgumentException(nameof(openBraceToken));
@@ -40925,10 +41263,10 @@ public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxToken open
#endif
int hash;
- var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.PropertyPatternClause, openBraceToken, subpatterns.Node, closeBraceToken, out hash);
+ var cached = SyntaxNodeCache.TryGetNode((int)kind, openBraceToken, subpatterns.Node, closeBraceToken, out hash);
if (cached != null) return (PropertyPatternClauseSyntax)cached;
- var result = new PropertyPatternClauseSyntax(SyntaxKind.PropertyPatternClause, openBraceToken, subpatterns.Node, closeBraceToken);
+ var result = new PropertyPatternClauseSyntax(kind, openBraceToken, subpatterns.Node, closeBraceToken);
if (hash >= 0)
{
SyntaxNodeCache.AddNode(result, hash);
@@ -41101,6 +41439,26 @@ public static UnaryPatternSyntax UnaryPattern(SyntaxToken operatorToken, Pattern
return result;
}
+ public static SlicePatternSyntax SlicePattern(SyntaxToken dotDotToken, PatternSyntax? pattern)
+ {
+#if DEBUG
+ if (dotDotToken == null) throw new ArgumentNullException(nameof(dotDotToken));
+ if (dotDotToken.Kind != SyntaxKind.DotDotToken) throw new ArgumentException(nameof(dotDotToken));
+#endif
+
+ int hash;
+ var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.SlicePattern, dotDotToken, pattern, out hash);
+ if (cached != null) return (SlicePatternSyntax)cached;
+
+ var result = new SlicePatternSyntax(SyntaxKind.SlicePattern, dotDotToken, pattern);
+ if (hash >= 0)
+ {
+ SyntaxNodeCache.AddNode(result, hash);
+ }
+
+ return result;
+ }
+
public static InterpolatedStringTextSyntax InterpolatedStringText(SyntaxToken textToken)
{
#if DEBUG
@@ -43951,6 +44309,7 @@ internal static IEnumerable GetNodeTypes()
typeof(DeclarationPatternSyntax),
typeof(VarPatternSyntax),
typeof(RecursivePatternSyntax),
+ typeof(LengthPatternClauseSyntax),
typeof(PositionalPatternClauseSyntax),
typeof(PropertyPatternClauseSyntax),
typeof(SubpatternSyntax),
@@ -43960,6 +44319,7 @@ internal static IEnumerable GetNodeTypes()
typeof(TypePatternSyntax),
typeof(BinaryPatternSyntax),
typeof(UnaryPatternSyntax),
+ typeof(SlicePatternSyntax),
typeof(InterpolatedStringTextSyntax),
typeof(InterpolationSyntax),
typeof(InterpolationAlignmentClauseSyntax),
diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs
index 86a0e9c3dc084..09ecb8281e66a 100644
--- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs
@@ -273,6 +273,9 @@ public partial class CSharpSyntaxVisitor
/// Called when the visitor visits a RecursivePatternSyntax node.
public virtual TResult? VisitRecursivePattern(RecursivePatternSyntax node) => this.DefaultVisit(node);
+ /// Called when the visitor visits a LengthPatternClauseSyntax node.
+ public virtual TResult? VisitLengthPatternClause(LengthPatternClauseSyntax node) => this.DefaultVisit(node);
+
/// Called when the visitor visits a PositionalPatternClauseSyntax node.
public virtual TResult? VisitPositionalPatternClause(PositionalPatternClauseSyntax node) => this.DefaultVisit(node);
@@ -300,6 +303,9 @@ public partial class CSharpSyntaxVisitor
/// Called when the visitor visits a UnaryPatternSyntax node.
public virtual TResult? VisitUnaryPattern(UnaryPatternSyntax node) => this.DefaultVisit(node);
+ /// Called when the visitor visits a SlicePatternSyntax node.
+ public virtual TResult? VisitSlicePattern(SlicePatternSyntax node) => this.DefaultVisit(node);
+
/// Called when the visitor visits a InterpolatedStringTextSyntax node.
public virtual TResult? VisitInterpolatedStringText(InterpolatedStringTextSyntax node) => this.DefaultVisit(node);
@@ -969,6 +975,9 @@ public partial class CSharpSyntaxVisitor
/// Called when the visitor visits a RecursivePatternSyntax node.
public virtual void VisitRecursivePattern(RecursivePatternSyntax node) => this.DefaultVisit(node);
+ /// Called when the visitor visits a LengthPatternClauseSyntax node.
+ public virtual void VisitLengthPatternClause(LengthPatternClauseSyntax node) => this.DefaultVisit(node);
+
/// Called when the visitor visits a PositionalPatternClauseSyntax node.
public virtual void VisitPositionalPatternClause(PositionalPatternClauseSyntax node) => this.DefaultVisit(node);
@@ -996,6 +1005,9 @@ public partial class CSharpSyntaxVisitor
/// Called when the visitor visits a UnaryPatternSyntax node.
public virtual void VisitUnaryPattern(UnaryPatternSyntax node) => this.DefaultVisit(node);
+ /// Called when the visitor visits a SlicePatternSyntax node.
+ public virtual void VisitSlicePattern(SlicePatternSyntax node) => this.DefaultVisit(node);
+
/// Called when the visitor visits a InterpolatedStringTextSyntax node.
public virtual void VisitInterpolatedStringText(InterpolatedStringTextSyntax node) => this.DefaultVisit(node);
@@ -1663,7 +1675,10 @@ public partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor
=> node.Update(VisitToken(node.VarKeyword), (VariableDesignationSyntax?)Visit(node.Designation) ?? throw new ArgumentNullException("designation"));
public override SyntaxNode? VisitRecursivePattern(RecursivePatternSyntax node)
- => node.Update((TypeSyntax?)Visit(node.Type), (PositionalPatternClauseSyntax?)Visit(node.PositionalPatternClause), (PropertyPatternClauseSyntax?)Visit(node.PropertyPatternClause), (VariableDesignationSyntax?)Visit(node.Designation));
+ => node.Update((TypeSyntax?)Visit(node.Type), (PositionalPatternClauseSyntax?)Visit(node.PositionalPatternClause), (LengthPatternClauseSyntax?)Visit(node.LengthPatternClause), (PropertyPatternClauseSyntax?)Visit(node.PropertyPatternClause), (VariableDesignationSyntax?)Visit(node.Designation));
+
+ public override SyntaxNode? VisitLengthPatternClause(LengthPatternClauseSyntax node)
+ => node.Update(VisitToken(node.OpenBracketToken), (PatternSyntax?)Visit(node.Pattern) ?? throw new ArgumentNullException("pattern"), VisitToken(node.CloseBracketToken));
public override SyntaxNode? VisitPositionalPatternClause(PositionalPatternClauseSyntax node)
=> node.Update(VisitToken(node.OpenParenToken), VisitList(node.Subpatterns), VisitToken(node.CloseParenToken));
@@ -1692,6 +1707,9 @@ public partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor
public override SyntaxNode? VisitUnaryPattern(UnaryPatternSyntax node)
=> node.Update(VisitToken(node.OperatorToken), (PatternSyntax?)Visit(node.Pattern) ?? throw new ArgumentNullException("pattern"));
+ public override SyntaxNode? VisitSlicePattern(SlicePatternSyntax node)
+ => node.Update(VisitToken(node.DotDotToken), (PatternSyntax?)Visit(node.Pattern));
+
public override SyntaxNode? VisitInterpolatedStringText(InterpolatedStringTextSyntax node)
=> node.Update(VisitToken(node.TextToken));
@@ -3552,14 +3570,27 @@ public static VarPatternSyntax VarPattern(VariableDesignationSyntax designation)
=> SyntaxFactory.VarPattern(SyntaxFactory.Token(SyntaxKind.VarKeyword), designation);
/// Creates a new RecursivePatternSyntax instance.
- public static RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ public static RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
{
- return (RecursivePatternSyntax)Syntax.InternalSyntax.SyntaxFactory.RecursivePattern(type == null ? null : (Syntax.InternalSyntax.TypeSyntax)type.Green, positionalPatternClause == null ? null : (Syntax.InternalSyntax.PositionalPatternClauseSyntax)positionalPatternClause.Green, propertyPatternClause == null ? null : (Syntax.InternalSyntax.PropertyPatternClauseSyntax)propertyPatternClause.Green, designation == null ? null : (Syntax.InternalSyntax.VariableDesignationSyntax)designation.Green).CreateRed();
+ return (RecursivePatternSyntax)Syntax.InternalSyntax.SyntaxFactory.RecursivePattern(type == null ? null : (Syntax.InternalSyntax.TypeSyntax)type.Green, positionalPatternClause == null ? null : (Syntax.InternalSyntax.PositionalPatternClauseSyntax)positionalPatternClause.Green, lengthPatternClause == null ? null : (Syntax.InternalSyntax.LengthPatternClauseSyntax)lengthPatternClause.Green, propertyPatternClause == null ? null : (Syntax.InternalSyntax.PropertyPatternClauseSyntax)propertyPatternClause.Green, designation == null ? null : (Syntax.InternalSyntax.VariableDesignationSyntax)designation.Green).CreateRed();
}
/// Creates a new RecursivePatternSyntax instance.
public static RecursivePatternSyntax RecursivePattern()
- => SyntaxFactory.RecursivePattern(default, default, default, default);
+ => SyntaxFactory.RecursivePattern(default, default, default, default, default);
+
+ /// Creates a new LengthPatternClauseSyntax instance.
+ public static LengthPatternClauseSyntax LengthPatternClause(SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken)
+ {
+ if (openBracketToken.Kind() != SyntaxKind.OpenBracketToken) throw new ArgumentException(nameof(openBracketToken));
+ if (pattern == null) throw new ArgumentNullException(nameof(pattern));
+ if (closeBracketToken.Kind() != SyntaxKind.CloseBracketToken) throw new ArgumentException(nameof(closeBracketToken));
+ return (LengthPatternClauseSyntax)Syntax.InternalSyntax.SyntaxFactory.LengthPatternClause((Syntax.InternalSyntax.SyntaxToken)openBracketToken.Node!, (Syntax.InternalSyntax.PatternSyntax)pattern.Green, (Syntax.InternalSyntax.SyntaxToken)closeBracketToken.Node!).CreateRed();
+ }
+
+ /// Creates a new LengthPatternClauseSyntax instance.
+ public static LengthPatternClauseSyntax LengthPatternClause(PatternSyntax pattern)
+ => SyntaxFactory.LengthPatternClause(SyntaxFactory.Token(SyntaxKind.OpenBracketToken), pattern, SyntaxFactory.Token(SyntaxKind.CloseBracketToken));
/// Creates a new PositionalPatternClauseSyntax instance.
public static PositionalPatternClauseSyntax PositionalPatternClause(SyntaxToken openParenToken, SeparatedSyntaxList subpatterns, SyntaxToken closeParenToken)
@@ -3574,16 +3605,22 @@ public static PositionalPatternClauseSyntax PositionalPatternClause(SeparatedSyn
=> SyntaxFactory.PositionalPatternClause(SyntaxFactory.Token(SyntaxKind.OpenParenToken), subpatterns, SyntaxFactory.Token(SyntaxKind.CloseParenToken));
/// Creates a new PropertyPatternClauseSyntax instance.
- public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxToken openBraceToken, SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
+ public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxKind kind, SyntaxToken openBraceToken, SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
{
+ switch (kind)
+ {
+ case SyntaxKind.PropertyPatternClause:
+ case SyntaxKind.ListPatternClause: break;
+ default: throw new ArgumentException(nameof(kind));
+ }
if (openBraceToken.Kind() != SyntaxKind.OpenBraceToken) throw new ArgumentException(nameof(openBraceToken));
if (closeBraceToken.Kind() != SyntaxKind.CloseBraceToken) throw new ArgumentException(nameof(closeBraceToken));
- return (PropertyPatternClauseSyntax)Syntax.InternalSyntax.SyntaxFactory.PropertyPatternClause((Syntax.InternalSyntax.SyntaxToken)openBraceToken.Node!, subpatterns.Node.ToGreenSeparatedList(), (Syntax.InternalSyntax.SyntaxToken)closeBraceToken.Node!).CreateRed();
+ return (PropertyPatternClauseSyntax)Syntax.InternalSyntax.SyntaxFactory.PropertyPatternClause(kind, (Syntax.InternalSyntax.SyntaxToken)openBraceToken.Node!, subpatterns.Node.ToGreenSeparatedList(), (Syntax.InternalSyntax.SyntaxToken)closeBraceToken.Node!).CreateRed();
}
/// Creates a new PropertyPatternClauseSyntax instance.
- public static PropertyPatternClauseSyntax PropertyPatternClause(SeparatedSyntaxList subpatterns = default)
- => SyntaxFactory.PropertyPatternClause(SyntaxFactory.Token(SyntaxKind.OpenBraceToken), subpatterns, SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
+ public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxKind kind, SeparatedSyntaxList subpatterns = default)
+ => SyntaxFactory.PropertyPatternClause(kind, SyntaxFactory.Token(SyntaxKind.OpenBraceToken), subpatterns, SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
/// Creates a new SubpatternSyntax instance.
public static SubpatternSyntax Subpattern(NameColonSyntax? nameColon, PatternSyntax pattern)
@@ -3684,6 +3721,17 @@ public static UnaryPatternSyntax UnaryPattern(SyntaxToken operatorToken, Pattern
public static UnaryPatternSyntax UnaryPattern(PatternSyntax pattern)
=> SyntaxFactory.UnaryPattern(SyntaxFactory.Token(SyntaxKind.NotKeyword), pattern);
+ /// Creates a new SlicePatternSyntax instance.
+ public static SlicePatternSyntax SlicePattern(SyntaxToken dotDotToken, PatternSyntax? pattern)
+ {
+ if (dotDotToken.Kind() != SyntaxKind.DotDotToken) throw new ArgumentException(nameof(dotDotToken));
+ return (SlicePatternSyntax)Syntax.InternalSyntax.SyntaxFactory.SlicePattern((Syntax.InternalSyntax.SyntaxToken)dotDotToken.Node!, pattern == null ? null : (Syntax.InternalSyntax.PatternSyntax)pattern.Green).CreateRed();
+ }
+
+ /// Creates a new SlicePatternSyntax instance.
+ public static SlicePatternSyntax SlicePattern(PatternSyntax? pattern = default)
+ => SyntaxFactory.SlicePattern(SyntaxFactory.Token(SyntaxKind.DotDotToken), pattern);
+
/// Creates a new InterpolatedStringTextSyntax instance.
public static InterpolatedStringTextSyntax InterpolatedStringText(SyntaxToken textToken)
{
diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs
index 04aa76e5e9761..d430eb93dd10c 100644
--- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs
@@ -5015,6 +5015,7 @@ public sealed partial class RecursivePatternSyntax : PatternSyntax
{
private TypeSyntax? type;
private PositionalPatternClauseSyntax? positionalPatternClause;
+ private LengthPatternClauseSyntax? lengthPatternClause;
private PropertyPatternClauseSyntax? propertyPatternClause;
private VariableDesignationSyntax? designation;
@@ -5027,17 +5028,20 @@ internal RecursivePatternSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNod
public PositionalPatternClauseSyntax? PositionalPatternClause => GetRed(ref this.positionalPatternClause, 1);
- public PropertyPatternClauseSyntax? PropertyPatternClause => GetRed(ref this.propertyPatternClause, 2);
+ public LengthPatternClauseSyntax? LengthPatternClause => GetRed(ref this.lengthPatternClause, 2);
- public VariableDesignationSyntax? Designation => GetRed(ref this.designation, 3);
+ public PropertyPatternClauseSyntax? PropertyPatternClause => GetRed(ref this.propertyPatternClause, 3);
+
+ public VariableDesignationSyntax? Designation => GetRed(ref this.designation, 4);
internal override SyntaxNode? GetNodeSlot(int index)
=> index switch
{
0 => GetRedAtZero(ref this.type),
1 => GetRed(ref this.positionalPatternClause, 1),
- 2 => GetRed(ref this.propertyPatternClause, 2),
- 3 => GetRed(ref this.designation, 3),
+ 2 => GetRed(ref this.lengthPatternClause, 2),
+ 3 => GetRed(ref this.propertyPatternClause, 3),
+ 4 => GetRed(ref this.designation, 4),
_ => null,
};
@@ -5046,19 +5050,20 @@ internal RecursivePatternSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNod
{
0 => this.type,
1 => this.positionalPatternClause,
- 2 => this.propertyPatternClause,
- 3 => this.designation,
+ 2 => this.lengthPatternClause,
+ 3 => this.propertyPatternClause,
+ 4 => this.designation,
_ => null,
};
public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitRecursivePattern(this);
public override TResult? Accept(CSharpSyntaxVisitor visitor) where TResult : default => visitor.VisitRecursivePattern(this);
- public RecursivePatternSyntax Update(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ public RecursivePatternSyntax Update(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, LengthPatternClauseSyntax? lengthPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
{
- if (type != this.Type || positionalPatternClause != this.PositionalPatternClause || propertyPatternClause != this.PropertyPatternClause || designation != this.Designation)
+ if (type != this.Type || positionalPatternClause != this.PositionalPatternClause || lengthPatternClause != this.LengthPatternClause || propertyPatternClause != this.PropertyPatternClause || designation != this.Designation)
{
- var newNode = SyntaxFactory.RecursivePattern(type, positionalPatternClause, propertyPatternClause, designation);
+ var newNode = SyntaxFactory.RecursivePattern(type, positionalPatternClause, lengthPatternClause, propertyPatternClause, designation);
var annotations = GetAnnotations();
return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode;
}
@@ -5066,21 +5071,62 @@ public RecursivePatternSyntax Update(TypeSyntax? type, PositionalPatternClauseSy
return this;
}
- public RecursivePatternSyntax WithType(TypeSyntax? type) => Update(type, this.PositionalPatternClause, this.PropertyPatternClause, this.Designation);
- public RecursivePatternSyntax WithPositionalPatternClause(PositionalPatternClauseSyntax? positionalPatternClause) => Update(this.Type, positionalPatternClause, this.PropertyPatternClause, this.Designation);
- public RecursivePatternSyntax WithPropertyPatternClause(PropertyPatternClauseSyntax? propertyPatternClause) => Update(this.Type, this.PositionalPatternClause, propertyPatternClause, this.Designation);
- public RecursivePatternSyntax WithDesignation(VariableDesignationSyntax? designation) => Update(this.Type, this.PositionalPatternClause, this.PropertyPatternClause, designation);
+ public RecursivePatternSyntax WithType(TypeSyntax? type) => Update(type, this.PositionalPatternClause, this.LengthPatternClause, this.PropertyPatternClause, this.Designation);
+ public RecursivePatternSyntax WithPositionalPatternClause(PositionalPatternClauseSyntax? positionalPatternClause) => Update(this.Type, positionalPatternClause, this.LengthPatternClause, this.PropertyPatternClause, this.Designation);
+ public RecursivePatternSyntax WithLengthPatternClause(LengthPatternClauseSyntax? lengthPatternClause) => Update(this.Type, this.PositionalPatternClause, lengthPatternClause, this.PropertyPatternClause, this.Designation);
+ public RecursivePatternSyntax WithPropertyPatternClause(PropertyPatternClauseSyntax? propertyPatternClause) => Update(this.Type, this.PositionalPatternClause, this.LengthPatternClause, propertyPatternClause, this.Designation);
+ public RecursivePatternSyntax WithDesignation(VariableDesignationSyntax? designation) => Update(this.Type, this.PositionalPatternClause, this.LengthPatternClause, this.PropertyPatternClause, designation);
public RecursivePatternSyntax AddPositionalPatternClauseSubpatterns(params SubpatternSyntax[] items)
{
var positionalPatternClause = this.PositionalPatternClause ?? SyntaxFactory.PositionalPatternClause();
return WithPositionalPatternClause(positionalPatternClause.WithSubpatterns(positionalPatternClause.Subpatterns.AddRange(items)));
}
- public RecursivePatternSyntax AddPropertyPatternClauseSubpatterns(params SubpatternSyntax[] items)
+ }
+
+ ///
+ /// This node is associated with the following syntax kinds:
+ ///
+ ///
+ ///
+ ///
+ public sealed partial class LengthPatternClauseSyntax : CSharpSyntaxNode
+ {
+ private PatternSyntax? pattern;
+
+ internal LengthPatternClauseSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position)
+ : base(green, parent, position)
+ {
+ }
+
+ public SyntaxToken OpenBracketToken => new SyntaxToken(this, ((Syntax.InternalSyntax.LengthPatternClauseSyntax)this.Green).openBracketToken, Position, 0);
+
+ public PatternSyntax Pattern => GetRed(ref this.pattern, 1)!;
+
+ public SyntaxToken CloseBracketToken => new SyntaxToken(this, ((Syntax.InternalSyntax.LengthPatternClauseSyntax)this.Green).closeBracketToken, GetChildPosition(2), GetChildIndex(2));
+
+ internal override SyntaxNode? GetNodeSlot(int index) => index == 1 ? GetRed(ref this.pattern, 1)! : null;
+
+ internal override SyntaxNode? GetCachedSlot(int index) => index == 1 ? this.pattern : null;
+
+ public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitLengthPatternClause(this);
+ public override TResult? Accept(CSharpSyntaxVisitor visitor) where TResult : default => visitor.VisitLengthPatternClause(this);
+
+ public LengthPatternClauseSyntax Update(SyntaxToken openBracketToken, PatternSyntax pattern, SyntaxToken closeBracketToken)
{
- var propertyPatternClause = this.PropertyPatternClause ?? SyntaxFactory.PropertyPatternClause();
- return WithPropertyPatternClause(propertyPatternClause.WithSubpatterns(propertyPatternClause.Subpatterns.AddRange(items)));
+ if (openBracketToken != this.OpenBracketToken || pattern != this.Pattern || closeBracketToken != this.CloseBracketToken)
+ {
+ var newNode = SyntaxFactory.LengthPatternClause(openBracketToken, pattern, closeBracketToken);
+ var annotations = GetAnnotations();
+ return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode;
+ }
+
+ return this;
}
+
+ public LengthPatternClauseSyntax WithOpenBracketToken(SyntaxToken openBracketToken) => Update(openBracketToken, this.Pattern, this.CloseBracketToken);
+ public LengthPatternClauseSyntax WithPattern(PatternSyntax pattern) => Update(this.OpenBracketToken, pattern, this.CloseBracketToken);
+ public LengthPatternClauseSyntax WithCloseBracketToken(SyntaxToken closeBracketToken) => Update(this.OpenBracketToken, this.Pattern, closeBracketToken);
}
///
@@ -5141,6 +5187,7 @@ public PositionalPatternClauseSyntax Update(SyntaxToken openParenToken, Separate
/// This node is associated with the following syntax kinds:
///
///
+ ///
///
///
public sealed partial class PropertyPatternClauseSyntax : CSharpSyntaxNode
@@ -5176,7 +5223,7 @@ public PropertyPatternClauseSyntax Update(SyntaxToken openBraceToken, SeparatedS
{
if (openBraceToken != this.OpenBraceToken || subpatterns != this.Subpatterns || closeBraceToken != this.CloseBraceToken)
{
- var newNode = SyntaxFactory.PropertyPatternClause(openBraceToken, subpatterns, closeBraceToken);
+ var newNode = SyntaxFactory.PropertyPatternClause(this.Kind(), openBraceToken, subpatterns, closeBraceToken);
var annotations = GetAnnotations();
return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode;
}
@@ -5515,6 +5562,48 @@ public UnaryPatternSyntax Update(SyntaxToken operatorToken, PatternSyntax patter
public UnaryPatternSyntax WithPattern(PatternSyntax pattern) => Update(this.OperatorToken, pattern);
}
+ ///
+ /// This node is associated with the following syntax kinds:
+ ///
+ ///
+ ///
+ ///
+ public sealed partial class SlicePatternSyntax : PatternSyntax
+ {
+ private PatternSyntax? pattern;
+
+ internal SlicePatternSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position)
+ : base(green, parent, position)
+ {
+ }
+
+ public SyntaxToken DotDotToken => new SyntaxToken(this, ((Syntax.InternalSyntax.SlicePatternSyntax)this.Green).dotDotToken, Position, 0);
+
+ public PatternSyntax? Pattern => GetRed(ref this.pattern, 1);
+
+ internal override SyntaxNode? GetNodeSlot(int index) => index == 1 ? GetRed(ref this.pattern, 1) : null;
+
+ internal override SyntaxNode? GetCachedSlot(int index) => index == 1 ? this.pattern : null;
+
+ public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSlicePattern(this);
+ public override TResult? Accept(CSharpSyntaxVisitor visitor) where TResult : default => visitor.VisitSlicePattern(this);
+
+ public SlicePatternSyntax Update(SyntaxToken dotDotToken, PatternSyntax? pattern)
+ {
+ if (dotDotToken != this.DotDotToken || pattern != this.Pattern)
+ {
+ var newNode = SyntaxFactory.SlicePattern(dotDotToken, pattern);
+ var annotations = GetAnnotations();
+ return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode;
+ }
+
+ return this;
+ }
+
+ public SlicePatternSyntax WithDotDotToken(SyntaxToken dotDotToken) => Update(dotDotToken, this.Pattern);
+ public SlicePatternSyntax WithPattern(PatternSyntax? pattern) => Update(this.DotDotToken, pattern);
+ }
+
public abstract partial class InterpolatedStringContentSyntax : CSharpSyntaxNode
{
internal InterpolatedStringContentSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position)
diff --git a/src/Compilers/CSharp/Portable/GlobalSuppressions.cs b/src/Compilers/CSharp/Portable/GlobalSuppressions.cs
index 751f8d5a7383e..dca5a2db834c5 100644
--- a/src/Compilers/CSharp/Portable/GlobalSuppressions.cs
+++ b/src/Compilers/CSharp/Portable/GlobalSuppressions.cs
@@ -10,6 +10,7 @@
// a specific target and scoped to a namespace, type, member, etc.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetDeclaredSymbol(Microsoft.CodeAnalysis.SemanticModel,Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax,System.Threading.CancellationToken)~Microsoft.CodeAnalysis.ISymbol")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SlicePattern(Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax)~Microsoft.CodeAnalysis.CSharp.Syntax.SlicePatternSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TupleType(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.TupleElementSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TupleExpression(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WhenClause(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax)~Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax")]
@@ -31,6 +32,7 @@
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ArrayRankSpecifier(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.ArrayRankSpecifierSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeconstructionPattern(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.SubpatternSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionPatternSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.PropertyPatternClause(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.SubpatternSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.PropertyPatternClauseSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.PropertyPatternClause(Microsoft.CodeAnalysis.CSharp.SyntaxKind,Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.SubpatternSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.PropertyPatternClauseSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.PositionalPatternClause(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.SubpatternSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.PositionalPatternClauseSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeconstructionPatternClause(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.SubpatternSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionPatternClauseSyntax")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(System.String,Microsoft.CodeAnalysis.CSharp.CSharpParseOptions,System.String,System.Text.Encoding,System.Threading.CancellationToken)~Microsoft.CodeAnalysis.SyntaxTree")]
diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
index 24b4d78971d71..44dfe4361c157 100644
--- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
+++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
@@ -6708,22 +6708,32 @@ bool canBeNullableType()
case SyntaxKind.OpenBracketToken:
// Now check for arrays.
{
- var ranks = _pool.Allocate();
- try
+ // We don't want to consume a sized rank specifier in patterns, we leave it out to parse it as a length pattern.
+ bool inPattern = (nameOptions & NameOptions.PossiblePattern) != 0;
+ if (!inPattern || isOmittedSize())
{
- while (this.CurrentToken.Kind == SyntaxKind.OpenBracketToken)
+ bool sawOpenBracket;
+ var ranks = _pool.Allocate();
+ try
{
- var rank = this.ParseArrayRankSpecifier(out _);
- ranks.Add(rank);
+ do
+ {
+ ranks.Add(this.ParseArrayRankSpecifier(out _));
+ }
+ while ((sawOpenBracket = this.CurrentToken.Kind == SyntaxKind.OpenBracketToken) && (!inPattern || isOmittedSize()));
+
+ type = _syntaxFactory.ArrayType(type, ranks);
+ }
+ finally
+ {
+ _pool.Free(ranks);
}
- type = _syntaxFactory.ArrayType(type, ranks);
- }
- finally
- {
- _pool.Free(ranks);
+ // If we saw an open bracket that is not followed by an omitted size, it's possibly a length pattern.
+ if (!sawOpenBracket)
+ continue;
}
- continue;
+ goto done; // token not consumed
}
default:
goto done; // token not consumed
@@ -6733,6 +6743,8 @@ bool canBeNullableType()
Debug.Assert(type != null);
return type;
+
+ bool isOmittedSize() => this.PeekToken(1).Kind is SyntaxKind.CommaToken or SyntaxKind.CloseBracketToken;
}
private SyntaxToken EatNullableQualifierIfApplicable(ParseTypeMode mode)
diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs
index 2e6b9ecae1980..6f4ba91f68ac0 100644
--- a/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs
+++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs
@@ -207,6 +207,10 @@ private PatternSyntax ParsePrimaryPattern(Precedence precedence, bool afterIs, b
switch (CurrentToken.Kind)
{
+ case SyntaxKind.DotDotToken:
+ return _syntaxFactory.SlicePattern(
+ CheckFeatureAvailability(EatToken(), MessageID.IDS_FeatureSlicePattern),
+ IsPossibleSubpatternElement() ? ParseNegatedPattern(precedence, afterIs: false, whenIsKeyword) : null);
case SyntaxKind.LessThanToken:
case SyntaxKind.LessThanEqualsToken:
case SyntaxKind.GreaterThanToken:
@@ -301,8 +305,10 @@ private PatternSyntax ParsePatternContinued(TypeSyntax type, Precedence preceden
subPatterns: out SeparatedSyntaxList subPatterns,
closeToken: out SyntaxToken closeParenToken,
openKind: SyntaxKind.OpenParenToken,
- closeKind: SyntaxKind.CloseParenToken);
+ closeKind: SyntaxKind.CloseParenToken,
+ isPropertyPatternClause: out _);
+ parseLengthPatternClause(out LengthPatternClauseSyntax lengthPatternClause0);
parsePropertyPatternClause(out PropertyPatternClauseSyntax propertyPatternClause0);
parseDesignation(out VariableDesignationSyntax designation0);
@@ -330,14 +336,15 @@ private PatternSyntax ParsePatternContinued(TypeSyntax type, Precedence preceden
}
var positionalPatternClause = _syntaxFactory.PositionalPatternClause(openParenToken, subPatterns, closeParenToken);
- var result = _syntaxFactory.RecursivePattern(type, positionalPatternClause, propertyPatternClause0, designation0);
+ var result = _syntaxFactory.RecursivePattern(type, positionalPatternClause, lengthPatternClause0, propertyPatternClause0, designation0);
return result;
}
- if (parsePropertyPatternClause(out PropertyPatternClauseSyntax propertyPatternClause))
+ if (parseLengthPatternClause(out LengthPatternClauseSyntax lengthPatternClause) |
+ parsePropertyPatternClause(out PropertyPatternClauseSyntax propertyPatternClause))
{
parseDesignation(out VariableDesignationSyntax designation0);
- return _syntaxFactory.RecursivePattern(type, positionalPatternClause: null, propertyPatternClause, designation0);
+ return _syntaxFactory.RecursivePattern(type, positionalPatternClause: null, lengthPatternClause, propertyPatternClause, designation0);
}
if (type != null)
@@ -363,6 +370,17 @@ private PatternSyntax ParsePatternContinued(TypeSyntax type, Precedence preceden
// let the caller fall back to parsing an expression
return null;
+ bool parseLengthPatternClause(out LengthPatternClauseSyntax lengthPatternClause)
+ {
+ if (this.CurrentToken.Kind == SyntaxKind.OpenBracketToken)
+ {
+ lengthPatternClause = ParseLengthPatternClause();
+ return true;
+ }
+ lengthPatternClause = null;
+ return false;
+ }
+
bool parsePropertyPatternClause(out PropertyPatternClauseSyntax propertyPatternClauseResult)
{
propertyPatternClauseResult = null;
@@ -397,6 +415,15 @@ bool looksLikeCast()
}
}
+ private LengthPatternClauseSyntax ParseLengthPatternClause()
+ {
+ var openBracket = EatToken(SyntaxKind.OpenBracketToken);
+ var pattern = ParsePattern(Precedence.Conditional);
+ var closeBracket = EatToken(SyntaxKind.CloseBracketToken);
+ var result = _syntaxFactory.LengthPatternClause(openBracket, pattern, closeBracket);
+ return CheckFeatureAvailability(result, MessageID.IDS_FeatureLengthPattern);
+ }
+
private bool IsValidPatternDesignation(bool whenIsKeyword)
{
if (CurrentToken.Kind == SyntaxKind.IdentifierToken)
@@ -511,8 +538,10 @@ private PropertyPatternClauseSyntax ParsePropertyPatternClause()
subPatterns: out SeparatedSyntaxList subPatterns,
closeToken: out SyntaxToken closeBraceToken,
openKind: SyntaxKind.OpenBraceToken,
- closeKind: SyntaxKind.CloseBraceToken);
- return _syntaxFactory.PropertyPatternClause(openBraceToken, subPatterns, closeBraceToken);
+ closeKind: SyntaxKind.CloseBraceToken,
+ out bool isPropertyPatternClause);
+ var kind = isPropertyPatternClause ? SyntaxKind.PropertyPatternClause : SyntaxKind.ListPatternClause;
+ return _syntaxFactory.PropertyPatternClause(kind, openBraceToken, subPatterns, closeBraceToken);
}
private void ParseSubpatternList(
@@ -520,23 +549,26 @@ private void ParseSubpatternList(
out SeparatedSyntaxList subPatterns,
out SyntaxToken closeToken,
SyntaxKind openKind,
- SyntaxKind closeKind)
+ SyntaxKind closeKind,
+ out bool isPropertyPatternClause)
{
- Debug.Assert(openKind == SyntaxKind.OpenParenToken || openKind == SyntaxKind.OpenBraceToken);
- Debug.Assert(closeKind == SyntaxKind.CloseParenToken || closeKind == SyntaxKind.CloseBraceToken);
- Debug.Assert((openKind == SyntaxKind.OpenParenToken) == (closeKind == SyntaxKind.CloseParenToken));
+ Debug.Assert((openKind, closeKind) is
+ (SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken) or
+ (SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken));
Debug.Assert(openKind == this.CurrentToken.Kind);
+ isPropertyPatternClause = true;
+
openToken = this.EatToken(openKind);
var list = _pool.AllocateSeparated();
try
{
tryAgain:
-
if (this.IsPossibleSubpatternElement() || this.CurrentToken.Kind == SyntaxKind.CommaToken)
{
+ isPropertyPatternClause = false;
// first pattern
- list.Add(this.ParseSubpatternElement());
+ list.Add(this.ParseSubpatternElement(ref isPropertyPatternClause));
// additional patterns
int lastTokenPosition = -1;
@@ -555,7 +587,7 @@ private void ParseSubpatternList(
{
break;
}
- list.Add(this.ParseSubpatternElement());
+ list.Add(this.ParseSubpatternElement(ref isPropertyPatternClause));
continue;
}
else if (this.SkipBadPatternListTokens(ref openToken, list, SyntaxKind.CommaToken, closeKind) == PostSkipAction.Abort)
@@ -578,7 +610,7 @@ private void ParseSubpatternList(
}
}
- private SubpatternSyntax ParseSubpatternElement()
+ private SubpatternSyntax ParseSubpatternElement(ref bool sawNameColon)
{
NameColonSyntax nameColon = null;
if (this.CurrentToken.Kind == SyntaxKind.IdentifierToken && this.PeekToken(1).Kind == SyntaxKind.ColonToken)
@@ -586,6 +618,7 @@ private SubpatternSyntax ParseSubpatternElement()
var name = this.ParseIdentifierName();
var colon = this.EatToken(SyntaxKind.ColonToken);
nameColon = _syntaxFactory.NameColon(name, colon);
+ sawNameColon = true;
}
var pattern = ParsePattern(Precedence.Conditional);
@@ -600,15 +633,13 @@ private SubpatternSyntax ParseSubpatternElement()
private bool IsPossibleSubpatternElement()
{
return this.IsPossibleExpression(allowBinaryExpressions: false, allowAssignmentExpressions: false) ||
- this.CurrentToken.Kind switch
- {
- SyntaxKind.OpenBraceToken => true,
- SyntaxKind.LessThanToken => true,
- SyntaxKind.LessThanEqualsToken => true,
- SyntaxKind.GreaterThanToken => true,
- SyntaxKind.GreaterThanEqualsToken => true,
- _ => false
- };
+ this.CurrentToken.Kind is
+ SyntaxKind.OpenBraceToken or
+ SyntaxKind.OpenBracketToken or
+ SyntaxKind.LessThanToken or
+ SyntaxKind.LessThanEqualsToken or
+ SyntaxKind.GreaterThanToken or
+ SyntaxKind.GreaterThanEqualsToken;
}
private PostSkipAction SkipBadPatternListTokens(
diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
index 47fdde3be2e2f..78cdcc4bdbf1a 100644
--- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
+++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
@@ -1 +1,4 @@
override Microsoft.CodeAnalysis.CSharp.CSharpCompilation.GetUsedAssemblyReferences(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Immutable.ImmutableArray
+Microsoft.CodeAnalysis.CSharp.SyntaxKind.SlicePattern = 9034 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
+Microsoft.CodeAnalysis.CSharp.SyntaxKind.LengthPatternClause = 9035 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
+Microsoft.CodeAnalysis.CSharp.SyntaxKind.ListPatternClause = 9036 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
diff --git a/src/Compilers/CSharp/Portable/Syntax/PropertyPatternClauseSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/PropertyPatternClauseSyntax.cs
new file mode 100644
index 0000000000000..4032b57704448
--- /dev/null
+++ b/src/Compilers/CSharp/Portable/Syntax/PropertyPatternClauseSyntax.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#nullable enable
+
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Microsoft.CodeAnalysis.CSharp
+{
+ public partial class SyntaxFactory
+ {
+ public static PropertyPatternClauseSyntax PropertyPatternClause(SyntaxToken openBraceToken, SeparatedSyntaxList subpatterns, SyntaxToken closeBraceToken)
+ {
+ return PropertyPatternClause(SyntaxKind.PropertyPatternClause, openBraceToken, subpatterns, closeBraceToken);
+ }
+
+ public static PropertyPatternClauseSyntax PropertyPatternClause(SeparatedSyntaxList subpatterns = default)
+ {
+ return PropertyPatternClause(SyntaxKind.PropertyPatternClause, subpatterns);
+ }
+ }
+}
diff --git a/src/Compilers/CSharp/Portable/Syntax/RecursivePatternSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/RecursivePatternSyntax.cs
new file mode 100644
index 0000000000000..0138199debf84
--- /dev/null
+++ b/src/Compilers/CSharp/Portable/Syntax/RecursivePatternSyntax.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#nullable enable
+
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Microsoft.CodeAnalysis.CSharp.Syntax
+{
+ public partial class RecursivePatternSyntax
+ {
+ public RecursivePatternSyntax Update(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ {
+ return Update(type, positionalPatternClause, this.LengthPatternClause, propertyPatternClause, designation);
+ }
+
+ public RecursivePatternSyntax AddPropertyPatternClauseSubpatterns(params SubpatternSyntax[] items)
+ {
+ var propertyPatternClause = this.PropertyPatternClause ?? SyntaxFactory.PropertyPatternClause();
+ return WithPropertyPatternClause(propertyPatternClause.WithSubpatterns(propertyPatternClause.Subpatterns.AddRange(items)));
+ }
+ }
+}
+
+namespace Microsoft.CodeAnalysis.CSharp
+{
+ public partial class SyntaxFactory
+ {
+ public static RecursivePatternSyntax RecursivePattern(TypeSyntax? type, PositionalPatternClauseSyntax? positionalPatternClause, PropertyPatternClauseSyntax? propertyPatternClause, VariableDesignationSyntax? designation)
+ {
+ return RecursivePattern(type, positionalPatternClause, lengthPatternClause: null, propertyPatternClause, designation);
+ }
+ }
+}
diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml
index f24059e17aa41..d2371ee50b256 100644
--- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml
+++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml
@@ -2002,12 +2002,23 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -2020,6 +2031,7 @@
+
@@ -2093,6 +2105,13 @@
+
+
+
+
+
+
+
diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs
index 4686c56198157..45829f23243cd 100644
--- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs
+++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs
@@ -827,6 +827,11 @@ public enum SyntaxKind : ushort
AndPattern = 9032,
NotPattern = 9033,
+ // new patterns added in C# 10.0
+ SlicePattern = 9034,
+ LengthPatternClause = 9035,
+ ListPatternClause = 9036,
+
// Kinds between 9000 and 9039 are "reserved" for pattern matching.
DeclarationExpression = 9040,
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index ac1a9531bd044..cf2011ddfef2d 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -977,11 +977,26 @@
Vytvoření objektu s cílovým typem
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
Sestavení {0}, které obsahuje typ {1}, se odkazuje na architekturu .NET Framework, což se nepodporuje.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index c13857bef8189..e2c44555f5e45 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -977,11 +977,26 @@
Objekterstellung mit Zieltyp
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
Die Assembly "{0}" mit dem Typ "{1}" verweist auf das .NET Framework. Dies wird nicht unterstützt.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index e77b6c0174b94..b4d0ae7065265 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -977,11 +977,26 @@
creación de objetos con tipo de destino
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
El ensamblado "{0}" que contiene el tipo "{1}" hace referencia a .NET Framework, lo cual no se admite.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 09aa035471de8..26b99702a1ddb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -977,11 +977,26 @@
création d'un objet typé cible
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
L'assembly '{0}' contenant le type '{1}' référence le .NET Framework, ce qui n'est pas pris en charge.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 23ba661cefe46..2b4829f127dac 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -977,11 +977,26 @@
creazione di oggetti con tipo di destinazione
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
L'assembly '{0}' che contiene il tipo '{1}' fa riferimento a .NET Framework, che non è supportato.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index b514b4403a277..64d5cd824c1b9 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -977,11 +977,26 @@
target-typed オブジェクトの作成
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
型 '{1}' を含むアセンブリ '{0}' が .NET Framework を参照しています。これはサポートされていません。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 4d1e5edcf9666..8263349ee8aa8 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -977,11 +977,26 @@
대상으로 형식화된 개체 만들기
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
'{1}' 형식을 포함하는 '{0}' 어셈블리가 지원되지 않는 .NET Framework를 참조합니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 761e1ae2d9251..f2be468b5bdea 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -977,11 +977,26 @@
tworzenie obiektu z typem docelowym
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
Zestaw „{0}” zawierający typ „{1}” odwołuje się do platformy .NET Framework, co nie jest obsługiwane.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 349c28c45bc43..535b5f8beb48f 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -977,11 +977,26 @@
criação de objeto de tipo de destino
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
O assembly '{0}' contendo o tipo '{1}' referencia o .NET Framework, mas não há suporte para isso.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 6bcc64b24402b..3a97067f81bda 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -977,11 +977,26 @@
создание объекта с типом целевого объекта
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
Сборка "{0}", содержащая тип "{1}", ссылается на платформу .NET Framework, которая не поддерживается.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index fcbbf5ccca853..a47e819754a8f 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -977,11 +977,26 @@
hedeflenen türde nesne oluşturma
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
'{1}' türünü içeren '{0}' bütünleştirilmiş kodu, desteklenmeyen .NET Framework'e başvuruyor.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 2b3e67c909fc6..349126cfbbc4c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -977,11 +977,26 @@
创建目标类型对象
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
包含类型“{1}”的程序集“{0}”引用了 .NET Framework,而此操作不受支持。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 2c811ba28ee0e..a12cb2fb7b694 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -977,11 +977,26 @@
建立具目標類型的物件
+
+
+ length pattern
+
+
+
+
+ list pattern
+
+
sealed ToString in record
+
+
+ slice pattern
+
+
包含類型 '{1}' 的組件 '{0}' 參考了 .NET Framework,此情形不受支援。
diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IIsPatternExpression.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IIsPatternExpression.cs
index 5ecd5a7f3e309..af592087663b3 100644
--- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IIsPatternExpression.cs
+++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IIsPatternExpression.cs
@@ -1088,18 +1088,15 @@ void M1(object o, bool b)
var compilation = CreateCompilation(source, new[] { vbCompilation.EmitToImageReference() }, parseOptions: TestOptions.Regular8);
compilation.VerifyDiagnostics(
- // (6,33): error CS8400: Feature 'type pattern' is not available in C# 8.0. Please use language version 9.0 or greater.
- // b = /**/o is C1 { Prop[1]: var x }/**/;
- Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion8, "Prop[1]").WithArguments("type pattern", "9.0").WithLocation(6, 33),
// (6,33): error CS8503: A property subpattern requires a reference to the property or field to be matched, e.g. '{ Name: Prop[1] }'
// b = /**/o is C1 { Prop[1]: var x }/**/;
Diagnostic(ErrorCode.ERR_PropertyPatternNameMissing, "Prop[1]").WithArguments("Prop[1]").WithLocation(6, 33),
// (6,33): error CS0246: The type or namespace name 'Prop' could not be found (are you missing a using directive or an assembly reference?)
// b = /**/o is C1 { Prop[1]: var x }/**/;
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Prop").WithArguments("Prop").WithLocation(6, 33),
- // (6,37): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
+ // (6,37): error CS8652: The feature 'length pattern' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// b = /**/o is C1 { Prop[1]: var x }/**/;
- Diagnostic(ErrorCode.ERR_ArraySizeInDeclaration, "[1]").WithLocation(6, 37),
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "[1]").WithArguments("length pattern").WithLocation(6, 37),
// (6,40): error CS1003: Syntax error, ',' expected
// b = /**/o is C1 { Prop[1]: var x }/**/;
Diagnostic(ErrorCode.ERR_SyntaxError, ":").WithArguments(",", ":").WithLocation(6, 40),
@@ -1120,7 +1117,9 @@ void M1(object o, bool b)
IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'Prop[1]')
Children(0)
Pattern:
- ITypePatternOperation (OperationKind.TypePattern, Type: null, IsInvalid) (Syntax: 'Prop[1]') (InputType: ?, NarrowedType: Prop[], MatchedType: Prop[])
+ IRecursivePatternOperation (OperationKind.RecursivePattern, Type: null, IsInvalid) (Syntax: 'Prop[1]') (InputType: ?, NarrowedType: Prop, DeclaredSymbol: null, MatchedType: Prop, DeconstructSymbol: null)
+ DeconstructionSubpatterns (0)
+ PropertySubpatterns (0)
IPropertySubpatternOperation (OperationKind.PropertySubpattern, Type: null, IsInvalid) (Syntax: 'var x')
Member:
IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'var x')
diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs
index edeb611cea0f9..94dd2ad7f717b 100644
--- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs
@@ -33,6 +33,10 @@ public void DiagnosticAnalyzerAllInOne()
// https://github.com/dotnet/roslyn/issues/44682 Add to all in one
missingSyntaxKinds.Add(SyntaxKind.WithExpression);
missingSyntaxKinds.Add(SyntaxKind.RecordDeclaration);
+ // PROTOTYPE(list-patterns)
+ missingSyntaxKinds.Add(SyntaxKind.SlicePattern);
+ missingSyntaxKinds.Add(SyntaxKind.LengthPatternClause);
+ missingSyntaxKinds.Add(SyntaxKind.ListPatternClause);
var analyzer = new CSharpTrackingDiagnosticAnalyzer();
var options = new AnalyzerOptions(new[] { new TestAdditionalText() }.ToImmutableArray());
diff --git a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs
index fe56c3ae30b27..4be42307aa1df 100644
--- a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs
@@ -266,13 +266,16 @@ private static Syntax.InternalSyntax.VarPatternSyntax GenerateVarPattern()
=> InternalSyntaxFactory.VarPattern(InternalSyntaxFactory.Token(SyntaxKind.VarKeyword), GenerateSingleVariableDesignation());
private static Syntax.InternalSyntax.RecursivePatternSyntax GenerateRecursivePattern()
- => InternalSyntaxFactory.RecursivePattern(null, null, null, null);
+ => InternalSyntaxFactory.RecursivePattern(null, null, null, null, null);
+
+ private static Syntax.InternalSyntax.LengthPatternClauseSyntax GenerateLengthPatternClause()
+ => InternalSyntaxFactory.LengthPatternClause(InternalSyntaxFactory.Token(SyntaxKind.OpenBracketToken), GenerateDiscardPattern(), InternalSyntaxFactory.Token(SyntaxKind.CloseBracketToken));
private static Syntax.InternalSyntax.PositionalPatternClauseSyntax GeneratePositionalPatternClause()
=> InternalSyntaxFactory.PositionalPatternClause(InternalSyntaxFactory.Token(SyntaxKind.OpenParenToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.CloseParenToken));
private static Syntax.InternalSyntax.PropertyPatternClauseSyntax GeneratePropertyPatternClause()
- => InternalSyntaxFactory.PropertyPatternClause(InternalSyntaxFactory.Token(SyntaxKind.OpenBraceToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.CloseBraceToken));
+ => InternalSyntaxFactory.PropertyPatternClause(SyntaxKind.PropertyPatternClause, InternalSyntaxFactory.Token(SyntaxKind.OpenBraceToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(), InternalSyntaxFactory.Token(SyntaxKind.CloseBraceToken));
private static Syntax.InternalSyntax.SubpatternSyntax GenerateSubpattern()
=> InternalSyntaxFactory.Subpattern(null, GenerateDiscardPattern());
@@ -295,6 +298,9 @@ private static Syntax.InternalSyntax.BinaryPatternSyntax GenerateBinaryPattern()
private static Syntax.InternalSyntax.UnaryPatternSyntax GenerateUnaryPattern()
=> InternalSyntaxFactory.UnaryPattern(InternalSyntaxFactory.Token(SyntaxKind.NotKeyword), GenerateDiscardPattern());
+ private static Syntax.InternalSyntax.SlicePatternSyntax GenerateSlicePattern()
+ => InternalSyntaxFactory.SlicePattern(InternalSyntaxFactory.Token(SyntaxKind.DotDotToken), null);
+
private static Syntax.InternalSyntax.InterpolatedStringTextSyntax GenerateInterpolatedStringText()
=> InternalSyntaxFactory.InterpolatedStringText(InternalSyntaxFactory.Token(SyntaxKind.InterpolatedStringTextToken));
@@ -1719,12 +1725,25 @@ public void TestRecursivePatternFactoryAndProperties()
Assert.Null(node.Type);
Assert.Null(node.PositionalPatternClause);
+ Assert.Null(node.LengthPatternClause);
Assert.Null(node.PropertyPatternClause);
Assert.Null(node.Designation);
AttachAndCheckDiagnostics(node);
}
+ [Fact]
+ public void TestLengthPatternClauseFactoryAndProperties()
+ {
+ var node = GenerateLengthPatternClause();
+
+ Assert.Equal(SyntaxKind.OpenBracketToken, node.OpenBracketToken.Kind);
+ Assert.NotNull(node.Pattern);
+ Assert.Equal(SyntaxKind.CloseBracketToken, node.CloseBracketToken.Kind);
+
+ AttachAndCheckDiagnostics(node);
+ }
+
[Fact]
public void TestPositionalPatternClauseFactoryAndProperties()
{
@@ -1826,6 +1845,17 @@ public void TestUnaryPatternFactoryAndProperties()
AttachAndCheckDiagnostics(node);
}
+ [Fact]
+ public void TestSlicePatternFactoryAndProperties()
+ {
+ var node = GenerateSlicePattern();
+
+ Assert.Equal(SyntaxKind.DotDotToken, node.DotDotToken.Kind);
+ Assert.Null(node.Pattern);
+
+ AttachAndCheckDiagnostics(node);
+ }
+
[Fact]
public void TestInterpolatedStringTextFactoryAndProperties()
{
@@ -5898,6 +5928,32 @@ public void TestRecursivePatternIdentityRewriter()
Assert.Same(oldNode, newNode);
}
+ [Fact]
+ public void TestLengthPatternClauseTokenDeleteRewriter()
+ {
+ var oldNode = GenerateLengthPatternClause();
+ var rewriter = new TokenDeleteRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ if(!oldNode.IsMissing)
+ {
+ Assert.NotEqual(oldNode, newNode);
+ }
+
+ Assert.NotNull(newNode);
+ Assert.True(newNode.IsMissing, "No tokens => missing");
+ }
+
+ [Fact]
+ public void TestLengthPatternClauseIdentityRewriter()
+ {
+ var oldNode = GenerateLengthPatternClause();
+ var rewriter = new IdentityRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ Assert.Same(oldNode, newNode);
+ }
+
[Fact]
public void TestPositionalPatternClauseTokenDeleteRewriter()
{
@@ -6132,6 +6188,32 @@ public void TestUnaryPatternIdentityRewriter()
Assert.Same(oldNode, newNode);
}
+ [Fact]
+ public void TestSlicePatternTokenDeleteRewriter()
+ {
+ var oldNode = GenerateSlicePattern();
+ var rewriter = new TokenDeleteRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ if(!oldNode.IsMissing)
+ {
+ Assert.NotEqual(oldNode, newNode);
+ }
+
+ Assert.NotNull(newNode);
+ Assert.True(newNode.IsMissing, "No tokens => missing");
+ }
+
+ [Fact]
+ public void TestSlicePatternIdentityRewriter()
+ {
+ var oldNode = GenerateSlicePattern();
+ var rewriter = new IdentityRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ Assert.Same(oldNode, newNode);
+ }
+
[Fact]
public void TestInterpolatedStringTextTokenDeleteRewriter()
{
@@ -9929,13 +10011,16 @@ private static VarPatternSyntax GenerateVarPattern()
=> SyntaxFactory.VarPattern(SyntaxFactory.Token(SyntaxKind.VarKeyword), GenerateSingleVariableDesignation());
private static RecursivePatternSyntax GenerateRecursivePattern()
- => SyntaxFactory.RecursivePattern(default(TypeSyntax), default(PositionalPatternClauseSyntax), default(PropertyPatternClauseSyntax), default(VariableDesignationSyntax));
+ => SyntaxFactory.RecursivePattern(default(TypeSyntax), default(PositionalPatternClauseSyntax), default(LengthPatternClauseSyntax), default(PropertyPatternClauseSyntax), default(VariableDesignationSyntax));
+
+ private static LengthPatternClauseSyntax GenerateLengthPatternClause()
+ => SyntaxFactory.LengthPatternClause(SyntaxFactory.Token(SyntaxKind.OpenBracketToken), GenerateDiscardPattern(), SyntaxFactory.Token(SyntaxKind.CloseBracketToken));
private static PositionalPatternClauseSyntax GeneratePositionalPatternClause()
=> SyntaxFactory.PositionalPatternClause(SyntaxFactory.Token(SyntaxKind.OpenParenToken), new SeparatedSyntaxList(), SyntaxFactory.Token(SyntaxKind.CloseParenToken));
private static PropertyPatternClauseSyntax GeneratePropertyPatternClause()
- => SyntaxFactory.PropertyPatternClause(SyntaxFactory.Token(SyntaxKind.OpenBraceToken), new SeparatedSyntaxList(), SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
+ => SyntaxFactory.PropertyPatternClause(SyntaxKind.PropertyPatternClause, SyntaxFactory.Token(SyntaxKind.OpenBraceToken), new SeparatedSyntaxList(), SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
private static SubpatternSyntax GenerateSubpattern()
=> SyntaxFactory.Subpattern(default(NameColonSyntax), GenerateDiscardPattern());
@@ -9958,6 +10043,9 @@ private static BinaryPatternSyntax GenerateBinaryPattern()
private static UnaryPatternSyntax GenerateUnaryPattern()
=> SyntaxFactory.UnaryPattern(SyntaxFactory.Token(SyntaxKind.NotKeyword), GenerateDiscardPattern());
+ private static SlicePatternSyntax GenerateSlicePattern()
+ => SyntaxFactory.SlicePattern(SyntaxFactory.Token(SyntaxKind.DotDotToken), default(PatternSyntax));
+
private static InterpolatedStringTextSyntax GenerateInterpolatedStringText()
=> SyntaxFactory.InterpolatedStringText(SyntaxFactory.Token(SyntaxKind.InterpolatedStringTextToken));
@@ -11382,9 +11470,22 @@ public void TestRecursivePatternFactoryAndProperties()
Assert.Null(node.Type);
Assert.Null(node.PositionalPatternClause);
+ Assert.Null(node.LengthPatternClause);
Assert.Null(node.PropertyPatternClause);
Assert.Null(node.Designation);
- var newNode = node.WithType(node.Type).WithPositionalPatternClause(node.PositionalPatternClause).WithPropertyPatternClause(node.PropertyPatternClause).WithDesignation(node.Designation);
+ var newNode = node.WithType(node.Type).WithPositionalPatternClause(node.PositionalPatternClause).WithLengthPatternClause(node.LengthPatternClause).WithPropertyPatternClause(node.PropertyPatternClause).WithDesignation(node.Designation);
+ Assert.Equal(node, newNode);
+ }
+
+ [Fact]
+ public void TestLengthPatternClauseFactoryAndProperties()
+ {
+ var node = GenerateLengthPatternClause();
+
+ Assert.Equal(SyntaxKind.OpenBracketToken, node.OpenBracketToken.Kind());
+ Assert.NotNull(node.Pattern);
+ Assert.Equal(SyntaxKind.CloseBracketToken, node.CloseBracketToken.Kind());
+ var newNode = node.WithOpenBracketToken(node.OpenBracketToken).WithPattern(node.Pattern).WithCloseBracketToken(node.CloseBracketToken);
Assert.Equal(node, newNode);
}
@@ -11489,6 +11590,17 @@ public void TestUnaryPatternFactoryAndProperties()
Assert.Equal(node, newNode);
}
+ [Fact]
+ public void TestSlicePatternFactoryAndProperties()
+ {
+ var node = GenerateSlicePattern();
+
+ Assert.Equal(SyntaxKind.DotDotToken, node.DotDotToken.Kind());
+ Assert.Null(node.Pattern);
+ var newNode = node.WithDotDotToken(node.DotDotToken).WithPattern(node.Pattern);
+ Assert.Equal(node, newNode);
+ }
+
[Fact]
public void TestInterpolatedStringTextFactoryAndProperties()
{
@@ -15561,6 +15673,32 @@ public void TestRecursivePatternIdentityRewriter()
Assert.Same(oldNode, newNode);
}
+ [Fact]
+ public void TestLengthPatternClauseTokenDeleteRewriter()
+ {
+ var oldNode = GenerateLengthPatternClause();
+ var rewriter = new TokenDeleteRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ if(!oldNode.IsMissing)
+ {
+ Assert.NotEqual(oldNode, newNode);
+ }
+
+ Assert.NotNull(newNode);
+ Assert.True(newNode.IsMissing, "No tokens => missing");
+ }
+
+ [Fact]
+ public void TestLengthPatternClauseIdentityRewriter()
+ {
+ var oldNode = GenerateLengthPatternClause();
+ var rewriter = new IdentityRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ Assert.Same(oldNode, newNode);
+ }
+
[Fact]
public void TestPositionalPatternClauseTokenDeleteRewriter()
{
@@ -15795,6 +15933,32 @@ public void TestUnaryPatternIdentityRewriter()
Assert.Same(oldNode, newNode);
}
+ [Fact]
+ public void TestSlicePatternTokenDeleteRewriter()
+ {
+ var oldNode = GenerateSlicePattern();
+ var rewriter = new TokenDeleteRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ if(!oldNode.IsMissing)
+ {
+ Assert.NotEqual(oldNode, newNode);
+ }
+
+ Assert.NotNull(newNode);
+ Assert.True(newNode.IsMissing, "No tokens => missing");
+ }
+
+ [Fact]
+ public void TestSlicePatternIdentityRewriter()
+ {
+ var oldNode = GenerateSlicePattern();
+ var rewriter = new IdentityRewriter();
+ var newNode = rewriter.Visit(oldNode);
+
+ Assert.Same(oldNode, newNode);
+ }
+
[Fact]
public void TestInterpolatedStringTextTokenDeleteRewriter()
{
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests.cs
index 6ab590092da35..fee8745b097f5 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests.cs
@@ -6669,7 +6669,7 @@ public void TrailingCommaInPropertyPattern_02()
N(SyntaxKind.IsKeyword);
N(SyntaxKind.RecursivePattern);
{
- N(SyntaxKind.PropertyPatternClause);
+ N(SyntaxKind.ListPatternClause);
{
N(SyntaxKind.OpenBraceToken);
M(SyntaxKind.Subpattern);
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs
new file mode 100644
index 0000000000000..024c9af699370
--- /dev/null
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs
@@ -0,0 +1,1521 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
+using Microsoft.CodeAnalysis.Test.Utilities;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Microsoft.CodeAnalysis.CSharp.UnitTests
+{
+ public class PatternParsingTests_ListPatterns : ParsingTests
+ {
+ private new void UsingExpression(string text, params DiagnosticDescription[] expectedErrors)
+ {
+ UsingExpression(text, options: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview), expectedErrors);
+ }
+
+ public PatternParsingTests_ListPatterns(ITestOutputHelper output) : base(output)
+ {
+ }
+
+ [Fact]
+ public void LengthPattern_01()
+ {
+ UsingExpression(@"c is [0]{}");
+ verify();
+
+ UsingExpression(@"c is [0]{}", TestOptions.Regular9,
+ // (1,6): error CS8652: The feature 'length pattern' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // c is [0]{}
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "[0]").WithArguments("length pattern").WithLocation(1, 6));
+ verify();
+
+ void verify()
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+ }
+
+ [Fact]
+ public void LengthPattern_02()
+ {
+ UsingExpression(@"c is [>0]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.RelationalPattern);
+ {
+ N(SyntaxKind.GreaterThanToken);
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_03()
+ {
+ UsingExpression(@"c is [_]{P:P}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.DiscardPattern);
+ {
+ N(SyntaxKind.UnderscoreToken);
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.NameColon);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "P");
+ }
+ N(SyntaxKind.ColonToken);
+ }
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "P");
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_04()
+ {
+ UsingExpression(@"c is ()[0]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PositionalPatternClause);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_05()
+ {
+ UsingExpression(@"c is int[][0]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ArrayType);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.ArrayRankSpecifier);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.OmittedArraySizeExpression);
+ {
+ N(SyntaxKind.OmittedArraySizeExpressionToken);
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_06()
+ {
+ UsingExpression(@"c is int[0]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_07()
+ {
+ UsingExpression(@"c is List[0]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.GenericName);
+ {
+ N(SyntaxKind.IdentifierToken, "List");
+ N(SyntaxKind.TypeArgumentList);
+ {
+ N(SyntaxKind.LessThanToken);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.GreaterThanToken);
+ }
+ }
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_08()
+ {
+ UsingExpression(@"c is [{}]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ }
+
+ [Fact]
+ public void LengthPattern_09()
+ {
+ UsingExpression(@"c is C1 { Prop[1]: var x }",
+ // (1,18): error CS1003: Syntax error, ',' expected
+ // c is C1 { Prop[1]: var x }
+ Diagnostic(ErrorCode.ERR_SyntaxError, ":").WithArguments(",", ":").WithLocation(1, 18),
+ // (1,20): error CS1003: Syntax error, ',' expected
+ // c is C1 { Prop[1]: var x }
+ Diagnostic(ErrorCode.ERR_SyntaxError, "var").WithArguments(",", "").WithLocation(1, 20));
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "C1");
+ }
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "Prop");
+ }
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "1");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ M(SyntaxKind.CommaToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_10()
+ {
+ UsingExpression(@"c is [var x]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_11()
+ {
+ UsingExpression(@"c is [List]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.TypePattern);
+ {
+ N(SyntaxKind.GenericName);
+ {
+ N(SyntaxKind.IdentifierToken, "List");
+ N(SyntaxKind.TypeArgumentList);
+ {
+ N(SyntaxKind.LessThanToken);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.GreaterThanToken);
+ }
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_12()
+ {
+ UsingExpression(@"c is [string[]]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.TypePattern);
+ {
+ N(SyntaxKind.ArrayType);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.StringKeyword);
+ }
+ N(SyntaxKind.ArrayRankSpecifier);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.OmittedArraySizeExpression);
+ {
+ N(SyntaxKind.OmittedArraySizeExpressionToken);
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_13()
+ {
+ UsingExpression(@"c is [string[>0]]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.StringKeyword);
+ }
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.RelationalPattern);
+ {
+ N(SyntaxKind.GreaterThanToken);
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_14()
+ {
+ UsingExpression(@"c is [[_]]");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.DiscardPattern);
+ {
+ N(SyntaxKind.UnderscoreToken);
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_15()
+ {
+ UsingExpression(@"c is []",
+ // (1,7): error CS8504: Pattern missing
+ // c is []
+ Diagnostic(ErrorCode.ERR_MissingPattern, "]").WithLocation(1, 7));
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ M(SyntaxKind.ConstantPattern);
+ {
+ M(SyntaxKind.IdentifierName);
+ {
+ M(SyntaxKind.IdentifierToken);
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void LengthPattern_16()
+ {
+ UsingExpression(@"c is [0]()",
+ // (1,1): error CS1073: Unexpected token '('
+ // c is [0]()
+ Diagnostic(ErrorCode.ERR_UnexpectedToken, "c is [0]").WithArguments("(").WithLocation(1, 1));
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void NoRegressionOnEmptyPropertyPattern()
+ {
+ UsingExpression(@"c is {}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void NoRegressionOnArrayTypePattern()
+ {
+ UsingExpression(@"c is string[]");
+
+ N(SyntaxKind.IsExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.ArrayType);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.StringKeyword);
+ }
+ N(SyntaxKind.ArrayRankSpecifier);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.OmittedArraySizeExpression);
+ {
+ N(SyntaxKind.OmittedArraySizeExpressionToken);
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ListPattern_01()
+ {
+ UsingExpression(@"c is {{}}");
+ verify();
+
+ UsingExpression(@"c is {{}}", TestOptions.Regular9);
+ verify();
+
+ void verify()
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+ }
+
+ [Fact]
+ public void ListPattern_02()
+ {
+ UsingExpression(@"c is { 1, prop: 0 }");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "1");
+ }
+ }
+ }
+ N(SyntaxKind.CommaToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.NameColon);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "prop");
+ }
+ N(SyntaxKind.ColonToken);
+ }
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_01()
+ {
+ UsingExpression(@"c is {..}");
+ verify();
+
+ UsingExpression(@"c is {..}", TestOptions.Regular9,
+ // (1,7): error CS8652: The feature 'slice pattern' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // c is {..}
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "..").WithArguments("slice pattern").WithLocation(1, 7));
+ verify();
+
+ void verify()
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+ }
+
+ [Fact]
+ public void SlicePattern_02()
+ {
+ UsingExpression(@"c is {.. var x}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_03()
+ {
+ UsingExpression(@"c is ..");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_04()
+ {
+ UsingExpression(@"c is ....",
+ // (1,6): error CS8635: Unexpected character sequence '...'
+ // c is ....
+ Diagnostic(ErrorCode.ERR_TripleDotNotAllowed, "").WithLocation(1, 6)
+ );
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_05()
+ {
+ UsingExpression(@"c is {..{}}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_06()
+ {
+ UsingExpression(@"c is {.. not p}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.NotPattern);
+ {
+ N(SyntaxKind.NotKeyword);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "p");
+ }
+ }
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_07()
+ {
+ UsingExpression(@"c is {.. p or q}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.OrPattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "p");
+ }
+ }
+ }
+ N(SyntaxKind.OrKeyword);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "q");
+ }
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_08()
+ {
+ UsingExpression(@"c is {.. p or .. q}");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.OrPattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "p");
+ }
+ }
+ }
+ N(SyntaxKind.OrKeyword);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "q");
+ }
+ }
+ }
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_09()
+ {
+ UsingExpression(@"c is .. var x");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_10()
+ {
+ UsingExpression(@"c is .. Type");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "Type");
+ }
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_11()
+ {
+ UsingExpression(@"c is {var x ..}",
+ // (1,13): error CS1003: Syntax error, ',' expected
+ // c is {var x ..}
+ Diagnostic(ErrorCode.ERR_SyntaxError, "..").WithArguments(",", "..").WithLocation(1, 13));
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ }
+ M(SyntaxKind.CommaToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_12()
+ {
+ UsingExpression(@"c is var x ..",
+ // (1,12): error CS1073: Unexpected token '..'
+ // c is var x ..
+ Diagnostic(ErrorCode.ERR_UnexpectedToken, "..").WithArguments("..").WithLocation(1, 12));
+
+ N(SyntaxKind.RangeExpression);
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ }
+ N(SyntaxKind.DotDotToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_13()
+ {
+ UsingExpression(@"c is {{}..}",
+ // (1,9): error CS1003: Syntax error, ',' expected
+ // c is {{}..}
+ Diagnostic(ErrorCode.ERR_SyntaxError, "..").WithArguments(",", "..").WithLocation(1, 9));
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.ListPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.PropertyPatternClause);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ M(SyntaxKind.CommaToken);
+ N(SyntaxKind.Subpattern);
+ {
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_14()
+ {
+ UsingExpression(@"c is not p ..",
+ // (1,13): error CS1001: Identifier expected
+ // c is not p ..
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(1, 13),
+ // (1,14): error CS1001: Identifier expected
+ // c is not p ..
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(1, 14));
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.NotPattern);
+ {
+ N(SyntaxKind.NotKeyword);
+ N(SyntaxKind.ConstantPattern);
+ {
+ N(SyntaxKind.SimpleMemberAccessExpression);
+ {
+ N(SyntaxKind.SimpleMemberAccessExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "p");
+ }
+ N(SyntaxKind.DotToken);
+ M(SyntaxKind.IdentifierName);
+ {
+ M(SyntaxKind.IdentifierToken);
+ }
+ }
+ N(SyntaxKind.DotToken);
+ M(SyntaxKind.IdentifierName);
+ {
+ M(SyntaxKind.IdentifierToken);
+ }
+ }
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_15()
+ {
+ UsingExpression(@"c is not ..");
+
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.NotPattern);
+ {
+ N(SyntaxKind.NotKeyword);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ }
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_16()
+ {
+ UsingExpression(@"c is [..] ..",
+ // (1,11): error CS1073: Unexpected token '..'
+ // c is [..] ..
+ Diagnostic(ErrorCode.ERR_UnexpectedToken, "..").WithArguments("..").WithLocation(1, 11));
+
+ N(SyntaxKind.RangeExpression);
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.RecursivePattern);
+ {
+ N(SyntaxKind.LengthPatternClause);
+ {
+ N(SyntaxKind.OpenBracketToken);
+ N(SyntaxKind.SlicePattern);
+ {
+ N(SyntaxKind.DotDotToken);
+ }
+ N(SyntaxKind.CloseBracketToken);
+ }
+ }
+ }
+ N(SyntaxKind.DotDotToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_17()
+ {
+ UsingExpression(@"c is a .. or b ..",
+ // (1,9): error CS1001: Identifier expected
+ // c is a .. or b ..
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, ".").WithLocation(1, 9),
+ // (1,16): error CS1073: Unexpected token '..'
+ // c is a .. or b ..
+ Diagnostic(ErrorCode.ERR_UnexpectedToken, "..").WithArguments("..").WithLocation(1, 16));
+
+ N(SyntaxKind.RangeExpression);
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.DeclarationPattern);
+ {
+ N(SyntaxKind.QualifiedName);
+ {
+ N(SyntaxKind.QualifiedName);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "a");
+ }
+ N(SyntaxKind.DotToken);
+ M(SyntaxKind.IdentifierName);
+ {
+ M(SyntaxKind.IdentifierToken);
+ }
+ }
+ N(SyntaxKind.DotToken);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "or");
+ }
+ }
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "b");
+ }
+ }
+ }
+ N(SyntaxKind.DotDotToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void SlicePattern_18()
+ {
+ UsingExpression(@"c is (var x) .. > 0",
+ // (1,14): error CS1073: Unexpected token '..'
+ // c is (var x) .. > 0
+ Diagnostic(ErrorCode.ERR_UnexpectedToken, "..").WithArguments("..").WithLocation(1, 14));
+
+ N(SyntaxKind.GreaterThanExpression);
+ {
+ N(SyntaxKind.RangeExpression);
+ {
+ N(SyntaxKind.IsPatternExpression);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "c");
+ }
+ N(SyntaxKind.IsKeyword);
+ N(SyntaxKind.ParenthesizedPattern);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.VarPattern);
+ {
+ N(SyntaxKind.VarKeyword);
+ N(SyntaxKind.SingleVariableDesignation);
+ {
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ }
+ N(SyntaxKind.DotDotToken);
+ }
+ N(SyntaxKind.GreaterThanToken);
+ N(SyntaxKind.NumericLiteralExpression);
+ {
+ N(SyntaxKind.NumericLiteralToken, "0");
+ }
+ }
+ EOF();
+ }
+ }
+}
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
index a2a1db99543d7..f471533681ae8 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
@@ -48,6 +48,10 @@ public async Task DiagnosticAnalyzerDriverAllInOne()
// https://github.com/dotnet/roslyn/issues/44682 - Add to all in one
missingSyntaxNodes.Add(SyntaxKind.WithExpression);
missingSyntaxNodes.Add(SyntaxKind.RecordDeclaration);
+ // PROTOTYPE(list-patterns)
+ missingSyntaxNodes.Add(SyntaxKind.SlicePattern);
+ missingSyntaxNodes.Add(SyntaxKind.LengthPatternClause);
+ missingSyntaxNodes.Add(SyntaxKind.ListPatternClause);
var analyzer = new CSharpTrackingDiagnosticAnalyzer();
using var workspace = TestWorkspace.CreateCSharp(source, TestOptions.Regular, composition: s_compositionWithMockDiagnosticUpdateSourceRegistrationService);
diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs
index 43069af8b68ef..0515cf27b53db 100644
--- a/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs
+++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/PropertySubPatternCompletionProvider.cs
@@ -124,7 +124,7 @@ private static SyntaxToken TryGetOpenBraceOrCommaInPropertyPatternClause(SyntaxT
return default;
}
- return token.Parent.IsKind(SyntaxKind.PropertyPatternClause) ? token : default;
+ return token.Parent.IsKind(SyntaxKind.PropertyPatternClause, SyntaxKind.ListPatternClause) ? token : default;
}
}
}
diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs
index 99a45e3ec9dbe..c0ad5ce49ee3c 100644
--- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs
+++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs
@@ -160,6 +160,7 @@ public static bool IsCloseBraceOfExpression(this SyntaxToken token)
return false;
}
+ // PROTOTYPE(list-patterns) SyntaxKind.ListPatternClause
return token.Parent is ExpressionSyntax || token.Parent.IsKind(SyntaxKind.PropertyPatternClause);
}
@@ -330,6 +331,7 @@ public static bool IsCommaInSwitchExpression(this SyntaxToken token)
=> token.Kind() == SyntaxKind.CommaToken && token.Parent.IsKind(SyntaxKind.SwitchExpression);
public static bool IsCommaInPropertyPatternClause(this SyntaxToken token)
+ // PROTOTYPE(list-patterns) SyntaxKind.ListPatternClause
=> token.Kind() == SyntaxKind.CommaToken && token.Parent.IsKind(SyntaxKind.PropertyPatternClause);
public static bool IsIdentifierInLabeledStatement(this SyntaxToken token)
diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs
index 3d8136fbabfd5..f822c6dc3ea65 100644
--- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs
+++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs
@@ -180,6 +180,7 @@ protected static void AddBraceSuppressOperations(List list, S
// include lambda itself.
firstTokenOfNode = node.Parent.GetFirstToken(includeZeroWidth: true);
}
+ // PROTOTYPE(list-patterns) SyntaxKind.ListPatternClause
else if (node.IsKind(SyntaxKind.PropertyPatternClause))
{
// include the pattern recursive pattern syntax and/or subpattern
diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs
index 722c935523600..a975d0795f299 100644
--- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs
+++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Formatting.Rules;
@@ -219,7 +220,7 @@ private void AddBlockIndentationOperation(List list, Synta
}
// for lambda, set alignment around braces so that users can put brace wherever they want
- if (node.IsLambdaBodyBlock() || node.IsAnonymousMethodBlock() || node.IsKind(SyntaxKind.PropertyPatternClause) || node.IsKind(SyntaxKind.SwitchExpression))
+ if (node.IsLambdaBodyBlock() || node.IsAnonymousMethodBlock() || node.IsKind(SyntaxKind.PropertyPatternClause, SyntaxKind.ListPatternClause) || node.IsKind(SyntaxKind.SwitchExpression))
{
AddAlignmentBlockOperationRelativeToFirstTokenOnBaseTokenLine(list, bracePair);
}