Skip to content

Commit dcd06a2

Browse files
authored
Fix constructor of generic parameters table (#185)
***NO_CI***
1 parent a6c862b commit dcd06a2

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

MetadataProcessor.Shared/Tables/nanoGenericParamTable.cs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public nanoGenericParamTable(
7676
{
7777
foreach (var gp in items)
7878
{
79-
var methodWithGenericParam = _context.MethodDefinitionTable.Items.SingleOrDefault(m => m.GenericParameters.Contains(gp));
79+
MethodDefinition methodWithGenericParam = _context.MethodDefinitionTable.Items.SingleOrDefault(m => m.GenericParameters.Contains(gp));
8080

8181
if (methodWithGenericParam != null)
8282
{
@@ -85,27 +85,63 @@ public nanoGenericParamTable(
8585
mr => mr.DeclaringType.GetElementType() == methodWithGenericParam.DeclaringType &&
8686
mr.Name == methodWithGenericParam.Name) as GenericInstanceMethod;
8787

88-
Debug.Assert(instanceMethod != null, $"Couldn't find a method specification for type {methodWithGenericParam.DeclaringType} when processing generic parameter {gp}.");
88+
Debug.Assert(
89+
instanceMethod != null,
90+
$"Couldn't find a method specification for type {methodWithGenericParam.DeclaringType} when processing generic parameter {gp}.");
8991

90-
_typeForGenericParam.Add(gp, instanceMethod.GenericArguments.ElementAt(gp.Position));
92+
_typeForGenericParam.Add(
93+
gp,
94+
instanceMethod.GenericArguments.ElementAt(gp.Position));
9195
}
9296
else
9397
{
94-
var typeWithGenericParam = _context.TypeDefinitionTable.Items.SingleOrDefault(t => t.GenericParameters.Contains(gp));
98+
TypeDefinition typeWithGenericParam = _context.TypeDefinitionTable.Items.SingleOrDefault(t => t.GenericParameters.Contains(gp));
9599

96100
if (typeWithGenericParam != null)
97101
{
98102
if (_context.MethodReferencesTable.Items.Any())
99103
{
100-
var genericInstance = _context.MethodReferencesTable.Items.FirstOrDefault(
101-
mr => mr.DeclaringType.GetElementType() == typeWithGenericParam)
102-
.DeclaringType as GenericInstanceType;
103-
Debug.Assert(genericInstance != null, $"Couldn't find a method reference for type {typeWithGenericParam} when processing generic parameter {gp}.");
104-
105-
_typeForGenericParam.Add(gp, genericInstance.GenericArguments.ElementAt(gp.Position));
104+
// try to find an existing GenericInstanceType in the TypeReferencesTable
105+
GenericInstanceType genericInstance = _context.TypeReferencesTable.Items
106+
.OfType<GenericInstanceType>()
107+
.FirstOrDefault(gt => gt.ElementType == typeWithGenericParam);
108+
109+
// fallback to whatever TryGetTypeSpecification gives us
110+
if (genericInstance == null)
111+
{
112+
TypeReference spec = _context.TypeSpecificationsTable.TryGetTypeSpecification(typeWithGenericParam.MetadataToken);
113+
114+
// If it really is an instance, grab its args...
115+
if (spec is GenericInstanceType genericInstanceType)
116+
{
117+
genericInstance = genericInstanceType;
118+
}
119+
else
120+
{
121+
// ... otherwise it's just an open generic definition (unbound T),
122+
// so our "argument" for gp is gp itself:
123+
_typeForGenericParam.Add(gp, gp);
124+
125+
// done here
126+
continue;
127+
}
128+
}
129+
130+
// at this point we know we've got a GenericInstanceType,
131+
// so pull out the actual generic‐argument at position gp.Position:
132+
Debug.Assert(
133+
genericInstance != null,
134+
$"Couldn't find a generic instance for type {typeWithGenericParam} when processing generic parameter {gp}."
135+
);
136+
137+
_typeForGenericParam.Add(
138+
gp,
139+
genericInstance.GenericArguments.ElementAt(gp.Position)
140+
);
106141
}
107142
else
108143
{
144+
// No methods in scope → no instantiation possible
109145
_typeForGenericParam.Add(gp, null);
110146
}
111147
}

MetadataProcessor.Shared/Tables/nanoTablesContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ public nanoTablesContext(
192192

193193
MethodSpecificationTable = new nanoMethodSpecificationTable(methodSpecifications, this);
194194

195+
TypeSpecificationsTable = new nanoTypeSpecificationsTable(this);
196+
195197
// build list of generic parameters belonging to method defs
196198
List<GenericParameter> methodDefsGenericParameters = new List<GenericParameter>();
197199

@@ -204,8 +206,6 @@ public nanoTablesContext(
204206

205207
GenericParamsTable = new nanoGenericParamTable(generics, this);
206208

207-
TypeSpecificationsTable = new nanoTypeSpecificationsTable(this);
208-
209209
// Pre-allocate strings from some tables
210210
AssemblyReferenceTable.AllocateStrings();
211211
TypeReferencesTable.AllocateStrings();

0 commit comments

Comments
 (0)