[Python-checkins] python/dist/src/Lib/plat-mac gensuitemodule.py,1.3,1.4
jackjansen@users.sourceforge.net
jackjansen@users.sourceforge.net
Tue, 01 Apr 2003 06:25:55 -0800
Update of /cvsroot/python/python/dist/src/Lib/plat-mac
In directory sc8-pr-cvs1:/tmp/cvs-serv2273
Modified Files:
gensuitemodule.py
Log Message:
Turned the suite compiler into an object.
Index: gensuitemodule.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/gensuitemodule.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** gensuitemodule.py 1 Apr 2003 13:32:17 -0000 1.3
--- gensuitemodule.py 1 Apr 2003 14:25:49 -0000 1.4
***************
*** 468,473 ****
allsuites = []
for suite in suites:
! code, suite, pathname, modname, precompinfo = precompilesuite(suite, basepackage,
! output=output, edit_modnames=edit_modnames, verbose=verbose)
if not code:
continue
--- 468,473 ----
allsuites = []
for suite in suites:
! compiler = SuiteCompiler(suite, basepackage, output, edit_modnames, verbose)
! code, modname, precompinfo = compiler.precompilesuite()
if not code:
continue
***************
*** 475,482 ****
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)
initfilename = os.path.join(output, '__init__.py')
fp = open(initfilename, 'w')
--- 475,481 ----
suiteinfo = suite, pathname, modname
suitelist.append((code, modname))
! 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')
***************
*** 541,806 ****
fp.write("\t_moduleName = '%s'\n\n"%packagename)
fp.close()
-
- def precompilesuite(suite, basepackage=None, edit_modnames=None, output=None,
- verbose=None):
- """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
-
- modname = identify(name)
- if len(modname) > 28:
- modname = modname[:27]
- if edit_modnames is None:
- pathname = EasyDialogs.AskFileForSave(message='Python output file',
- savedFileName=modname+'.py')
- else:
- for old, new in edit_modnames:
- if old == modname:
- modname = new
- if modname:
- pathname = os.path.join(output, modname + '.py')
- else:
- pathname = None
- if not pathname:
- return None, None, None, None, None
-
- modname = os.path.splitext(os.path.split(pathname)[1])[0]
-
- if basepackage and 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]
- else:
- # We are not an extension.
- basemodule = None
-
- enumsneeded = {}
- for event in events:
- findenumsinevent(event, enumsneeded)
! objc = ObjectCompiler(None, basemodule, interact=(edit_modnames is None),
! verbose=verbose)
! for cls in classes:
! objc.compileclass(cls)
! for cls in classes:
! objc.fillclasspropsandelems(cls)
! for comp in comps:
! objc.compilecomparison(comp)
! for enum in enums:
! objc.compileenumeration(enum)
!
! for enum in enumsneeded.keys():
! objc.checkforenum(enum)
! objc.dumpindex()
!
! precompinfo = objc.getprecompinfo(modname)
!
! return code, suite, pathname, modname, precompinfo
!
! def compilesuite((suite, pathname, modname), major, minor, language, script,
! fname, basepackage, precompinfo, interact=1, verbose=None):
! """Generate code for a single suite"""
! [name, desc, code, level, version, events, classes, comps, enums] = 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"""
! # [name, code, desc, properties, elements] = cls
! if k1[1] < k2[1]: return -1
! if k1[1] > k2[1]: return 1
! if not k2[3] or k2[3][0][1] == 'c@#!':
! # This is a synonym, the other one is better
! return -1
! if not k1[3] or k1[3][0][1] == 'c@#!':
! # This is a synonym, the other one is better
! return 1
! return 0
! events.sort()
! classes.sort(class_sorter)
! comps.sort()
! enums.sort()
!
! fp = open(pathname, 'w')
! MacOS.SetCreatorAndType(pathname, 'Pyth', 'TEXT')
! fp.write('"""Suite %s: %s\n' % (ascii(name), ascii(desc)))
! fp.write("Level %d, version %d\n\n" % (level, version))
! fp.write("Generated from %s\n"%ascii(fname))
! fp.write("AETE/AEUT resource version %d/%d, language %d, script %d\n" % \
! (major, minor, language, script))
! fp.write('"""\n\n')
! 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):
! # 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()):
! # 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()]
! else:
! # We are not an extension.
! basemodule = None
! compileclassheader(fp, modname, basemodule)
!
! enumsneeded = {}
! if events:
for event in events:
! compileevent(fp, event, enumsneeded)
! else:
! fp.write("\tpass\n\n")
!
! objc = ObjectCompiler(fp, basemodule, precompinfo, interact=interact,
! verbose=verbose)
! for cls in classes:
! objc.compileclass(cls)
! for cls in classes:
! objc.fillclasspropsandelems(cls)
! for comp in comps:
! objc.compilecomparison(comp)
! for enum in enums:
! objc.compileenumeration(enum)
! for enum in enumsneeded.keys():
! objc.checkforenum(enum)
! objc.dumpindex()
! return code, modname
! def compileclassheader(fp, name, module=None):
! """Generate class boilerplate"""
! classname = '%s_Events'%name
! if module:
! modshortname = string.split(module.__name__, '.')[-1]
! baseclassname = '%s_Events'%modshortname
! fp.write("class %s(%s):\n\n"%(classname, baseclassname))
! else:
! fp.write("class %s:\n\n"%classname)
! def compileevent(fp, event, enumsneeded):
! """Generate code for a single event"""
! [name, desc, code, subcode, returns, accepts, arguments] = event
! funcname = identify(name)
! #
! # generate name->keyword map
! #
! if arguments:
! fp.write("\t_argmap_%s = {\n"%funcname)
! for a in arguments:
! fp.write("\t\t%s : %s,\n"%(`identify(a[0])`, `a[1]`))
! fp.write("\t}\n\n")
! #
! # Generate function header
! #
! has_arg = (not is_null(accepts))
! opt_arg = (has_arg and is_optional(accepts))
!
! fp.write("\tdef %s(self, "%funcname)
! if has_arg:
! if not opt_arg:
! fp.write("_object, ") # Include direct object, if it has one
else:
! fp.write("_object=None, ") # Also include if it is optional
! else:
! fp.write("_no_object=None, ") # For argument checking
! fp.write("_attributes={}, **_arguments):\n") # include attribute dict and args
! #
! # Generate doc string (important, since it may be the only
! # available documentation, due to our name-remaping)
! #
! fp.write('\t\t"""%s: %s\n'%(ascii(name), ascii(desc)))
! if has_arg:
! fp.write("\t\tRequired argument: %s\n"%getdatadoc(accepts))
! elif opt_arg:
! fp.write("\t\tOptional argument: %s\n"%getdatadoc(accepts))
! for arg in arguments:
! fp.write("\t\tKeyword argument %s: %s\n"%(identify(arg[0]),
! getdatadoc(arg[2])))
! fp.write("\t\tKeyword argument _attributes: AppleEvent attribute dictionary\n")
! if not is_null(returns):
! fp.write("\t\tReturns: %s\n"%getdatadoc(returns))
! fp.write('\t\t"""\n')
! #
! # Fiddle the args so everything ends up in 'arguments' dictionary
! #
! fp.write("\t\t_code = %s\n"% `code`)
! fp.write("\t\t_subcode = %s\n\n"% `subcode`)
! #
! # Do keyword name substitution
! #
! if arguments:
! fp.write("\t\taetools.keysubst(_arguments, self._argmap_%s)\n"%funcname)
! else:
! fp.write("\t\tif _arguments: raise TypeError, 'No optional args expected'\n")
! #
! # Stuff required arg (if there is one) into arguments
! #
! if has_arg:
! fp.write("\t\t_arguments['----'] = _object\n")
! elif opt_arg:
! fp.write("\t\tif _object:\n")
! fp.write("\t\t\t_arguments['----'] = _object\n")
! else:
! fp.write("\t\tif _no_object != None: raise TypeError, 'No direct arg expected'\n")
! fp.write("\n")
! #
! # Do enum-name substitution
! #
! for a in arguments:
! if is_enum(a[2]):
! kname = a[1]
! ename = a[2][0]
! if ename <> '****':
! fp.write("\t\taetools.enumsubst(_arguments, %s, _Enum_%s)\n" %
! (`kname`, identify(ename)))
! enumsneeded[ename] = 1
! fp.write("\n")
! #
! # Do the transaction
! #
! fp.write("\t\t_reply, _arguments, _attributes = self.send(_code, _subcode,\n")
! fp.write("\t\t\t\t_arguments, _attributes)\n")
! #
! # Error handling
! #
! fp.write("\t\tif _arguments.get('errn', 0):\n")
! fp.write("\t\t\traise aetools.Error, aetools.decodeerror(_arguments)\n")
! fp.write("\t\t# XXXX Optionally decode result\n")
! #
! # Decode result
! #
! fp.write("\t\tif _arguments.has_key('----'):\n")
! if is_enum(returns):
! fp.write("\t\t\t# XXXX Should do enum remapping here...\n")
! 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):
- """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
-
#
# This class stores the code<->name translations for a single module. It is used
--- 540,810 ----
fp.write("\t_moduleName = '%s'\n\n"%packagename)
fp.close()
! 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] = self.suite
!
! modname = identify(name)
! if len(modname) > 28:
! modname = modname[:27]
! if self.edit_modnames is None:
! self.pathname = EasyDialogs.AskFileForSave(message='Python output file',
! savedFileName=modname+'.py')
! else:
! for old, new in self.edit_modnames:
! if old == modname:
! modname = new
! if modname:
! self.pathname = os.path.join(self.output, modname + '.py')
! else:
! self.pathname = None
! if not self.pathname:
! return None, None, None
! self.modname = os.path.splitext(os.path.split(self.pathname)[1])[0]
!
! 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 = self.basepackage._code_to_module[code]
! else:
! # We are not an extension.
! basemodule = None
! self.enumsneeded = {}
for event in events:
! self.findenumsinevent(event)
! objc = ObjectCompiler(None, basemodule, interact=(self.edit_modnames is None),
! verbose=self.verbose)
! for cls in classes:
! objc.compileclass(cls)
! for cls in classes:
! objc.fillclasspropsandelems(cls)
! for comp in comps:
! objc.compilecomparison(comp)
! for enum in enums:
! objc.compileenumeration(enum)
! for enum in self.enumsneeded.keys():
! objc.checkforenum(enum)
!
! objc.dumpindex()
!
! precompinfo = objc.getprecompinfo(self.modname)
!
! return code, self.modname, precompinfo
! def compilesuite(self, major, minor, language, script, fname, precompinfo):
! """Generate code for a single 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"""
! # [name, code, desc, properties, elements] = cls
! if k1[1] < k2[1]: return -1
! if k1[1] > k2[1]: return 1
! if not k2[3] or k2[3][0][1] == 'c@#!':
! # This is a synonym, the other one is better
! return -1
! if not k1[3] or k1[3][0][1] == 'c@#!':
! # This is a synonym, the other one is better
! return 1
! return 0
!
! events.sort()
! classes.sort(class_sorter)
! comps.sort()
! enums.sort()
!
! 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))
! fp.write("Generated from %s\n"%ascii(fname))
! fp.write("AETE/AEUT resource version %d/%d, language %d, script %d\n" % \
! (major, minor, language, script))
! fp.write('"""\n\n')
!
! fp.write('import aetools\n')
! fp.write('import MacOS\n\n')
! fp.write("_code = %s\n\n"% `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'%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'%self.basepackage._code_to_fullname[code.lower()][0])
! basemodule = self.basepackage._code_to_module[code.lower()]
! else:
! # We are not an extension.
! basemodule = None
! self.basemodule = basemodule
! self.compileclassheader()
! self.enumsneeded = {}
! if events:
! for event in events:
! self.compileevent(event)
! else:
! fp.write("\tpass\n\n")
! 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:
! objc.fillclasspropsandelems(cls)
! for comp in comps:
! objc.compilecomparison(comp)
! for enum in enums:
! objc.compileenumeration(enum)
! for enum in self.enumsneeded.keys():
! objc.checkforenum(enum)
!
! objc.dumpindex()
!
! def compileclassheader(self):
! """Generate class boilerplate"""
! classname = '%s_Events'%self.modname
! if self.basemodule:
! modshortname = string.split(self.basemodule.__name__, '.')[-1]
! baseclassname = '%s_Events'%modshortname
! self.fp.write("class %s(%s):\n\n"%(classname, baseclassname))
else:
! self.fp.write("class %s:\n\n"%classname)
!
! 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
! #
! if arguments:
! fp.write("\t_argmap_%s = {\n"%funcname)
! for a in arguments:
! fp.write("\t\t%s : %s,\n"%(`identify(a[0])`, `a[1]`))
! fp.write("\t}\n\n")
!
! #
! # Generate function header
! #
! has_arg = (not is_null(accepts))
! opt_arg = (has_arg and is_optional(accepts))
!
! fp.write("\tdef %s(self, "%funcname)
! if has_arg:
! if not opt_arg:
! fp.write("_object, ") # Include direct object, if it has one
! else:
! fp.write("_object=None, ") # Also include if it is optional
! else:
! fp.write("_no_object=None, ") # For argument checking
! fp.write("_attributes={}, **_arguments):\n") # include attribute dict and args
! #
! # Generate doc string (important, since it may be the only
! # available documentation, due to our name-remaping)
! #
! fp.write('\t\t"""%s: %s\n'%(ascii(name), ascii(desc)))
! if has_arg:
! fp.write("\t\tRequired argument: %s\n"%getdatadoc(accepts))
! elif opt_arg:
! fp.write("\t\tOptional argument: %s\n"%getdatadoc(accepts))
! for arg in arguments:
! fp.write("\t\tKeyword argument %s: %s\n"%(identify(arg[0]),
! getdatadoc(arg[2])))
! fp.write("\t\tKeyword argument _attributes: AppleEvent attribute dictionary\n")
! if not is_null(returns):
! fp.write("\t\tReturns: %s\n"%getdatadoc(returns))
! fp.write('\t\t"""\n')
! #
! # Fiddle the args so everything ends up in 'arguments' dictionary
! #
! fp.write("\t\t_code = %s\n"% `code`)
! fp.write("\t\t_subcode = %s\n\n"% `subcode`)
! #
! # Do keyword name substitution
! #
! if arguments:
! fp.write("\t\taetools.keysubst(_arguments, self._argmap_%s)\n"%funcname)
! else:
! fp.write("\t\tif _arguments: raise TypeError, 'No optional args expected'\n")
! #
! # Stuff required arg (if there is one) into arguments
! #
! if has_arg:
! fp.write("\t\t_arguments['----'] = _object\n")
! elif opt_arg:
! fp.write("\t\tif _object:\n")
! fp.write("\t\t\t_arguments['----'] = _object\n")
! else:
! fp.write("\t\tif _no_object != None: raise TypeError, 'No direct arg expected'\n")
! fp.write("\n")
! #
! # Do enum-name substitution
! #
! for a in arguments:
! if is_enum(a[2]):
! kname = a[1]
! ename = a[2][0]
! if ename <> '****':
! fp.write("\t\taetools.enumsubst(_arguments, %s, _Enum_%s)\n" %
! (`kname`, identify(ename)))
! self.enumsneeded[ename] = 1
! fp.write("\n")
! #
! # Do the transaction
! #
! fp.write("\t\t_reply, _arguments, _attributes = self.send(_code, _subcode,\n")
! fp.write("\t\t\t\t_arguments, _attributes)\n")
! #
! # Error handling
! #
! fp.write("\t\tif _arguments.get('errn', 0):\n")
! fp.write("\t\t\traise aetools.Error, aetools.decodeerror(_arguments)\n")
! fp.write("\t\t# XXXX Optionally decode result\n")
! #
! # Decode result
! #
! fp.write("\t\tif _arguments.has_key('----'):\n")
! if is_enum(returns):
! fp.write("\t\t\t# XXXX Should do enum remapping here...\n")
! fp.write("\t\t\treturn _arguments['----']\n")
! fp.write("\n")
!
! 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 <> '****':
! self.enumsneeded[ename] = 1
#
# This class stores the code<->name translations for a single module. It is used