Skip to content

Commit

Permalink
Add TypeSpecification and MethodSpecification (dotnet#21)
Browse files Browse the repository at this point in the history
These are pretty boring, but adding them adds more testing opportunities for dotnet#4 since these all have a blob that dotnet#4 should be able to parse/rewrite.
  • Loading branch information
MichalStrehovsky committed Oct 12, 2021
1 parent ba4c4fc commit 984c9f9
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/coreclr/tools/ILTrim/ILTrim/DependencyAnalysis/NodeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public TokenBasedNode GetNodeForToken(EcmaModule module, EntityHandle handle)
case HandleKind.ModuleReference:
throw new NotImplementedException();
case HandleKind.TypeSpecification:
throw new NotImplementedException();
return TypeSpecification(module, (TypeSpecificationHandle)handle);
case HandleKind.AssemblyReference:
return AssemblyReference(module, (AssemblyReferenceHandle)handle);
case HandleKind.AssemblyFile:
Expand All @@ -65,7 +65,7 @@ public TokenBasedNode GetNodeForToken(EcmaModule module, EntityHandle handle)
case HandleKind.GenericParameter:
throw new NotImplementedException();
case HandleKind.MethodSpecification:
throw new NotImplementedException();
return MethodSpecification(module, (MethodSpecificationHandle)handle);
case HandleKind.GenericParameterConstraint:
throw new NotImplementedException();
default:
Expand Down Expand Up @@ -145,6 +145,22 @@ public ModuleDefinitionNode ModuleDefinition(EcmaModule module)
return _moduleDefinitions.GetOrAdd(module);
}

NodeCache<HandleKey<MethodSpecificationHandle>, MethodSpecificationNode> _methodSpecifications
= new NodeCache<HandleKey<MethodSpecificationHandle>, MethodSpecificationNode>(key
=> new MethodSpecificationNode(key.Module, key.Handle));
public MethodSpecificationNode MethodSpecification(EcmaModule module, MethodSpecificationHandle handle)
{
return _methodSpecifications.GetOrAdd(new HandleKey<MethodSpecificationHandle>(module, handle));
}

NodeCache<HandleKey<TypeSpecificationHandle>, TypeSpecificationNode> _typeSpecifications
= new NodeCache<HandleKey<TypeSpecificationHandle>, TypeSpecificationNode>(key
=> new TypeSpecificationNode(key.Module, key.Handle));
public TypeSpecificationNode TypeSpecification(EcmaModule module, TypeSpecificationHandle handle)
{
return _typeSpecifications.GetOrAdd(new HandleKey<TypeSpecificationHandle>(module, handle));
}

NodeCache<EcmaModule, AssemblyDefinitionNode> _assemblyDefinitions
= new NodeCache<EcmaModule, AssemblyDefinitionNode>(
key => new AssemblyDefinitionNode(key));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Reflection.Metadata;

namespace ILTrim.DependencyAnalysis
{
/// <summary>
/// Represents an entry in the MethodSpec metadata table (an instantiated generic method).
/// </summary>
public sealed class MethodSpecificationNode : TokenBasedNode
{
public MethodSpecificationNode(EcmaModule module, MethodSpecificationHandle handle)
: base(module, handle)
{
}

private MethodSpecificationHandle Handle => (MethodSpecificationHandle)_handle;

public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
{
MethodSpecification methodSpec = _module.MetadataReader.GetMethodSpecification(Handle);

// TODO: report dependencies from the signature

yield return new(factory.GetNodeForToken(_module, methodSpec.Method), "Instantiated method");
}

protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
{
MetadataReader reader = _module.MetadataReader;

MethodSpecification methodSpec = reader.GetMethodSpecification(Handle);

var builder = writeContext.MetadataBuilder;

// TODO: the signature blob might contain references to tokens we need to rewrite
var signatureBlob = reader.GetBlobBytes(methodSpec.Signature);

return builder.AddMethodSpecification(
writeContext.TokenMap.MapToken(methodSpec.Method),
builder.GetOrAddBlob(signatureBlob));
}

public override string ToString()
{
// TODO: would be nice to have a common formatter we can call into
return "MethodSpecification";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Reflection.Metadata;

namespace ILTrim.DependencyAnalysis
{
/// <summary>
/// Represents an entry in the TypeSpec metadata table (a constructed type).
/// </summary>
public sealed class TypeSpecificationNode : TokenBasedNode
{
public TypeSpecificationNode(EcmaModule module, TypeSpecificationHandle handle)
: base(module, handle)
{
}

private TypeSpecificationHandle Handle => (TypeSpecificationHandle)_handle;

public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
{
TypeSpecification typeSpec = _module.MetadataReader.GetTypeSpecification(Handle);

// TODO: report dependencies from the signature
yield break;
}

protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
{
MetadataReader reader = _module.MetadataReader;

TypeSpecification typeSpec = reader.GetTypeSpecification(Handle);

var builder = writeContext.MetadataBuilder;

// TODO: the signature blob might contain references to tokens we need to rewrite
var signatureBlob = reader.GetBlobBytes(typeSpec.Signature);

return builder.AddTypeSpecification(
builder.GetOrAddBlob(signatureBlob));
}

public override string ToString()
{
// TODO: would be nice to have a common formatter we can call into
return "TypeSpecification";
}
}
}

0 comments on commit 984c9f9

Please sign in to comment.