diff --git a/NameNode.py b/NameNode.py index b89110fdae7d6959e4dc5fefc54a731bade93974..141b789454f2bf8c26b4ad99c1ef0ad5429a7fe9 100644 --- a/NameNode.py +++ b/NameNode.py @@ -118,7 +118,12 @@ class NameNode(ASTNode): typeFieldNode = typeNode.env.getNode(staticFieldName, "fieldDcl") if "static" in typeFieldNode.mods: - self.prefixLink = typeFieldNode.variableDcl.dclType.myType.typePointer + self.prefixLink = typeFieldNode.variableDcl + + # if it is primitive, then we leave it as a VarDclNode + if not self.prefixLink.dclType.myType.isPrimitive: + self.prefixLink = self.prefixLink.dclType.myType.typePointer + self.prefix = currPrefix + "." + staticFieldName self.IDs = self.IDs[index+2:] return True @@ -163,7 +168,6 @@ class NameNode(ASTNode): # type checking: go through each prefix and determine what type it is, get that type, and check if that type contains the next access # eg: a.b.c.d - disambigName would have already determined what the heck the shortest prefix is for this, so take that (let's say it's a.b) then check type c, see if it contains d, then get d return type and add it to self.myType - if not self.prefixLink or self.prefixLink == 'contain': self.prefixLink = self diff --git a/TypeNodes.py b/TypeNodes.py index 1f793e69bcb6cb2925b6ba7085c18db51a4fcac9..85d32ee14c4176b520934e3fab373fb9a3e17d92 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -85,9 +85,13 @@ class ClassInterNode(ASTNode): sicOverwritten = False for scc in superClassContains: if type(sic) == type(scc) and sic == scc: - safeReplace(sic, scc, self.name) - sicOverwritten = True - break + # sic is implicitly abstract, if scc is abstract, then it is not replacing sic + # Thus scc will be added to superContains as well (having 1+ abstract methods with same signiture is fine) + # Example: Tests/A3/J1_supermethod_override11/ + if 'abstract' not in scc.mods: + safeReplace(sic, scc, self.name) + sicOverwritten = True + break if not sicOverwritten: superContains.append(sic) @@ -319,18 +323,18 @@ def safeReplace(cur, new, className): # 11. A nonstatic method must not replace a static method if 'static' in cur.mods and 'static' not in new.mods: - raise Exception("ERROR: Non-static {0} '{1}' in class '{2}' replaces static {0}".format(methodOrField, new.name, className)) + raise Exception("ERROR: In class {0}, non-static {1} '{2}' in class '{3}' replaces static {1} in class/interface {3}".format(className, methodOrField, new.name, new.typeName, cur.typeName)) # 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 if isinstance(cur, MethodNode) and cur.methodType != new.methodType: - raise Exception("ERROR: Method '{}' in class '{}' replaces method with a different return type".format(className, cur.name)) + raise Exception("ERROR: In class {}, method '{}' in class '{}' replaces method with a different return type in class/interface {}".format(className, new.name, new.typeName, cur.typeName)) # 13. A protected method must not replace a public method if 'public' in cur.mods and 'protected' in new.mods: - raise Exception("ERROR: Protected {0} '{1}' in class '{2}' replaces public {0}".format(methodOrField, new.name, className)) + raise Exception("ERROR: In class {0}, protected {1} '{2}' from class '{3}' replaces public {1} from class/interface {4}".format(className, methodOrField, new.name, new.typeName, cur.typeName)) # 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': - raise Exception("ERROR: {} '{}' in class '{}' replaces final {}".format(methodOrField.capitalize(), cur.name, className, methodOrField)) + raise Exception("ERROR: In class {0}, {1} '{2}' in class '{3}' replaces final {1} in class/interface {4}".format(className, methodOrField, new.name, new.typeName, cur.typeName))