public void TestVirtualDispatchOnGenericType() { // Verifies that virtual dispatch to a non-generic method on a generic instantiation works DefType objectType = _context.GetWellKnownType(WellKnownType.Object); MethodSignature toStringSig = new MethodSignature(MethodSignatureFlags.None, 0, _stringType, Array.Empty <TypeDesc>()); MethodDesc objectToString = objectType.GetMethod("ToString", toStringSig); Assert.NotNull(objectToString); MetadataType openTestType = _testModule.GetType("VirtualFunctionOverride", "SimpleGeneric`1"); InstantiatedType testInstance = openTestType.MakeInstantiatedType(new Instantiation(new TypeDesc[] { objectType })); MethodDesc targetOnInstance = testInstance.GetMethod("ToString", toStringSig); MethodDesc targetMethod = testInstance.FindVirtualFunctionTargetMethodOnObjectType(objectToString); Assert.Equal(targetOnInstance, targetMethod); }
public void TestConstructedMethodAdjustment() { TypeDesc intType = _context.GetWellKnownType(WellKnownType.Int32); TypeDesc stringType = _context.GetWellKnownType(WellKnownType.String); TypeDesc charType = _context.GetWellKnownType(WellKnownType.Char); TypeDesc objectType = _context.GetWellKnownType(WellKnownType.Object); MetadataType genericOpenType = _testModule.GetType("GenericTypes", "TwoParamGenericClass`2"); MetadataType nonGenericType = _testModule.GetType("GenericTypes", "NonGenericClass"); MethodDesc nonGenericOnGeneric = genericOpenType.GetMethod("NonGenericFunction", null); MethodDesc genericOnGeneric = genericOpenType.GetMethod("GenericFunction", null); MethodDesc genericOnNonGeneric = nonGenericType.GetMethod("GenericFunction", null); InstantiatedType genericIntString = genericOpenType.MakeInstantiatedType(intType, stringType); InstantiatedType genericCharString = genericOpenType.MakeInstantiatedType(charType, stringType); InstantiatedType genericCharObject = genericOpenType.MakeInstantiatedType(charType, objectType); MethodDesc nonGenericOnGenericIntString = genericIntString.GetMethod("NonGenericFunction", null); MethodDesc nonGenericOnGenericCharString = genericCharString.GetMethod("NonGenericFunction", null); MethodDesc nonGenericOnGenericCharObject = genericCharObject.GetMethod("NonGenericFunction", null); MethodDesc genericIntStringOnGenericIntString = genericIntString.GetMethod("GenericFunction", null).MakeInstantiatedMethod(intType, stringType); MethodDesc genericCharStringOnGenericCharString = genericCharString.GetMethod("GenericFunction", null).MakeInstantiatedMethod(charType, stringType); MethodDesc genericCharObjectOnGenericCharObject = genericCharObject.GetMethod("GenericFunction", null).MakeInstantiatedMethod(charType, objectType); MethodDesc genericIntStringOnNonGeneric = genericOnNonGeneric.MakeInstantiatedMethod(intType, stringType); MethodDesc genericCharStringOnNonGeneric = genericOnNonGeneric.MakeInstantiatedMethod(charType, stringType); MethodDesc genericCharObjectOnNonGeneric = genericOnNonGeneric.MakeInstantiatedMethod(charType, objectType); // Test complete replacement MethodDesc testDirectReplacementNonGenericOnGeneric = nonGenericOnGenericIntString.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType, stringType }, new TypeDesc[] { charType, objectType }); Assert.Equal(nonGenericOnGenericCharObject, testDirectReplacementNonGenericOnGeneric); MethodDesc testDirectReplacementGenericOnGeneric = genericIntStringOnGenericIntString.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType, stringType }, new TypeDesc[] { charType, objectType }); Assert.Equal(genericCharObjectOnGenericCharObject, testDirectReplacementGenericOnGeneric); MethodDesc testDirectReplacementGenericOnNonGeneric = genericIntStringOnNonGeneric.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType, stringType }, new TypeDesc[] { charType, objectType }); Assert.Equal(genericCharObjectOnNonGeneric, testDirectReplacementGenericOnNonGeneric); // Test replace first type in instantiation MethodDesc testPartialReplacementNonGenericOnGeneric = nonGenericOnGenericIntString.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType }, new TypeDesc[] { charType }); Assert.Equal(nonGenericOnGenericCharString, testPartialReplacementNonGenericOnGeneric); MethodDesc testPartialReplacementGenericOnGeneric = genericIntStringOnGenericIntString.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType }, new TypeDesc[] { charType }); Assert.Equal(genericCharStringOnGenericCharString, testPartialReplacementGenericOnGeneric); MethodDesc testPartialReplacementGenericOnNonGeneric = genericIntStringOnNonGeneric.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType }, new TypeDesc[] { charType }); Assert.Equal(genericCharStringOnNonGeneric, testPartialReplacementGenericOnNonGeneric); // Test ArrayMethod case ArrayType mdArrayChar = _context.GetArrayType(charType, 3); ArrayType mdArrayInt = _context.GetArrayType(intType, 3); MethodDesc getMethodOnMDIntArray = mdArrayInt.GetArrayMethod(ArrayMethodKind.Get); MethodDesc getMethodOnMDCharArray = mdArrayChar.GetArrayMethod(ArrayMethodKind.Get); MethodDesc testArrayMethodCase = getMethodOnMDIntArray.ReplaceTypesInConstructionOfMethod(new TypeDesc[] { intType }, new TypeDesc[] { charType }); Assert.Equal(getMethodOnMDCharArray, testArrayMethodCase); }