protected override ReferenceKeyValuePair <string, QualifiedNamespaceDefinition[]> CreateValueFromKey(string key) { ArrayBuilder <QualifiedNamespaceDefinition> namespaceDefinitions = new ArrayBuilder <QualifiedNamespaceDefinition>(); foreach (QualifiedScopeDefinition qdefinition in _scopes) { MetadataReader metadataReader = qdefinition.MetadataReader; NamespaceDefinitionHandle rootNamespaceHandle = qdefinition.Definition.RootNamespaceDefinition; NamespaceDefinition currentNamespace = metadataReader.GetNamespaceDefinition(rootNamespaceHandle); if (key == "") { namespaceDefinitions.Add(new QualifiedNamespaceDefinition(qdefinition.MetadataUnit, currentNamespace)); // We're done now. } else { string[] components = key.Split('.'); bool found = false; foreach (string namespaceComponent in components) { found = false; foreach (NamespaceDefinitionHandle childNamespaceHandle in currentNamespace.NamespaceDefinitions) { NamespaceDefinition childNamespace = metadataReader.GetNamespaceDefinition(childNamespaceHandle); if (childNamespace.Name.StringEquals(namespaceComponent, metadataReader)) { found = true; currentNamespace = childNamespace; break; } } if (!found) { break; } } if (found) { namespaceDefinitions.Add(new QualifiedNamespaceDefinition(qdefinition.MetadataUnit, currentNamespace)); } } } return(new ReferenceKeyValuePair <System.String, QualifiedNamespaceDefinition[]>(key, namespaceDefinitions.ToArray())); }
private bool TryGetCategoryFlagsForPrimitiveType(out TypeFlags categoryFlags) { categoryFlags = 0; if (_module != _metadataUnit.Context.SystemModule) { // Primitive types reside in the system module return(false); } NamespaceDefinition namespaceDef = MetadataReader.GetNamespaceDefinition(_typeDefinition.NamespaceDefinition); if (namespaceDef.ParentScopeOrNamespace.HandleType != HandleType.NamespaceDefinition) { // Primitive types are in the System namespace the parent of which is the root namespace return(false); } if (!namespaceDef.Name.StringEquals("System", MetadataReader)) { // Namespace name must be 'System' return(false); } NamespaceDefinitionHandle parentNamespaceDefHandle = namespaceDef.ParentScopeOrNamespace.ToNamespaceDefinitionHandle(MetadataReader); NamespaceDefinition parentDef = MetadataReader.GetNamespaceDefinition(parentNamespaceDefHandle); if (parentDef.ParentScopeOrNamespace.HandleType != HandleType.ScopeDefinition) { // The root parent namespace should have scope (assembly) handle as its parent return(false); } return(s_primitiveTypes.TryGetValue(Name, out categoryFlags)); }
/// <summary> /// Enumerate all type definitions within a given namespace. /// </summary> /// <param name="metadataUnit">Metadata unit containing the namespace</param> /// <param name="metadataReader">Metadata reader for the scope metadata</param> /// <param name="namespaceDefinitionHandle">Namespace to enumerate</param> private IEnumerable <MetadataType> GetTypesInNamespace( NativeFormatMetadataUnit metadataUnit, MetadataReader metadataReader, NamespaceDefinitionHandle namespaceDefinitionHandle) { NamespaceDefinition namespaceDefinition = metadataReader.GetNamespaceDefinition(namespaceDefinitionHandle); // First, enumerate all types (including nested) in the current namespace foreach (TypeDefinitionHandle namespaceTypeHandle in namespaceDefinition.TypeDefinitions) { yield return((MetadataType)metadataUnit.GetType(namespaceTypeHandle)); foreach (MetadataType nestedType in GetNestedTypes(metadataUnit, metadataReader, namespaceTypeHandle)) { yield return(nestedType); } } // Second, recurse into nested namespaces foreach (NamespaceDefinitionHandle nestedNamespace in namespaceDefinition.NamespaceDefinitions) { foreach (MetadataType type in GetTypesInNamespace(metadataUnit, metadataReader, nestedNamespace)) { yield return(type); } } }
/// <summary> /// Extracts the method signature from the metadata by rid /// </summary> public R2RMethod(byte[] image, MetadataReader mdReader, uint rid, int entryPointId, GenericElementTypes[] instanceArgs, uint[] tok) { Token = _mdtMethodDef | rid; EntryPointRuntimeFunctionId = entryPointId; _mdReader = mdReader; RuntimeFunctions = new List <RuntimeFunction>(); // get the method signature from the MethodDefhandle MethodDefinitionHandle methodDefHandle = MetadataTokens.MethodDefinitionHandle((int)rid); _methodDef = mdReader.GetMethodDefinition(methodDefHandle); Name = mdReader.GetString(_methodDef.Name); BlobReader signatureReader = mdReader.GetBlobReader(_methodDef.Signature); TypeDefinitionHandle declaringTypeHandle = _methodDef.GetDeclaringType(); TypeDefinition declaringTypeDef; while (!declaringTypeHandle.IsNil) { declaringTypeDef = mdReader.GetTypeDefinition(declaringTypeHandle); DeclaringType = mdReader.GetString(declaringTypeDef.Name) + "." + DeclaringType; declaringTypeHandle = declaringTypeDef.GetDeclaringType(); } NamespaceDefinitionHandle namespaceHandle = declaringTypeDef.NamespaceDefinition; while (!namespaceHandle.IsNil) { NamespaceDefinition namespaceDef = mdReader.GetNamespaceDefinition(namespaceHandle); DeclaringType = mdReader.GetString(namespaceDef.Name) + "." + DeclaringType; namespaceHandle = namespaceDef.Parent; } SignatureHeader signatureHeader = signatureReader.ReadSignatureHeader(); IsGeneric = signatureHeader.IsGeneric; GenericParameterHandleCollection genericParams = _methodDef.GetGenericParameters(); _genericParamInstanceMap = new Dictionary <string, GenericInstance>(); int argCount = signatureReader.ReadCompressedInteger(); if (IsGeneric) { argCount = signatureReader.ReadCompressedInteger(); } ReturnType = new SignatureType(ref signatureReader, mdReader, genericParams); ArgTypes = new SignatureType[argCount]; for (int i = 0; i < argCount; i++) { ArgTypes[i] = new SignatureType(ref signatureReader, mdReader, genericParams); } if (IsGeneric && instanceArgs != null && tok != null) { InitGenericInstances(genericParams, instanceArgs, tok); } }
public static MetadataDefinition Create( MetadataReader reader, NamespaceDefinitionHandle namespaceHandle) { var definition = reader.GetNamespaceDefinition(namespaceHandle); return(new MetadataDefinition( MetadataDefinitionKind.Namespace, reader.GetString(definition.Name), @namespace: definition)); }
private void AddNamespaceParts( NamespaceDefinitionHandle namespaceHandle, List <string> simpleNames) { if (namespaceHandle.IsNil) { return; } var namespaceDefinition = _metadataReader.GetNamespaceDefinition(namespaceHandle); AddNamespaceParts(namespaceDefinition.Parent, simpleNames); simpleNames.Add(_metadataReader.GetString(namespaceDefinition.Name)); }
public NativeFormatModule GetModuleFromNamespaceDefinition(NamespaceDefinitionHandle handle) { while (true) { NamespaceDefinition namespaceDef = _metadataReader.GetNamespaceDefinition(handle); Handle parentScopeOrDefinitionHandle = namespaceDef.ParentScopeOrNamespace; if (parentScopeOrDefinitionHandle.HandleType == HandleType.ScopeDefinition) { return((NativeFormatModule)GetObject(parentScopeOrDefinitionHandle, null)); } else { handle = parentScopeOrDefinitionHandle.ToNamespaceDefinitionHandle(_metadataReader); } } }
private void EmitNamespaceDefinitionName(NamespaceDefinitionHandle namespaceDefHandle) { NamespaceDefinition namespaceDef = _metadataReader.GetNamespaceDefinition(namespaceDefHandle); if (!namespaceDef.ParentScopeOrNamespace.IsNull(_metadataReader) && namespaceDef.ParentScopeOrNamespace.HandleType == HandleType.NamespaceDefinition) { int charsWritten = _outputBuilder.Length; EmitNamespaceDefinitionName(namespaceDef.ParentScopeOrNamespace.ToNamespaceDefinitionHandle(_metadataReader)); if (_outputBuilder.Length - charsWritten > 0) { _outputBuilder.Append('.'); } } EmitString(namespaceDef.Name); }
public static bool CompareNamespaceReferenceToDefinition(NamespaceReferenceHandle nr1, MetadataReader mr1, NamespaceDefinitionHandle nd2, MetadataReader mr2) { NamespaceReference nrData1 = mr1.GetNamespaceReference(nr1); NamespaceDefinition ndData2 = mr2.GetNamespaceDefinition(nd2); if (nrData1.Name.IsNull(mr1) != ndData2.Name.IsNull(mr2)) { return(false); } if (!nrData1.Name.IsNull(mr1)) { if (!nrData1.Name.StringEquals(ndData2.Name.GetConstantStringValue(mr2).Value, mr1)) { return(false); } } switch (nrData1.ParentScopeOrNamespace.HandleType) { case HandleType.NamespaceReference: if (ndData2.ParentScopeOrNamespace.HandleType != HandleType.NamespaceDefinition) { return(false); } return(CompareNamespaceReferenceToDefinition(nrData1.ParentScopeOrNamespace.ToNamespaceReferenceHandle(mr1), mr1, ndData2.ParentScopeOrNamespace.ToNamespaceDefinitionHandle(mr2), mr2)); case HandleType.ScopeReference: if (ndData2.ParentScopeOrNamespace.HandleType != HandleType.ScopeDefinition) { return(false); } return(CompareScopeReferenceToDefinition(nrData1.ParentScopeOrNamespace.ToScopeReferenceHandle(mr1), mr1, ndData2.ParentScopeOrNamespace.ToScopeDefinitionHandle(mr2), mr2)); default: Debug.Assert(false); throw new BadImageFormatException(); } }
/// <summary> /// Extracts the method signature from the metadata by rid /// </summary> public R2RMethod(byte[] image, MetadataReader mdReader, uint rid, int entryPointId, GenericElementTypes[] instanceArgs, uint[] tok) { Token = _mdtMethodDef | rid; Rid = rid; EntryPointRuntimeFunctionId = entryPointId; _mdReader = mdReader; RuntimeFunctions = new List <RuntimeFunction>(); // get the method signature from the MethodDefhandle MethodDefinitionHandle methodDefHandle = MetadataTokens.MethodDefinitionHandle((int)rid); _methodDef = mdReader.GetMethodDefinition(methodDefHandle); Name = mdReader.GetString(_methodDef.Name); BlobReader signatureReader = mdReader.GetBlobReader(_methodDef.Signature); TypeDefinitionHandle declaringTypeHandle = _methodDef.GetDeclaringType(); TypeDefinition declaringTypeDef; while (!declaringTypeHandle.IsNil) { declaringTypeDef = mdReader.GetTypeDefinition(declaringTypeHandle); DeclaringType = mdReader.GetString(declaringTypeDef.Name) + "." + DeclaringType; declaringTypeHandle = declaringTypeDef.GetDeclaringType(); } NamespaceDefinitionHandle namespaceHandle = declaringTypeDef.NamespaceDefinition; while (!namespaceHandle.IsNil) { NamespaceDefinition namespaceDef = mdReader.GetNamespaceDefinition(namespaceHandle); DeclaringType = mdReader.GetString(namespaceDef.Name) + "." + DeclaringType; namespaceHandle = namespaceDef.Parent; } SignatureHeader signatureHeader = signatureReader.ReadSignatureHeader(); IsGeneric = signatureHeader.IsGeneric; GenericParameterHandleCollection genericParams = _methodDef.GetGenericParameters(); _genericParamInstanceMap = new Dictionary <string, string>(); int argCount = signatureReader.ReadCompressedInteger(); if (IsGeneric) { argCount = signatureReader.ReadCompressedInteger(); } DisassemblingTypeProvider provider = new DisassemblingTypeProvider(); if (IsGeneric && instanceArgs != null && tok != null) { InitGenericInstances(genericParams, instanceArgs, tok); } DisassemblingGenericContext genericContext = new DisassemblingGenericContext(new string[0], _genericParamInstanceMap.Values.ToArray()); Signature = _methodDef.DecodeSignature(provider, genericContext); SignatureString = GetSignature(); }
/// <summary> /// Helper method that will validate that a NamespaceDefinition (and all NamespaceDefinitions considered children /// of it) report correct values for their child namespaces, types, etc. All namespaces in the module are expected /// to be listed in the allNamespaces array. Additionally, the global namespace is expected to have type definitions /// for GlobalClassA, GlobalClassB, and Module. No type forwarder declarations are expected. /// /// All namespaces that aren't the global NS are expected to have type definitions equal to the array /// @namespaceName.Split('.') /// So, ns1.Ns2.NS3 is expected to have type definitions /// {"ns1", "Ns2", "NS3"}. /// /// definitionExceptions and forwarderExceptions may be used to override the default expectations. Pass in /// namespace (key) and what is expected (list of strings) for each exception. /// </summary> private void ValidateNamespaceChildren( MetadataReader reader, NamespaceDefinitionHandle initHandle, string[] allNamespaces, IReadOnlyDictionary<string, IList<string>> definitionExceptions = null, IReadOnlyDictionary<string, IList<string>> forwarderExceptions = null) { // Don't want to have to deal with null. if (definitionExceptions == null) { definitionExceptions = new Dictionary<string, IList<string>>(); } if (forwarderExceptions == null) { forwarderExceptions = new Dictionary<string, IList<string>>(); } var rootNamespaceDefinition = reader.GetNamespaceDefinition(initHandle); string rootNamespaceName = reader.GetString(initHandle); // We need to be in the table of all namespaces... Assert.Contains(rootNamespaceName, allNamespaces); // Cool. Now check to make sure that .Name only returns the last bit of our namespace name. var expNamespaceNameSegment = rootNamespaceName.Split('.').Last(); var rootNamespaceNameSegment = reader.GetString(rootNamespaceDefinition.Name); Assert.Equal(expNamespaceNameSegment, rootNamespaceNameSegment); bool isGlobalNamespace = rootNamespaceName.Length == 0; string[] expTypeDefinitions = null; // Special case: Global NS has GlobalClassA, GlobalClassB. Others just have autogenerated classes. if (definitionExceptions.ContainsKey(rootNamespaceName)) { expTypeDefinitions = definitionExceptions[rootNamespaceName].ToArray(); } else if (isGlobalNamespace) { expTypeDefinitions = new[] { "GlobalClassA", "GlobalClassB", "<Module>" }; } else { expTypeDefinitions = rootNamespaceName.Split('.'); } // Validating type definitions inside the namespace... int numberOfTypeDefinitions = 0; foreach (var definitionHandle in rootNamespaceDefinition.TypeDefinitions) { var definition = reader.GetTypeDefinition(definitionHandle); var definitionName = reader.GetString(definition.Name); var definitionFullNamespaceName = reader.GetString(definition.Namespace); Assert.Equal(rootNamespaceName, definitionFullNamespaceName); Assert.Contains(definitionName, expTypeDefinitions); numberOfTypeDefinitions += 1; } // Guarantee that there are no extra unexpected members... Assert.Equal(numberOfTypeDefinitions, expTypeDefinitions.Length); string[] expTypeForwarders = null; if (forwarderExceptions.ContainsKey(rootNamespaceName)) { expTypeForwarders = forwarderExceptions[rootNamespaceName].ToArray(); } else { expTypeForwarders = new string[] { }; } int numberOfTypeForwarders = 0; foreach (var forwarderHandle in rootNamespaceDefinition.ExportedTypes) { var forwarder = reader.GetExportedType(forwarderHandle); Assert.True(reader.StringComparer.Equals(forwarder.Namespace, rootNamespaceName)); var forwarderName = reader.GetString(forwarder.Name); Assert.Contains(forwarderName, expTypeForwarders); numberOfTypeForwarders += 1; } Assert.Equal(expTypeForwarders.Length, numberOfTypeForwarders); // Validate sub-namespaces // If the last index of '.' in a namespace name is == the current name's length, then // that ns is a direct child of the current one! IList<String> expChildren = null; // Special case: Global NS's children won't have .s in them. if (isGlobalNamespace) { expChildren = allNamespaces.Where(ns => !String.IsNullOrEmpty(ns) && !ns.Contains('.')).ToList(); } else { expChildren = allNamespaces .Where(ns => ns.StartsWith(rootNamespaceName) && ns.LastIndexOf('.') == rootNamespaceName.Length) .ToList(); } int numberOfSubNamespaces = 0; foreach (var subNamespaceHandle in rootNamespaceDefinition.NamespaceDefinitions) { Assert.False(subNamespaceHandle.IsNil); string subNamespaceFullName = reader.GetString(subNamespaceHandle); NamespaceDefinition subNamespace = reader.GetNamespaceDefinition(subNamespaceHandle); string subNamespaceName = subNamespaceFullName.Split('.').Last(); Assert.Equal(subNamespaceName, reader.GetString(subNamespace.Name)); Assert.True(reader.StringComparer.Equals(subNamespace.Name, subNamespaceName)); Assert.True(reader.StringComparer.StartsWith(subNamespace.Name, subNamespaceName)); Assert.True(reader.StringComparer.StartsWith(subNamespace.Name, subNamespaceName.Substring(0, subNamespaceName.Length - 1))); Assert.Equal(subNamespace.Parent, initHandle); Assert.Contains(subNamespaceFullName, expChildren); ValidateNamespaceChildren(reader, subNamespaceHandle, allNamespaces, definitionExceptions, forwarderExceptions); numberOfSubNamespaces += 1; } // Guarantee no extra unexpected namespaces... Assert.Equal(expChildren.Count, numberOfSubNamespaces); }
public static NamespaceDefinition GetNamespaceDefinition(this NamespaceDefinitionHandle handle, MetadataReader reader) => reader.GetNamespaceDefinition(handle);
public static bool CompareNamespaceReferenceToDefinition(NamespaceReferenceHandle nr1, MetadataReader mr1, NamespaceDefinitionHandle nd2, MetadataReader mr2) { NamespaceReference nrData1 = mr1.GetNamespaceReference(nr1); NamespaceDefinition ndData2 = mr2.GetNamespaceDefinition(nd2); if (nrData1.Name.IsNull(mr1) != ndData2.Name.IsNull(mr2)) return false; if (!nrData1.Name.IsNull(mr1)) { if (!nrData1.Name.StringEquals(ndData2.Name.GetConstantStringValue(mr2).Value, mr1)) return false; } switch (nrData1.ParentScopeOrNamespace.HandleType) { case HandleType.NamespaceReference: if (ndData2.ParentScopeOrNamespace.HandleType != HandleType.NamespaceDefinition) return false; return CompareNamespaceReferenceToDefinition(nrData1.ParentScopeOrNamespace.ToNamespaceReferenceHandle(mr1), mr1, ndData2.ParentScopeOrNamespace.ToNamespaceDefinitionHandle(mr2), mr2); case HandleType.ScopeReference: if (ndData2.ParentScopeOrNamespace.HandleType != HandleType.ScopeDefinition) return false; return CompareScopeReferenceToDefinition(nrData1.ParentScopeOrNamespace.ToScopeReferenceHandle(mr1), mr1, ndData2.ParentScopeOrNamespace.ToScopeDefinitionHandle(mr2), mr2); default: Debug.Assert(false); throw new BadImageFormatException(); } }