summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/list/meta.lst4
-rw-r--r--sources/meta/java/AbstractJavaExpander.java49
-rw-r--r--sources/meta/java/JavaWriter.java394
-rw-r--r--sources/meta/java/Type.java152
4 files changed, 599 insertions, 0 deletions
diff --git a/config/list/meta.lst b/config/list/meta.lst
index 0438674c3a..8011ee20ba 100644
--- a/config/list/meta.lst
+++ b/config/list/meta.lst
@@ -7,4 +7,8 @@ util/AbstractFileExpander.java
util/TextExpander.java
util/TextWriter.java
+java/AbstractJavaExpander.java
+java/JavaWriter.java
+java/Type.java
+
##############################################################################
diff --git a/sources/meta/java/AbstractJavaExpander.java b/sources/meta/java/AbstractJavaExpander.java
new file mode 100644
index 0000000000..c633ef8c45
--- /dev/null
+++ b/sources/meta/java/AbstractJavaExpander.java
@@ -0,0 +1,49 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package meta.java;
+
+import meta.util.TextWriter;
+import meta.util.AbstractFileExpander;
+
+/** A base class for java file expanders. */
+public abstract class AbstractJavaExpander extends AbstractFileExpander {
+
+ //########################################################################
+ // Public Fields
+
+ /** The underlying java writer */
+ public final JavaWriter writer;
+
+ //########################################################################
+ // Public Constructors
+
+ public AbstractJavaExpander() {
+ this.writer = new JavaWriter(getPackage());
+ }
+
+ //########################################################################
+ // Public Methods
+
+ /** Returns the TextWriter in which this expander writes. */
+ public TextWriter getTextWriter() {
+ return writer.getTextWriter();
+ }
+
+ /** Returns the suffix of the target file. Returns "java". */
+ public String getTargetSuffix() {
+ return "java";
+ }
+
+ /** Prints the import statements. */
+ public void printImports() {
+ writer.printImports();
+ }
+
+ //########################################################################
+}
diff --git a/sources/meta/java/JavaWriter.java b/sources/meta/java/JavaWriter.java
new file mode 100644
index 0000000000..d0106f3215
--- /dev/null
+++ b/sources/meta/java/JavaWriter.java
@@ -0,0 +1,394 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package meta.java;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.TreeSet;
+
+import meta.util.TextWriter;
+import meta.util.TextExpander;
+
+/** A string generator with support for java source code generation. */
+public class JavaWriter {
+
+ //########################################################################
+ // Public Constants
+
+ /** The width of a separator */
+ public static final int SEPARATOR_WIDTH = 78;
+
+ //########################################################################
+ // Private Fields
+
+ /** The underlying text writer */
+ private final TextWriter writer;
+
+ /** The current package */
+ private final String peckage;
+
+ /** List of imports on-demand */
+ private final Set/*<String>*/ owners;
+
+ /** List of explicit imports (maps short names to full names) */
+ private final Map/*<String,String>*/ types;
+
+ //########################################################################
+ // Public Constructors
+
+ /** Creates a new JavaPrinter with no current package. */
+ public JavaWriter() {
+ this((String)null);
+ }
+
+ /** Creates a new JavaPrinter with the given current package. */
+ public JavaWriter(String peckage) {
+ this(new TextWriter(" "), peckage);
+ }
+
+ /** Creates a new JavaPrinter with no current package. */
+ public JavaWriter(TextWriter writer) {
+ this(writer, null);
+ }
+
+ /** Creates a new JavaPrinter with the given current package. */
+ public JavaWriter(TextWriter writer, String peckage) {
+ this.writer = writer;
+ this.peckage = peckage;
+ this.owners = new HashSet();
+ this.types = new HashMap();
+ }
+
+ //########################################################################
+ // Public Methods - Importing types
+
+ /** Returns the current package. */
+ public String getPackage() {
+ return peckage;
+ }
+
+ /** Returns true if the given type needs to be fully qualified. */
+ public boolean needsQualification(Type type) {
+ type = type.getBaseType();
+ String owner = type.getOwner();
+ if (owner == null) return true;
+ Object current = types.get(type.getName());
+ if (current != null) return !type.getFullName().equals(current);
+ return !owner.equals(getPackage()) && !owners.contains(owner);
+ }
+
+ /** If necessary, adds an explicit import for the given type. */
+ public void importType(Type type) {
+ importType(type, false);
+ }
+
+ /** If necessary, adds an explicit import for the given type. */
+ public void importType(Type type, boolean force) {
+ type = type.getBaseType();
+ String owner = type.getOwner();
+ if (owner == null) return;
+ if (!force && owner.equals(getPackage())) return;
+ if (!force && owners.contains(owner)) return;
+ String shortname = type.getName();
+ String longname = type.getFullName();
+ Object current = types.get(shortname);
+ if (current == null) {
+ types.put(shortname, longname);
+ } else if (!longname.equals(current)) {
+ throw new Error();
+ }
+ }
+
+ /** Adds an import on demand for members of the given type. */
+ public void importFrom(Type type) {
+ importFrom(type.getFullName());
+ }
+
+ /** Adds an import on demand for members of the given owner. */
+ public void importFrom(String owner) {
+ owners.add(owner);
+ }
+
+ //########################################################################
+ // Public Methods - Printing java statements and expressions
+
+ /** Prints a package statement for the current package. */
+ public JavaWriter printPackage() {
+ return getPackage() == null ? this : printPackage(getPackage());
+ }
+
+ /** Prints a package statement. */
+ public JavaWriter printPackage(String peckage) {
+ return print("package ").print(peckage).println(";");
+ }
+
+ /** Prints an import statement. */
+ public JavaWriter printImport(String inport) {
+ return print("import ").print(inport).println(";");
+ }
+
+ /** Prints import statements for the current imports. */
+ public JavaWriter printImports() {
+ return printImports(getImports());
+ }
+
+ /** Prints a list of import statements. */
+ public JavaWriter printImports(Set imports) {
+ for (Iterator i = imports.iterator(); i.hasNext(); )
+ printImport((String)i.next());
+ if (imports.size() > 0) println();
+ return this;
+ }
+
+ /** Prints a "do not edit" comment. */
+ public JavaWriter printDoNotEdit() {
+ return printComment(TextExpander.DO_NOT_EDIT);
+ }
+
+ /** Prints a single-line Java documentation comment. */
+ public JavaWriter printDescription(String line) {
+ return print("/** ").print(line).println(" */");
+ }
+
+ /** Prints a multi-line Java documentation comment. */
+ public JavaWriter printDescription(String[] lines) {
+ println("/**");
+ for (int i = 0; i < lines.length; i++) print(" * ").println(lines[i]);
+ return println(" */");
+ }
+
+ /** Prints a single-line comment. */
+ public JavaWriter printComment(String comment) {
+ return print("// ").println(comment);
+ }
+
+ /** Prints a separator. */
+ public JavaWriter printSeparator() {
+ println().print("//");
+ int width = SEPARATOR_WIDTH - 2 - getIndentLevel() * getIndentWidth();
+ for (int i = 0; i < width; i++) print("#");
+ return println();
+ }
+
+ /** Prints a separator with the given title. */
+ public JavaWriter printSeparator(String title) {
+ return printSeparator().printComment(title).println();
+ }
+
+ /** Prints a separator with the given title and subtitle. */
+ public JavaWriter printSeparator(String title, String subtitle) {
+ return printSeparator(title + " - " + subtitle);
+ }
+
+ //########################################################################
+ // Public Methods - Printing simple values
+
+ /** Prints a new line. */
+ public JavaWriter println() {
+ return line();
+ }
+
+ /** Prints the boolean value followed by a new line. */
+ public JavaWriter println(boolean value) {
+ return print(value).line();
+ }
+
+ /** Prints the byte value followed by a new line. */
+ public JavaWriter println(byte value) {
+ return print(value).line();
+ }
+
+ /** Prints the short value followed by a new line. */
+ public JavaWriter println(short value) {
+ return print(value).line();
+ }
+
+ /** Prints the char value followed by a new line. */
+ public JavaWriter println(char value) {
+ return print(value).line();
+ }
+
+ /** Prints the int value followed by a new line. */
+ public JavaWriter println(int value) {
+ return print(value).line();
+ }
+
+ /** Prints the long value followed by a new line. */
+ public JavaWriter println(long value) {
+ return print(value).line();
+ }
+
+ /** Prints the float value followed by a new line. */
+ public JavaWriter println(float value) {
+ return print(value).line();
+ }
+
+ /** Prints the double value followed by a new line. */
+ public JavaWriter println(double value) {
+ return print(value).line();
+ }
+
+ /** Prints the string followed by a new line. */
+ public JavaWriter println(String value) {
+ return print(value).line();
+ }
+
+ /** Prints the type followed by a new line. */
+ public JavaWriter println(Type value) {
+ return print(value).line();
+ }
+
+ /** Prints the boolean value. */
+ public JavaWriter print(boolean value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the byte value. */
+ public JavaWriter print(byte value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the short value. */
+ public JavaWriter print(short value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the char value. */
+ public JavaWriter print(char value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the int value. */
+ public JavaWriter print(int value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the long value. */
+ public JavaWriter print(long value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the float value. */
+ public JavaWriter print(float value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the long value. */
+ public JavaWriter print(double value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the string. */
+ public JavaWriter print(String value) {
+ writer.print(value);
+ return this;
+ }
+
+ /** Prints the type. */
+ public JavaWriter print(Type value) {
+ return print(value.getName(needsQualification(value)));
+ }
+
+ //########################################################################
+ // Public Methods - Formating
+
+ /** Returns the indentation width. */
+ public int getIndentWidth() {
+ return writer.getIndentWidth();
+ }
+
+ /** Returns the indentation level. */
+ public int getIndentLevel() {
+ return writer.getIndentLevel();
+ }
+
+ /** Returns the indentation level. */
+ public JavaWriter setIndentLevel(int level) {
+ writer.setIndentLevel(level);
+ return this;
+ }
+
+ /** Increases the indentation level by one. */
+ public JavaWriter indent() {
+ writer.indent();
+ return this;
+ }
+
+ /** Decreases the indentation level by one. */
+ public JavaWriter undent() {
+ writer.undent();
+ return this;
+ }
+
+ /** Starts a new line. */
+ public JavaWriter line() {
+ writer.line();
+ return this;
+ }
+
+ /** Inserts a white space. */
+ public JavaWriter space() {
+ writer.space();
+ return this;
+ }
+
+ /** Prints an opening brace followed by a new line. */
+ public JavaWriter lbrace() {
+ return space().println("{").indent();
+ }
+
+ /** Prints a closing brace followed by a new line. */
+ public JavaWriter rbrace() {
+ return undent().space().println("}");
+ }
+
+ //########################################################################
+ // Public Methods - Accessing
+
+ /** Returns the underlying StringBuffer. */
+ public TextWriter getTextWriter() {
+ return writer;
+ }
+
+ /** Returns the underlying StringBuffer. */
+ public StringBuffer getBuffer() {
+ return writer.getBuffer();
+ }
+
+ /** Returns the generated string. */
+ public String toString() {
+ return writer.toString();
+ }
+
+ //########################################################################
+ // Private Methods
+
+ /** Returns the current list of imports (explicit and on-demand). */
+ private Set getImports() {
+ Set imports = new TreeSet();
+ for (Iterator i = owners.iterator(); i.hasNext(); )
+ imports.add(i.next() + ".*");
+ for (Iterator i = types.values().iterator(); i.hasNext(); )
+ imports.add(i.next());
+ return imports;
+ }
+
+ //########################################################################
+}
diff --git a/sources/meta/java/Type.java b/sources/meta/java/Type.java
new file mode 100644
index 0000000000..0d4545cbd4
--- /dev/null
+++ b/sources/meta/java/Type.java
@@ -0,0 +1,152 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package meta.java;
+
+/** A representation for Java types. */
+public class Type {
+
+ //########################################################################
+ // Public Constants
+
+ /** The Java primitive type void */
+ public static final Type VOID = Primitive("void");
+
+ /** The Java primitive type boolean */
+ public static final Type BOOLEAN = Primitive("boolean");
+
+ /** The Java primitive type byte */
+ public static final Type BYTE = Primitive("byte");
+
+ /** The Java primitive type short */
+ public static final Type SHORT = Primitive("short");
+
+ /** The Java primitive type char */
+ public static final Type CHAR = Primitive("char");
+
+ /** The Java primitive type int */
+ public static final Type INT = Primitive("int");
+
+ /** The Java primitive type long */
+ public static final Type LONG = Primitive("long");
+
+ /** The Java primitive type float */
+ public static final Type FLOAT = Primitive("float");
+
+ /** The Java primitive type double */
+ public static final Type DOUBLE = Primitive("double");
+
+ //########################################################################
+ // Public Cases
+
+ /** A primitive type */
+ public case Primitive(String name);
+
+ /** A reference type (the owner may be null) */
+ public case Reference(String owner, String name);
+
+ /** An array type */
+ public case Array(Type item);
+
+ //########################################################################
+ // Public Methods
+
+ /** Returns the type's fully qualified name. */
+ public String getFullName() {
+ return getName(true);
+ }
+
+ /** Returns the type's short name. */
+ public String getName() {
+ return getName(false);
+ }
+
+ /** Returns the type's (possibly fully qualified) name. */
+ public String getName(boolean qualified) {
+ switch (this) {
+ case Primitive(String name):
+ return name;
+ case Reference(String owner, String name):
+ return qualified && owner != null ? owner + "." + name : name;
+ case Array(Type item):
+ return item.getName(qualified) + "[]";
+ default:
+ throw new Error("illegal case: " + getName(true));
+ }
+ }
+
+ /** Returns the type's owner (its package or enclosing type). */
+ public String getOwner() {
+ switch (this) {
+ case Primitive(_):
+ return null;
+ case Reference(String owner, _):
+ return owner;
+ case Array(Type item):
+ return item.getOwner();
+ default:
+ throw new Error("illegal case: " + getName(true));
+ }
+ }
+
+ /** If this is an array type, returns the type of the elements. */
+ public Type getItemType() {
+ switch (this) {
+ case Array(Type item):
+ return item;
+ default:
+ throw new Error("not an array type: " + getName(true));
+ }
+ }
+
+ /** Returns the base type of this type. */
+ public Type getBaseType() {
+ return isArray() ? getItemType() : this;
+ }
+
+ /** Returns true if this is a primitive type. */
+ public boolean isPrimitive() {
+ switch (this) {
+ case Primitive(_):
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /** Returns true if this is an array type. */
+ public boolean isArray() {
+ switch (this) {
+ case Array(_):
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns the string representation of an array instantiation
+ * with the given bounds and whose elements are of this type.
+ */
+ public String newArray(String bounds) {
+ switch (this) {
+ case Array(Type item):
+ return item.newArray(bounds + "[]");
+ default:
+ return this + bounds;
+ }
+ }
+
+
+ /** Returns the string representation of this type. */
+ public String toString() {
+ return getName();
+ }
+
+ //########################################################################
+}