Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6654422

Browse files
committed
Generate class, property and comparison code (finally!). The resulting
code isn't ideal yet: xxx.Window(1).Paragraph(3).font will only work if all the classes and properties are declared in the same suite, but at least font(Paragraph(3, Window(1))) always works.
1 parent 622f73f commit 6654422

1 file changed

Lines changed: 201 additions & 41 deletions

File tree

Mac/scripts/gensuitemodule.py

Lines changed: 201 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ def process(fullname):
3939
print "decoding", res.GetResInfo(), "..."
4040
data = res.data
4141
aete = decode(data)
42+
# switch back (needed for dialogs in Python)
43+
UseResFile(cur)
4244
compileaete(aete, fullname)
45+
UseResFile(rf)
4346
finally:
4447
if rf <> cur:
4548
CloseResFile(rf)
@@ -237,27 +240,35 @@ def compilesuite(suite, major, minor, language, script, fname):
237240
fp.write('import MacOS\n\n')
238241
fp.write("_code = %s\n\n"% `code`)
239242

240-
enum_names = []
241-
for enum in enums:
242-
name = compileenumeration(fp, enum)
243-
enum_names.append(enum)
244-
245243
compileclassheader(fp, modname)
244+
245+
enumsneeded = {}
246246
if events:
247247
for event in events:
248-
compileevent(fp, event)
248+
compileevent(fp, event, enumsneeded)
249249
else:
250250
fp.write("\tpass\n\n")
251+
252+
objc = ObjectCompiler(fp)
253+
for cls in classes:
254+
objc.compileclass(cls)
251255
for cls in classes:
252-
compileclass(fp, cls)
256+
objc.fillclasspropsandelems(cls)
253257
for comp in comps:
254-
compilecomparison(fp, comp)
258+
objc.compilecomparison(comp)
259+
for enum in enums:
260+
objc.compileenumeration(enum)
261+
262+
for enum in enumsneeded.keys():
263+
objc.checkforenum(enum)
264+
265+
objc.dumpindex()
255266

256267
def compileclassheader(fp, name):
257268
"""Generate class boilerplate"""
258269
fp.write("class %s:\n\n"%name)
259270

260-
def compileevent(fp, event):
271+
def compileevent(fp, event, enumsneeded):
261272
"""Generate code for a single event"""
262273
[name, desc, code, subcode, returns, accepts, arguments] = event
263274
funcname = identify(name)
@@ -334,6 +345,7 @@ def compileevent(fp, event):
334345
if ename <> '****':
335346
fp.write("\t\taetools.enumsubst(_arguments, %s, _Enum_%s)\n" %
336347
(`kname`, ename))
348+
enumsneeded[ename] = 1
337349
fp.write("\n")
338350
#
339351
# Do the transaction
@@ -365,37 +377,182 @@ def compileargument(arg):
365377
[name, keyword, what] = arg
366378
print "# %s (%s)" % (name, `keyword`), compiledata(what)
367379

