public CliAbstractAssemblyReferences(CliAssembly assembly) { var referenceTables = assembly.ObtainAssemblyRefTables().ToArray(); List <ICliMetadataAssemblyRefTableRow> referenceSources = new List <ICliMetadataAssemblyRefTableRow>(); HashSet <IAssemblyUniqueIdentifier> distinctIdentifiers = new HashSet <IAssemblyUniqueIdentifier>(); foreach (var table in referenceTables) { var copy = table.ToArray(); for (int copyIndex = 0; copyIndex < copy.Length; copyIndex++) { var current = copy[copyIndex]; if (distinctIdentifiers.Add(CliCommon.GetAssemblyUniqueIdentifier(current).Item2)) { referenceSources.Add(current); } } } this.referenceSources = referenceSources.ToArray(); this.identifiers = new ArrayReadOnlyCollection <IAssemblyUniqueIdentifier>(distinctIdentifiers.ToArray()); int mscorLib = -1; for (int i = 0; i < identifiers.Count; i++) { if (identifiers[i].Name == "mscorlib") { mscorLib = i; break; } } this.assembly = assembly; this.references = new IAssembly[this.identifiers.Count]; }
private static void ValidateTypeReferenceTable(IAssembly hostAssembly, ICliMetadataRoot metadataRoot, CompilerErrorCollection resultErrorCollection) { var typeRefTable = metadataRoot.TableStream.TypeRefTable; if (typeRefTable != null) { Parallel.ForEach(typeRefTable.ToArray(), typeRef => { var @namespace = typeRef.Namespace; string fullName = null; if (@namespace == null) { fullName = typeRef.Name; } else { fullName = string.Format("{0}.{1}", @namespace, typeRef.Name); } switch (typeRef.ResolutionScope) { case CliMetadataResolutionScopeTag.Module: if (typeRef.Source == null) { var exportedTypeTable = metadataRoot.TableStream.ExportedTypeTable; if (exportedTypeTable == null) { /* * * When resolution scope is null, there shall be an * ExportedType table row for this type (fullName). * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0101a, hostAssembly, typeRef, new string[] { fullName }); } var exportedType = (from eType in exportedTypeTable where eType.NamespaceIndex == typeRef.NamespaceIndex && eType.NameIndex == typeRef.NameIndex select eType).FirstOrDefault(); if (exportedType == null) { /* * * When resolution scope is null, there shall be an * ExportedType table row for this type (fullName). * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0101a, hostAssembly, metadataRoot, new string[] { fullName }); } } else { /* * * When resolution scope is a module token, the type referenced (fullName) * should be defined within the current module; though, this should not * occur in a CLI ("Compressed Metadata") module. * */ resultErrorCollection.ModelWarning(CliWarningsAndErrors.CliMetadata0101d, hostAssembly, typeRef, new string[] { fullName }); } break; case CliMetadataResolutionScopeTag.ModuleReference: var moduleRef = (ICliMetadataModuleReferenceTableRow)typeRef.Source; if (!hostAssembly.Modules.ContainsKey(TypeSystemIdentifiers.GetDeclarationIdentifier(moduleRef.Name))) { /* * * When resolution scope is a moduleref token, the target type (fullName) * is defined in another module within the same assembly. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0101c, hostAssembly, typeRef, new string[] { fullName }); } break; case CliMetadataResolutionScopeTag.AssemblyReference: var assemblyReference = (ICliMetadataAssemblyRefTableRow)typeRef.Source; var assemblyUniqueId = CliCommon.GetAssemblyUniqueIdentifier(assemblyReference).Item2; if (assemblyUniqueId == hostAssembly.UniqueIdentifier) { /* * * When resolution scope is an assemblyref, the type referenced (fullName) * should be defined within another assembly other than the current * module's assembly. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0101e, hostAssembly, typeRef, new string[] { fullName }); } else if (!hostAssembly.References.ContainsKey(assemblyUniqueId)) { hostAssembly.References.ContainsKey(assemblyUniqueId); /* * * When resolution scope is an assemblyref, the type referenced (fullName) * should be defined within another assembly (assemblyUniqueId) which * cannot be found. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0101f, hostAssembly, typeRef, new string[] { fullName, assemblyUniqueId.ToString() }); } break; case CliMetadataResolutionScopeTag.TypeReference: break; default: break; } if (typeRef.NameIndex == 0 || typeRef.Name == string.Empty) { /* * * Name shall index a non-empty string within the StringHeap. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0102, hostAssembly, typeRef); } if (typeRef.NamespaceIndex > 0 && typeRef.Namespace == string.Empty) { /* * * Namespace shall index a non-empty string if not null. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0104, hostAssembly, typeRef); } }); } }