Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4bfe89c

Browse files
authored
Merge pull request #1370 from hvitved/csharp/is-case-extraction
Approved by calumgrant
2 parents af08f85 + 2d0554a commit 4bfe89c

28 files changed

Lines changed: 173 additions & 146 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/IsPattern.cs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@ public static Expression CreatePattern(this Context cx, PatternSyntax syntax, IE
1818
case DeclarationPatternSyntax declPattern:
1919
// Creates a single local variable declaration.
2020
{
21-
if (declPattern.Designation is VariableDesignationSyntax designation && cx.Model(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
21+
if (declPattern.Designation is VariableDesignationSyntax designation)
2222
{
23-
var type = Type.Create(cx, symbol.Type);
24-
25-
return VariableDeclaration.Create(cx, symbol, type, cx.Create(syntax.GetLocation()), cx.Create(designation.GetLocation()), false, parent, child);
23+
if (cx.Model(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
24+
{
25+
var type = Type.Create(cx, symbol.Type);
26+
return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.Create(syntax.GetLocation()), cx.Create(designation.GetLocation()), false, parent, child);
27+
}
28+
if (designation is DiscardDesignationSyntax)
29+
{
30+
return Expressions.TypeAccess.Create(cx, declPattern.Type, parent, child);
31+
}
32+
throw new InternalError(designation, "Designation pattern not handled");
2633
}
27-
throw new InternalError(syntax, "Is pattern not handled");
34+
throw new InternalError(declPattern, "Declaration pattern not handled");
2835
}
2936

3037
case RecursivePatternSyntax recPattern:
@@ -40,7 +47,7 @@ public static Expression CreatePattern(this Context cx, PatternSyntax syntax, IE
4047
{
4148
var type = Type.Create(cx, symbol.Type);
4249

43-
return VariableDeclaration.Create(cx, symbol, type, cx.Create(syntax.GetLocation()), cx.Create(varDesignation.GetLocation()), false, parent, child);
50+
return VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), cx.Create(varDesignation.GetLocation()), false, parent, child);
4451
}
4552
else
4653
{
@@ -54,7 +61,7 @@ public static Expression CreatePattern(this Context cx, PatternSyntax syntax, IE
5461
return new Discard(cx, dp, parent, child);
5562

5663
default:
57-
throw new InternalError(syntax, "Is pattern not handled");
64+
throw new InternalError(syntax, "Pattern not handled");
5865
}
5966
}
6067
}
@@ -108,7 +115,7 @@ public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionPa
108115
{
109116
var type = Type.Create(cx, symbol.Type);
110117

111-
VariableDeclaration.Create(cx, symbol, type, cx.Create(syntax.GetLocation()), cx.Create(designation.GetLocation()), false, this, 0);
118+
VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), cx.Create(designation.GetLocation()), false, this, 0);
112119
}
113120

114121
if (syntax.PositionalPatternClause is PositionalPatternClauseSyntax posPc)
@@ -131,19 +138,14 @@ private IsPattern(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.IS))
131138

