Files
codeql/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs

87 lines
4.4 KiB
C#

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
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 BinaryPatternSyntax binaryPattern:
return new BinaryPattern(cx, binaryPattern, parent, child);
case DeclarationPatternSyntax declPattern:
// Creates a single local variable declaration.
{
switch (declPattern.Designation)
{
case SingleVariableDesignationSyntax singleDesignation:
if (cx.GetModel(syntax).GetDeclaredSymbol(singleDesignation) is ILocalSymbol symbol)
{
var type = symbol.GetAnnotatedType();
return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.CreateLocation(syntax.GetLocation()), false, parent, child);
}
throw new InternalError(singleDesignation, "Unable to get the declared symbol of the declaration pattern designation.");
case DiscardDesignationSyntax _:
return Expressions.TypeAccess.Create(cx, declPattern.Type, parent, child);
default:
throw new InternalError($"declaration pattern designation of type {declPattern.Designation.GetType()} is unhandled");
}
}
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 = symbol.GetAnnotatedType();
return VariableDeclaration.Create(cx, symbol, type, null, cx.CreateLocation(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 of type {varPattern.Designation.GetType()} is unhandled");
}
case DiscardPatternSyntax dp:
return new Discard(cx, dp, parent, child);
case ListPatternSyntax listPattern:
return new ListPattern(cx, listPattern, parent, child);
case SlicePatternSyntax slicePattern:
return new SlicePattern(cx, slicePattern, parent, child);
default:
throw new InternalError(syntax, "Pattern not handled");
}
}
}
}