Skip to content
Snippets Groups Projects
Commit 4186f53f authored by Nicholas Robinson's avatar Nicholas Robinson
Browse files

class & interface sets

- Test.py stop printing stars so much
- ClassInterNode - create common fields in constructor
- create super & contain set for Class & Interface
parent be3fa80b
No related branches found
No related tags found
No related merge requests found
...@@ -129,7 +129,7 @@ def run(testFiles): ...@@ -129,7 +129,7 @@ def run(testFiles):
print("ERROR in Parsing: " + error.args[0]) print("ERROR in Parsing: " + error.args[0])
# for n in error.args[1]: # the parse tree # for n in error.args[1]: # the parse tree
# print(n) # print(n)
print("**********************************************************") print("**********************************************************")
continue continue
parseTrees.append((f, tree)) parseTrees.append((f, tree))
......
...@@ -2,9 +2,23 @@ from AST import ASTNode, getParseTreeNodes ...@@ -2,9 +2,23 @@ from AST import ASTNode, getParseTreeNodes
from MemberNodes import FieldNode, MethodNode from MemberNodes import FieldNode, MethodNode
from Environment import Env from Environment import Env
# types: class , interface # types: class, interface
class ClassInterNode(ASTNode): 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): def checkHierarchy(self):
# 3. An interface must not be repeated in an implements clause # 3. An interface must not be repeated in an implements clause
if self.superInter: if self.superInter:
...@@ -26,7 +40,6 @@ class ClassInterNode(ASTNode): ...@@ -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 # 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 # 11. A nonstatic method must not replace a static method
# 13. A protected method must not replace a public method # 13. A protected method must not replace a public method
return self.getContains([]) return self.getContains([])
def getContains(self, hierarchy): def getContains(self, hierarchy):
...@@ -66,18 +79,19 @@ class ClassInterNode(ASTNode): ...@@ -66,18 +79,19 @@ class ClassInterNode(ASTNode):
class ClassNode(ClassInterNode): class ClassNode(ClassInterNode):
# always list all fields in the init method to show the class structure # always list all fields in the init method to show the class structure
def __init__(self, parseTree, packageName): def __init__(self, parseTree, packageName):
self.parseTree = parseTree super().__init__(parseTree, packageName)
self.packageName = packageName # self.parseTree = parseTree
self.name = '' # self.packageName = packageName
# self.name = ''
# self.methods = []
# self.superInter = []
# self.env = None
# self.children = []
# self.canonName = ""
self.fields = [] self.fields = []
self.methods = []
self.constructors = [] self.constructors = []
self.mods = [] self.mods = []
self.superClass = '' # these fields initially stores a string that represent the super 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: for node in parseTree.children:
if node.name == 'classMod': if node.name == 'classMod':
...@@ -123,14 +137,20 @@ class ClassNode(ClassInterNode): ...@@ -123,14 +137,20 @@ class ClassNode(ClassInterNode):
def linkType(self): def linkType(self):
# link types to the actual nodes fom the environment (envs already created) # link types to the actual nodes fom the environment (envs already created)
# also create super set
if self.env is not None: if self.env is not None:
if self.superClass: if self.superClass:
newSuperClass = self.env.getNode(self.superClass, 'type') newSuperClass = self.env.getNode(self.superClass, 'type')
self.superClass = newSuperClass self.superClass = newSuperClass
self.super.append(newSuperClass)
if self.superInter: if self.superInter:
for (index, inter) in enumerate(self.superInter): for (index, inter) in enumerate(self.superInter):
newSuperInter = self.env.getNode(inter, 'type') newSuperInter = self.env.getNode(inter, 'type')
self.superInter[index] = newSuperInter 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): def checkHierarchy(self):
# 1. A class must not extend an interface. # 1. A class must not extend an interface.
...@@ -167,6 +187,8 @@ class ClassNode(ClassInterNode): ...@@ -167,6 +187,8 @@ class ClassNode(ClassInterNode):
raise Exception("ERROR: Non-abstract Class '{}' contains an abstract method".format(self.name)) 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)): 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)) raise Exception("ERROR: Non-abstract Class '{}' contains an abstract method {}".format(self.name, con.name))
self.contains = contains
# hierarchy: string[] # hierarchy: string[]
def getContains(self, hierarchy): def getContains(self, hierarchy):
...@@ -215,14 +237,15 @@ class ClassNode(ClassInterNode): ...@@ -215,14 +237,15 @@ class ClassNode(ClassInterNode):
class InterNode(ClassInterNode): class InterNode(ClassInterNode):
# always list all fields in the init method to show the class structure # always list all fields in the init method to show the class structure
def __init__(self, parseTree, packageName): def __init__(self, parseTree, packageName):
self.parseTree = parseTree super().__init__(parseTree, packageName)
self.packageName = packageName # self.parseTree = parseTree
self.name = '' # self.packageName = packageName
self.methods = [] # self.name = ''
self.superInter = [] # list of strings of extendInterface's name, then stores a pointer to the node after type linking # self.methods = []
self.env = None # self.superInter = []
self.children = [] # self.env = None
self.canonName = "" # self.children = []
# self.canonName = ""
for node in parseTree.children: for node in parseTree.children:
if node.name == 'ID': if node.name == 'ID':
...@@ -254,6 +277,7 @@ class InterNode(ClassInterNode): ...@@ -254,6 +277,7 @@ class InterNode(ClassInterNode):
for (index, inter) in enumerate(self.superInter): for (index, inter) in enumerate(self.superInter):
newSuperInter = self.env.getNode(inter, 'type') newSuperInter = self.env.getNode(inter, 'type')
self.superInter[index] = newSuperInter self.superInter[index] = newSuperInter
self.super.append(newSuperInter)
def checkHierarchy(self): def checkHierarchy(self):
# 5. An interface must not extend a class. # 5. An interface must not extend a class.
...@@ -268,7 +292,7 @@ class InterNode(ClassInterNode): ...@@ -268,7 +292,7 @@ class InterNode(ClassInterNode):
unique.append(inter.name) unique.append(inter.name)
# centralized point for overlapping class & interface logic # centralized point for overlapping class & interface logic
contains = super().checkHierarchy() self.contains = super().checkHierarchy()
# hierarchy: string[] # hierarchy: string[]
def getContains(self, hierarchy): def getContains(self, hierarchy):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment