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

class inherit java.lang.Object & removed contains

- if class extends no other class and implements no other interface, it
should inherit each method from java.lang.Object
- switched up a lot of " to be ', for my ocd lol
- removed contains attribute in ClassInterNode
parent 56fdcbfd
No related branches found
No related tags found
No related merge requests found
......@@ -13,11 +13,10 @@ class ClassInterNode(ASTNode):
self.superInter = [] # class/Interface's name, then stores a pointer to the class after type linking
self.env = None
self.children = []
self.canonName = ""
self.canonName = ''
# sets
self.inherits = []
self.contains = []
self.super = []
def checkHierarchy(self):
......@@ -38,12 +37,21 @@ class ClassInterNode(ASTNode):
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]:
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)
self.contains = self.getContains([])
contains = self.getContains([])
# 10. A class that contains any abstract methods must be abstract.
if isinstance(self, ClassNode):
for con in contains:
if isinstance(con, MethodNode):
if 'abstract' in con.mods and (not('abstract' in self.mods)):
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))
# add inherited methods/fields to environment
for i in self.inherits:
......@@ -84,13 +92,14 @@ class ClassInterNode(ASTNode):
superContains.extend(superClassContains)
# an interface without any super interfaces implicitly declares an abstract version of every public method in java.lang.Object
elif isinstance(self, InterNode) and not self.superInter:
objectInterface = self.env.getNode('java.lang.Object', 'type')
objectContains = objectInterface.getContains(hierarchy + [self.canonName])
for oc in objectContains:
if 'public' in oc.mods:
superContains.append(oc)
elif not self.superInter and self.canonName != 'java.lang.Object':
# an interface without any super interfaces implicitly declares an abstract version of every public method in java.lang.Object
# as well; every class inherits each method from java.lang.Object
objectInterface = self.env.getNode('java.lang.Object', 'type')
objectContains = objectInterface.getContains(hierarchy + [self.canonName])
for oc in objectContains:
if isinstance(self, ClassNode) or 'public' in oc.mods:
superContains.append(oc)
elif superInterContains: # if no superClass and we do have superInterContains
superContains.extend(superInterContains)
......@@ -132,13 +141,6 @@ class ClassInterNode(ASTNode):
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 ClassNode(ClassInterNode):
# always list all fields in the init method to show the class structure
......@@ -213,8 +215,8 @@ class ClassNode(ClassInterNode):
newSuperInter = self.env.getNode(inter, 'type')
self.superInter[index] = newSuperInter
self.super.append(newSuperInter)
if not self.super and self.canonName != "java.lang.Object":
objectNode = self.env.getNode("java.lang.Object", 'type')
if not self.super and self.canonName != 'java.lang.Object':
objectNode = self.env.getNode('java.lang.Object', 'type')
self.super.append(objectNode)
def checkHierarchy(self):
......@@ -243,17 +245,9 @@ class ClassNode(ClassInterNode):
raise Exception("ERROR: Class '{}' declares 2 constructors with the same parameter types".format(self.name))
unique.append(key)
# overlapping class/interface logic & sets self.contains
# overlapping class/interface logic
super().checkHierarchy()
# 10. A class that contains any abstract methods must be abstract.
for con in self.contains:
if isinstance(con, MethodNode):
if 'abstract' in con.mods and (not('abstract' in self.mods)):
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))
def getConstructor(self, argTypes):
for c in self.constructors:
if c.paramTypes == argTypes:
......@@ -319,7 +313,7 @@ class InterNode(ClassInterNode):
raise Exception("ERROR: Interface '{}' extends duplicate interfaces '{}'".format(self.name, inter.name))
unique.append(inter.name)
# centralized point for overlapping class & interface logic. Also sets self.contains
# centralized point for overlapping class & interface logic.
super().checkHierarchy()
# helper - replace method check
......@@ -327,9 +321,9 @@ class InterNode(ClassInterNode):
def safeReplace(cur, new, className):
# getting here signifies that cur and new have the same signature (and are the same type)
methodOrField = "method"
methodOrField = 'method'
if isinstance(cur, FieldNode):
methodOrField = "field"
methodOrField = 'field'
# 11. A nonstatic method must not replace a static method
if 'static' in cur.mods and 'static' not in new.mods:
......@@ -346,5 +340,5 @@ def safeReplace(cur, new, className):
# 14. A method must not replace a final method
# quick fix for final method getClass from java.lang.Object
if 'final' in cur.mods and cur.name != "getClass":
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