mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
270 lines
12 KiB
C#
270 lines
12 KiB
C#
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.Kinds;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|
{
|
|
internal static class Factory
|
|
{
|
|
internal static Expression Create(ExpressionNodeInfo info)
|
|
{
|
|
// Some expressions can be extremely deep (e.g. string + string + string ...)
|
|
// to the extent that the stack has been known to overflow.
|
|
using (info.Context.StackGuard)
|
|
{
|
|
if (info.Node is null)
|
|
{
|
|
info.Context.ModelError(info.Location, "Attempt to create a null expression");
|
|
return new Unknown(info);
|
|
}
|
|
|
|
switch (info.Node.Kind())
|
|
{
|
|
case SyntaxKind.AddExpression:
|
|
case SyntaxKind.SubtractExpression:
|
|
case SyntaxKind.LessThanExpression:
|
|
case SyntaxKind.LessThanOrEqualExpression:
|
|
case SyntaxKind.GreaterThanExpression:
|
|
case SyntaxKind.GreaterThanOrEqualExpression:
|
|
case SyntaxKind.MultiplyExpression:
|
|
case SyntaxKind.LogicalAndExpression:
|
|
case SyntaxKind.EqualsExpression:
|
|
case SyntaxKind.ModuloExpression:
|
|
case SyntaxKind.BitwiseAndExpression:
|
|
case SyntaxKind.BitwiseOrExpression:
|
|
case SyntaxKind.DivideExpression:
|
|
case SyntaxKind.NotEqualsExpression:
|
|
case SyntaxKind.LogicalOrExpression:
|
|
case SyntaxKind.IsExpression:
|
|
case SyntaxKind.AsExpression:
|
|
case SyntaxKind.RightShiftExpression:
|
|
case SyntaxKind.UnsignedRightShiftExpression:
|
|
case SyntaxKind.LeftShiftExpression:
|
|
case SyntaxKind.ExclusiveOrExpression:
|
|
case SyntaxKind.CoalesceExpression:
|
|
return Binary.Create(info);
|
|
|
|
case SyntaxKind.FalseLiteralExpression:
|
|
case SyntaxKind.TrueLiteralExpression:
|
|
case SyntaxKind.StringLiteralExpression:
|
|
case SyntaxKind.Utf8StringLiteralExpression:
|
|
case SyntaxKind.NullLiteralExpression:
|
|
case SyntaxKind.NumericLiteralExpression:
|
|
case SyntaxKind.CharacterLiteralExpression:
|
|
case SyntaxKind.DefaultLiteralExpression:
|
|
return Literal.Create(info);
|
|
|
|
case SyntaxKind.InvocationExpression:
|
|
return Invocation.Create(info);
|
|
|
|
case SyntaxKind.PostIncrementExpression:
|
|
return PostfixUnary.Create(info.SetKind(ExprKind.POST_INCR), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
|
|
|
|
case SyntaxKind.PostDecrementExpression:
|
|
return PostfixUnary.Create(info.SetKind(ExprKind.POST_DECR), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
|
|
|
|
case SyntaxKind.AwaitExpression:
|
|
return Await.Create(info);
|
|
|
|
case SyntaxKind.ElementAccessExpression:
|
|
return NormalElementAccess.Create(info);
|
|
|
|
case SyntaxKind.SimpleAssignmentExpression:
|
|
case SyntaxKind.OrAssignmentExpression:
|
|
case SyntaxKind.AndAssignmentExpression:
|
|
case SyntaxKind.SubtractAssignmentExpression:
|
|
case SyntaxKind.AddAssignmentExpression:
|
|
case SyntaxKind.MultiplyAssignmentExpression:
|
|
case SyntaxKind.ExclusiveOrAssignmentExpression:
|
|
case SyntaxKind.LeftShiftAssignmentExpression:
|
|
case SyntaxKind.RightShiftAssignmentExpression:
|
|
case SyntaxKind.UnsignedRightShiftAssignmentExpression:
|
|
case SyntaxKind.DivideAssignmentExpression:
|
|
case SyntaxKind.ModuloAssignmentExpression:
|
|
case SyntaxKind.CoalesceAssignmentExpression:
|
|
return Assignment.Create(info);
|
|
|
|
case SyntaxKind.ObjectCreationExpression:
|
|
return ExplicitObjectCreation.Create(info);
|
|
|
|
case SyntaxKind.ImplicitObjectCreationExpression:
|
|
return ImplicitObjectCreation.Create(info);
|
|
|
|
case SyntaxKind.ArrayCreationExpression:
|
|
return NormalArrayCreation.Create(info);
|
|
|
|
case SyntaxKind.ObjectInitializerExpression:
|
|
return ObjectInitializer.Create(info);
|
|
|
|
case SyntaxKind.ArrayInitializerExpression:
|
|
return ImplicitArrayInitializer.Create(info);
|
|
|
|
case SyntaxKind.CollectionInitializerExpression:
|
|
return CollectionInitializer.Create(info);
|
|
|
|
case SyntaxKind.ConditionalAccessExpression:
|
|
return MemberAccess.Create(info, (ConditionalAccessExpressionSyntax)info.Node);
|
|
|
|
case SyntaxKind.SimpleMemberAccessExpression:
|
|
return MemberAccess.Create(info, (MemberAccessExpressionSyntax)info.Node);
|
|
|
|
case SyntaxKind.UnaryMinusExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.MINUS));
|
|
|
|
case SyntaxKind.UnaryPlusExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.PLUS));
|
|
|
|
case SyntaxKind.SimpleLambdaExpression:
|
|
return Lambda.Create(info, (SimpleLambdaExpressionSyntax)info.Node);
|
|
|
|
case SyntaxKind.ParenthesizedLambdaExpression:
|
|
return Lambda.Create(info, (ParenthesizedLambdaExpressionSyntax)info.Node);
|
|
|
|
case SyntaxKind.ConditionalExpression:
|
|
return Conditional.Create(info);
|
|
|
|
case SyntaxKind.CastExpression:
|
|
return Cast.Create(info);
|
|
|
|
case SyntaxKind.ParenthesizedExpression:
|
|
return Create(info.SetNode(((ParenthesizedExpressionSyntax)info.Node).Expression));
|
|
|
|
case SyntaxKind.PointerType:
|
|
case SyntaxKind.ArrayType:
|
|
case SyntaxKind.PredefinedType:
|
|
case SyntaxKind.NullableType:
|
|
case SyntaxKind.TupleType:
|
|
return TypeAccess.Create(info);
|
|
|
|
case SyntaxKind.TypeOfExpression:
|
|
return TypeOf.Create(info);
|
|
|
|
case SyntaxKind.QualifiedName:
|
|
case SyntaxKind.IdentifierName:
|
|
case SyntaxKind.AliasQualifiedName:
|
|
case SyntaxKind.GenericName:
|
|
return Name.Create(info);
|
|
|
|
case SyntaxKind.LogicalNotExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.LOG_NOT));
|
|
|
|
case SyntaxKind.BitwiseNotExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.BIT_NOT));
|
|
|
|
case SyntaxKind.PreIncrementExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.PRE_INCR));
|
|
|
|
case SyntaxKind.PreDecrementExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.PRE_DECR));
|
|
|
|
case SyntaxKind.ThisExpression:
|
|
return This.CreateExplicit(info);
|
|
|
|
case SyntaxKind.AddressOfExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.ADDRESS_OF));
|
|
|
|
case SyntaxKind.PointerIndirectionExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.POINTER_INDIRECTION));
|
|
|
|
case SyntaxKind.DefaultExpression:
|
|
return Default.Create(info);
|
|
|
|
case SyntaxKind.CheckedExpression:
|
|
return Checked.Create(info);
|
|
|
|
case SyntaxKind.UncheckedExpression:
|
|
return Unchecked.Create(info);
|
|
|
|
case SyntaxKind.BaseExpression:
|
|
return Base.Create(info);
|
|
|
|
case SyntaxKind.AnonymousMethodExpression:
|
|
return Lambda.Create(info, (AnonymousMethodExpressionSyntax)info.Node);
|
|
|
|
case SyntaxKind.ImplicitArrayCreationExpression:
|
|
return ImplicitArrayCreation.Create(info);
|
|
|
|
case SyntaxKind.AnonymousObjectCreationExpression:
|
|
return AnonymousObjectCreation.Create(info);
|
|
|
|
case SyntaxKind.ComplexElementInitializerExpression:
|
|
return CollectionInitializer.Create(info);
|
|
|
|
case SyntaxKind.SizeOfExpression:
|
|
return SizeOf.Create(info);
|
|
|
|
case SyntaxKind.PointerMemberAccessExpression:
|
|
return PointerMemberAccess.Create(info);
|
|
|
|
case SyntaxKind.QueryExpression:
|
|
return Query.Create(info);
|
|
|
|
case SyntaxKind.InterpolatedStringExpression:
|
|
return InterpolatedString.Create(info);
|
|
|
|
case SyntaxKind.MemberBindingExpression:
|
|
return MemberAccess.Create(info, (MemberBindingExpressionSyntax)info.Node);
|
|
|
|
case SyntaxKind.ElementBindingExpression:
|
|
return BindingElementAccess.Create(info);
|
|
|
|
case SyntaxKind.StackAllocArrayCreationExpression:
|
|
return StackAllocArrayCreation.Create(info);
|
|
|
|
case SyntaxKind.ImplicitStackAllocArrayCreationExpression:
|
|
return ImplicitStackAllocArrayCreation.Create(info);
|
|
|
|
case SyntaxKind.ArgListExpression:
|
|
return ArgList.Create(info);
|
|
|
|
case SyntaxKind.RefTypeExpression:
|
|
return RefType.Create(info);
|
|
|
|
case SyntaxKind.RefValueExpression:
|
|
return RefValue.Create(info);
|
|
|
|
case SyntaxKind.MakeRefExpression:
|
|
return MakeRef.Create(info);
|
|
|
|
case SyntaxKind.ThrowExpression:
|
|
return Throw.Create(info);
|
|
|
|
case SyntaxKind.DeclarationExpression:
|
|
return VariableDeclaration.Create(info.Context, (DeclarationExpressionSyntax)info.Node, info.Parent, info.Child);
|
|
|
|
case SyntaxKind.TupleExpression:
|
|
return Tuple.Create(info);
|
|
|
|
case SyntaxKind.RefExpression:
|
|
return Ref.Create(info);
|
|
|
|
case SyntaxKind.IsPatternExpression:
|
|
return IsPattern.Create(info);
|
|
|
|
case SyntaxKind.RangeExpression:
|
|
return RangeExpression.Create(info);
|
|
|
|
case SyntaxKind.IndexExpression:
|
|
return Unary.Create(info.SetKind(ExprKind.INDEX));
|
|
|
|
case SyntaxKind.SwitchExpression:
|
|
return Switch.Create(info);
|
|
|
|
case SyntaxKind.SuppressNullableWarningExpression:
|
|
return PostfixUnary.Create(info.SetKind(ExprKind.SUPPRESS_NULLABLE_WARNING), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
|
|
|
|
case SyntaxKind.WithExpression:
|
|
return WithExpression.Create(info);
|
|
|
|
case SyntaxKind.CollectionExpression:
|
|
return Collection.Create(info);
|
|
|
|
default:
|
|
info.Context.ModelError(info.Node, $"Unhandled expression '{info.Node}' of kind '{info.Node.Kind()}'");
|
|
return new Unknown(info);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|