gencode.beh.html

Program{
	private void generateCode(boolean is_aspect, boolean is_html)=allClassDefs{
		before ClassDef (@
      ClassName c = host.get_classname();
      if(!is_html) {
      if (is_aspect) {
	Program.openOutputFile(new File(Program.prog.gendir, c + ".asp"));
	Program.out.println("core:");
      } else {
	Program.openJavaOutputFile(c);
      }
      Program.prog.generateHeader(is_aspect);
      if (is_aspect) {
	Program.out.print("add: ");
      }
      host.printKeywords();
      Program.out.print(c);
      host.printParents();
      Program.out.println(" {");
      if (!host.isInterface()) {
	host.generateStructureCode(is_aspect);
	host.generateConstructors(is_aspect);
	host.generateUtilCode(is_aspect);
      }
      host.generateBehaviorCode(is_aspect);
      Program.out.println("}");
      if (is_aspect) {
	Program.closeOutputFile();
      } else {
	Program.closeJavaOutputFile();
      }
      // HTML generate java files
      } else if(Program.prog.html && !is_aspect) {
	// determine needed filenames
	File javfile = new File(c + ".java");
	File htmlfile = new File(Program.htmlgendir, javfile.toString() + 
				 Program.htmlext);
        Program.addFiles(".java", new File(Program.gen.toString() + javfile.toString()));
        System.out.println("Creating " + htmlfile.toString() + "...");
	// write HTML preamble
	Program.openOutputFile(htmlfile);
	Program.htmlHeader(Program.out, htmlfile.getName());
	Program.out.println(Program.BODY);
	Program.out.println("<H2>" + htmlfile.getName() + "</H2>");
	Program.out.println(Program.BASE);
	Program.out.println(Program.PRE);
	Program.prog.generateHeader(is_aspect);
	if (is_aspect) {
	  Program.out.print("add: ");
	}
	host.printKeywords();
	// need HtmlVisitor to have java class hyperlink to other files
	HtmlVisitor hv = new HtmlVisitor(Program.out, javfile, Program.getHtmlClassNames());
	hv.htmlTagBeg(c.toString());
	Program.out.print(c);
	hv.htmlTagEnd();
	host.printParents();
	Program.out.println(" {");
	if (!host.isInterface()) {
	  host.generateStructureCode(is_aspect);
	  host.generateConstructors(is_aspect);
	  host.generateUtilCode(is_aspect);
	}
	host.generateBehaviorCode(is_aspect);
	Program.out.println("}");
	Program.out.println(Program._PRE);
	Program.out.println(Program._BODY);
	Program.htmlFooter(Program.out);
      }
    @)
	}
	void generateHeader(boolean is_aspect)to{ Package, Import, Preamble }{
		before Program (@
      if (is_aspect) Program.out.println(Text.begin);
    @)
		before{ Package, Import }(@ Program.out.println(host); @)
		before Preamble (@ Program.out.println(host.get_javacode().get_code()); @)
		after Program (@
      Program.out.println("import EDU.neu.ccs.demeter.*;");
      if (is_aspect) Program.out.println(Text.end);
    @)
	}
}

ClassDef{
	void printKeywords()to{ PublicClass, FinalClass, AlternationClass, InterfaceClass }{
		(@ String cl = "class "; @)
		before PublicClass (@ Program.out.print("public "); @)
		before FinalClass (@ Program.out.print("final "); @)
		before AlternationClass (@ Program.out.print("abstract "); @)
		before InterfaceClass (@ cl = "interface "; @)
		after ClassDef (@ Program.out.print(cl); @)
	}
}

ClassDef{
	void printParents()to ClassParents{
		(@ boolean isInterface; @)
		before ClassDef (@ isInterface = host.isInterface(); @)
		before ClassParents (@
      if (host.get_superclasses() != null)
	Program.out.print(" extends " + host.get_superclasses());
      if (!isInterface) {
	Program.out.print(" implements ");
	if (host.get_interfaces() != null)
	  Program.out.print(host.get_interfaces() + ", ");
	Program.out.print("Cloneable");
      }
    @)
	}
}

ClassDef{
	void generateStructureCode(boolean is_aspect)=allParts{
		before Part (@ host.print(is_aspect); @)
	}
}

Part{
	void print(boolean is_aspect)(@
    if (!isDerived()) {
      PartName part = get_partname();
      ClassName type = get_classname();

      printKeywords();
      Program.out.print("protected " + type + " " + part);
      if (partinit != null) {
	Program.out.print(" =" + 
	    (is_aspect ? " " + partinit.get_javacode()
		       : partinit.get_javacode().get_code() + ";"));
      } else {
	Program.out.println(";");
      }
      // For now, make getter and setter package-scope instead of
      // omitting them.
      String open = (is_aspect ? Text.begin : "{");
      String close = (is_aspect ? Text.end : "}");

      printKeywords();
      Program.out.println((hasGetter() ? "public " : " ") + type +
			  " get_" + part + "()" + " " +
			  open + " return " + part + "; " + close);
      if (!isFinal()) {
	printKeywords();
	Program.out.println((hasSetter() ? "public " : " ") + "void" +
			   " set_" + part + "(" + type + " new_" + part + ")");
	Program.out.println("    " + open + " " + part +
					  " = new_" + part + "; " + close);
      }
    }
  @)
	void printKeywords()to{ FinalPart, StaticPart }{
		before Part (@ Program.out.print("  "); @)
		before FinalPart (@ Program.out.print("final "); @)
		before StaticPart (@ Program.out.print("static "); @)
	}
}

