Inheritance: NominalTypeName
 /// <summary>
 /// Returns a reference to the type that the given alias stands for. For example, if alias is a type forwarder, return a reference to the forwarded type (in another assembly).
 /// </summary>
 internal INamedTypeReference/*?*/ GetReferenceToAliasedType(ExportedTypeAliasBase alias) {
   Assembly/*?*/ thisAssembly = this.Module as Assembly;
   if (thisAssembly == null) return null;
   uint exportedTypeRowId = alias.ExportedTypeRowId;
   if (exportedTypeRowId == 0) return null;
   ExportedTypeRow exportedTypeRow = this.PEFileReader.ExportedTypeTable[exportedTypeRowId];
   uint tokenType = exportedTypeRow.Implementation & TokenTypeIds.TokenTypeMask;
   uint rowId = exportedTypeRow.Implementation & TokenTypeIds.RIDMask;
   IName namespaceName = this.GetNameFromOffset(exportedTypeRow.TypeNamespace);
   IName mangledTypeName = this.GetNameFromOffset(exportedTypeRow.TypeName);
   IName unmangledTypeName = this.GetUnmangledNameFromOffset(exportedTypeRow.TypeName);
   switch (tokenType) {
     case TokenTypeIds.File: {
         FileReference/*?*/ fileRef = this.GetFileReferenceAt(rowId);
         if (fileRef == null) return null;
         var module = thisAssembly.FindMemberModuleNamed(fileRef.Name) as Module;
         if (module == null) return null;
         var foundType = module.PEFileToObjectModel.ResolveNamespaceTypeDefinition(namespaceName, mangledTypeName);
         if (foundType == null) return null;
         return foundType;
       }
     case TokenTypeIds.ExportedType: {
         ExportedTypeAliasBase/*?*/ parentExportedType = this.GetExportedTypeAtRowWorker(rowId);
         if (parentExportedType == null) return null;
         var parentModuleType = this.GetReferenceToAliasedType(parentExportedType);
         if (parentModuleType == null) return null;
         ITypeDefinition parentType = parentModuleType.ResolvedType;
         if (!(parentType is Dummy)) {
           foreach (ITypeDefinitionMember tdm in parentModuleType.ResolvedType.GetMembersNamed(unmangledTypeName, false)) {
             var modTypeRef = tdm as IMetadataReaderNamedTypeReference;
             if (modTypeRef != null)
               return modTypeRef;
           }
         } else {
           NamespaceTypeNameTypeReference/*?*/ nstr = parentModuleType as NamespaceTypeNameTypeReference;
           if (nstr != null) {
             var nestedTypeName = new NestedTypeName(this.NameTable, nstr.NamespaceTypeName, mangledTypeName);
             return nestedTypeName.GetAsNamedTypeReference(this, nstr.Module);
           }
           NestedTypeNameTypeReference/*?*/ netr = parentModuleType as NestedTypeNameTypeReference;
           if (netr != null) {
             var nestedTypeName = new NestedTypeName(this.NameTable, netr.NestedTypeName, mangledTypeName);
             return nestedTypeName.GetAsNamedTypeReference(this, netr.Module);
           }
         }
         return null;
       }
     case TokenTypeIds.AssemblyRef: {
         AssemblyReference/*?*/ assemRef = this.GetAssemblyReferenceAt(rowId);
         if (assemRef == null) return null;
         var internalAssembly = assemRef.ResolvedAssembly as Assembly;
         if (internalAssembly != null) {
           //Since we have already loaded the assembly that is supposed to hold this type, we may as well try and resolve it.
           PEFileToObjectModel assemblyPEFileToObjectModel = internalAssembly.PEFileToObjectModel;
           var type = assemblyPEFileToObjectModel.ResolveNamespaceTypeDefinition(namespaceName, mangledTypeName);
           if (type != null) return type;
           //The other assembly (internalAssembly) does not have a namespace type def for this reference.
           //Perhaps it has an alias that forwards to somewhere else... Not very likely happen in practice, I would hope.
           ExportedTypeAliasBase/*?*/ aliasType = assemblyPEFileToObjectModel.TryToResolveAsNamespaceTypeAlias(namespaceName, mangledTypeName);
           if (aliasType != null && aliasType != alias) return assemblyPEFileToObjectModel.GetReferenceToAliasedType(aliasType);
           //Although we can resolve the target assembly, we can neither resolve the aliased type, nor find a secondary alias.
           //This is mighty strange. Probably the host has fluffed assembly resolution and internalAssembly isn't really the
           //assembly we are looking for. We now have to give up and simply return an unresolved reference.
         }
         string fullTypeName = mangledTypeName.Value;
         if (namespaceName.Value.Length > 0) fullTypeName = namespaceName.Value+"."+fullTypeName;
         var parser = new TypeNameParser(this.NameTable, fullTypeName);
         return parser.ParseTypeName().GetAsTypeReference(this, assemRef) as INamedTypeReference;
       }
   }
   return null;
 }