132139
private void PopulatePattern(PatternSyntax pattern, TypeSyntax optionalType, SyntaxToken varKeyword, VariableDesignationSyntax designation)
133140
{
134-
bool isVar = optionalType is null;
135-
if (!isVar)
136-
Expressions.TypeAccess.Create(cx, optionalType, this, 1);
137-
141+
var isVar = optionalType is null;
138142
if (!(designation is null) && cx.Model(pattern).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
139143
{
140144
var type = Type.Create(cx, symbol.Type);
141-
142-
if (isVar)
143-
new Expression(new ExpressionInfo(cx, type, cx.Create(varKeyword.GetLocation()), ExprKind.TYPE_ACCESS, this, 1, false, null));
144-
145-
VariableDeclaration.Create(cx, symbol, type, cx.Create(pattern.GetLocation()), cx.Create(designation.GetLocation()), isVar, this, 2);
145+
VariableDeclaration.Create(cx, symbol, type, optionalType, cx.Create(pattern.GetLocation()), cx.Create(designation.GetLocation()), isVar, this, 1);
146146
}
147+
else if (!isVar)
148+
Expressions.TypeAccess.Create(cx, optionalType, this, 1);
147149
}
148150

149151
protected override void Populate()
@@ -152,7 +154,7 @@ protected override void Populate()
152154
switch (Syntax.Pattern)
153155
{
154156
case ConstantPatternSyntax constantPattern:
155-
Create(cx, constantPattern.Expression, this, 3);
157+
Create(cx, constantPattern.Expression, this, 1);
156158
return;
157159
case VarPatternSyntax varPattern:
158160
PopulatePattern(varPattern, null, varPattern.VarKeyword, varPattern.Designation);
@@ -161,7 +163,7 @@ protected override void Populate()
161163
PopulatePattern(declPattern, declPattern.Type, default(SyntaxToken), declPattern.Designation);
162164
return;
163165
case RecursivePatternSyntax recPattern:
164-
new RecursivePattern(cx, recPattern, this, 3);
166+
new RecursivePattern(cx, recPattern, this, 1);
165167
return;
166168
default:
167169
throw new InternalError(Syntax, "Is pattern not handled");

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,21 @@ protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity pa
6666
Extraction.Entities.Location nameLoc;
6767

6868
Type declType;
69+
TypeSyntax declTypeSyntax = null;
6970
if (getElement)
7071
{
7172
var from = node as FromClauseSyntax;
72-
declType = from != null && from.Type != null
73-
? Type.Create(cx, cx.GetType(from.Type))
74-
: type.ElementType;
73+
(declType, declTypeSyntax) = from != null && from.Type != null
74+
? (Type.Create(cx, cx.GetType(from.Type)), from.Type)
75+
: (type.ElementType, null);
7576
}
7677
else
7778
declType = type;
7879

7980
var decl = VariableDeclaration.Create(cx,
8081
variableSymbol,
8182
declType,
83+
declTypeSyntax,
8284
cx.Create(node.GetLocation()),
8385
nameLoc = cx.Create(name.GetLocation()),
8486
true,

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Switch.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ protected override void Populate()
1818
{
1919
SwitchedExpr = Expression.Create(cx, Syntax.GoverningExpression, this, -1);
2020
int child = 0;
21-
foreach(var arm in Syntax.Arms)
21+
foreach (var arm in Syntax.Arms)
2222
{
2323
new SwitchCase(cx, arm, this, child++);
2424
}

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/VariableDeclaration.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@ class VariableDeclaration : Expression
1111
{
1212
VariableDeclaration(IExpressionInfo info) : base(info) { }
1313

14-
public static VariableDeclaration Create(Context cx, ISymbol symbol, Type type, Extraction.Entities.Location exprLocation, Extraction.Entities.Location declLocation, bool isVar, IExpressionParentEntity parent, int child)
14+
public static VariableDeclaration Create(Context cx, ISymbol symbol, Type type, TypeSyntax optionalSyntax, Extraction.Entities.Location exprLocation, Extraction.Entities.Location declLocation, bool isVar, IExpressionParentEntity parent, int child)
1515
{
1616
var ret = new VariableDeclaration(new ExpressionInfo(cx, type, exprLocation, ExprKind.LOCAL_VAR_DECL, parent, child, false, null));
17-
cx.Try(null, null, () => LocalVariable.Create(cx, symbol, ret, isVar, declLocation));
17+
cx.Try(null, null, () =>
18+
{
19+
LocalVariable.Create(cx, symbol, ret, isVar, declLocation);
20+
if (optionalSyntax != null)
21+
TypeMention.Create(cx, optionalSyntax, parent, type);
22+
});
1823
return ret;
1924
}
2025

@@ -65,7 +70,7 @@ public static Expression CreateParenthesized(Context cx, VarPatternSyntax varPat
6570
{
6671
var child0 = 0;
6772
foreach (var variable in designation.Variables)
68-
switch(variable)
73+
switch (variable)
6974
{
7075
case ParenthesizedVariableDesignationSyntax paren:
7176
CreateParenthesized(cx, varPattern, paren, tuple, child0++);
@@ -97,7 +102,7 @@ public static Expression CreateParenthesized(Context cx, VarPatternSyntax varPat
97102

98103
static Expression Create(Context cx, DeclarationExpressionSyntax node, VariableDesignationSyntax designation, IExpressionParentEntity parent, int child)
99104
{
100-
switch(designation)
105+
switch (designation)
101106
{
102107
case SingleVariableDesignationSyntax single:
103108
return CreateSingle(cx, node, single, parent, child);

csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Case.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,23 @@ class CasePattern : Case<CasePatternSwitchLabelSyntax>
6767
private CasePattern(Context cx, CasePatternSwitchLabelSyntax node, Switch parent, int child)
6868
: base(cx, node, parent, child) { }
6969

70-
private void PopulatePattern(PatternSyntax pattern, TypeSyntax optionalType, SyntaxToken varKeyword, VariableDesignationSyntax designation)
70+
private void PopulatePattern(PatternSyntax pattern, TypeSyntax optionalType, VariableDesignationSyntax designation)
7171
{
7272
var isVar = optionalType is null;
73-
if (!isVar)
74-
Expressions.TypeAccess.Create(cx, optionalType, this, 1);
75-
7673
switch (designation)
7774
{
7875
case SingleVariableDesignationSyntax _:
7976
if (cx.Model(pattern).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
8077
{
8178
var type = Type.Create(cx, symbol.Type);
82-
83-
if (isVar)
84-
new Expression(new ExpressionInfo(cx, type, cx.Create(varKeyword.GetLocation()), ExprKind.TYPE_ACCESS, this, 1, false, null));
85-
86-
Expressions.VariableDeclaration.Create(cx, symbol, type, cx.Create(pattern.GetLocation()), cx.Create(designation.GetLocation()), isVar, this, 0);
79+
Expressions.VariableDeclaration.Create(cx, symbol, type, optionalType, cx.Create(pattern.GetLocation()), cx.Create(designation.GetLocation()), isVar, this, 0);
8780
}
8881
break;
8982
case DiscardDesignationSyntax discard:
90-
new Expressions.Discard(cx, discard, this, 0);
83+
if (isVar)
84+
new Expressions.Discard(cx, discard, this, 0);
85+
else
86+
Expressions.TypeAccess.Create(cx, optionalType, this, 0);
9187
break;
9288
case null:
9389
break;
@@ -104,10 +100,10 @@ protected override void Populate()
104100
switch (Stmt.Pattern)
105101
{
106102
case VarPatternSyntax varPattern:
107-
PopulatePattern(varPattern, null, varPattern.VarKeyword, varPattern.Designation);
103+
PopulatePattern(varPattern, null, varPattern.Designation);
108104
break;
109105
case DeclarationPatternSyntax declarationPattern:
110-
PopulatePattern(declarationPattern, declarationPattern.Type, default(SyntaxToken), declarationPattern.Designation);
106+
PopulatePattern(declarationPattern, declarationPattern.Type, declarationPattern.Designation);
111107
break;
112108
case ConstantPatternSyntax pattern:
113109
Expression.Create(cx, pattern.Expression, this, 0);
@@ -121,7 +117,7 @@ protected override void Populate()
121117

122118
if (Stmt.WhenClause != null)
123119
{
124-
Expression.Create(cx, Stmt.WhenClause.Condition, this, 2);
120+
Expression.Create(cx, Stmt.WhenClause.Condition, this, 1);
125121
}
126122
}
127123

csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/ForEach.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ protected override void Populate()
2727
var location = cx.Create(Stmt.Identifier.GetLocation());
2828

2929
if (typeSymbol.Name != "_")
30-
Expressions.VariableDeclaration.Create(cx, typeSymbol, type, location, location, Stmt.Type.IsVar, this, 0);
31-
TypeMention.Create(cx, Stmt.Type, this, type);
30+
Expressions.VariableDeclaration.Create(cx, typeSymbol, type, Stmt.Type, location, location, Stmt.Type.IsVar, this, 0);
31+
else
32+
TypeMention.Create(cx, Stmt.Type, this, type);
3233

3334
Statement.Create(cx, Stmt.Statement, this, 2);
3435
}

csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ class ConstantNullnessCondition extends ConstantCondition {
7272
ConstantNullnessCondition() {
7373
forex(ControlFlow::Node cfn | cfn = this.getAControlFlowNode() |
7474
exists(ControlFlow::SuccessorTypes::NullnessSuccessor t, ControlFlow::Node s |
75-
s = cfn.getASuccessorByType(t) |
75+
s = cfn.getASuccessorByType(t)
76+
|
7677
b = t.getValue() and
7778
not s.isJoin()
7879
) and

csharp/ql/src/semmle/code/csharp/Assignable.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,8 @@ module AssignableInternal {
306306
/** A local variable declaration at the top-level of a pattern. */
307307
class TopLevelPatternDecl extends LocalVariableDeclExpr {
308308
private PatternMatch pm;
309-
TopLevelPatternDecl() {
310-
this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr()
311-
}
309+
310+
TopLevelPatternDecl() { this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr() }
312311

313312
PatternMatch getMatch() { result = pm }
314313
}

csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,8 @@ predicate expr_parent_top_level_adjusted(Expr child, int i, @top_level_exprorstm
1919
}
2020

2121
/**
22-
* Holds if `case` statement `cs` is a type check of the form `case int _`,
23-
* where `ta` is the type access `int`.
24-
*/
25-
private predicate discardTypeCaseStmt(CaseStmt cs, TypeAccess ta) {
26-
expr_parent(ta, 1, cs) and
27-
expr_parent(any(DiscardExpr de), 0, cs)
28-
}
29-
30-
/**
31-
* The `expr_parent()` relation adjusted for expandable assignments, `is` expressions,
32-
* and `case` statements. For example, the assignment `x += y` is extracted as
22+
* The `expr_parent()` relation adjusted for expandable assignments. For example,
23+
* the assignment `x += y` is extracted as
3324
*
3425
* ```
3526
* +=
@@ -78,35 +69,7 @@ private predicate expr_parent_adjusted(Expr child, int i, ControlFlowElement par
7869
not ao.hasExpandedAssignment() and
7970
expr_parent(child, i, parent)
8071
)
81-
else
82-
if parent instanceof IsExpr
83-
then
84-
i = 0 and
85-
expr_parent(child, i, parent)
86-
or
87-
// e.g. `x is string s` or `x is null`
88-
i = 1 and
89-
expr_parent(child, any(int j | j in [2 .. 3]), parent)
90-
or
91-
// e.g. `x is string`
92-
i = 1 and
93-
not expr_parent(_, any(int j | j in [2 .. 3]), parent) and
94-
expr_parent(child, i, parent)
95-
else
96-
if parent instanceof CaseStmt
97-
then
98-
// e.g. `case string s:` or `case 5:`
99-
i = 0 and
100-
expr_parent(child, i, parent) and
101-
not discardTypeCaseStmt(parent, _)
102-
or
103-
// e.g. `case string _`
104-
i = 0 and
105-
discardTypeCaseStmt(parent, child)
106-
or
107-
i = 1 and
108-
expr_parent(child, 2, parent)
109-
else expr_parent(child, i, parent)
72+
else expr_parent(child, i, parent)
11073
}
11174

11275
/**

csharp/ql/src/semmle/code/csharp/controlflow/internal/Completion.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,7 @@ predicate switchMatching(Switch s, Case c, PatternExpr pe) {
417417
pe = c.getPattern()
418418
}
419419

420-
private predicate mustHaveMatchingCompletion(Switch s, PatternExpr pe) {
421-
switchMatching(s, _, pe)
422-
}
420+
private predicate mustHaveMatchingCompletion(Switch s, PatternExpr pe) { switchMatching(s, _, pe) }
423421

424422
/**
425423
* Holds if a normal completion of `cfe` must be a matching completion. Thats is,

0 commit comments

Comments
 (0)