private ITypeReference Specialize(uint typeSpecToken, INamedTypeReference namedTypeReference, ref ushort genericArgumentCount, bool outer) { if (genericArgumentCount == 0) return namedTypeReference; var nestedTypeReference = namedTypeReference as INestedTypeReference; if (nestedTypeReference != null) { Contract.Assume(!(nestedTypeReference is ISpecializedNestedTypeReference)); //the type reference comes from the metadata, which is always fully unspecialized var containingType = this.Specialize(0, (INamedTypeReference)nestedTypeReference.ContainingType, ref genericArgumentCount, outer: false); if (containingType != nestedTypeReference.ContainingType) namedTypeReference = new SpecializedNestedTypeReference(nestedTypeReference, containingType, this.PEFileToObjectModel.InternFactory); } var genericParametersCount = namedTypeReference.GenericParameterCount; if (genericParametersCount == 0) { if (genericArgumentCount == 0 || !outer) return namedTypeReference; //If we get here we believed that namedTypeReference has no type parameters because it has no tick in its name. //However, there actually are generic types without ticks, so we better now change our belief to match this signature. //This does not work for nested generics, but that is just too bad. genericParametersCount = genericArgumentCount; } genericArgumentCount -= genericParametersCount; var genericArgumentArray = new ITypeReference[genericParametersCount]; //TODO: it would be very desirable to cache these objects by structure so that we can reuse them. //However, it is not safe at this point to use the intern table because we might still be reading the //signature of a generic method whose generic parameters feature in the arguments to the generic type. //We cannot compute the intern key of a generic method type parameter before we are able to compute the intern key of the generic method. for (int i = 0; i < genericParametersCount; ++i) genericArgumentArray[i] = this.GetTypeReference()??Dummy.TypeReference; if (outer && typeSpecToken != 0xFFFFFFFF) return new GenericTypeInstanceReferenceWithToken(typeSpecToken, namedTypeReference, IteratorHelper.GetReadonly(genericArgumentArray), this.PEFileToObjectModel.InternFactory); else return new GenericTypeInstanceReference(namedTypeReference, IteratorHelper.GetReadonly(genericArgumentArray), this.PEFileToObjectModel.InternFactory); }
private ITypeReference GetSpecializedTypeReference(PEFileToObjectModel peFileToObjectModel, INamedTypeReference nominalType, out int argumentUsed, bool mostNested) { argumentUsed = 0; int len = this.GenericArguments.Count; var nestedType = nominalType as INestedTypeReference; if (nestedType != null) { var parentTemplate = this.GetSpecializedTypeReference(peFileToObjectModel, (INamedTypeReference)nestedType.ContainingType, out argumentUsed, mostNested: false); if (parentTemplate != nestedType.ContainingType) nominalType = new SpecializedNestedTypeReference(nestedType, parentTemplate, peFileToObjectModel.InternFactory); } var argsToUse = mostNested ? len-argumentUsed : nominalType.GenericParameterCount; if (argsToUse == 0) return nominalType; var genericArgumentsReferences = new ITypeReference[argsToUse]; for (int i = 0; i < argsToUse; ++i) genericArgumentsReferences[i] = this.GenericArguments[i+argumentUsed].GetAsTypeReference(peFileToObjectModel, peFileToObjectModel.Module)??Dummy.TypeReference; argumentUsed += argsToUse; return new GenericTypeInstanceReference(nominalType, IteratorHelper.GetReadonly(genericArgumentsReferences), peFileToObjectModel.InternFactory); }
internal Microsoft.Cci.INamedTypeReference Translate(NamedTypeSymbol namedTypeSymbol, bool needDeclaration) { System.Diagnostics.Debug.Assert(ReferenceEquals(namedTypeSymbol, namedTypeSymbol.OriginalDefinition) || !namedTypeSymbol.Equals(namedTypeSymbol.OriginalDefinition)); if (!ReferenceEquals(namedTypeSymbol, namedTypeSymbol.OriginalDefinition)) { // generic instantiation for sure System.Diagnostics.Debug.Assert(!needDeclaration); return namedTypeSymbol; } else if (!needDeclaration) { object reference; Microsoft.Cci.INamedTypeReference typeRef; NamedTypeSymbol container = namedTypeSymbol.ContainingType; if (namedTypeSymbol.Arity > 0) { if (genericInstanceMap.TryGetValue(namedTypeSymbol, out reference)) { return (Microsoft.Cci.INamedTypeReference)reference; } if (container != null) { if (IsGenericType(container)) { // Container is a generic instance too. typeRef = new SpecializedGenericNestedTypeInstanceReference(namedTypeSymbol); } else { typeRef = new GenericNestedTypeInstanceReference(namedTypeSymbol); } } else { typeRef = new GenericNamespaceTypeInstanceReference(namedTypeSymbol); } genericInstanceMap.Add(namedTypeSymbol, typeRef); return typeRef; } else if (IsGenericType(container)) { System.Diagnostics.Debug.Assert(container != null); if (genericInstanceMap.TryGetValue(namedTypeSymbol, out reference)) { return (Microsoft.Cci.INamedTypeReference)reference; } typeRef = new SpecializedNestedTypeReference(namedTypeSymbol); genericInstanceMap.Add(namedTypeSymbol, typeRef); return typeRef; } } return namedTypeSymbol; }
private ITypeReference SpecializeAndOrInstantiate(uint typeSpecToken, INamedTypeReference namedTypeReference, ref ushort genericArgumentCount, bool outer) { if (genericArgumentCount == 0) return namedTypeReference; var nestedTypeReference = namedTypeReference as INestedTypeReference; if (nestedTypeReference != null) { Contract.Assume(!(nestedTypeReference is ISpecializedNestedTypeReference)); //the type reference comes from the metadata, which is always fully unspecialized var containingType = this.SpecializeAndOrInstantiate(0, (INamedTypeReference)nestedTypeReference.ContainingType, ref genericArgumentCount, outer: false); if (containingType != nestedTypeReference.ContainingType) namedTypeReference = new SpecializedNestedTypeReference(nestedTypeReference, containingType, this.PEFileToObjectModel.InternFactory); } if (genericArgumentCount <= 0) return namedTypeReference; var genericParametersCount = namedTypeReference.GenericParameterCount; genericArgumentCount -= genericParametersCount; if (genericArgumentCount < 0) { genericParametersCount += genericArgumentCount; }; if (genericParametersCount == 0) return namedTypeReference; return this.Instantiate(typeSpecToken, namedTypeReference, genericParametersCount); }
private ITypeReference Specialize(uint typeSpecToken, INamedTypeReference namedTypeReference, ref ushort genericArgumentCount, bool outer) { if (genericArgumentCount == 0) return namedTypeReference; var nestedTypeReference = namedTypeReference as INestedTypeReference; if (nestedTypeReference != null) { Contract.Assume(!(nestedTypeReference is ISpecializedNestedTypeReference)); //the type reference comes from the metadata, which is always fully unspecialized var containingType = this.Specialize(0, (INamedTypeReference)nestedTypeReference.ContainingType, ref genericArgumentCount, outer: false); if (containingType != nestedTypeReference.ContainingType) namedTypeReference = new SpecializedNestedTypeReference(nestedTypeReference, containingType, this.PEFileToObjectModel.InternFactory); } var genericParametersCount = namedTypeReference.GenericParameterCount; if (genericParametersCount == 0) { if (genericArgumentCount == 0 || !outer) return namedTypeReference; //If we get here we believed that namedTypeReference has no type parameters because it has no tick in its name. //However, there actually are generic types without ticks, so we better now change our belief to match this signature. //This does not work for nested generics, but that is just too bad. genericParametersCount = genericArgumentCount; } genericArgumentCount -= genericParametersCount; var genericArgumentArray = new ITypeReference[genericParametersCount]; for (int i = 0; i < genericParametersCount; ++i) genericArgumentArray[i] = this.GetTypeReference()??Dummy.TypeReference; if (outer) return new GenericTypeInstanceReferenceWithToken(typeSpecToken, namedTypeReference, IteratorHelper.GetReadonly(genericArgumentArray), this.PEFileToObjectModel.InternFactory); else return new GenericTypeInstanceReference(namedTypeReference, IteratorHelper.GetReadonly(genericArgumentArray), this.PEFileToObjectModel.InternFactory); }
internal Microsoft.Cci.INamedTypeReference Translate(NamedTypeSymbol namedTypeSymbol, bool needDeclaration) { System.Diagnostics.Debug.Assert(ReferenceEquals(namedTypeSymbol, namedTypeSymbol.OriginalDefinition) || !namedTypeSymbol.Equals(namedTypeSymbol.OriginalDefinition)); if (!ReferenceEquals(namedTypeSymbol, namedTypeSymbol.OriginalDefinition)) { // generic instantiation for sure System.Diagnostics.Debug.Assert(!needDeclaration); return(namedTypeSymbol); } else if (!needDeclaration) { object reference; Microsoft.Cci.INamedTypeReference typeRef; NamedTypeSymbol container = namedTypeSymbol.ContainingType; if (namedTypeSymbol.Arity > 0) { if (genericInstanceMap.TryGetValue(namedTypeSymbol, out reference)) { return((Microsoft.Cci.INamedTypeReference)reference); } if (container != null) { if (IsGenericType(container)) { // Container is a generic instance too. typeRef = new SpecializedGenericNestedTypeInstanceReference(namedTypeSymbol); } else { typeRef = new GenericNestedTypeInstanceReference(namedTypeSymbol); } } else { typeRef = new GenericNamespaceTypeInstanceReference(namedTypeSymbol); } genericInstanceMap.Add(namedTypeSymbol, typeRef); return(typeRef); } else if (IsGenericType(container)) { System.Diagnostics.Debug.Assert(container != null); if (genericInstanceMap.TryGetValue(namedTypeSymbol, out reference)) { return((Microsoft.Cci.INamedTypeReference)reference); } typeRef = new SpecializedNestedTypeReference(namedTypeSymbol); genericInstanceMap.Add(namedTypeSymbol, typeRef); return(typeRef); } } return(namedTypeSymbol); }
/// <summary> /// Rewrites the given specialized nested type reference. /// </summary> /// <param name="specializedNestedTypeReference"></param> public override void RewriteChildren(SpecializedNestedTypeReference specializedNestedTypeReference) { specializedNestedTypeReference.ContainingType = this.Rewrite(specializedNestedTypeReference.ContainingType); }