1
+ using System ;
2
+ using System . Collections . Generic ;
1
3
using Microsoft . CodeAnalysis . CSharp . Syntax ;
2
4
using Semmle . Extraction . Kinds ;
3
5
using Semmle . Extraction . Entities ;
@@ -10,17 +12,91 @@ internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpression
10
12
base ( new ExpressionInfo ( cx , null , cx . CreateLocation ( pp . GetLocation ( ) ) , ExprKind . PROPERTY_PATTERN , parent , child , false , null ) )
11
13
{
12
14
child = 0 ;
13
- var trapFile = cx . TrapWriter . Writer ;
14
15
foreach ( var sub in pp . Subpatterns )
15
16
{
16
- var p = Expressions . Pattern . Create ( cx , sub . Pattern , this , child ++ ) ;
17
- if ( sub . NameColon is null )
17
+ if ( sub . ExpressionColon is null )
18
18
{
19
- Context . ModelError ( sub , "Expected to find 'Name :' in pattern." ) ;
19
+ Context . ModelError ( sub , "Expected to find 'Expression :' in pattern." ) ;
20
20
continue ;
21
21
}
22
- trapFile . exprorstmt_name ( p , sub . NameColon . Name . ToString ( ) ) ;
22
+ MakeExpressions ( cx , this , sub , child ++ ) ;
23
+ }
24
+ }
25
+
26
+ private class AccessStep
27
+ {
28
+ public readonly string Identifier ;
29
+ public readonly Microsoft . CodeAnalysis . Location Location ;
30
+
31
+ public AccessStep ( string identifier , Microsoft . CodeAnalysis . Location location )
32
+ {
33
+ Identifier = identifier ;
34
+ Location = location ;
35
+ }
36
+ }
37
+
38
+ private class AccessStepPack
39
+ {
40
+ public readonly List < AccessStep > Prefix = new List < AccessStep > ( ) ;
41
+ public AccessStep Last { get ; private set ; }
42
+
43
+ public AccessStepPack Add ( string identifier , Microsoft . CodeAnalysis . Location location )
44
+ {
45
+ Prefix . Add ( Last ) ;
46
+ Last = new AccessStep ( identifier , location ) ;
47
+ return this ;
48
+ }
49
+
50
+ public AccessStepPack ( string identifier , Microsoft . CodeAnalysis . Location location )
51
+ {
52
+ Last = new AccessStep ( identifier , location ) ;
53
+ }
54
+ }
55
+
56
+ private static AccessStepPack GetAccessStepPack ( ExpressionSyntax syntax )
57
+ {
58
+ switch ( syntax )
59
+ {
60
+ case MemberAccessExpressionSyntax memberAccess :
61
+ return GetAccessStepPack ( memberAccess . Expression ) . Add ( memberAccess . Name . Identifier . ValueText , memberAccess . Name . Identifier . GetLocation ( ) ) ;
62
+ case IdentifierNameSyntax identifier :
63
+ return new AccessStepPack ( identifier . Identifier . Text , identifier . GetLocation ( ) ) ;
64
+ default :
65
+ throw new InternalError ( syntax , "Unexpected expression syntax in property patterns." ) ;
23
66
}
24
67
}
68
+
69
+ private static AccessStepPack GetAccessStepPack ( BaseExpressionColonSyntax syntax )
70
+ {
71
+ switch ( syntax )
72
+ {
73
+ case NameColonSyntax ncs :
74
+ return new AccessStepPack ( ncs . Name . ToString ( ) , ncs . Name . GetLocation ( ) ) ;
75
+ case ExpressionColonSyntax ecs :
76
+ return GetAccessStepPack ( ecs . Expression ) ;
77
+ default :
78
+ throw new InternalError ( syntax , "Unsupported expression colon in property pattern." ) ;
79
+ } ;
80
+ }
81
+
82
+ private static Expression CreateSyntheticExp ( Context cx , Microsoft . CodeAnalysis . Location location , IExpressionParentEntity parent , int child ) =>
83
+ new Expression ( new ExpressionInfo ( cx , null , cx . CreateLocation ( location ) , ExprKind . PROPERTY_PATTERN , parent , child , false , null ) ) ;
84
+
85
+ private static void MakeExpressions ( Context cx , IExpressionParentEntity parent , SubpatternSyntax syntax , int child )
86
+ {
87
+ var trapFile = cx . TrapWriter . Writer ;
88
+ var pack = GetAccessStepPack ( syntax . ExpressionColon ! ) ;
89
+
90
+ foreach ( var step in pack . Prefix )
91
+ {
92
+ var exp = CreateSyntheticExp ( cx , step . Location , parent , child ) ;
93
+ trapFile . exprorstmt_name ( exp , step . Identifier ) ;
94
+ parent = exp ;
95
+ child = 0 ;
96
+ }
97
+
98
+ var p = Expressions . Pattern . Create ( cx , syntax . Pattern , parent , child ) ;
99
+ trapFile . exprorstmt_name ( p , pack . Last . Identifier ) ;
100
+ }
25
101
}
26
102
}
0 commit comments