diff options
author | paltherr <paltherr@epfl.ch> | 2003-04-14 11:05:43 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2003-04-14 11:05:43 +0000 |
commit | 0aa5643808efec65ae5fccbd40fc97bebf0de526 (patch) | |
tree | d0deb3d8f142e7626acc63ad46e70ef85c401d88 /sources/meta/java | |
parent | 8f51cb5a38a44f1f9f8074db476545eb57bb12d9 (diff) | |
download | scala-0aa5643808efec65ae5fccbd40fc97bebf0de526.tar.gz scala-0aa5643808efec65ae5fccbd40fc97bebf0de526.tar.bz2 scala-0aa5643808efec65ae5fccbd40fc97bebf0de526.zip |
- Added AbstractJavaExpander.java
- Added JavaWriter.java
- Added Type.java
Diffstat (limited to 'sources/meta/java')
-rw-r--r-- | sources/meta/java/AbstractJavaExpander.java | 49 | ||||
-rw-r--r-- | sources/meta/java/JavaWriter.java | 394 | ||||
-rw-r--r-- | sources/meta/java/Type.java | 152 |
3 files changed, 595 insertions, 0 deletions
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(); + } + + //######################################################################## +} |