Registry { (@ GeneratedCodeCategory get_generatedCategory(String name) throws ParseException { CodeCategory result = get_category(name); if( ! (result instanceof GeneratedCodeCategory)) throw new ParseException("Not a GeneratedCodeCategory: "+name); return (GeneratedCodeCategory)result; } @) void generateCode(GeneratedCodeCategory category,CmdArgs args) (@ SourceList sources = new SourceList(); generateEntityCode(category,args,sources); if( ! sources.isEmpty()) // initialize a macro table category.expandMakeTemplate(/*macros, */args,sources); @) private void generateEntityCode( GeneratedCodeCategory category, CmdArgs args, SourceList sources) bypassing ParentEntity to Entity { (@ private Registry registry; @) before Registry (@ registry = host; @) before Entity (@ final String entityName = host.get_name().get_value(); if(category.get_keys().intersects(host.get_keys())){ System.out.println(" Generating source for: "+entityName); ExpansionContext context = new ExpansionContext(); host.collectContext(context,category.get_keys()); MacroTable macros = new MacroTable(); registry.addMacros(macros,host); String thisClassName = category.className(host); macros.define("ThisClass",thisClassName); macros.define("ThisClassHeader", category.headerFile(host).toString()); macros.define("ThisClassHeaderKey", thisClassName.toUpperCase()+"_H"); category.expandEntityTemplates(context,macros,args,sources); } @) } void addMacros(MacroTable macros,Entity entity) to CodeCategory { before CodeCategory (@ String name = host.get_macroBaseName(); macros.define(name,host.className(entity)); macros.define(name+"Header",host.headerFile(entity).toString()); @) } } Entity { void collectContext(ExpansionContext context, AccessKeyList keys) to TypeUse { before Entity(@ if(context.get_entity() == null) context.set_entity(host); @) around Method (@ // The buck stops at unqualified Methods :-) if(host.get_keys().intersects(keys)){ context.add(host); subtraversal.apply(); } @) before TypeUse (@ context.add(host); @) } } ExpansionContext{ (@ Hashtable useMap; @) init (@ useMap = new Hashtable(); methods = new MethodList(); useage = new TypeUseList(); entity = null; @) void add(Method method) (@ get_methods().add(method); @) void add(TypeUse newUse) (@ final String key = newUse.get_typeName().get_value(); TypeUse use = (TypeUse)useMap.get(key); if(use == null){ use = new TypeUse( newUse.get_typeName(), false, newUse.get_type()); useMap.put(key,use); useage.add(use); } if(newUse.get_needHeader()) use.set_needHeader(true); @) } GeneratedCodeCategory{ void expandEntityTemplates(ExpansionContext context, MacroTable macros, CmdArgs args, SourceList sources) to {HeaderTemplate,ImplTemplate} { (@ GeneratedCodeCategory category; @) before GeneratedCodeCategory (@ category = host; @) before HeaderTemplate (@ File outDir = args.getHeaderOutDir(); if(outDir != null){ File headerFile = category.headerFile(context.get_entity()); String headerFileName = headerFile.getName(); macros.define("File",headerFileName); File outFileSpec = new File(outDir,headerFileName); try { PrintWriter outFile = new PrintWriter(new FileWriter(outFileSpec)); host.expand(outFile,context,macros,args); outFile.close(); } catch(IOException e){ Main.die(e); } } @) before ImplTemplate (@ File outDir = args.getImplOutDir(); if(outDir != null){ File implFile = category.implFile(context.get_entity()); String implFileName = implFile.getName(); sources.add(implFileName); macros.define("File",implFileName); File outFileSpec = new File(outDir,implFileName); try{ PrintWriter outFile = new PrintWriter(new FileWriter(outFileSpec)); host.expand(outFile,context,macros,args); outFile.close(); } catch(IOException e){ } } @) } void expandMakeTemplate(CmdArgs args, SourceList sources) to MakeTemplate { before MakeTemplate (@ if(args.getImplOutDir() != null){ System.out.println("Expanding Make Template"); } @) } }