Commit 3279cb03 authored by Jack Jansen's avatar Jack Jansen

Turned the suite compiler into an object.

parent 18c9b139
......@@ -467,17 +467,16 @@ def compileaete(aete, resinfo, fname, output=None, basepkgname=None,
allprecompinfo = []
allsuites = []
for suite in suites:
code, suite, pathname, modname, precompinfo = precompilesuite(suite, basepackage,
output=output, edit_modnames=edit_modnames, verbose=verbose)
compiler = SuiteCompiler(suite, basepackage, output, edit_modnames, verbose)
code, modname, precompinfo = compiler.precompilesuite()
if not code:
continue
allprecompinfo = allprecompinfo + precompinfo
suiteinfo = suite, pathname, modname
suitelist.append((code, modname))
allsuites.append(suiteinfo)
for suiteinfo in allsuites:
compilesuite(suiteinfo, major, minor, language, script, fname, basepackage,
allprecompinfo, interact=(edit_modnames is None), verbose=verbose)
allsuites.append(compiler)
for compiler in allsuites:
compiler.compilesuite(major, minor, language, script, fname, allprecompinfo)
initfilename = os.path.join(output, '__init__.py')
fp = open(initfilename, 'w')
MacOS.SetCreatorAndType(initfilename, 'Pyth', 'TEXT')
......@@ -541,46 +540,62 @@ def compileaete(aete, resinfo, fname, output=None, basepkgname=None,
fp.write("\t_moduleName = '%s'\n\n"%packagename)
fp.close()
def precompilesuite(suite, basepackage=None, edit_modnames=None, output=None,
verbose=None):
class SuiteCompiler:
def __init__(self, suite, basepackage, output, edit_modnames, verbose):
self.suite = suite
self.basepackage = basepackage
self.edit_modnames = edit_modnames
self.output = output
self.verbose = verbose
# Set by precompilesuite
self.pathname = None
self.modname = None
# Set by compilesuite
self.fp = None
self.basemodule = None
self.enumsneeded = {}
def precompilesuite(self):
"""Parse a single suite without generating the output. This step is needed
so we can resolve recursive references by suites to enums/comps/etc declared
in other suites"""
[name, desc, code, level, version, events, classes, comps, enums] = suite
[name, desc, code, level, version, events, classes, comps, enums] = self.suite
modname = identify(name)
if len(modname) > 28:
modname = modname[:27]
if edit_modnames is None:
pathname = EasyDialogs.AskFileForSave(message='Python output file',
if self.edit_modnames is None:
self.pathname = EasyDialogs.AskFileForSave(message='Python output file',
savedFileName=modname+'.py')
else:
for old, new in edit_modnames:
for old, new in self.edit_modnames:
if old == modname:
modname = new
if modname:
pathname = os.path.join(output, modname + '.py')
self.pathname = os.path.join(self.output, modname + '.py')
else:
pathname = None
if not pathname:
return None, None, None, None, None
self.pathname = None
if not self.pathname:
return None, None, None
modname = os.path.splitext(os.path.split(pathname)[1])[0]
self.modname = os.path.splitext(os.path.split(self.pathname)[1])[0]
if basepackage and basepackage._code_to_module.has_key(code):
if self.basepackage and self.basepackage._code_to_module.has_key(code):
# We are an extension of a baseclass (usually an application extending
# Standard_Suite or so). Import everything from our base module
basemodule = basepackage._code_to_module[code]
basemodule = self.basepackage._code_to_module[code]
else:
# We are not an extension.
basemodule = None
enumsneeded = {}
self.enumsneeded = {}
for event in events:
findenumsinevent(event, enumsneeded)
self.findenumsinevent(event)
objc = ObjectCompiler(None, basemodule, interact=(edit_modnames is None),
verbose=verbose)
objc = ObjectCompiler(None, basemodule, interact=(self.edit_modnames is None),
verbose=self.verbose)
for cls in classes:
objc.compileclass(cls)
for cls in classes:
......@@ -590,19 +605,18 @@ def precompilesuite(suite, basepackage=None, edit_modnames=None, output=None,
for enum in enums:
objc.compileenumeration(enum)
for enum in enumsneeded.keys():
for enum in self.enumsneeded.keys():
objc.checkforenum(enum)
objc.dumpindex()
precompinfo = objc.getprecompinfo(modname)
precompinfo = objc.getprecompinfo(self.modname)
return code, suite, pathname, modname, precompinfo
return code, self.modname, precompinfo
def compilesuite((suite, pathname, modname), major, minor, language, script,
fname, basepackage, precompinfo, interact=1, verbose=None):
def compilesuite(self, major, minor, language, script, fname, precompinfo):
"""Generate code for a single suite"""
[name, desc, code, level, version, events, classes, comps, enums] = suite
[name, desc, code, level, version, events, classes, comps, enums] = self.suite
# Sort various lists, so re-generated source is easier compared
def class_sorter(k1, k2):
"""Sort classes by code, and make sure main class sorts before synonyms"""
......@@ -622,8 +636,8 @@ def compilesuite((suite, pathname, modname), major, minor, language, script,
comps.sort()
enums.sort()
fp = open(pathname, 'w')
MacOS.SetCreatorAndType(pathname, 'Pyth', 'TEXT')
self.fp = fp = open(self.pathname, 'w')
MacOS.SetCreatorAndType(self.pathname, 'Pyth', 'TEXT')
fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc)))
fp.write("Level %d, version %d\n\n" % (level, version))
......@@ -635,29 +649,30 @@ def compilesuite((suite, pathname, modname), major, minor, language, script,
fp.write('import aetools\n')
fp.write('import MacOS\n\n')
fp.write("_code = %s\n\n"% `code`)
if basepackage and basepackage._code_to_module.has_key(code):
if self.basepackage and self.basepackage._code_to_module.has_key(code):
# We are an extension of a baseclass (usually an application extending
# Standard_Suite or so). Import everything from our base module
fp.write('from %s import *\n'%basepackage._code_to_fullname[code][0])
basemodule = basepackage._code_to_module[code]
elif basepackage and basepackage._code_to_module.has_key(code.lower()):
fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code][0])
basemodule = self.basepackage._code_to_module[code]
elif self.basepackage and self.basepackage._code_to_module.has_key(code.lower()):
# This is needed by CodeWarrior and some others.
fp.write('from %s import *\n'%basepackage._code_to_fullname[code.lower()][0])
basemodule = basepackage._code_to_module[code.lower()]
fp.write('from %s import *\n'%self.basepackage._code_to_fullname[code.lower()][0])
basemodule = self.basepackage._code_to_module[code.lower()]
else:
# We are not an extension.
basemodule = None
compileclassheader(fp, modname, basemodule)
self.basemodule = basemodule
self.compileclassheader()
enumsneeded = {}
self.enumsneeded = {}
if events:
for event in events:
compileevent(fp, event, enumsneeded)
self.compileevent(event)
else:
fp.write("\tpass\n\n")
objc = ObjectCompiler(fp, basemodule, precompinfo, interact=interact,
verbose=verbose)
objc = ObjectCompiler(fp, basemodule, precompinfo, interact=(self.edit_modnames is None),
verbose=self.verbose)
for cls in classes:
objc.compileclass(cls)
for cls in classes:
......@@ -667,26 +682,25 @@ def compilesuite((suite, pathname, modname), major, minor, language, script,
for enum in enums:
objc.compileenumeration(enum)
for enum in enumsneeded.keys():
for enum in self.enumsneeded.keys():
objc.checkforenum(enum)
objc.dumpindex()
return code, modname
def compileclassheader(fp, name, module=None):
def compileclassheader(self):
"""Generate class boilerplate"""
classname = '%s_Events'%name
if module:
modshortname = string.split(module.__name__, '.')[-1]
classname = '%s_Events'%self.modname
if self.basemodule:
modshortname = string.split(self.basemodule.__name__, '.')[-1]
baseclassname = '%s_Events'%modshortname
fp.write("class %s(%s):\n\n"%(classname, baseclassname))
self.fp.write("class %s(%s):\n\n"%(classname, baseclassname))
else:
fp.write("class %s:\n\n"%classname)
self.fp.write("class %s:\n\n"%classname)
def compileevent(fp, event, enumsneeded):
def compileevent(self, event):
"""Generate code for a single event"""
[name, desc, code, subcode, returns, accepts, arguments] = event
fp = self.fp
funcname = identify(name)
#
# generate name->keyword map
......@@ -761,7 +775,7 @@ def compileevent(fp, event, enumsneeded):
if ename <> '****':
fp.write("\t\taetools.enumsubst(_arguments, %s, _Enum_%s)\n" %
(`kname`, identify(ename)))
enumsneeded[ename] = 1
self.enumsneeded[ename] = 1
fp.write("\n")
#
# Do the transaction
......@@ -783,24 +797,14 @@ def compileevent(fp, event, enumsneeded):
fp.write("\t\t\treturn _arguments['----']\n")
fp.write("\n")
# print "\n# Command %s -- %s (%s, %s)" % (`name`, `desc`, `code`, `subcode`)
# print "# returns", compiledata(returns)
# print "# accepts", compiledata(accepts)
# for arg in arguments:
# compileargument(arg)
def compileargument(arg):
[name, keyword, what] = arg
print "# %s (%s)" % (name, `keyword`), compiledata(what)
def findenumsinevent(event, enumsneeded):
def findenumsinevent(self, event):
"""Find all enums for a single event"""
[name, desc, code, subcode, returns, accepts, arguments] = event
for a in arguments:
if is_enum(a[2]):
ename = a[2][0]
if ename <> '****':
enumsneeded[ename] = 1
self.enumsneeded[ename] = 1
#
# This class stores the code<->name translations for a single module. It is used
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment