From 4186f53f0dadf3ef1d44a2658633f68f613a7ac1 Mon Sep 17 00:00:00 2001 From: Nicholas Robinson <nwrobins@edu.uwaterloo.ca> Date: Tue, 3 Mar 2020 00:41:22 -0500 Subject: [PATCH] class & interface sets - Test.py stop printing stars so much - ClassInterNode - create common fields in constructor - create super & contain set for Class & Interface --- Test.py | 2 +- TypeNodes.py | 62 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/Test.py b/Test.py index c2a3468..17be600 100644 --- a/Test.py +++ b/Test.py @@ -129,7 +129,7 @@ def run(testFiles): print("ERROR in Parsing: " + error.args[0]) # for n in error.args[1]: # the parse tree # print(n) - print("**********************************************************") + print("**********************************************************") continue parseTrees.append((f, tree)) diff --git a/TypeNodes.py b/TypeNodes.py index 4238dab..4581b10 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -2,9 +2,23 @@ from AST import ASTNode, getParseTreeNodes from MemberNodes import FieldNode, MethodNode from Environment import Env -# types: class , interface +# types: class, interface class ClassInterNode(ASTNode): + def __init__(self, parseTree, packageName): + self.parseTree = parseTree + self.packageName = packageName + self.name = '' + self.methods = [] + self.superInter = [] # class/Interface's name, then stores a pointer to the class after type linking + self.env = None + self.children = [] + self.canonName = "" + + # sets + self.contains = [] + self.super = [] + def checkHierarchy(self): # 3. An interface must not be repeated in an implements clause if self.superInter: @@ -26,7 +40,6 @@ class ClassInterNode(ASTNode): # 9. A class or interface must not contain (declare or inherit) two methods with the same signature but different return types # 11. A nonstatic method must not replace a static method # 13. A protected method must not replace a public method - return self.getContains([]) def getContains(self, hierarchy): @@ -66,18 +79,19 @@ class ClassInterNode(ASTNode): class ClassNode(ClassInterNode): # always list all fields in the init method to show the class structure def __init__(self, parseTree, packageName): - self.parseTree = parseTree - self.packageName = packageName - self.name = '' + super().__init__(parseTree, packageName) + # self.parseTree = parseTree + # self.packageName = packageName + # self.name = '' + # self.methods = [] + # self.superInter = [] + # self.env = None + # self.children = [] + # self.canonName = "" self.fields = [] - self.methods = [] self.constructors = [] self.mods = [] self.superClass = '' # these fields initially stores a string that represent the super - self.superInter = [] # class/Interface's name, then stores a pointer to the class after type linking - self.env = None - self.children = [] - self.canonName = "" for node in parseTree.children: if node.name == 'classMod': @@ -123,14 +137,20 @@ class ClassNode(ClassInterNode): def linkType(self): # link types to the actual nodes fom the environment (envs already created) + # also create super set if self.env is not None: if self.superClass: newSuperClass = self.env.getNode(self.superClass, 'type') self.superClass = newSuperClass + self.super.append(newSuperClass) if self.superInter: for (index, inter) in enumerate(self.superInter): newSuperInter = self.env.getNode(inter, 'type') self.superInter[index] = newSuperInter + self.super.append(newSuperInter) + if not self.super: + objectNode = self.env.getNode("java.lang.Object", 'type') + self.super.append(objectNode) def checkHierarchy(self): # 1. A class must not extend an interface. @@ -167,6 +187,8 @@ class ClassNode(ClassInterNode): raise Exception("ERROR: Non-abstract Class '{}' contains an abstract method".format(self.name)) if (not con.body) and (not ('native' in con.mods)) and (not ('abstract' in self.mods)) and (not (con in self.constructors)): raise Exception("ERROR: Non-abstract Class '{}' contains an abstract method {}".format(self.name, con.name)) + + self.contains = contains # hierarchy: string[] def getContains(self, hierarchy): @@ -215,14 +237,15 @@ class ClassNode(ClassInterNode): class InterNode(ClassInterNode): # always list all fields in the init method to show the class structure def __init__(self, parseTree, packageName): - self.parseTree = parseTree - self.packageName = packageName - self.name = '' - self.methods = [] - self.superInter = [] # list of strings of extendInterface's name, then stores a pointer to the node after type linking - self.env = None - self.children = [] - self.canonName = "" + super().__init__(parseTree, packageName) + # self.parseTree = parseTree + # self.packageName = packageName + # self.name = '' + # self.methods = [] + # self.superInter = [] + # self.env = None + # self.children = [] + # self.canonName = "" for node in parseTree.children: if node.name == 'ID': @@ -254,6 +277,7 @@ class InterNode(ClassInterNode): for (index, inter) in enumerate(self.superInter): newSuperInter = self.env.getNode(inter, 'type') self.superInter[index] = newSuperInter + self.super.append(newSuperInter) def checkHierarchy(self): # 5. An interface must not extend a class. @@ -268,7 +292,7 @@ class InterNode(ClassInterNode): unique.append(inter.name) # centralized point for overlapping class & interface logic - contains = super().checkHierarchy() + self.contains = super().checkHierarchy() # hierarchy: string[] def getContains(self, hierarchy): -- GitLab