|
| 1 | +using System.IO; |
| 2 | +using System.Linq; |
| 3 | +using Microsoft.CodeAnalysis; |
| 4 | +using Microsoft.CodeAnalysis.CSharp; |
| 5 | +using Microsoft.CodeAnalysis.CSharp.Syntax; |
| 6 | +using Semmle.Extraction.Kinds; |
| 7 | + |
| 8 | +namespace Semmle.Extraction.CSharp.Entities.Expressions |
| 9 | +{ |
| 10 | + internal abstract class BaseObjectCreation<TExpressionSyntax> : Expression<TExpressionSyntax> |
| 11 | + where TExpressionSyntax : BaseObjectCreationExpressionSyntax |
| 12 | + { |
| 13 | + protected BaseObjectCreation(ExpressionNodeInfo info) |
| 14 | + : base(info.SetKind(GetKind(info.Context, (BaseObjectCreationExpressionSyntax)info.Node))) |
| 15 | + { |
| 16 | + } |
| 17 | + |
| 18 | + protected override void PopulateExpression(TextWriter trapFile) |
| 19 | + { |
| 20 | + if (Syntax.ArgumentList != null) |
| 21 | + { |
| 22 | + PopulateArguments(trapFile, Syntax.ArgumentList, 0); |
| 23 | + } |
| 24 | + |
| 25 | + var target = cx.GetModel(Syntax).GetSymbolInfo(Syntax); |
| 26 | + if (target.Symbol is IMethodSymbol method) |
| 27 | + { |
| 28 | + trapFile.expr_call(this, Method.Create(cx, method)); |
| 29 | + } |
| 30 | + |
| 31 | + if (IsDynamicObjectCreation(cx, Syntax)) |
| 32 | + { |
| 33 | + if (cx.GetModel(Syntax).GetTypeInfo(Syntax).Type is INamedTypeSymbol type && |
| 34 | + !string.IsNullOrEmpty(type.Name)) |
| 35 | + { |
| 36 | + trapFile.dynamic_member_name(this, type.Name); |
| 37 | + } |
| 38 | + else |
| 39 | + { |
| 40 | + cx.ModelError(Syntax, "Unable to get name for dynamic object creation."); |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + if (Syntax.Initializer != null) |
| 45 | + { |
| 46 | + switch (Syntax.Initializer.Kind()) |
| 47 | + { |
| 48 | + case SyntaxKind.CollectionInitializerExpression: |
| 49 | + CollectionInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1) { Type = Type }); |
| 50 | + break; |
| 51 | + case SyntaxKind.ObjectInitializerExpression: |
| 52 | + ObjectInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1) { Type = Type }); |
| 53 | + break; |
| 54 | + default: |
| 55 | + cx.ModelError("Unhandled initializer in object creation"); |
| 56 | + break; |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + private static ExprKind GetKind(Context cx, BaseObjectCreationExpressionSyntax node) |
| 62 | + { |
| 63 | + var type = cx.GetModel(node).GetTypeInfo(node).Type; |
| 64 | + return Entities.Type.IsDelegate(type as INamedTypeSymbol) |
| 65 | + ? ExprKind.EXPLICIT_DELEGATE_CREATION |
| 66 | + : ExprKind.OBJECT_CREATION; |
| 67 | + } |
| 68 | + |
| 69 | + private static bool IsDynamicObjectCreation(Context cx, BaseObjectCreationExpressionSyntax node) |
| 70 | + { |
| 71 | + return node.ArgumentList != null && |
| 72 | + node.ArgumentList.Arguments.Any(arg => IsDynamic(cx, arg.Expression)); |
| 73 | + } |
| 74 | + } |
| 75 | +} |
0 commit comments