1
- using Microsoft . CodeAnalysis ;
2
- using Microsoft . CodeAnalysis . CSharp . Syntax ;
3
- using Microsoft . CodeAnalysis . CSharp ;
1
+ using Microsoft . CodeAnalysis . CSharp . Syntax ;
4
2
using Semmle . Extraction . Kinds ;
5
- using Semmle . Extraction . Entities ;
6
3
using System . IO ;
7
4
8
5
namespace Semmle . Extraction . CSharp . Entities . Expressions
9
6
{
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
-
133
7
internal class IsPattern : Expression < IsPatternExpressionSyntax >
134
8
{
135
9
private IsPattern ( ExpressionNodeInfo info ) : base ( info . SetKind ( ExprKind . IS ) )
@@ -139,7 +13,7 @@ private IsPattern(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.IS))
139
13
protected override void PopulateExpression ( TextWriter trapFile )
140
14
{
141
15
Create ( cx , Syntax . Expression , this , 0 ) ;
142
- cx . CreatePattern ( Syntax . Pattern , this , 1 ) ;
16
+ Expressions . Pattern . Create ( cx , Syntax . Pattern , this , 1 ) ;
143
17
}
144
18
145
19
public static Expression Create ( ExpressionNodeInfo info ) => new IsPattern ( info ) . TryPopulate ( ) ;
0 commit comments