private ICliMetadataTypeDefinitionTableRow GetTypeDefinition(IGeneralTypeUniqueIdentifier identifier) { var nestingHierarchy = identifier.GetNestingHierarchy(); ICliMetadataTypeDefinitionTableRow typeDefinition = null; bool first = true; while (nestingHierarchy.Count > 0) { var current = nestingHierarchy.Pop(); if (first) { /* * * Going off of a true namespace setup. * */ var topLevelType = this.FindType(current); if (topLevelType == null) { return(null); } typeDefinition = topLevelType; first = false; } else { bool found = false; string name = current.Name; if (current is IGenericTypeUniqueIdentifier) { var genericCurrent = ((IGenericTypeUniqueIdentifier)current); if (!genericCurrent.UsesNonstandardGraveAccentElement) { name = string.Format("{0}`{1}", name, genericCurrent.TypeParameters); } } foreach (var nestedType in typeDefinition.NestedClasses) { if (nestedType.Name == name && current.Namespace == null && string.IsNullOrEmpty(nestedType.Namespace) || (current.Namespace != null && nestedType.Namespace == current.Namespace.Name)) { typeDefinition = nestedType; found = true; break; } } if (!found) { return(null); } } } return(typeDefinition); }
private IType OnGetType() { if (this.metadataEntry == null) { throw new InvalidOperationException(); } var metadataEntryCtor = metadataEntry.Ctor; if (metadataEntryCtor == null) { throw new InvalidOperationException(); } ICliMetadataTypeDefinitionTableRow typeDef = null; switch (metadataEntryCtor.CustomAttributeTypeEncoding) { case CliMetadataCustomAttributeTypeTag.MethodDefinition: ICliMetadataMethodDefinitionTableRow methodDefinition = (ICliMetadataMethodDefinitionTableRow)metadataEntryCtor; var tdTable = metadataEntry.MetadataRoot.TableStream.TypeDefinitionTable; uint typeIndex = tdTable.GetTypeFromMethodIndex(methodDefinition.Index); typeDef = tdTable[(int)typeIndex]; break; case CliMetadataCustomAttributeTypeTag.MemberReference: ICliMetadataMemberReferenceTableRow reference = (ICliMetadataMemberReferenceTableRow)metadataEntryCtor; switch (reference.ClassSource) { case CliMetadataMemberRefParentTag.TypeDefinition: typeDef = (ICliMetadataTypeDefinitionTableRow)reference.Class; break; case CliMetadataMemberRefParentTag.TypeReference: typeDef = identityManager.ResolveScope((ICliMetadataTypeRefTableRow)reference.Class); break; case CliMetadataMemberRefParentTag.TypeSpecification: case CliMetadataMemberRefParentTag.ModuleReference: case CliMetadataMemberRefParentTag.MethodDefinition: default: throw new BadImageFormatException(); } break; } if (typeDef == null) { throw new BadImageFormatException(); } return(identityManager.ObtainTypeReference(typeDef)); }
internal IType ObtainTypeReference(ICliMetadataTypeDefinitionTableRow typeIdentity) { if (CliCommon.IsSpecialModule(typeIdentity)) { return(null); } IType result; lock (this.metadataTypeCache) { if (!metadataTypeCache.TryGetValue(typeIdentity, out result)) { var refAssem = this.manager.GetRelativeAssembly(typeIdentity.MetadataRoot); if (CliCommon.IsBaseObject(this.manager, typeIdentity)) { result = new CliClassType(refAssem, typeIdentity); } else if ((typeIdentity.TypeAttributes & TypeAttributes.Interface) == TypeAttributes.Interface && (typeIdentity.TypeAttributes & TypeAttributes.Sealed) != TypeAttributes.Sealed) { result = new CliInterfaceType(refAssem, typeIdentity); } else if (CliCommon.IsBaseObject(this.manager, typeIdentity.Extends)) { result = new CliClassType(refAssem, typeIdentity); } else if (CliCommon.IsEnum(this.manager, typeIdentity)) { //result = new CliEnumType(); result = new CliEnumType(refAssem, typeIdentity); } else if (CliCommon.IsValueType(this.manager, typeIdentity)) { result = new CliStructType(refAssem, typeIdentity); } else if (CliCommon.IsDelegate(this.manager, typeIdentity) && !CliCommon.IsBaseDelegateType(this.manager, typeIdentity)) { result = new CliDelegateType(refAssem, typeIdentity); } else { result = new CliClassType(refAssem, typeIdentity); } this.metadataTypeCache.Add(typeIdentity, result); } } return(result); }
private static bool CheckForDeclSecurityRow(ICliMetadataRoot metadataRoot, ICliMetadataTypeDefinitionTableRow typeDefinition) { var declSecurityTable = metadataRoot.TableStream.DeclSecurityTable; if (declSecurityTable == null) { return(false); } bool hasSecurityRow = false; foreach (var declSecurity in declSecurityTable) { if (declSecurity.ParentSource == CliMetadataHasDeclSecurityTag.TypeDefinition && declSecurity.ParentIndex == typeDefinition.Index) { hasSecurityRow = true; } } return(hasSecurityRow); }
public ICliMetadataTypeDefinitionTableRow FindType(IGeneralTypeUniqueIdentifier uniqueIdentifier) { var myID = this.UniqueIdentifier; var depth = ((IGeneralTypeUniqueIdentifier)this.UniqueIdentifier).GetDepth(); /* * * If the hierarchy of the unique identifier is properly formed, then * the current type's identifier should be contained within it. * */ var hierarchy = uniqueIdentifier.GetNestingHierarchy().Skip(depth - 1); var first = hierarchy.FirstOrDefault(); if (first == null || !myID.Equals(first)) { return(null); } ICliMetadataTypeDefinitionTableRow typeDefinition = this.MetadataEntry; var remainingHierarchy = new Stack <IGeneralTypeUniqueIdentifier>(hierarchy.Skip(1).Reverse()); while (remainingHierarchy.Count > 0) { var current = remainingHierarchy.Pop(); bool found = false; foreach (var nestedType in typeDefinition.NestedClasses) { if (nestedType.Name == current.Name && current.Namespace == null && string.IsNullOrEmpty(nestedType.Namespace) || (current.Namespace != null && nestedType.Namespace == current.Namespace.Name)) { typeDefinition = nestedType; found = true; break; } } if (!found) { return(null); } } return(typeDefinition); }
internal static IEnumerable <IInterfaceType> GetImplementations(ICliMetadataTypeDefinitionTableRow parentDef, ICliMetadataMethodDefinitionTableRow methodMetadata, CliManager identityManager, IType activeType, IMethodSignatureMember activeMethod, IAssembly activeAssembly) { var targets = (from t in parentDef.ImplementationMap where t.MethodBody == methodMetadata select t.MethodDeclaration); foreach (var target in targets) { IType currentType = null; switch (target.MethodDefOrRefEncoding) { case CliMetadataMethodDefOrRefTag.MethodDefinition: ICliMetadataMethodDefinitionTableRow methodDef = (ICliMetadataMethodDefinitionTableRow)target; currentType = identityManager.ObtainTypeReference(methodMetadata.MetadataRoot.TableStream.TypeDefinitionTable[(int)methodMetadata.MetadataRoot.TableStream.TypeDefinitionTable.GetTypeFromMethodIndex(methodDef.Index)], activeType, activeMethod, activeAssembly); break; case CliMetadataMethodDefOrRefTag.MemberRef: ICliMetadataMemberReferenceTableRow memberRef = (ICliMetadataMemberReferenceTableRow)target; switch (memberRef.ClassSource) { case CliMetadataMemberRefParentTag.TypeDefinition: currentType = identityManager.ObtainTypeReference((ICliMetadataTypeDefinitionTableRow)memberRef.Class, activeType, activeMethod, activeAssembly); break; case CliMetadataMemberRefParentTag.TypeReference: currentType = identityManager.ObtainTypeReference((ICliMetadataTypeRefTableRow)memberRef.Class, activeType, activeMethod, activeAssembly); break; case CliMetadataMemberRefParentTag.TypeSpecification: currentType = identityManager.ObtainTypeReference((ICliMetadataTypeSpecificationTableRow)memberRef.Class, activeType, activeMethod, activeAssembly); break; } break; } if (currentType != null && currentType is IInterfaceType) { yield return((IInterfaceType)currentType); } } }
private static bool ExtendsTarget(ICliMetadataTypeDefinitionTableRow typeDefinition, string nameSpace, string name) { var extends = typeDefinition.Extends; if (extends == null) { return(false); } if (typeDefinition.ExtendsSource == CliMetadataTypeDefOrRefTag.TypeDefinition) { var extendsDef = (ICliMetadataTypeDefinitionTableRow)extends; if (!(extendsDef.Name == name && extendsDef.Namespace == nameSpace && extendsDef.DeclaringType == null)) { return(false); } } else if (typeDefinition.ExtendsSource == CliMetadataTypeDefOrRefTag.TypeReference) { var extendsRef = (ICliMetadataTypeRefTableRow)extends; if (!(extendsRef.Name == name && extendsRef.Namespace == nameSpace && (extendsRef.ResolutionScope == CliMetadataResolutionScopeTag.AssemblyReference || extendsRef.ResolutionScope == CliMetadataResolutionScopeTag.ModuleReference || extendsRef.ResolutionScope == CliMetadataResolutionScopeTag.Module))) { return(false); } } else { return(false); } return(true); }
protected CliGenericTypeBase(CliAssembly assembly, ICliMetadataTypeDefinitionTableRow metadataEntry) : base(assembly, metadataEntry) { }
/// <summary> /// Creates a new <see cref="CliGenericParentType{TIdentifier, TType}"/> with the /// <paramref name="owner"/> and <paramref name="metadataEntry"/> provided. /// </summary> /// <param name="owner">The <see cref="CliAssembly"/> which contains the /// <see cref="CliGenericParentType{TIdentifier, TType}"/>.</param> /// <param name="metadataEntry">The <see cref="ICliMetadataTypeDefinitionTableRow"/> from /// which the information within the <see cref="CliGenericParentType{TIdentifier, TType}"/> /// is derived.</param> internal CliGenericParentType(CliAssembly owner, ICliMetadataTypeDefinitionTableRow metadataEntry) : base(owner, metadataEntry) { }
internal CliTypeBase(CliAssembly assembly, ICliMetadataTypeDefinitionTableRow metadataEntry) { this.assembly = assembly; this.metadataEntry = metadataEntry; }
protected CliGenericInstantiableTypeBase(CliAssembly assembly, ICliMetadataTypeDefinitionTableRow metadata) : base(assembly, metadata) { }
internal void InitializeCommon() { ICliMetadataModuleTableRow[] modules = this.Modules.GetMetadata(); var typeTables = (from moduleRow in modules let ts = moduleRow.MetadataRoot.TableStream where ts.TypeDefinitionTable != null select ts.TypeDefinitionTable).ToArray(); if (typeTables.Length == 0) { return; } HashSet <Tuple <int, uint> > namespaceIndices = new HashSet <Tuple <int, uint> >(); Dictionary <uint, CliMetadataTypeDefinitionLockedTableRow[]> nonNestedTypes = new Dictionary <uint, CliMetadataTypeDefinitionLockedTableRow[]>(); Dictionary <uint, int> nonNestedCounts = new Dictionary <uint, int>(); /* * * Breakdown the types by their namespace index, and * create a unique list of namespaceIndices via a HashSet<T>. * * * Copy the table to a local set to avoid redundant load * checks, and to instruct it to read the full table sequentially. * */ int totalTypeCount = 0; for (int typeTable = 0; typeTable < typeTables.Length; typeTable++) { totalTypeCount += typeTables[typeTable].Count; } ICliMetadataTypeDefinitionTableRow[] types = new ICliMetadataTypeDefinitionTableRow[totalTypeCount]; for (int moduleIndex = 0, cOff = 0; moduleIndex < typeTables.Length; cOff += typeTables[moduleIndex++].Count) { typeTables[moduleIndex].CopyTo(types, cOff); } ICliMetadataTypeDefinitionTable moduleTypes = typeTables[0]; for (int typeIndex = 0, moduleIndex = 0, moduleOffset = 0; typeIndex < types.Length; typeIndex++, moduleOffset++) { moduleCheck: if (moduleOffset >= moduleTypes.Count) { moduleIndex++; if (moduleIndex < typeTables.Length) { moduleTypes = typeTables[moduleIndex]; } moduleOffset = 0; goto moduleCheck; } var typeRow = types[typeIndex]; if ((typeRow.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic || (typeRow.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) { uint nsIndex = typeRow.NamespaceIndex; namespaceIndices.Add(Tuple.Create(moduleIndex, nsIndex)); CliMetadataTypeDefinitionLockedTableRow[] currentRows; if (!nonNestedTypes.TryGetValue(nsIndex, out currentRows)) { nonNestedTypes.Add(nsIndex, currentRows = new CliMetadataTypeDefinitionLockedTableRow[4]); nonNestedCounts.Add(nsIndex, 0); } CliMetadataTypeDefinitionLockedTableRow[] spaceAvailableRows = currentRows.EnsureSpaceExists(nonNestedCounts[nsIndex], 1); if (spaceAvailableRows != currentRows) { nonNestedTypes[nsIndex] = currentRows = spaceAvailableRows; } currentRows[nonNestedCounts[nsIndex]++] = typeRow as CliMetadataTypeDefinitionLockedTableRow; } } var namespaceIndicesArray = namespaceIndices.ToArray(); CliMetadataTypeDefinitionLockedTableRow[] topLevelRows; if (nonNestedTypes.TryGetValue(0, out topLevelRows)) { int topLevelCount = nonNestedCounts[0]; int noModuleCount = 0; for (int typeIndex = 0; typeIndex < topLevelCount; typeIndex++) { if (topLevelRows[typeIndex].Index != CliMetadataTypeDefinitionTableReader.__COR_TYPEDEFINITION_MODULE_INDEX__) { noModuleCount++; } } if (topLevelRows.Length != noModuleCount) { CliMetadataTypeDefinitionLockedTableRow[] topLevelRowsActual = new CliMetadataTypeDefinitionLockedTableRow[noModuleCount]; /* * * Filter the entries based off of their index. The special <Module> type * is the global fields and methods. There's no need to include them and * have to inject checks elsewhere to filter it out. * */ for (int typeIndex = 0, cOffset = 0; typeIndex < topLevelCount; typeIndex++) { if (topLevelRows[typeIndex].Index != CliMetadataTypeDefinitionTableReader.__COR_TYPEDEFINITION_MODULE_INDEX__) { topLevelRowsActual[cOffset++] = topLevelRows[typeIndex]; } } Array.Sort(topLevelRowsActual, _CompareTo_); topLevelRows = topLevelRowsActual; } else { Array.Sort(topLevelRows, _CompareTo_); } } else { topLevelRows = new CliMetadataTypeDefinitionLockedTableRow[0]; } CliNamespaceKeyedTree partialOrFullNamespaces = new CliNamespaceKeyedTree(topLevelRows); Dictionary <string, uint> partIndex = new Dictionary <string, uint>(); for (int namespaceIndex = 0; namespaceIndex < namespaceIndicesArray.Length; namespaceIndex++) { uint currentIndex = namespaceIndicesArray[namespaceIndex].Item2; if (currentIndex == 0) { continue; } var currentRows = nonNestedTypes[currentIndex]; var currentCount = nonNestedCounts[currentIndex]; var module = modules[namespaceIndicesArray[namespaceIndex].Item1]; string currentString = module.MetadataRoot.StringsHeap[currentIndex]; /* * * Eliminate the null row entries by reducing the sizes * of the arrays. * */ if (currentRows.Length != currentCount) { var currentRowsCopy = new CliMetadataTypeDefinitionLockedTableRow[currentCount]; Array.ConstrainedCopy(currentRows, 0, currentRowsCopy, 0, currentCount); Array.Sort(currentRowsCopy, _CompareTo_); currentRows = currentRowsCopy; } else { Array.Sort(currentRows, _CompareTo_); } CliNamespaceKeyedTree current = partialOrFullNamespaces; string[] breakdown = currentString.Split(new[] { "." }, StringSplitOptions.None); int currentLength = 0; bool first = true; foreach (var part in breakdown) { /* * * Position tracking, there is no period preceeding * the first namespace identifier. * */ if (first) { first = false; } else { currentLength++; } uint partId; /* * * Don't use the namespace index as a key for the * partial or full dictionary. * * * Use the substring of the current namespace as a guide, * since the 'System' of 'System'.Collections.Generic would * be a different string heap index than 'System' alone, * create our own reference lookup for the individual * segments of the namespace's name. * * * Use the segment's hash code to determine the part index; * while there's a chance for collision, the chances are slim. * Main reason is: while the space of possible character combinations * is small, the chance of a user-written name overlapping, in the * realm of its sibling namespaces, is unlikely. * */ if (!partIndex.TryGetValue(part, out partId)) { partIndex.Add(part, partId = (uint)part.GetHashCode()); } int startIndex = currentLength; currentLength += part.Length; bool fullName = currentLength == currentString.Length; CliNamespaceKeyedTreeNode next; if (!current.TryGetValue(partId, out next)) { if (fullName) { current = current.Add(partId, currentIndex, startIndex, currentLength - startIndex, currentRows, module.MetadataRoot.StringsHeap); } else { current = current.Add(partId, currentIndex, startIndex, currentLength - startIndex, module.MetadataRoot.StringsHeap); } } else { current = next; if (fullName) { current.PushModuleTypes(currentRows); } } } } this.namespaceInformation = partialOrFullNamespaces; }
//#endregion internal static int _CompareTo_(ICliMetadataTypeDefinitionTableRow leftRow, ICliMetadataTypeDefinitionTableRow rightRow) { return(leftRow.Name.CompareTo(rightRow.Name)); }
internal CliModule(CliAssembly owner, ICliMetadataModuleTableRow metadata) : base(owner) { this.Metadata = metadata; this.memberData = ScanForMemberData(metadata); }
public static IEnumerable <Tuple <CliMemberType, ICliMetadataTableRow> > GetMemberData(this ICliMetadataTypeDefinitionTableRow target) { IEnumerable <Tuple <CliMemberType, uint, ICliMetadataTableRow> > propertyData = null; /* * * Build our own list of methods tied to semantics, * this is about 3 times faster than querying the full * set each time, but uses a little more memory. * */ List <uint> fullSemantics = new List <uint>(); uint fieldCount = target.Fields == null ? 0 : (uint)target.Fields.Count; var properties = target.Properties; /* * * Construct the property and event sets remembering the * lowest order method associated to each. * * * This is for proper member ordering, fields are always first, because there's no context * information to order them relative to the original source, as fields don't * associate to methods like events and properties do. * */ if (properties == null || properties.Count == 0) { propertyData = new Tuple <CliMemberType, uint, ICliMetadataTableRow> [0]; } else { uint startIndex = properties[0].Index; uint endIndex = (uint)(startIndex + properties.Count - 1); //var subSemantics = (from s in target.MetadataRoot.PropertySemantics // where ((startIndex <= s.AssociationIndex) && (s.AssociationIndex <= endIndex)) // select s).ToArray(); List <ICliMetadataMethodSemanticsTableRow> subSemantics = new List <ICliMetadataMethodSemanticsTableRow>(); foreach (var propertySemantic in target.MetadataRoot.PropertySemantics) { if (startIndex <= propertySemantic.AssociationIndex && propertySemantic.AssociationIndex <= endIndex) { subSemantics.Add(propertySemantic); fullSemantics.Add(propertySemantic.MethodIndex); } } propertyData = (from property in target.Properties join semantics in subSemantics on property.Index equals semantics.AssociationIndex into methods let minSemantics = methods.MinSemantics() let elementType = (minSemantics.Semantics == MethodSemanticsAttributes.Getter ? minSemantics.Method.Parameters.Count > 0 : minSemantics.Method.Parameters.Count > 1) ? CliMemberType.Indexer : CliMemberType.Property select new Tuple <CliMemberType, uint, ICliMetadataTableRow>(elementType, minSemantics.MethodIndex + fieldCount + target.FieldStartIndex, property)); } IEnumerable <Tuple <CliMemberType, uint, ICliMetadataTableRow> > @eventData = null; var events = target.Events; if (events == null || events.Count == 0) { @eventData = new Tuple <CliMemberType, uint, ICliMetadataTableRow> [0]; } else { uint startIndex = events[0].Index; uint endIndex = (uint)(startIndex + events.Count - 1); List <ICliMetadataMethodSemanticsTableRow> subSemantics = new List <ICliMetadataMethodSemanticsTableRow>(); foreach (var eventSemantic in target.MetadataRoot.EventSemantics) { if (startIndex <= eventSemantic.AssociationIndex && eventSemantic.AssociationIndex <= endIndex) { subSemantics.Add(eventSemantic); fullSemantics.Add(eventSemantic.MethodIndex); } } eventData = (from @event in target.Events join semantics in subSemantics on @event.Index equals semantics.AssociationIndex into methods select new Tuple <CliMemberType, uint, ICliMetadataTableRow>(CliMemberType.Event, methods.Min() + fieldCount + target.FieldStartIndex, @event)); } /* * * Using the indices gathered from the events and properties, * select difference from the type's overall method set. * * * Then distinguish each variation of method as a constructor (.ctor, .cctor), * binary operator (op_Addition, et al), unary operator (op_Decrement, et al), * or expression type coercion operator (op_Implicit, op_Explicit) * */ var remainingMethods = (from m in from method in target.Methods where !fullSemantics.Contains(method.Index) select method //(target.Methods.Except(from m in target.Methods // join semantics in fullSemantics on m.Index equals semantics // select m)) select new Tuple <CliMemberType, uint, ICliMetadataTableRow>(DiscernMemberType(m), m.Index + fieldCount + target.FieldStartIndex, m)); /* * * Yield a full set of members, remembering their kind, and ordering them * by a close approximate of their original order. * */ IEnumerable <Tuple <CliMemberType, ICliMetadataTableRow> > result; if (target.Fields == null) { result = from m in propertyData.Concat(eventData).Concat(remainingMethods).ToArray() orderby m.Item2 select new Tuple <CliMemberType, ICliMetadataTableRow>(m.Item1, m.Item3); } else { result = from m in propertyData.Concat(eventData).Concat(remainingMethods).Concat( from f in target.Fields select new Tuple <CliMemberType, uint, ICliMetadataTableRow>(CliMemberType.Field, f.Index, f)).ToArray() orderby m.Item2 select new Tuple <CliMemberType, ICliMetadataTableRow>(m.Item1, m.Item3); } return(result); }
internal CliClassType(CliAssembly assembly, ICliMetadataTypeDefinitionTableRow metadata) : base(assembly, metadata) { }
private static void ValidateTypeDefinitionTable(IAssembly hostAssembly, ICliMetadataRoot metadataRoot, CompilerErrorCollection resultErrorCollection, _ICliManager identityManager) { var typeDefTable = metadataRoot.TableStream.TypeDefinitionTable; if (typeDefTable == null) { return; } int maxTypeDef = typeDefTable.Count; int maxTypeRef = metadataRoot.TableStream.TypeRefTable == null ? 0 : metadataRoot.TableStream.TypeRefTable.Count; int maxTypeSpec = metadataRoot.TableStream.TypeSpecificationTable == null ? 0 : metadataRoot.TableStream.TypeSpecificationTable.Count; Parallel.ForEach(typeDefTable.ToArray(), typeDefinition => { var typeAttributes = typeDefinition.TypeAttributes; if (((int)(typeAttributes ^ (typeAttributes & (TypeAttributes)0xD77DBF))) != 0) { /* * * Flags must contain only those values specified by System.Reflection.TypeAttributes * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0202a, hostAssembly, typeDefinition); } if (((typeAttributes & TypeAttributes.SequentialLayout) == TypeAttributes.SequentialLayout) && ((typeAttributes & TypeAttributes.ExplicitLayout) == TypeAttributes.SequentialLayout)) { /* * * Sequential Layout and Explicit Layout cannot be set together. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0202b, hostAssembly, typeDefinition); } if (((typeAttributes & TypeAttributes.AutoClass) == TypeAttributes.AutoClass) && ((typeAttributes & TypeAttributes.UnicodeClass) == TypeAttributes.UnicodeClass)) { /* * * UnicodeClass and AutoClass flags cannot be set together. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0202c, hostAssembly, typeDefinition); } if ((typeAttributes & TypeAttributes.HasSecurity) == TypeAttributes.HasSecurity) { if (!(CheckForDeclSecurityRow(metadataRoot, typeDefinition) || CheckForSecuritySuppressionAttribute(metadataRoot, typeDefTable, typeDefinition))) { /* * * If HasSecurity is set, then the type must contain at least one * DeclSecurity row, or a custom attribute called * SuppressUnmanagedCodeSecurityAttribute. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0202d, hostAssembly, typeDefinition); } if ((typeAttributes & TypeAttributes.Interface) == TypeAttributes.Interface) { /* * * Interfaces are allowed to have the HasSecurity flag set; however, * the security system ignores any permission requests attached to * that interface. * */ resultErrorCollection.ModelWarning(CliWarningsAndErrors.CliMetadata0202g, hostAssembly, typeDefinition); } } else if (CheckForDeclSecurityRow(metadataRoot, typeDefinition)) { /* * * If this type owns one (or more) DeclSecurity rows, then the HasSecurity * flag must be set. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0202e, hostAssembly, typeDefinition); } else if (CheckForSecuritySuppressionAttribute(metadataRoot, typeDefTable, typeDefinition)) { /* * * If this type has a custom attribute called SuppressUnmanagedCodeSecurityAttribute, * then the HasSecurity flag must be set. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0202f, hostAssembly, typeDefinition); } if (string.IsNullOrEmpty(typeDefinition.Name)) { /* * * Name shall index a non-empty string in the String Heap. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0203, hostAssembly, typeDefinition); } string name = typeDefinition.Name, @namespace = typeDefinition.Namespace; int maxIndex = 0; switch (typeDefinition.ExtendsSource) { case CliMetadataTypeDefOrRefTag.TypeDefinition: maxIndex = maxTypeDef; break; case CliMetadataTypeDefOrRefTag.TypeReference: maxIndex = maxTypeRef; break; case CliMetadataTypeDefOrRefTag.TypeSpecification: maxIndex = maxTypeSpec; break; } /* * * If the index is beyond the allowed ranges, don't even check the * 'Extends' part as it'll yield an exception. * * * The exception being if there's no actual reference in the first place, * when the source is a type def and the index is zero. * */ if (!(typeDefinition.ExtendsSource == CliMetadataTypeDefOrRefTag.TypeDefinition && typeDefinition.ExtendsIndex == 0) && (1 > typeDefinition.ExtendsIndex || typeDefinition.ExtendsIndex > maxIndex)) { resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0211a, hostAssembly, typeDefinition); } else if (typeDefinition.Extends == null && (typeAttributes & TypeAttributes.Interface) != TypeAttributes.Interface) { if (!(CliCommon.IsSpecialModule(typeDefinition) || CliCommon.IsBaseObject(identityManager, typeDefinition))) { /* * * Every class (with exception to System.Object and the special class * <Module>) shall extend one, and only one, other Class - so Extends * is for a Class shall be non-null. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0208, hostAssembly, typeDefinition); } } else if (typeDefinition.Extends != null && name == "Object" && @namespace == "System" && typeDefinition.DeclaringType == null) { /* * * System.Object must have an extends value of null. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0209, hostAssembly, typeDefinition); } else if (name == "ValueType" && @namespace == "System" && typeDefinition.DeclaringType == null) { if (!CliCommon.IsBaseObject(identityManager, typeDefinition.Extends)) { /* * * System.ValueType must have an extends value of System.Object * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0210, hostAssembly, typeDefinition); } } else if (typeDefinition.Extends != null) { var extendsDef = identityManager.ResolveScope(typeDefinition.Extends); if (extendsDef != null) { var events = extendsDef.Events; if (CliCommon.IsValueType(identityManager, extendsDef) || ((extendsDef.TypeAttributes & TypeAttributes.Interface) == TypeAttributes.Interface)) { resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0211b, hostAssembly, typeDefinition, extendsDef); } if ((extendsDef.TypeAttributes & TypeAttributes.Sealed) == TypeAttributes.Sealed) { resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0211c, hostAssembly, typeDefinition, extendsDef); } List <ICliMetadataTypeDefinitionTableRow> extendsTable = new List <ICliMetadataTypeDefinitionTableRow>(); ICliMetadataTypeDefinitionTableRow current = typeDefinition; while (current != null) { if (extendsTable.Contains(current)) { /* * * A class shall not extend itself, or any of its children (i.e., * its derived classes), because this will introduce loops in the * hierarchy tree. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0212, hostAssembly, typeDefinition); break; } extendsTable.Add(current); current = identityManager.ResolveScope(current.Extends); } } } /* * * ToDo: Add code here to check the name identifier against CLS rules. * Warning CliMetadata0204 * */ if (typeDefinition.NamespaceIndex != 0 && typeDefinition.Namespace == string.Empty) { /* * * If non-null, Namespace shall index a non-empty string in the * String Heap. * */ resultErrorCollection.ModelError(CliWarningsAndErrors.CliMetadata0206, hostAssembly, typeDefinition); } /* * * ToDo: Add code here to check the namespace identifier against CLS rules. * Warning CliMetadata0207 * */ }); }
public static IEnumerable <Tuple <CliMemberType, ICliMetadataTableRow> > GetMemberData2(this ICliMetadataTypeDefinitionTableRow target) { var fields = target.Fields; var methods = target.Methods; var properties = target.Properties; var events = target.Events; var methodQuery = from m in methods select new Tuple <CliMemberType, ICliMetadataTableRow>(CliMemberType.Method, m); var propertyQuery = from m in properties select new Tuple <CliMemberType, ICliMetadataTableRow>(CliMemberType.Property, m); var eventQuery = from m in properties select new Tuple <CliMemberType, ICliMetadataTableRow>(CliMemberType.Property, m); IEnumerable <Tuple <CliMemberType, ICliMetadataTableRow> > result = (fields == null) ? null : from f in fields select new Tuple <CliMemberType, ICliMetadataTableRow>(CliMemberType.Field, f); if (result == null && methods != null) { result = methodQuery; } else if (methods != null) { result = result.Concat(methodQuery); } if (result == null && properties != null) { result = propertyQuery; } else if (properties != null) { result = result.Concat(propertyQuery); } if (result == null && events != null) { result = eventQuery; } else if (events != null) { result = result.Concat(eventQuery); } return(result ?? new Tuple <CliMemberType, ICliMetadataTableRow> [0]); //return target.Methods.Concat<ICliMetadataTableRow>(target.Properties.Concat<ICliMetadataTableRow>(target.Events.Concat<ICliMetadataTableRow>(target.Fields))); }
private static bool CheckForSecuritySuppressionAttribute(ICliMetadataRoot metadataRoot, ICliMetadataTypeDefinitionTable typeDefTable, ICliMetadataTypeDefinitionTableRow typeDefinition) { bool hasSuppressionAttribute = false; foreach (var customAttr in typeDefinition.CustomAttributes) { switch (customAttr.CtorSource) { case CliMetadataCustomAttributeTypeTag.MethodDefinition: { var methodDef = (ICliMetadataMethodDefinitionTableRow)customAttr.Ctor; for (int i = 1; i <= metadataRoot.TableStream.TypeDefinitionTable.Count; i++) { var current = typeDefTable[i]; if (current.MethodStartIndex <= methodDef.Index) { if (i == metadataRoot.TableStream.TypeDefinitionTable.Count) { if (current.Name == "SuppressUnmanagedCodeSecurityAttribute" && current.Namespace == "System.Security") { hasSuppressionAttribute = true; goto breakLoop; } } else { var next = typeDefTable[i + 1]; if (next.MethodStartIndex <= methodDef.Index) { continue; } if (current.Name == "SuppressUnmanagedCodeSecurityAttribute" && current.Namespace == "System.Security") { hasSuppressionAttribute = true; goto breakLoop; } } } } } break; case CliMetadataCustomAttributeTypeTag.MemberReference: var methodRef = (ICliMetadataMemberReferenceTableRow)customAttr.Ctor; if (methodRef.ClassSource == CliMetadataMemberRefParentTag.TypeReference) { var typeRef = (ICliMetadataTypeRefTableRow)methodRef.Class; if (typeRef.Name == "SuppressUnmanagedCodeSecurityAttribute" && typeRef.Namespace == "System.Security") { hasSuppressionAttribute = true; goto breakLoop; } } else if (methodRef.ClassSource == CliMetadataMemberRefParentTag.TypeDefinition) { var typeDef = (ICliMetadataTypeDefinitionTableRow)methodRef.Class; if (typeDef.Name == "SuppressUnmanagedCodeSecurityAttribute" && typeDef.Namespace == "System.Security") { hasSuppressionAttribute = true; goto breakLoop; } } break; } } breakLoop: return(hasSuppressionAttribute); }
internal CliDelegateType(CliAssembly assembly, ICliMetadataTypeDefinitionTableRow metadataEntry) : base(assembly, metadataEntry) { }
public CliInterfaceType(CliAssembly owner, ICliMetadataTypeDefinitionTableRow metadataEntry) : base(owner, metadataEntry) { }