void DeclareIntoVariable(Context cx, IExpressionParentEntity parent, int intoChild, bool getElement) { if (intoDeclaration != null) { DeclareRangeVariable(cx, parent, intoChild, getElement, intoDeclaration, name); } }
/// <summary> /// Creates and populates a recursive pattern. /// </summary> /// <param name="cx">The extraction context.</param> /// <param name="syntax">The syntax node of the recursive pattern.</param> /// <param name="parent">The parent pattern/expression.</param> /// <param name="child">The child index of this pattern.</param> /// <param name="isTopLevel">If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere.</param> public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null)) { // Extract the type access if (syntax.Type is TypeSyntax t) { Expressions.TypeAccess.Create(cx, t, this, 1); } // Extract the local variable declaration if (syntax.Designation is VariableDesignationSyntax designation && cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol) { var type = Entities.Type.Create(cx, symbol.GetAnnotatedType()); VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), cx.Create(designation.GetLocation()), false, this, 0); } if (syntax.PositionalPatternClause is PositionalPatternClauseSyntax posPc) { new PositionalPattern(cx, posPc, this, 2); } if (syntax.PropertyPatternClause is PropertyPatternClauseSyntax pc) { new PropertyPattern(cx, pc, this, 3); } }
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, IEnumerable <TypedConstant> items, Semmle.Extraction.Entities.Location location) { var info = new ExpressionInfo( cx, AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.ARRAY_CREATION, parent, childIndex, true, null); var arrayCreation = new Expression(info); var length = items.Count(); Literal.CreateGenerated(cx, arrayCreation, 0, cx.Compilation.GetSpecialType(SpecialType.System_Int32), length, location); if (length > 0) { var arrayInit = ArrayInitializer.CreateGenerated(cx, arrayCreation, InitializerIndex, location); var child = 0; foreach (var item in items) { Expression.CreateGenerated(cx, item, arrayInit, child++, location); } } return(arrayCreation); }
public Expression Populate(Context cx, IExpressionParentEntity parent, int child) { if (declaration != null) // The first "from" clause, or a "let" clause { if (operand == null) { return(DeclareRangeVariable(cx, parent, child, true)); } else { if (method == null) { cx.ModelError(node, "Unable to determine target of query expression"); } var callExpr = new QueryCall(cx, method, node, parent, child); operand.Populate(cx, callExpr, 0); DeclareRangeVariable(cx, callExpr, 1, false); PopulateArguments(cx, callExpr, 2); DeclareIntoVariable(cx, callExpr, 2 + arguments.Count, false); return(callExpr); } } else { var callExpr = new QueryCall(cx, method, node, parent, child); operand.Populate(cx, callExpr, 0); PopulateArguments(cx, callExpr, 1); return(callExpr); } }
public override Expression Populate(Context cx, IExpressionParentEntity parent, int child) { var callExpr = new QueryCall(cx, method, node, parent, child); operand.Populate(cx, callExpr, 0); PopulateArguments(cx, callExpr, 1); return(callExpr); }
public QueryCall(Context cx, IMethodSymbol method, SyntaxNode clause, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, Type.Create(cx, method?.ReturnType), cx.Create(clause.GetLocation()), ExprKind.METHOD_INVOCATION, parent, child, false, null)) { if (method != null) { cx.Emit(Tuples.expr_call(this, Method.Create(cx, method))); } }
public ExpressionNodeInfo(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child, TypeInfo typeInfo) { Context = cx; Node = node; Parent = parent; Child = child; TypeInfo = typeInfo; Conversion = cx.GetModel(node).GetConversion(node); }
internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null)) { child = 0; foreach (var sub in posPc.Subpatterns) { cx.CreatePattern(sub.Pattern, this, child++); } }
public static void Populate(Context cx, VariableDeclarationSyntax decl, IExpressionParentEntity parent, int child, int childIncrement = 1) { var type = Type.Create(cx, cx.GetType(decl.Type)); foreach (var v in decl.Variables) { VariableDeclaration.CreateDeclarator(cx, v, type, decl.Type.IsVar, parent, child); child += childIncrement; } }
public QueryCall(Context cx, IMethodSymbol?method, SyntaxNode clause, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, method?.GetAnnotatedReturnType(), cx.CreateLocation(clause.GetLocation()), ExprKind.METHOD_INVOCATION, parent, child, false, null)) { if (method is not null) { cx.TrapWriter.Writer.expr_call(this, Method.Create(cx, method)); } }
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, Type.Create(cx, null), cx.Create(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null)) { child = 0; foreach (var sub in pp.Subpatterns) { var p = cx.CreatePattern(sub.Pattern, this, child++); cx.Emit(Tuples.exprorstmt_name(p, sub.NameColon.Name.ToString())); } }
public ExpressionInfo(Context cx, AnnotatedType type, Extraction.Entities.Location location, ExprKind kind, IExpressionParentEntity parent, int child, bool isCompilerGenerated, string value) { Context = cx; Type = type; Location = location; Kind = kind; Parent = parent; Child = child; ExprValue = value; IsCompilerGenerated = isCompilerGenerated; }
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, null, cx.CreateLocation(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null)) { child = 0; var trapFile = cx.TrapWriter.Writer; foreach (var sub in pp.Subpatterns) { var p = Expressions.Pattern.Create(cx, sub.Pattern, this, child++); trapFile.exprorstmt_name(p, sub.NameColon.Name.ToString()); } }
/// <summary> /// Creates an expression from a syntax node. /// Inserts type conversion as required. /// Population is deferred to avoid overflowing the stack. /// </summary> /// <param name="cx">The extraction context.</param> /// <param name="node">The node to extract.</param> /// <param name="parent">The parent entity.</param> /// <param name="child">The child index.</param> /// <param name="type">A type hint.</param> public static void CreateDeferred(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child) { if (ContainsPattern(node)) { // Expressions with patterns should be created right away, as they may introduce // local variables referenced in `LocalVariable::GetAlreadyCreated()` Create(cx, node, parent, child); } else { cx.PopulateLater(() => Create(cx, node, parent, child)); } }
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, Microsoft.CodeAnalysis.ITypeSymbol type, Extraction.Entities.Location location) { var typeAccessInfo = new ExpressionInfo( cx, AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.TYPE_ACCESS, parent, childIndex, true, null); return(new Expression(typeAccessInfo)); }
public static Expression CreateGeneratedNullLiteral(Context cx, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location) { var info = new ExpressionInfo( cx, null, location, ExprKind.NULL_LITERAL, parent, childIndex, true, ValueAsString(null)); return(new Expression(info)); }
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int index, Extraction.Entities.Location location) { var info = new ExpressionInfo( cx, null, location, ExprKind.ARRAY_INIT, parent, index, true, null); return(new Expression(info)); }
public static void Extract(this Context cx, CSharpSyntaxNode node, IExpressionParentEntity parent, int child) { using (cx.StackGuard) { try { node.Accept(new Ast(cx, parent, child)); } catch (System.Exception ex) // lgtm[cs/catch-of-all-exceptions] { cx.ModelError(node, $"Exception processing syntax node of type {node.Kind()}: {ex.Message}"); } } }
public static void Extract(this Context cx, CSharpSyntaxNode node, IExpressionParentEntity parent, int child) { using (cx.StackGuard) { try { node.Accept(new Ast(cx, parent, child)); } catch (System.Exception e) { cx.ModelError(node, "Exception processing syntax node of type {0}: {1}", node.Kind(), e); } } }
internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, null, cx.CreateLocation(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null)) { child = 0; foreach (var sub in pp.Subpatterns) { if (sub.ExpressionColon is null) { Context.ModelError(sub, "Expected to find 'Expression:' in pattern."); continue; } MakeExpressions(cx, this, sub, child++); } }
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location, string?value) { var info = new ExpressionInfo( cx, null, location, ExprKind.DEFAULT, parent, childIndex, true, value); return(new Expression(info)); }
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object value, Extraction.Entities.Location location) { var info = new ExpressionInfo( cx, AnnotatedTypeSymbol.CreateNotAnnotated(type), location, GetExprKind(type, null, cx), parent, childIndex, true, ValueAsString(value)); return(new Expression(info)); }
public override Expression Populate(Context cx, IExpressionParentEntity parent, int child) { if (method == null) { cx.ModelError(node, "Unable to determine target of query expression"); } var callExpr = new QueryCall(cx, method, node, parent, child); operand.Populate(cx, callExpr, 0); DeclareRangeVariable(cx, callExpr, 1, false, declaration, name); PopulateArguments(cx, callExpr, 2); DeclareIntoVariable(cx, callExpr, 2 + arguments.Count, false); return(callExpr); }
protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name) { var type = cx.GetType(Expr); AnnotatedTypeSymbol?declType; TypeSyntax? declTypeSyntax = null; if (getElement) { if (node is FromClauseSyntax from && from.Type is not null) { declTypeSyntax = from.Type; declType = cx.GetType(from.Type); } else { declTypeSyntax = null; declType = GetElementType(cx, type.Symbol); } }
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, Microsoft.CodeAnalysis.ITypeSymbol type, object?value, Action <Expression, int> createChild, Extraction.Entities.Location location) { var info = new ExpressionInfo( cx, AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.CAST, parent, childIndex, true, ValueAsString(value)); var ret = new Expression(info); createChild(ret, ExpressionIndex); TypeAccess.CreateGenerated(cx, ret, TypeAccessIndex, type, location); return(ret); }
protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name) { var type = Type.Create(cx, cx.GetType(Expr)); Extraction.Entities.Location nameLoc; Type declType; TypeSyntax declTypeSyntax = null; if (getElement) { var from = node as FromClauseSyntax; (declType, declTypeSyntax) = from != null && from.Type != null ? (Type.Create(cx, cx.GetType(from.Type)), from.Type) : (type.ElementType, null); } else { declType = type; } var decl = VariableDeclaration.Create(cx, variableSymbol, declType, declTypeSyntax, cx.Create(node.GetLocation()), nameLoc = cx.Create(name.GetLocation()), true, parent, child ); Expression.Create(cx, Expr, decl, 0); var access = new Expression(new ExpressionInfo(cx, type, nameLoc, ExprKind.LOCAL_VARIABLE_ACCESS, decl, 1, false, null)); cx.Emit(Tuples.expr_access(access, LocalVariable.GetAlreadyCreated(cx, variableSymbol))); return(decl); }
protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name) { var type = Type.Create(cx, cx.GetType(Expr)); Extraction.Entities.Location nameLoc; AnnotatedType declType; TypeSyntax declTypeSyntax = null; if (getElement) { if (node is FromClauseSyntax from && from.Type != null) { declTypeSyntax = from.Type; declType = Type.Create(cx, cx.GetType(from.Type)); } else { declTypeSyntax = null; declType = type.Type.ElementType; } }
/// <summary> /// Creates a generated expression from a typed constant. /// </summary> public static Expression?CreateGenerated(Context cx, TypedConstant constant, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location) { if (constant.IsNull || constant.Type is null) { return(Literal.CreateGeneratedNullLiteral(cx, parent, childIndex, location)); } switch (constant.Kind) { case TypedConstantKind.Primitive: return(Literal.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Value, location)); case TypedConstantKind.Enum: // Enum value is generated in the following format: (Enum)value Action <Expression, int> createChild = (parent, index) => Literal.CreateGenerated(cx, parent, index, ((INamedTypeSymbol)constant.Type).EnumUnderlyingType !, constant.Value, location); var cast = Cast.CreateGenerated(cx, parent, childIndex, constant.Type !, constant.Value, createChild, location); return(cast); case TypedConstantKind.Type: var type = ((ITypeSymbol)constant.Value !).OriginalDefinition; return(TypeOf.CreateGenerated(cx, parent, childIndex, type, location)); case TypedConstantKind.Array: // Single dimensional arrays are in the following format: // * new Type[N] { item1, item2, ..., itemN } // * new Type[0] // // itemI is generated recursively. return(NormalArrayCreation.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Values, location)); case TypedConstantKind.Error: default: cx.ExtractionError("Couldn't extract constant in attribute", constant.ToString(), location); return(null); } }
public static Expression CreateParenthesized(Context cx, VarPatternSyntax varPattern, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child) { var type = NullType.Create(cx); // 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.GetModel(variable).GetDeclaredSymbol(single) is ILocalSymbol local) { var decl = Create(cx, variable, Entities.Type.Create(cx, local.GetAnnotatedType()), true, tuple, child0++); var id = single.Identifier; 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); }
/// <summary> /// 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> public static Expression CreateParenthesized(Context cx, DeclarationExpressionSyntax node, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child) { var type = Entities.NullType.Create(cx); // 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)); cx.Try(null, null, () => { var child0 = 0; foreach (var variable in designation.Variables) { Create(cx, node, variable, tuple, child0++); } }); return(tuple); }