/// <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; } }