1- using Microsoft . CodeAnalysis ;
2- using Microsoft . CodeAnalysis . CSharp . Syntax ;
3- using Microsoft . CodeAnalysis . CSharp ;
1+ using Microsoft . CodeAnalysis . CSharp . Syntax ;
42using Semmle . Extraction . Kinds ;
5- using Semmle . Extraction . Entities ;
63using System . IO ;
74
85namespace Semmle . Extraction . CSharp . Entities . Expressions
96{
10- internal static class PatternExtensions
11- {
12- public static Expression CreatePattern ( this Context cx , PatternSyntax syntax , IExpressionParentEntity parent , int child )
13- {
14- switch ( syntax )
15- {
16- case ConstantPatternSyntax constantPattern :
17- return Expression . Create ( cx , constantPattern . Expression , parent , child ) ;
18-
19- case DeclarationPatternSyntax declPattern :
20- // Creates a single local variable declaration.
21- {
22- if ( declPattern . Designation is VariableDesignationSyntax designation )
23- {
24- if ( cx . GetModel ( syntax ) . GetDeclaredSymbol ( designation ) is ILocalSymbol symbol )
25- {
26- var type = Type . Create ( cx , symbol . GetAnnotatedType ( ) ) ;
27- return VariableDeclaration . Create ( cx , symbol , type , declPattern . Type , cx . Create ( syntax . GetLocation ( ) ) , false , parent , child ) ;
28- }
29- if ( designation is DiscardDesignationSyntax )
30- {
31- return Expressions . TypeAccess . Create ( cx , declPattern . Type , parent , child ) ;
32- }
33- throw new InternalError ( designation , "Designation pattern not handled" ) ;
34- }
35- throw new InternalError ( declPattern , "Declaration pattern not handled" ) ;
36- }
37-
38- case RecursivePatternSyntax recPattern :
39- return new RecursivePattern ( cx , recPattern , parent , child ) ;
40-
41- case VarPatternSyntax varPattern :
42- switch ( varPattern . Designation )
43- {
44- case ParenthesizedVariableDesignationSyntax parDesignation :
45- return VariableDeclaration . CreateParenthesized ( cx , varPattern , parDesignation , parent , child ) ;
46- case SingleVariableDesignationSyntax varDesignation :
47- if ( cx . GetModel ( syntax ) . GetDeclaredSymbol ( varDesignation ) is ILocalSymbol symbol )
48- {
49- var type = Type . Create ( cx , symbol . GetAnnotatedType ( ) ) ;
50-
51- return VariableDeclaration . Create ( cx , symbol , type , null , cx . Create ( syntax . GetLocation ( ) ) , true , parent , child ) ;
52- }
53-
54- throw new InternalError ( varPattern , "Unable to get the declared symbol of the var pattern designation." ) ;
55- default :
56- throw new InternalError ( "var pattern designation is unhandled" ) ;
57- }
58-
59- case DiscardPatternSyntax dp :
60- return new Discard ( cx , dp , parent , child ) ;
61-
62- default :
63- throw new InternalError ( syntax , "Pattern not handled" ) ;
64- }
65- }
66- }
67-
68- internal class PropertyPattern : Expression
69- {
70- internal PropertyPattern ( Context cx , PropertyPatternClauseSyntax pp , IExpressionParentEntity parent , int child ) :
71- base ( new ExpressionInfo ( cx , Entities . NullType . Create ( cx ) , cx . Create ( pp . GetLocation ( ) ) , ExprKind . PROPERTY_PATTERN , parent , child , false , null ) )
72- {
73- child = 0 ;
74- var trapFile = cx . TrapWriter . Writer ;
75- foreach ( var sub in pp . Subpatterns )
76- {
77- var p = cx . CreatePattern ( sub . Pattern , this , child ++ ) ;
78- trapFile . exprorstmt_name ( p , sub . NameColon . Name . ToString ( ) ) ;
79- }
80- }
81- }
82-
83- internal class PositionalPattern : Expression
84- {
85- internal PositionalPattern ( Context cx , PositionalPatternClauseSyntax posPc , IExpressionParentEntity parent , int child ) :
86- base ( new ExpressionInfo ( cx , Entities . NullType . Create ( cx ) , cx . Create ( posPc . GetLocation ( ) ) , ExprKind . POSITIONAL_PATTERN , parent , child , false , null ) )
87- {
88- child = 0 ;
89- foreach ( var sub in posPc . Subpatterns )
90- {
91- cx . CreatePattern ( sub . Pattern , this , child ++ ) ;
92- }
93- }
94- }
95-
96- internal class RecursivePattern : Expression
97- {
98- /// <summary>
99- /// Creates and populates a recursive pattern.
100- /// </summary>
101- /// <param name="cx">The extraction context.</param>
102- /// <param name="syntax">The syntax node of the recursive pattern.</param>
103- /// <param name="parent">The parent pattern/expression.</param>
104- /// <param name="child">The child index of this pattern.</param>
105- /// <param name="isTopLevel">If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere.</param>
106- public RecursivePattern ( Context cx , RecursivePatternSyntax syntax , IExpressionParentEntity parent , int child ) :
107- base ( new ExpressionInfo ( cx , Entities . NullType . Create ( cx ) , cx . Create ( syntax . GetLocation ( ) ) , ExprKind . RECURSIVE_PATTERN , parent , child , false , null ) )
108- {
109- // Extract the type access
110- if ( syntax . Type is TypeSyntax t )
111- Expressions . TypeAccess . Create ( cx , t , this , 1 ) ;
112-
113- // Extract the local variable declaration
114- if ( syntax . Designation is VariableDesignationSyntax designation && cx . GetModel ( syntax ) . GetDeclaredSymbol ( designation ) is ILocalSymbol symbol )
115- {
116- var type = Entities . Type . Create ( cx , symbol . GetAnnotatedType ( ) ) ;
117-
118- VariableDeclaration . Create ( cx , symbol , type , null , cx . Create ( syntax . GetLocation ( ) ) , false , this , 0 ) ;
119- }
120-
121- if ( syntax . PositionalPatternClause is PositionalPatternClauseSyntax posPc )
122- {
123- new PositionalPattern ( cx , posPc , this , 2 ) ;
124- }
125-
126- if ( syntax . PropertyPatternClause is PropertyPatternClauseSyntax pc )
127- {
128- new PropertyPattern ( cx , pc , this , 3 ) ;
129- }
130- }
131- }
132-
1337 internal class IsPattern : Expression < IsPatternExpressionSyntax >
1348 {
1359 private IsPattern ( ExpressionNodeInfo info ) : base ( info . SetKind ( ExprKind . IS ) )
@@ -139,7 +13,7 @@ private IsPattern(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.IS))
13913 protected override void PopulateExpression ( TextWriter trapFile )
14014 {
14115 Create ( cx , Syntax . Expression , this , 0 ) ;
142- cx . CreatePattern ( Syntax . Pattern , this , 1 ) ;
16+ Expressions . Pattern . Create ( cx , Syntax . Pattern , this , 1 ) ;
14317 }
14418
14519 public static Expression Create ( ExpressionNodeInfo info ) => new IsPattern ( info ) . TryPopulate ( ) ;
0 commit comments