Skip to content

Commit 39ffd56

Browse files
tlakolloMichalStrehovsky
authored andcommitted
Add support for GenericParameter and GenericParameterConstraint (#30)
1 parent 5426ac8 commit 39ffd56

5 files changed

Lines changed: 138 additions & 2 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Mono.Linker.Tests.Cases.Expectations.Assertions;
2+
3+
namespace Mono.Linker.Tests.Cases.Basic
4+
{
5+
[Kept]
6+
class GenericParameters
7+
{
8+
[Kept]
9+
public static void Main()
10+
{
11+
// We will generate corrupted IL in the method body until we fix the signature parsing
12+
//var t = typeof(A<>).ToString();
13+
}
14+
/*
15+
[Kept]
16+
class A<T>
17+
{
18+
}
19+
*/
20+
}
21+
}

src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/NodeFactory.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ public TokenBasedNode GetNodeForToken(EcmaModule module, EntityHandle handle)
6363
case HandleKind.ManifestResource:
6464
throw new NotImplementedException();
6565
case HandleKind.GenericParameter:
66-
throw new NotImplementedException();
66+
return GenericParameter(module, (GenericParameterHandle)handle);
6767
case HandleKind.MethodSpecification:
6868
return MethodSpecification(module, (MethodSpecificationHandle)handle);
6969
case HandleKind.GenericParameterConstraint:
70-
throw new NotImplementedException();
70+
return GenericParameterConstraint(module, (GenericParameterConstraintHandle)handle);
7171
default:
7272
throw new NotImplementedException();
7373
}
@@ -193,6 +193,22 @@ public AssemblyReferenceNode AssemblyReference(EcmaModule module, AssemblyRefere
193193
return _assemblyReferences.GetOrAdd(new HandleKey<AssemblyReferenceHandle>(module, handle));
194194
}
195195

196+
NodeCache<HandleKey<GenericParameterHandle>, GenericParameterNode> _genericParameters
197+
= new NodeCache<HandleKey<GenericParameterHandle>, GenericParameterNode>(key
198+
=> new GenericParameterNode(key.Module, key.Handle));
199+
public GenericParameterNode GenericParameter(EcmaModule module, GenericParameterHandle handle)
200+
{
201+
return _genericParameters.GetOrAdd(new HandleKey<GenericParameterHandle>(module, handle));
202+
}
203+
204+
NodeCache<HandleKey<GenericParameterConstraintHandle>, GenericParameterConstraintNode> _genericParameterConstraints
205+
= new NodeCache<HandleKey<GenericParameterConstraintHandle>, GenericParameterConstraintNode>(key
206+
=> new GenericParameterConstraintNode(key.Module, key.Handle));
207+
public GenericParameterConstraintNode GenericParameterConstraint(EcmaModule module, GenericParameterConstraintHandle handle)
208+
{
209+
return _genericParameterConstraints.GetOrAdd(new HandleKey<GenericParameterConstraintHandle>(module, handle));
210+
}
211+
196212
private struct HandleKey<T> : IEquatable<HandleKey<T>> where T : struct, IEquatable<T>
197213
{
198214
public readonly EcmaModule Module;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Reflection.Metadata;
6+
7+
namespace ILTrim.DependencyAnalysis
8+
{
9+
/// <summary>
10+
/// Represents an entry in the GenericParamConstraint metadata table.
11+
/// </summary>
12+
public sealed class GenericParameterConstraintNode : TokenBasedNode
13+
{
14+
public GenericParameterConstraintNode(EcmaModule module, GenericParameterConstraintHandle handle)
15+
: base(module, handle)
16+
{
17+
}
18+
19+
private GenericParameterConstraintHandle Handle => (GenericParameterConstraintHandle)_handle;
20+
21+
public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
22+
{
23+
GenericParameterConstraint genericParamConstraint = _module.MetadataReader.GetGenericParameterConstraint(Handle);
24+
yield return new DependencyListEntry(factory.GetNodeForToken(_module, genericParamConstraint.Type), "Parameter constrained to type");
25+
}
26+
27+
protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
28+
{
29+
MetadataReader reader = _module.MetadataReader;
30+
GenericParameterConstraint genericParamConstraint = reader.GetGenericParameterConstraint(Handle);
31+
32+
var builder = writeContext.MetadataBuilder;
33+
34+
return builder.AddGenericParameterConstraint(
35+
(GenericParameterHandle)writeContext.TokenMap.MapToken(genericParamConstraint.Parameter),
36+
writeContext.TokenMap.MapToken(genericParamConstraint.Type));
37+
}
38+
39+
public override string ToString()
40+
{
41+
// TODO: would be nice to have a common formatter we can call into
42+
return "GenericParameterConstraint";
43+
}
44+
}
45+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Reflection.Metadata;
6+
7+
namespace ILTrim.DependencyAnalysis
8+
{
9+
/// <summary>
10+
/// Represents an entry in the GenericParam metadata table.
11+
/// </summary>
12+
public sealed class GenericParameterNode : TokenBasedNode
13+
{
14+
public GenericParameterNode(EcmaModule module, GenericParameterHandle handle)
15+
: base(module, handle)
16+
{
17+
}
18+
19+
private GenericParameterHandle Handle => (GenericParameterHandle)_handle;
20+
21+
public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
22+
{
23+
GenericParameter genericParam = _module.MetadataReader.GetGenericParameter(Handle);
24+
foreach (var genericParamConstrain in genericParam.GetConstraints())
25+
{
26+
yield return new DependencyListEntry(factory.GenericParameterConstraint(_module, genericParamConstrain), "Generic Parameter Constraint of Generic Parameter");
27+
}
28+
}
29+
30+
protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
31+
{
32+
MetadataReader reader = _module.MetadataReader;
33+
GenericParameter genericParam = reader.GetGenericParameter(Handle);
34+
35+
var builder = writeContext.MetadataBuilder;
36+
37+
return builder.AddGenericParameter(writeContext.TokenMap.MapToken(genericParam.Parent),
38+
genericParam.Attributes,
39+
builder.GetOrAddString(reader.GetString(genericParam.Name)),
40+
genericParam.Index);
41+
}
42+
43+
public override string ToString()
44+
{
45+
MetadataReader reader = _module.MetadataReader;
46+
return reader.GetString(reader.GetGenericParameter(Handle).Name);
47+
}
48+
}
49+
}

src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/TokenBased/TypeDefinitionNode.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
2828
yield return new(factory.GetNodeForToken(_module, typeDef.BaseType), "Base type of a type");
2929
}
3030

31+
foreach (var parameter in typeDef.GetGenericParameters())
32+
{
33+
yield return new(factory.GenericParameter(_module, parameter), "Generic parameter of type");
34+
}
35+
3136
foreach (CustomAttributeHandle customAttribute in typeDef.GetCustomAttributes())
3237
{
3338
yield return new(factory.CustomAttribute(_module, customAttribute), "Custom attribute of a type");

0 commit comments

Comments
 (0)