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); }
internal void SetType(ITypeSymbol?type) { if (type is not null) { Type = new AnnotatedTypeSymbol(type, type.NullableAnnotation); } }
protected void PopulateNullability(TextWriter trapFile, AnnotatedTypeSymbol type) { var n = NullabilityEntity.Create(Context, Nullability.Create(type)); if (!type.HasObliviousNullability()) { trapFile.type_nullability(this, n); } }
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 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 static IEnumerable <AnnotatedTypeSymbol> GetAnnotatedTypeArguments(this AnnotatedTypeSymbol at) { switch (at.Symbol) { case IArrayTypeSymbol array: yield return(array.GetAnnotatedElementType()); break; case INamedTypeSymbol named: foreach (var n in named.GetAnnotatedTypeArguments()) { yield return(n); } break; } }
public static Nullability Create(AnnotatedTypeSymbol ts) { if (ts.HasConsistentNullability()) { switch (ts.Nullability) { case NullableAnnotation.Annotated: return(annotated); case NullableAnnotation.NotAnnotated: return(notannotated); default: return(oblivious); } } return(new Nullability(ts)); }
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 override void PopulateExpression(TextWriter trapFile) { var child = 0; foreach (var i in Syntax.Expressions) { var collectionInfo = cx.GetModel(Syntax).GetCollectionInitializerSymbolInfo(i); var addMethod = Method.Create(cx, collectionInfo.Symbol as IMethodSymbol); var voidType = AnnotatedTypeSymbol.CreateNotAnnotated(cx.Compilation.GetSpecialType(SpecialType.System_Void)); var invocation = new Expression(new ExpressionInfo(cx, voidType, cx.CreateLocation(i.GetLocation()), ExprKind.METHOD_INVOCATION, this, child++, false, null)); if (addMethod != null) { trapFile.expr_call(invocation, addMethod); } else { cx.ModelError(Syntax, "Unable to find an Add() method for collection initializer"); } if (i.Kind() == SyntaxKind.ComplexElementInitializerExpression) { // Arrays of the form new Foo { { 1,2 }, { 3, 4 } } // where the arguments { 1, 2 } are passed to the Add() method. var init = (InitializerExpressionSyntax)i; var addChild = 0; foreach (var arg in init.Expressions) { Create(cx, arg, invocation, addChild++); } } else { Create(cx, i, invocation, 0); } } }
public override void Populate(TextWriter trapFile) { PopulateMetadataHandle(trapFile); PopulateAttributes(); PopulateModifiers(trapFile); BindComments(); PopulateNullability(trapFile, symbol.GetAnnotatedType()); PopulateRefKind(trapFile, symbol.RefKind); var type = Type; trapFile.properties(this, symbol.GetName(), ContainingType, type.TypeRef, Create(Context, symbol.OriginalDefinition)); var getter = symbol.GetMethod; var setter = symbol.SetMethod; if (!(getter is null)) { Method.Create(Context, getter); } if (!(setter is null)) { Method.Create(Context, setter); } var declSyntaxReferences = IsSourceDeclaration ? symbol.DeclaringSyntaxReferences. Select(d => d.GetSyntax()).OfType <PropertyDeclarationSyntax>().ToArray() : Enumerable.Empty <PropertyDeclarationSyntax>(); foreach (var explicitInterface in symbol.ExplicitInterfaceImplementations.Select(impl => Type.Create(Context, impl.ContainingType))) { trapFile.explicitly_implements(this, explicitInterface.TypeRef); foreach (var syntax in declSyntaxReferences) { TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier.Name, this, explicitInterface); } } foreach (var l in Locations) { trapFile.property_location(this, l); } if (IsSourceDeclaration && symbol.FromSource()) { var expressionBody = ExpressionBody; if (expressionBody != null) { Context.PopulateLater(() => Expression.Create(Context, expressionBody, this, 0)); } var child = 1; foreach (var initializer in declSyntaxReferences .Select(n => n.Initializer) .Where(i => i != null)) { Context.PopulateLater(() => { var loc = Context.CreateLocation(initializer.GetLocation()); var annotatedType = AnnotatedTypeSymbol.CreateNotAnnotated(symbol.Type); var simpleAssignExpr = new Expression(new ExpressionInfo(Context, annotatedType, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, null)); Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer.Value, simpleAssignExpr, 0)); var access = new Expression(new ExpressionInfo(Context, annotatedType, Location, ExprKind.PROPERTY_ACCESS, simpleAssignExpr, 1, false, null)); trapFile.expr_access(access, this); if (!symbol.IsStatic) { This.CreateImplicit(Context, symbol.ContainingType, Location, access, -1); } }); } foreach (var syntax in declSyntaxReferences) { TypeMention.Create(Context, syntax.Type, this, type); } } }
private Nullability(AnnotatedTypeSymbol ts) : this(ts.Nullability) { NullableParameters = ts.HasConsistentNullability() ? emptyArray : ts.GetAnnotatedTypeArguments().Select(Create).ToArray(); }
/// <summary> /// Holds if the type symbol is completely oblivious to nullability. /// </summary> /// <param name="at">The annotated type symbol.</param> /// <returns>If at is oblivious.</returns> public static bool HasObliviousNullability(this AnnotatedTypeSymbol at) => at.Nullability.GetTypeAnnotation() == Kinds.TypeAnnotation.None && at.HasConsistentNullability();
/// <summary> /// Checks if this type has consistent nullability, which is the most common case. /// Either the code is oblivious to nullability, or is non-nullable. /// This is so that we can avoid populating nullability in most cases. /// For example, /// <code> /// IEnumerable<string?> // false /// IEnumerable<string?>? // true /// string? // true /// string[] // true /// string?[] // false /// string?[]? // true /// </code> /// </summary> /// <param name="at">The annotated type.</param> /// <returns>If the nullability is consistent in the type.</returns> public static bool HasConsistentNullability(this AnnotatedTypeSymbol at) => at.GetAnnotatedTypeArguments().All(a => a.Nullability == at.Nullability && a.HasConsistentNullability());
protected override void ExtractInitializers(TextWriter trapFile) { // Do not extract initializers for constructed types. if (!IsSourceDeclaration) { return; } var syntax = Syntax; var initializer = syntax?.Initializer; if (initializer is null) { return; } ITypeSymbol initializerType; var symbolInfo = Context.GetSymbolInfo(initializer); switch (initializer.Kind()) { case SyntaxKind.BaseConstructorInitializer: initializerType = Symbol.ContainingType.BaseType !; break; case SyntaxKind.ThisConstructorInitializer: initializerType = Symbol.ContainingType; break; default: Context.ModelError(initializer, "Unknown initializer"); return; } var initInfo = new ExpressionInfo(Context, AnnotatedTypeSymbol.CreateNotAnnotated(initializerType), Context.CreateLocation(initializer.ThisOrBaseKeyword.GetLocation()), Kinds.ExprKind.CONSTRUCTOR_INIT, this, -1, false, null); var init = new Expression(initInfo); var target = Constructor.Create(Context, (IMethodSymbol?)symbolInfo.Symbol); if (target is null) { Context.ModelError(Symbol, "Unable to resolve call"); return; } trapFile.expr_call(init, target); var child = 0; foreach (var arg in initializer.ArgumentList.Arguments) { Expression.Create(Context, arg.Expression, init, child++); } }
public static VariableDeclaration CreateDeclarator(Context cx, VariableDeclaratorSyntax d, AnnotatedTypeSymbol type, bool isVar, IExpressionParentEntity parent, int child) { var ret = Create(cx, d, type, parent, child); cx.Try(d, null, () => { var declSymbol = cx.GetModel(d).GetDeclaredSymbol(d) !; var localVar = LocalVariable.Create(cx, declSymbol); localVar.PopulateManual(ret, isVar); if (d.Initializer is not null) { Create(cx, d.Initializer.Value, ret, 0); // Create an access var access = new Expression(new ExpressionInfo(cx, type, localVar.Location, ExprKind.LOCAL_VARIABLE_ACCESS, ret, 1, false, null)); cx.TrapWriter.Writer.expr_access(access, localVar); } if (d.Parent is VariableDeclarationSyntax decl) { TypeMention.Create(cx, decl.Type, ret, type); } }); return(ret); }
public static AnnotatedType Create(Context cx, AnnotatedTypeSymbol type) => new AnnotatedType(Create(cx, type.Symbol), type.Nullability.GetTypeAnnotation());
protected override void ExtractInitializers(TextWriter trapFile) { // Do not extract initializers for constructed types. if (!IsSourceDeclaration) { return; } var syntax = Syntax; var initializer = syntax?.Initializer; if (initializer is null) { if (Symbol.MethodKind is MethodKind.Constructor) { var baseType = Symbol.ContainingType.BaseType; if (baseType is null) { if (Symbol.ContainingType.SpecialType != SpecialType.System_Object) { Context.ModelError(Symbol, "Unable to resolve base type in implicit constructor initializer"); } return; } var baseConstructor = baseType.InstanceConstructors.FirstOrDefault(c => c.Arity is 0); if (baseConstructor is null) { Context.ModelError(Symbol, "Unable to resolve implicit constructor initializer call"); return; } var baseConstructorTarget = Create(Context, baseConstructor); var info = new ExpressionInfo(Context, AnnotatedTypeSymbol.CreateNotAnnotated(baseType), Location, Kinds.ExprKind.CONSTRUCTOR_INIT, this, -1, isCompilerGenerated: true, null); trapFile.expr_call(new Expression(info), baseConstructorTarget); } return; } ITypeSymbol initializerType; var symbolInfo = Context.GetSymbolInfo(initializer); switch (initializer.Kind()) { case SyntaxKind.BaseConstructorInitializer: initializerType = Symbol.ContainingType.BaseType !; break; case SyntaxKind.ThisConstructorInitializer: initializerType = Symbol.ContainingType; break; default: Context.ModelError(initializer, "Unknown initializer"); return; } var initInfo = new ExpressionInfo(Context, AnnotatedTypeSymbol.CreateNotAnnotated(initializerType), Context.CreateLocation(initializer.ThisOrBaseKeyword.GetLocation()), Kinds.ExprKind.CONSTRUCTOR_INIT, this, -1, false, null); var init = new Expression(initInfo); var target = Constructor.Create(Context, (IMethodSymbol?)symbolInfo.Symbol); if (target is null) { Context.ModelError(Symbol, "Unable to resolve call"); return; } trapFile.expr_call(init, target); var child = 0; foreach (var arg in initializer.ArgumentList.Arguments) { Expression.Create(Context, arg.Expression, init, child++); } }
public static This CreateImplicit(Context cx, ITypeSymbol @class, Extraction.Entities.Location loc, IExpressionParentEntity parent, int child) => new This(new ExpressionInfo(cx, AnnotatedTypeSymbol.CreateNotAnnotated(@class), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, true, null));