Skip to content

Commit 1df1b0c

Browse files
committed
C#: Refactor ArrayCreations to allow stackalloc arrays to have initializers (C# 7.3).
1 parent a4b3b1e commit 1df1b0c

File tree

2 files changed

+36
-34
lines changed

2 files changed

+36
-34
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,55 +9,35 @@ abstract class ArrayCreation<SyntaxNode> : Expression<SyntaxNode> where SyntaxNo
99
protected ArrayCreation(ExpressionNodeInfo info) : base(info) { }
1010
}
1111

12-
class StackAllocArrayCreation : ArrayCreation<StackAllocArrayCreationExpressionSyntax>
12+
abstract class ExplicitArrayCreation<T> : ArrayCreation<T> where T:ExpressionSyntax
1313
{
14-
StackAllocArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
14+
protected ExplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
1515

16-
public static Expression Create(ExpressionNodeInfo info) => new StackAllocArrayCreation(info).TryPopulate();
16+
public abstract ArrayTypeSyntax TypeSyntax { get; }
17+
18+
public abstract InitializerExpressionSyntax Initializer { get; }
1719

1820
protected override void Populate()
1921
{
20-
var arrayType = Syntax.Type as ArrayTypeSyntax;
21-
22-
if (arrayType == null)
23-
{
24-
cx.ModelError(Syntax, "Unexpected array type");
25-
return;
26-
}
27-
2822
var child = 0;
23+
bool explicitlySized = false;
2924

30-
foreach (var rank in arrayType.RankSpecifiers.SelectMany(rs => rs.Sizes))
25+
if(TypeSyntax is null)
3126
{
32-
Create(cx, rank, this, child++);
27+
cx.ModelError(Syntax, "Array has unexpected type syntax");
3328
}
3429

35-
cx.Emit(Tuples.explicitly_sized_array_creation(this));
36-
}
37-
}
38-
39-
class ExplicitArrayCreation : ArrayCreation<ArrayCreationExpressionSyntax>
40-
{
41-
ExplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
42-
43-
public static Expression Create(ExpressionNodeInfo info) => new ExplicitArrayCreation(info).TryPopulate();
44-
45-
protected override void Populate()
46-
{
47-
var child = 0;
48-
bool explicitlySized = false;
49-
50-
foreach (var rank in Syntax.Type.RankSpecifiers.SelectMany(rs => rs.Sizes))
30+
foreach (var rank in TypeSyntax.RankSpecifiers.SelectMany(rs => rs.Sizes))
5131
{
5232
if (rank is OmittedArraySizeExpressionSyntax)
5333
{
5434
// Create an expression which simulates the explicit size of the array
5535

56-
if (Syntax.Initializer != null)
36+
if (Initializer != null)
5737
{
5838
// An implicitly-sized array must have an initializer.
5939
// Guard it just in case.
60-
var size = Syntax.Initializer.Expressions.Count;
40+
var size = Initializer.Expressions.Count;
6141

6242
var info = new ExpressionInfo(
6343
cx,
@@ -79,16 +59,38 @@ protected override void Populate()
7959
}
8060
child++;
8161
}
82-
if (Syntax.Initializer != null)
62+
if (Initializer != null)
8363
{
84-
ArrayInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1));
64+
ArrayInitializer.Create(new ExpressionNodeInfo(cx, Initializer, this, -1));
8565
}
8666

8767
if (explicitlySized)
8868
cx.Emit(Tuples.explicitly_sized_array_creation(this));
8969
}
9070
}
9171

72+
class NormalArrayCreation : ExplicitArrayCreation<ArrayCreationExpressionSyntax>
73+
{
74+
private NormalArrayCreation(ExpressionNodeInfo info) : base(info) { }
75+
76+
public override ArrayTypeSyntax TypeSyntax => Syntax.Type;
77+
78+
public override InitializerExpressionSyntax Initializer => Syntax.Initializer;
79+
80+
public static Expression Create(ExpressionNodeInfo info) => new NormalArrayCreation(info).TryPopulate();
81+
}
82+
83+
class StackAllocArrayCreation : ExplicitArrayCreation<StackAllocArrayCreationExpressionSyntax>
84+
{
85+
StackAllocArrayCreation(ExpressionNodeInfo info) : base(info) { }
86+
87+
public override ArrayTypeSyntax TypeSyntax => Syntax.Type as ArrayTypeSyntax;
88+
89+
public override InitializerExpressionSyntax Initializer => Syntax.Initializer;
90+
91+
public static Expression Create(ExpressionNodeInfo info) => new StackAllocArrayCreation(info).TryPopulate();
92+
}
93+
9294
class ImplicitArrayCreation : ArrayCreation<ImplicitArrayCreationExpressionSyntax>
9395
{
9496
ImplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ internal static Expression Create(ExpressionNodeInfo info)
8686
return ExplicitObjectCreation.Create(info);
8787

8888
case SyntaxKind.ArrayCreationExpression:
89-
return ExplicitArrayCreation.Create(info);
89+
return NormalArrayCreation.Create(info);
9090

9191
case SyntaxKind.ObjectInitializerExpression:
9292
return ObjectInitializer.Create(info);

0 commit comments

Comments
 (0)