C#: Refactor recursive patterns implementation

- Extract names of properties in a propery match, using the `exprorstmt_name` relation.
- Simplify extraction of properties by not distinguishing between top-level patterns
  and nested patterns.
- Introduce `PatternExpr` to capture patterns in `is` expressions, `case` statements,
  and `switch` expression arms.
- Generalize `IsTypeExpr`, `IsPatternExpr`, `IsRecursivePatternExpr`, and `IsConstantExpr`
  to just `IsExpr` with a member predicate `PatternExpr getPattern()`.
- Generalize `TypeCase`, `RecursivePatternCase`, and `ConstCase` to just `CaseStmt` with
  a member predicate `PatternExpr getPattern()`.
- Introduce classes `Switch` and `Case` as base classes of switch statements/expressions
  and case statements/switch expression arms, respectively.
- Simplify CFG logic using the generalized classes.
- Generalize guards library to cover `switch` expressions tests.
- Generalize data flow library to cover `switch` expression assignments.
This commit is contained in:
Tom Hvitved
2019-05-21 15:26:20 +02:00
committed by Calum Grant
parent b28ad9066f
commit a1e58cedac
60 changed files with 1198 additions and 1307 deletions

View File

@@ -70,7 +70,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
private void PopulatePattern(PatternSyntax pattern, TypeSyntax optionalType, SyntaxToken varKeyword, VariableDesignationSyntax designation)
{
var isVar = optionalType is null;
if(!isVar)
if (!isVar)
Expressions.TypeAccess.Create(cx, optionalType, this, 1);
switch (designation)
@@ -101,7 +101,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
protected override void Populate()
{
switch(Stmt.Pattern)
switch (Stmt.Pattern)
{
case VarPatternSyntax varPattern:
PopulatePattern(varPattern, null, varPattern.VarKeyword, varPattern.Designation);
@@ -113,8 +113,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
Expression.Create(cx, pattern.Expression, this, 0);
break;
case RecursivePatternSyntax recPattern:
PopulatePattern(recPattern, recPattern.Type, default(SyntaxToken), recPattern.Designation);
new Expressions.RecursivePattern(cx, recPattern, this, 4, true);
new Expressions.RecursivePattern(cx, recPattern, this, 0);
break;
default:
throw new InternalError(Stmt, "Case pattern not handled");