Files
codeql/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs
2021-01-18 09:19:27 +01:00

80 lines
3.9 KiB
C#

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp;
using Semmle.Extraction.Entities;
namespace Semmle.Extraction.CSharp.Entities.Expressions
{
public static class Pattern
{
internal static Expression Create(Context cx, PatternSyntax syntax, IExpressionParentEntity parent, int child)
{
switch (syntax)
{
case ParenthesizedPatternSyntax parenthesizedPattern:
return Pattern.Create(cx, parenthesizedPattern.Pattern, parent, child);
case ConstantPatternSyntax constantPattern:
return Expression.Create(cx, constantPattern.Expression, parent, child);
case TypePatternSyntax typePattern:
return Expressions.TypeAccess.Create(cx, typePattern.Type, parent, child);
case UnaryPatternSyntax unaryPattern:
return new UnaryPattern(cx, unaryPattern, parent, child);
case DeclarationPatternSyntax declPattern:
// Creates a single local variable declaration.
{
if (declPattern.Designation is VariableDesignationSyntax designation)
{
if (cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.Create(syntax.GetLocation()), false, parent, child);
}
if (designation is DiscardDesignationSyntax)
{
return Expressions.TypeAccess.Create(cx, declPattern.Type, parent, child);
}
throw new InternalError(designation, "Designation pattern not handled");
}
throw new InternalError(declPattern, "Declaration pattern not handled");
}
case RecursivePatternSyntax recPattern:
return new RecursivePattern(cx, recPattern, parent, child);
case RelationalPatternSyntax relPattern:
return new RelationalPattern(cx, relPattern, parent, child);
case VarPatternSyntax varPattern:
switch (varPattern.Designation)
{
case ParenthesizedVariableDesignationSyntax parDesignation:
return VariableDeclaration.CreateParenthesized(cx, varPattern, parDesignation, parent, child);
case SingleVariableDesignationSyntax varDesignation:
if (cx.GetModel(syntax).GetDeclaredSymbol(varDesignation) is ILocalSymbol symbol)
{
var type = Type.Create(cx, symbol.GetAnnotatedType());
return VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), true, parent, child);
}
throw new InternalError(varPattern, "Unable to get the declared symbol of the var pattern designation.");
case DiscardDesignationSyntax discard:
return new Expressions.Discard(cx, discard, parent, child);
default:
throw new InternalError("var pattern designation is unhandled");
}
case DiscardPatternSyntax dp:
return new Discard(cx, dp, parent, child);
default:
throw new InternalError(syntax, "Pattern not handled");
}
}
}
}