Esempio n. 1
0
            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);
            }
Esempio n. 2
0
        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
                 * */
            });
        }