from AST import ASTNode, getParseTreeNodes from TypeNodes import InterNode, ClassNode from Environment import Env, CompEnv # compilation unit class CompNode(ASTNode): # always list all fields in the init method to show the class structure def __init__(self, parseTree): self.parseTree = parseTree self.packageName = '' self.importNames = [] self.env = None self.typeDcl = None self.children = [] for node in parseTree.children: if node.name == 'packageDcl': nameNodes = getParseTreeNodes(['ID', 'COMPID'], node) for n in nameNodes: self.packageName = n.lex elif node.name == 'importDcls': nameNodes = getParseTreeNodes(['ID', 'COMPID', 'IMPORTALL'], node) for n in nameNodes: self.importNames.append(n.lex) elif node.name == 'topDcls': typeNode = getParseTreeNodes('classDcl', node) if not typeNode: typeNode = getParseTreeNodes('interfaceDcl', node) self.typeDcl = InterNode(typeNode[0], self.packageName) else: self.typeDcl = ClassNode(typeNode[0], self.packageName) # always populate the children list self.children.append(self.typeDcl) def buildEnv(self, parentEnv): env = CompEnv(parentEnv, self.importNames, self.packageName) env.addtoEnv(self.typeDcl) self.env = env return env def linkType(self): seenImports = set() # check for repeated Imports, which are allowed for i in self.importNames: if ".*" not in i: # add single Type import to self.env under their simple name sImport = self.env.getNode(i, "type") if not sImport: raise Exception("ERROR: Importing non existing type.") if i not in seenImports and sImport != self.typeDcl: # can import self self.env.addtoEnv(sImport) seenImports.add(i) else: # check if on demand import package exists # remove last two char .* to get package name p = self.env.parentEnv.ExistPackage(i[:-2])