mirror of
https://github.com/github/codeql.git
synced 2026-05-05 13:45:19 +02:00
C#: Implement recursive patterns
This commit is contained in:
@@ -26,13 +26,13 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
if (variableSymbol == null)
|
||||
{
|
||||
cx.ModelError(node, "Failed to determine local variable");
|
||||
return new VariableDeclaration(cx, node, null, isVar, parent, child);
|
||||
return Create(cx, node, null, isVar, parent, child);
|
||||
}
|
||||
|
||||
var type = Type.Create(cx, variableSymbol.Type);
|
||||
var location = cx.Create(designation.GetLocation());
|
||||
|
||||
var ret = new VariableDeclaration(cx, designation, type, isVar, parent, child);
|
||||
var ret = Create(cx, designation, type, isVar, parent, child);
|
||||
cx.Try(null, null, () => LocalVariable.Create(cx, variableSymbol, ret, isVar, location));
|
||||
return ret;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
/// Create a tuple expression representing a parenthesized variable declaration.
|
||||
/// That is, we consider `var (x, y) = ...` to be equivalent to `(var x, var y) = ...`.
|
||||
/// </summary>
|
||||
static Expression CreateParenthesized(Context cx, DeclarationExpressionSyntax node, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child)
|
||||
public static Expression CreateParenthesized(Context cx, DeclarationExpressionSyntax node, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var type = Type.Create(cx, null); // Should ideally be a corresponding tuple type
|
||||
var tuple = new Expression(new ExpressionInfo(cx, type, cx.Create(node.GetLocation()), ExprKind.TUPLE, parent, child, false, null));
|
||||
@@ -56,41 +56,73 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
return tuple;
|
||||
}
|
||||
|
||||
public static Expression CreateParenthesized(Context cx, VarPatternSyntax varPattern, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var type = Type.Create(cx, null); // Should ideally be a corresponding tuple type
|
||||
var tuple = new Expression(new ExpressionInfo(cx, type, cx.Create(varPattern.GetLocation()), ExprKind.TUPLE, parent, child, false, null));
|
||||
|
||||
cx.Try(null, null, () =>
|
||||
{
|
||||
var child0 = 0;
|
||||
foreach (var variable in designation.Variables)
|
||||
switch(variable)
|
||||
{
|
||||
case ParenthesizedVariableDesignationSyntax paren:
|
||||
CreateParenthesized(cx, varPattern, paren, tuple, child0++);
|
||||
break;
|
||||
case SingleVariableDesignationSyntax single:
|
||||
if (cx.Model(variable).GetDeclaredSymbol(single) is ILocalSymbol local)
|
||||
{
|
||||
var decl = Create(cx, variable, Type.Create(cx, local.Type), true, tuple, child0++);
|
||||
var id = single.Identifier;
|
||||
var declSymbol = cx.Model(single).GetDeclaredSymbol(single);
|
||||
var location = cx.Create(id.GetLocation());
|
||||
LocalVariable.Create(cx, local, decl, true, location);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InternalError(single, "Failed to access local variable");
|
||||
}
|
||||
break;
|
||||
case DiscardDesignationSyntax discard:
|
||||
new Discard(cx, discard, tuple, child0++);
|
||||
break;
|
||||
default:
|
||||
throw new InternalError(variable, "Unhandled designation type");
|
||||
}
|
||||
});
|
||||
|
||||
return tuple;
|
||||
}
|
||||
|
||||
|
||||
static Expression Create(Context cx, DeclarationExpressionSyntax node, VariableDesignationSyntax designation, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var single = designation as SingleVariableDesignationSyntax;
|
||||
if (single != null)
|
||||
return CreateSingle(cx, node, single, parent, child);
|
||||
|
||||
var paren = designation as ParenthesizedVariableDesignationSyntax;
|
||||
if (paren != null)
|
||||
return CreateParenthesized(cx, node, paren, parent, child);
|
||||
|
||||
var discard = designation as DiscardDesignationSyntax;
|
||||
if (discard != null)
|
||||
switch(designation)
|
||||
{
|
||||
var type = cx.Model(node).GetTypeInfo(node).Type;
|
||||
return new VariableDeclaration(cx, node, Type.Create(cx, type), node.Type.IsVar, parent, child);
|
||||
case SingleVariableDesignationSyntax single:
|
||||
return CreateSingle(cx, node, single, parent, child);
|
||||
case ParenthesizedVariableDesignationSyntax paren:
|
||||
return CreateParenthesized(cx, node, paren, parent, child);
|
||||
case DiscardDesignationSyntax discard:
|
||||
var type = cx.Model(discard).GetTypeInfo(discard).Type;
|
||||
return Create(cx, node, Type.Create(cx, type), node.Type.IsVar, parent, child);
|
||||
default:
|
||||
cx.ModelError(node, "Failed to determine designation type");
|
||||
return Create(cx, node, null, node.Type.IsVar, parent, child);
|
||||
}
|
||||
|
||||
cx.ModelError(node, "Failed to determine designation type");
|
||||
return new VariableDeclaration(cx, node, null, node.Type.IsVar, parent, child);
|
||||
}
|
||||
|
||||
public static Expression Create(Context cx, DeclarationExpressionSyntax node, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
return Create(cx, node, node.Designation, parent, child);
|
||||
}
|
||||
public static Expression Create(Context cx, DeclarationExpressionSyntax node, IExpressionParentEntity parent, int child) =>
|
||||
Create(cx, node, node.Designation, parent, child);
|
||||
|
||||
VariableDeclaration(Context cx, CSharpSyntaxNode d, Type type, bool isVar, IExpressionParentEntity parent, int child)
|
||||
: base(new ExpressionInfo(cx, type, cx.Create(d.FixedLocation()), ExprKind.LOCAL_VAR_DECL, parent, child, false, null))
|
||||
{
|
||||
}
|
||||
public static VariableDeclaration Create(Context cx, CSharpSyntaxNode c, Type type, bool isVar, IExpressionParentEntity parent, int child) =>
|
||||
new VariableDeclaration(new ExpressionInfo(cx, type, cx.Create(c.FixedLocation()), ExprKind.LOCAL_VAR_DECL, parent, child, false, null));
|
||||
|
||||
public static VariableDeclaration Create(Context cx, CatchDeclarationSyntax d, bool isVar, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var type = Type.Create(cx, cx.Model(d).GetDeclaredSymbol(d).Type);
|
||||
var ret = new VariableDeclaration(cx, d, type, isVar, parent, child);
|
||||
var ret = Create(cx, d, type, isVar, parent, child);
|
||||
cx.Try(d, null, () =>
|
||||
{
|
||||
var id = d.Identifier;
|
||||
@@ -102,9 +134,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static VariableDeclaration Create(Context cx, VariableDeclaratorSyntax d, Type type, bool isVar, IExpressionParentEntity parent, int child)
|
||||
public static VariableDeclaration CreateDeclarator(Context cx, VariableDeclaratorSyntax d, Type type, bool isVar, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var ret = new VariableDeclaration(cx, d, type, isVar, parent, child);
|
||||
var ret = Create(cx, d, type, isVar, parent, child);
|
||||
cx.Try(d, null, () =>
|
||||
{
|
||||
var id = d.Identifier;
|
||||
@@ -137,7 +169,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
foreach (var v in decl.Variables)
|
||||
{
|
||||
VariableDeclaration.Create(cx, v, type, decl.Type.IsVar, parent, child);
|
||||
VariableDeclaration.CreateDeclarator(cx, v, type, decl.Type.IsVar, parent, child);
|
||||
child += childIncrement;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user