public override bool Equals(object obj) { if (obj is IdEntry) { IdEntry o = (IdEntry)obj; return(o.ReflectionObject == this.ReflectionObject && o.Level == this.Level && o.Node == this.Node); } return(false); }
private UserField DefineField(UserType type, String name, List <string> modifiers, String _return) { FieldAttributes attr = 0; foreach (String s in modifiers) { attr |= (FieldAttributes)Enum.Parse(typeof(FieldAttributes), s, true); } IdEntry ret = this.GetTypeIdEntry(_return); return(type.DefineField(name, attr, ret)); }
/// <summary> /// Enters an id together with an entry into this SymbolTable using the /// current scope level. The entry's level is set to this.Level /// </summary> /// <param name="id">The identifier to enter</param> /// <param name="entry">The entry to enter</param> public void Enter(String id, IdEntry entry) { entry.Level = this.CurrentLevel; if (this.cache.Peek().Contains(id)) { throw new SymbolTableException("Variable already declared for current scope: " + id); } if (!entries.ContainsKey(id)) { entries[id] = new Stack <IdEntry>(); } cache.Peek().Add(id); entries[id].Push(entry); }
private UserMethod DefineInterfaceMethod(UserType type, string name, string _return, string[] parTypes, string[] parNames) { MethodAttributes attr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Abstract | MethodAttributes.NewSlot | MethodAttributes.Virtual; IdEntry[] pars = new IdEntry[parTypes.Length]; for (int i = 0; i < parTypes.Length; i++) { pars[i] = this.GetTypeIdEntry(parTypes[i]); } IdEntry ret = KeywordToType(_return) != null ? new IdEntry() { ReflectionObject = KeywordToType(_return) } : this.GetTypeIdEntry(_return); UserMethod metb = type.DefineMethod(name, attr, ret, pars, parNames); return(metb); }
private UserConstructor DefineConstructor(UserType type, List <string> modifiers, String[] parTypes, String[] parNames) { MethodAttributes attr = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; foreach (String s in modifiers) { attr |= (MethodAttributes)Enum.Parse(typeof(MethodAttributes), s, true); } IdEntry[] pars = new IdEntry[parTypes.Length]; for (int i = 0; i < parTypes.Length; i++) { pars[i] = this.GetTypeIdEntry(parTypes[i]); } UserConstructor cb = type.DefineConstructor(attr, pars, parNames); return(cb); }
private UserMethod DefineMethod(UserType type, String name, List <string> modifiers, String _return, String[] parTypes, String[] parNames) { bool overrid = modifiers.Remove("override"); if (overrid) { modifiers.Add("virtual"); } if (!type.IsAbstract && modifiers.Contains("abstract")) { throw new CheckerException("Cannot declare abstract method " + name + " in a non-abstract class: " + type.Name); } if (modifiers.Contains("abstract")) { modifiers.Add("virtual"); } MethodAttributes attr = MethodAttributes.HideBySig; foreach (String s in modifiers) { attr |= (MethodAttributes)Enum.Parse(typeof(MethodAttributes), s, true); } IdEntry[] pars = new IdEntry[parTypes.Length]; for (int i = 0; i < parTypes.Length; i++) { pars[i] = this.GetTypeIdEntry(parTypes[i]); } IdEntry ret = KeywordToType(_return) != null ? new IdEntry() { ReflectionObject = KeywordToType(_return) } : this.GetTypeIdEntry(_return); if (overrid) { MethodInfo m = type.BaseType.GetMethod(name, BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, LibraryChecker.ToArray <Type>(pars), null); if (m == null || m.ReturnType != ret.ReflectionObject) { throw new CheckerException("No suitable method found to override: " + name); } if (!m.IsVirtual) { throw new CheckerException("Cannot override a non-virtual method: " + m.Name); } } else { MethodInfo m = type.GetMethod(name, BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, LibraryChecker.ToArray <Type>(pars), null); if (m != null) { throw new CheckerException("Method already exists: " + m.Name); } if (type.GetInterfaceMethod(name, LibraryChecker.ToArray <Type>(pars)) != null) { attr |= MethodAttributes.NewSlot | MethodAttributes.Virtual; } } UserMethod metb = type.DefineMethod(name, attr, ret, pars, parNames); return(metb); }
/// <summary> /// Finally walk all members of the classes and interfaces. Methods etc. are defined here /// </summary> public void WalkClassMembers() { CheckerException exc = new CheckerException(); bool hasMain = false; for (int i = 0; i < reorderedTypes.Count; i++) { TreeNode n = reorderedTypes[i]; currentType = (UserType)n.Entry.ReflectionObject; searchPath = (List <string>)((TreeNode)n.Parent.Parent).Entry.ReflectionObject; this.searchPath.Add(currentType.Namespace); foreach (TreeNode n2 in n.Children) { try { if (n2.Type == VnvdTreeWalker.FIELD) { n2.EntryType = EntryType.Variable; IdEntry entry = new IdEntry(); entry.Node = n2; string ret = n2.GetChild(1).Type == VnvdTreeWalker.FQUALIFIER ? AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString() : n2.GetChild(1).Text; UserField field = DefineField(currentType, n2.GetChild(2).Text, AbstractHelper.GetModifiers(n2.GetChild(0)), ret); field.Entry = entry; entry.ReflectionObject = field; n2.Entry = entry; } else if (n2.Type == VnvdTreeWalker.CONSTRUCTOR) { n2.EntryType = EntryType.Constructor; IdEntry entry = new IdEntry(); entry.Node = n2; String[] parNames = AbstractHelper.GetParameterNames(n2.GetChild(2)); String[] parTypes = AbstractHelper.GetParameterTypes(n2.GetChild(2)); UserConstructor cons = DefineConstructor(currentType, AbstractHelper.GetModifiers(n2.GetChild(0)), parTypes, parNames); cons.Entry = entry; entry.ReflectionObject = cons; n2.Entry = entry; } else if (n2.Type == VnvdTreeWalker.METHOD) { n2.EntryType = EntryType.Method; IdEntry entry = new IdEntry(); entry.Node = n2; String[] parNames = AbstractHelper.GetParameterNames(n2.GetChild(3)); String[] parTypes = AbstractHelper.GetParameterTypes(n2.GetChild(3)); string ret = n2.GetChild(1).Type == VnvdTreeWalker.FQUALIFIER ? AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString() : n2.GetChild(1).Text; UserMethod met = DefineMethod(currentType, n2.GetChild(2).Text, AbstractHelper.GetModifiers(n2.GetChild(0)), ret, parTypes, parNames); if (met.Name.Equals(GeneratorManual.MAINMETHOD)) { if (hasMain) { throw new CheckerException(n2, "Duplicate main method."); } hasMain = true; } met.Entry = entry; entry.ReflectionObject = met; n2.Entry = entry; } else if (n2.Type == VnvdTreeWalker.IMETHOD) { n2.EntryType = EntryType.Method; IdEntry entry = new IdEntry(); entry.Node = n2; String[] parNames = AbstractHelper.GetParameterNames(n2.GetChild(2)); String[] parTypes = AbstractHelper.GetParameterTypes(n2.GetChild(2)); string ret = n2.GetChild(0).Type == VnvdTreeWalker.FQUALIFIER ? AbstractHelper.GetFullQualifier(n2.GetChild(0)).ToString() : n2.GetChild(0).Text; UserMethod met = DefineInterfaceMethod(currentType, n2.GetChild(1).Text, ret, parTypes, parNames); met.Entry = entry; entry.ReflectionObject = met; n2.Entry = entry; } else if (n2.Type == VnvdTreeWalker.SCONSTRUCTOR) { n2.EntryType = EntryType.Constructor; IdEntry entry = new IdEntry(); entry.Node = n2; UserConstructor cons = currentType.DefineTypeInitializer(); cons.Entry = entry; entry.ReflectionObject = cons; n2.Entry = entry; } else if (n2.Type == VnvdTreeWalker.ENUMOPTION) { n2.EntryType = EntryType.Variable; IdEntry entry = new IdEntry(); entry.Node = n2; UserField option = ((UserEnum)currentType).DefineOption(n2.GetChild(0).Text); option.Entry = entry; entry.ReflectionObject = option; n2.Entry = entry; } } catch (CheckerException ex) { exc.AddError(n2, ex.GetLastError().Second); } catch (InvalidOperationException ex) { exc.AddError(n2, ex.Message); } catch (SymbolTableException ex) { exc.AddError(n2, ex.Message); } } if (currentType.IsClass && currentType.GetConstructors().Length == 0) { UserConstructor uc = DefineConstructor(currentType, new List <string>() { "public" }, new string[] {}, new string[] {}); uc.Entry = new IdEntry(); uc.Entry.ReflectionObject = uc; } try { if (!currentType.IsInterface) { currentType.CheckInterfaces(); } } catch (CheckerException ex) { exc.AddError(n, ex.GetLastError().Second); } this.searchPath.Remove(currentType.Namespace); } if (exc.ErrorCount > 0) { throw exc; } }
/// <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; } }