예제 #1
0
        /// <summary>
        /// Now walk the previously defined types and check each extends and implements
        /// </summary>
        public void WalkClassExtendation()
        {
            CheckerException exc = new CheckerException();

            reorderedTypes = new List <TreeNode>(types);

            for (int i = 0; i < types.Count; i++)
            {
                TreeNode n = types[i];
                currentType = (UserType)n.Entry.ReflectionObject;
                searchPath  = (List <string>)((TreeNode)n.Parent.Parent).Entry.ReflectionObject;
                searchPath.Add(currentType.Namespace);

                Qualifier        extends;
                List <Qualifier> implements;
                if (n.GetChild(2) != null)
                {
                    if (n.GetChild(2).Type == VnvdTreeWalker.EXTENDS)
                    {
                        extends = AbstractHelper.GetFullQualifier(n.GetChild(2).GetChild(0));
                        if (n.GetChild(3) != null && n.GetChild(3).Type == VnvdTreeWalker.IMPLEMENTS)
                        {
                            implements = AbstractHelper.GetImplements(n.GetChild(3));
                        }
                        else
                        {
                            implements = new List <Qualifier>();
                        }
                    }
                    else if (n.GetChild(2).Type == VnvdTreeWalker.IMPLEMENTS)
                    {
                        implements = AbstractHelper.GetImplements(n.GetChild(2));
                        extends    = new Qualifier()
                        {
                            "System", "Object"
                        };
                    }
                    else
                    {
                        extends = new Qualifier()
                        {
                            "System", "Object"
                        };
                        implements = new List <Qualifier>();
                    }
                }
                else
                {
                    extends = new Qualifier()
                    {
                        "System", "Object"
                    };
                    implements = new List <Qualifier>();
                }

                try
                {
                    IdEntry ext     = this.GetTypeIdEntry(extends.ToString());
                    Type    extType = (Type)ext.ReflectionObject;

                    if (currentType.IsInterface && ext.ReflectionObject != typeof(object) && !((Type)ext.ReflectionObject).IsInterface)
                    {
                        throw new CheckerException(n, "An interface can only extend another interface, not a class: " + ((Type)ext.ReflectionObject).FullName);
                    }
                    if (!currentType.IsInterface && !extType.IsClass)
                    {
                        throw new CheckerException(n, "Cannot extend interface or value type " + extType.FullName);
                    }
                    if (extType.IsSubclassOf(currentType))
                    {
                        throw new CheckerException(n, "Circular extendation detected at " + extType.FullName + " and " + currentType.FullName);
                    }
                    if (extType.IsSealed)
                    {
                        throw new CheckerException(n, "Cannot extend types marked as sealed: " + extType.FullName);
                    }
                    if (currentType.IsInterface && ext.ReflectionObject != typeof(object))
                    {
                        implements.Add(extends);
                    }
                    else if (!currentType.IsInterface && !currentType.IsEnum)
                    {
                        currentType.SetBaseType(ext);
                    }

                    for (int j = i + 1; j < reorderedTypes.Count; j++)
                    {
                        if (reorderedTypes[j].Entry.ReflectionObject == ext.ReflectionObject)
                        {
                            TreeNode temp = reorderedTypes[j];
                            reorderedTypes.Remove(temp);
                            reorderedTypes.Insert(i, temp);
                        }
                    }
                }
                catch (CheckerException ex)
                {
                    exc.AddError(n, ex.GetLastError().Second);
                }

                try
                {
                    foreach (var implement in implements)
                    {
                        IdEntry imple = this.GetTypeIdEntry(implement.ToString());
                        Type    t     = (Type)imple.ReflectionObject;
                        if (!t.IsInterface)
                        {
                            throw new CheckerException(n, "Cannot implement a class or value type " + t.FullName);
                        }
                        currentType.AddInterface(imple);
                    }
                }
                catch (CheckerException ex)
                {
                    exc.AddError(n, ex.GetLastError().Second);
                }

                this.searchPath.Remove(currentType.Namespace);
            }

            if (exc.ErrorCount > 0)
            {
                throw exc;
            }
        }