TAO.beh.html
Program{
(@
public static Vector TAOclasses = new Vector(13);
public static String visitorclass="TAOVisitor";
static {
TAOclasses.addElement("Traversal");
TAOclasses.addElement("TAO_TravList");
TAOclasses.addElement("TAO_TravLabel");
TAOclasses.addElement("TAO_Bypass");
TAOclasses.addElement("TAO_NextTrav");
TAOclasses.addElement("TAO_ClassNames");
TAOclasses.addElement("TAO_OneClassGlob");
TAOclasses.addElement("TAO_ClassGlob");
TAOclasses.addElement("TAO_ClassGlobSet");
TAOclasses.addElement("TAO_ClassGlobList");
TAOclasses.addElement("TAO_NextClassGlob");
TAOclasses.addElement("TAO_AnyClass");
TAOclasses.addElement("TAO_ClassName");
}
public static FindVisitorTargetsV fvtv;
// before parser expansion
public static void genTAO1() {
// sanity check. we need some classes to be undefined:
// Therefore, this must come before we start adding those classes
for (Enumeration classes = prog.get_cg().get_defdict().keys();classes.hasMoreElements();) {
String classname = ((ClassName) classes.nextElement()).toString();
if (TAOclasses.contains(classname)) {
System.err.println("Please don't use the class name "+classname+" as TAO needs it");
System.exit(1);
}
}
log.println(" TAO: Adding support classes");
Program.addTAOClasses();
}
// after repetiton expansion
public static void genTAO2() {
log.println(" TAO: Adding Methods to user classes");
Program.addToUserCodeTAO();
}
public static void addTAOClasses() {
System.err.println(" TAO: parsing functions");
// System.err.println("Traversal");
prog.addClassDef(ClassDef.parse(
"Traversal *parse* = [<label> TAO_TravLabel] \"from\" <fromclasses> TAO_ClassNames <path> TAO_TravList \";\" {("+"@" +
" static Graph fgraph ;\n"+
" static Graph rgraph ; \n"+
//" static Vector alternations = new Vector(); \n"+
" static public void set_graph(Graph g) {\n"+
" fgraph = g;\n"+
" rgraph = g.reversegraph();\n"+
" }\n"+
" static Hashtable cache = new Hashtable(); \n"+
" public String thestr; \n"+
" static void printindented(String str1, int indent, String str2) { System.err.print(str1); for (int i=0; i<indent; i++) System.err.print(\" \"); System.err.println(str2); } \n"+
" public void traverse(Object instobj, Vector vs) {\n"+
" "+Program.visitorclass+"[] vsarr = new "+Program.visitorclass+"[vs.size()]; \n"+
" vs.copyInto(vsarr); \n"+
" traverse(instobj,vsarr);\n"+
" }\n"+
" public void traverse(Object instobj, "+Program.visitorclass+"[] vs) {\n"+
((Program.dbg)?" System.err.println(\"TAO running: \"+thestr);\n":"")+
" try { pathtrav(path.protoobject, fromclasses.toVector(), instobj,vs"+((Program.dbg)?",0":"")+");\n"+
" } catch (NullPointerException e) {System.err.println(\" Traversal called on Class not in the traversal: \"+instobj.getClass().getName()+\"\\nprotoobj: \"+path.protoobject.toString()); e.printStackTrace(); System.exit(1);} \n"+
" }\n"+
" public void traverse(Object instobj, "+Program.visitorclass+" v) {\n"+
" "+Program.visitorclass+"[] vsarr = {v}; \n"+
" traverse(instobj,vsarr);\n"+
" }\n"+
" public static Traversal fromString(String str) {\n"+
" Traversal t = (Traversal) cache.get(str); \n"+
" if (t != null) return t; \n"+
" else { \n"+
" t = Traversal.parse(str); \n"+
" try { t.path.initPath(t.get_fromclasses().toVector());\n"+
" } catch (Exception e) {System.err.println(\"Error initing the traversal \"+str); e.printStackTrace(); System.exit(1);} \n"+
" t.thestr = str; \n"+
" cache.put(str,t); \n"+
" return t; } \n"+
" } \n"+
" @"+")}."));
// System.err.println("TAO_TravList");
prog.addClassDef(ClassDef.parse(
"TAO_TravList *parse* = [<bypass> TAO_Bypass] \"to\" <too> TAO_ClassNames [<next> TAO_NextTrav] {("+"@" +
" public Hashtable protoobject;\n"+
" public Graph myfgraph = Traversal.fgraph.deepcopy();\n"+
" public Graph myrgraph = Traversal.rgraph.deepcopy();\n"+
" private Vector fromclasses; \n"+
" static String strippackage(String str) { return str.substring(str.lastIndexOf('.')+1,str.length()); } \n"+
" public void initPath(Vector fclasses) { \n"+
" fromclasses = fclasses;\n"+
" Vector toclasses = too.toVector();\n"+
" protoobject = new Hashtable();\n"+
" Vector bypassclasses;\n"+
" if (get_bypass() == null) bypassclasses = new Vector(0);\n"+
" else bypassclasses= get_bypass().toVector();\n"+
" if (next != null) { \n"+
" // The boaz-lieberherr single protoobject impl.\n "+
// make the next traversal of the join
" next.get_trav().initPath(toclasses); \n"+
" try {\n"+
" for (Enumeration tocenum = toclasses.elements(); tocenum.hasMoreElements();) {\n"+
// grab each to class of this traversal from the next traversal: this is called priming
" String toclass = tocenum.nextElement().toString();\n"+
// grab the to class. This should be done better:
// 1) check that toinst is a fromclass of the next trav
// 2) for tc in {this.to}, if tc.superclass* in {next.from}&& tc not in {next.from},
// we should grab the closest superclass that is in {next.from}
" Object[] toinst = (Object[]) next.get_trav().protoobject.get(toclass); \n"+
// store the grabbed object in this traversal, as per liberherr & boaz
" protoobject.put(toclass,toinst);\n"+
" }\n"+
" } catch (NullPointerException e) {\n"+
" System.err.println(\n"+
" \"During a join, a nullpointer was derefrenced. Oops. Tell johan\");\n"+
" e.printStackTrace();\n"+
" System.exit(1);\n"+
" }\n"+
" selectFromToStop(fromclasses, bypassclasses, toclasses); \n"+ // next != null
" } else { selectFromTo(fromclasses, bypassclasses, toclasses); } \n"+ // next = null
//" System.err.println(\"myfgraph:\"+myfgraph.toString());\n"+
" for (Enumeration fcenum = fromclasses.elements(); fcenum.hasMoreElements();) {\n"+
" String fromclassname = fcenum.nextElement().toString();\n"+
" Traversal.makeproto(fromclassname,protoobject,myfgraph"+((Program.dbg)?",0":"")+");\n"+
" }\n"+
" myfgraph = null; myrgraph = null; \n"+
" }\n"+
" public void selectFromToStop(Vector fromclasses, Vector bypassclasses, Vector toclasses) { \n"+
" for (Enumeration tcenum = toclasses.elements(); tcenum.hasMoreElements();) {\n"+
" Ident toname = (Ident) tcenum.nextElement();\n"+
" myfgraph.clearnode(toname); \n"+
" } \n"+
" myrgraph = myfgraph.reversegraph();\n"+
" selectFromTo(fromclasses, bypassclasses, toclasses);\n"+
" }\n"+
" public void selectFromTo(Vector fromclasses, Vector bypassclasses, Vector toclasses) {\n"+
// bypass edges: remove incoming
" for (Enumeration bcenum = bypassclasses.elements(); bcenum.hasMoreElements();) {\n"+
" Ident bypassingname = (Ident) bcenum.nextElement();\n"+
" myrgraph.clearnode(bypassingname); \n"+
" myfgraph.removeincoming(bypassingname); \n"+
" } \n"+
((Program.dbg)?" System.err.println(\"Subgraph from \"+fromclasses.toString()+\" bypassing \"+bypassclasses.toString()+\" to \"+toclasses.toString());\n":"")+
" for (Enumeration fcenum = fromclasses.elements(); fcenum.hasMoreElements();) {\n"+
" Ident fromname = (Ident) fcenum.nextElement();\n"+
" for (Enumeration tcenum = toclasses.elements(); tcenum.hasMoreElements();) {\n"+
" Ident toname = (Ident) tcenum.nextElement();\n"+
//" System.err.println(\"DFS \"+fromname+\" -> \"+toname); \n"+
" myfgraph.dfs(fromname,\"TAO_f_mark\");\n"+
" myrgraph.dfs(toname,\"TAO_r_mark\");\n"+
" for (Enumeration nodes = myfgraph.nodes(); nodes.hasMoreElements();) {\n"+
" Ident node = (Ident) nodes.nextElement();\n"+
" if (myfgraph.nodehasmark(node,\"TAO_f_mark\") && myrgraph.nodehasmark(node,\"TAO_r_mark\")) {\n"+
" myfgraph.marknode(node,\"TAO_t_mark\");\n"+
((Program.dbg)?" System.err.println(\" includes: \"+node.toString());\n":"")+
" } }\n"+
" myfgraph.clearmark(\"TAO_f_mark\");\n"+
" myrgraph.clearmark(\"TAO_r_mark\");\n"+
((Program.dbg)?" System.err.println(\"done\");\n":"")+
" }\n"+
" }\n"+
" }\n"+
"\n"+
" @"+")}."));
// System.err.println("TAO_NextTrav");
prog.addClassDef(ClassDef.parse("TAO_NextTrav *parse* = \"then\" <trav> TAO_TravList. \n"));
// System.err.println("TAO_Bypass");
prog.addClassDef(ClassDef.parse(
"TAO_Bypass *parse* = \"bypassing\" <bypass> TAO_ClassNames \n"+
" { ("+"@ public Vector toVector() { Vector v = new Vector(); bypass.allClassNames(v); return v;} \n"+
" @"+") }.\n"));
// System.err.println("TAO_TravLabel");
prog.addClassDef(ClassDef.parse("TAO_TravLabel *parse* = <travlab> Ident \"=\".\n"));
prog.addClassDef(ClassDef.parse(
"TAO_ClassNames *parse* : TAO_OneClassGlob | TAO_ClassGlobSet \n"+
"{ ("+"@ public Vector toVector() { Vector v = new Vector(); allClassNames(v); return v;} \n"+
" public void allClassNames(Vector v) {System.out.println(\"ClassNames should be overridden.\");}"+
" @"+")}."));
prog.addClassDef(ClassDef.parse(
"TAO_OneClassGlob *parse* = <classglob> TAO_ClassGlob {("+"@\n"+
"public void allClassNames(Vector v) {get_classglob().allClassNames(v);} @"+")} ."));
prog.addClassDef(ClassDef.parse(
"TAO_ClassGlobSet *parse* = \"{\" <classglobs> TAO_ClassGlobList \"}\" {("+"@ \n"+
"public void allClassNames(Vector v) {get_classglobs().allClassNames(v);} @"+")} ."));
prog.addClassDef(ClassDef.parse(
"TAO_ClassGlobList *parse* = <classglob> TAO_ClassGlob [ <next> TAO_NextClassGlob] {("+"@ \n"+
"public void allClassNames(Vector v) {get_classglob().allClassNames(v); if (get_next() != null) get_next().allClassNames(v);} @"+")} ."));
prog.addClassDef(ClassDef.parse(
"TAO_NextClassGlob *parse* = \",\" <classgloblist> TAO_ClassGlobList {("+"@ \n"+
"public void allClassNames(Vector v) {get_classgloblist().allClassNames(v);} @"+")} ."));
prog.addClassDef(ClassDef.parse(
"TAO_ClassGlob *parse* : TAO_AnyClass | TAO_ClassName {("+"@ \n"+
"public void allClassNames(Vector v) {System.out.println(\"TAO_ClassGlob override\");} @"+")} ."));
prog.addClassDef(ClassDef.parse(
"TAO_AnyClass *parse* = \"*\" {("+"@ \n"+
"public void allClassNames(Vector v) {System.err.println(\"Help\");} @"+")} ."));
prog.addClassDef(ClassDef.parse(
"TAO_ClassName *parse* = <name> Ident {("+"@ \n"+
"public void allClassNames(Vector v) { \n"+
" if (!v.contains(name)) v.addElement(name); } @"+")} ."));
// finally, connect up the backlinks.
prog.setInheritanceLinks();
}
@)
}
Program{
(@
public static void addToUserCodeTAO() {
// see if doug's wrapper info can remove the fvtv visitor.
fvtv = new FindVisitorTargetsV();
prog.findVisitorTargets(fvtv);
CreateMethodsV cmv = new CreateMethodsV(fvtv.get_btargets(),fvtv.get_atargets(),fvtv.get_aroundtargets() );
prog.makemethods(cmv);
}
@)
}
{ Program, ClassDef }{
traversal makemethods(CreateMethodsV cmv) {
to{ ClassDef, ConstructionClass, AlternationClass, OptionalPart, Part, Subclass, ClassParents, AlternationClass };
}
}
Program{
traversal findVisitorTargets(FindVisitorTargetsV fvtv) {
through Wrapper to{ Before, After, Around, ClassNameExact, AnyClass };
}
}
FindVisitorTargetsV{
init (@
btargets = new Vector();
atargets = new Vector();
aroundtargets = new Vector();
@)
before ClassDef (@ visitorname = host.get_classname().toString();
if (Program.dbg) System.err.println("looking for wrappers in "+visitorname);
@)
before Before (@ doing = btargets;
if (Program.dbg) System.err.println(" seeing Before wrappers");
@)
before After (@ doing = atargets;
if (Program.dbg) System.err.println(" seeing After wrappers");
@)
before Around (@
doing = aroundtargets;
if (Program.dbg) System.err.println(" seeing Around wrappers");
@)
before ClassNameExact (@
if (Program.dbg) System.err.println(" "+host.get_classname());
if (!doing.contains(host.get_classname()))
doing.addElement(host.get_classname());
@)
before AnyClass (@
// BUG: a bit of one, at least....
System.err.println("OOPS! died trying to goto all classes");
System.exit(1);
@)
after Program (@
// now go through the two arrays and mark any class wiht an active superclass as active
for (Enumeration cds = Program.prog.get_cg().defdict.elements(); cds.hasMoreElements();) {
ClassDef cd = (ClassDef) cds.nextElement();
ClassName cdn = cd.get_classname();
if (!btargets.contains(cdn)) {
ClassDef tcd = cd;
tcd = tcd.get_superclass_def();
while (tcd != null) {
if (btargets.contains(tcd.get_classname())) {
btargets.addElement(cdn);
if (Program.dbg) System.err.println("Before v in "+cdn);
break;
}
tcd = tcd.get_superclass_def();
}
} else if (Program.dbg) System.err.println("Before v in "+cdn);
if (!atargets.contains(cdn)) {
ClassDef tcd = cd;
tcd = tcd.get_superclass_def();
while (tcd != null) {
if (atargets.contains(tcd.get_classname())) {
atargets.addElement(cdn);
if (Program.dbg) System.err.println("After v in "+cdn);
break;
}
tcd = tcd.get_superclass_def();
}
} else if (Program.dbg) System.err.println("After v in "+cdn);
if (!aroundtargets.contains(cdn)) {
ClassDef tcd = cd;
tcd = tcd.get_superclass_def();
while (tcd != null) {
if (aroundtargets.contains(tcd.get_classname())) {
aroundtargets.addElement(cdn);
if (Program.dbg) System.err.println("Around v in "+cdn);
break;
}
tcd = tcd.get_superclass_def();
}
} else if (Program.dbg) System.err.println("Around v in "+cdn);
}
@)
}
CreateMethodsV{
(@
public CreateMethodsV(Vector b, Vector a, Vector ar) {
btargets = b;
atargets = a;
aroundtargets = ar;
}
@)
}
CreateMethodsV{
before Program (@
makeprotomain = "";
pathtravmain = "";
graphstr = "";
visitorstr = "";
doneclasses = new Vector();
baseclassname = "";
@)
around ClassDef (@
// perhaps abort if we come into an alternation class first?
// don't do the added classes or classes already done
abort = Program.TAOclasses.contains(host.get_classname().toString()) ;
if (abort) return;
// used in alternation hierarchies to check for *common* edges
// from the flattened location, ie the _construction_ class at
// the base of the hierarchy. This will be set to the last seen
// construction class, so it might seem that we will get
// erroneous results if we see a construction class, and then an
// unrelated alternation class, but the computations affected by
// this value (makeprotoparts) is only used by construction
// classes, so it is harmless. Probably needs more expl.
if (host.isConstructionClass()) set_baseclassname(host.get_classname().toString());
set_makeprotoparts("");
set_hierarchy(new Vector());
set_partstr("");
set_partcounter(1); // 0 is used as the classname checker.
// first we do any superclass, if thsi is an alternation:
ClassDef wcd = host.get_superclass_def();
if (wcd != null)
wcd.makemethods(this); // use this visitor, so partstr and friends gets set
get_hierarchy().addElement(host.get_classname());
set_traverseparts("");
set_subclassstr("");
set_subclasscounter(1);
set_makeprotosubclasses("");
set_traversesubclasses("");
set_abort(false);
set_classname(host.get_classname().toString());
set_rcd(host);
set_optionalpart(false);
if (!doneclasses.contains(get_classname())) {
makeBeforeVisitorStuff();
makeAfterVisitorStuff();
makeprotomain = makeprotomain +
" if (cn.equals(\""+classname+"\")) makeproto_"+classname+"(ht,pgt"+((Program.dbg)?", indent":"")+"); \n";
pathtravmain = pathtravmain +
" if ((instobj instanceof "+classname+") && (fromclasses.contains(new Ident(\""+classname+"\")))) { (("+classname+") instobj).prototrav_"+classname+"((Object[]) protoobj.get(\""+classname+"\"),visitors"+((Program.dbg)?", indent":"")+"); return ;}\n";
visitorstr=visitorstr+
" void before("+classname+" foo) {}\n void after("+classname+" foo) {}\n void around(AroundContinuation subtraversal, "+classname+" foo) {subtraversal.apply();}\n";
}
// the parts
subtraversal.apply();
if (!doneclasses.contains(get_classname())) {
String runaround =
" AroundContinuation cont_foo = new AroundContinuation() {public void apply() {subtraversal.apply(); parttrav_"+get_classname()+"(protoobj,visitors"+((Program.dbg)?",indent":"")+"); }}; \n"+
((get_aroundtargets().contains(get_classname()))
?" final "+get_classname()+" oldthis = this;\n"+
" for (int i = visitors.length -1; i >= 0 ; i-- ) {\n"+
" final int j = i;\n final AroundContinuation cont_bar = cont_foo; \n"+
" cont_foo = new AroundContinuation() {public void apply() { visitors[j].around(cont_bar, oldthis);}}; } \n"
:"");
rcd.addMethod(Verbatim.parse("("+"@\n"+
" public void runwrappers_"+get_classname()+"(final Object[] protoobj,final "+Program.visitorclass+"[] visitors"+((Program.dbg)?",final int indent":"")+",final AroundContinuation subtraversal) {\n"+
// ((Program.dbg)?"System.err.println(\"Protoobject is of type:\"+(String) protoobj[0]+\" and this is a "+get_classname()+"\"); \n":"")+
((get_btargets().contains(get_classname()))?" runBeforeVisitors_"+get_classname()+"(visitors);\n":"")+
runaround+" cont_foo.apply();\n"+
((get_atargets().contains(get_classname()))?" runAfterVisitors_"+get_classname()+"(visitors);\n":"")+
" } // end of runwrappers\n\n"+
"@"+")\n"));
rcd.addMethod(Verbatim.parse("("+"@\n"+
" public void parttrav_"+get_classname()+"(final Object[] protoobj,final "+Program.visitorclass+"[] visitors"+((Program.dbg)?",final int indent":"")+") {\n"+
traverseparts+
"} @"+")\n"));
doneclasses.addElement(get_classname());
}
@)
before ConstructionClass (@
if (abort) return;
if (Program.dbg) System.err.print("\n Construction: "+get_classname());
@)
before AlternationClass (@
if (abort) return;
if (Program.dbg) System.err.print("\n Alternation: "+ get_classname());
@)
before OptionalPart (@ optionalpart = true; @)
after OptionalPart (@ optionalpart = false; @)
before Part (@
if (abort) return;
PartName partname = host.get_partname();
ClassName partclass = host.get_classname();
// only traverse .cd defined classes
if (! Program.prog.get_cg().definesClass(partclass)) return;
if ( Program.TAOclasses.contains(partclass.toString())) return;
if (Program.dbg) System.err.print(" "+partname+":"+partcounter);
makeprotoparts = makeprotoparts +
((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\" making part: "+classname+"=>"+partclass+"\"); \n":"")+
" arr["+partcounter+"] = ((pgt.edgeexists(new Ident(\""+baseclassname+"\"),new Ident(\""+partname+"\")))?makeproto_"+partclass+"(ht,pgt"+((Program.dbg)?",indent+1":"")+"):null); \n";
traverseparts = traverseparts +
" if (protoobj["+partcounter+"] != null) "+((optionalpart)?"if (get_"+partname+"() != null)":"")+" {\n"+
((Program.dbg)?"Traversal.printindented(\"prototrav \",indent,\""+classname+"->"+partname+"\");\n":"")+
" get_"+partname+"().prototrav_"+partclass+"((Object []) protoobj["+partcounter+"],visitors"+((Program.dbg)?",indent+1":"")+");\n"+
" }\n";
partstr = partstr + partname+" "+partclass+" ";
partcounter++;
@)
before Subclass (@
if (abort) return;
ClassName partclass = host.get_classname();
if (! Program.prog.get_cg().definesClass(partclass)) return; // only traverse .cd defined classes
String partname = "_"+partclass.toString().toLowerCase();
if (Program.dbg) System.err.print(" "+partname+":"+subclasscounter);
traversesubclasses = traversesubclasses +
" if ((protoobj["+subclasscounter+"] != null) && (this instanceof "+partclass+")) {\n"+
((Program.dbg)?"Traversal.printindented(\"prototrav \",indent,\""+classname+"=> "+partname+"\");\n":"")+
" (("+partclass+") this).prototrav_"+partclass+"((Object []) protoobj["+subclasscounter+"],visitors"+((Program.dbg)?",indent+1":"")+");\n"+
" }\n";
makeprotosubclasses = makeprotosubclasses +
((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\" making part: "+classname+"=>"+partclass+"\"); \n":"")+
" arr["+subclasscounter+"] = ((pgt.edgeexists(new Ident(\""+classname+"\"),new Ident(\""+partname+"\")))? makeproto_"+partclass+"(ht,pgt"+((Program.dbg)?",indent+1":"")+"):null);\n";
subclassstr = subclassstr + partname+" "+partclass+" ";
subclasscounter++;
@)
after ConstOrAltClass (@
if (abort) return;
if (doneclasses.contains(get_classname())) return;
if (rcd.isAlternationClass()) {
rcd.addMethod(Verbatim.parse(
"("+"@\n public void prototrav_"+get_classname()+"(Object[] protoobj,"+Program.visitorclass+"[] visitors"+((Program.dbg)?",int indent":"")+") {\n"+
((Program.dbg)?"System.err.println(\"Protoobject is of type:\"+(String) protoobj[0]+\" and this is a "+get_classname()+"\");\n":"")+
traversesubclasses +
" } // end of prototrav\n\n@"+")"));
ClassDef tcd = (ClassDef) Program.prog.findClassDef(ClassName.parse("Traversal"));
if (tcd == null) System.err.println("No class Traversal was found.");
tcd.addMethod(Verbatim.parse(
"("+"@\n"+
" public static Object[] makeproto_"+get_classname()+"(Hashtable ht,Graph pgt"+((Program.dbg)?",int indent":"")+") { \n" +
" // first check that this class belongs in the traversal. \n" +
" if (! pgt.nodehasmark(new Ident(\""+get_classname()+"\"),\"TAO_t_mark\")) { \n"+
((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\""+get_classname()+" not in graph\");\n":"")+
" return null;}\n"+
" // if this class has an entry already, then return the entry, else make it and recurse for children \n" +
((Program.dbg)?"System.err.println(\"makeproto "+get_classname()+" in graph\");\n":"")+
" if (ht.containsKey(\""+get_classname()+"\")) { \n"+
" return (Object[]) ht.get(\""+get_classname()+"\");\n"+
" } \n"+
" Object[] arr = new Object["+subclasscounter+"];\n"+
" ht.put(\""+get_classname()+"\",arr);\n\n"+
" arr[0] = \""+get_classname()+"\";\n"+
makeprotosubclasses+"\n"+
" return arr;\n"+
" } // end makeproto \n\n @"+")"));
graphstr = graphstr + get_classname()+" ( "+(subclasscounter-1) +" "+subclassstr+") ";
}
// else!
if (rcd.isConstructionClass()) {
String makeconts = "";
Enumeration hclasses= hierarchy.elements();
ClassName thisclass = null;
ClassName lowerclass = (ClassName) hclasses.nextElement(); // there is at least one element- this class!
// while loop for all non concrete classes in the alterantion chain, from the top
while (hclasses.hasMoreElements()) {
thisclass = lowerclass;
lowerclass = (ClassName) hclasses.nextElement();
String subcall = "runwrappers_"+lowerclass+"(protoobj,visitors"+((Program.dbg)?", indent":"")+",cont_"+lowerclass+");";
makeconts =
" final AroundContinuation cont_"+thisclass+" = new AroundContinuation() { public void apply() { "+
subcall+
"}}; \n" + makeconts;
}
// so there is one more class to do: the concrete one: lowerclass
// This is just an empty placeholder, to be handed to runWrappers
makeconts =
" final AroundContinuation cont_"+lowerclass+" = new AroundContinuation() { public void apply() {}}; \n "+
makeconts;
rcd.addMethod(Verbatim.parse(
"("+"@\n"+
" public void prototrav_"+get_classname()+"(final Object[] protoobj, final "+Program.visitorclass+"[] visitors"+((Program.dbg)?",final int indent":"")+") {\n"+
makeconts+
" runwrappers_"+((ClassName) hierarchy.firstElement())+"(protoobj,visitors"+((Program.dbg)?",indent":"")+",cont_"+((ClassName) hierarchy.firstElement())+"); \n"+
" } // end of prototrav\n\n"+
"@"+")\n"));
ClassDef tcd = (ClassDef) Program.prog.findClassDef(ClassName.parse("Traversal"));
if (tcd == null) System.err.println("No class Traversal was found.");
tcd.addMethod(Verbatim.parse(
"("+"@\n"+
" public static Object[] makeproto_"+get_classname()+"(Hashtable ht,Graph pgt"+((Program.dbg)?",int indent":"")+") { \n" +
" // first check that this class belongs in the traversal. \n" +
" if (! pgt.nodehasmark(new Ident(\""+get_classname()+"\"),\"TAO_t_mark\")) { \n"+
((Program.dbg)?"Traversal.printindented(\"makeproto \",indent,\""+get_classname()+" not in graph\");\n":"")+
" return null;}\n"+
" // if this class has an entry already, then return the entry, else make it and recurse for children \n" +
((Program.dbg)?"System.err.println(\"makeproto "+get_classname()+" in graph\");\n":"")+
" if (ht.containsKey(\""+get_classname()+"\")) { \n"+
" return (Object[]) ht.get(\""+get_classname()+"\");\n"+
" } \n"+
" Object[] arr = new Object["+partcounter+"];\n"+
" ht.put(\""+get_classname()+"\",arr);\n\n"+
" arr[0] = \""+get_classname()+"\";\n"+
makeprotoparts+"\n"+
" return arr;\n"+
" } // end makeproto \n\n @"+")"));
graphstr = graphstr + get_classname()+" ( "+(partcounter-1) +" "+partstr+") ";
}
@)
after Program (@
ClassDef tcd = (ClassDef) Program.prog.findClassDef(ClassName.parse("Traversal"));
if (tcd == null) System.err.println("No class Traversal was found.");
// the makeproto and pathtrav dispatch code.
tcd.addMethod(Verbatim.parse(
"("+"@\n"+
" public static void makeproto(String cn, Hashtable ht,Graph pgt"+((Program.dbg)?",int indent":"")+") { \n" +
makeprotomain+"\n"+
" } // end makeproto \n\n @"+")"));
tcd.addMethod(Verbatim.parse(
"("+"@\n"+
" public static void pathtrav(Hashtable protoobj,Vector fromclasses, Object instobj, "+Program.visitorclass+"[] visitors"+((Program.dbg)?", int indent":"")+") {;\n"+
pathtravmain+
" // if we reach this spot, we were unable to dispatch the traversal, so cry foul \n"+
" System.err.println(\"Pathtrav on \"+instobj+\" failed to be found as a fromclass of the traversal\"); System.exit(1);\n"+
" } // end pathtrav \n\n @"+")"));
// visitor
ClassDef vcd = (ClassDef) Program.prog.findClassDef(ClassName.parse(Program.visitorclass));
if (vcd == null)
System.err.println("All visitors to be used with TAO must subclass "+Program.visitorclass+". \nYour program has no "+Program.visitorclass+" class");
// we'll die later on...
vcd.addMethod(Verbatim.parse("("+"@\n"+visitorstr+" @"+")"));
// the cd graph init code
tcd.addMethod(Verbatim.parse(
"("+"@ static { set_graph(Graph.fromString(\""+graphstr+"\")); } @"+")"));
// We also need to let Traversal know which classes are alternation classes.
if (Program.dbg) System.err.println("");
@)
(@
// This code prints out some java level mumbo of the class
public void makeBeforeVisitorStuff() {
if (!get_btargets().contains(get_classname())) return;
// if no before visitors, don't even output code
StringWriter vis_baos = new StringWriter();
PrintWriter vis_behout = new PrintWriter(vis_baos);
vis_behout.print("("+"@\n");
vis_behout.print(" public void runBeforeVisitors_"+get_classname()+"("+Program.visitorclass+"[] visitors) {\n");
ClassName supcn = rcd.get_superclass_name();
if ((supcn != null) && (get_btargets().contains(supcn))) // if superclass has befores, runem
vis_behout.print(" runBeforeVisitors_"+rcd.get_superclass_name()+"(visitors);\n");
if (Program.dbg) vis_behout.print(" System.err.println(\"before visitors for "+get_classname()+"\");\n");
vis_behout.print(" int len = visitors.length ; \n");
vis_behout.print(" for (int i = 0; i < len ; i++ ) \n");
vis_behout.print(" visitors[i].before(this);\n");
vis_behout.print(" }\n @"+")");
vis_baos.flush();
rcd.addMethod(Verbatim.parse(vis_baos.toString()));
}
@)
(@
public void makeAfterVisitorStuff() {
if (!get_atargets().contains(get_classname())) return;
StringWriter vis_baos = new StringWriter();
PrintWriter vis_behout = new PrintWriter(vis_baos);
vis_behout.print("("+"@\n");
vis_behout.print(" public void runAfterVisitors_"+get_classname()+"("+Program.visitorclass+"[] visitors) {\n");
if (Program.dbg) vis_behout.print(" System.err.println(\"after visitors for "+get_classname()+"\");\n");
vis_behout.print(" for (int i = visitors.length -1; i >= 0 ; i-- ) \n");
vis_behout.print(" visitors[i].after(this); \n");
ClassName supcn = rcd.get_superclass_name();
if ((supcn != null) && (get_atargets().contains(supcn))) // if superclass has befores, runem
vis_behout.print(" runAfterVisitors_"+rcd.get_superclass_name()+"(visitors);\n");
vis_behout.print(" }\n @"+")");
vis_baos.flush();
rcd.addMethod(Verbatim.parse(vis_baos.toString()));
}
@)
}