CompNode.py 2.27 KiB
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])