Parts{
	public Parts lisp_append(Parts list)(@
      Parts retval = new Parts();
      Enumeration e = this.elements();
      while (e.hasMoreElements()) retval.addElement((Part) e.nextElement());
      e = list.elements();
      while (e.hasMoreElements()) retval.addElement((Part) e.nextElement());
      return retval;
  @)
}

ClassDef{
	void generateConstructors(boolean is_aspect)(@
    String open = (is_aspect ? Text.begin : "{");
    String close = (is_aspect ? Text.end : "}");
    Parts parts = getParts();
    Parts superclassParts = getSuperclassParts();
    Parts allParts = superclassParts.lisp_append(parts);
    boolean hasParts = !allParts.isEmpty();
    boolean hasNoArgConstructor = hasNoArgConstructor();
    if (hasParts && !hasNoArgConstructor) {
      // no-arg constructor, can be called from same package only.
      // This is needed for, e.g., the parse functions.
      Program.out.print("  ");
      if (is_aspect) Program.out.print("constructor ");
      Program.out.println(get_classname() + "() " +
			  open + " super(); " + close);
    }
    if (hasParts || !hasNoArgConstructor) {
      Program.out.print("  public ");
      if (is_aspect) Program.out.print("constructor ");
      Program.out.print(get_classname() + "(");
      allParts.generateConstructorArgs();
      Program.out.println(") " + open);
      Program.out.print("    super(");
      superclassParts.generateConstructorSuperInit();
      Program.out.println(");");
      parts.generateConstructorInits();
      Program.out.println("  " + close);
    }
  @)
	private Parts getParts()=allParts{
		init (@ return_val = new Parts(); @)
		before Part (@
      if (!host.isFinal() && !host.isStatic() && !host.isDerived())
	return_val.addElement(host);
    @)
	}
	private Parts getSuperclassParts()(@
    ClassDef superclass = get_superclass_def();
    // A class might extend an external class, so the superclass might
    // not have a definition.
    if (superclass != null) {
      return superclass.getSuperclassParts()
		       .lisp_append(superclass.getParts());
    }
    return new Parts();
  @)
}

Parts{
	void generateConstructorArgs()(@
    boolean first = true;
    Enumeration e = elements();
    while (e.hasMoreElements()) {
      Part part = (Part) e.nextElement();
      if (first) first = false; else Program.out.print(", ");
      Program.out.print(part.get_classname() + " " + part.get_partname());
    }
  @)
	void generateConstructorSuperInit()(@
    boolean first = true;
    Enumeration e = elements();
    while (e.hasMoreElements()) {
      Part part = (Part) e.nextElement();
      if (first) first = false; else Program.out.print(", ");
      Program.out.print(part.get_partname());
    }
  @)
	void generateConstructorInits()(@
    Enumeration e = elements();
    while (e.hasMoreElements()) {
      PartName part = ((Part) e.nextElement()).get_partname();
      Program.out.println("    set_" + part + "(" + part + ");");
    }
  @)
}

ClassDef{
	(@
    void generateUtilCode(boolean is_aspect) {
      generateParseCode(is_aspect);
    }
  @)
}

ClassDef{
	void generateBehaviorCode(boolean is_aspect)bypassing VisitorSpec via{ MethodDef, Wrapper, Getter, Setter, Constructor, ReturnValue, Verbatim }to{ JavaCode, NoMethodBody }{
		(@ String open, close; @)
		(@ ClassDef classdef; ClassName classname; @)
		before ClassDef (@
      open = (is_aspect ? Text.begin : "{");
      close = (is_aspect ? Text.end : "}");
      classdef = host; classname = host.get_classname();
    @)
		(@ HostSpec hosts; @)
		before Method (@ hosts = null; @)
		before MethodDef (@
      Program.out.print("  " + host.get_methodsignature());
    @)
		before NoMethodBody (@
      Program.out.println(";");
    @)
		before VerbatimMethodBody (@
      Program.out.print(" " + open);
    @)
		(@ WrapperKind kind; @)
		before Wrapper (@
      hosts = host.get_hosts();
      kind = host.get_kind();
    @)
		(@ PartName partname; @)
		before Accessor (@
      partname = host.get_partname();
      classname = classdef.getPartClass(partname);
    @)
		before Getter (@ 
      Program.out.print("  " + classname + " get_" + partname + "() " + open);
    @)
		before Setter (@
      Program.out.print("  void set_" +partname+ "(" + classname + " dest) "
		        + open);
    @)
		before Constructor (@
      Program.out.print("  public " + classname + "() " + open);
    @)
		before ReturnValue (@
      Program.out.print("  " +host.get_type()+ " get_return_val() "
			+ open + " return");
    @)
		before Verbatim (@
      if (is_aspect) Program.out.print(Text.begin);
    @)
		before JavaCode (@
      if (hosts != null) {
	hosts.generateWrapperCode(kind, host.get_code());
      } else {
	Program.out.print(host.get_code());
      }
    @)
		after{ VerbatimMethodBody, Accessor, Constructor }(@
      Program.out.println(close);
    @)
		after ReturnValue (@
      Program.out.println("; " + close);
    @)
		after Verbatim (@
      if (is_aspect) Program.out.println(Text.end);
    @)
	}
}