Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2016-05-28 02:10:54 +0300
committerDavid Wrighton <davidwr@microsoft.com>2016-05-28 02:10:54 +0300
commit2368e17c76ba69d085945790528d6f6acc1bb608 (patch)
tree61dddbbabfb8be863eb33a98ab3f6cc205821109 /src/ILCompiler.MetadataTransform
parent00b31bc66f897b8fb7157362e3cf4308bd7d5fbf (diff)
Add support for generating MethodImpl metadata in metadata transform (#1332)
- implementation only for ECMA metadata as we don't have TypeSystem api surface that is general purpose enough to avoid using the ECMA metadata reader directly - metadata transform tests for generic and non-generic scenarios
Diffstat (limited to 'src/ILCompiler.MetadataTransform')
-rw-r--r--src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs19
-rw-r--r--src/ILCompiler.MetadataTransform/tests/SampleMetadataAssembly/SampleMetadata.cs18
-rw-r--r--src/ILCompiler.MetadataTransform/tests/SimpleTests.cs51
3 files changed, 84 insertions, 4 deletions
diff --git a/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs b/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs
index 982e76ed9..6869aefa3 100644
--- a/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs
+++ b/src/ILCompiler.MetadataTransform/src/ILCompiler/Metadata/Transform.Type.cs
@@ -302,9 +302,24 @@ namespace ILCompiler.Metadata
{
record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes);
}
- }
- // TODO: MethodImpls
+ foreach (var miHandle in ecmaRecord.GetMethodImplementations())
+ {
+ Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader;
+
+ Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle);
+
+ Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody);
+ Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration);
+ MethodImpl methodImplRecord = new MethodImpl
+ {
+ MethodBody = HandleQualifiedMethod(methodBody),
+ MethodDeclaration = HandleQualifiedMethod(methodDecl)
+ };
+
+ record.MethodImpls.Add(methodImplRecord);
+ }
+ }
}
private TypeAttributes GetTypeAttributes(Cts.MetadataType type)
diff --git a/src/ILCompiler.MetadataTransform/tests/SampleMetadataAssembly/SampleMetadata.cs b/src/ILCompiler.MetadataTransform/tests/SampleMetadataAssembly/SampleMetadata.cs
index 6ea288ecc..2bb736a00 100644
--- a/src/ILCompiler.MetadataTransform/tests/SampleMetadataAssembly/SampleMetadata.cs
+++ b/src/ILCompiler.MetadataTransform/tests/SampleMetadataAssembly/SampleMetadata.cs
@@ -1650,4 +1650,22 @@ namespace SampleMetadataRex
}
}
+namespace SampleMetadataMethodImpl
+{
+ interface ICloneable
+ {
+ void Clone();
+ void GenericClone<T>();
+ }
+
+ class ImplementsICloneable : ICloneable
+ {
+ void ICloneable.Clone()
+ {
+ }
+ void ICloneable.GenericClone<T>()
+ {
+ }
+ }
+}
diff --git a/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs b/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs
index 3c9018893..87156bfc0 100644
--- a/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs
+++ b/src/ILCompiler.MetadataTransform/tests/SimpleTests.cs
@@ -31,7 +31,7 @@ namespace MetadataTransformTests
var transformResult = MetadataTransform.Run(policy, new[] { _systemModule });
Assert.Equal(1, transformResult.Scopes.Count());
-
+
Assert.Equal(
_systemModule.GetAllTypes().Count(x => !policy.IsBlocked(x)),
transformResult.Scopes.Single().GetAllTypes().Count());
@@ -207,5 +207,52 @@ namespace MetadataTransformTests
Assert.Equal(5, allowedCount);
Assert.Equal(8, blockedCount);
}
+
+ [Fact]
+ public void TestMethodImplMetadata()
+ {
+ // Test that custom attributes referring to blocked types don't show up in metadata
+
+ var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly");
+ Cts.MetadataType iCloneable = sampleMetadataModule.GetType("SampleMetadataMethodImpl", "ICloneable");
+ Cts.MetadataType implementsICloneable = sampleMetadataModule.GetType("SampleMetadataMethodImpl", "ImplementsICloneable");
+ Cts.MethodDesc iCloneableDotClone = iCloneable.GetMethod("Clone", null);
+ Cts.MethodDesc iCloneableImplementation = implementsICloneable.GetMethod("SampleMetadataMethodImpl.ICloneable.Clone", null);
+ Cts.MethodDesc iCloneableDotGenericClone = iCloneable.GetMethod("GenericClone", null);
+ Cts.MethodDesc iCloneableGenericImplementation = implementsICloneable.GetMethod("SampleMetadataMethodImpl.ICloneable.GenericClone", null);
+
+ var policy = new SingleFileMetadataPolicy();
+ var transformResult = MetadataTransform.Run(policy,
+ new[] { _systemModule, sampleMetadataModule });
+
+ var iCloneableType = transformResult.GetTransformedTypeDefinition(iCloneable);
+ var implementsICloneableType = transformResult.GetTransformedTypeDefinition(implementsICloneable);
+
+ Assert.Equal(2, implementsICloneableType.MethodImpls.Count);
+
+ // non-generic MethodImpl
+ Method iCloneableDotCloneMethod = transformResult.GetTransformedMethodDefinition(iCloneableDotClone);
+ Method iCloneableImplementationMethod = transformResult.GetTransformedMethodDefinition(iCloneableImplementation);
+ QualifiedMethod methodImplMethodDecl = (QualifiedMethod)implementsICloneableType.MethodImpls[0].MethodDeclaration;
+ QualifiedMethod methodImplMethodBody = (QualifiedMethod)implementsICloneableType.MethodImpls[0].MethodBody;
+
+ Assert.Equal(iCloneableDotCloneMethod, methodImplMethodDecl.Method);
+ Assert.Equal(iCloneableType, methodImplMethodDecl.EnclosingType);
+
+ Assert.Equal(iCloneableImplementationMethod, methodImplMethodBody.Method);
+ Assert.Equal(implementsICloneableType, methodImplMethodBody.EnclosingType);
+
+ // generic MethodImpl
+ Method iCloneableDotGenericCloneMethod = transformResult.GetTransformedMethodDefinition(iCloneableDotGenericClone);
+ Method iCloneableGenericImplementationMethod = transformResult.GetTransformedMethodDefinition(iCloneableGenericImplementation);
+ QualifiedMethod methodImplGenericMethodDecl = (QualifiedMethod)implementsICloneableType.MethodImpls[1].MethodDeclaration;
+ QualifiedMethod methodImplGenericMethodBody = (QualifiedMethod)implementsICloneableType.MethodImpls[1].MethodBody;
+
+ Assert.Equal(iCloneableDotGenericCloneMethod, methodImplGenericMethodDecl.Method);
+ Assert.Equal(iCloneableType, methodImplGenericMethodDecl.EnclosingType);
+
+ Assert.Equal(iCloneableGenericImplementationMethod, methodImplGenericMethodBody.Method);
+ Assert.Equal(implementsICloneableType, methodImplGenericMethodBody.EnclosingType);
+ }
}
-}
+} \ No newline at end of file