/// <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;
 }
 /// <summary>
 /// Given a alias type and type's mangled name this method resolves it to a nested aliased type.
 /// Aliased type can further be walked to find the exact type it resolved to.
 /// </summary>
 /// <param name="parentType"></param>
 /// <param name="typeName"></param>
 /// <returns></returns>
 internal ExportedTypeAliasBase/*?*/ ResolveExportedNestedType(
   ExportedTypeAliasBase parentType,
   IName typeName
 ) {
   uint exportedTypeToken = this.NestedTypeTokenTable.Find(TokenTypeIds.ExportedType | parentType.ExportedTypeRowId, (uint)typeName.UniqueKey);
   if (exportedTypeToken == 0 || ((exportedTypeToken & TokenTypeIds.TokenTypeMask) != TokenTypeIds.ExportedType)) {
     return null;
   }
   return this.GetExportedTypeAtRowWorker(exportedTypeToken & TokenTypeIds.RIDMask);
 }
 internal void LoadNestedExportedTypesOfAlias(ExportedTypeAliasBase exportedType) {
   uint currentToken = exportedType.TokenValue;
   uint numberOfExportedTypes = this.PEFileReader.ExportedTypeTable.NumberOfRows;
   ExportedTypeAliasBase/*?*/[] exportedTypeArray = this.ExportedTypeArray;
   for (uint i = 1; i <= numberOfExportedTypes; ++i) {
     ExportedTypeRow exportedTypeRow = this.PEFileReader.ExportedTypeTable[i];
     //  Check if its in the same namespace
     if (exportedTypeRow.Implementation != currentToken || !exportedTypeRow.IsNested)
       continue;
     //  This will not be loaded by anyone other than 
     ExportedTypeNestedAlias/*?*/ type = (ExportedTypeNestedAlias)exportedTypeArray[i];
     if (type == null) {
       type = this.CreateExportedNestedType(i, exportedTypeRow, exportedType);
       this.ExportedTypeArray[i] = type;
       this.ExportedTypeLoadState[i] = LoadState.Loaded;
     }
   }
 }
 ExportedTypeNestedAlias CreateExportedNestedType(
   uint exportedTypeRowId,
   ExportedTypeRow exportedTypeRow,
   ExportedTypeAliasBase parentExportedType
 ) {
   IName typeName = this.GetNameFromOffset(exportedTypeRow.TypeName);
   ExportedTypeNestedAlias exportedType = new ExportedTypeNestedAlias(this, typeName, exportedTypeRowId, exportedTypeRow.Flags, parentExportedType);
   parentExportedType.AddMember(exportedType);
   return exportedType;
 }
Example #5
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;
 }
 ExportedTypeNestedAlias CreateExportedNestedType(uint exportedTypeRowId, ExportedTypeRow exportedTypeRow, ExportedTypeAliasBase parentExportedType) {
   ExportedTypeNestedAlias exportedType = new ExportedTypeNestedAlias(this, exportedTypeRowId, exportedTypeRow.Flags, parentExportedType);
   parentExportedType.AddMember(exportedType);
   return exportedType;
 }