Skip to content
Snippets Groups Projects
Commit 2e9cc435 authored by Xun Yang's avatar Xun Yang
Browse files

add order to class members for forward reference checking

parent 5ba347bf
No related branches found
No related tags found
No related merge requests found
...@@ -158,7 +158,7 @@ class ArrayCreateNode(ASTNode): ...@@ -158,7 +158,7 @@ class ArrayCreateNode(ASTNode):
self.children.append(self.arrayType) self.children.append(self.arrayType)
self.children.append(self.arraySize) self.children.append(self.arraySize)
def disambigName(self): def disambigName(self):
helperDisambigName(self.arraySize) helperDisambigName(self.arraySize)
...@@ -183,7 +183,7 @@ class AssignNode(ASTNode): ...@@ -183,7 +183,7 @@ class AssignNode(ASTNode):
self.children.append(self.right) self.children.append(self.right)
self.children.append(self.left) self.children.append(self.left)
def disambigName(self): def disambigName(self):
helperDisambigName(self.right) helperDisambigName(self.right)
helperDisambigName(self.left) helperDisambigName(self.left)
...@@ -208,10 +208,10 @@ class CastNode(ASTNode): ...@@ -208,10 +208,10 @@ class CastNode(ASTNode):
self.children.append(self.left) self.children.append(self.left)
self.children.append(self.right) self.children.append(self.right)
def disambigName(self): def disambigName(self):
helperDisambigName(self.left) helperDisambigName(self.left)
helperDisambigName(self.right) helperDisambigName(self.right)
################################################################################### ###################################################################################
# classInstanceCreate unqualCreate # classInstanceCreate unqualCreate
...@@ -271,7 +271,7 @@ class ExprNode(ASTNode): ...@@ -271,7 +271,7 @@ class ExprNode(ASTNode):
# make a TypeStruct node and populate myType field for self # make a TypeStruct node and populate myType field for self
super().checkType() # check children's type first to populate their myType field super().checkType() # check children's type first to populate their myType field
print(self.left)
# Unary operations: # Unary operations:
if not self.left: if not self.left:
if self.op == '-' and self.right.myType.isNum(): if self.op == '-' and self.right.myType.isNum():
...@@ -336,7 +336,7 @@ class FieldAccessNode(ASTNode): ...@@ -336,7 +336,7 @@ class FieldAccessNode(ASTNode):
self.ID = NameNode(parseTree.children[2], False, typeName) self.ID = NameNode(parseTree.children[2], False, typeName)
self.children.append(self.primary) self.children.append(self.primary)
def disambigName(self): def disambigName(self):
if not self.primary: # this implies that the ID has nothing that comes before it if not self.primary: # this implies that the ID has nothing that comes before it
helperDisambigName(self.ID) helperDisambigName(self.ID)
......
...@@ -9,7 +9,7 @@ from collections import OrderedDict ...@@ -9,7 +9,7 @@ from collections import OrderedDict
# field # field
class FieldNode(ASTNode): class FieldNode(ASTNode):
# 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, typeName): def __init__(self, parseTree, typeName, order):
self.parseTree = parseTree self.parseTree = parseTree
self.name = '' self.name = ''
self.variableDcl = None self.variableDcl = None
...@@ -17,6 +17,7 @@ class FieldNode(ASTNode): ...@@ -17,6 +17,7 @@ class FieldNode(ASTNode):
self.env = None self.env = None
self.children = [] self.children = []
self.typeName = typeName self.typeName = typeName
self.order = order
# get field name # get field name
nameNodes = getParseTreeNodes(['ID'], parseTree, ['params', 'type', 'methodBody']) nameNodes = getParseTreeNodes(['ID'], parseTree, ['params', 'type', 'methodBody'])
...@@ -41,7 +42,7 @@ class FieldNode(ASTNode): ...@@ -41,7 +42,7 @@ class FieldNode(ASTNode):
# method # method
class MethodNode(ASTNode): class MethodNode(ASTNode):
# 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, typeName): def __init__(self, parseTree, typeName, order):
self.parseTree = parseTree self.parseTree = parseTree
self.name = '' self.name = ''
self.methodType = '' self.methodType = ''
...@@ -52,6 +53,7 @@ class MethodNode(ASTNode): ...@@ -52,6 +53,7 @@ class MethodNode(ASTNode):
self.env = None self.env = None
self.children = [] self.children = []
self.typeName = typeName self.typeName = typeName
self.order = order
# get method name # get method name
nameNodes = getParseTreeNodes(['ID'], parseTree, ['params', 'type', 'methodBody']) nameNodes = getParseTreeNodes(['ID'], parseTree, ['params', 'type', 'methodBody'])
......
...@@ -47,7 +47,7 @@ def a2Multiple(): ...@@ -47,7 +47,7 @@ def a2Multiple():
for c in testCases: for c in testCases:
# get all files from stdlib folder # get all files from stdlib folder
testFiles = [join(dp, f) for dp, dn, filenames in walk('stdlib/2.0/java/') for f in filenames] testFiles = [join(dp, f) for dp, dn, filenames in walk('stdlib/2.0/java/') for f in filenames]
if '.java' in c: if '.java' in c:
# add this one file # add this one file
testFiles.append(c) testFiles.append(c)
...@@ -82,7 +82,7 @@ def run(testFiles): ...@@ -82,7 +82,7 @@ def run(testFiles):
parseTrees = [] parseTrees = []
for f in testFiles: for f in testFiles:
print(f) # print(f)
if f.split("/")[-1] == ".DS_Store": if f.split("/")[-1] == ".DS_Store":
continue continue
content = open(f, "r").read() content = open(f, "r").read()
...@@ -142,7 +142,7 @@ def run(testFiles): ...@@ -142,7 +142,7 @@ def run(testFiles):
# except Exception as e: # except Exception as e:
# print("ERROR at AST building for file {}".format(f)) # print("ERROR at AST building for file {}".format(f))
# traceback.print_stack() # traceback.print_stack()
# return "building AST: " + e.args[0] # return "building AST: " + e.args[0]
ASTs = astBuild(parseTrees) ASTs = astBuild(parseTrees)
# for (n, t) in ASTs: # for (n, t) in ASTs:
...@@ -150,7 +150,7 @@ def run(testFiles): ...@@ -150,7 +150,7 @@ def run(testFiles):
# print("--------------------") # print("--------------------")
# t.printTree() # t.printTree()
# print("\n \n\n \n") # print("\n \n\n \n")
try: try:
buildEnvAndLink(ASTs) buildEnvAndLink(ASTs)
except Exception as e: except Exception as e:
...@@ -160,11 +160,11 @@ def run(testFiles): ...@@ -160,11 +160,11 @@ def run(testFiles):
return "buildEnvAndLink: " + e.args[0] return "buildEnvAndLink: " + e.args[0]
# print("<<<<------- after buildEnvAndLink -------->>>>>>") # print("<<<<------- after buildEnvAndLink -------->>>>>>")
for (n, t) in ASTs: # for (n, t) in ASTs:
print(n) # print(n)
print("--------------------") # print("--------------------")
t.printTree() # t.printTree()
print("\n \n\n \n") # print("\n \n\n \n")
# try: # try:
# disamiguateAndTypeChecking(ASTs) # disamiguateAndTypeChecking(ASTs)
......
...@@ -72,7 +72,7 @@ class ClassInterNode(ASTNode): ...@@ -72,7 +72,7 @@ class ClassInterNode(ASTNode):
# parent interface methods # parent interface methods
for inter in self.superInter: for inter in self.superInter:
superInterContains.extend(inter.getContains(hierarchy + [self.canonName])) superInterContains.extend(inter.getContains(hierarchy + [self.canonName]))
# parent class methods # parent class methods
if hasattr(self, 'superClass') and self.superClass: if hasattr(self, 'superClass') and self.superClass:
superClassContains.extend(self.superClass.getContains(hierarchy + [self.canonName])) superClassContains.extend(self.superClass.getContains(hierarchy + [self.canonName]))
...@@ -89,7 +89,7 @@ class ClassInterNode(ASTNode): ...@@ -89,7 +89,7 @@ class ClassInterNode(ASTNode):
break break
if not sicOverwritten: if not sicOverwritten:
superContains.append(sic) superContains.append(sic)
superContains.extend(superClassContains) superContains.extend(superClassContains)
elif not self.superInter and self.canonName != 'java.lang.Object': elif not self.superInter and self.canonName != 'java.lang.Object':
...@@ -176,17 +176,17 @@ class ClassNode(ClassInterNode): ...@@ -176,17 +176,17 @@ class ClassNode(ClassInterNode):
self.superInter.append(n.lex) self.superInter.append(n.lex)
elif node.name == 'classBody': elif node.name == 'classBody':
fieldNodes = getParseTreeNodes(['fieldDcl'], node, ['constructorDcl', 'methodDcl']) order = 0
for f in fieldNodes: memberDcls = getParseTreeNodes(['classBodyDcl'], node, ['constructorDcl', 'methodDcl', 'fieldDcl'])
self.fields.append(FieldNode(f, self.name))
for m in memberDcls:
constructorDcl = getParseTreeNodes(['constructorDcl'], node, ['fieldDcl', 'methodDcl']) if m.children[0].name == 'fieldDcl':
for c in constructorDcl: self.fields.append(FieldNode(m.children[0], self.name, order))
self.constructors.append(MethodNode(c, self.name)) elif m.children[0].name == 'methodDcl':
self.methods.append(MethodNode(m.children[0], self.name, order))
methodNodes = getParseTreeNodes(['methodDcl'], node, ['constructorDcl', 'fieldDcl']) elif m.children[0].name == 'constructorDcl':
for m in methodNodes: self.constructors.append(MethodNode(m.children[0], self.name, order))
self.methods.append(MethodNode(m, self.name)) order += 1
self.canonName = self.packageName + '.' + self.name self.canonName = self.packageName + '.' + self.name
self.children += self.fields + self.methods + self.constructors self.children += self.fields + self.methods + self.constructors
...@@ -280,7 +280,7 @@ class InterNode(ClassInterNode): ...@@ -280,7 +280,7 @@ class InterNode(ClassInterNode):
elif node.name == 'interfaceBody': elif node.name == 'interfaceBody':
nodes = getParseTreeNodes(['interfaceMethodDcl'], node) nodes = getParseTreeNodes(['interfaceMethodDcl'], node)
for n in nodes: for n in nodes:
self.methods.append(MethodNode(n, self.name)) self.methods.append(MethodNode(n, self.name, 0)) # order = 0 since no method body in interface needs to be checked
self.canonName = self.packageName + '.' + self.name self.canonName = self.packageName + '.' + self.name
self.children.extend(self.methods) self.children.extend(self.methods)
...@@ -337,7 +337,7 @@ def safeReplace(cur, new, className): ...@@ -337,7 +337,7 @@ def safeReplace(cur, new, className):
# 13. A protected method must not replace a public method # 13. A protected method must not replace a public method
if 'public' in cur.mods and 'protected' in new.mods: 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: 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
# quick fix for final method getClass from java.lang.Object # 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':
......
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