/*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.max.jdwp.generate;
import java.io.*;
import java.util.*;
/**
* @author JDK7: jdk/make/tools/src/build/tools/jdwpgen
*/
class SelectNode extends AbstractGroupNode implements TypeNode {
private TypeNode typeNode;
@Override
void prune() {
super.prune();
final Iterator it = components.iterator();
if (it.hasNext()) {
final Node typeNode = (Node) it.next();
if (typeNode.javaType().equals("byte") || typeNode.javaType().equals("int")) {
this.typeNode = (AbstractSimpleTypeNode) typeNode;
it.remove();
} else {
error("Select must be based on 'int' or 'byte'");
}
} else {
error("empty");
}
}
@Override
void constrain(Context ctx) {
super.constrain(ctx);
if (components.size() < 2) {
error("Select must have at least two options");
}
}
@Override
void constrainComponent(Context ctx, Node node) {
node.constrain(ctx);
if (!(node instanceof AltNode)) {
error("Select must consist of selector followed by Alt items");
}
}
String commonBaseClass() {
return name() + "Common";
}
private String commonVar() {
return "a" + commonBaseClass();
}
private String commonVarField() {
return commonVar();
}
@Override
void genJavaClassSpecifics(PrintWriter writer, int depth) {
indent(writer, depth);
writer.println("public abstract static class " + commonBaseClass() + " {");
indent(writer, depth + 1);
writer.println("public abstract void write(JDWPOutputStream ps) throws java.io.IOException;");
indent(writer, depth + 1);
writer.println("public abstract void read(JDWPInputStream ps) throws java.io.IOException, JDWPException;");
if (!context.isWritingCommand()) {
indent(writer, depth + 1);
writer.println("public abstract " + typeNode.javaParam() + "();");
}
indent(writer, depth);
writer.println("}");
typeNode.genJavaDeclaration(writer, depth);
indent(writer, depth);
writer.println("public " + commonBaseClass() + " " + commonVarField() + ";");
super.genJavaClassSpecifics(writer, depth);
}
@Override
void genJavaClassBodyComponents(PrintWriter writer, int depth) {
// don't naively include alt components
}
@Override
void genJavaReadingClassBody(PrintWriter writer, int depth, String className) {
writer.println();
indent(writer, depth);
writer.print("public " + className + "(" + typeNode.javaParam() + ", ");
writer.print(commonBaseClass() + " " + commonVar());
writer.println(") {");
indent(writer, depth + 1);
writer.println("this." + typeNode.fieldName() + " = " + typeNode.name() + ";");
indent(writer, depth + 1);
writer.println("this." + commonVarField() + " = " + commonVar() + ";");
indent(writer, depth);
writer.println("}");
writer.println();
indent(writer, depth);
writer.print("public " + className + "(");
writer.println(") {");
indent(writer, depth);
writer.println("}");
indent(writer, depth);
writer.println("public void read(JDWPInputStream ps) throws java.io.IOException, JDWPException {");
genJavaReads(writer, depth + 1);
indent(writer, depth);
writer.println("}");
indent(writer, depth);
writer.println("public void write(JDWPOutputStream ps) throws java.io.IOException {");
genJavaWrites(writer, depth + 1);
indent(writer, depth);
writer.println("}");
indent(writer, depth);
writer.println("@Override");
indent(writer, depth);
writer.println("public String toString() {");
indent(writer, depth + 1);
writer.println("final StringBuilder stringBuilder = new StringBuilder();");
genJavaToString(writer, depth + 1);
indent(writer, depth + 1);
writer.println("return stringBuilder.toString();");
indent(writer, depth);
writer.println("}");
}
@Override
void genJavaWritingClassBody(PrintWriter writer, int depth, String className) {
writer.println();
indent(writer, depth);
writer.print("public " + className + "(" + typeNode.javaParam() + ", ");
writer.print(commonBaseClass() + " " + commonVar());
writer.println(") {");
indent(writer, depth + 1);
writer.println("this." + typeNode.fieldName() + " = " + typeNode.name() + ";");
indent(writer, depth + 1);
writer.println("this." + commonVarField() + " =" + commonVar() + ";");
indent(writer, depth);
writer.println("}");
}
@Override
void genJavaWrites(PrintWriter writer, int depth) {
typeNode.genJavaWrite(writer, depth, typeNode.fieldName());
indent(writer, depth);
writer.println(commonVarField() + ".write(ps);");
}
@Override
void genJavaToString(PrintWriter writer, int depth) {
typeNode.genJavaToString(writer, depth, typeNode.fieldName());
indent(writer, depth);
writer.println("stringBuilder.append(" + commonVarField() + ");");
}
@Override
void genJavaReads(PrintWriter writer, int depth) {
typeNode.genJavaRead(writer, depth, typeNode.fieldName());
indent(writer, depth);
writer.println("switch (" + typeNode.fieldName() + ") {");
for (final Iterator it = components.iterator(); it.hasNext();) {
final AltNode alt = (AltNode) it.next();
alt.genJavaReadsSelectCase(writer, depth + 1, commonVarField());
}
indent(writer, depth);
writer.println("}");
indent(writer, depth);
writer.println(commonVarField() + ".read(ps);");
}
@Override
public void genJavaDeclaration(PrintWriter writer, int depth) {
typeNode.genJavaDeclaration(writer, depth);
super.genJavaDeclaration(writer, depth);
}
@Override
public String javaParam() {
return typeNode.javaParam() + ", " + name() + " a" + name();
}
public TypeNode typeNode() {
return typeNode;
}
}