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

inherit set & contain set added fields

- add fields to contain set
- added inherit set
- quick fix for final method getClass in java.lang.Object that was
creating errors
parent d29a3eb0
No related branches found
No related tags found
No related merge requests found
...@@ -32,6 +32,9 @@ class FieldNode(ASTNode): ...@@ -32,6 +32,9 @@ class FieldNode(ASTNode):
self.children.append(self.variableDcl) self.children.append(self.variableDcl)
def __eq__(self, other):
return self.name == other.name
########################################################### ###########################################################
# method # method
......
...@@ -16,6 +16,7 @@ class ClassInterNode(ASTNode): ...@@ -16,6 +16,7 @@ class ClassInterNode(ASTNode):
self.canonName = "" self.canonName = ""
# sets # sets
self.inherits = []
self.contains = [] self.contains = []
self.super = [] self.super = []
...@@ -35,12 +36,18 @@ class ClassInterNode(ASTNode): ...@@ -35,12 +36,18 @@ class ClassInterNode(ASTNode):
key = (method.name, method.paramTypes) key = (method.name, method.paramTypes)
if key in unique: if key in unique:
raise Exception("ERROR: Class/Interface '{}' declares 2 methods with the same signature '{}'".format(self.name, key[0])) raise Exception("ERROR: Class/Interface '{}' declares 2 methods with the same signature '{}'".format(self.name, key[0]))
# quick fix for errors with java.lang.Object getClass function
if self.canonName != "java.lang.Object" and key[0] == "getClass" and not key[1]:
raise Exception("ERROR: Method 'getClass' in class/interface '{}' replaces java.lang.Object's final method".format(self.name, key[0]))
unique.append(key) unique.append(key)
self.contains = self.getContains([]) self.contains = self.getContains([])
# for c in self.contains: # add inherited methods/fields to environment
# self.env.addToEnv(c) for i in self.inherits:
self.env.addtoEnv(i)
# hierarchy: string[] # hierarchy: string[]
def getContains(self, hierarchy): def getContains(self, hierarchy):
...@@ -68,7 +75,7 @@ class ClassInterNode(ASTNode): ...@@ -68,7 +75,7 @@ class ClassInterNode(ASTNode):
for sic in superInterContains: for sic in superInterContains:
sicOverwritten = False sicOverwritten = False
for scc in superClassContains: for scc in superClassContains:
if sic == scc: if type(sic) == type(scc) and sic == scc:
safeReplace(sic, scc, self.name) safeReplace(sic, scc, self.name)
sicOverwritten = True sicOverwritten = True
break break
...@@ -88,22 +95,50 @@ class ClassInterNode(ASTNode): ...@@ -88,22 +95,50 @@ class ClassInterNode(ASTNode):
elif superInterContains: # if no superClass and we do have superInterContains elif superInterContains: # if no superClass and we do have superInterContains
superContains.extend(superInterContains) superContains.extend(superInterContains)
# ---- SUPER CONTAINS AGAINST SELF METHODS ---- # # ---- SUPER CONTAINS AGAINST SELF DECLARES ---- #
inherits = []
contains = [] contains = []
contains.extend(self.methods)
if hasattr(self, 'fields'):
contains.extend(self.fields)
for sc in superContains: for sc in superContains:
scOverwritten = False scOverwritten = False
for m in self.methods: for c in contains:
if sc == m: if type(sc) == type(c) and sc == c:
safeReplace(sc, m, self.name) safeReplace(sc, c, self.name)
scOverwritten = True scOverwritten = True
break break
if not scOverwritten: if not scOverwritten:
contains.append(sc) contains.append(sc)
inherits.append(sc)
if not self.inherits:
self.inherits.extend(inherits)
contains.extend(self.methods)
return contains return contains
def printSets(self):
print("---- Sets for Class/Interface {}".format(self.name))
print("> self.super")
for c in self.super:
print(c.name)
print("> self.inherits")
for i in self.inherits:
if isinstance(i, MethodNode):
print(i.name + "(" + i.paramTypes + ")")
if isinstance(i, FieldNode):
print(i.name)
print("> self.contains")
for c in self.contains:
if isinstance(c, MethodNode):
print(c.name + "(" + c.paramTypes + ")")
if isinstance(c, FieldNode):
print(c.name)
# class # class
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
...@@ -213,10 +248,11 @@ class ClassNode(ClassInterNode): ...@@ -213,10 +248,11 @@ class ClassNode(ClassInterNode):
# 10. A class that contains any abstract methods must be abstract. # 10. A class that contains any abstract methods must be abstract.
for con in self.contains: for con in self.contains:
if 'abstract' in con.mods and (not('abstract' in self.mods)): if isinstance(con, MethodNode):
raise Exception("ERROR: Non-abstract Class '{}' contains an abstract method".format(self.name)) if 'abstract' in con.mods and (not('abstract' in self.mods)):
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))
raise Exception("ERROR: Non-abstract Class '{}' contains an abstract method {}".format(self.name, con.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))
def getConstructor(self, argTypes): def getConstructor(self, argTypes):
for c in self.constructors: for c in self.constructors:
...@@ -287,23 +323,28 @@ class InterNode(ClassInterNode): ...@@ -287,23 +323,28 @@ class InterNode(ClassInterNode):
super().checkHierarchy() super().checkHierarchy()
# helper - replace method check # helper - replace method check
# curMethod/newMethod: MethodNode # cur/new: MethodNode or FieldNode
def safeReplace(curMethod, newMethod, className): def safeReplace(cur, new, className):
# getting here signifies that curMethod and newMethod have the same signature # getting here signifies that cur and new have the same signature (and are the same type)
methodOrField = "method"
if isinstance(cur, FieldNode):
methodOrField = "field"
# 11. A nonstatic method must not replace a static method # 11. A nonstatic method must not replace a static method
if 'static' in curMethod.mods and 'static' not in newMethod.mods: if 'static' in cur.mods and 'static' not in new.mods:
raise Exception("ERROR: Non-static method '{}' in class '{}' replaces static method '{}'".format(newMethod.name, className, curMethod.name)) raise Exception("ERROR: Non-static {0} '{1}' in class '{2}' replaces static {0}".format(methodOrField, new.name, className))
# 9. A class/interface must not contain two methods with the same signature but different return types # 9. A class/interface must not contain two methods with the same signature but different return types
# 12. A method must not replace a method with a different return type # 12. A method must not replace a method with a different return type
if curMethod.methodType != newMethod.methodType: if isinstance(cur, MethodNode) and cur.methodType != new.methodType:
raise Exception("ERROR: Method '{}' in class '{}' replaces a method with a different return type".format(className, curMethod.name)) raise Exception("ERROR: Method '{}' in class '{}' replaces method with a different return type".format(className, cur.name))
# 13. A protected method must not replace a public method # 13. A protected method must not replace a public method
if 'public' in curMethod.mods and 'protected' in newMethod.mods: if 'public' in cur.mods and 'protected' in new.mods:
raise Exception("ERROR: Protected method '{}' in class '{}' replaces public method '{}'".format(newMethod.name, className, curMethod.name)) raise Exception("ERROR: Protected {0} '{1}' in class '{2}' replaces public {0}".format(methodOrField, new.name, className))
# 14. A method must not replace a final method # 14. A method must not replace a final method
if 'final' in curMethod.mods: # quick fix for final method getClass from java.lang.Object
raise Exception("ERROR: Method '{}' in class '{}' replaces final method '{}'".format(curMethod.name, className, curMethod.name)) if 'final' in cur.mods and cur.name != "getClass":
raise Exception("ERROR: {} '{}' in class '{}' replaces final {}".format(methodOrField.capitalize(), cur.name, className, methodOrField))
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