Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cdea3af

Browse files
committed
C#: Change extraction of Attributes to have ID based on the location when location is from source
1 parent c04d6f4 commit cdea3af

2 files changed

Lines changed: 65 additions & 25 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using System.IO;
32
using System.Linq;
43
using Microsoft.CodeAnalysis;
@@ -8,39 +7,62 @@
87

98
namespace Semmle.Extraction.CSharp.Entities
109
{
11-
internal class Attribute : FreshEntity, IExpressionParentEntity
10+
internal class Attribute : CachedEntity<(AttributeData, IEntity)>, IExpressionParentEntity
1211
{
1312
bool IExpressionParentEntity.IsTopLevelParent => true;
1413

1514
private readonly AttributeData attributeData;
1615
private readonly AttributeSyntax attributeSyntax;
1716
private readonly IEntity entity;
1817

19-
public Attribute(Context cx, AttributeData attributeData, IEntity entity)
20-
: base(cx)
18+
private Attribute(Context cx, AttributeData attributeData, IEntity entity)
19+
: base(cx, (attributeData, entity))
2120
{
2221
this.attributeData = attributeData;
2322
this.attributeSyntax = attributeData.ApplicationSyntaxReference?.GetSyntax() as AttributeSyntax;
2423
this.entity = entity;
24+
}
25+
26+
public override void WriteId(TextWriter trapFile)
27+
{
28+
if (ReportingLocation?.IsInSource == true)
29+
{
30+
trapFile.WriteSubId(Context.Create(ReportingLocation));
31+
trapFile.Write(";attribute");
32+
}
33+
else
34+
{
35+
trapFile.Write('*');
36+
}
37+
}
2538

26-
TryPopulate();
39+
public override void WriteQuotedId(TextWriter trapFile)
40+
{
41+
if (ReportingLocation?.IsInSource == true)
42+
{
43+
base.WriteQuotedId(trapFile);
44+
}
45+
else
46+
{
47+
trapFile.Write('*');
48+
}
2749
}
2850

29-
protected override void Populate(TextWriter trapFile)
51+
public override void Populate(TextWriter trapFile)
3052
{
31-
var type = Type.Create(cx, attributeData.AttributeClass);
53+
var type = Type.Create(Context, attributeData.AttributeClass);
3254
trapFile.attributes(this, type.TypeRef, entity);
3355

3456
if (attributeSyntax is object)
3557
{
36-
trapFile.attribute_location(this, cx.Create(attributeSyntax.Name.GetLocation()));
58+
trapFile.attribute_location(this, Context.Create(attributeSyntax.Name.GetLocation()));
3759

38-
if (cx.Extractor.OutputPath != null)
60+
if (Context.Extractor.OutputPath != null)
3961
{
40-
trapFile.attribute_location(this, Assembly.CreateOutputAssembly(cx));
62+
trapFile.attribute_location(this, Assembly.CreateOutputAssembly(Context));
4163
}
4264

43-
TypeMention.Create(cx, attributeSyntax.Name, this, type);
65+
TypeMention.Create(Context, attributeSyntax.Name, this, type);
4466
}
4567

4668
ExtractArguments(trapFile);
@@ -80,7 +102,7 @@ private Expression CreateExpressionFromArgument(TypedConstant constant, Expressi
80102
{
81103
if (syntax is object)
82104
{
83-
return Expression.Create(cx, syntax, parent, childIndex);
105+
return Expression.Create(Context, syntax, parent, childIndex);
84106
}
85107

86108
return CreateGeneratedExpressionFromArgument(constant, parent, childIndex);
@@ -91,25 +113,25 @@ private Expression CreateGeneratedExpressionFromArgument(TypedConstant constant,
91113
{
92114
if (constant.IsNull)
93115
{
94-
return Literal.CreateGeneratedNullLiteral(cx, parent, childIndex);
116+
return Literal.CreateGeneratedNullLiteral(Context, parent, childIndex);
95117
}
96118

97119
switch (constant.Kind)
98120
{
99121
case TypedConstantKind.Primitive:
100-
return Literal.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Value);
122+
return Literal.CreateGenerated(Context, parent, childIndex, constant.Type, constant.Value);
101123
case TypedConstantKind.Enum:
102124
// Enum value is generated in the following format: (Enum)value
103125

104-
var cast = Cast.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Value);
105-
Literal.CreateGenerated(cx, cast, Cast.ExpressionIndex, ((INamedTypeSymbol)constant.Type).EnumUnderlyingType, constant.Value);
106-
TypeAccess.CreateGenerated(cx, cast, Cast.TypeAccessIndex, constant.Type);
126+
var cast = Cast.CreateGenerated(Context, parent, childIndex, constant.Type, constant.Value);
127+
Literal.CreateGenerated(Context, cast, Cast.ExpressionIndex, ((INamedTypeSymbol)constant.Type).EnumUnderlyingType, constant.Value);
128+
TypeAccess.CreateGenerated(Context, cast, Cast.TypeAccessIndex, constant.Type);
107129

108130
return cast;
109131
case TypedConstantKind.Type:
110132
var type = ((ITypeSymbol)constant.Value).OriginalDefinition;
111-
var t = TypeOf.CreateGenerated(cx, parent, childIndex, type);
112-
TypeAccess.CreateGenerated(cx, t, TypeOf.TypeAccessIndex, type);
133+
var t = TypeOf.CreateGenerated(Context, parent, childIndex, type);
134+
TypeAccess.CreateGenerated(Context, t, TypeOf.TypeAccessIndex, type);
113135
return t;
114136
case TypedConstantKind.Array:
115137
{
@@ -119,11 +141,11 @@ private Expression CreateGeneratedExpressionFromArgument(TypedConstant constant,
119141
//
120142
// itemI is generated recursively.
121143

122-
var arrayCreation = NormalArrayCreation.CreateGenerated(cx, parent, childIndex, constant.Type, constant.Values.Length);
144+
var arrayCreation = NormalArrayCreation.CreateGenerated(Context, parent, childIndex, constant.Type, constant.Values.Length);
123145

124146
if (constant.Values.Length > 0)
125147
{
126-
var arrayInit = ArrayInitializer.CreateGenerated(cx, arrayCreation);
148+
var arrayInit = ArrayInitializer.CreateGenerated(Context, arrayCreation);
127149

128150
constant.Values
129151
.Select((constantItem, itemIndex) => CreateGeneratedExpressionFromArgument(constantItem, arrayInit, itemIndex))
@@ -134,19 +156,37 @@ private Expression CreateGeneratedExpressionFromArgument(TypedConstant constant,
134156
return arrayCreation;
135157
}
136158
default:
137-
cx.ExtractionError("Couldn't extract constant in attribute", entity.ToString(), cx.Create(entity.ReportingLocation));
159+
Context.ExtractionError("Couldn't extract constant in attribute", entity.ToString(), Context.Create(entity.ReportingLocation));
138160
return null;
139161
}
140162
}
141163

164+
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel;
165+
166+
public override Microsoft.CodeAnalysis.Location ReportingLocation => attributeSyntax?.Name.GetLocation();
167+
168+
public override bool NeedsPopulation => true;
169+
142170
public static void ExtractAttributes(Context cx, ISymbol symbol, IEntity entity)
143171
{
144172
foreach (var attribute in symbol.GetAttributes())
145173
{
146-
new Attribute(cx, attribute, entity);
174+
Create(cx, attribute, entity);
147175
}
148176
}
149177

150-
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel;
178+
public static Attribute Create(Context cx, AttributeData attributeData, IEntity entity)
179+
{
180+
var init = (attributeData, entity);
181+
return AttributeFactory.Instance.CreateEntity(cx, init, init);
182+
}
183+
184+
private class AttributeFactory : ICachedEntityFactory<(AttributeData attributeData, IEntity receiver), Attribute>
185+
{
186+
public static readonly AttributeFactory Instance = new AttributeFactory();
187+
188+
public Attribute Create(Context cx, (AttributeData attributeData, IEntity receiver) init) =>
189+
new Attribute(cx, init.attributeData, init.receiver);
190+
}
151191
}
152192
}

csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnit.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public override void VisitAttributeList(AttributeListSyntax node)
6565
var attributeData = attributeDatas.Single(ad => ad.ApplicationSyntaxReference?.GetSyntax() == attribute);
6666
if (attributeData is object)
6767
{
68-
var ae = new Attribute(cx, attributeData, outputAssembly);
68+
var ae = Attribute.Create(cx, attributeData, outputAssembly);
6969
cx.BindComments(ae, attribute.GetLocation());
7070
}
7171
}

0 commit comments

Comments
 (0)