|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
1 | 3 | using System.IO;
|
2 | 4 | using System.Linq;
|
3 | 5 | using Microsoft.CodeAnalysis;
|
|
6 | 8 |
|
7 | 9 | namespace Semmle.Extraction.CSharp.Entities
|
8 | 10 | {
|
| 11 | + internal enum AttributeKind |
| 12 | + { |
| 13 | + Default = 0, |
| 14 | + Return = 1, |
| 15 | + Assembly = 2, |
| 16 | + Module = 3, |
| 17 | + } |
| 18 | + |
9 | 19 | internal class Attribute : CachedEntity<AttributeData>, IExpressionParentEntity
|
10 | 20 | {
|
11 | 21 | bool IExpressionParentEntity.IsTopLevelParent => true;
|
12 | 22 |
|
13 | 23 | private readonly AttributeSyntax? attributeSyntax;
|
14 | 24 | private readonly IEntity entity;
|
| 25 | + private readonly AttributeKind kind; |
15 | 26 |
|
16 |
| - private Attribute(Context cx, AttributeData attributeData, IEntity entity) |
| 27 | + private Attribute(Context cx, AttributeData attributeData, IEntity entity, AttributeKind kind) |
17 | 28 | : base(cx, attributeData)
|
18 | 29 | {
|
19 | 30 | this.attributeSyntax = attributeData.ApplicationSyntaxReference?.GetSyntax() as AttributeSyntax;
|
20 | 31 | this.entity = entity;
|
| 32 | + this.kind = kind; |
21 | 33 | }
|
22 | 34 |
|
23 | 35 | public override void WriteId(EscapingTextWriter trapFile)
|
@@ -48,7 +60,7 @@ public sealed override void WriteQuotedId(EscapingTextWriter trapFile)
|
48 | 60 | public override void Populate(TextWriter trapFile)
|
49 | 61 | {
|
50 | 62 | var type = Type.Create(Context, Symbol.AttributeClass);
|
51 |
| - trapFile.attributes(this, type.TypeRef, entity); |
| 63 | + trapFile.attributes(this, kind, type.TypeRef, entity); |
52 | 64 | trapFile.attribute_location(this, Location);
|
53 | 65 |
|
54 | 66 | if (attributeSyntax is not null)
|
@@ -125,26 +137,36 @@ private void ExtractArguments(TextWriter trapFile)
|
125 | 137 |
|
126 | 138 | public override bool NeedsPopulation => true;
|
127 | 139 |
|
| 140 | + private static void ExtractAttributes<T>(Context cx, T symbol, Func<T, IEnumerable<AttributeData>> getAttributes, IEntity entity, AttributeKind kind) where T : ISymbol |
| 141 | + { |
| 142 | + foreach (var attribute in getAttributes(symbol)) |
| 143 | + { |
| 144 | + Create(cx, attribute, entity, kind); |
| 145 | + } |
| 146 | + } |
| 147 | + |
128 | 148 | public static void ExtractAttributes(Context cx, ISymbol symbol, IEntity entity)
|
129 | 149 | {
|
130 |
| - foreach (var attribute in symbol.GetAttributes()) |
| 150 | + ExtractAttributes(cx, symbol, s => s.GetAttributes(), entity, AttributeKind.Default); |
| 151 | + if (symbol is IMethodSymbol method) |
131 | 152 | {
|
132 |
| - Create(cx, attribute, entity); |
| 153 | + ExtractAttributes(cx, method, s => s.GetReturnTypeAttributes(), entity, AttributeKind.Return); |
133 | 154 | }
|
134 | 155 | }
|
135 | 156 |
|
136 |
| - public static Attribute Create(Context cx, AttributeData attributeData, IEntity entity) |
| 157 | + |
| 158 | + public static Attribute Create(Context cx, AttributeData attributeData, IEntity entity, AttributeKind kind) |
137 | 159 | {
|
138 |
| - var init = (attributeData, entity); |
| 160 | + var init = (attributeData, entity, kind); |
139 | 161 | return AttributeFactory.Instance.CreateEntity(cx, attributeData, init);
|
140 | 162 | }
|
141 | 163 |
|
142 |
| - private class AttributeFactory : CachedEntityFactory<(AttributeData attributeData, IEntity receiver), Attribute> |
| 164 | + private class AttributeFactory : CachedEntityFactory<(AttributeData attributeData, IEntity receiver, AttributeKind kind), Attribute> |
143 | 165 | {
|
144 | 166 | public static readonly AttributeFactory Instance = new AttributeFactory();
|
145 | 167 |
|
146 |
| - public override Attribute Create(Context cx, (AttributeData attributeData, IEntity receiver) init) => |
147 |
| - new Attribute(cx, init.attributeData, init.receiver); |
| 168 | + public override Attribute Create(Context cx, (AttributeData attributeData, IEntity receiver, AttributeKind kind) init) => |
| 169 | + new Attribute(cx, init.attributeData, init.receiver, init.kind); |
148 | 170 | }
|
149 | 171 | }
|
150 | 172 | }
|
0 commit comments