Example #2
0
 NominalTypeName/*?*/ ParseNominalTypeName() {
   NominalTypeName/*?*/ nomTypeName = this.ParseNamespaceTypeName();
   if (nomTypeName == null)
     return null;
   while (this.CurrentTypeNameTokenKind == TypeNameTokenKind.Plus) {
     this.NextToken(false);
     if (this.CurrentTypeNameTokenKind != TypeNameTokenKind.Identifier) {
       return null;
     }
     nomTypeName = new NestedTypeName(this.NameTable, nomTypeName, this.CurrentIdentifierInfo);
     this.NextToken(false);
   }
   return nomTypeName;
 }
Example #3
0
 /// <summary>
 /// Finds the given aliased type in the exported type table.
 /// </summary>
 /// <param name="aliasAliasBase"></param>
 /// <returns></returns>
 internal IModuleTypeReference/*?*/ FindExportedType(
   ExportedTypeAliasBase aliasAliasBase
 ) {
   Assembly/*?*/ thisAssembly = this.Module as Assembly;
   if (thisAssembly == null)
     return null;
   uint exportedTypeRowId = aliasAliasBase.ExportedTypeRowId;
   if (exportedTypeRowId == 0)
     return null;
   ExportedTypeRow exportedTypeRow = this.PEFileReader.ExportedTypeTable[exportedTypeRowId];
   uint tokenType = exportedTypeRow.Implementation & TokenTypeIds.TokenTypeMask;
   uint rowId = exportedTypeRow.Implementation & TokenTypeIds.RIDMask;
   IName namespaceName = this.GetNameFromOffset(exportedTypeRow.TypeNamespace);
   IName typeName = this.GetNameFromOffset(exportedTypeRow.TypeName);
   switch (tokenType) {
     case TokenTypeIds.File: {
         FileReference/*?*/ fileRef = this.GetFileReferenceAt(rowId);
         if (fileRef == null) {
           return null;
         }
         Module/*?*/ module =thisAssembly.FindMemberModuleNamed(fileRef.Name);
         if (module == null) {
           return null;
         }
         TypeBase/*?*/ foundType = module.PEFileToObjectModel.ResolveNamespaceTypeDefinition(namespaceName, typeName);
         if (foundType == null) {
           return null;
         }
         return foundType;
       }
     case TokenTypeIds.ExportedType: {
         ExportedTypeAliasBase/*?*/ parentExportedType = this.GetExportedTypeAtRowWorker(rowId);
         if (parentExportedType == null) {
           return null;
         }
         IModuleTypeReference/*?*/ parentModuleType = this.FindExportedType(parentExportedType);
         if (parentModuleType == null) {
           return null;
         }
         ITypeDefinition parentType = parentModuleType.ResolvedType;
         if (parentType != Dummy.Type) {
           foreach (ITypeDefinitionMember tdm in parentModuleType.ResolvedType.GetMembersNamed(typeName, false)) {
             IModuleTypeReference/*?*/ modTypeRef = tdm as IModuleTypeReference;
             if (modTypeRef != null)
               return modTypeRef;
           }
         } else {
           NamespaceTypeNameTypeReference/*?*/ nstr = parentModuleType as NamespaceTypeNameTypeReference;
           if (nstr != null) {
             var nestedTypeName = new NestedTypeName(this.NameTable, nstr.NamespaceTypeName, typeName);
             return nestedTypeName.GetAsTypeReference(this, nstr.Module);
           }
           NestedTypeNameTypeReference/*?*/ netr = parentModuleType as NestedTypeNameTypeReference;
           if (netr != null) {
             var nestedTypeName = new NestedTypeName(this.NameTable, netr.NestedTypeName, typeName);
             return nestedTypeName.GetAsTypeReference(this, netr.Module);
           }
         }
         return null;
       }
     case TokenTypeIds.AssemblyRef: {
         AssemblyReference/*?*/ assemRef = this.GetAssemblyReferenceAt(rowId);
         if (assemRef == null) {
           return null;
         }
         var internalAssembly = assemRef.ResolvedAssembly as Assembly;
         if (internalAssembly != null) {
           PEFileToObjectModel assemblyPEFileToObjectModel = internalAssembly.PEFileToObjectModel;
           TypeBase/*?*/ type = assemblyPEFileToObjectModel.ResolveNamespaceTypeDefinition(namespaceName, typeName);
           if (type != null)
             return type;
           ExportedTypeAliasBase/*?*/ aliasType = assemblyPEFileToObjectModel.ResolveExportedNamespaceType(namespaceName, typeName);
           if (aliasType != null && aliasType != aliasAliasBase) {
             return assemblyPEFileToObjectModel.FindExportedType(aliasType);
           }
         } else {
           string fullTypeName = typeName.Value;
           if (namespaceName.Value.Length > 0)
             fullTypeName = namespaceName.Value+"."+typeName.Value;
           var parser = new TypeNameParser(this.NameTable, fullTypeName);
           return parser.ParseTypeName().GetAsTypeReference(this, assemRef);
         }
       }
       break;
   }
   return null;
 }