368-
def compileclass(fp, cls):
369-
[name, code, desc, properties, elements] = cls
370-
fp.write("\n# Class %s (%s) -- %s\n" % (`name`, `code`, `desc`))
371-
for prop in properties:
372-
compileproperty(fp, prop)
373-
for elem in elements:
374-
compileelement(fp, elem)
375-
376-
def compileproperty(fp, prop):
377-
[name, code, what] = prop
378-
fp.write("# property %s (%s) %s\n" % (`name`, `code`, compiledata(what)))
379-
380-
def compileelement(fp, elem):
381-
[code, keyform] = elem
382-
fp.write("# element %s as %s\n" % (`code`, keyform))
383-
384-
def compilecomparison(fp, comp):
385-
[name, code, comment] = comp
386-
fp.write("# comparison %s (%s) -- %s\n" % (`name`, `code`, comment))
387-
388-
def compileenumeration(fp, enum):
389-
[code, items] = enum
390-
fp.write("_Enum_%s = {\n" % identify(code))
391-
for item in items:
392-
compileenumerator(fp, item)
393-
fp.write("}\n\n")
394-
return code
395-
396-
def compileenumerator(fp, item):
397-
[name, code, desc] = item
398-
fp.write("\t%s : %s,\t# %s\n" % (`identify(name)`, `code`, desc))
380+
class ObjectCompiler:
381+
def __init__(self, fp):
382+
self.fp = fp
383+
self.propnames = {}
384+
self.classnames = {}
385+
self.propcodes = {}
386+
self.classcodes = {}
387+
self.compcodes = {}
388+
self.enumcodes = {}
389+
self.othersuites = []
390+
391+
def findcodename(self, type, code):
392+
while 1:
393+
if type == 'property':
394+
if self.propcodes.has_key(code):
395+
return self.propcodes[code], self.propcodes[code], None
396+
for s in self.othersuites:
397+
if s._propdeclarations.has_key(code):
398+
name = s._propdeclarations[code].__name__
399+
return name, '%s.%s' % (s.__name__, name), s.__name__
400+
if type == 'class':
401+
if self.classcodes.has_key(code):
402+
return self.classcodes[code], self.classcodes[code], None
403+
for s in self.othersuites:
404+
if s._classdeclarations.has_key(code):
405+
name = s._classdeclarations[code].__name__
406+
return name, '%s.%s' % (s.__name__, name), s.__name__
407+
if type == 'enum':
408+
if self.enumcodes.has_key(code):
409+
return self.enumcodes[code], self.enumcodes[code], None
410+
for s in self.othersuites:
411+
if s._enumdeclarations.has_key(code):
412+
name = '_Enum_' + identify(code)
413+
return name, '%s.%s' % (s.__name__, name), s.__name__
414+
if type == 'comparison':
415+
if self.compcodes.has_key(code):
416+
return self.compcodes[code], self.compcodes[code], None
417+
for s in self.othersuites:
418+
if s._compdeclarations.has_key(code):
419+
name = s._compdeclarations[code].__name__
420+
return name, '%s.%s' % (s.__name__, name), s.__name__
421+
422+
m = self.askdefinitionmodule(type, code)
423+
if not m: return None, None, None
424+
self.othersuites.append(m)
425+
426+
def askdefinitionmodule(self, type, code):
427+
fss, ok = macfs.PromptGetFile('Where is %s %s declared?'%(type, code))
428+
if not ok: return
429+
path, file = os.path.split(fss.as_pathname())
430+
modname = os.path.splitext(file)[0]
431+
if not path in sys.path:
432+
sys.path.insert(0, path)
433+
m = __import__(modname)
434+
self.fp.write("import %s\n"%modname)
435+
return m
436+
437+
def compileclass(self, cls):
438+
[name, code, desc, properties, elements] = cls
439+
pname = identify(name)
440+
if self.classcodes.has_key(code):
441+
# plural forms and such
442+
self.fp.write("\n%s = %s\n"%(pname, self.classcodes[code]))
443+
self.classnames[pname] = code
444+
else:
445+
self.fp.write('\nclass %s(aetools.ComponentItem):\n' % pname)
446+
self.fp.write('\t"""%s - %s"""\n' % (name, desc))
447+
self.fp.write('\twant = %s\n' % `code`)
448+
self.classnames[pname] = code
449+
self.classcodes[code] = pname
450+
for prop in properties:
451+
self.compileproperty(prop)
452+
for elem in elements:
453+
self.compileelement(elem)
454+
455+
def compileproperty(self, prop):
456+
[name, code, what] = prop
457+
if code == 'c@#!':
458+
# Something silly with plurals. Skip it.
459+
return
460+
pname = identify(name)
461+
if self.propcodes.has_key(code):
462+
self.fp.write("# repeated property %s %s\n"%(pname, what[1]))
463+
else:
464+
self.fp.write("class %s(aetools.NProperty):\n" % pname)
465+
self.fp.write('\t"""%s - %s"""\n' % (name, what[1]))
466+
self.fp.write("\twhich = %s\n" % `code`)
467+
self.fp.write("\twant = %s\n" % `what[0]`)
468+
self.propnames[pname] = code
469+
self.propcodes[code] = pname
470+
471+
def compileelement(self, elem):
472+
[code, keyform] = elem
473+
self.fp.write("# element %s as %s\n" % (`code`, keyform))
474+
475+
def fillclasspropsandelems(self, cls):
476+
[name, code, desc, properties, elements] = cls
477+
cname = identify(name)
478+
if self.classcodes[code] != cname:
479+
# This is an other name (plural or so) for something else. Skip.
480+
return
481+
plist = []
482+
elist = []
483+
for prop in properties:
484+
[pname, pcode, what] = prop
485+
if pcode == 'c@#!':
486+
continue
487+
pname = identify(pname)
488+
plist.append(pname)
489+
for elem in elements:
490+
[ecode, keyform] = elem
491+
if ecode == 'c@#!':
492+
continue
493+
name, ename, module = self.findcodename('class', ecode)
494+
if not name:
495+
self.fp.write("# XXXX %s element %s not found!!\n"%(cname, `ecode`))
496+
else:
497+
elist.append(name, ename)
498+
499+
self.fp.write("%s._propdict = {\n"%cname)
500+
for n in plist:
501+
self.fp.write("\t'%s' : %s,\n"%(n, n))
502+
self.fp.write("}\n")
503+
self.fp.write("%s._elemdict = {\n"%cname)
504+
for n, fulln in elist:
505+
self.fp.write("\t'%s' : %s,\n"%(n, fulln))
506+
self.fp.write("}\n")
507+
508+
def compilecomparison(self, comp):
509+
[name, code, comment] = comp
510+
iname = identify(name)
511+
self.compcodes[code] = iname
512+
self.fp.write("class %s(aetools.NComparison):\n" % iname)
513+
self.fp.write('\t"""%s - %s"""\n' % (name, comment))
514+
515+
def compileenumeration(self, enum):
516+
[code, items] = enum
517+
name = "_Enum_%s" % identify(code)
518+
self.fp.write("%s = {\n" % name)
519+
for item in items:
520+
self.compileenumerator(item)
521+
self.fp.write("}\n\n")
522+
self.enumcodes[code] = name
523+
return code
524+
525+
def compileenumerator(self, item):
526+
[name, code, desc] = item
527+
self.fp.write("\t%s : %s,\t# %s\n" % (`identify(name)`, `code`, desc))
528+
529+
def checkforenum(self, enum):
530+
"""This enum code is used by an event. Make sure it's available"""
531+
name, fullname, module = self.findcodename('enum', enum)
532+
if not name:
533+
self.fp.write("# XXXX enum %s not found!!\n"%(enum))
534+
return
535+
if module:
536+
self.fp.write("from %s import %s\n"%(module, name))
537+
538+
def dumpindex(self):
539+
self.fp.write("\n#\n# Indices of types declared in this module\n#\n")
540+
self.fp.write("_classdeclarations = {\n")
541+
for k in self.classcodes.keys():
542+
self.fp.write("\t%s : %s,\n" % (`k`, self.classcodes[k]))
543+
self.fp.write("}\n")
544+
self.fp.write("\n_propdeclarations = {\n")
545+
for k in self.propcodes.keys():
546+
self.fp.write("\t%s : %s,\n" % (`k`, self.propcodes[k]))
547+
self.fp.write("}\n")
548+
self.fp.write("\n_compdeclarations = {\n")
549+
for k in self.compcodes.keys():
550+
self.fp.write("\t%s : %s,\n" % (`k`, self.compcodes[k]))
551+
self.fp.write("}\n")
552+
self.fp.write("\n_enumdeclarations = {\n")
553+
for k in self.enumcodes.keys():
554+
self.fp.write("\t%s : %s,\n" % (`k`, self.enumcodes[k]))
555+
self.fp.write("}\n")
399556

400557
def compiledata(data):
401558
[type, description, flags] = data
@@ -432,14 +589,17 @@ def compiledataflags(flags):
432589
return '[%s]' % string.join(bits)
433590

434591
# XXXX Do we have a set of python keywords somewhere?
435-
illegal_ids = [ "for", "in", "from", "and", "or", "not", "print" ]
592+
illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return",
593+
"def" ]
436594

437595
def identify(str):
438596
"""Turn any string into an identifier:
439597
- replace space by _
440598
- replace other illegal chars by _xx_ (hex code)
441599
- prepend _ if the result is a python keyword
442600
"""
601+
if not str:
602+
return "_empty_ae_name"
443603
rv = ''
444604
ok = string.letters + '_'
445605
ok2 = ok + string.digits

0 commit comments

Comments
 (0)