gencopyvis.beh.html

Program{
	void addCopyVisitor(String name)(@
    addClassDef(ClassDef.parse("*notparsed* *visitor*" + name
			       + " = <copy> *derived* Object."));
  @)
	void generateCopyVisitor(String name, File file)=allParts{
		before Program (@
      host.openOutputFile(file);
      Program.out.println(
 "// This file is automatically generated by Demeter/Java.\n"
+"\n"
+ name + " {\n"
+"  " + Text.begin + "\n"
+"    private java.util.Stack history = new java.util.Stack();\n"
+"    public " + name + "(Class firstClass) {\n"
+"      try {\n"
+"        history.push(firstClass.newInstance());\n"
+"      } catch(Exception e) {\n"
+"        e.printStackTrace();\n"
+"      }\n"
+"    }\n"
+"  " + Text.end + "\n"
+"  get copy " + Text.begin + " return history.peek(); " + Text.end + "\n"
+"  return Object " + Text.begin + " get_copy() " + Text.end + "\n"
+"\n"
      );
    @)
		(@ ClassName classname; @)
		before ClassDef (@ classname = host.get_classname(); @)
		before Part (@
      // Don't copy final, static or derived members.
      if (host.isFinal() || host.isStatic() || host.isDerived()) return;
      PartName part = host.get_partname();
      ClassName dest = host.get_classname();
      ClassDef def = Program.prog.findClassDef(dest);
      String s = "    " + classname + " it = "
				    + "(" + classname + ") history.peek();\n";
      if (def == null) {
	// Terminal part.
	// if (dest.isKnownTerminal()) {
	  s += "    it.set_" + part + "(dest);\n";
	/*
	 * This doesn't compile because CloneNotSupportedException is
	 * never thrown!  Sigh.
	} else {
	  s += "    try {\n"
	    + "      it.set_" + partname
	    + "((" + dest + ") dest.clone());\n"
	    + "    } catch (CloneNotSupportedException e) {\n"
	    + "      it.set_" + partname + "(dest);\n"
	    + "    }\n";
	}
	 */
      } else if (def.isAlternationClass()) {
	s +="    Class c = dest.getClass();\n"
	  + "    Object p = null;\n"
	  + "    try {\n"
	  + "      p = c.newInstance();\n"
	  + "    } catch(Exception e) {\n"
	  + "      e.printStackTrace();\n"
	  + "    }\n"
	  + "    it.set_" + part + "((" + dest + ") p);\n"
	  + "    history.push(p);\n";
      } else {
	// it's a construction class
	s +="    " + dest + " p = new " + dest + "();\n"
	  + "    it.set_" + part + "(p);\n"
	  + "    history.push(p);\n";
      }
      Program.out.println(host.makeBefore(classname, s) + "\n");
      if (def != null) {
	Program.out.println(host.makeAfter(classname,
					   "    history.pop();\n") + "\n");
      }
    @)
		after Program (@
      Program.out.println("}");
      host.closeOutputFile();
    @)
	}
}