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

ClassNode Hierarchy Checks

parent 9d05dc14
No related branches found
No related tags found
No related merge requests found
......@@ -34,6 +34,9 @@ class ASTNode():
def linkType(self):
pass
def checkHierarchy(self):
pass
def printNodePretty(self, prefix=0):
pp = pprint.PrettyPrinter(indent=prefix)
pp.pprint(self.__class__.__name__)
......
......@@ -30,6 +30,12 @@ def buildEnvAndLink(ASTs):
# t[1].buildEnvFromImports(globalEnv)
t[1].recurseAction("linkType")
# hierarchy checking
print('--------->>> hierarchy checking time!')
for t in ASTs:
# t[1].buildEnvFromImports(globalEnv)
t[1].recurseAction("checkHierarchy")
#######################################################
# # ast: Node
......
......@@ -66,14 +66,40 @@ class ClassNode(ASTNode):
# to use: self.env.getNode(name, namespace)
# print('hello here we go we are in classNode {}'.format(self.name))
if self.env is not None:
if self.superClass is not '':
if self.superClass:
newSuperClass = self.env.getNode(self.superClass, 'type')
self.superClass = newSuperClass
if self.superInter is not []:
if self.superInter:
for (index, inter) in enumerate(self.superInter):
newSuperInter = self.env.getNode(inter, 'type')
self.superInter[index] = newSuperInter
def checkHierarchy(self):
if self.superClass:
# A class must not extend an interface.
if isinstance(self.superClass, InterNode):
raise Exception("ERROR: Class {} extends interface {}".format(self.name, self.superClass.name))
# A class must not extend a final class.
if 'final' in self.superClass.mods:
raise Exception("ERROR: Class {} extends final class {}".format(self.name, self.superClass.name))
# A class must not implement a class.
if self.superInter:
for inter in self.superInter:
if isinstance(inter, ClassNode):
raise Exception("ERROR: Class {} implements class {}".format(self.name, inter.name))
# A class or interface must not declare two methods with the same signature (name and parameter types).
uniqueMethods = []
for method in self.methods:
key = (method.name, method.paramTypes)
if key in uniqueMethods:
raise Exception("ERROR: Class {} declares 2 methods with the same signature {}".format(self.name, key[0]))
uniqueMethods.append(key)
# A class or interface must not contain (declare or inherit) two methods with the same signature but different return types
# A class must not declare two constructors with the same parameter types
# A class that contains (declares or inherits) any abstract methods must be abstract.
def getConstructor(self, argTypes):
for c in self.constructors:
if c.paramTypes == argTypes:
......@@ -113,3 +139,11 @@ class InterNode(ASTNode):
env.addtoEnv(c)
self.env = env
return env
def linkType(self):
# link types to the actual nodes fom the environment (envs already created)
if self.env is not None:
if self.superInter:
for (index, inter) in enumerate(self.superInter):
newSuperInter = self.env.getNode(inter, 'type')
self.superInter[index] = newSuperInter
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