1 /*
   2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package build.tools.jdwpgen;
  27 
  28 
  29 import java.util.*;
  30 import java.io.*;
  31 
  32 abstract class Node {
  33 
  34     String kind;
  35     List<Node> components;
  36     int lineno;
  37     List<String> commentList = new ArrayList<>();
  38     Node parent = null;
  39     Context context = null;
  40 
  41     static final int maxStructIndent = 5;
  42     static int structIndent = 0; // horrible hack
  43 
  44     abstract void document(PrintWriter writer);
  45 
  46     void set(String kind, List<Node> components, int lineno) {
  47         this.kind = kind;
  48         this.components = components;
  49         this.lineno = lineno;
  50     }
  51 
  52     void parentAndExtractComments() {
  53         for (Iterator<Node> it = components.iterator(); it.hasNext();) {
  54             Node node = it.next();
  55             if (node instanceof CommentNode) {
  56                 it.remove();
  57                 commentList.add(((CommentNode)node).text());
  58             } else {
  59                 node.parent = this;
  60                 node.parentAndExtractComments();
  61             }
  62         }
  63     }
  64 
  65     void prune() {
  66         for (Node node : components) {
  67             node.prune();
  68         }
  69     }
  70 
  71     void constrain(Context ctx) {
  72         context = ctx;
  73         for (Node node : components) {
  74             constrainComponent(ctx, node);
  75         }
  76     }
  77 
  78     void constrainComponent(Context ctx, Node node) {
  79         node.constrain(ctx);
  80     }
  81 
  82     void indent(PrintWriter writer, int depth) {
  83         for (int i = 0; i < depth; i++) {
  84             writer.print("    ");
  85         }
  86     }
  87 
  88     void documentIndex(PrintWriter writer) {
  89     }
  90 
  91     String indentElement(int depth, String content) {
  92         return depth > 0
  93                 ? "<div class=\"indent" + depth + "\">" + content + "</div>"
  94                 : content;
  95     }
  96 
  97     String comment() {
  98         StringBuffer comment = new StringBuffer();
  99         for (String st : commentList) {
 100             comment.append(st);
 101         }
 102         return comment.toString();
 103     }
 104 
 105     void genJavaComment(PrintWriter writer, int depth) {
 106         if (commentList.size() > 0) {
 107             indent(writer, depth);
 108             writer.println("/**");
 109             for (String comment : commentList) {
 110                 indent(writer, depth);
 111                 writer.println(" * " + comment);
 112             }
 113             indent(writer, depth);
 114             writer.println(" */");
 115         }
 116     }
 117 
 118     String javaType() {
 119         return "-- WRONG ---";
 120     }
 121 
 122     void genJava(PrintWriter writer, int depth) {
 123         for (Node node : components) {
 124             node.genJava(writer, depth);
 125         }
 126     }
 127 
 128     void genCInclude(PrintWriter writer) {
 129         for (Node node : components) {
 130             node.genCInclude(writer);
 131         }
 132     }
 133 
 134     String debugValue(String label) {
 135         return label;
 136     }
 137 
 138     void genJavaDebugWrite(PrintWriter writer, int depth,
 139                            String writeLabel) {
 140         genJavaDebugWrite(writer, depth, writeLabel, debugValue(writeLabel));
 141     }
 142 
 143     void genJavaDebugWrite(PrintWriter writer, int depth,
 144                            String writeLabel, String displayValue) {
 145         if (!Main.genDebug) {
 146             return;
 147         }
 148         indent(writer, depth);
 149         writer.println(
 150           "if ((ps.vm.traceFlags & VirtualMachineImpl.TRACE_SENDS) != 0) {");
 151         indent(writer, depth+1);
 152         writer.print("ps.vm.printTrace(\"Sending: ");
 153         indent(writer, depth);  // this is inside the quotes
 154         writer.print(writeLabel + "(" + javaType() + "): \" + ");
 155         writer.println(displayValue + ");");
 156         indent(writer, depth);
 157         writer.println("}");
 158     }
 159 
 160     public void genJavaRead(PrintWriter writer, int depth,
 161                             String readLabel) {
 162         error("Internal - Should not call Node.genJavaRead()");
 163     }
 164 
 165     void genJavaDebugRead(PrintWriter writer, int depth,
 166                           String readLabel, String displayValue) {
 167         if (!Main.genDebug) {
 168             return;
 169         }
 170         indent(writer, depth);
 171         writer.println(
 172           "if (vm.traceReceives) {");
 173         indent(writer, depth+1);
 174         writer.print("vm.printReceiveTrace(" + depth + ", \"");
 175         writer.print(readLabel + "(" + javaType() + "): \" + ");
 176         writer.println(displayValue + ");");
 177         indent(writer, depth);
 178         writer.println("}");
 179     }
 180 
 181     void genJavaPreDef(PrintWriter writer, int depth) {
 182         for (Node node : components) {
 183             node.genJavaPreDef(writer, depth);
 184         }
 185     }
 186 
 187     void error(String errmsg) {
 188         System.err.println();
 189         System.err.println(Main.specSource + ":" + lineno + ": " +
 190                            kind + " - " + errmsg);
 191         System.err.println();
 192         throw new RuntimeException("Error: " + errmsg);
 193     }
 194 }