Skip to content

Commit df28544

Browse files
committed
C#: Separate all classes to dedicated files in CIL extractor
1 parent df29a16 commit df28544

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2474
-2256
lines changed

csharp/extractor/Semmle.Extraction.CIL/Context.cs

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
43
using System.Linq;
54
using System.Reflection.Metadata;
@@ -116,69 +115,4 @@ public Entities.Type ErrorType
116115
return Pdb?.GetMethod(handle.ToDebugInformationHandle());
117116
}
118117
}
119-
120-
/// <summary>
121-
/// When we decode a type/method signature, we need access to
122-
/// generic parameters.
123-
/// </summary>
124-
public abstract class GenericContext
125-
{
126-
public Context Cx { get; }
127-
128-
protected GenericContext(Context cx)
129-
{
130-
this.Cx = cx;
131-
}
132-
133-
/// <summary>
134-
/// The list of generic type parameters, including type parameters of
135-
/// containing types.
136-
/// </summary>
137-
public abstract IEnumerable<Entities.Type> TypeParameters { get; }
138-
139-
/// <summary>
140-
/// The list of generic method parameters.
141-
/// </summary>
142-
public abstract IEnumerable<Entities.Type> MethodParameters { get; }
143-
144-
/// <summary>
145-
/// Gets the `p`th type parameter.
146-
/// </summary>
147-
/// <param name="p">The index of the parameter.</param>
148-
/// <returns>
149-
/// For constructed types, the supplied type.
150-
/// For unbound types, the type parameter.
151-
/// </returns>
152-
public Entities.Type GetGenericTypeParameter(int p)
153-
{
154-
return TypeParameters.ElementAt(p);
155-
}
156-
157-
/// <summary>
158-
/// Gets the `p`th method type parameter.
159-
/// </summary>
160-
/// <param name="p">The index of the parameter.</param>
161-
/// <returns>
162-
/// For constructed types, the supplied type.
163-
/// For unbound types, the type parameter.
164-
/// </returns>
165-
public Entities.Type GetGenericMethodParameter(int p)
166-
{
167-
return MethodParameters.ElementAt(p);
168-
}
169-
}
170-
171-
/// <summary>
172-
/// A generic context which does not contain any type parameters.
173-
/// </summary>
174-
public class EmptyContext : GenericContext
175-
{
176-
public EmptyContext(Context cx) : base(cx)
177-
{
178-
}
179-
180-
public override IEnumerable<Entities.Type> TypeParameters { get { yield break; } }
181-
182-
public override IEnumerable<Entities.Type> MethodParameters { get { yield break; } }
183-
}
184118
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Collections.Generic;
2+
3+
namespace Semmle.Extraction.CIL
4+
{
5+
/// <summary>
6+
/// A generic context which does not contain any type parameters.
7+
/// </summary>
8+
public class EmptyContext : GenericContext
9+
{
10+
public EmptyContext(Context cx) : base(cx)
11+
{
12+
}
13+
14+
public override IEnumerable<Entities.Type> TypeParameters { get { yield break; } }
15+
16+
public override IEnumerable<Entities.Type> MethodParameters { get { yield break; } }
17+
}
18+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
5+
namespace Semmle.Extraction.CIL.Entities
6+
{
7+
/// <summary>
8+
/// An array type.
9+
/// </summary>
10+
internal sealed class ArrayType : Type, IArrayType
11+
{
12+
private readonly Type elementType;
13+
private readonly int rank;
14+
15+
public ArrayType(Context cx, Type elementType, int rank) : base(cx)
16+
{
17+
this.rank = rank;
18+
this.elementType = elementType;
19+
}
20+
21+
public ArrayType(Context cx, Type elementType) : this(cx, elementType, 1)
22+
{
23+
}
24+
25+
public override bool Equals(object? obj)
26+
{
27+
return obj is ArrayType array && elementType.Equals(array.elementType) && rank == array.rank;
28+
}
29+
30+
public override int GetHashCode()
31+
{
32+
return elementType.GetHashCode() * 5 + rank;
33+
}
34+
35+
public override void WriteId(TextWriter trapFile, bool inContext)
36+
{
37+
elementType.GetId(trapFile, inContext);
38+
trapFile.Write('[');
39+
for (var i = 1; i < rank; ++i)
40+
trapFile.Write(',');
41+
trapFile.Write(']');
42+
}
43+
44+
public override string Name => elementType.Name + "[]";
45+
46+
public override Namespace Namespace => Cx.SystemNamespace;
47+
48+
public override Type? ContainingType => null;
49+
50+
public override int ThisTypeParameters => elementType.ThisTypeParameters;
51+
52+
public override CilTypeKind Kind => CilTypeKind.Array;
53+
54+
public override Type Construct(IEnumerable<Type> typeArguments) => Cx.Populate(new ArrayType(Cx, elementType.Construct(typeArguments)));
55+
56+
public override Type SourceDeclaration => Cx.Populate(new ArrayType(Cx, elementType.SourceDeclaration));
57+
58+
public override IEnumerable<IExtractionProduct> Contents
59+
{
60+
get
61+
{
62+
foreach (var c in base.Contents)
63+
yield return c;
64+
65+
yield return Tuples.cil_array_type(this, elementType, rank);
66+
}
67+
}
68+
69+
public override void WriteAssemblyPrefix(TextWriter trapFile) => elementType.WriteAssemblyPrefix(trapFile);
70+
71+
public override IEnumerable<Type> GenericArguments => elementType.GenericArguments;
72+
73+
public override IEnumerable<Type> TypeParameters => elementType.TypeParameters;
74+
75+
public override IEnumerable<Type> MethodParameters => throw new NotImplementedException();
76+
}
77+
}

csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@
99

1010
namespace Semmle.Extraction.CIL.Entities
1111
{
12-
public interface ILocation : IEntity
13-
{
14-
}
15-
16-
internal interface IAssembly : ILocation
17-
{
18-
}
19-
2012
/// <summary>
2113
/// An assembly to extract.
2214
/// </summary>

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

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44

55
namespace Semmle.Extraction.CIL.Entities
66
{
7-
/// <summary>
8-
/// A CIL attribute.
9-
/// </summary>
10-
internal interface IAttribute : IExtractedEntity
11-
{
12-
}
13-
147
/// <summary>
158
/// Entity representing a CIL attribute.
169
/// </summary>
@@ -79,33 +72,4 @@ public static IEnumerable<IExtractionProduct> Populate(Context cx, IEntity @obje
7972
}
8073
}
8174
}
82-
83-
/// <summary>
84-
/// Helper class to decode the attribute structure.
85-
/// Note that there are some unhandled cases that should be fixed in due course.
86-
/// </summary>
87-
internal class CustomAttributeDecoder : ICustomAttributeTypeProvider<Type>
88-
{
89-
private readonly Context cx;
90-
public CustomAttributeDecoder(Context cx) { this.cx = cx; }
91-
92-
public Type GetPrimitiveType(PrimitiveTypeCode typeCode) => cx.Create(typeCode);
93-
94-
public Type GetSystemType() => throw new NotImplementedException();
95-
96-
public Type GetSZArrayType(Type elementType) =>
97-
cx.Populate(new ArrayType(cx, elementType));
98-
99-
public Type GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) =>
100-
(Type)cx.Create(handle);
101-
102-
public Type GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) =>
103-
(Type)cx.Create(handle);
104-
105-
public Type GetTypeFromSerializedName(string name) => throw new NotImplementedException();
106-
107-
public PrimitiveTypeCode GetUnderlyingEnumType(Type type) => throw new NotImplementedException();
108-
109-
public bool IsSystemType(Type type) => type is PrimitiveType; // ??
110-
}
11175
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Semmle.Extraction.CIL.Entities
2+
{
3+
/// <summary>
4+
/// The CIL database type-kind.
5+
/// </summary>
6+
public enum CilTypeKind
7+
{
8+
ValueOrRefType,
9+
TypeParameter,
10+
Array,
11+
Pointer
12+
}
13+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using System;
2+
using Microsoft.CodeAnalysis;
3+
using System.Linq;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using Semmle.Util;
7+
8+
namespace Semmle.Extraction.CIL.Entities
9+
{
10+
/// <summary>
11+
/// A constructed type.
12+
/// </summary>
13+
public sealed class ConstructedType : Type
14+
{
15+
private readonly Type unboundGenericType;
16+
17+
// Either null or notEmpty
18+
private readonly Type[]? thisTypeArguments;
19+
20+
public override IEnumerable<Type> ThisTypeArguments => thisTypeArguments.EnumerateNull();
21+
22+
public override IEnumerable<Type> ThisGenericArguments => thisTypeArguments.EnumerateNull();
23+
24+
public override IEnumerable<IExtractionProduct> Contents
25+
{
26+
get
27+
{
28+
foreach (var c in base.Contents)
29+
yield return c;
30+
31+
var i = 0;
32+
foreach (var type in ThisGenericArguments)
33+
{
34+
yield return type;
35+
yield return Tuples.cil_type_argument(this, i++, type);
36+
}
37+
}
38+
}
39+
40+
public override Type SourceDeclaration => unboundGenericType;
41+
42+
public ConstructedType(Context cx, Type unboundType, IEnumerable<Type> typeArguments) : base(cx)
43+
{
44+
var suppliedArgs = typeArguments.Count();
45+
if (suppliedArgs != unboundType.TotalTypeParametersCheck)
46+
throw new InternalError("Unexpected number of type arguments in ConstructedType");
47+
48+
unboundGenericType = unboundType;
49+
var thisParams = unboundType.ThisTypeParameters;
50+
51+
if (typeArguments.Count() == thisParams)
52+
{
53+
containingType = unboundType.ContainingType;
54+
thisTypeArguments = typeArguments.ToArray();
55+
}
56+
else if (thisParams == 0)
57+
{
58+
// all type arguments belong to containing type
59+
containingType = unboundType.ContainingType!.Construct(typeArguments);
60+
}
61+
else
62+
{
63+
// some type arguments belong to containing type
64+
var parentParams = suppliedArgs - thisParams;
65+
containingType = unboundType.ContainingType!.Construct(typeArguments.Take(parentParams));
66+
thisTypeArguments = typeArguments.Skip(parentParams).ToArray();
67+
}
68+
}
69+
70+
public override bool Equals(object? obj)
71+
{
72+
if (obj is ConstructedType t && Equals(unboundGenericType, t.unboundGenericType) && Equals(containingType, t.containingType))
73+
{
74+
if (thisTypeArguments is null)
75+
return t.thisTypeArguments is null;
76+
if (!(t.thisTypeArguments is null))
77+
return thisTypeArguments.SequenceEqual(t.thisTypeArguments);
78+
}
79+
return false;
80+
}
81+
82+
public override int GetHashCode()
83+
{
84+
var h = unboundGenericType.GetHashCode();
85+
h = 13 * h + (containingType is null ? 0 : containingType.GetHashCode());
86+
if (!(thisTypeArguments is null))
87+
h = h * 13 + thisTypeArguments.SequenceHash();
88+
return h;
89+
}
90+
91+
private readonly Type? containingType;
92+
public override Type? ContainingType => containingType;
93+
94+
public override string Name => unboundGenericType.Name;
95+
96+
public override Namespace Namespace => unboundGenericType.Namespace!;
97+
98+
public override int ThisTypeParameters => thisTypeArguments == null ? 0 : thisTypeArguments.Length;
99+
100+
public override CilTypeKind Kind => unboundGenericType.Kind;
101+
102+
public override Type Construct(IEnumerable<Type> typeArguments)
103+
{
104+
throw new NotImplementedException();
105+
}
106+
107+
public override void WriteId(TextWriter trapFile, bool inContext)
108+
{
109+
if (ContainingType != null)
110+
{
111+
ContainingType.GetId(trapFile, inContext);
112+
trapFile.Write('.');
113+
}
114+
else
115+
{
116+
WriteAssemblyPrefix(trapFile);
117+
118+
if (!Namespace.IsGlobalNamespace)
119+
{
120+
Namespace.WriteId(trapFile);
121+
trapFile.Write('.');
122+
}
123+
}
124+
trapFile.Write(unboundGenericType.Name);
125+
126+
if (thisTypeArguments != null && thisTypeArguments.Any())
127+
{
128+
trapFile.Write('<');
129+
var index = 0;
130+
foreach (var t in thisTypeArguments)
131+
{
132+
trapFile.WriteSeparator(",", ref index);
133+
t.WriteId(trapFile);
134+
}
135+
trapFile.Write('>');
136+
}
137+
}
138+
139+
public override void WriteAssemblyPrefix(TextWriter trapFile) => unboundGenericType.WriteAssemblyPrefix(trapFile);
140+
141+
public override IEnumerable<Type> TypeParameters => GenericArguments;
142+
143+
public override IEnumerable<Type> MethodParameters => throw new NotImplementedException();
144+
}
145+
}

0 commit comments

Comments
 (0)