diff options
Diffstat (limited to 'sources')
285 files changed, 0 insertions, 82498 deletions
diff --git a/sources/MANIFEST b/sources/MANIFEST deleted file mode 100644 index cca1bee615..0000000000 --- a/sources/MANIFEST +++ /dev/null @@ -1 +0,0 @@ -Main-Class: scala.compiler.Main diff --git a/sources/ch/epfl/lamp/util/CodePrinter.java b/sources/ch/epfl/lamp/util/CodePrinter.java deleted file mode 100644 index 7bce133a43..0000000000 --- a/sources/ch/epfl/lamp/util/CodePrinter.java +++ /dev/null @@ -1,277 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package ch.epfl.lamp.util; - -import java.io.Writer; -import java.io.StringWriter; -import java.io.IOException; - -/** - * This class provides methods for printing code. It has support for - * indentation and spacing. - */ -public class CodePrinter { - - //######################################################################## - // Public Constants - - /** The default indentation string */ - public static final String STEP = " "; - - /** The line separator */ - public static final String LINE = System.getProperty("line.separator"); - - //######################################################################## - // Private Fields - - /** The underlying writer */ - private final Writer writer; - - /** The indentation string */ - private String step; - - /** The indentation level */ - private int level; - - /** Do we need to align? */ - private boolean align; - - /** Do we need to print a white space? */ - private boolean space; - - /** Is there already a empty line? */ - private boolean line; - - //######################################################################## - // Public Constructors - - /** Creates a new instance. */ - public CodePrinter() { - this(new StringWriter()); - } - - /** Creates a new instance. */ - public CodePrinter(String step) { - this(new StringWriter(), step); - } - - /** Creates a new instance. */ - public CodePrinter(Writer writer) { - this(writer, STEP); - } - - /** Creates a new instance. */ - public CodePrinter(Writer writer, String step) { - this.writer = writer; - this.step = step; - this.level = 0; - this.align = true; - this.space = false; - this.line = false; - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** Returns the underlying writer. */ - public Writer getWriter() { - return writer; - } - - /** Returns the indentation level. */ - public int getIndentLevel() { - return level; - } - - /** Returns the indentation width. */ - public int getIndentWidth() { - return step == null ? -1 : step.length(); - } - - /** Returns the indentation string. */ - public String getIndentString() { - return step; - } - - /** Sets the indentation level. */ - public CodePrinter setIndentLevel(int level) { - this.level = level; - return this; - } - - /** Sets the indentation width. */ - public CodePrinter setIndentWidth(int width) { - StringBuffer buffer = new StringBuffer(width); - for (int i = 0; i < width; i++) buffer.append(' '); - return setIndentString(buffer.toString()); - } - - /** Sets the indentation string. */ - public CodePrinter setIndentString(String step) { - this.step = step; - return this; - } - - //######################################################################## - // Public Methods - Formating - - /** Increases the indentation level by one. */ - public CodePrinter indent() { - level++; - return this; - } - - /** Decreases the indentation level by one. */ - public CodePrinter undent() { - level--; - return this; - } - - /** Inserts a new line. */ - public CodePrinter line() { - if (step == null) return space(); - if (line) return this; - write(LINE); - line = align; - align = true; - space = false; - return this; - } - - /** Inserts a white space. */ - public CodePrinter space() { - space = !align; - return this; - } - - //######################################################################## - // Public Methods - Printing - - /** Prints a new line. */ - public CodePrinter println() { - return line(); - } - - /** Prints the boolean value followed by a new line. */ - public CodePrinter println(boolean value) { - return print(value).line(); - } - - /** Prints the byte value followed by a new line. */ - public CodePrinter println(byte value) { - return print(value).line(); - } - - /** Prints the short value followed by a new line. */ - public CodePrinter println(short value) { - return print(value).line(); - } - - /** Prints the char value followed by a new line. */ - public CodePrinter println(char value) { - return print(value).line(); - } - - /** Prints the int value followed by a new line. */ - public CodePrinter println(int value) { - return print(value).line(); - } - - /** Prints the long value followed by a new line. */ - public CodePrinter println(long value) { - return print(value).line(); - } - - /** Prints the float value followed by a new line. */ - public CodePrinter println(float value) { - return print(value).line(); - } - - /** Prints the double value followed by a new line. */ - public CodePrinter println(double value) { - return print(value).line(); - } - - /** Prints the string followed by a new line. */ - public CodePrinter println(String value) { - return print(value).line(); - } - - /** Prints the boolean value. */ - public CodePrinter print(boolean value) { - return print(String.valueOf(value)); - } - - /** Prints the byte value. */ - public CodePrinter print(byte value) { - return print(String.valueOf(value)); - } - - /** Prints the short value. */ - public CodePrinter print(short value) { - return print(String.valueOf(value)); - } - - /** Prints the char value. */ - public CodePrinter print(char value) { - return print(String.valueOf(value)); - } - - /** Prints the int value. */ - public CodePrinter print(int value) { - return print(String.valueOf(value)); - } - - /** Prints the long value. */ - public CodePrinter print(long value) { - return print(String.valueOf(value)); - } - - /** Prints the float value. */ - public CodePrinter print(float value) { - return print(String.valueOf(value)); - } - - /** Prints the long value. */ - public CodePrinter print(double value) { - return print(String.valueOf(value)); - } - - /** Prints the string. */ - public CodePrinter print(String value) { - if (align) for (int i = 0; i < level; i++) write(step); - if (space) write(" "); - write(value); - align = false; - space = false; - line = false; - return this; - } - - //######################################################################## - // Public Methods - Converting - - /** Returns the string representation of this printer. */ - public String toString() { - return writer.toString(); - } - - //######################################################################## - // Private Methods - - private void write(String string) { - try { - writer.write(string); - } catch (IOException exception) { - throw new Error(exception); - } - } - - //######################################################################## -} diff --git a/sources/ch/epfl/lamp/util/ForwardingMap.java b/sources/ch/epfl/lamp/util/ForwardingMap.java deleted file mode 100644 index 7efc3627b0..0000000000 --- a/sources/ch/epfl/lamp/util/ForwardingMap.java +++ /dev/null @@ -1,97 +0,0 @@ -package ch.epfl.lamp.util; - -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -/** - * This class implements the interface Map by forwarding all its - * operations to an underlying instance of Map. - */ -public class ForwardingMap implements Map { - - //######################################################################## - // Protected Fields - - protected final Map delegate; - - //######################################################################## - // Public Constructors - - public ForwardingMap(Map delegate) { - this.delegate = delegate; - } - - //######################################################################## - // Public Methods - Query operations - - public int size() { - return delegate.size(); - } - - public boolean isEmpty() { - return delegate.isEmpty(); - } - - public boolean containsKey(Object key) { - return delegate.containsKey(key); - } - - public boolean containsValue(Object value) { - return delegate.containsValue(value); - } - - public Object get(Object key) { - return delegate.get(key); - } - - //######################################################################## - // Public Methods - Modification operations - - public Object put(Object key, Object value) { - return delegate.put(key, value); - } - - public Object remove(Object key) { - return delegate.remove(key); - } - - //######################################################################## - // Public Methods - Bulk operations - - public void putAll(Map map) { - delegate.putAll(map); - } - - public void clear() { - delegate.clear(); - } - - //######################################################################## - // Public Methods - Views - - public Set keySet() { - return delegate.keySet(); - } - - public Collection values() { - return delegate.values(); - } - - public Set entrySet() { - return delegate.entrySet(); - } - - //######################################################################## - // Public Methods - Comparison and hashing - - public boolean equals(Object that) { - return delegate.equals(that); - } - - public int hashCode() { - return delegate.hashCode(); - } - - //######################################################################## -} diff --git a/sources/ch/epfl/lamp/util/HTMLPrinter.java b/sources/ch/epfl/lamp/util/HTMLPrinter.java deleted file mode 100644 index bc1afcd441..0000000000 --- a/sources/ch/epfl/lamp/util/HTMLPrinter.java +++ /dev/null @@ -1,886 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package ch.epfl.lamp.util; - -import java.io.Writer; - -/** - * This class provides methods to print HTML document. - * - * @author Stephane Micheloud - * @version 1.1 - */ -public class HTMLPrinter { - - public static final String DEFAULT_STYLESHEET = "style.css"; - public static final String DEFAULT_JAVASCRIPT = "script.js"; - - //######################################################################## - // Private Constants - - /* - * The characters which must be HTML encoded - */ - private static final Character AMP = new Character('&'); - private static final Character GT = new Character('>'); - private static final Character LT = new Character('<'); - private static final Character QUOT = new Character('"'); - - //######################################################################## - // Private Fields - - /** - * The underlying code printer. - */ - private final CodePrinter printer; - - /** - * The document title. - */ - private final String title; - - //######################################################################## - // Protected Fields - - /** - * The document representation. - */ - protected final HTMLRepresentation representation; - - /** - * The document stylesheet. - */ - protected final String stylesheet; - - /** - * The document script. - */ - protected final String script; - - //######################################################################## - // Public Constructors - - /** - * Creates a new instance. - * - * @param writer - * @param title - * @param representation - * @param stylesheet - * @param script - */ - public HTMLPrinter(Writer writer, String title, HTMLRepresentation representation, - String stylesheet, String script) - { - this.printer = new CodePrinter(writer, " "); - this.title = title; - this.representation = representation; - this.stylesheet = stylesheet; - this.script = script; - } - - /** - * Creates a new instance. - * - * @param writer - * @param title - * @param representation - * @param stylesheet - */ - public HTMLPrinter(Writer writer, String title, HTMLRepresentation representation, - String stylesheet) - { - this(writer, title, representation, stylesheet, DEFAULT_JAVASCRIPT); - } - - /** - * Creates a new instance. - * - * @param writer - * @param title - * @param representation - */ - public HTMLPrinter(Writer writer, String title, HTMLRepresentation representation) { - this(writer, title, representation, DEFAULT_STYLESHEET); - } - - /** - * Creates a new instance with "HTML 4.01 Transitional" as default - * document type. - * - * @param writer - * @param title - * @param encoding - */ - public HTMLPrinter(Writer writer, String title, String docencoding) { - this( - writer, - title, - new HTMLRepresentation(HTMLRepresentation.DEFAULT_DOCTYPE, docencoding) - ); - } - - /** - * Creates a new instance with "iso-8859-1" as default character encoding. - * - * @param writer - * @param title - */ - public HTMLPrinter(Writer writer, String title) { - this(writer, title, HTMLRepresentation.DEFAULT_DOCENCODING); - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** - * Returns the underlying code printer. - */ - public CodePrinter getCodePrinter() { - return printer; - } - - /** - * Returns the underlying title. - */ - public String getTitle() { - return title; - } - - //######################################################################## - // Public Methods - Character encoding - - /** - * Encodes the special character <code>ch</code> to its - * corresponding HTML encoding. - * - * @param ch - */ - public static String encode(Character ch) { - if (AMP.compareTo(ch) == 0) return "&"; - else if (GT.compareTo(ch) == 0) return ">"; - else if (LT.compareTo(ch) == 0) return "<"; - else if (QUOT.compareTo(ch) == 0) return """; - else return ch.toString(); - } - - /** - * Encodes the special characters to their corresponding HTML encodings. - * - * @param text - */ - public static String encode(String text) { - return text; - } - - //######################################################################## - // Public Methods - Formatting - - /** - * Increases the indentation level by one. - */ - public HTMLPrinter indent() { - printer.indent(); - return this; - } - - /** Decreases the indentation level by one. */ - public HTMLPrinter undent() { - printer.undent(); - return this; - } - - /** Inserts a new line. */ - public HTMLPrinter line() { - printer.line(); - return this; - } - - /** Inserts a white space. */ - public HTMLPrinter space() { - printer.space(); - return this; - } - - //######################################################################## - // Public Methods - Printing simple values followed by a new line - - /** Prints a new line. */ - public HTMLPrinter println() { - printer.println(); - return this; - } - - /** Prints the boolean value followed by a new line. */ - public HTMLPrinter println(boolean value) { - printer.println(value); - return this; - } - - /** Prints the byte value followed by a new line. */ - public HTMLPrinter println(byte value) { - printer.println(value); - return this; - } - - /** Prints the short value followed by a new line. */ - public HTMLPrinter println(short value) { - printer.println(value); - return this; - } - - /** Prints the char value followed by a new line. */ - public HTMLPrinter println(char value) { - printer.println(value); - return this; - } - - /** Prints the int value followed by a new line. */ - public HTMLPrinter println(int value) { - printer.println(value); - return this; - } - - /** Prints the long value followed by a new line. */ - public HTMLPrinter println(long value) { - printer.println(value); - return this; - } - - /** Prints the float value followed by a new line. */ - public HTMLPrinter println(float value) { - printer.println(value); - return this; - } - - /** Prints the double value followed by a new line. */ - public HTMLPrinter println(double value) { - printer.println(value); - return this; - } - - /** Prints the string followed by a new line. */ - public HTMLPrinter println(String value) { - printer.println(value); - return this; - } - - /** Prints the opening HTML tag followed by a new line. */ - public HTMLPrinter printlnOTag(String label) { - printer.print("<"); - printer.print(label); - printer.println(">"); - return this; - } - - /** Prints the HTML tag with attributes followed by a new line. */ - public HTMLPrinter printlnOTag(String label, XMLAttribute[] attrs) { - printer.print("<"); - printer.print(label); - printer.print(" "); - printer.print(StringOf.object.array(attrs, "", " ", "")); - printer.println(">"); - return this; - } - - /** Prints the closing HTML tag followed by a new line. */ - public HTMLPrinter printlnCTag(String label) { - printer.print("</"); - printer.print(label); - printer.println(">"); - return this; - } - - /** - * Prints HTML tag with label and contents followed by a new line. - * - * @param label - * @param text - */ - public HTMLPrinter printlnTag(String label, String text) { - printlnOTag(label); - print(text); - return printlnCTag(label); - } - - /** - * Prints the HTML tag <code>label</code> with attributes <code>attrs</code> - * and contents <code>text</code> followed by a new line. - * - * @param label - * @param attrs - * @param text - */ - public HTMLPrinter printlnTag(String label, XMLAttribute[] attrs, String text) { - printOTag(label, attrs); - print(text); - return printlnCTag(label); - } - - /** - * Prints the short HTML tag followed by a new line. - * - * @param label - */ - public HTMLPrinter printlnSTag(String label) { - printer.print("<"); - printer.print(label); - printer.println("/>"); - return this; - } - - /** - * Prints the short HTML tag with attributes <code>attrs</code> - * followed by a new line. - * - * @param label - * @param attrs - */ - public HTMLPrinter printlnSTag(String label, XMLAttribute[] attrs) { - printer.print("<"); - printer.print(label); - printer.print(" "); - printer.print(StringOf.object.array(attrs, "", " ", "")); - printer.println("/>"); - return this; - } - - /** - * Prints <A HREF=link> text </a> tag followed by a new line. - * - * @param dest - * @param text - */ - public HTMLPrinter printlnAhref(String dest, String text) { - printOTag("a", new XMLAttribute[]{ new XMLAttribute("href", dest) }); - print(text); - return printlnCTag("a"); - } - - /** - * Prints <A HREF=dest TARGET=target> text </a> tag followed by a new line. - * - * @param dest - * @param target - * @param text - */ - public HTMLPrinter printlnAhref(String dest, String target, String text) { - printOTag("a", new XMLAttribute[]{ - new XMLAttribute("href", dest), - new XMLAttribute("target", target)}); - print(text); - return printlnCTag("a"); - } - - /** - * Prints <A NAME=name> text </a> tag followed by a new line. - * - * @param anchor - * @param text - */ - public HTMLPrinter printlnAname(String anchor, String text) { - printOTag("a", new XMLAttribute[]{new XMLAttribute("name", anchor)}); - print(text); - return printlnCTag("a"); - } - - /** - * Prints text <code>text</code> in bold followed by a new line. - * - * @param text - */ - public HTMLPrinter printlnBold(String text) { - return printlnTag("b", text); - } - - /** - * Prints text <code>text</code> in color <code>color</code> followed by a new line. - * - * @param color - * @param text - */ - public HTMLPrinter printlnFontColor(String color, String text) { - return printlnTag( - "font", - new XMLAttribute[]{ new XMLAttribute("color", color)}, - text); - } - - /** - * Prints comment with contents <code>text</code> followed by a new line. - * - * @param text - */ - public HTMLPrinter printlnComment(String text) { - printer.print("<!--"); - printer.print(text); - printer.println("-->"); - return this; - } - - /** - * Prints script followed by a new line. - * - * @param script - */ - public HTMLPrinter printlnScript(String script) { - printOTag("script", new XMLAttribute[]{ - new XMLAttribute("type", "text/javascript"), - new XMLAttribute("src", script) - }); - return printlnCTag("script"); - } - - /** - * Prints <code>n</code> HTML blank spaces followed by a new line. - * - * @param n The parameter <code>n</code> gives the number - * of printed blank spaces - */ - public HTMLPrinter printlnNbsp(int n) { - return printNbsp(n).line(); - } - - /** - * Prints an horizontal line separator followed by a new line. - */ - public HTMLPrinter printlnHLine() { - return printlnOTag("hr"); - } - - /** - * Prints an horizontal line separator with attributes <code>attrs</code>. - * - * @param attrs - */ - public HTMLPrinter printlnHLine(XMLAttribute[] attrs) { - return printlnOTag("hr", attrs); - } - - /** - * Prints the <meta> tag with attributes 'attrs' followed by a new line. - * - * @param attrs - */ - public HTMLPrinter printlnMeta(XMLAttribute[] attrs) { - return printlnOTag("meta", attrs); - } - - /** - * Prints the <link> tag with attributes 'attrs' followed by a new line. - * - * @param attrs - */ - public HTMLPrinter printlnLink(XMLAttribute[] attrs) { - return printlnOTag("link", attrs); - } - - //######################################################################## - // Public Methods - Printing simple values - - /** Prints the boolean value. */ - public HTMLPrinter print(boolean value) { - printer.print(value); - return this; - } - - /** Prints the byte value. */ - public HTMLPrinter print(byte value) { - printer.print(value); - return this; - } - - /** Prints the short value. */ - public HTMLPrinter print(short value) { - printer.print(value); - return this; - } - - /** Prints the char value. */ - public HTMLPrinter print(char value) { - printer.print(value); - return this; - } - - /** Prints the int value. */ - public HTMLPrinter print(int value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public HTMLPrinter print(long value) { - printer.print(value); - return this; - } - - /** Prints the float value. */ - public HTMLPrinter print(float value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public HTMLPrinter print(double value) { - printer.print(value); - return this; - } - - /** Prints the string. */ - public HTMLPrinter print(String value) { - printer.print(value); - return this; - } - - /** Prints the opening HTML tag. */ - public HTMLPrinter printOTag(String label) { - printer.print("<"); - printer.print(label); - printer.print(">"); - return this; - } - - /** Prints the opening HTML tag 'label' with attributes 'attrs'. */ - public HTMLPrinter printOTag(String label, XMLAttribute[] attrs) { - printer.print("<"); - printer.print(label); - printer.print(" "); - printer.print(StringOf.object.array(attrs, "", " ", "")); - printer.print(">"); - return this; - } - - /** Prints the closing HTML tag 'label'. */ - public HTMLPrinter printCTag(String label) { - printer.print("</"); - printer.print(label); - printer.print(">"); - return this; - } - - /** - * Prints the HTML tag <code>label</code> with contents <code>text</code>. - * - * @param label - * @param text - */ - public HTMLPrinter printTag(String label, String text) { - printOTag(label); - print(text); - return printCTag(label); - } - - /** Prints the HTML tag 'label' with attributes 'attrs' and contents 'text'. */ - public HTMLPrinter printTag(String label, XMLAttribute[] attrs, String text) { - printOTag(label, attrs); - print(text); - printCTag(label); - return this; - } - - /** Prints the short HTML tag 'label'. */ - public HTMLPrinter printSTag(String label) { - printer.print("<"); - printer.print(label); - printer.print("/>"); - return this; - } - - /** Prints <A HREF=link> text </a> tag. */ - public HTMLPrinter printAhref(String dest, String text) { - printOTag("a", new XMLAttribute[]{ new XMLAttribute("href", dest) }); - print(text); - return printCTag("a"); - } - - /** Prints <A HREF=dest TARGET=target> text </a> tag. */ - public HTMLPrinter printAhref(String dest, String target, String text) { - printOTag("a", new XMLAttribute[]{ - new XMLAttribute("href", dest), - new XMLAttribute("target", target)}); - print(text); - return printCTag("a"); - } - - /** Prints <A NAME=name> text </a> tag. */ - public HTMLPrinter printAname(String anchor, String text) { - printOTag("a", new XMLAttribute[]{ new XMLAttribute("name", anchor) }); - print(text); - return printCTag("a"); - } - - /** - * Prints text <code>text</code> in bold. - * - * @param text - */ - public HTMLPrinter printBold(String text) { - return printTag("b", text); - } - - /** - * Prints text <code>text</code> in color <code>color</code>. - * - * @param color - * @param text - */ - public HTMLPrinter printFontColor(String color, String text) { - return printTag("font", new XMLAttribute[]{ new XMLAttribute("color", color) }, text); - } - - /** - * Prints comment with contents <code>text</code>. - * - * @param text - */ - public HTMLPrinter printComment(String text) { - printer.print("<!-- "); - printer.print(text); - printer.print(" -->"); - return this; - } - - /** - * Prints <code>n</code> HTML blank spaces. - * - * @param n The parameter <code>n</code> gives the number - * of printed blank spaces - */ - public HTMLPrinter printNbsp(int n) { - while (n > 0) { - print(" "); - n--; - } - return this; - } - - /** - * Prints an horizontal line separator. - */ - public HTMLPrinter printHLine() { - return printOTag("hr"); - } - - /** - * Prints an horizontal line separator with attributes <code>attrs</code>. - * - * @param attrs - */ - public HTMLPrinter printHLine(XMLAttribute[] attrs) { - return printOTag("hr", attrs); - } - - //######################################################################## - // Public Methods - Converting - - /** - * Returns the string representation of this printer. - */ - public String toString() { - return printer.toString(); - } - - //######################################################################## - - /** - * Prints the HTML preamble of the current page. - */ - protected void printPreamble() { - println("<!DOCTYPE html PUBLIC \"-//W3C//DTD " + - representation.getType() + "//" + representation.getLanguage() + "\">"); - printlnOTag("html").line(); - } - - /** - * Prints HTML meta informations. - * - * @param metaAttrs - */ - protected void printMetaInfo(XMLAttribute[] metaAttrs) { - printlnMeta(new XMLAttribute[]{ - new XMLAttribute("http-equiv", "content-type"), - new XMLAttribute("content", - "text/html; charset=" + representation.getEncoding())}); - for (int i = 0; i < metaAttrs.length; i++) { - printlnMeta(new XMLAttribute[]{ - new XMLAttribute("name", metaAttrs[i].name), - new XMLAttribute("content", metaAttrs[i].value)}); - } - } - - /** - * Prints HTML link information for the given stylesheet. - * - * @param stylesheet The stylesheet to be linked - * to the current HTML document - */ - protected void printlnStyle(String stylesheet) { - printlnLink(new XMLAttribute[]{ - new XMLAttribute("rel", "stylesheet"), - new XMLAttribute("type", "text/css"), - new XMLAttribute("href", stylesheet)}); - } - - /** - * Prints HTML header section of the current page. - * - * @param metaAttrs - * @param generator - * @param stylesheets - */ - public void printHeader(XMLAttribute[] metaAttrs, - String[] comments, String[] stylesheets, String[] scripts) - { - printPreamble(); - printlnOTag("head").indent(); - printlnTag("title", title); - for (int i = 0; i < comments.length; i++) - printlnComment(comments[i]); - printMetaInfo(metaAttrs); - for (int i = 0; i < stylesheets.length; i++) - printlnStyle(stylesheets[i]); - for (int i = 0; i < scripts.length; i++) - printlnScript(scripts[i]); - undent().printlnCTag("head").line(); - } - - /** - * Prints HTML header section. - * - * @param metaXMLAttributes - * @param generator - * @param stylesheet - */ - public void printHeader(XMLAttribute[] metaAttrs, String comment, - String stylesheet, String script) - { - printHeader(metaAttrs, - new String[]{ comment }, - new String[]{ stylesheet }, - new String[]{ script }); - } - - /** - * Prints HTML header section. - * - * @param metaXMLAttributes - * @param generator - * @param stylesheet - */ - public void printHeader(XMLAttribute[] metaAttrs, String comment, - String stylesheet) - { - printHeader(metaAttrs, comment, stylesheet, script); - } - - /** - * Prints HTML header section. - * - * @param metaXMLAttributes - * @param generator - */ - public void printHeader(XMLAttribute[] metaAttrs, String comment) { - printHeader(metaAttrs, comment, stylesheet); - } - - /** - * Prints the header section of the current page. - * - * @param metaXMLAttributes - */ - public void printHeader(XMLAttribute[] metaAttrs) { - printHeader(metaAttrs, null); - } - - /** - * Open the body section of the current page. - */ - public void printOpenBody(XMLAttribute[] attrs) { - printlnOTag("body", attrs).indent(); - } - - /** - * Open the body section of the current page. - */ - public void printOpenBody() { - printlnOTag("body").indent(); - } - - /** - * Prints the HTML footer of the current page. - */ - public void printFootpage() { - undent().printlnCTag("body"); - printlnCTag("html"); - } - - //######################################################################## -} - - -/** - * Map from Object to String. - */ -public abstract class StringOf { - - /** - * Gives the string representation of an object. - * - * @param o - */ - public abstract String element(Object o); - - /** - * Gives the string representation of an array of objects. - * Return delimiters for empty arrays depending on "delimWhenEmpty". - * - * @param objects - * @param open - * @param sep - * @param close - * @param delimWhenEmpty - */ - public String array(Object[] objects, String open, String sep, String close, boolean delimWhenEmpty) { - if ((objects.length == 0) && !delimWhenEmpty) - return ""; - else { - StringBuffer str = new StringBuffer(); - str.append(open); - if (objects.length > 0) { - str.append(element(objects[0])); - for(int i = 1; i < objects.length; i++) - str.append(sep + element(objects[i])); - } - str.append(close); - return str.toString(); - } - } - - /** - * Returns always delimiters. - * - * @param objects - * @param open - * @param sep - * @param close - */ - public String array(Object[] objects, String open, String sep, String close) { - return array(objects, open, sep, close, true); - } - - /** - * Basic map. - */ - public static StringOf object = new StringOf() { - public String element(Object o) { - return o.toString(); - } - }; - -} diff --git a/sources/ch/epfl/lamp/util/HTMLRepresentation.java b/sources/ch/epfl/lamp/util/HTMLRepresentation.java deleted file mode 100644 index debe5288bd..0000000000 --- a/sources/ch/epfl/lamp/util/HTMLRepresentation.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package ch.epfl.lamp.util; - -/** - * This class contains properties of HTML document representation - * (see http://www.w3.org/TR/REC-html40/charset.html). - */ -public class HTMLRepresentation { - - public static final String DEFAULT_DOCTYPE = "HTML 4.01 Transitional"; - public static final String DEFAULT_DOCENCODING = "iso-8859-1"; - public static final String DEFAULT_DOCLANGUAGE = "EN"; - - //######################################################################## - // Private Fields - - /** The document type */ - private final String doctype; - - /** The document character encoding */ - private final String docencoding; - - /** The document language */ - private final String language; - - //######################################################################## - // Public Constructors - - /** Creates a new instance */ - public HTMLRepresentation(String doctype, String docencoding, String language) { - this.doctype = doctype; - this.docencoding = docencoding; - this.language = language; - } - - /** Creates a new instance */ - public HTMLRepresentation(String doctype, String docencoding) { - this(doctype, docencoding, DEFAULT_DOCLANGUAGE); - } - - /** Creates a new instance */ - public HTMLRepresentation(String doctype) { - this(doctype, DEFAULT_DOCENCODING, DEFAULT_DOCLANGUAGE); - } - - /** Creates a new instance */ - public HTMLRepresentation() { - this(DEFAULT_DOCTYPE, DEFAULT_DOCENCODING, DEFAULT_DOCLANGUAGE); - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** - * Returns the underlying document type. - */ - public String getType() { - return doctype; - } - - /** - * Returns the underlying character encoding. - */ - public String getEncoding() { - return docencoding; - } - - /** - * Returns the underlying document language. - * - * @ return the language name of the underlying document - */ - public String getLanguage() { - return language; - } - - /** - * Returns <code>true</code> if the document type is HTML. - */ - public boolean isHTMLType() { - return doctype.toLowerCase().matches("^html\\p{Space}\\d\\.\\d.*"); - } - - /** - * Returns <code>true</code> if the document type is XHTML. - */ - public boolean isXHTMLType() { - return doctype.toLowerCase().matches("^xhtml\\p{Space}\\d\\.\\d.*"); - } - - //######################################################################## -} diff --git a/sources/ch/epfl/lamp/util/Pair.java b/sources/ch/epfl/lamp/util/Pair.java deleted file mode 100644 index 1b755ca18a..0000000000 --- a/sources/ch/epfl/lamp/util/Pair.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package ch.epfl.lamp.util; - -/** - * Pairs of values. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class Pair { - public final Object fst, snd; - public Pair(Object fst, Object snd) { - this.fst = fst; - this.snd = snd; - } - public String toString() { - return "Pair(" + fst + ", " + snd + ")"; - } -} diff --git a/sources/ch/epfl/lamp/util/XHTMLPrinter.java b/sources/ch/epfl/lamp/util/XHTMLPrinter.java deleted file mode 100644 index be76c45023..0000000000 --- a/sources/ch/epfl/lamp/util/XHTMLPrinter.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package ch.epfl.lamp.util; - -import java.io.Writer; - -/** - * This class provides methods to print XHTML document. - * - * @author Stephane Micheloud - * @version 1.1 - */ -public class XHTMLPrinter extends HTMLPrinter { - - //######################################################################## - // Public Constructors - - /** - * Creates a new instance. - * - * @param writer - * @param title - * @param representation - * @param stylesheet - * @param script - */ - public XHTMLPrinter(Writer writer, String title, HTMLRepresentation representation, - String stylesheet, String script) - { - super(writer, title, representation, stylesheet, script); - } - - /** - * Creates a new instance. - * - * @param writer - * @param title - * @param representation - * @param stylesheet - */ - public XHTMLPrinter(Writer writer, String title, HTMLRepresentation representation, - String stylesheet) - { - this(writer, title, representation, stylesheet, DEFAULT_JAVASCRIPT); - } - - /** - * Creates a new instance. - * - * @param writer - * @param title - * @param repr - */ - public XHTMLPrinter(Writer writer, String title, HTMLRepresentation representation) { - this(writer, title, representation, DEFAULT_STYLESHEET); - } - - /** - * Creates a new instance with "XHTML 1.0 Transitional" as default document type. - * - * @param writer - * @param title - * @param docencoding - */ - public XHTMLPrinter(Writer writer, String title, String docencoding) { - this(writer, title, new HTMLRepresentation("XHTML 1.0 Transitional", docencoding)); - } - - /** - * Creates a new instance with "utf-8" as default character encoding. - * - * @param writer - * @param title - */ - public XHTMLPrinter(Writer writer, String title) { - this(writer, title, "utf-8"); - } - - //######################################################################## - // Public Methods - Printing simple values followed by a new line - - /** - * Prints text <code>text</code> in bold followed by a new line. - * - * @param text - * @return the current HTML printer - */ - public HTMLPrinter printlnBold(String text) { - return printlnTag("span", - new XMLAttribute[]{ new XMLAttribute("style", "font-weight:bold;") }, - text); - } - - /** - * Prints an horizontal line separator followed by a new line. - * - * @return the current HTML printer - */ - public HTMLPrinter printlnHLine() { - printOTag("div", new XMLAttribute[] { - new XMLAttribute("style", "border:1px solid #aaaaaa; " + - "margin:10px 0px 5px 0px;height:1px;") }); - return printlnCTag("div"); - } - - //######################################################################## - // Public Methods - Printing simple values - - /** - * Prints text <code>text</code> in bold. - * - * @param text - * @return the current HTML printer - */ - public HTMLPrinter printBold(String text) { - return printTag("span", - new XMLAttribute[]{ new XMLAttribute("style", "font-weight:bold;") }, - text); - } - - /** - * Prints an horizontal line separator - * - * @return the current HTML printer - */ - public HTMLPrinter printHLine() { - printOTag("div", new XMLAttribute[] { - new XMLAttribute("style", "border:1px solid #aaaaaa; " + - "margin:10px 0px 5px 0px;height:1px;") }); - return printCTag("div"); - } - - /** - * Prints an horizontal line separator with attributes <code>attrs</code>. - * - * @param attrs - * @return the current HTML printer - */ - public HTMLPrinter printHLine(XMLAttribute[] attrs) { - return printHLine(); - } - - /** - * Prints the <meta/> tag with attributes <code>attrs</code> - * followed by a new line. - * - * @param attrs - * @return the current HTML printer - */ - public HTMLPrinter printlnMeta(XMLAttribute[] attrs) { - return printlnSTag("meta", attrs); - } - - /** - * Prints the <link> tag with attributes <code>attrs</code> - * followed by a new line. - * - * @param attrs - * @return the current HTML printer - */ - public HTMLPrinter printlnLink(XMLAttribute[] attrs) { - return printlnSTag("link", attrs); - } - - //######################################################################## - - /** - * Prints XHTML preamble. - */ - protected void printPreamble() { - println("<!--"); - println("< ?xml version=\"1.0\" encoding=\"" + - representation.getEncoding() + "\"?>"); - println("//-->"); - println("<!DOCTYPE html PUBLIC \"-//W3C//DTD " + - representation.getType() + "//" + representation.getLanguage() + - "\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); - println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"" + - representation.getLanguage() + "\">").line(); - } - - //######################################################################## -} diff --git a/sources/ch/epfl/lamp/util/XMLAttribute.java b/sources/ch/epfl/lamp/util/XMLAttribute.java deleted file mode 100644 index 309a4cc621..0000000000 --- a/sources/ch/epfl/lamp/util/XMLAttribute.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package ch.epfl.lamp.util; - -/** An XML attribute. - */ -public class XMLAttribute { - - /** Name of the attribute. - */ - public String name; - - /** Value of the attribute. - */ - public String value; - - public XMLAttribute(String name, String value) { - this.name = name; - this.value = value; - } - - public String toString() { - return name + "=\"" + value + "\""; - } -}
\ No newline at end of file diff --git a/sources/meta/GenerateAll.java b/sources/meta/GenerateAll.java deleted file mode 100644 index d522fbcb58..0000000000 --- a/sources/meta/GenerateAll.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta; - -import java.io.File; -import java.io.FileWriter; -import java.io.BufferedWriter; -import java.io.PrintWriter; -import java.io.PrintStream; -import java.io.IOException; - -import meta.util.AbstractMain; -import meta.util.AbstractFileExpander; -import meta.util.TextExpander; -import meta.util.TextWriter; - -/** A program that invokes all file generators. */ -public class GenerateAll extends AbstractMain { - - //######################################################################## - // Public Constants - - public static final AbstractFileExpander[] expanders = { - new meta.scala.MetaFunction(0), - new meta.scala.MetaFunction(1), - new meta.scala.MetaFunction(2), - new meta.scala.MetaFunction(3), - new meta.scala.MetaFunction(4), - new meta.scala.MetaFunction(5), - new meta.scala.MetaFunction(6), - new meta.scala.MetaFunction(7), - new meta.scala.MetaFunction(8), - new meta.scala.MetaFunction(9), - new meta.scala.MetaTuple(1), - new meta.scala.MetaTuple(2), - new meta.scala.MetaTuple(3), - new meta.scala.MetaTuple(4), - new meta.scala.MetaTuple(5), - new meta.scala.MetaTuple(6), - new meta.scala.MetaTuple(7), - new meta.scala.MetaTuple(8), - new meta.scala.MetaTuple(9), - new meta.scalac.ast.MetaTree(), - new meta.scalac.ast.MetaTreeFactory(), - new meta.scalac.ast.MetaDefaultTreeFactory(), - new meta.scalac.ast.MetaTreeCopier(), - new meta.scalac.ast.MetaStrictTreeCopier(), - new meta.scalac.ast.MetaLazyTreeCopier(), - new meta.scalac.ast.MetaTraverser(), - new meta.scalac.ast.MetaTransformer(), - new meta.scalac.checkers.MetaCheckTreeNodes(), - }; - - //######################################################################## - // Public Functions - - public static void usage(PrintStream out) { - out.println("usage: " + script() + " <outputdir> [<logfile>]"); - } - - public static void main(String[] args) throws Exception { - if (args.length < 1 || 2 < args.length) { - usage(System.err); - throw abort(); - } - int errors = 0; - File root = new File(args[0]); - PrintWriter filelist = args.length <= 1 ? null : - new PrintWriter(new BufferedWriter(new FileWriter(args[1]))); - for (int i = 0; i < expanders.length; i++) { - File source = expanders[i].getSourceFile(root); - File target = expanders[i].getTargetFile(root); - System.out.println("Generating file " + target); - if (filelist != null) {filelist.println(target);filelist.flush();} - try { - TextWriter writer = expanders[i].getTextWriter(); - TextExpander expander = new TextExpander(writer, expanders[i]); - expander.expandText(source); - errors += expander.getErrorCount(); - target.delete(); - FileWriter output = new FileWriter(target); - output.write(writer.toString()); - output.close(); - target.setReadOnly(); - } catch (IOException exception) { - throw abort(exception); - } - } - if (errors > 0) throw abort(); - } - - //######################################################################## -} diff --git a/sources/meta/java/AbstractJavaExpander.java b/sources/meta/java/AbstractJavaExpander.java deleted file mode 100644 index c633ef8c45..0000000000 --- a/sources/meta/java/AbstractJavaExpander.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ 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 deleted file mode 100644 index d0106f3215..0000000000 --- a/sources/meta/java/JavaWriter.java +++ /dev/null @@ -1,394 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ 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 deleted file mode 100644 index 0d4545cbd4..0000000000 --- a/sources/meta/java/Type.java +++ /dev/null @@ -1,152 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ 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(); - } - - //######################################################################## -} diff --git a/sources/meta/scala/AbstractScalaExpander.java b/sources/meta/scala/AbstractScalaExpander.java deleted file mode 100644 index 0e121bfca9..0000000000 --- a/sources/meta/scala/AbstractScalaExpander.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scala; - -import meta.java.JavaWriter; -import meta.util.TextWriter; -import meta.util.AbstractFileExpander; - -/** A base class for scala file expanders. */ -public abstract class AbstractScalaExpander extends AbstractFileExpander { - - //######################################################################## - // Public Fields - - /** The underlying java writer */ - public final JavaWriter writer; - - //######################################################################## - // Public Constructors - - public AbstractScalaExpander() { - 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 "scala". */ - public String getTargetSuffix() { - return "scala"; - } - - //######################################################################## -} diff --git a/sources/meta/scala/MetaFunction.java b/sources/meta/scala/MetaFunction.java deleted file mode 100644 index 11ed9cc159..0000000000 --- a/sources/meta/scala/MetaFunction.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scala; - -import meta.java.AbstractJavaExpander; - -public class MetaFunction extends AbstractScalaExpander { - - //######################################################################## - // Public Fields - - public final int arity; - - //######################################################################## - // Public Constructors - - public MetaFunction(int arity) { - this.arity = arity; - } - - //######################################################################## - // Public Methods - - public String getTargetBaseName() { - return super.getTargetBaseName() + arity; - } - - public void printn() { - writer.print(arity); - } - - public void printClassSignature() { - writer.print("["); - for (int i = 0; i < arity; i++) - writer.print("-T").print(i).print(", "); - writer.print("+R]"); - } - - public void printApplySignature() { - writer.print("("); - for (int i = 0; i < arity; i++) { - if (i > 0) writer.print(", "); - writer.print("v").print(i).print(":").space().print("T").print(i); - } - writer.print("): R"); - } - - //######################################################################## -} diff --git a/sources/meta/scala/MetaTuple.java b/sources/meta/scala/MetaTuple.java deleted file mode 100644 index 2c67d9b919..0000000000 --- a/sources/meta/scala/MetaTuple.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scala; - -public class MetaTuple extends AbstractScalaExpander { - - //######################################################################## - // Public Fields - - public final int arity; - - //######################################################################## - // Public Constructors - - public MetaTuple(int arity) { - this.arity = arity; - } - - //######################################################################## - // Public Methods - - public String getTargetBaseName() { - return super.getTargetBaseName() + arity; - } - - public void printn() { - writer.print(arity); - } - - public void printTParams() { - for (int i = 1; i <= arity; i++) { - if (i > 1) writer.print(", "); - writer.print("+T").print(i); - } - } - - public void printVParams() { - for (int i = 1; i <= arity; i++) { - if (i > 1) writer.print(", "); - writer.print("_").print(i).print(": T").print(i); - } - } - - public void printToStringBody() { - for (int i = 1; i <= arity; i++) { - if (i > 1) writer.print(" + \",\" + "); - writer.print("_").print(i); - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/Phase.java b/sources/meta/scalac/Phase.java deleted file mode 100644 index 8092d6125b..0000000000 --- a/sources/meta/scalac/Phase.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac; - -/** A representation for Scala compiler phases. */ -public class Phase { - - //######################################################################## - // Public Constants - - public static final Phase - START = new Phase("start", null), - PARSER = new Phase("parser", "PARSER"), - DESUGARIZER = new Phase("desugarizer", "ANALYZER"), - ANALYZER = new Phase("analyzer", "ANALYZER"), - REFCHECK = new Phase("refcheck", "REFCHECK"), - UNCURRY = new Phase("uncurry", "UNCURRY"), - TRANSMATCH = new Phase("transmatch", "TRANSMATCH"), - LAMBDALIFT = new Phase("lambdalift", "LAMBDALIFT"), - EXPLICITOUTER = new Phase("explicitouter", "EXPLICITOUTER"), - ERASURE = new Phase("erasure", "ERASURE"), - UNKNOWN = new Phase("? !!!", null), - END = new Phase("-", null); - - //######################################################################## - // Public Fields - - public final String name; - public final String constant; - - //######################################################################## - // Public Constructors - - public Phase(String name, String constant) { - this.name = name; - this.constant = constant; - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/AbstractTreeCaseExpander.java b/sources/meta/scalac/ast/AbstractTreeCaseExpander.java deleted file mode 100644 index c7e023c16f..0000000000 --- a/sources/meta/scalac/ast/AbstractTreeCaseExpander.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -/** A base class for expanders that generate switches on tree nodes. */ -public abstract class AbstractTreeCaseExpander extends AbstractTreeExpander { - - //######################################################################## - // Public Constructors - - public AbstractTreeCaseExpander() { - writer.importType(t_Debug); - } - - //######################################################################## - // Public Methods - - public void printTreeSwitch() { - writer.println("switch (tree) {"); - writer.println(); - printTreeCases(); - writer.println("default:"); - writer.indent(); - writer.print("throw ").print(t_Debug). - println(".abort(\"unknown tree\", tree);"); - writer.undent(); - writer.println("}"); - } - - public void printTreeCases() { - for (int i = 0; i < tree.nodes.length; i++) { - printTreeCase(tree.nodes[i]); - writer.println(); - } - } - - public void printTreeCase(TreeNode node) { - printTreeCaseHeader(node); - writer.println().indent(); - printTreeCaseBody(node); - printTreeCaseFooter(node); - writer.undent(); - } - - public void printTreeCaseHeader(TreeNode node) { - node.printCase(writer, false); - } - - public abstract void printTreeCaseBody(TreeNode node); - - public void printTreeCaseFooter(TreeNode node) { - // do nothing - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/AbstractTreeExpander.java b/sources/meta/scalac/ast/AbstractTreeExpander.java deleted file mode 100644 index 503a9651a2..0000000000 --- a/sources/meta/scalac/ast/AbstractTreeExpander.java +++ /dev/null @@ -1,41 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; -import meta.java.AbstractJavaExpander; - -/** A base class for expanders that handle tree nodes. */ -public abstract class AbstractTreeExpander extends AbstractJavaExpander { - - //######################################################################## - // Public Fields - - public final Type t_Debug; - public final Tree tree; - - //######################################################################## - // Public Constructors - - public AbstractTreeExpander() { - this.t_Debug = TreeType.Reference("scalac.util", "Debug"); - this.tree = new Tree(); - writer.importFrom(t_Debug); - writer.importFrom(tree.getType(0)); - for (int i = 0; i < tree.nodes.length; i++) { - if (tree.nodes[i].fields != null) - for (int j = 0; j < tree.nodes[i].fields.length; j++) - writer.importType(tree.nodes[i].fields[j].type); - if (tree.nodes[i].hasSymbol()) - writer.importType(tree.nodes[i].getSymbol().type); - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/AbstractTreeMethodExpander.java b/sources/meta/scalac/ast/AbstractTreeMethodExpander.java deleted file mode 100644 index 7444759111..0000000000 --- a/sources/meta/scalac/ast/AbstractTreeMethodExpander.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -/** A base class for expanders that generate one method per tree node. */ -public abstract class AbstractTreeMethodExpander extends AbstractTreeExpander { - - //######################################################################## - // Public Methods - - public void printTreeMethods() { - for (int i = 0; i < tree.nodes.length; i++) { - if (tree.nodes[i].fields != null) { - printTreeMethod(tree.nodes[i], false); - if (tree.nodes[i].hasSymbol()) - printTreeMethod(tree.nodes[i], true); - } - writer.println(); - } - } - - public abstract void printTreeMethod(TreeNode node, boolean withSymbol); - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaDefaultTreeFactory.java b/sources/meta/scalac/ast/MetaDefaultTreeFactory.java deleted file mode 100644 index fde4fe7773..0000000000 --- a/sources/meta/scalac/ast/MetaDefaultTreeFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -public class MetaDefaultTreeFactory extends AbstractTreeMethodExpander { - - //######################################################################## - // Public Methods - - public void printTreeMethod(TreeNode node, boolean withSymbol) { - node.printMethod(writer, "int pos", withSymbol).lbrace(); - node.printNew(writer.print(node + " t = "), withSymbol).println(";"); - writer.println("t.pos = pos;"); - writer.println("return t;"); - writer.rbrace(); - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaLazyTreeCopier.java b/sources/meta/scalac/ast/MetaLazyTreeCopier.java deleted file mode 100644 index c389ab9404..0000000000 --- a/sources/meta/scalac/ast/MetaLazyTreeCopier.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -public class MetaLazyTreeCopier extends AbstractTreeMethodExpander { - - //######################################################################## - // Public Methods - - public void printTreeMethod(TreeNode node, boolean withSymbol) { - TreeField symbol = node.getSymbol(); - node.printMethod(writer, tree.getFormal("tree"), withSymbol).lbrace(); - if (!withSymbol && node.hasLinkedFields()) - writer.println("assert tree.symbol() == null : "+ - "\"tree's symbol is not null\";"); - writer.print(node.getType(0)).print(" t = ("). - print(node.getType(0)).println(")tree;"); - TreeField[] fields = node.getFields(withSymbol); - // !!! why do we copy if there is no symbol and no field - if (withSymbol || node.fields.length > 0) { - writer.print("if (").indent(); - if (withSymbol) writer.print("t.symbol() == " + symbol); - for (int i = 0; i < fields.length; i++) { - if (i > 0 ? true : withSymbol) writer.println(" &&"); - writer.print("t." + fields[i] + " == " + fields[i]); - } - writer.println(")"); - writer.println("return t;").undent(); - } - writer.print("return copier."); - node.printCall(writer, "tree", withSymbol).println(";"); - writer.rbrace(); - - if (withSymbol && node.hasLinkedFields()) { - node.printMethod(writer, tree.getFormal("tree"), false, true); - writer.lbrace(); - symbol.print(writer, true).println(" = tree.symbol();"); - node.printCall(writer.print("return "), "tree", true).println(";"); - writer.rbrace(); - return; - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaStrictTreeCopier.java b/sources/meta/scalac/ast/MetaStrictTreeCopier.java deleted file mode 100644 index 62823377dd..0000000000 --- a/sources/meta/scalac/ast/MetaStrictTreeCopier.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -public class MetaStrictTreeCopier extends AbstractTreeMethodExpander { - - //######################################################################## - // Public Methods - - public void printTreeMethod(TreeNode node, boolean withSymbol) { - TreeField symbol = node.getSymbol(); - node.printMethod(writer, tree.getFormal("tree"), withSymbol).lbrace(); - if (!withSymbol && node.hasLinkedFields()) - writer.println("assert tree.symbol() == null : "+ - "\"tree's symbol is not null\";"); - writer.print(node.getType(0)).print(" t = make."); - node.printCall(writer, "tree.pos", withSymbol).println(";"); - writer.println("t.type = tree.type;"); - if (!withSymbol && node.hasSymbol() && !node.hasLinkedFields()) { - symbol.print(writer, true).println(" = tree.symbol();"); - writer.println("if ("+symbol+" != null) t.setSymbol("+symbol+");"); - } - writer.println("return t;"); - writer.rbrace(); - - if (withSymbol && node.hasLinkedFields()) { - node.printMethod(writer, tree.getFormal("tree"), false, true); - writer.lbrace(); - symbol.print(writer, true).println(" = tree.symbol();"); - node.printCall(writer.print("return "), "tree", true).println(";"); - writer.rbrace(); - } - } - - //######################################################################## -} - - diff --git a/sources/meta/scalac/ast/MetaTransformer.java b/sources/meta/scalac/ast/MetaTransformer.java deleted file mode 100644 index 79ebebaf2f..0000000000 --- a/sources/meta/scalac/ast/MetaTransformer.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; - -public class MetaTransformer extends AbstractTreeCaseExpander { - - //######################################################################## - // Public Methods - - public void printTreeCaseBody(TreeNode node) { - if (node.fields == null) { - writer.println("return tree;"); - } else { - if (node.hasSymbol()) { - writer.print("if (tree.symbol() != null)").lbrace(); - printTransformNode(node, true); - writer.undent().print("} else").lbrace(); - } - printTransformNode(node, false); - if (node.hasSymbol()) writer.rbrace(); - } - } - - public void printTransformNode(TreeNode node, boolean withSymbol) { - TreeField[] fields = node.getFields(withSymbol); - writer.print("return copy." + node + "(tree"); - if (withSymbol) writer.print(", tree.symbol()"); - for (int i = 0; i < fields.length; i++) { - writer.print(", "); - if (Tree.isTree(fields[i].type)) - writer.print("transform(" + fields[i].name + ")"); - else - writer.print(fields[i].name); - } - writer.println(");"); - } - - public void printTransformArrays() { - for (int j = 1; j <= tree.arrays; j++) - printTransformArray(tree.getType(j), false); - for (int i = 0; i < tree.nodes.length; i++) - for (int j = 1; j <= tree.nodes[i].arrays; j++) - printTransformArray(tree.nodes[i].getType(j), j == 1); - } - - public void printTransformArray(Type type, boolean needCast) { - Type item = type.getItemType(); - Type erased = needCast ? tree.getType(0) : item; - String cast = needCast ? "(" + item + ")" : ""; - writer.print("public ").print(type).print(" transform"). - print("(").print(type).print(" ts)").lbrace(); - writer.print("for (int i = 0; i < ts.length; i++)").lbrace(); - writer.println(erased + " t = transform(ts[i]);"); - writer.print("if (t != ts[i])").lbrace(); - writer.println(type+" res = new "+item.newArray("[ts.length]")+";"); - writer.println("System.arraycopy(ts, 0, res, 0, i);"); - writer.println("res[i++] = "+cast+"t;"); - writer.print("for (; i < ts.length; i++)"). - println("res[i] = "+cast+"transform(ts[i]);"); - writer.println("return res;"); - writer.rbrace(); - writer.rbrace(); - writer.println("return ts;"); - writer.rbrace(); - writer.line(); - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaTraverser.java b/sources/meta/scalac/ast/MetaTraverser.java deleted file mode 100644 index 0f166510db..0000000000 --- a/sources/meta/scalac/ast/MetaTraverser.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; - -public class MetaTraverser extends AbstractTreeCaseExpander { - - //######################################################################## - // Public Methods - - public void printTreeCaseBody(TreeNode node) { - if (node.fields != null) - for (int i = 0; i < node.fields.length; i++) - if (Tree.isTree(node.fields[i].type)) - writer.println("traverse(" + node.fields[i] + ");"); - writer.println("return;"); - } - - public void printTraverseArrays() { - int max = tree.arrays; - for (int i = 0; i < tree.nodes.length; i++) - max = Math.max(max, tree.nodes[i].arrays); - for (int i = 1; i <= max; i++) - printTraverseArray(tree.getType(i)); - } - - public void printTraverseArray(Type type) { - writer.print("public void traverse"). - print("(").print(type).print(" trees)").lbrace(); - writer.print("for (int i = 0; i < trees.length; i++) "). - println("traverse(trees[i]);"); - writer.rbrace(); - writer.line(); - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaTree.java b/sources/meta/scalac/ast/MetaTree.java deleted file mode 100644 index 31b98d1d4b..0000000000 --- a/sources/meta/scalac/ast/MetaTree.java +++ /dev/null @@ -1,218 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; - -public class MetaTree extends AbstractTreeExpander { - - //######################################################################## - // Public Methods - - public void printEmptyArrays() { - printEmptyArrays(tree.getType(0), "EMPTY", tree.arrays); - for (int i = 0; i < tree.nodes.length; i++) { - TreeNode node = tree.nodes[i]; - printEmptyArrays(node.getType(0), node + "_EMPTY", node.arrays); - } - } - - public void printEmptyArrays(Type base, String prefix, int maxRank) { - Type type = base; - for (int rank = 1; rank <= maxRank; rank++) { - type = Type.Array(type); - writer.print("public static final ").print(type).print(" "+prefix); - for (int i = 0; i < rank; i++) writer.print("_ARRAY"); - writer.print(" = new ").print(base).print("[0]"); - for (int i = 1; i < rank; i++) writer.print("[]"); - writer.println(";"); - } - } - - public void printTreeCases() { - for (int i = 0; i < tree.nodes.length; i++) - printTreeCase(tree.nodes[i]); - } - - private void printTreeCase(TreeNode node) { - writer.printDescription(new String[] { - node.description, - "- kind : " + description(node.kind), - "- symbol : " + description(node.symbol), - "- introduced by: " + node.start.name, - "- eliminated by: " + node.stop.name, - }); - node.printDecl(writer.print("public case "), null, false); - if (node.fields != null) { - writer.lbrace(); - writer.println("assert CheckTreeNodes.instance.checkNode(this);"); - writer.rbrace(); - } else { - writer.println(";"); - } - if (node == tree.n_Empty) - writer.print("static { " + node + ".type = Type.NoType; }"); - writer.println(); - } - - private String description(TreeKind kind) { - switch (kind) { - case Any : return "this tree is of any kind"; - case Type: return "this tree is a type"; - case Term: return "this tree is a term"; - case Dual: return "this tree is a type or a term"; - case Test: return "this tree is a type or a term " + - "(determined by the kind of the name field)"; - case None: return "this tree is neither a type nor a term"; - default : throw new Error(kind.getClass().getName()); - } - } - - private String description(TreeSymbol symbol) { - switch (symbol) { - case NoSym : return "this tree has no symbol"; - case HasSym(_, false): return "this tree references a symbol"; - case HasSym(_, true ): return "this tree defines a symbol"; - default : throw new Error(symbol.getClass().getName()); - } - } - - public void printIsKind() { - printIsKind(tree.nodes, TreeKind.Type); - printIsKind(tree.nodes, TreeKind.Term); - } - - private void printIsKind(TreeNode[] nodes, TreeKind kind) { - writer.println("/** Returns true if this tree is a " + - kind.toString().toLowerCase() + ". */"); - writer.print("public boolean is" + kind + "()").lbrace(); - writer.println("switch (this) {"); - - for (int i = 0; i < nodes.length; i++) - if (nodes[i].kind != TreeKind.Test && nodes[i].kind.isA(kind)) - nodes[i].printCase(writer, true).println(); - writer.indent().println("return true;").undent(); - - for (int i = 0; i < nodes.length; i++) { - if (nodes[i].kind != TreeKind.Test) continue; - writer.print("case " + nodes[i].name + "("); - for (int j = 0; j < nodes[i].fields.length; j++) { - if (j > 0) writer.print(", "); - switch (nodes[i].fields[j].type) { - case TreeType.Name(Test): - writer.print(nodes[i].fields[j].type + " name"); - break; - default: - writer.print("_"); - break; - } - } - writer.println("):"); - writer.indent().print("return "); - switch (kind) { - case TreeKind.Type: - writer.print("name.isTypeName() && (symbol() == null || !symbol().isConstructor()) || name == Names.ERROR"); - break; - case TreeKind.Term: - writer.print("name.isTermName() || (symbol() != null && symbol().isConstructor())"); - break; - default: - throw new Error("unexpected kind " + kind); - } - writer.println(";").undent(); - } - - writer.println("default:"); - writer.indent().println("return false;").undent(); - - writer.println("}"); - writer.rbrace(); - writer.println(); - } - - public void printExtClasses() { - for (int i = 0;i < tree.nodes.length;i++) printExtClass(tree.nodes[i]); - } - - private void printExtClass(TreeNode node) { - TreeField symbol = node.getSymbol(); - if (symbol == null) return; - writer.print("public static class Ext"+node+" extends "+node).lbrace(); - symbol.print(writer.print("private "), true).println(";"); - writer.println(); - - printExtConstructor(node, false); - printExtConstructor(node, true); - writer.println(); - - writer.print("public boolean hasSymbol()").lbrace(); - writer.println("return true;"); - writer.rbrace(); - writer.println(); - - if (node.definesSymbol()) { - writer.print("public boolean definesSymbol()").lbrace(); - writer.println("return true;"); - writer.rbrace(); - writer.println(); - } - - writer.print("public ").print(symbol.type).print(" symbol()"); - writer.lbrace(); - writer.println("return " + symbol + ";"); - writer.rbrace(); - writer.println(); - - writer.print("public ").print(tree.getType(0)).print(" setSymbol"); - symbol.print(writer.print("("), true).print(")").lbrace(); - printSetSymbol(symbol); - for (int i = 0; i < node.fields.length; i++) { - TreeField field = node.fields[i]; - TreeFieldLink link = field.link; - if (link == null) continue; - link.print(writer.print("this."+field+" = "),symbol).println(";"); - } - writer.println("return this;"); - writer.rbrace(); - - writer.rbrace(); - writer.println(); - } - - private void printExtConstructor(TreeNode node, boolean withSymbol) { - node.printDecl(writer.print("public Ext"), null, withSymbol).lbrace(); - TreeField symbol = node.getSymbol(); - writer.print("super("); - for (int i = 0; i < node.fields.length; i++) { - if (i > 0) writer.print(", "); - if (withSymbol && node.fields[i].link != null) { - node.fields[i].link.print(writer, symbol); - } else { - writer.print(node.fields[i].name); - } - } - writer.println(");"); - if (withSymbol) printSetSymbol(symbol); - writer.rbrace(); - } - - private void printSetSymbol(TreeField symbol) { - writer.println("assert " + symbol + " != null : \"null symbol\";"); - writer.println("this." + symbol + " = " + symbol + ";"); - } - - public void printEmptyCases() { - for (int i = 0;i < tree.nodes.length;i++) { - tree.nodes[i].printCase(writer, false).println(); - writer.println(); - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaTreeCopier.java b/sources/meta/scalac/ast/MetaTreeCopier.java deleted file mode 100644 index 785c3a99da..0000000000 --- a/sources/meta/scalac/ast/MetaTreeCopier.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -public class MetaTreeCopier extends AbstractTreeMethodExpander { - - //######################################################################## - // Public Methods - - public void printTreeMethod(TreeNode node, boolean withSymbol) { - node.printMethod(writer,tree.getFormal("tree"),withSymbol); - writer.println(";"); - if (withSymbol && node.hasLinkedFields()) { - node.printMethod(writer, tree.getFormal("tree"), false, true); - writer.println(";"); - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/MetaTreeFactory.java b/sources/meta/scalac/ast/MetaTreeFactory.java deleted file mode 100644 index 28b1f381c9..0000000000 --- a/sources/meta/scalac/ast/MetaTreeFactory.java +++ /dev/null @@ -1,21 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -public class MetaTreeFactory extends AbstractTreeMethodExpander { - - //######################################################################## - // Public Methods - - public void printTreeMethod(TreeNode node, boolean withSymbol) { - node.printMethod(writer, "int pos", withSymbol).println(";"); - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/Tree.java b/sources/meta/scalac/ast/Tree.java deleted file mode 100644 index 492461bc59..0000000000 --- a/sources/meta/scalac/ast/Tree.java +++ /dev/null @@ -1,441 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import java.util.List; -import java.util.ArrayList; - -import meta.java.Type; -import meta.scalac.Phase; - -/** This class describes all tree nodes. */ -public class Tree { - - //######################################################################## - // Private Fields - - private final TreeKind - Any = TreeKind.Any, - Type = TreeKind.Type, - Term = TreeKind.Term, - Dual = TreeKind.Dual, - Test = TreeKind.Test, - None = TreeKind.None; - - private final Type - t_int = TreeType.INT, - t_ints = TreeType.Array(t_int), - t_Object = TreeType.Reference(null, "Object"), - t_String = TreeType.Reference(null, "String"), - t_Global = TreeType.Reference("scalac", "Global"), - t_Unit = TreeType.Reference("scalac", "Unit"), - t_TreeGen = TreeType.Reference("scalac.ast", "TreeGen"), - t_AConstant = TreeType.Reference("scalac.atree", "AConstant"), - t_Symbol = TreeType.Reference("scalac.symtab", "Symbol"), - t_Type = TreeType.Reference("scalac.symtab", "Type"), - t_Name = TreeType.Name(Any), - t_TypeName = TreeType.Name(Type), - t_TermName = TreeType.Name(Term), - t_TestName = TreeType.Name(Test), - t_Names = TreeType.Array(t_Name), - t_Tree = getType(0), - t_TypeTree = getType(0, Type), - t_TermTree = getType(0, Term), - t_Trees = getType(1), - t_TypeTrees = getType(1, Type), - t_TermTrees = getType(1, Term); - - private final TreeFieldLink - SymFlags = TreeFieldLink.SymFlags, - SymName = TreeFieldLink.SymName; - - private final TreeField - tree_symbol = new TreeField(t_Symbol, "symbol"); - - private final TreeSymbol - NoSym = TreeSymbol.NoSym, - HasSym = TreeSymbol.HasSym(tree_symbol, false), - DefSym = TreeSymbol.HasSym(tree_symbol, true); - - private final List list - = new ArrayList(); - - //######################################################################## - // Public Fields - - public final TreeNode - n_Empty = node("Empty" , Any , NoSym), - n_Attributed = node("Attributed" , None, NoSym), - n_DocDef = node("DocDef" , None, NoSym), - n_ClassDef = node("ClassDef" , None, DefSym), - n_PackageDef = node("PackageDef" , None, NoSym), - n_ModuleDef = node("ModuleDef" , None, DefSym), - n_ValDef = node("ValDef" , None, DefSym), - n_PatDef = node("PatDef" , None, NoSym), - n_DefDef = node("DefDef" , None, DefSym), - n_AbsTypeDef = node("AbsTypeDef" , None, DefSym), - n_AliasTypeDef = node("AliasTypeDef" , None, DefSym), - n_Import = node("Import" , None, HasSym), - n_CaseDef = node("CaseDef" , None, NoSym), - n_Template = node("Template" , None, HasSym), - n_LabelDef = node("LabelDef" , Term, DefSym), - n_Block = node("Block" , Term, NoSym), - n_Sequence = node("Sequence" , Term, NoSym), - n_Alternative = node("Alternative" , Term, NoSym), - n_Bind = node("Bind" , Term, DefSym), - n_Visitor = node("Visitor" , Term, NoSym), - n_Function = node("Function" , Term, NoSym), - n_Assign = node("Assign" , Term, NoSym), - n_If = node("If" , Term, NoSym), - n_Switch = node("Switch" , Term, NoSym), - n_Return = node("Return" , Term, HasSym), - n_Throw = node("Throw" , Term, NoSym), - n_New = node("New" , Term, NoSym), - n_Create = node("Create" , Term, HasSym), - n_Typed = node("Typed" , Term, NoSym), - n_TypeApply = node("TypeApply" , Term, NoSym), - n_Apply = node("Apply" , Term, NoSym), - n_Super = node("Super" , Term, HasSym), - n_This = node("This" , Term, HasSym), - n_Select = node("Select" , Test, HasSym), - n_Ident = node("Ident" , Test, HasSym), - n_Literal = node("Literal" , Term, NoSym), - n_TypeTerm = node("TypeTerm" , Type, NoSym), - n_SingletonType = node("SingletonType" , Type, NoSym), - n_SelectFromType = node("SelectFromType", Type, HasSym), - n_FunType = node("FunType" , Type, NoSym), - n_CompoundType = node("CompoundType" , Type, NoSym), - n_AppliedType = node("AppliedType" , Type, NoSym), - n_Try = node("Try" , Term, NoSym); - - public final TreeNode[] nodes; - public int arrays; - - //######################################################################## - // Public Constructors - - public Tree() { - nodes = (TreeNode[])list.toArray(new TreeNode[list.size()]); - - n_Empty. - setDescription("A tree node for the absence of a tree"). - setRange(Phase.PARSER, Phase.UNKNOWN). - noFields(); - - n_Attributed. - setDescription("Attributed definition"). - setRange(Phase.PARSER, Phase.ANALYZER). - addField(t_Tree, "attribute"). - addField(t_Tree, "definition"); - - n_DocDef. - setDescription("Documented definition"). - setRange(Phase.PARSER, Phase.ANALYZER). - addField(t_String, "comment"). - addField(t_Tree, "definition"); - - n_ClassDef. - setDescription("Class and data declaration"). - setRange(Phase.PARSER, Phase.END). - addField(t_int, "mods", SymFlags). - addField(t_TypeName, "name", SymName). - addField(n_AbsTypeDef.getType(1), "tparams"). - addField(n_ValDef.getType(2), "vparams"). - addField(t_TypeTree, "tpe"). - addField(n_Template.getType(0), "impl"); - - n_PackageDef. - setDescription("Package declaration"). - setRange(Phase.PARSER, Phase.UNKNOWN). - addField(t_TermTree, "packaged"). - addField(n_Template.getType(0), "impl"); - - n_ModuleDef. - setDescription("Module declaration"). - setRange(Phase.PARSER, Phase.REFCHECK). - addField(t_int, "mods", SymFlags). - addField(t_TermName, "name", SymName). - addField(t_TypeTree, "tpe"). - addField(n_Template.getType(0), "impl"); - - n_ValDef. - setDescription("Value declaration (var or let)"). - setRange(Phase.PARSER, Phase.END). - addField(t_int, "mods", SymFlags). - addField(t_TermName, "name", SymName). - addField(t_TypeTree, "tpe"). - addField(t_TermTree, "rhs"); - - - n_PatDef. - setDescription("Value declaration with patterns (val)"). - setRange(Phase.PARSER, Phase.DESUGARIZER). - addField(t_int, "mods"). - addField(t_TermTree, "pat"). - addField(t_TermTree, "rhs"); - - n_DefDef. - setDescription("Function declaration (def)"). - setRange(Phase.PARSER, Phase.END). - addField(t_int, "mods", SymFlags). - addField(t_TermName, "name", SymName). - addField(n_AbsTypeDef.getType(1), "tparams"). - addField(n_ValDef.getType(2), "vparams"). - addField(t_TypeTree, "tpe"). - addField(t_TermTree, "rhs"); - - n_AbsTypeDef. - setDescription("Type declaration"). - setRange(Phase.PARSER, Phase.END). // !!! needed for type params - addField(t_int, "mods", SymFlags). - addField(t_TypeName, "name", SymName). - addField(t_TypeTree, "rhs"). - addField(t_TypeTree, "lobound"); - - n_AliasTypeDef. - setDescription("Type alias"). - setRange(Phase.PARSER, Phase.EXPLICITOUTER). - addField(t_int, "mods", SymFlags). - addField(t_TypeName, "name", SymName). - addField(n_AbsTypeDef.getType(1), "tparams"). - addField(t_TypeTree, "rhs"); - - n_Import. - setDescription("Import declaration"). - setRange(Phase.PARSER, Phase.ANALYZER). - addField(t_TermTree, "expr"). - addField(t_Names, "selectors"); - - n_CaseDef. - setDescription("Case declaration"). - setRange(Phase.PARSER, Phase.TRANSMATCH). - addField(t_TermTree, "pat"). - addField(t_TermTree, "guard"). - addField(t_TermTree, "body"); - - n_Template. - setDescription("Instantiation templates"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTrees, "parents"). - addField(t_Trees, "body"); - - n_LabelDef. - setDescription("Labelled expression - the symbols in the array (must be Idents!) are those the label takes as argument"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermName, "name", SymName). - addField(n_Ident.getType(1), "params"). - addField(t_TermTree, "rhs"); - - n_Block. - setDescription("Block of expressions " + - "(semicolon separated expressions)"). - setRange(Phase.PARSER, Phase.END). - addField(t_Trees, "stats"). - addField(t_TermTree, "expr"); - - n_Sequence. - setDescription("Sequence of expressions (comma separated expressions)"). - setRange(Phase.PARSER, Phase.TRANSMATCH). - addField(t_TermTrees, "trees"); - - n_Alternative. - setDescription("Alternatives of expressions/patterns"). - setRange(Phase.PARSER, Phase.TRANSMATCH). - addField(t_TermTrees, "trees"); - - n_Bind. - setDescription("Bind of a variable to a rhs pattern, possibly recursive"). - setRange(Phase.PARSER, Phase.TRANSMATCH). - addField(t_TermName, "name", SymName). - addField(t_TermTree, "rhs"); - - - n_Visitor. - setDescription("Visitor (a sequence of cases)"). - setRange(Phase.PARSER, Phase.TRANSMATCH). - addField(n_CaseDef.getType(1), "cases"); - - - n_Function. - setDescription("Anonymous function"). - setRange(Phase.PARSER, Phase.ANALYZER). - addField(n_ValDef.getType(1), "vparams"). - addField(t_TermTree, "body"); - - n_Assign. - setDescription("Assignment"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "lhs"). - addField(t_TermTree, "rhs"); - - n_If. - setDescription("Conditional expression"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "cond"). - addField(t_TermTree, "thenp"). - addField(t_TermTree, "elsep"); - - n_Switch. - setDescription("Switch"). - setRange(Phase.REFCHECK, Phase.END). - addField(t_TermTree, "test"). - addField(t_ints, "tags"). - addField(t_TermTrees, "bodies"). - addField(t_TermTree, "otherwise"); - - n_Return. - setDescription("Return"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "expr"); - - n_Throw. - setDescription("Throw"). - setRange(Phase.PARSER, Phase.ANALYZER). - addField(t_TermTree, "expr"); - - n_New. - setDescription("Instantiation"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "init"); - - n_Create. - setDescription("Instance creation"). - setRange(Phase.ANALYZER, Phase.END). - addField(t_TermTree, "qualifier"). - addField(t_TypeTrees, "targs"); - - n_Typed. - setDescription("Type annotation"). - setRange(Phase.PARSER, Phase.EXPLICITOUTER). - addField(t_TermTree, "expr"). - addField(t_TypeTree, "tpe"); - - - n_TypeApply. - setDescription("Type application"). - setRange(Phase.PARSER, Phase.END). - addField(t_Tree, "fun"). - addField(t_TypeTrees, "args"); - - n_Apply. - setDescription("Value application"). - setRange(Phase.PARSER, Phase.END). - addField(t_Tree, "fun"). // !!! should be t_TermTree - addField(t_TermTrees, "args"); - - n_Super. - setDescription("Super reference"). - setRange(Phase.PARSER, Phase.END). - addField(t_TypeName, "qualifier", SymName). - addField(t_TypeName, "mixin"); - - n_This. - setDescription("Self reference"). - setRange(Phase.PARSER, Phase.END). - addField(t_TypeName, "qualifier", SymName); - - n_Select. - setDescription("Designator"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "qualifier"). - addField(t_TestName, "selector", SymName); - - n_Ident. - setDescription("Identifier"). - setRange(Phase.PARSER, Phase.END). - addField(t_TestName, "name", SymName); - - n_Literal. - setDescription("Literal"). - setRange(Phase.PARSER, Phase.END). - addField(t_AConstant, "value"); - - n_TypeTerm. - setDescription("TypeTerm"). - setRange(Phase.PARSER, Phase.END); - - n_SingletonType. - setDescription("Singleton type"). - setRange(Phase.PARSER, Phase.REFCHECK). - addField(t_TermTree, "ref"); - - n_SelectFromType. - setDescription("Type selection"). - setRange(Phase.PARSER, Phase.REFCHECK). - addField(t_TypeTree, "qualifier"). - addField(t_TypeName, "selector", SymName); - - n_FunType. - setDescription("Function type"). - setRange(Phase.PARSER, Phase.REFCHECK). - addField(t_TypeTrees, "argtpes"). - addField(t_TypeTree, "restpe"); - - n_CompoundType. - setDescription("Object type (~ Template)"). - setRange(Phase.PARSER, Phase.REFCHECK). - addField(t_TypeTrees, "parents"). - addField(t_Trees, "refinements"); - - n_AppliedType. - setDescription("Applied type"). - setRange(Phase.PARSER, Phase.REFCHECK). - addField(t_TypeTree, "tpe"). - addField(t_TypeTrees, "args"); - - n_Try. - setDescription("Try Expression"). - setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "block"). - addField(t_TermTree, "catcher"). - addField(t_TermTree, "finalizer"); - } - - //######################################################################## - // Public Functions - - public static boolean isTree(Type type) { - switch (type) { - case Array(Type item): - return isTree(item); - case TreeType.Tree(_): - case TreeType.Node(_): - return true; - default: - return false; - } - } - - //######################################################################## - // Public Methods - - public Type getType(int rank) { - return getType(rank, Any); - } - - public Type getType(int rank, TreeKind kind) { - arrays = Math.max(arrays , rank); - return rank==0 ? TreeType.Tree(kind) : TreeType.Array(getType(rank-1)); - } - - public String getFormal(String name) { - return getType(0) + " " + name; - } - - //######################################################################## - // Private Methods - - private TreeNode node(String name, TreeKind kind, TreeSymbol symbol) { - TreeNode node = new TreeNode(name, kind, symbol); - list.add(node); - return node; - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/TreeField.java b/sources/meta/scalac/ast/TreeField.java deleted file mode 100644 index 19df9cb42e..0000000000 --- a/sources/meta/scalac/ast/TreeField.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; -import meta.java.JavaWriter; - -/** This class describes a tree node field. */ -public class TreeField { - - //######################################################################## - // Public Fields - - public final Type type; - public final String name; - public final TreeFieldLink link; - - //######################################################################## - // Public Constructors - - public TreeField(Type type, String name) { - this(type, name, null); - } - - public TreeField(Type type, String name, TreeFieldLink link) { - this.type = type; - this.name = name; - this.link = link; - } - - //######################################################################## - // Public Function - - public static JavaWriter print(JavaWriter writer, TreeField[] fields, - boolean withType) - { - for (int i = 0; i < fields.length; i++) { - if (i > 0) writer.print(", "); - fields[i].print(writer, withType); - } - return writer; - } - - //######################################################################## - // Public Methods - - public JavaWriter print(JavaWriter writer, boolean withType) { - if (withType) writer.print(type).space(); - return writer.print(name); - } - - public String toString() { - return name; - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/TreeFieldLink.java b/sources/meta/scalac/ast/TreeFieldLink.java deleted file mode 100644 index 62e8dcfb10..0000000000 --- a/sources/meta/scalac/ast/TreeFieldLink.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.JavaWriter; - -/** - * This class describes the possible links between a given field of a - * tree and the symbol of that tree. - */ -public class TreeFieldLink { - - //######################################################################## - // Public Cases - - /** Field is linked to the symbol's flags */ - public case SymFlags; - - /** Field is linked to the symbol's name */ - public case SymName; - - //######################################################################## - // Public Methods - - /** Returns the field or method to invoke to get the linked value. */ - public String getLink() { - switch (this) { - case SymFlags: - return "flags"; - case SymName: - return "name"; - default: - throw new Error("unknown case: " + this); - } - } - - /** Returns the name of this link. */ - public String toString() { - switch (this) { - case SymFlags: - return "flags"; - case SymName: - return "name"; - default: - throw new Error("unknown case: " + this); - } - } - - public JavaWriter print(JavaWriter writer, TreeField symbol) { - return writer.print(symbol.name).print('.').print(getLink()); - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/TreeKind.java b/sources/meta/scalac/ast/TreeKind.java deleted file mode 100644 index 35dcd0dd55..0000000000 --- a/sources/meta/scalac/ast/TreeKind.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -/** This class enumerates the different kinds of tree nodes. */ -public class TreeKind { - - //######################################################################## - // Public Cases - - /** Designates a type, a term or anything else. */ - public case Any; - - /** Designates a type. */ - public case Type; - - /** Designates a term. */ - public case Term; - - /** Designates either a type or a term. */ - public case Dual; - - /** Designates either a type or a term (a test may indicate which one). */ - public case Test; - - /** Designates neither a type nor a term. */ - public case None; - - //######################################################################## - // Public Method - - public boolean isA(TreeKind that) { - switch (this) { - case Any : return true; - case Type: return that == Type; - case Term: return that == Term; - case Dual: return that == Type || that == Term || that == Dual; - case Test: return that == Type || that == Term || that == Dual; - case None: return that == None; - default : throw new Error(); - } - } - - public String toString() { - switch(this) { - case Any : return "Any"; - case Type: return "Type"; - case Term: return "Term"; - case Dual: return "Dual"; - case Test: return "Test"; - case None: return "None"; - default : throw new Error(); - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/TreeNode.java b/sources/meta/scalac/ast/TreeNode.java deleted file mode 100644 index 340eaa8109..0000000000 --- a/sources/meta/scalac/ast/TreeNode.java +++ /dev/null @@ -1,231 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; -import meta.java.JavaWriter; -import meta.scalac.Phase; - -/** This class describes a tree node. */ -public class TreeNode { - - //######################################################################## - // Public Fields - - public final String name; - public final TreeKind kind; - public final TreeSymbol symbol; - public String description; - public Phase start; - public Phase stop; - public TreeField[] fields; - public int arrays; - - //######################################################################## - // Public Constructors - - public TreeNode(String name, TreeKind kind, TreeSymbol symbol) { - this(name, kind, symbol, new TreeField[0]); - } - - public TreeNode(String name, TreeKind kind, TreeSymbol symbol, - TreeField[] fields) - { - this.name = name; - this.kind = kind; - this.symbol = symbol; - this.fields = fields; - } - - //######################################################################## - // Public Methods - Initializing - - public TreeNode setDescription(String description) { - this.description = description; - return this; - } - - public TreeNode setRange(Phase start, Phase stop) { - this.start = start; - this.stop = stop; - return this; - } - - public TreeNode noFields() { - fields = null; - return this; - } - - public TreeNode addField(Type type, String name) { - return addField(type, name, null); - } - - public TreeNode addField(Type type, String name, TreeFieldLink link) { - if (link != null && !hasSymbol()) - throw new Error("node "+this+" may not have linked fields"); - TreeField[] array = new TreeField[fields.length + 1]; - for (int i = 0; i < fields.length; i++) array[i] = fields[i]; - array[fields.length] = new TreeField(type, name, link); - fields = array; - return this; - } - - //######################################################################## - // Public Methods - Querying - - public Type getType(int rank) { - arrays = Math.max(arrays , rank); - return rank == 0 ? TreeType.Node(this) : Type.Array(getType(rank - 1)); - } - - public boolean hasExtClass() { - return hasSymbol(); - } - - public boolean hasSymbol() { - switch (symbol) { - case TreeSymbol.HasSym(_, _): - return true; - default: - return false; - } - } - - public boolean definesSymbol() { - switch (symbol) { - case TreeSymbol.HasSym(_, true): - return true; - default: - return false; - } - } - - public TreeField getSymbol() { - switch (symbol) { - case TreeSymbol.HasSym(TreeField field, _): - return field; - default: - return null; - } - } - - public boolean hasLinkedFields() { - for (int i = 0; i < fields.length; i++) - if (fields[i].link != null) return true; - return false; - } - - public TreeField[] getFields(boolean withoutLinkedFields) { - if (fields == null || !withoutLinkedFields) return fields; - int count = 0;; - for (int i = 0; i < fields.length; i++) - if (fields[i].link == null) count++; - TreeField[] array = new TreeField[count]; - for (int i = 0, j = 0; i < fields.length; i++) - if (fields[i].link == null) array[j++] = fields[i]; - return array; - } - - public String toString() { - return name; - } - - //######################################################################## - // Public Methods - Printing - - public JavaWriter printCase(JavaWriter writer, boolean withWildcards) { - writer.print("case "); - if (fields != null && withWildcards) { - writer.print(name).print('('); - for (int i = 0; i < fields.length; i++) { - if (i > 0) writer.print(", "); - writer.print("_"); - } - writer.print(')'); - } else { - printDecl(writer, null, false); - } - return writer.print(":").space(); - } - - public JavaWriter printNew(JavaWriter writer, boolean withSymbol) { - writer.print("new "); - if (hasExtClass()) writer.print("Ext"); - return printCall(writer, null, withSymbol); - } - - public JavaWriter printMethod(JavaWriter writer, String prefix, - boolean withSymbol) - { - return printMethod(writer, prefix, withSymbol, withSymbol); - } - - public JavaWriter printMethod(JavaWriter writer, String prefix, - boolean withSymbol, boolean withoutLinkedFields) - { - writer.print("public ").print(name).space(); - return printDecl(writer, prefix, withSymbol, withoutLinkedFields); - } - - public JavaWriter printDecl(JavaWriter writer, String prefix, - boolean withSymbol) - { - return printDecl(writer, prefix, withSymbol, withSymbol); - } - - public JavaWriter printDecl(JavaWriter writer, String prefix, - boolean withSymbol, boolean withoutLinkedFields) - { - return printPattern(writer,true,prefix,withSymbol,withoutLinkedFields); - } - - public JavaWriter printCall(JavaWriter writer, String prefix, - boolean withSymbol) - { - return printCall(writer, prefix, withSymbol, withSymbol); - } - - public JavaWriter printCall(JavaWriter writer, String prefix, - boolean withSymbol, boolean withoutLinkedFields) - { - return printPattern( - writer, false, prefix, withSymbol, withoutLinkedFields); - } - - public JavaWriter printPattern(JavaWriter writer, boolean withType, - String prefix, boolean withSymbol, boolean withoutLinkedFields) - { - writer.print(name); - if (fields != null || prefix != null || withSymbol) { - writer.print('('); - printFields(writer,withType,prefix,withSymbol,withoutLinkedFields); - writer.print(')'); - } - return writer; - } - - public JavaWriter printFields(JavaWriter writer, boolean withType, - String prefix, boolean withSymbol, boolean withoutLinkedFields) - { - TreeField[] fields = getFields(withoutLinkedFields); - if (prefix != null) { - writer.print(prefix); - if (withSymbol || (fields != null && fields.length > 0)) - writer.print(", "); - } - if (withSymbol) { - getSymbol().print(writer, withType); - if (fields != null && fields.length > 0) writer.print(", "); - } - TreeField.print(writer, fields, withType); - return writer; - } - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/TreeSymbol.java b/sources/meta/scalac/ast/TreeSymbol.java deleted file mode 100644 index 1e53be4013..0000000000 --- a/sources/meta/scalac/ast/TreeSymbol.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -/** This class describes the symbol stored in some tree nodes. */ -public class TreeSymbol { - - //######################################################################## - // Public Cases - - /** Indicates the absence of symbol. */ - public case NoSym; - - /** Indicates the presence of a symbol. */ - public case HasSym(TreeField field, boolean isDef); - - //######################################################################## -} diff --git a/sources/meta/scalac/ast/TreeType.java b/sources/meta/scalac/ast/TreeType.java deleted file mode 100644 index 52c2e6d9b3..0000000000 --- a/sources/meta/scalac/ast/TreeType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.ast; - -import meta.java.Type; - -/** This class describes types used in tree nodes. */ -public class TreeType extends Type { - - //######################################################################## - // Private Constants - - private static final String NAME_PACKAGE = "scalac.util"; - private static final String NAME_NAME = "Name"; - private static final String NAME_FULLNAME = NAME_PACKAGE + "." + NAME_NAME; - private static final String TREE_PACKAGE = "scalac.ast"; - private static final String TREE_NAME = "Tree"; - private static final String TREE_FULLNAME = TREE_PACKAGE + "." + TREE_NAME; - - //######################################################################## - // Public Cases - - public case Name(TreeKind kind); - public case Tree(TreeKind kind); - public case Node(TreeNode node); - - //######################################################################## - // Public Methods - - /** Returns the type's (possibly fully qualified) name. */ - public String getName(boolean qualified) { - switch (this) { - case Name(_): - return qualified ? NAME_FULLNAME : NAME_NAME; - case Tree(_): - return qualified ? TREE_FULLNAME : TREE_NAME; - case Node(TreeNode node): - return qualified ? TREE_FULLNAME + "." + node.name : node.name; - default: - return super.getName(qualified); - } - } - - /** Returns the type's owner (its package or enclosing type). */ - public String getOwner() { - switch (this) { - case Name(_): - return NAME_PACKAGE; - case Tree(_): - return TREE_PACKAGE; - case Node(TreeNode node): - return TREE_FULLNAME; - default: - return super.getOwner(); - } - } - - //######################################################################## -} diff --git a/sources/meta/scalac/checkers/MetaCheckTreeNodes.java b/sources/meta/scalac/checkers/MetaCheckTreeNodes.java deleted file mode 100644 index 11ad75d77a..0000000000 --- a/sources/meta/scalac/checkers/MetaCheckTreeNodes.java +++ /dev/null @@ -1,158 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.scalac.checkers; - -import meta.java.Type; -import meta.scalac.ast.AbstractTreeCaseExpander; -import meta.scalac.ast.TreeKind; -import meta.scalac.ast.TreeType; -import meta.scalac.ast.TreeNode; -import meta.scalac.ast.TreeField; -import meta.scalac.ast.TreeFieldLink; - -public class MetaCheckTreeNodes extends AbstractTreeCaseExpander { - - //######################################################################## - // Public Methods - - public void printTreeCaseBody(TreeNode node) { - if (node.fields != null) { - for (int i = 0; i < node.fields.length; i++) { - TreeField field = node.fields[i]; - printCheckField(node, field.type, field.name, "i"); - } - if (node.hasLinkedFields()) { - writer.println("Symbol symbol = tree.symbol();"); - writer.print("if (symbol != null)").lbrace(); - for (int i = 0; i < node.fields.length; i++) - if (node.fields[i].link != null) - printCheckFieldLink(node.fields[i]); - writer.rbrace(); - } - } - printCheckNode(node); - writer.println("return;"); - } - - private void printCheckNode(TreeNode node) { - if (node.start.constant != null) { - writer.println("assert global.currentPhase.id >= " + - "phases."+node.start.constant + ".id() :").indent(); - writer.println("\"cannot create instance of " + node.name + - " before phase " + node.start.name + ", \" +"); - writer.println( - "\"current phase is \" + " + "global.currentPhase;").undent(); - } - if (node.stop.constant != null) { - writer.println("assert global.currentPhase.id <= " + - "phases."+node.stop.constant + ".id() :").indent(); - writer.println("\"cannot create instance of " + node.name + - " after phase " + node.stop.name + ", \" +"); - writer.println( - "\"current phase is \" + " + "global.currentPhase;").undent(); - } - } - - private void printCheckField(TreeNode node,Type type,String name,String i){ - if (type.isPrimitive()) return; - writer.println("assert " + name + " != null :").indent(); - printNullValue(node, name); - writer.println(";").undent(); - switch (type) { - case Reference(_, _): - break; - - case Array(Type item): - writer.print( - "for (int "+i+" = 0; "+i+" < "+name+".length; "+i+"++)"); - writer.lbrace(); - printCheckField(node, item, name+"["+i+"]", i+"i"); - writer.rbrace(); - break; - - case TreeType.Name(TreeKind kind): - if (kind != TreeKind.Any && kind != TreeKind.Test) { - writer.println("assert " + name + ".is" + kind + "Name() :") - .indent(); - printWrongKind(node, name, kind); - writer.println(";").undent(); - } - break; - - case TreeType.Tree(TreeKind kind): - if (kind != TreeKind.Any) { - writer.println("assert " + - name + ".is" + kind + "() :").indent(); - printWrongKind(node, name, kind); - writer.println(";").undent(); - } - break; - - case TreeType.Node(_): - break; - - default: - throw new Error(type.getClass().getName()); - } - } - - private void printCheckFieldLink(TreeField field) { - String getter = field.link.getLink(); - writer.println("assert symbol." +getter+ " == " +field+ " :").indent(); - writer.println("\"symbol and tree " + field.link + " differ: \"+" + - "symbol." + getter + "+\" != \"+" +field+ ";"); - writer.undent(); - } - - private void printNullValue(TreeNode node, String field) { - String expanded = getExpandedField(field); - writer.print("\"field " +expanded+ " of class " +node+ " is null\""); - } - - private void printWrongKind(TreeNode node, String field, TreeKind kind) { - String expanded = getExpandedField(field); - writer.println("\"field " + expanded + " of class " + node + - " is not of kind " + kind + ", \" +"); - writer.print("\"found: \" + Debug.show("+field+")"); - // !!! " + \" of kind \" + kind("+field+")"; - } - - private String getExpandedField(String field) { - int begin = field.indexOf('['); - if (begin < 0) return field; - StringBuffer buffer = new StringBuffer(field.substring(0, begin)); - for (int end; (end = field.indexOf(']', begin)) >= 0; begin = end + 1){ - String index = field.substring(begin + 1, end); - buffer.append("[\"+").append(index).append("+\"]"); - } - return buffer.toString(); - } - - //######################################################################## -} - - -/* !!! - - protected static String kind(Tree tree) { - switch (tree) { - case Select(_, Name name): return kind(name); - case Ident(Name name): return kind(name); - } - return "unknown"; - } - - protected static String kind(Name name) { - if (name.isTypeName()) return "Type"; - if (name.isTermName()) return "Term"; - if (name.isConstrName()) return "Constr"; - return "unknown"; - } - -*/ diff --git a/sources/meta/util/AbstractFileExpander.java b/sources/meta/util/AbstractFileExpander.java deleted file mode 100644 index d77f6b81b3..0000000000 --- a/sources/meta/util/AbstractFileExpander.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.util; - -import java.io.File; - -/** A base class for file expanders. */ -public abstract class AbstractFileExpander { - - //######################################################################## - // Private Constants - - /** The meta package */ - private static final String meta = "meta"; - - /** The meta name prefix */ - private static final String Meta = "Meta"; - - //######################################################################## - // Public Methods - - /** Returns the TextWriter in which this expander writes. */ - public abstract TextWriter getTextWriter(); - - /** - * Returns the package associated with this expander or null if - * there no such package. The default implementation returns the - * package of this instance's class. If the outermost package is - * named "meta", this package is omitted. - */ - public String getPackage() { - String fullname = getClass().getName(); - int end = fullname.lastIndexOf('.'); - if (end < 0) return null; - int start = fullname.startsWith(meta + ".") ? meta.length() + 1 : 0; - return fullname.substring(start, end); - } - - /** - * Returns the name associated with this expander. The default - * implementation returns the name of this instance's class. If - * that name starts with "Meta", this prefix is omitted. - */ - public String getName() { - String fullname = getClass().getName(); - int index = fullname.lastIndexOf('.'); - String name = index < 0 ? fullname : fullname.substring(index + 1); - return name.startsWith(Meta) ? name.substring(Meta.length()) : name; - } - - /** - * Returns the directory of the target file. The default - * implementation returns the directory corresponding to the - * this instance's associated package. - */ - public String getTargetDirectory() { - String peckage = getPackage(); - return peckage == null ? "." : peckage.replace('.',File.separatorChar); - } - - /** - * Returns the base name of the target file. The default - * implementation returns this instance's associated name. - */ - public String getTargetBaseName() { - return getName(); - } - - /** - * Returns the suffix of the target file or null if it has no - * suffix. The default implementation returns null. - */ - public String getTargetSuffix() { - return null; - } - - /** Returns the target file. */ - public File getTargetFile(File root) { - String suffix = getTargetSuffix(); - String name = getTargetBaseName(); - if (suffix != null) name = name + "." + suffix; - return new File(new File(root, getTargetDirectory()), name); - } - - /** - * Returns the directory of the source file. The default - * implementation returns the directory of the target file. - */ - public String getSourceDirectory() { - return getTargetDirectory(); - } - - /** - * Returns the base name of the source file. The default - * implementation returns this instance's associated name. - */ - public String getSourceBaseName() { - return getName(); - } - - /** - * Returns the suffix of the source file or null if it has no - * suffix. The default implementation returns the target suffix - * suffixed with ".tmpl". - */ - public String getSourceSuffix() { - String suffix = getTargetSuffix(); - return (suffix == null ? "" : suffix + ".") + "tmpl"; - } - - /** Returns the source file. */ - public File getSourceFile(File root) { - String suffix = getSourceSuffix(); - String name = getSourceBaseName(); - if (suffix != null) name = name + "." + suffix; - return new File(new File(root, getSourceDirectory()), name); - } - - //######################################################################## -} diff --git a/sources/meta/util/AbstractMain.java b/sources/meta/util/AbstractMain.java deleted file mode 100644 index b7a3e190ff..0000000000 --- a/sources/meta/util/AbstractMain.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.util; - -/** A base class for Java programs. */ -public abstract class AbstractMain { - - //######################################################################## - // Public Functions - - public static String script() { - StackTraceElement[] stack = new Throwable().getStackTrace(); - return stack[stack.length - 1].getClassName(); - } - - public static Error abort() { - System.exit(1); - throw new Error("abort"); - } - - public static Error abort(String error) { - System.err.println(script() + ": " + error); - System.exit(1); - throw new Error(); - } - - public static Error abort(Exception exception) { - return abort("caught exception " + exception.toString()); - } - - //######################################################################## -} diff --git a/sources/meta/util/TextExpander.java b/sources/meta/util/TextExpander.java deleted file mode 100644 index 5fe7fbdb38..0000000000 --- a/sources/meta/util/TextExpander.java +++ /dev/null @@ -1,275 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.util; - -import java.io.File; -import java.io.FileReader; -import java.io.BufferedReader; -import java.io.IOException; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; - -/** A macro expander with support for indentation */ -public class TextExpander { - - //######################################################################## - // Public Constants - - /** Default macro name prefix */ - public static final String MACRO_PREFIX = "print"; - - /** Default macro left quote */ - public static final String MACRO_LQUOTE = "{#"; - - /** Default macro right quote */ - public static final String MACRO_RQUOTE = "#}"; - - /** Do not edit warning */ - public static final String DO_NOT_EDIT = - "DO NOT EDIT. Automatically generated file!"; - - //######################################################################## - // Private Constants - - /** An empty array of Classes */ - private static final Class [] NO_PARAMS = new Class[0]; - - /** An empty array of Objects */ - private static final Object[] NO_ARGS = new Object[0]; - - //######################################################################## - // Private Fields - - /** The output text writer */ - private final TextWriter writer; - - /** The macro expander */ - private final Object expander; - - /** The current macro name prefix */ - private String prefix; - - /** The current macro left quote */ - private String lquote; - - /** The current macro right quote */ - private String rquote; - - /** The current input name */ - private String name; - - /** The current input line number */ - private int line; - - /** The current error count */ - private int errors; - - //######################################################################## - // Public Constructors - - /** Creates a new TextExpander. */ - public TextExpander(TextWriter writer, Object expander) { - this.writer = writer; - this.expander = expander; - this.prefix = MACRO_PREFIX; - this.lquote = MACRO_LQUOTE; - this.rquote = MACRO_RQUOTE; - } - - //######################################################################## - // Public Methods - Text expansion - - /** Expands the text from the given file. */ - public void expandText(File file) { - setInputName(file.toString()); - setInputLine(0); - try { - BufferedReader reader = new BufferedReader(new FileReader(file)); - expandText(reader); - reader.close(); - } catch (IOException exception) { - error("input error", exception); - } - } - - /** Expands the text from the given character stream. */ - public void expandText(BufferedReader reader) { - try { - for (String line; (line = reader.readLine()) != null;) { - this.line++; - expandLine(line); - } - } catch (IOException exception) { - error("input error", exception); - } - } - - /** Expands the given line. */ - public void expandLine(String line) { - int index = 0; - int column = 0; - for (; index < line.length(); index++) { - switch (line.charAt(index)) { - case ' ' : column += 1; continue; - case '\t': column += 8 - (column % 8); continue; - } - break; - } - if (index < line.length()) { - int width = writer.getIndentWidth(); - writer.setIndentLevel(column / width); - for (int i = 0; i < column % width; i++) writer.print(' '); - line = line.substring(index); - if (line.indexOf("$Id") >= 0) - line = line.replaceFirst("[$]Id.*[$]", DO_NOT_EDIT); - expand(line); - } - writer.println(); - } - - /** Expands the given string. */ - public void expand(String input) { - int start = 0; - while (true) { - int lindex = input.indexOf(lquote, start); - if (lindex < 0) break; - int rindex = input.indexOf(rquote, lindex + lquote.length()); - if (rindex < 0) { error("unclosed macro"); break; } - String macro = input.substring(lindex + lquote.length(), rindex); - if (macro.indexOf(lquote) >= 0) { error("unclosed macro"); break; } - if (start < lindex) writer.print(input.substring(start, lindex)); - expandMacro(macro); - start = rindex + rquote.length(); - } - if (start < input.length()) writer.print(input.substring(start)); - } - - //######################################################################## - // Public Methods - Macro expansion - - /** Expands the given macro. */ - public void expandMacro(String macro) { - String member = prefix + macro; - Class clasz = expander.getClass(); - try { - expandMacro(macro, clasz.getMethod(member, NO_PARAMS)); - } catch (NoSuchMethodException exception) { - error("macro '" + macro + "' is undefined"); - writer.print(lquote + macro + rquote); - } - } - - /** Expands the given macro by invoking the given method. */ - public void expandMacro(String macro, Method method) { - try { - method.invoke(expander, NO_ARGS); - } catch (IllegalAccessException exception) { - error("macro '" + macro + "' could not access method " + method); - writer.print(lquote + macro + rquote); - } catch (InvocationTargetException exception) { - error("macro '" + macro + "' raised an exception"); - exception.getTargetException().printStackTrace(); - } - } - - //######################################################################## - // Public Methods - Error messages - - /** Prints an error message. */ - public void error(String error) { - String prefix = name != null ? name + ":" : "error:"; - if (line > 0) prefix = prefix + line + ":"; - System.err.println(prefix + " " + error); - errors++; - } - - /** Prints an error message. */ - public void error(String error, Throwable exception) { - if (exception.getMessage() != null) - error(exception.getMessage()); - else - error(error + " (" + exception.getClass().getName() + ")"); - } - - //######################################################################## - // Public Methods - Getters - - /** Returns the output text writer. */ - public TextWriter getOutputWriter() { - return writer; - } - - /** Returns the macro expander. */ - public Object getMacroExpander() { - return expander; - } - - /** Returns the current macro name prefix. */ - public String getMacroPrefix() { - return prefix; - } - - /** Returns the current macro left quote. */ - public String getMacroLeftQuote() { - return lquote; - } - - /** Returns the current macro right quote. */ - public String getMacroRightQuote() { - return lquote; - } - - /** Returns the current input name. */ - public String getInputName() { - return name; - } - - /** Returns the current input line. */ - public int getInputLine() { - return line; - } - - /** Returns the current error count. */ - public int getErrorCount() { - return errors; - } - - //######################################################################## - // Public Methods - Setters - - /** Sets the current macro name prefix. */ - public void setMacroPrefix(String prefix) { - this.prefix = prefix; - } - - /** Sets the current macro quotes. */ - public void setMacroQuotes(String lquote, String rquote) { - this.lquote = lquote; - this.rquote = rquote; - } - - /** Sets the current input name. */ - public void setInputName(String name) { - this.name = name; - } - - /** Sets the current input line. */ - public void setInputLine(int line) { - this.line = line; - } - - /** Sets the current error count. */ - public void setErrorCount(int errors) { - this.errors = errors; - } - - //######################################################################## -} diff --git a/sources/meta/util/TextWriter.java b/sources/meta/util/TextWriter.java deleted file mode 100644 index 2884848e83..0000000000 --- a/sources/meta/util/TextWriter.java +++ /dev/null @@ -1,248 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package meta.util; - -/** A string generator with support for indentation and spacing. */ -public class TextWriter { - - //######################################################################## - // Private Constants - - /** The line separator */ - private static final String LINE = System.getProperty("line.separator"); - - /** The default width of an indentation level */ - private static final String STEP = " "; - - //######################################################################## - // Private Fields - - /** The output buffer */ - private final StringBuffer buffer; - - /** The width of an indentation level */ - private final String step; - - /** The current indentation level */ - private int level; - - /** Do we need to align? */ - private boolean align; - - /** Do we need to print a white space? */ - private boolean space; - - /** Is there already a empty line? */ - private boolean line; - - //######################################################################## - // Public Constructors - - /** Creates a new TextWriter. */ - public TextWriter() { - this(new StringBuffer()); - } - - /** Creates a new TextWriter. */ - public TextWriter(String step) { - this(new StringBuffer(), step); - } - - /** Creates a new TextWriter. */ - public TextWriter(String step, int level) { - this(new StringBuffer(), step, level); - } - - /** Creates a new TextWriter. */ - public TextWriter(StringBuffer buffer) { - this(buffer, STEP, 0); - } - - /** Creates a new TextWriter. */ - public TextWriter(StringBuffer buffer, String step) { - this(buffer, step, 0); - } - - /** Creates a new TextWriter. */ - public TextWriter(StringBuffer buffer, String step, int level) { - this.buffer = buffer; - this.step = step; - this.level = level; - this.align = false; - this.space = false; - this.line = false; - } - - //######################################################################## - // Public Methods - Printing - - /** Prints a new line. */ - public TextWriter println() { - return line(); - } - - /** Prints the boolean value followed by a new line. */ - public TextWriter println(boolean value) { - return print(value).line(); - } - - /** Prints the byte value followed by a new line. */ - public TextWriter println(byte value) { - return print(value).line(); - } - - /** Prints the short value followed by a new line. */ - public TextWriter println(short value) { - return print(value).line(); - } - - /** Prints the char value followed by a new line. */ - public TextWriter println(char value) { - return print(value).line(); - } - - /** Prints the int value followed by a new line. */ - public TextWriter println(int value) { - return print(value).line(); - } - - /** Prints the long value followed by a new line. */ - public TextWriter println(long value) { - return print(value).line(); - } - - /** Prints the float value followed by a new line. */ - public TextWriter println(float value) { - return print(value).line(); - } - - /** Prints the double value followed by a new line. */ - public TextWriter println(double value) { - return print(value).line(); - } - - /** Prints the string followed by a new line. */ - public TextWriter println(String value) { - return print(value).line(); - } - - /** Prints the boolean value. */ - public TextWriter print(boolean value) { - return print(String.valueOf(value)); - } - - /** Prints the byte value. */ - public TextWriter print(byte value) { - return print(String.valueOf(value)); - } - - /** Prints the short value. */ - public TextWriter print(short value) { - return print(String.valueOf(value)); - } - - /** Prints the char value. */ - public TextWriter print(char value) { - return print(String.valueOf(value)); - } - - /** Prints the int value. */ - public TextWriter print(int value) { - return print(String.valueOf(value)); - } - - /** Prints the long value. */ - public TextWriter print(long value) { - return print(String.valueOf(value)); - } - - /** Prints the float value. */ - public TextWriter print(float value) { - return print(String.valueOf(value)); - } - - /** Prints the long value. */ - public TextWriter print(double value) { - return print(String.valueOf(value)); - } - - /** Prints the string. */ - public TextWriter print(String value) { - if (align) for (int i = 0; i < level; i++) buffer.append(step); - if (space) buffer.append(' '); - buffer.append(value); - align = false; - space = false; - line = false; - return this; - } - - //######################################################################## - // Public Methods - Formating - - /** Returns the indentation width. */ - public int getIndentWidth() { - return step == null ? -1 : step.length(); - } - - /** Returns the indentation level. */ - public int getIndentLevel() { - return level; - } - - /** Sets the indentation level. */ - public TextWriter setIndentLevel(int level) { - this.level = level; - return this; - } - - /** Increases the indentation level by one. */ - public TextWriter indent() { - level++; - return this; - } - - /** Decreases the indentation level by one. */ - public TextWriter undent() { - level--; - return this; - } - - /** Starts a new line. */ - public TextWriter line() { - if (step == null) return space(); - if (line) return this; - buffer.append(LINE); - line = align; - align = true; - space = false; - return this; - } - - /** Inserts a white space. */ - public TextWriter space() { - space = !align; - return this; - } - - //######################################################################## - // Public Methods - Accessing - - /** Returns the underlying StringBuffer. */ - public StringBuffer getBuffer() { - return buffer; - } - - /** Returns the generated string. */ - public String toString() { - return buffer.toString(); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scala4ant/AntAdaptor.scala b/sources/scala/tools/scala4ant/AntAdaptor.scala deleted file mode 100644 index d60ef9c652..0000000000 --- a/sources/scala/tools/scala4ant/AntAdaptor.scala +++ /dev/null @@ -1,209 +0,0 @@ - -import scalac._; -import scala.tools.util.Reporter; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.Execute; -import org.apache.tools.ant.taskdefs.Javac; -import org.apache.tools.ant.taskdefs.LogStreamHandler; -import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; -import org.apache.tools.ant.types.Commandline; -import org.apache.tools.ant.types.Path; -import java.io.IOException; - -package scala.tools.scala4ant { - - /** Scala compiler adaptor. adapted from (see below for additions to Scala license) - * jaco.framework.ant.AntCompilerAdaptor (c) Matthias Zenger, and - * org.apache.tools.ant.taskdefs.DefaultCompilerAdapter - * (c) the Apache Software Foundation - * - * @author Burak Emir - * @version 1.6 - * $Id$ - */ - - class AntAdaptor extends DefaultCompilerAdapter { - - final val FSEP = java.io.File.separator; - final val PSEP = java.io.File.pathSeparator; - - final val PRODUCT = System.getProperty("scala.product", "scalac"); - final val VERSION = System.getProperty("scala.version", "unknown version"); - - def runCompiler( args:Array[String] ) = { - var ex:Throwable = _; - //Console.println("runCompiler"); - var result = true; - try { - scala.tools.scalac.Main.main1( false, args ); - } catch { - case e:Throwable => - ex = e; - } - if( null != ex ) { - ex.printStackTrace(); - throw new BuildException("internal error of scalac:"+ex.getClass()); - } - - if( scala.tools.scalac.Main.reporter.errors() > 0 ) - throw new BuildException("there were compile errors"); - - true - } - - def compilerName() = "scalac"; - - override def setJavac( attributes:Javac ) = { - super.setJavac( attributes ); - } - - def execute() = { - attributes.log("Using " + compilerName() + " as scala compiler", - Project.MSG_VERBOSE); - runCompiler( setupScalacCommand().getArguments() ); - } - - def inferScalaPath( paths:Array[String] ) = { - - //Console.println("inferScalaPath"); - var x:List[String] = Nil; - for (val p <- paths) { - val z = p.lastIndexOf("lib"+FSEP+"scala.jar"); - if( z > -1 ) { // distribution - val p1 = new StringBuffer( p.substring( 0, z ) ); - x = p1.append("src").toString() :: p :: x ; - x = p::x; - } else { - val z2 = p.lastIndexOf("scala"+FSEP+"classes"); - if( z2 > -1 ) { // developer version - val p1 = new StringBuffer( - p.substring( 0, z2 + 6 /* length of "scala"+SEP */ ) - ); - x = p :: p1.append("sources").toString() :: x ; - } - } - } - //Console.println("DONE inferScalaPath"); - x - }; - - def setupScalacCommand() = { - //Console.println("setupScalaCommand"); - val cmd = new Commandline(); - val cp = new Path( this.project ); - - //- encoding? - val stask = this.attributes.asInstanceOf[ScalacTask]; - if(null != stask.getEncoding()) { - cmd.createArgument().setValue( "-encoding" ); - cmd.createArgument().setValue( stask.getEncoding() ); - } - - if( destDir != null ) { - cmd.createArgument().setValue( "-d" ); - cmd.createArgument().setFile( destDir ); - cp.setLocation( destDir ); - } - - if ( debug ) - cmd.createArgument().setValue( "-g" ); - - /* cp.addExisting( Path.systemClasspath );*/ - /* cp.addJavaRuntime(); */ - - if( compileClasspath != null ) { - cp.addExisting( compileClasspath ); - } - - cmd.createArgument().setValue("-classpath"); - cmd.createArgument().setPath( cp ); - - var bcp = inferScalaPath(Path.systemClasspath.list()); - val bcps = (bcp./: (PSEP) { (x:String,y:String) => x+PSEP+y }); - - /* scala.tools.util.ClassPath replaces "::" / ";;" at the beginning - with something meaningful - */ - cmd.createArgument().setValue("-bootclasspath"); - cmd.createArgument().setValue( bcps ); - - cmd.createArgument().setValue("-sourcepath"); - cmd.createArgument().setPath( - if (compileSourcepath != null) { - compileSourcepath; - } else { - src; - } - ); - - - if (bootclasspath != null && bootclasspath.size() > 0) { - cmd.createArgument().setValue("-bootclasspath"); - cmd.createArgument().setPath(bootclasspath); - } - - if (extdirs != null && extdirs.size() > 0) { - cmd.createArgument().setValue("-extdirs"); - cmd.createArgument().setPath(extdirs); - } - - logAndAddFilesToCompile(cmd); - //Console.println("DONE setupScalaCommand"); - cmd - } - } -} - -/* - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2002 The Apache Software Foundation. All rights - * reserved. - * Copyright (c) 2000-2002 Matthias Zenger. All rights reserved. - * Copyright (c) 2003-2004 Burak Emir. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "The Jakarta Project", "Ant", and "Apache Software - * Foundation" must not be used to endorse or promote products derived - * from this software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * -*/ diff --git a/sources/scala/tools/scala4ant/AntTask.scala b/sources/scala/tools/scala4ant/AntTask.scala deleted file mode 100644 index 61b529cf35..0000000000 --- a/sources/scala/tools/scala4ant/AntTask.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tools.scala4ant; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.taskdefs.Javac; - -// obsolete - -class AntTask extends Javac { - override def execute():unit = { - throw new BuildException("please use ScalacTask$class instead of AntTask$class"); - } - -} diff --git a/sources/scala/tools/scala4ant/NscAdaptor.scala b/sources/scala/tools/scala4ant/NscAdaptor.scala deleted file mode 100644 index 57d8fd5059..0000000000 --- a/sources/scala/tools/scala4ant/NscAdaptor.scala +++ /dev/null @@ -1,134 +0,0 @@ - -//import scalac._; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.Execute; -import org.apache.tools.ant.taskdefs.Javac; -import org.apache.tools.ant.taskdefs.LogStreamHandler; -import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; -import org.apache.tools.ant.types.Commandline; -import org.apache.tools.ant.types.Path; -import java.io.IOException; - -package scala.tools.scala4ant { - - /** Scala compiler adaptor. adapted from (see below for additions to Scala license) - * jaco.framework.ant.AntCompilerAdaptor (c) Matthias Zenger, and - * org.apache.tools.ant.taskdefs.DefaultCompilerAdapter - * (c) the Apache Software Foundation - * - * @author Burak Emir - * @version 1.6 - * $Id$ - */ - - class NscAdaptor extends DefaultCompilerAdapter { - - def runCompiler( args:Array[String] ) = { - var ex:Throwable = _; - //Console.println("runCompiler"); - var result = true; - try { - scala.tools.nsc.Main.process( args ); - } catch { - case e:Throwable => - ex = e; - } - if( null != ex ) { - ex.printStackTrace(); - throw new BuildException("internal error of nsc:"+ex.getClass()); - } - - if( scala.tools.nsc.Main.errors() > 0 ) - throw new BuildException("there were compile errors"); - - true - } - - def compilerName() = "nsc"; - - def execute() = { - attributes.log("Using " + compilerName() + " as scala compiler", - Project.MSG_VERBOSE); - - runCompiler( setupNscCommand().getArguments() ); - } - - def setupNscCommand() = { - //Console.println("setupScalaCommand"); - val cmd = new Commandline(); - val cp = new Path( this.project ); - - //- attribute @nscArgs in order to pass anything you like - val moreargs = this.attributes.asInstanceOf[NscTask].moreArgs(); - for(val a <- moreargs) { - if(a.length() > 0) { - Console.println("NscAdaptor adds argument '"+a+"'"); - cmd.createArgument().setValue(a); - } - } - - - //- encoding? @todo - //val stask = this.attributes.asInstanceOf[ScalacTask]; - //if(null != stask.getEncoding()) { - // cmd.createArgument().setValue( "-encoding" ); - // cmd.createArgument().setValue( stask.getEncoding() ); - //} - - //- destdir - if( destDir != null ) { - cmd.createArgument().setValue( "-d" ); - cmd.createArgument().setFile( destDir ); - cp.setLocation( destDir ); - } - - /* cp.addExisting( Path.systemClasspath );*/ - /* cp.addJavaRuntime(); */ - - //- classpath - if( compileClasspath != null ) { - cp.addExisting( compileClasspath ); - } - - cmd.createArgument().setValue("-classpath"); - cmd.createArgument().setPath( cp ); - - //var bcp = inferScalaPath(Path.systemClasspath.list()); - //val bcps = (bcp./: (PSEP) { (x:String,y:String) => x+PSEP+y }); - - /* scala.tools.util.ClassPath replaces "::" / ";;" at the beginning - with something meaningful - */ - //cmd.createArgument().setValue("-bootclasspath"); - //cmd.createArgument().setValue( bcps ); - - cmd.createArgument().setValue("-sourcepath"); - cmd.createArgument().setPath( - if (compileSourcepath != null) { - compileSourcepath; - } else { - src; - } - ); - - if (bootclasspath != null && bootclasspath.size() > 0) { - cmd.createArgument().setValue("-bootclasspath"); - cmd.createArgument().setPath(bootclasspath); - } - - //if (extdirs != null && extdirs.size() > 0) { - // cmd.createArgument().setValue("-extdirs"); - // cmd.createArgument().setPath(extdirs); - //} - - logAndAddFilesToCompile(cmd); - //Console.println("DONE setupScalaCommand"); - cmd - } - - - } -} - diff --git a/sources/scala/tools/scala4ant/NscTask.scala b/sources/scala/tools/scala4ant/NscTask.scala deleted file mode 100644 index e50199f6ac..0000000000 --- a/sources/scala/tools/scala4ant/NscTask.scala +++ /dev/null @@ -1,118 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -package scala.tools.scala4ant; - -import java.io.File; - -import org.apache.tools.ant.taskdefs.Javac; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.util._; - - -/** - * The <code>NscTask</code> class provides an Ant task for - * for the as-yet nonexistent <code>nsc</code> command. - * i.e.<pre> - * <nsc srcdir="${src}" destdir="${build}"> - * <include name="test.scala"/> - * </nsc> - * </pre> - * - * @author Burak Emir, Stephane Micheloud - * @version 1.0 - */ - -class NscTask extends Javac { - - private val fileUtils: FileUtils = FileUtils.newFileUtils(); - - private var verbose = false; - private var force = false; - private var nscArgs = ""; - - def setCp(s: Path) = setClasspath(s); - - def setForce(b: Boolean) = this.force = b; - def getForce() = force; - - def setNscArgs(s: String) = this.nscArgs = s; - def getNscArgs() = nscArgs; - - def moreArgs():Array[String] = { - getNscArgs().split(";"); - } - - override def execute() = { - System.setProperty("scala.home", ScalaRuntime.home.toString()); - //System.setProperty("scala.product", scala.tools.scalac.Main.PRODUCT); - //System.setProperty("scala.version", scala.tools.scalac.Main.VERSION); - System.setProperty("scala.class.path", "."); - System.setProperty("scala.boot.class.path", ScalaRuntime.bootclasspath.toString()); - - getProject().setProperty("build.compiler", - "scala.tools.scala4ant.NscAdaptor$class"); - - super.execute(); - } - - override protected def scanDir(srcDir: File, destDir: File, files: Array[String]): Unit = { - if (force) { - val newCompileList = new Array[File](compileList.length + files.length); - System.arraycopy(compileList, 0, newCompileList, 0, compileList.length); - var j, i = 0; - - def handleFile( theFile:String ):unit = { - /* this, because wile create anon-class -> access violation */ - if (theFile.endsWith(".scala")) { - if (srcDir == null) { - newCompileList(compileList.length + j) = new File(theFile); - j = j + 1; - } - else { - newCompileList(compileList.length + j) = - fileUtils.resolveFile(srcDir, theFile); - j = j + 1 - } - } - } - - while (i < files.length) { - handleFile(files(i)); - i = i + 1; - } - - if (j == files.length) - compileList = newCompileList; - else { - compileList = new Array[File](j); - System.arraycopy(newCompileList, 0, compileList, 0, j); - } - } else { - val m = new GlobPatternMapper(); - - def handleNewFiles(newFiles:Array[File]): Unit = { - if (newFiles.length > 0) { - val newCompileList = - new Array[File](compileList.length + newFiles.length); - System.arraycopy(compileList, 0, newCompileList, 0, - compileList.length); - System.arraycopy(newFiles, 0, newCompileList, - compileList.length, newFiles.length); - compileList = newCompileList; - } - } - m.setFrom("*.scala"); - m.setTo("*.class"); - val sfs = new SourceFileScanner(this); - handleNewFiles(sfs.restrictAsFiles(files, srcDir, destDir, m)); - } - } - -} diff --git a/sources/scala/tools/scala4ant/ScalaRuntime.scala b/sources/scala/tools/scala4ant/ScalaRuntime.scala deleted file mode 100644 index 72cfdf0ae7..0000000000 --- a/sources/scala/tools/scala4ant/ScalaRuntime.scala +++ /dev/null @@ -1,133 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -package scala.tools.scala4ant; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.types.Path; - - -/** - * The <code>ScalaRuntime</code> object provides informations - * about the Scala runtime environment. - * - * @author Stephane Micheloud - * @version 1.1 - */ - -object ScalaRuntime { - - private val SCALA_RUNTIME_LIB = "lib"; - private val SCALA_RUNTIME_SOURCES = "sources"; - private val SCALA_RUNTIME_CLASSES = "classes"; - - private val SCALA_JAR_SOME_CLASS = "scala.ScalaObject"; - private val TOOLS_JAR_SOME_CLASS = getClass().getName(); // myself ! - private val FJBG_JAR_SOME_CLASS = "ch.epfl.lamp.fjbg.JFieldOrMethod"; - - check(SCALA_JAR_SOME_CLASS, "scala.jar"); - check(TOOLS_JAR_SOME_CLASS, "tools.jar"); - check(FJBG_JAR_SOME_CLASS, "fjbg.jar"); - - val home: Path = { - val p = Path.systemClasspath.createPath(); - val name = getResourceLocation(SCALA_JAR_SOME_CLASS); - val i = Math.max(name.lastIndexOf(SCALA_RUNTIME_LIB), - name.lastIndexOf(SCALA_RUNTIME_CLASSES)); - p.setPath(if (i > 0) name.substring(0, i - 1) else name); - p - } - - val sourcepath: Path = { - val p = Path.systemClasspath.createPath(); - val s = home.toString() + java.io.File.separator + SCALA_RUNTIME_SOURCES; - p.setPath(s); - p - } - - val scalapath: Path = - getResourcePath(SCALA_JAR_SOME_CLASS); - - val classpath: Path = { - val toolsPath = getResourcePath(TOOLS_JAR_SOME_CLASS); - val fjbgPath = getResourcePath(FJBG_JAR_SOME_CLASS); - val p = Path.systemClasspath.createPath(); - p.append(scalapath); - p.append(toolsPath); - p.append(fjbgPath); - p - } - - val bootclasspath: Path = { - val p = Path.systemClasspath.createPath(); - p.append(scalapath); - p.append(sourcepath); - p - } - - /** - * Check if the required Scala libraries are present. - */ - private def check(className: String, jarName: String) = try { - Class.forName(className) - } catch { - case e: ClassNotFoundException => - throw new BuildException("Cannot run scala4ant.\n" - + "It seems " + jarName + " is not in your CLASSPATH."); - } - - /** - * Return the full path string of the the jar file or the - * directory containing the class <code>className</code>. - * - * @param classname - * @return - */ - private def getResourceLocation(className: String): String = { - def asResourceName(resource: String) = { - val name = - if (! resource.startsWith("/")) "/" + resource else resource; - name.replace('.', '/') + ".class" - } - val rsrcName = asResourceName(className); - val url = getClass().getResource(rsrcName); - if (url != null) { - val fn = url.getFile(); - val name = if (fn.startsWith("file:")) fn.substring(5) else fn; - val inx = name.lastIndexOf('!'); - val end = if (inx > 0) inx else name.lastIndexOf(rsrcName); - name.substring(0, end); - } - else - throw new BuildException("Cannot run scala4ant.\n" - + "Scala installation directory cannot be found."); - } - - /** - * Return the Ant path of the class <code>className</code>. - * - * @param classname - * @return - */ - private def getResourcePath(className: String) = { - val name = getResourceLocation(className); - val p = Path.systemClasspath.createPath(); - p.setPath(name); - p - } - - // for testing - def main(args: Array[String]): Unit = { - System.out.println("ScalaRuntime.home = " + ScalaRuntime.home); - System.out.println("ScalaRuntime.classpath = " + ScalaRuntime.classpath); - System.out.println("ScalaRuntime.bootclasspath = " + ScalaRuntime.bootclasspath); - System.out.println("ScalaRuntime.sourcepath = " + ScalaRuntime.sourcepath); - System.out.println("ScalaRuntime.scalapath = " + ScalaRuntime.scalapath); - } -} diff --git a/sources/scala/tools/scala4ant/ScalaTask.scala b/sources/scala/tools/scala4ant/ScalaTask.scala deleted file mode 100644 index 7b1a53984d..0000000000 --- a/sources/scala/tools/scala4ant/ScalaTask.scala +++ /dev/null @@ -1,51 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -package scala.tools.scala4ant; - -import org.apache.tools.ant.taskdefs.Java; -import org.apache.tools.ant.types.Path; - - -/** - * The <code>ScalaTask</code> class provides an Ant task for - * the <code>scala</code> command. - * i.e.<pre> - * <scala classpath="${build}" classname="examples.sort"/> - * </pre> - * - * @author Stephane Micheloud - * @version 1.0 - */ - -class ScalaTask extends Java { - - private val PRODUCT = "scala"; - - private val classpath = ScalaRuntime.scalapath; - - private var debug = false; - - override def getTaskName(): String = PRODUCT; - - override def setClasspath(s: Path): Unit = { - classpath.append(s); - super.setClasspath(classpath) - } - - def setDebug(debug: Boolean): Unit = this.debug = debug; - - override def execute() = { - if (debug) { - log("CLASSPATH=" + classpath.toString()); - } - super.execute() - } - -} diff --git a/sources/scala/tools/scala4ant/ScalacTask.scala b/sources/scala/tools/scala4ant/ScalacTask.scala deleted file mode 100644 index 76d130e0fa..0000000000 --- a/sources/scala/tools/scala4ant/ScalacTask.scala +++ /dev/null @@ -1,109 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -package scala.tools.scala4ant; - -import java.io.File; - -import org.apache.tools.ant.taskdefs.Javac; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.util._; - - -/** - * The <code>ScalacTask</code> class provides an Ant task for - * for the <code>scalac</code> command. - * i.e.<pre> - * <scalac srcdir="${src}" destdir="${build}"> - * <include name="test.scala"/> - * </scalac> - * </pre> - * - * @author Burak Emir, Stephane Micheloud - * @version 1.0 - */ - -class ScalacTask extends Javac { - - private val fileUtils: FileUtils = FileUtils.newFileUtils(); - - private var force = false; - - def setCp(s: Path) = setClasspath(s); - - def setForce(b: Boolean) = this.force = b; - def getForce() = force; - - override def execute() = { - System.setProperty("scala.home", ScalaRuntime.home.toString()); - System.setProperty("scala.product", scala.tools.scalac.Main.PRODUCT); - System.setProperty("scala.version", scala.tools.scalac.Main.VERSION); - System.setProperty("scala.class.path", "."); - System.setProperty("scala.boot.class.path", ScalaRuntime.bootclasspath.toString()); - - getProject().setProperty("build.compiler", - "scala.tools.scala4ant.AntAdaptor$class"); - - super.execute(); - } - - override protected def scanDir(srcDir: File, destDir: File, files: Array[String]): Unit = { - if (force) { - val newCompileList = new Array[File](compileList.length + files.length); - System.arraycopy(compileList, 0, newCompileList, 0, compileList.length); - var j, i = 0; - - def handleFile( theFile:String ):unit = { - /* this, because wile create anon-class -> access violation */ - if (theFile.endsWith(".scala")) { - if (srcDir == null) { - newCompileList(compileList.length + j) = new File(theFile); - j = j + 1; - } - else { - newCompileList(compileList.length + j) = - fileUtils.resolveFile(srcDir, theFile); - j = j + 1 - } - } - } - - while (i < files.length) { - handleFile(files(i)); - i = i + 1; - } - - if (j == files.length) - compileList = newCompileList; - else { - compileList = new Array[File](j); - System.arraycopy(newCompileList, 0, compileList, 0, j); - } - } else { - val m = new GlobPatternMapper(); - - def handleNewFiles(newFiles:Array[File]): Unit = { - if (newFiles.length > 0) { - val newCompileList = - new Array[File](compileList.length + newFiles.length); - System.arraycopy(compileList, 0, newCompileList, 0, - compileList.length); - System.arraycopy(newFiles, 0, newCompileList, - compileList.length, newFiles.length); - compileList = newCompileList; - } - } - m.setFrom("*.scala"); - m.setTo("*.class"); - val sfs = new SourceFileScanner(this); - handleNewFiles(sfs.restrictAsFiles(files, srcDir, destDir, m)); - } - } - -} diff --git a/sources/scala/tools/scala4ant/ScalapTask.scala b/sources/scala/tools/scala4ant/ScalapTask.scala deleted file mode 100644 index 837453b82f..0000000000 --- a/sources/scala/tools/scala4ant/ScalapTask.scala +++ /dev/null @@ -1,81 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -package scala.tools.scala4ant; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.Commandline; -import org.apache.tools.ant.types.Path; - - -/** - * The <code>ScalapTask</code> class provides an Ant task for - * for the <code>scalap</code> command. - * i.e.<pre> - * <scalap classpath="${build}" classname="examples.sort" private="true"/> - * </pre> - * - * @author Stephane Micheloud - * @version 1.0 - */ - -class ScalapTask extends Task { - - private val PRODUCT = "scalap"; - - private var classpath = ScalaRuntime.classpath; - private var classname = ""; - - private var showPrivateDefs = false; - private var isVerbose = false; - private var debug = false; - - override def getTaskName(): String = PRODUCT; - - def setClasspath(s: Path): Unit = classpath.append(s); - - def setCp(s: Path) = setClasspath(s); - - def setClassname(name: String): Unit = classname = name; - - def setPrivate(show: Boolean): Unit = showPrivateDefs = show; - - def setVerbose(verbose: Boolean): Unit = isVerbose = verbose; - - def setDebug(debug: Boolean): Unit = this.debug = debug; - - override def execute() = try { - System.setProperty("scala.home", ScalaRuntime.home.toString()); - System.setProperty("scala.product", PRODUCT); - System.setProperty("scala.version", scala.tools.scalap.Main.VERSION); - System.setProperty("scala.class.path", "."); - System.setProperty("scala.boot.class.path", ScalaRuntime.bootclasspath.toString()); - - if (debug) { - for (val arg <- getArgs()) - System.out.println(arg); - } - scala.tools.scalap.Main.main(getArgs()); - } - catch { - case e => - throw new BuildException("exception occurred:" + e.getClass()); - } - - private def getArgs() = { - val cmd = new Commandline(); - cmd.createArgument().setValue("-classpath"); - cmd.createArgument().setPath(classpath); - if (showPrivateDefs) cmd.createArgument().setValue("-private"); - if (isVerbose) cmd.createArgument().setValue("-verbose"); - cmd.createArgument().setValue(classname); - cmd.getArguments() - } -} diff --git a/sources/scala/tools/scalac/CompilerPhases.scala b/sources/scala/tools/scalac/CompilerPhases.scala deleted file mode 100644 index 9983a73e90..0000000000 --- a/sources/scala/tools/scalac/CompilerPhases.scala +++ /dev/null @@ -1,37 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{CompilerPhases => scalac_CompilerPhases} - -package scala.tools.scalac { - -/** - * This class defines all compiler phases and maintains a list of - * active phases. - */ -class CompilerPhases extends scalac_CompilerPhases { - - protected override def PARSER_PHASE(): Class = - Class.forName("scala.tools.scalac.ast.parser.ParserPhase$class"); - protected override def NAMER_PHASE(): Class = - Class.forName("scala.tools.scalac.typechecker.NamerPhase$class"); - protected override def ANALYZER_PHASE(): Class = - Class.forName("scala.tools.scalac.typechecker.AnalyzerPhase$class"); - protected override def REFCHECK_PHASE(): Class = - Class.forName("scala.tools.scalac.typechecker.RefCheckPhase$class"); - protected override def UNCURRY_PHASE(): Class = - Class.forName("scala.tools.scalac.transformer.UnCurryPhase$class"); - protected override def TRANSMATCH_PHASE(): Class = - Class.forName("scala.tools.scalac.transformer.TransMatchPhase$class"); - protected override def WHOLEPROG_PHASE(): Class = - Class.forName("scala.tools.scalac.wholeprog.WholeProgPhase$class"); - protected override def ICODE_PHASE(): Class = - Class.forName("scala.tools.scalac.icode.ICodePhase$class"); - - } -} diff --git a/sources/scala/tools/scalac/Global.scala b/sources/scala/tools/scalac/Global.scala deleted file mode 100644 index 03fb13986e..0000000000 --- a/sources/scala/tools/scalac/Global.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id: Global.scala -\* */ - - -import java.io.PrintWriter; - -import scalac.{CompilationUnit, CompilerCommand, Global => scalac_Global}; -import scalac.ast.printer.TreePrinter; -import scalac.backend.jvm.GenJVM; -import scalac.backend.msil.GenMSIL; -import scalac.symtab.Symbol; -import scalac.util.Debug; - -import scala.tools.util.Timer; - -package scala.tools.scalac { - -import ast.printer.{TextTreePrinter, HTMLTreePrinter, SwingTreePrinter}; -import backend.GenJVMFromICode; -import typechecker.Infer; - - -/** The global environment of a compiler run - * - */ -class Global(args: CompilerCommand, timer: Timer, interpret: Boolean) extends scalac_Global(args, timer, interpret) { - - def this(args: CompilerCommand, interpret: Boolean) = - this(args, scalac_Global.getTimer(args.reporter()), interpret); - - def this(args: CompilerCommand) = this(args, false); - - override def newInfer(): Infer = - new Infer(this, treeGen, make); - - override def newTextTreePrinter(writer: PrintWriter): TreePrinter = - new TextTreePrinter(this, writer); - - override def newHTMLTreePrinter(writer: PrintWriter): TreePrinter = - new HTMLTreePrinter(this, writer); - - override def newSwingTreePrinter(writer: PrintWriter): TreePrinter = - new SwingTreePrinter(this); - - /** .. - * - * @param units - */ - override def dump(units: Array[CompilationUnit]): Unit = { - if (target == scalac_Global.TARGET_JVM) { - GenJVM.translate(this, units); - } else if (target == scalac_Global.TARGET_MSIL) { - GenMSIL.translate(this, units); - } else if (target == scalac_Global.TARGET_JVMFROMICODE) { - GenJVMFromICode.translate(this, units); - } - symdata.clear(); - } - - /** .. - * - */ - protected override def loadFunctions(): Unit = { - val mixinOnly = target != scalac_Global.TARGET_INT; - List.range(0, definitions.FUNCTION_COUNT).foreach( - i => loadCode(definitions.FUNCTION_CLASS(i), mixinOnly)); - } - - /** .. - * - * @param clasz - * @param mixinOnly - */ - private def loadCode(clasz: Symbol, mixinOnly: Boolean): Unit = { - assert(clasz.isClass() && !clasz.isModuleClass(), Debug.show(clasz)); - if (clasz.isExternal()) { - try { - compileLate(getSourceFile(clasz), mixinOnly); - } catch { - case exception: java.io.IOException => - if (debug) exception.printStackTrace(); - error(exception.getMessage() + "; source file for " - + clasz + " is needed"); - } - } - } - -} // class Global - -} diff --git a/sources/scala/tools/scalac/Main.scala b/sources/scala/tools/scalac/Main.scala deleted file mode 100644 index 1542f98a21..0000000000 --- a/sources/scala/tools/scalac/Main.scala +++ /dev/null @@ -1,72 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -import scala.tools.util.{AbstractReporter, ConsoleReporter}; -import scalac.{CompilerCommand, Global => scalac_Global}; -import scalac.symtab.classfile.CLRTypes; - -package scala.tools.scalac { - -/** The main class for SoCoS, a compiler for the programming - * language Scala. - * - * @author Matthias Zenger - * @version 1.0 - */ -object Main { - - val PRODUCT: String = - System.getProperty("scala.product", "socos"); - val VERSION: String = - System.getProperty("scala.version", "unknown version"); - - def main(args: Array[String]): unit = main1( true, args ); - - // ant task needs to be aware of reporter.errors - var reporter: AbstractReporter = _; - - def main1( exitOnError:boolean, args: Array[String] ):unit = { - val reporter = new ConsoleReporter(); - this.reporter = reporter; - val command = new CompilerCommand( - PRODUCT, VERSION, reporter, new CompilerPhases()); - var ok = true; - if (command.parse(args) && command.files.list.size() > 0) { - if (command.target.value == scalac_Global.TARGET_MSIL) { - try { CLRTypes.init(command); } - catch { case e: Error => - e.printStackTrace(); - ok = false; - } - } - if (ok) { - val timer = scalac_Global.getTimer(reporter); - timer.start(); - val global = new Global(command, timer, false); - try { - val units = global.compile(command.files.toArray(), false); - if (reporter.errors() == 0) - if (!global.PHASE.CODEGEN.hasSkipFlag()) global.dump(units); - } catch { - case e: scala.tools.util.debug.AbortError => - if (global.debug) - e.printStackTrace(); - else - global.error("Internal compiler error: " + e.getMessage() - + "; use -debug to see a stack trace"); - } - timer.stop("total"); - reporter.printSummary(); - } - } - if( exitOnError ) { - System.exit(if (reporter.errors() > 0 || !ok) 1 else 0); - } - } -} -} diff --git a/sources/scala/tools/scalac/ant/Scalac.java b/sources/scala/tools/scalac/ant/Scalac.java deleted file mode 100644 index ba0278deeb..0000000000 --- a/sources/scala/tools/scalac/ant/Scalac.java +++ /dev/null @@ -1,524 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ - ** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** - ** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** - ** /_____/\____/\___/\____/____/ ** - ** ** -\* */ - -// $Id: $ - -package scala.tools.scalac.ant; - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Vector; - -import org.apache.tools.ant.AntClassLoader; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.MatchingTask; -import org.apache.tools.ant.types.EnumeratedAttribute; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.util.FileUtils; -import org.apache.tools.ant.util.GlobPatternMapper; -import org.apache.tools.ant.util.SourceFileScanner; -import org.apache.tools.ant.types.Reference; - -import scala.tools.scalac.CompilerPhases$class; -import scala.tools.scalac.Global$class; -import scala.tools.util.ConsoleReporter; -import scala.tools.util.Reporter; -import scala.tools.util.Timer; -import scala.tools.util.debug.AbortError; -import scalac.CompilationUnit; -import scalac.CompilerCommand; - -/** - * An Ant task to compile with the old Scala compiler. - * This task can take the following parameters as attributes:<ul> - * <li>srcdir (mandatory),</li> - * <li>srcref,</li> - * <li>destdir,</li> - * <li>classpath,</li> - * <li>classpathref,</li> - * <li>sourcepath,</li> - * <li>sourcepathref,</li> - * <li>bootclasspath,</li> - * <li>bootclasspathref,</li> - * <li>extdirs,</li> - * <li>extdirsref,</li> - * <li>encoding,</li> - * <li>verbose,</li> - * <li>debug,</li> - * <li>usepredefs,</li> - * <li>useimports,</li> - * <li>force.</li> - * </ul> - * It also takes the following parameters as nested elements:<ul> - * <li>src (for srcdir),</li> - * <li>classpath,</li> - * <li>sourcepath,</li> - * <li>bootclasspath,</li> - * <li>extdirs.</li> - * </ul> - */ -public class Scalac extends MatchingTask { - - private FileUtils fileUtils = FileUtils.newFileUtils(); - - private String SCALA_PRODUCT = - System.getProperty("scala.product", "Scalac Ant compiler"); - private String SCALA_VERSION = - System.getProperty("scala.version", "Unknown version"); - - // ################################################################### - // ##### Ant Properties ##### - // ################################################################### - - /** The directories that contain source files to compile. */ - private Path origin = null; - /** The directory to put the compiled files in. */ - private File destination = null; - - /** The class path to use for this compilation. */ - private Path classpath = null; - /** The source path to use for this compilation. */ - private Path sourcepath = null; - /** The boot class path to use for this compilation. */ - private Path bootclasspath = null; - /** The external extensions path to use for this compilation. */ - private Path extpath = null; - - /** The text encoding of the files to compile. */ - private String encoding = null; - - /** Whether to use verbose output or not. */ - private boolean verbose = false; - /** Whether to print-out some additional ant compilation information. */ - private boolean debug = false; - /** Whether to use implicit predefined values or not. */ - private boolean usepredefs = true; - /** Whether to implicitly import or not. */ - private boolean useimports = true; - /** What type of force compilation to use, if any. */ - private String force = "never"; - - // ################################################################### - // ##### Properties setters ##### - // ################################################################### - - /** - * A setter for the srcdir attribute. Used by Ant. - * @param input The value of <code>origin</code>. - */ - public void setSrcdir(Path input) { - if (origin == null) { - origin = input; - } else { - origin.append(input); - } - } - - /** - * A setter of the <code>origin</code> as a nested src Ant parameter. - * @return An origin path to be configured. - */ - public Path createSrc() { - if (origin == null) { - origin = new Path(getProject()); - } - return origin.createPath(); - } - - /** - * A setter of the <code>origin</code> as an external reference Ant parameter. - * @param input A reference to an origin path. - */ - public void setSrcref(Reference input) { - createSrc().setRefid(input); - } - - /** - * A setter for the destdir attribute. Used by Ant. - * @param input The value of <code>destination</code>. - */ - public void setDestdir(File input) { - destination = input; - } - - /** - * A setter for the classpath attribute. Used by Ant. - * @param input The value of <code>classpath</code>. - */ - public void setClasspath(Path input) { - if (classpath == null) { - classpath = input; - } else { - classpath.append(input); - } - } - - /** - * A setter of the <code>classpath</code> as a nested classpath Ant parameter. - * @return A class path to be configured. - */ - public Path createClasspath() { - if (classpath == null) { - classpath = new Path(getProject()); - } - return classpath.createPath(); - } - - /** - * A setter of the <code>classpath</code> as an external reference Ant parameter. - * @param input A reference to a class path. - */ - public void setClasspathref(Reference input) { - createClasspath().setRefid(input); - } - - /** - * A setter for the sourcepath attribute. Used by Ant. - * @param input The value of <code>sourcepath</code>. - */ - public void setSourcepath(Path input) { - if (sourcepath == null) { - sourcepath = input; - } else { - sourcepath.append(input); - } - } - - /** - * A setter of the <code>sourcepath</code> as a nested sourcepath Ant parameter. - * @return A source path to be configured. - */ - public Path createSourcepath() { - if (sourcepath == null) { - sourcepath = new Path(getProject()); - } - return sourcepath.createPath(); - } - - /** - * A setter of the <code>sourcepath</code> as an external reference Ant parameter. - * @param input A reference to a source path. - */ - public void setSourcepathref(Reference input) { - createSourcepath().setRefid(input); - } - - /** - * A setter for the boot classpath attribute. Used by Ant. - * @param input The value of <code>bootclasspath</code>. - */ - public void setBootclasspath(Path input) { - if (bootclasspath == null) { - bootclasspath = input; - } else { - bootclasspath.append(input); - } - } - - /** - * A setter of the <code>bootclasspath</code> as a nested sourcepath Ant parameter. - * @return A source path to be configured. - */ - public Path createBootclasspath() { - if (bootclasspath == null) { - bootclasspath = new Path(getProject()); - } - return bootclasspath.createPath(); - } - - /** - * A setter of the <code>bootclasspath</code> as an external reference Ant parameter. - * @param input A reference to a source path. - */ - public void setBootclasspathref(Reference input) { - createBootclasspath().setRefid(input); - } - - /** - * A setter for the external extensions path attribute. Used by Ant. - * @param input The value of <code>extpath</code>. - */ - public void setExtdirs(Path input) { - if (extpath == null) { - extpath = input; - } else { - extpath.append(input); - } - } - - /** - * A setter of the <code>extpath</code> as a nested sourcepath Ant parameter. - * @return A source path to be configured. - */ - public Path createExtdirs() { - if (extpath == null) { - extpath = new Path(getProject()); - } - return extpath.createPath(); - } - - /** - * A setter of the <code>extpath</code> as an external reference Ant parameter. - * @param input A reference to a source path. - */ - public void setExtdirsref(Reference input) { - createExtdirs().setRefid(input); - } - - /** - * A setter for the encoding attribute. Used by Ant. - * @param input The value of <code>encoding</code>. - */ - public void setEncoding(String input) { - encoding = input; - } - - /** - * A setter for the verbose attribute. Used by Ant. - * @param input The value for <code>verbose</code>. - */ - public void setVerbose(boolean input) { - verbose = input; - } - - /** - * A setter for the debug attribute. Used by Ant. - * @param input The value for <code>debug</code>. - */ - public void setDebug(boolean input) { - debug = input; - } - - /** - * A setter for the use predefs attribute. Used by Ant. - * @param input The value for <code>usepredefs</code>. - */ - public void setUsepredefs(boolean input) { - usepredefs = input; - } - - /** - * A setter for the use imports attribute. Used by Ant. - * @param input The value for <code>useimport</code>. - */ - public void setUseimports(boolean input) { - useimports = input; - } - - /** - * A setter for the force attribute. Used by Ant. - * @param input The value for <code>force</code>. - */ - public void setForce(ForceMode input) { - force = input.getValue(); - } - - // ################################################################### - // ##### Compilation and support methods ##### - // ################################################################### - - /** - * Generates a build error. Error location will be the current task in the ant file. - * - * @param message The message of the error. This message should be end-user readable. - * @throws org.apache.tools.ant.BuildException The build error exception. - * Will be thrown in all conditions. - */ - private void error(String message) throws BuildException { - throw new BuildException(message, getLocation()); - } - - /** - * Performs the compilation. - */ - public void execute() throws BuildException { - - // Tests if all mandatory attributes are set and valid. - if (origin == null) error("Attribute 'srcdir' is not set."); - if (origin.size() == 0) error("Attribute 'srcdir' is not set."); - if (destination != null && !destination.isDirectory()) - error("Attribute 'destdir' does not refer to an existing directory."); - - Vector sourceFilesList = new Vector(); - - // Scans source directories to build up a compile lists. - // If force is false, only files were the .class file in destination - // is newer than the .suffix file will be used. - String[] originList = origin.list(); - for (int i = 0; i < originList.length; i++) { - File originDir = getProject().resolveFile(originList[i]); - if (!originDir.exists()) { - log("Element '" + originDir.getPath() + "' in attribute 'srcdir' does not refer to an existing directory.", Project.MSG_WARN); - break; - } - DirectoryScanner originDirScanner = this.getDirectoryScanner(originDir); - String[] files = originDirScanner.getIncludedFiles(); - - if (force.compareToIgnoreCase("always") == 0) { - addFilesToSourceList(files, originDir, sourceFilesList); - } - else { - GlobPatternMapper mapper = new GlobPatternMapper(); - mapper.setTo("*.class"); - mapper.setFrom("*.scala"); - SourceFileScanner scanner = new SourceFileScanner(this); - String[] newFiles = scanner.restrict(files, originDir, destination, mapper); - if (force.compareToIgnoreCase("changed") == 0 && (newFiles.length > 0)) { - addFilesToSourceList(files, originDir, sourceFilesList); - } - else if (force.compareToIgnoreCase("never") == 0) { - addFilesToSourceList(newFiles, originDir, sourceFilesList); - } - } - } - - if (sourceFilesList.isEmpty()) { - log("No files selected for compilation"); - } - else { - log("Compiling " + sourceFilesList.size() + " source file" + (sourceFilesList.size() == 1 ? "" : "s") + (destination != null ? " to " + destination.toString() : "")); - } - - // Builds-up the compilation settings for Scalac with the existing Ant parameters. - Reporter reporter = new ConsoleReporter(); - CompilerCommand command = new CompilerCommand(SCALA_PRODUCT, SCALA_VERSION, reporter, new CompilerPhases$class()); - if (destination != null) command.outpath.value = destination.getAbsolutePath(); - if (classpath != null) command.classpath.value = makeAbsolutePath(classpath, "classpath"); - if (sourcepath != null) { - command.sourcepath.value = makeAbsolutePath(sourcepath, "sourcepath"); - } - else { - command.sourcepath.value = destination.getAbsolutePath(); - } - // The bootclasspath needs to be treated specially. - // When no bootclasspath is provided, the classpath of the current classloader is used: - // This is where the scala classes should be. - // Furthermore, the source files for the library must be available in the bootclasspath too. - // Notice also how the bootclasspath must finish with a ":" for it to work. - Path baseBootclasspath; - if (bootclasspath != null) { - baseBootclasspath = bootclasspath; - } - else { - baseBootclasspath = getClassLoaderClasspath(this.getClass().getClassLoader()); - } - command.bootclasspath.value = - makeAbsolutePath(baseBootclasspath, "bootclasspath") + File.pathSeparator; - if (!containsScala(command.bootclasspath.value)) { - log("Bootclasspath does not contain a recognized Scala distribution. This might cause unexpected errors (Stack Overflow)", Project.MSG_WARN); - } - if (extpath != null) command.extdirs.value = makeAbsolutePath(extpath, "extpath"); - if (encoding != null) command.encoding.value = encoding; - command.verbose.value = verbose; - command.debug.value = debug; - command.noimports.value = !useimports; - command.nopredefs.value = !usepredefs; - Timer timer = scalac.Global.getTimer(reporter); - - // Compiles the actual code - Global$class compiler = new Global$class(command, timer, false); - - String[] stringArray = new String[sourceFilesList.size()]; - try { - timer.start(); - CompilationUnit[] classes = compiler.compile((String[])sourceFilesList.toArray(stringArray), false); - if (reporter.errors() > 0) { - error("Compile failed with " + reporter.errors() + " error" + (reporter.errors() == 1 ? "" : "s") + "; see the compiler error output for details."); - } - compiler.dump(classes); - } - catch (AbortError exception) { - if (debug) exception.printStackTrace(); - error("Compile failed because of an internal compiler error; see the error output for details."); - } - finally { - timer.stop("Compile time"); - } - if (reporter.warnings() > 0) { - log("Compile suceeded with " + reporter.errors() + " warning" + (reporter.warnings() == 1 ? "" : "s") + "; see the compiler output for details."); - } - } - - private void addFilesToSourceList(String[] files, File originDir, Vector sourceFilesList) { - for (int i = 0; i < files.length; i++) { - String sourceFile = fileUtils.resolveFile(originDir, files[i]).toString(); - log(sourceFile, Project.MSG_VERBOSE); - sourceFilesList.add(sourceFile); - } - } - - private String makeAbsolutePath(Path path, String pathName) { - String result = ""; - String[] pathList = path.list(); - for (int i = 0; i < pathList.length; i++) { - File pathFile = new File(pathList[i]); - if (pathFile.exists()) { - result = result + ((result == "") ? "" : File.pathSeparator) + pathFile.getAbsolutePath(); - } - else { - log("Element '" + pathFile.toString() + "' in " + pathName + " does not exist.", Project.MSG_WARN); - result = result + ((result == "") ? "" : File.pathSeparator) + pathFile.toString(); - } - } - return result; - } - - private Path getClassLoaderClasspath(ClassLoader classLoader) throws BuildException { - Path classLoaderClasspath = new Path(getProject()); - ClassLoader parentClassLoader = classLoader.getParent(); - String classloaderName = classLoader.getClass().getName(); - boolean isURLClassLoader = classloaderName.endsWith("URLClassLoader"); - boolean isAntClassLoader = classloaderName.endsWith("AntClassLoader2") || classloaderName.endsWith("AntClassLoader"); - if (isURLClassLoader) { - URL[] urls = ((URLClassLoader) classLoader).getURLs(); - for (int i = 0; i < urls.length; i++) { - classLoaderClasspath.append(new Path(getProject(), urls[i].toString())); - } - } - else if (isAntClassLoader) { - String[] paths = ((AntClassLoader) classLoader).getClasspath().split(File.pathSeparator); - for (int i = 0; i < paths.length; i++) { - classLoaderClasspath.append(new Path(getProject(), paths[i])); - } - } - if (parentClassLoader != null && parentClassLoader != classLoader) { - classLoaderClasspath.append(getClassLoaderClasspath(parentClassLoader)); - } - return classLoaderClasspath; - } - - private boolean containsScala(String path) { - boolean containsLibrary = false; - boolean containsTools = false; - String[] paths = path.split(File.pathSeparator); - for (int i = 0; i < paths.length; i++) { - if (paths[i].endsWith("scala.jar") || paths[i].endsWith("scala")) { - containsLibrary = true; - } - if (paths[i].endsWith("tools.jar") || paths[i].endsWith("tools")) { - containsTools = true; - } - } - return containsLibrary && containsTools; - } - - /** - * Enumerated attribute with the values "never", "always", "changed". - */ - public static class ForceMode extends EnumeratedAttribute { - /** - * @see EnumeratedAttribute#getValues - */ - public String[] getValues() { - return new String[] {"never", "always", "changed"}; - } - } - -} diff --git a/sources/scala/tools/scalac/ast/TreeList.scala b/sources/scala/tools/scalac/ast/TreeList.scala deleted file mode 100644 index e8ac0fb35b..0000000000 --- a/sources/scala/tools/scalac/ast/TreeList.scala +++ /dev/null @@ -1,86 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -import scalac.ast._; - -package scala.tools.scalac.ast { - -/** List of trees. - */ - -final class TreeList(ts: Array[Tree]) extends Iterable[Tree] { - - private var trees = ts; - private var len = ts.length; - - def this() = { this(new Array[Tree](4)); len = 0 } - - def append(tree: Tree): TreeList = { - if (len == trees.length) { - val ts = new Array[Tree](if (len == 0) 4 else len * 2); - System.arraycopy(trees, 0, ts, 0, len); - trees = ts; - } - trees(len) = tree; - len = len + 1; - this - } - - def append(tts: Array[Tree]): unit = { - for (val j <- Iterator.range(0, tts.length)) - append(tts(j)); - } - - def append(tl: TreeList): unit = { - for (val j <- Iterator.range(0, tl.len)) - append(tl.trees(j)); - } - - def clear(): unit = { - trees = new Array[Tree](4); - len = 0; - } - - def elements = new Iterator[Tree] { // don't change treelist while iterating! - private var i = 0; - def hasNext: Boolean = i < len; - def next: Tree = - if (i < len) { val x = trees(i) ; i = i + 1 ; x } - else error("next on empty iterator"); - } - - def length(): int = len; - - def get(i: int): Tree = trees(i); - - def first(): Tree = trees(0); - - def removeLast(): Tree = { - len = len - 1; - trees(len) - } - - def toArray(): Array[Tree] = { - val tts = new Array[Tree](len); - System.arraycopy(trees, 0, tts, 0, len); - tts - } - - def copyTo[t <: Tree](ts: Array[t]): Array[t] = copyTo(ts, 0); - - def copyTo[t <: Tree](ts: Array[t], from: int): Array[t] = { - System.arraycopy(trees, 0, ts, from, len); - ts; - } - - override def toString() = { - Iterator.fromArray(this.toArray()).toList.toString(); - } -} -} diff --git a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala deleted file mode 100644 index a817767544..0000000000 --- a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala +++ /dev/null @@ -1,608 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2005, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -** $Id$ -\* */ - -import java.lang.{Integer, Long, Float, Double}; - -import scalac._; -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.symtab.Modifiers; - -import scala.Iterator; -import scala.collection.immutable.ListMap ; -import scala.collection.mutable; -import scala.tools.scalac.util.NewArray; -import scala.tools.util.Position; -import scala.xml.{Text,TextBuffer}; - -package scala.tools.scalac.ast.parser { - -class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean) /*with scala.xml.parsing.MarkupParser[Tree,Tree] */{ - - import Tokens.{EMPTY, LBRACE, RBRACE}; - import scala.tools.scalac.ast.{TreeList => myTreeList} - - final val preserveWS = presWS; - - /** the XML tree factory */ - val handle: SymbolicXMLBuilder = - new SymbolicXMLBuilder(unit.global.make, unit.global.treeGen, p, presWS); - - /** holds the position in the source file */ - /*[Duplicate]*/ var pos: Int = _; - - /** holds temporary values of pos */ - /*[Duplicate]*/ var tmppos: Int = _; - - /** holds the next character */ - /*[Duplicate]*/ var ch: Char = _; - - /** character buffer, for names */ - /*[Duplicate]*/ protected val cbuf = new StringBuffer(); - - /** append Unicode character to name buffer*/ - /*[Duplicate]*/ protected def putChar(c: char) = cbuf.append( c ); - - /*[Duplicate]*/ var xEmbeddedBlock = false; - - /** munch expected XML token, report syntax error for unexpected */ - /*[Duplicate]*/ def xToken(that: Char): Unit = { - if( ch == that ) - nextch; - else - reportSyntaxError("'" + that + "' expected instead of '" + ch + "'"); - } - - var debugLastStartElement = new mutable.Stack[Pair[Int,String]]; - - /** checks whether next character starts a Scala block, if yes, skip it. - * @return true if next character starts a scala block - */ - /*[Duplicate]*/ def xCheckEmbeddedBlock:Boolean = { - xEmbeddedBlock = - enableEmbeddedExpressions && ( ch == '{' ) && { nextch;( ch != '{' ) }; - return xEmbeddedBlock; - } - - /** parse attribute and add it to listmap - * [41] Attributes ::= { S Name Eq AttValue } - * AttValue ::= `'` { _ } `'` - * | `"` { _ } `"` - * | `{` scalablock `}` - */ - /*[Duplicate]*/ def xAttributes = { - var aMap = new mutable.HashMap[String, Tree](); - while (xml.Parsing.isNameStart(ch)) { - val key = xName; - xEQ; - val delim = ch; - val pos1 = pos; - val value: /* AttribValue[*/Tree/*]*/ = ch match { - case '"' | '\'' => - nextch; - val tmp = xAttributeValue( delim ); - nextch; - gen.mkStringLit(pos1, tmp); - case '{' if enableEmbeddedExpressions => - nextch; - xEmbeddedExpr; - case _ => - reportSyntaxError( "' or \" delimited attribute value or '{' scala-expr '}' expected" ); - gen.mkStringLit(pos1, "<syntax-error>" ) - }; - // well-formedness constraint: unique attribute names - if( aMap.contains( key )) - reportSyntaxError( "attribute "+key+" may only be defined once" ); - aMap.update( key, value ); - if(( ch != '/' )&&( ch != '>' )) - xSpace; - }; - aMap - } - - /** attribute value, terminated by either ' or ". value may not contain <. - * @param endch either ' or " - */ - /*[Duplicate]*/ def xAttributeValue(endCh: char): String = { - while (ch != endCh) { - putChar(ch); - nextch; - }; - val str = cbuf.toString(); - cbuf.setLength(0); - // @todo: normalize attribute value - // well-formedness constraint - if (str.indexOf('<') != -1) { - reportSyntaxError( "'<' not allowed in attrib value" ); "" - } else { - str - } - } - - /** parse a start or empty tag. - * [40] STag ::= '<' Name { S Attribute } [S] - * [44] EmptyElemTag ::= '<' Name { S Attribute } [S] - */ - /*[Duplicate]*/ def xTag: Pair[String, mutable.Map[String, Tree]] = { - val elemName = xName; - xSpaceOpt; - val aMap = if (xml.Parsing.isNameStart(ch)) { - xAttributes; - } else { - new mutable.HashMap[String, Tree](); - } - Tuple2( elemName, aMap ); - } - - /* [42] '<' xmlEndTag ::= '<' '/' Name S? '>' */ - /*[Duplicate]*/ def xEndTag(n: String) = { - xToken('/'); - val m = xName; - if(n != m) reportSyntaxError( "expected closing tag of " + n/* +", not "+m*/); - xSpaceOpt; - xToken('>') - } - - /** '<! CharData ::= [CDATA[ ( {char} - {char}"]]>"{char} ) ']]>' - * - * see [15] - */ - /*[Duplicate]*/ def xCharData: Tree = { - xToken('['); - xToken('C'); - xToken('D'); - xToken('A'); - xToken('T'); - xToken('A'); - xToken('['); - val pos1 = pos; - val sb:StringBuffer = new StringBuffer(); - while (true) { - if (ch==']' && - { sb.append( ch ); nextch; ch == ']' } && - { sb.append( ch ); nextch; ch == '>' } ) { - sb.setLength( sb.length() - 2 ); - nextch; - return handle.charData( pos1, sb.toString() ); - } else sb.append( ch ); - nextch; - } - throw new ApplicationError("this cannot happen"); - }; - - /** CharRef ::= "&#" '0'..'9' {'0'..'9'} ";" - * | "&#x" '0'..'9'|'A'..'F'|'a'..'f' { hexdigit } ";" - * - * see [66] - */ - /*[Duplicate]*/ def xCharRef:String = { - val hex = ( ch == 'x' ) && { nextch; true }; - val base = if (hex) 16 else 10; - var i = 0; - while (ch != ';') { - ch match { - case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => - i = i * base + Character.digit( ch, base ); - case 'a' | 'b' | 'c' | 'd' | 'e' | 'f' - | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' => - if( !hex ) - reportSyntaxError("hex char not allowed in decimal char ref\n" - +"Did you mean to write &#x ?"); - else - i = i * base + Character.digit( ch, base ); - case _ => - reportSyntaxError("character '"+ch+" not allowed in char ref\n"); - } - nextch; - } - new String(Predef.Array(i.asInstanceOf[char])) - } -/** Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' - * - * see [15] - */ - /*[Duplicate]*/ def xComment: Tree = { - val sb:StringBuffer = new StringBuffer(); - xToken('-'); - xToken('-'); - while (true) { - if( ch=='-' && { sb.append( ch ); nextch; ch == '-' } ) { - sb.setLength( sb.length() - 1 ); - nextch; - xToken('>'); - return handle.comment( pos, sb.toString() ); - } else sb.append( ch ); - nextch; - } - throw new ApplicationError("this cannot happen"); - }; - - /*[Duplicate]*/ def appendText(pos: int, ts:mutable.Buffer[Tree], txt:String):Unit = { - if( !preserveWS ) - for( val t <- TextBuffer.fromString( txt ).toText ) { - ts.append( handle.text( pos, t.text ) ); - } - else - ts.append( handle.text( pos, txt )); - } - - /*[Duplicate]*/ def content: mutable.Buffer[Tree] = { - var ts = new mutable.ArrayBuffer[Tree]; - var exit = false; - while( !exit ) { - if( xEmbeddedBlock ) { - ts.append( xEmbeddedExpr ); - } else { - tmppos = pos; - ch match { - case '<' => // another tag - nextch; - ch match { - case '/' => - exit = true; // end tag - case '!' => - nextch; - if( '[' == ch ) // CDATA - ts.append( xCharData ); - else // comment - ts.append( xComment ); - case '?' => // PI - nextch; - ts.append( xProcInstr ); - case _ => - ts.append( element ); // child - } - - case '{' => - if( xCheckEmbeddedBlock ) { - ts.append(xEmbeddedExpr); - } else { - val str = new StringBuffer("{"); - str.append( xText ); - appendText(tmppos, ts, str.toString()); - } - // postcond: xEmbeddedBlock == false! - case '&' => // EntityRef or CharRef - nextch; - ch match { - case '#' => // CharacterRef - nextch; - val theChar = handle.text( tmppos, xCharRef ); - xToken(';'); - ts.append( theChar ); - case _ => // EntityRef - val n = xName ; - xToken(';'); - ts.append( handle.entityRef( tmppos, n ) ); - } - case _ => // text content - appendText(tmppos, ts, xText); - // here xEmbeddedBlock might be true - } - } - } - ts - } /* end content */ - - /** '<' element ::= xmlTag1 '>' { xmlExpr | '{' simpleExpr '}' } ETag - * | xmlTag1 '/' '>' - */ - /*[Duplicate]*/ def element: Tree = { - val pos1 = pos; - val Tuple2(qname, attrMap) = xTag; - //Console.println("MarkupParser::element("+qname+","+attrMap+")"); - if (ch == '/') { // empty element - xToken('/'); - xToken('>'); - handle.element( pos1, qname, attrMap, new mutable.ListBuffer[Tree] ); - } - else { // handle content - xToken('>'); - debugLastStartElement.push(Pair(pos1,qname)); - val ts = content; - xEndTag( qname ); - debugLastStartElement.pop; - handle.element( pos1, qname, attrMap, ts ); - } - } - - - /** Name ::= (Letter | '_' | ':') (NameChar)* - * - * see [5] of XML 1.0 specification - */ - /*[Duplicate]*/ def xName: String = { - if( xml.Parsing.isNameStart( ch ) ) { - do { - putChar( ch ); - nextch; - } while( xml.Parsing.isNameChar( ch ) ); - val n = cbuf.toString().intern(); - cbuf.setLength( 0 ); - n - } else { - reportSyntaxError( "name expected" ); - new String(); - } - } - - - /** scan [S] '=' [S]*/ - /*[Duplicate]*/ def xEQ = { xSpaceOpt; xToken('='); xSpaceOpt } - - /** skip optional space S? */ - /*[Duplicate]*/ def xSpaceOpt = { while( xml.Parsing.isSpace( ch ) ) { nextch; }} - - /** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */ - /*[Duplicate]*/ def xSpace = { - if (xml.Parsing.isSpace(ch)) { - nextch; xSpaceOpt - } - else { - reportSyntaxError("whitespace expected"); - } - } - -/** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {Char})]'?>' - * - * see [15] - */ - /*[Duplicate]*/ def xProcInstr: Tree = { - val sb:StringBuffer = new StringBuffer(); - val n = xName; - if( xml.Parsing.isSpace( ch ) ) { - xSpace; - while( true ) { - if( ch=='?' && { sb.append( ch ); nextch; ch == '>' } ) { - sb.setLength( sb.length() - 1 ); - nextch; - return handle.procInstr(tmppos, n.toString(), sb.toString()); - } else - sb.append( ch ); - nextch; - } - }; - xToken('?'); - xToken('>'); - return handle.procInstr(tmppos, n.toString(), sb.toString()); - } - - /** parse character data. - * precondition: xEmbeddedBlock == false (we are not in a scala block) - */ - /*[Duplicate]*/ def xText: String = { - if( xEmbeddedBlock ) throw new ApplicationError("internal error: encountered embedded block"); // assert - - if( xCheckEmbeddedBlock ) - return "" - else { - var exit = false; - while( !exit ) { - putChar( ch ); - exit = { nextch; xCheckEmbeddedBlock }||( ch == '<' ) || ( ch == '&' ); - } - val str = cbuf.toString(); - cbuf.setLength( 0 ); - str - } - } - //override type Tree = handle.Tree; - //override type Tree = handle.Tree; - - /** the XML tree builder */ - val gen = unit.global.treeGen ; - - final val PATTERN = true; - final val EXPR = false; - - val enableEmbeddedExpressions: Boolean = true; - - //val cbuf = new StringBuffer(); - - /** append Unicode character to name buffer*/ - //private def putChar(c: char) = cbuf.append( c ); - - /** xLiteral = element { element } - * @return Scala representation of this xml literal - * precondition: s.xStartsXML == true - */ - def xLiteral: Tree = try { - init; - handle.isPattern = false; - val pos = s.pos; - var tree = element; - xSpaceOpt; - // parse more XML ? - if (ch == '<') { - val ts = new mutable.ArrayBuffer[Tree](); - ts.append( tree ); - while( ch == '<' ) { - nextch; - ts.append( element ); - xSpaceOpt; - } - tree = handle.makeXMLseq( pos, ts ); - } - //Console.println("out of xLiteral, parsed:"+tree.toString()); - s.xSync2; - tree - } - catch { - case _:ArrayIndexOutOfBoundsException => - s.syntaxError(debugLastStartElement.top._1, - "missing end tag in XML literal for <" - +debugLastStartElement.top._2+">"); - Tree.Empty; - } - - /** @see xmlPattern. resynchronizes after succesful parse - * @return this xml pattern - * precondition: s.xStartsXML == true - */ - def xLiteralPattern:Tree = try { - init; - val oldMode = handle.isPattern; - handle.isPattern = true; - val pos = s.pos; - var tree = xPattern; xSpaceOpt; - if (ch == '<') { - val ts = new myTreeList(); ts.append( tree ); - while (ch == '<' && lookahead != '-') { - nextch; - ts.append( xPattern ); - xSpaceOpt; - } - tree = handle.makeXMLseqPat( pos, ts.toArray() ); - } - handle.isPattern = oldMode; - //Console.println("out of xLiteralPattern, parsed:"+tree.toString()); - s.xSync2; - tree - }catch { - case _:ArrayIndexOutOfBoundsException => - s.syntaxError(debugLastStartElement.top._1, - "missing end tag in XML literal for <" - +debugLastStartElement.top._2+">"); - Tree.Empty; - } - - def xEmbeddedExpr:Tree = { - sync; - val b = p.expr(true,false); - if(s.token != RBRACE) - reportSyntaxError(" expected end of Scala block"); - init; - //Console.println("[out of xScalaExpr s.ch = "+s.ch+" ch="+ch+"]"); - return b - } - - /** xScalaPatterns ::= patterns - */ - def xScalaPatterns: Array[Tree] = { - sync; - val b = p.patterns(); - if (s.token != RBRACE) - reportSyntaxError(" expected end of Scala patterns"); - init; - return b - } - - //var ch: Char = _; - - /** this method assign the next character to ch and advances in input */ - def nextch: Unit = { s.xNext; ch = s.ch; pos = s.pos; } - - def lookahead = { s.xLookahead } - - def init: Unit = { - ch = s.ch; - pos = s.pos; - //Console.println("\ninit! ch = "+ch); - } - - /** parse attribute and add it to listmap - * [41] Attributes ::= { S Name Eq AttValue } - * AttValue ::= `'` { _ } `'` - * | `"` { _ } `"` - * | `{` scalablock `}` - def xAttributes = { - var aMap = new mutable.HashMap[String, AttribValue[Tree]]; - while (xml.Parsing.isNameStart(ch)) { - val key = xName; - xEQ; - val delim = ch; - val value: Tree = ch match { - case '"' | '\'' => - val pos1 = pos; - nextch; - val tmp = xAttributeValue( delim ); - nextch; - gen.mkStringLit( pos1, tmp ) - case '{' => - nextch; - xEmbeddedExpr; - case _ => - xSyntaxError( "' or \" delimited attribute value or '{' scala-expr '}' expected" ); - gen.mkStringLit( pos, "<syntax-error>" ) - }; - // well-formedness constraint: unique attribute names - if( aMap.contains( key )) - xSyntaxError( "attribute "+key+" may only be defined once" ); - aMap.update( key, AttribValue( value )); - if(( ch != '/' )&&( ch != '>' )) - xSpace; - }; - aMap - } - */ - - - def reportSyntaxError(str: String) = { - s.syntaxError("in XML literal: " + str); - nextch; - } - - def sync: Unit = { - xEmbeddedBlock = false; - s.xSync; - } - - /** '<' xPattern ::= Name [S] { xmlPattern | '{' pattern3 '}' } ETag - * | Name [S] '/' '>' - */ - def xPattern:Tree = { - //Console.println("xPattern"); - val pos1 = pos; - val qname = xName; - debugLastStartElement.push(Pair(pos1,qname)); - xSpaceOpt; - if( ch == '/' ) { // empty tag - nextch; - xToken('>'); - return handle.makeXMLpat( pos1, qname, new mutable.ArrayBuffer[Tree]() ); - }; - - // else: tag with content - xToken('>'); - var ts = new mutable.ArrayBuffer[Tree]; - var exit = false; - while (! exit) { - val pos2 = pos; - if( xEmbeddedBlock ) { - ts ++ xScalaPatterns; - } else - ch match { - case '<' => { // tag - nextch; - if( ch != '/' ) { //child - ts.append( xPattern ); - } else { - exit = true - } - } - case '{' => // embedded Scala patterns - while( ch == '{' ) { - s.nextch(); - ts ++ xScalaPatterns; - } - // postcond: xEmbeddedBlock = false; - if (xEmbeddedBlock) throw new ApplicationError(); // assert - case _ => // teMaxt - appendText( pos2, ts, xText ); - // here xEmbeddedBlock might be true; - //if( xEmbeddedBlock ) throw new ApplicationError("after:"+text); // assert - } - } - xEndTag(qname); - debugLastStartElement.pop; - handle.makeXMLpat(pos1, qname, ts); - } - -} /* class MarkupParser */ -} diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala deleted file mode 100644 index 08c4a59f90..0000000000 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ /dev/null @@ -1,2314 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - - -import java.lang.{Integer, Long, Float, Double}; -import java.util.{Map, Stack}; - -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.symtab.Modifiers; -import scalac.symtab._; -import scalac._; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.NameTransformer; -import scalac.util.TypeNames; - -import scala.Iterator; -import scala.collection.immutable.ListMap; -import scala.collection.mutable; -import scala.collection.mutable.ListBuffer; -import scala.tools.scalac.util.NewArray; -import scala.tools.util.Position; - - -package scala.tools.scalac.ast.parser { - - -/** A recursive descent parser for the programming language Scala. - * - * @author Martin Odersky, Matthias Zenger, Burak Emir - * @version 1.3 - */ -class Parser(unit: CompilationUnit) { - - import Tokens._; - import scala.tools.scalac.ast.{TreeList => myTreeList} - - /** the lexical analyzer - */ - val s = new Scanner(unit); - - /** the markup parser - */ - val xmlp = new MarkupParser(unit, s, this, unit.global.xmlPreserveWS); - - /** the tree factory - */ - val make: TreeFactory = unit.global.make; - - /** the tree generator - */ - val gen: TreeGen = unit.global.treeGen; - - /** pattern checker and normalizer - */ - val pN = new PatternNormalizer(unit); - - /** The current nesting depths of while and do loops. - */ - var loopNestingDepth = 0; - - /** this is the general parse method - */ - def parse(): Array[Tree] = { - val ts = if (s.unit.console) templateStatSeq() else compilationUnit(); - accept(EOF); - ts - } - -/////// ERROR HANDLING /////////////////////////////////////////////////////// - - private def skip(): Unit = { - //System.out.println("<skipping> " + s.token2string(s.token));//DEBUG - var nparens = 0; - var nbraces = 0; - while (true) { - s.token match { - case EOF => - return; - case SEMI => - if (nparens == 0 && nbraces == 0) - return; - case RPAREN => - nparens = nparens - 1; - case RBRACE => - if (nbraces == 0) return; - nbraces = nbraces - 1; - case LPAREN => - nparens = nparens + 1; - case LBRACE => - nbraces = nbraces + 1; - case _ => - } - s.nextToken(); - } - } - - def syntaxError(msg: String, skipIt: boolean): Unit = - syntaxError(s.pos, msg, skipIt); - - def syntaxError(pos: Int, msg: String, skipIt: boolean): Unit = { - if (pos != s.errpos) { - s.unit.error(pos, msg); - s.errpos = pos; - } - if (skipIt) skip(); - } - - def accept(token: Int): Int = { - val pos = s.pos; - if (s.token != token) { - val errpos = if ((s.pos >>> Position.COLUMN_BITS) > - (s.lastpos >>> Position.COLUMN_BITS)) s.lastpos - else s.pos; - syntaxError(errpos, Tokens.token2string(token) + " expected but " + - Tokens.token2string(s.token) + " found.", true); - } - if (s.token == token) s.nextToken(); - pos - } - -/////// TOKEN CLASSES //////////////////////////////////////////////////////// - - def isModifier(): Boolean = - (s.token == ABSTRACT) - || (s.token == FINAL) - || (s.token == SEALED) - || (s.token == PRIVATE) - || (s.token == PROTECTED) - || (s.token == IMPLICIT) - || (s.token == OVERRIDE); - - def isLocalModifier(): Boolean = - (s.token == ABSTRACT) - || (s.token == FINAL) - || (s.token == SEALED); - - def isDefIntro(): Boolean = s.token match { - case VAL | VAR | DEF | TYPE | OBJECT | - CASEOBJECT | CLASS | CASECLASS | TRAIT => - true - case _ => - false - } - - def isDclIntro(): Boolean = s.token match { - case VAL | VAR | DEF | TYPE => - true - case _ => - false - } - - def isExprIntro(): Boolean = s.token match { - case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | - STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL | IDENTIFIER | - THIS | SUPER | IF | FOR | NEW | USCORE | TRY | WHILE | - DO | RETURN | THROW | LPAREN | LBRACE | XMLSTART => - true - case _ => - false - } - -/////// COMMENT AND ATTRIBUTE COLLECTION ///////////////////////////////////// - - /** Stack of comments - */ - protected val commentStack = new Stack(); - - /** Join the comment associated with a definition - * - * @param trees - * @return - */ - def joinComment(trees: => Array[Tree]): Array[Tree] = { - // push comment - commentStack.push(if (s.docBuffer == null) null else s.docBuffer.toString()); - s.docBuffer = null; - // parse - val ts = trees; - // pop comment - val comment = commentStack.pop().asInstanceOf[String]; - if (comment != null) - for (val i <- Iterator.range(0, ts.length)) { - val t = ts(i); - ts(i) = make.DocDef(t.pos, comment, t) - } - ts - } - -/////// TREE CONSTRUCTION //////////////////////////////////////////////////// - - def fresh(): Name = unit.fresh.newName("x"); - - /** Create a tree representing a packaging - * - * @param pos - * @param pkg0 - * @param stats0 - * @return - */ - def makePackaging(pos: Int, pkg0: Tree, stats0: Array[Tree]): Tree = { - var pkg = pkg0; - var stats = stats0; - while (true) { - val templ = make.Template(pos, Tree.EMPTY_ARRAY, stats); - pkg match { - case Tree$Select(qual, name) => - stats = NewArray.Tree( - make.PackageDef(pos, make.Ident(pkg.pos, name), templ)); - pkg = qual; - case _ => - return make.PackageDef(pos, pkg, templ); - } - } - null//dummy - } - - /** Create tree representing binary operation expression or pattern. - * - * @param isExpr - * @param pos - * @param left - * @param op - * @param right - * @return - */ - def makeBinop(isExpr: Boolean, pos: Int, left: Tree, op: Name, right: Tree): Tree = - if (isExpr) { - if (isLeftAssoc(op)) { - make.Apply( - pos, - make.Select(pos, left, NameTransformer.encode(op)), - NewArray.Tree(right)); - } else { - val x: Name = fresh(); - make.Block( - pos, - NewArray.Tree( - make.ValDef(pos, 0, x, Tree.Empty, left)), - make.Apply( - pos, - make.Select(pos, right, NameTransformer.encode(op)), - NewArray.Tree(make.Ident(left.pos, x)))); - } - } else { - make.Apply( - pos, - make.Ident(pos, NameTransformer.encode(op).toTypeName()), - NewArray.Tree(left, right)); - } - - - def scalaDot(pos: Int, name: Name): Tree = - make.Select(pos, make.Ident(pos, Names.scala), name); - - def scalaRuntimeDot(pos: Int, name: Name): Tree = - make.Select(pos, scalaDot(pos, Names.runtime), name); - - def ScalaRunTimeDot(pos: Int, name: Name): Tree = - make.Select(pos, scalaRuntimeDot(pos, Names.ScalaRunTime), name); - - def scalaBooleanDot(pos: Int, name: Name): Tree = - make.Select(pos, scalaDot(pos, Names.Boolean), name); - - def scalaAnyRefConstr(pos: Int): Tree = - make.Apply( - pos, scalaDot(pos, Names.AnyRef.toTypeName()), Tree.EMPTY_ARRAY); - - def scalaObjectConstr(pos: Int): Tree = - make.Apply( - pos, scalaDot(pos, Names.ScalaObject.toTypeName()), Tree.EMPTY_ARRAY); - - def caseClassConstr(pos: Int): Tree = - make.Apply( - pos, scalaDot(pos, Names.CaseClass.toTypeName()), Tree.EMPTY_ARRAY); - - /** Create tree for for-comprehension <for (enums) do body> or - * <for (enums) yield body> where mapName and flatmapName are chosen - * corresponding to whether this is a for-do or a for-yield. - * - * @param pos - * @param enums - * @param mapName - * @param flatmapName - * @param body - * @return - */ - def makeFor(pos: Int, enums: Array[Tree], mapName: Name, - flatmapName: Name, body: Tree): Tree = { - - def makeFor1(pos: Int, name: Name, pat: Tree, rhs: Tree, body: Tree): Tree = - make.Apply( - pos, make.Select(pos, rhs, name), - NewArray.Tree(makeForCont(pos, pat, body))); - - def makeForCont(pos: Int, pat: Tree, body: Tree): Tree = { - pat match { - case Tree$Ident(name1) if (name1.isVariable()) => - make.Function( - pos, - NewArray.ValDef( - make.ValDef( - pat.pos, Modifiers.PARAM, name1, Tree.Empty, Tree.Empty)), - body); - case _ => - make.Visitor(pos, NewArray.CaseDef( - make.CaseDef(pos, pat, Tree.Empty, body))); - } - } - - enums(0) match { - case Tree$PatDef(mods, pat, rhs) => - if (enums.length == 1) { - makeFor1(pos, mapName, pat, rhs, body); - } else { - val newenums = new Array[Tree](enums.length - 1); - enums(1) match { - case Tree$PatDef(mods2, pat2, rhs2) => - System.arraycopy(enums, 1, newenums, 0, newenums.length); - makeFor1( - pos, flatmapName, pat, rhs, - makeFor(enums(1).pos, newenums, mapName, flatmapName, body)); - case _ => - System.arraycopy(enums, 2, newenums, 1, newenums.length - 1); - newenums(0) = make.PatDef( - enums(0).pos, mods, pat, - makeFor1(enums(1).pos, Names.filter, pat.duplicate(), rhs, enums(1))); - makeFor(pos, newenums, mapName, flatmapName, body); - } - } - } - } - - /** .. - * - * @param pos - * @param body - * @param catcher - * @param finalizer - * @return - */ - def makeTry(pos: Int, body: Tree, catcher: Tree, finalizer: Tree): Tree = { - var t = body; - if (catcher != Tree.Empty) - t = make.Apply( - pos, - make.Select( - pos, - make.Apply( - pos, ScalaRunTimeDot(pos, Names.Try), NewArray.Tree(t)), - Names.Catch), - NewArray.Tree(catcher)); - if (finalizer != Tree.Empty) - t = make.Apply( - pos, - make.Select( - pos, - make.Apply( - pos, ScalaRunTimeDot(pos, Names.Try), NewArray.Tree(t)), - Names.Finally), - NewArray.Tree(finalizer)); - t - } - - /** Create tree for a while loop using a label/if construct, e.g. - * "label(<args>)": - * while (cond) if (cond) { - * body ===> body; "goto label(<args>)" - * } - * - * @param pos the source position - * @param lname the label name - * @param cond the tree representing the while condition - * @param body the tree representing the while body - * @return a label tree representing the while loop - */ - def makeWhile(pos: Int, lname: Name, cond: Tree, body: Tree): Tree = { - val continu = make.Apply( - pos, make.Ident(pos, lname), Tree.EMPTY_ARRAY); - val rhs = make.If( - pos, - cond, - make.Block(body.pos, NewArray.Tree(body), continu), - gen.mkUnitLit(pos)); - make.LabelDef(pos, lname, new Array[Tree$Ident](0), rhs); - } - - /** .. - * - * @param pos - * @param lname - * @param body - * @param cond - * @return a label tree representing the do-while loop - */ - def makeDoWhile(pos: Int, lname: Name, body: Tree, cond: Tree): Tree = { - val continu = make.Apply( - pos, make.Ident(pos, lname), Tree.EMPTY_ARRAY); - val rhs = make.Block( - body.pos, - NewArray.Tree( - body), - make.If( - cond.pos, - cond, - continu, - gen.mkUnitLit(pos))); - make.LabelDef(pos, lname, new Array[Tree$Ident](0), rhs) - } - - /** Convert tree to formal parameter list - * - * @param t - * @return a list of formal parameters - */ - def convertToParams(t: Tree): Array[Tree$ValDef] = t match { - case Tree$Function(params, Tree.Empty) => - params - case Tree$Ident(_) | Tree$Typed(Tree$Ident(_), _) => - NewArray.ValDef(convertToParam(t)); - case Tree$Literal(AConstant.UNIT) => // !!! - Tree.ValDef_EMPTY_ARRAY; - case _ => - syntaxError(t.pos, "malformed formal parameter list", false); - Tree.ValDef_EMPTY_ARRAY; - } - - /** Convert list of trees to formal parameter list - * - * @param trees - * @return - */ - def convertToParams(trees: Array[Tree]): Array[Tree$ValDef] = { - val res = new Array[Tree$ValDef](trees.length); - for (val i <- Iterator.range(0, res.length)) - res(i) = convertToParam(trees(i)); - res; - } - - /** Convert tree to formal parameter - * - * @param tree - * @return - */ - def convertToParam(tree: Tree): Tree$ValDef = tree match { - case Tree$Ident(name) => - make.ValDef( - tree.pos, Modifiers.PARAM, name, Tree.Empty, Tree.Empty) - case Tree$Typed(Tree$Ident(name), tpe) => - make.ValDef( - tree.pos, Modifiers.PARAM, name, tpe, Tree.Empty) - case _ => - syntaxError(tree.pos, "not a legal formal parameter", false); - val tpe = gen.mkType(tree.pos, Type.ErrorType); - make.ValDef( - tree.pos, Modifiers.PARAM, Names.ERROR, tpe, Tree.Empty) - } - - /** Convert (qual)ident to type identifier - * - * @param tree - * @return - */ - def convertToTypeId(tree: Tree): Tree = tree match { - case Tree$Ident(name) => - make.Ident(tree.pos, name.toTypeName()) - case Tree$Select(qual, name) => - make.Select(tree.pos, qual, name.toTypeName()) - case _ => - tree - } - - /** Convert (qual)ident to constructor identifier - * - * @param tree - * @return - */ - def convertToConstr(tree: Tree): Tree = tree match { - case Tree$Ident(name) => - make.Ident(tree.pos, name.toTypeName()) - case Tree$Select(qual, name) => - make.Select(tree.pos, qual, name.toTypeName()) - case _ => - Console.println("class instead " + tree.getClass()); - syntaxError(tree.pos, "class constructor expected", false); - gen.mkType(tree.pos, Type.ErrorType) - } - - /** Complete unapplied constructor with `()' arguments - * - * @param tree - * @return - */ - def applyConstr(tree: Tree): Tree = tree match { - case Tree$Apply(_, _) => - tree - case _ => - make.Apply(tree.pos, tree, Tree.EMPTY_ARRAY) - } - - /** Make closure from tree - * - * @param pos - * @param tree - * @return - */ - def makeClosure(pos: Int, tree: Tree): Tree = { - val pname = fresh(); - def insertParam(tree: Tree): Tree = tree match { - case Tree$Ident(name) => - make.Select(tree.pos, make.Ident(pos, pname), name) - case Tree$Select(qual, name) => - make.Select(tree.pos, insertParam(qual), name) - case Tree$Apply(fn, args) => - make.Apply(tree.pos, insertParam(fn), args) - case Tree$TypeApply(fn, args) => - make.TypeApply(tree.pos, insertParam(fn), args) - case _ => - syntaxError(pos, "cannot concert to closure", false); - gen.mkZeroLit(s.pos) - } - make.Function( - pos, - NewArray.ValDef( - make.ValDef(pos, Modifiers.PARAM, pname, Tree.Empty, Tree.Empty)), - insertParam(tree)) - } - -/////// OPERAND/OPERATOR STACK /////////////////////////////////////////////// - - var operands = new Array[Tree](8); - var positions = new Array[Int ](8); - var operators = new Array[Name](8); - var sp = 0; - - def precedence(operator: Name): Int = - if (operator eq Names.ERROR) -1 - else { - val first_ch = operator.charAt(0); - if (((first_ch >= 'A') && (first_ch <= 'Z')) || - ((first_ch >= 'a') && (first_ch <= 'z'))) - 1 - else - first_ch match { - case '|' => 2 - case '^' => 3 - case '&' => 4 - case '<' | '>' => 5 - case '=' | '!' => 6 - case ':' => 7 - case '+' | '-' => 8; - case '*' | '/' | '%' => 9; - case _ => 10; - } - } - - def isLeftAssoc(operator: Name): Boolean = - operator.length() > 0 && operator.charAt(operator.length() - 1) != ':'; - - /** .. - * - * @param od - * @param pos - * @param op - */ - def push(od: Tree, pos: Int, op: Name): Unit = { - if (sp == operands.length) { - val operands1 = new Array[Tree](sp * 2); - System.arraycopy(operands, 0, operands1, 0, sp); - operands = operands1; - val positions1 = new Array[Int](sp * 2); - System.arraycopy(positions, 0, positions1, 0, sp); - positions = positions1; - val operators1 = new Array[Name](sp * 2); - System.arraycopy(operators, 0, operators1, 0, sp); - operators = operators1; - } - operands(sp) = od; - positions(sp) = pos; - operators(sp) = op; - sp = sp + 1; - } - - /** .. - * - * @param isExpr - * @param base - * @param _top - * @param prec - * @param leftAssoc - * @return - */ - def reduceStack(isExpr: Boolean, base: Int, _top: Tree, - prec: Int, leftAssoc: Boolean): Tree = { - var top = _top; - if (sp != base && - precedence(operators(sp-1)) == prec && - isLeftAssoc(operators(sp-1)) != leftAssoc) { - syntaxError( - positions(sp-1), - "left- and right-associative operators with same precedence may not be mixed", - false); - } - while (sp != base && - (prec < precedence(operators(sp-1)) || - (leftAssoc && prec == precedence(operators(sp-1))))) { - sp = sp - 1; - top = makeBinop(isExpr, positions(sp), operands(sp), operators(sp), top); - } - top - } - -/////// IDENTIFIERS AND LITERALS ///////////////////////////////////////////// - - final val MINUS = Name.fromString("-"); - final val PLUS = Name.fromString("+"); - final val BANG = Name.fromString("!"); - final val TILDE = Name.fromString("~"); - final val STAR = Name.fromString("*"); - final val BAR = Name.fromString("|"); - final val OPT = Name.fromString("?"); - final val LT = Name.fromString("<"); - - def ident(): Name = - if (s.token == IDENTIFIER) { - val name = NameTransformer.encode(s.name); - s.nextToken(); - name - } else { - accept(IDENTIFIER); - Names.ERROR - } - - /** StableRef ::= StableId - * | [Ident `.'] this - * SimpleType ::= StableRef [`.' type] - * - * @param thisOK - * @param typeOK - * @return - */ - def stableRef(thisOK: Boolean, typeOK: Boolean): Tree = { - var t: Tree = null; - if (s.token == THIS) { - t = make.This(s.skipToken(), TypeNames.EMPTY); - if (!thisOK || s.token == DOT) - t = selectors(accept(DOT), t, typeOK); - } else if (s.token == SUPER) { - t = make.Super( - s.skipToken(), TypeNames.EMPTY, mixinQualifierOpt()); - t = make.Select(accept(DOT), t, ident()); - if (s.token == DOT) - t = selectors(s.skipToken(), t, typeOK); - } else { - val i: Tree$Ident = make.Ident(s.pos, ident()); - t = i; - if (s.token == DOT) { - val pos = s.skipToken(); - if (s.token == THIS) { - s.nextToken(); - t = make.This(i.pos, i.name.toTypeName()); - if (!thisOK || s.token == DOT) - t = selectors(accept(DOT), t, typeOK); - } else if (s.token == SUPER) { - s.nextToken(); - t = make.Super( - i.pos, i.name.toTypeName(), mixinQualifierOpt()); - t = make.Select(accept(DOT), t, ident()); - if (s.token == DOT) - t = selectors(s.skipToken(), t, typeOK); - } else { - t = selectors(pos, t, typeOK); - } - } - } - t - } - - def selectors(pos: Int, t: Tree, typeOK: Boolean): Tree = - if (typeOK && s.token == TYPE) { - s.nextToken(); - make.SingletonType(pos, t); - } else { - val t1 = make.Select(pos, t, ident()); - if (s.token == DOT) selectors(s.skipToken(), t1, typeOK); - else t1 - } - - /** MixinQualifier ::= `[' Id `]' - */ - def mixinQualifierOpt(): Name = - if (s.token == LBRACKET) { - s.nextToken(); - val name = ident().toTypeName(); - accept(RBRACKET); - name - } else { - TypeNames.EMPTY - } - - /** StableId ::= Id - * | StableRef `.' Id - * | [Id '.'] super [MixinQualifier] ` `.' Id - */ - def stableId(): Tree = - stableRef(false, false); - - /** QualId ::= Id {`.' Id} - */ - def qualId(): Tree = { - val id = make.Ident(s.pos, ident()); - if (s.token == DOT) selectors(s.skipToken(), id, false) - else id - } - - /** SimpleExpr ::= literal - * | symbol [ArgumentExprs] - * | null - * - * @param isPattern - * @param isNegated - * @return - */ - def literal(isPattern: Boolean, isNegated: Boolean): Tree = { - def litToTree() = s.token match { - case CHARLIT => - gen.mkCharLit(s.pos, s.intVal.asInstanceOf[Char]) - case INTLIT => - gen.mkIntLit(s.pos, s.intVal(isNegated).asInstanceOf[Int]) - case LONGLIT => - gen.mkLongLit(s.pos, s.intVal(isNegated)) - case FLOATLIT => - gen.mkFloatLit(s.pos, s.floatVal(isNegated).asInstanceOf[float]) - case DOUBLELIT => - gen.mkDoubleLit(s.pos, s.floatVal(isNegated)) - case STRINGLIT | SYMBOLLIT => - gen.mkStringLit(s.pos, s.name.toString()) - case TRUE => - gen.mkBooleanLit(s.pos, true) - case FALSE => - gen.mkBooleanLit(s.pos, false) - case NULL => - gen.mkNullLit(s.pos) - case _ => - syntaxError("illegal literal", true); - gen.mkZeroLit(s.pos) - } - - val isSymLit = s.token == SYMBOLLIT; - val t = litToTree(); - s.nextToken(); - if (isSymLit) { - val pos = s.pos; - /* - if (s.token == LPAREN || s.token == LBRACE) - xmlp.mkXML( pos, isPattern, t, argumentExprs() ); // xml shorthand - else { // Symbol("name") */ - var symT = scalaDot(pos, Names.Symbol); - if (isPattern) { symT = convertToTypeId(symT) }; - make.Apply(pos, symT, Predef.Array[Tree](t)) - /*} */ - } else { - t - } - } - -//////// TYPES /////////////////////////////////////////////////////////////// - - /** TypedOpt ::= [`:' Type] - */ - def typedOpt(): Tree = - if (s.token == COLON) { - s.nextToken(); - typ() - } else { - Tree.Empty - } - - /** SimpleTypedOpt ::= [`:' SimpleType] - */ - def simpleTypedOpt(): Tree = - if (s.token == COLON) { - s.nextToken(); - simpleType() - } else { - Tree.Empty - } - - /** Types ::= Type {`,' Type} - */ - def types(): Array[Tree] = { - val ts = new myTreeList(); - ts.append(typ()); - while (s.token == COMMA) { - s.nextToken(); - ts.append(typ()); - } - ts.toArray() - } - - /** Type ::= Type1 '=>' Type - * | '(' [Types] ')' '=>' Type - * | Type1 - */ - def typ(): Tree = { - var t: Tree = _; - if (s.token == LPAREN) { - s.nextToken(); - if (s.token == RPAREN) { - s.nextToken(); - val pos = accept(ARROW); - return make.FunType(pos, Tree.EMPTY_ARRAY, typ()); - } else { - t = typ(); - if (s.token == COMMA) { - s.nextToken(); - val ts = new myTreeList(); - ts.append(t); - ts.append(types()); - accept(RPAREN); - val pos = accept(ARROW); - return make.FunType(pos, ts.toArray(), typ()); - } else { - accept(RPAREN); - } - } - } else { - t = type1() - } - if (s.token == ARROW) - make.FunType(s.skipToken(), NewArray.Tree(t), typ()) - else - t - } - - /** Type1 ::= SimpleType {'with' SimpleType} [Refinement] - */ - def type1(): Tree = { - val pos = s.pos; - val t = simpleType(); - if (s.token == WITH || s.token == LBRACE) { - val ts = new myTreeList(); - ts.append(t); - while (s.token == WITH) { - s.nextToken(); - ts.append(simpleType()); - } - val rs = if (s.token == LBRACE) refinement() else Tree.EMPTY_ARRAY; - make.CompoundType(pos, ts.toArray(), rs) - } else { - t - } - } - - /** SimpleType ::= SimpleType TypeArgs - * | SimpleType `#' Id - * | StableId - * | StableRef `.' type - * | `(' Type `)' - */ - def simpleType(): Tree = { - val pos = s.pos; - var t: Tree = - if (s.token == LPAREN) { - s.nextToken(); - val t = typ(); - accept(RPAREN); - t - } else { - convertToTypeId(stableRef(false, true)); - } - while (true) { - if (s.token == HASH) - t = make.SelectFromType(s.skipToken(), t, ident().toTypeName()); - else if (s.token == LBRACKET) - t = make.AppliedType(pos, t, typeArgs()); - else - return t; - } - null; //dummy - } - - /** TypeArgs ::= `[' Types `]' - */ - def typeArgs(): Array[Tree] = { - accept(LBRACKET); - val ts = types(); - accept(RBRACKET); - ts - } - -//////// EXPRESSIONS //////////////////////////////////////////////////////// - - /** EqualsExpr ::= `=' Expr - */ - def equalsExpr(): Tree = { - accept(EQUALS); - expr() - } - - /** Exprs ::= Expr {`,' Expr} - * | Expr `:' `_' `*' - def exprs(): Array[Tree] = { val ts = new myTreeList(); - ts.append(expr(true, false)); - while (s.token == COMMA) { - s.nextToken(); - ts.append(expr()); - } - ts.toArray() - } - */ - - /** Exprs ::= Expr {`,' Expr} [ `:' `_' `*' ] - */ - def exprs(): Array[Tree] = { - val ts = new myTreeList(); - ts.append(expr(true, false)); - while (s.token == COMMA) { - s.nextToken(); - ts.append(expr(true, false)); - } - ts.toArray() - } - - /** Expr ::= Bindings `=>' Expr - * | Expr1 - * ResultExpr ::= Bindings `=>' Block - * | Expr1 - * Expr1 ::= (' Expr `)' Expr [[`;'] else Expr] - * | try `{' block `}' [catch Expr] [finally Expr] - * | while `(' Expr `)' Expr - * | do Expr [`;'] while `(' Expr `)' - * | for `(' Enumerators `)' (do | yield) Expr - * | throw Expr - * | return [Expr] - * | [SimpleExpr `.'] Id `=' Expr - * | SimpleExpr ArgumentExprs `=' Expr - * | `.' SimpleExpr - * | PostfixExpr [`:' Type1] - * Bindings ::= Id [`:' Type1] - * | `(' [Binding {`,' Binding}] `)' - * Binding ::= Id [`:' Type] - */ - - def expr(): Tree = - expr(false, false); - - def expr(isArgument: boolean, isInBlock: boolean): Tree = { - if (s.token == IF) { - val pos = s.skipToken(); - accept(LPAREN); - val cond = expr(); - accept(RPAREN); - val thenp = expr(); - val elsep = - if (s.token == ELSE) { s.nextToken(); expr() } - else Tree.Empty; - make.If(pos, cond, thenp, elsep) - } else if (s.token == TRY) { - val pos = s.skipToken(); - accept(LBRACE); - val body = block(pos); - accept(RBRACE); - val catcher = - if (s.token == CATCH) { s.nextToken(); expr() } - else Tree.Empty; - val finalizer = - if (s.token == FINALLY) { s.nextToken(); expr() } - else Tree.Empty; - makeTry(pos, body, catcher, finalizer) - } else if (s.token == WHILE) { - val lname = Name.fromString("label$" + loopNestingDepth); - loopNestingDepth = loopNestingDepth + 1; - val pos = s.skipToken(); - accept(LPAREN); - val cond = expr(); - accept(RPAREN); - val body = expr(); - loopNestingDepth = loopNestingDepth - 1; - makeWhile(pos, lname, cond, body) - } else if (s.token == DO) { - val lname = Name.fromString("label$" + loopNestingDepth); - loopNestingDepth = loopNestingDepth + 1; - val pos = s.skipToken(); - val body = expr(); - if (s.token == SEMI) s.nextToken(); - accept(WHILE); - accept(LPAREN); - val cond = expr(); - accept(RPAREN); - loopNestingDepth = loopNestingDepth - 1; - makeDoWhile(pos, lname, body, cond) - } else if (s.token == FOR) { - s.nextToken(); - accept(LPAREN); - val enums = enumerators(); - accept(RPAREN); - if (s.token == YIELD) - makeFor(s.skipToken(), enums, Names.map, Names.flatmap, expr()) - else - makeFor(s.pos, enums, Names.foreach, Names.foreach, expr()) - } else if (s.token == RETURN) { - val pos = s.skipToken(); - val e = - if (isExprIntro()) expr() - else gen.mkUnitLit(pos); - make.Return(pos, e) - } else if (s.token == THROW) { - val pos = s.skipToken(); - make.Throw(pos, expr()) - } else if (s.token == DOT) { - val pos = s.skipToken(); - if (s.token == IDENTIFIER) - makeClosure(pos, simpleExpr()) - else { - syntaxError("identifier expected", true); - gen.mkZeroLit(pos); - } - } else { - var t = postfixExpr(); - if (s.token == EQUALS) { - t match { - case Tree.Ident(_) | Tree.Select(_, _) | Tree.Apply(_, _) => - t = make.Assign(s.skipToken(), t, expr()); - case _ => - } - } else if (s.token == COLON) { - val pos = s.skipToken(); - if (isArgument && s.token == USCORE) { - val pos1 = s.skipToken(); - if (s.token == IDENTIFIER && s.name == Names.STAR) { - s.nextToken(); - /* - if (s.token != RPAREN) - syntaxError(s.pos, " escaping sequences only allowed for last argument", true); - */ - t = make.Typed( - pos, t, make.Ident(pos1, TypeNames.WILDCARD_STAR)); - } else { - syntaxError(s.pos, "`*' expected", true); - } - } else { - val tp = type1(); - t = make.Typed(pos, t, tp); - } - } - if (s.token == ARROW) { - val arrowpos = s.skipToken(); - t = make.Function(arrowpos, convertToParams(t), - if (isInBlock) block(arrowpos) else expr()); - } - t - } - } - - /** PostfixExpr ::= [`.'] InfixExpr [Id] - * InfixExpr ::= PrefixExpr - * | InfixExpr Id InfixExpr - */ - def postfixExpr(): Tree = { - val base = sp; - var top = prefixExpr(); - while (s.token == IDENTIFIER) { - top = reduceStack( - true, base, top, precedence(s.name), isLeftAssoc(s.name)); - push(top, s.pos, s.name); - ident(); - if (isExprIntro()) { - top = prefixExpr(); - } else { - sp = sp - 1; - val pos = positions(sp); - val postOp = operators(sp); - top = reduceStack(true, base, operands(sp), 0, true); - return make.Select(pos, top, NameTransformer.encode(postOp)); - } - } - reduceStack(true, base, top, 0, true) - } - - /** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr - */ - def prefixExpr(): Tree = - if (s.token == IDENTIFIER && s.name == MINUS) { - val name = ident(); - s.token match { - case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT => - return literal(false, true); - case _ => - make.Select(s.pos, simpleExpr(), name); - } - } else if (s.token == IDENTIFIER && - (s.name == PLUS || - s.name == TILDE || - s.name == BANG)) { - val name = ident(); - make.Select(s.pos, simpleExpr(), name); - } else { - simpleExpr() - } - - /** SimpleExpr ::= literal - * | xLiteral - * | StableRef - * | `(' [Expr] `)' - * | BlockExpr - * | new Template - * | SimpleExpr `.' Id - * | SimpleExpr TypeArgs - * | SimpleExpr ArgumentExprs - */ - def simpleExpr(): Tree = { - var t: Tree = null; - //Console.println("simpleExpr, s.lastch="+s.lastch+" token = "+token2string(s.token)); - s.token match { - case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | - SYMBOLLIT | TRUE | FALSE | NULL => - t = literal(false, false); - case XMLSTART => - t = xmlp.xLiteral; - case IDENTIFIER | THIS | SUPER => - t = stableRef(true, false); - case LPAREN => - val pos = s.skipToken(); - if (s.token == RPAREN) { - s.nextToken(); - t = gen.mkUnitLit(pos); - } else { - t = expr(); - if (s.token == COMMA) { - val commapos = s.skipToken(); - val ts = new myTreeList(); - ts.append(t); - ts.append(exprs()); - accept(RPAREN); - if (s.token == ARROW) { - t = make.Function( - pos, convertToParams(ts.toArray()), Tree.Empty); - } else { - syntaxError(commapos, "`)' expected", false); - t = gen.mkZeroLit(pos) - } - } else { - accept(RPAREN); - } - } - case LBRACE => - t = blockExpr(); - case NEW => - val pos = s.skipToken(); - val templ = template(); - if (templ.parents.length == 1 && templ.body.length == 0) { - t = make.New(pos, templ.parents(0)); - } else { - // flags == SYNTHETIC and name = ANON indicate an anonymous class - val flags = Modifiers.SYNTHETIC; - val name = Names.ANON_CLASS_NAME.toTypeName(); - val cd: Tree = make.ClassDef( - templ.pos, - flags, - name, - Tree.AbsTypeDef_EMPTY_ARRAY, - NewArray.ValDefArray(Tree.ValDef_EMPTY_ARRAY), - Tree.Empty, - templ); - t = make.Block( - pos, Predef.Array[Tree](cd), make.New( - pos, make.Apply(pos, make.Ident(pos, name), Tree.EMPTY_ARRAY))); - } - case _ => - syntaxError("illegal start of expression", true); - return gen.mkZeroLit(s.pos); - } - while (true) { - s.token match { - case DOT => - t = make.Select(s.skipToken(), t, ident()); - case LBRACKET => - t match { - case Tree.Ident(_) | Tree.Select(_, _) => - t = make.TypeApply(s.pos, t, typeArgs()); - case _ => - return t; - } - case LPAREN | LBRACE => - t = make.Apply(s.pos, t, argumentExprs()); - case _ => - return t; - } - } - null;//dummy - } - - /** ArgumentExprs ::= `(' [Exprs] `)' - * | BlockExpr - */ - def argumentExprs(): Array[Tree] = { - var ts = Tree.EMPTY_ARRAY; - if (s.token == LBRACE) { - ts = NewArray.Tree(blockExpr()); - } else { - accept(LPAREN); - if (s.token != RPAREN) - ts = exprs(); - accept(RPAREN); - } - ts - } - - /** BlockExpr ::= `{' CaseClause {CaseClause} `}' - * | `{' Block `}' - */ - def blockExpr(): Tree = { - val pos = accept(LBRACE); - val res = - if (s.token == CASE) { - val stats = new myTreeList(); - do { - stats.append(caseClause()); - } while (s.token == CASE); - make.Visitor(pos, - stats.copyTo(new Array[Tree.CaseDef](stats.length()))) - } else { - block(pos); - } - accept(RBRACE); - res - } - - /** Block ::= BlockStatSeq - */ - def block(pos: Int): Tree = { - block(pos, blockStatSeq(new myTreeList())); - } - private def block(pos: Int, stats: Array[Tree]): Tree = { - if (stats.length == 0) - gen.mkUnitLit(pos); - else if (!stats(stats.length - 1).isTerm()) - make.Block(pos, stats, gen.mkUnitLit(pos)); - else if (stats.length == 1) - return stats(0); - else { - val trees: Array[Tree] = new Array[Tree](stats.length - 1); - System.arraycopy(stats, 0, trees, 0, trees.length); - return make.Block(pos, trees, stats(stats.length - 1)); - } - } - - /** caseClause : =>= case Pattern [if PostfixExpr] `=>' Block - */ - def caseClause(): Tree = { - val pos = accept(CASE); - val pat = validPattern(); - val guard = - if (s.token == IF) { s.nextToken(); postfixExpr() } - else Tree.Empty; - make.CaseDef(pos, pat, guard, block(accept(ARROW))) - } - - /** Enumerators ::= Generator {`;' Enumerator} - * Enumerator ::= Generator - * | Expr - */ - def enumerators(): Array[Tree] = { - val enums = new myTreeList(); - enums.append(generator()); - while (s.token == SEMI) { - s.nextToken(); - if (s.token == VAL) enums.append(generator()); - else enums.append(expr()); - } - enums.toArray() - } - - /** Generator ::= val Pattern1 `<-' Expr - */ - def generator(): Tree = { - val pos = accept(VAL); - val pat = validPattern1(); - accept(LARROW); - var rhs = expr(); - if (!TreeInfo.isVarPattern(pat)) - rhs = make.Apply( - rhs.pos, - make.Select(rhs.pos, rhs, Names.filter), - NewArray.Tree( - make.Visitor( - rhs.pos, - NewArray.CaseDef( - make.CaseDef( - rhs.pos, pat.duplicate(), - Tree.Empty, gen.mkBooleanLit(s.pos, true)), - make.CaseDef( - rhs.pos, make.Ident(rhs.pos, Names.PATTERN_WILDCARD), - Tree.Empty, gen.mkBooleanLit(s.pos, false)))))); - make.PatDef(pos, 0, pat, rhs) - } - -//////// PATTERNS //////////////////////////////////////////////////////////// - - /** Pattern ( see pattern() ) which is checked for validity - */ - def validPattern(): Tree = { - val pos = s.pos; - val pat = pattern(); - if (this.pN.check(pat)) { // reports syntax errors as side effect - // normalize - pN.wrapAlternative(pN.elimSequence(pN.flattenSequence(pat))) - } else { - make.Ident(pos, Names.PATTERN_WILDCARD) - } - } - - /** Pattern1 ( see pattern1() ) which is checked for validity - */ - def validPattern1(): Tree = { - val pos = s.pos; - val pat = pattern1(); - if (this.pN.check(pat)) { // reports syntax errors as side effect - pN.wrapAlternative(pN.elimSequence(pN.flattenSequence(pat))) - } else { - make.Ident(pos, Names.PATTERN_WILDCARD) - } - } - - /** Patterns ::= Pattern {`,' Pattern} - */ - def patterns(): Array[Tree] = { - val ts = new myTreeList(); - ts.append(pattern()); - while (s.token == COMMA) { - s.nextToken(); - ts.append(pattern()); - } - ts.toArray() - } - - /** Pattern ::= Pattern1 { `|' Pattern1 } - */ - def pattern(): Tree = { - val pos = s.pos; - val first = pattern1(); - if (s.token == IDENTIFIER && s.name == BAR) { - val choices = new myTreeList(); - choices.append(first); - while (s.token == IDENTIFIER && s.name == BAR) { - s.nextToken(); - choices.append(pattern1()); - } - val tarr = choices.toArray(); - val ts = pN.flattenAlternativeChildren(tarr); - return pN.flattenAlternative(make.Alternative(pos, ts.toArray())); - } - first - } - - /** Pattern1 ::= varid `:' Type1 - * | `_' `:' Type1 - * | Pattern2 - */ - def pattern1(): Tree = { - val p = pattern2(); - if (s.token == COLON && TreeInfo.isVarPattern(p)) - make.Typed(s.skipToken(), p, type1()) - else p - } - - /** Pattern2 ::= varid [ @ Pattern3 ] - * | Pattern3 - */ - def pattern2(): Tree = { - val p = pattern3(); - if (s.token == AT && TreeInfo.isVarPattern(p)) { - p match { - case Tree.Ident(name) => - if (name == Names.PATTERN_WILDCARD) return pattern3() - case _ => - } - make.Bind(s.skipToken(), p.asInstanceOf[Tree.Ident].name, pattern3()); - } else { - p - } - } - - /* Pattern3 ::= SimplePattern [ '*' | '?' | '+' ] - * | SimplePattern {Id SimplePattern} // op2 must not be empty - */ - def pattern3(): Tree = { - val base = sp; - var top = simplePattern(); - if (s.token == IDENTIFIER) { - if (s.name == STAR) { /* p* becomes z@( |(p,z)) */ - s.nextToken(); - val zname = fresh(); - val zvar = make.Ident(s.pos, zname); - return make.Bind( - s.pos, zname, - pN.flattenAlternative( - make.Alternative(s.pos, NewArray.Tree( - make.Sequence(s.pos, Tree.EMPTY_ARRAY), - pN.flattenSequence(make.Sequence(s.pos, NewArray.Tree( - top, zvar))))))); - } else if (s.name == PLUS) { /* p+ becomes z@(p,(z| )) */ - s.nextToken(); - val zname = fresh(); - val zvar = make.Ident(s.pos, zname); - return make.Bind( - s.pos, zname, - pN.flattenSequence(make.Sequence(s.pos, NewArray.Tree( - top, - pN.flattenAlternative(make.Alternative(s.pos, NewArray.Tree( - zvar, make.Sequence(s.pos, Tree.EMPTY_ARRAY)))))))); - } else if (s.name == OPT) { /* p? becomes (p| ) */ - s.nextToken(); - return pN.flattenAlternative(make.Alternative(s.pos, NewArray.Tree( - top, - make.Sequence(s.pos, Tree.EMPTY_ARRAY)))); - } - } - while ((s.token == IDENTIFIER) && (s.name != BAR)) { - val tokn = s.name; // for error message - top = reduceStack( - false, base, top, precedence(s.name), isLeftAssoc(s.name)); - push(top, s.pos, s.name); - ident(); - top = simplePattern(); - if (TreeInfo.isEmptySequence(top)) { - syntaxError(top.pos, "2nd argument to binary op "+ s.name + " may not be empty sequence pattern", false); - } - } - reduceStack(false, base, top, 0, true) - } - - /** simplePattern ::= varid - * | `_' - * | literal - * | `<' xLiteralPattern - * | StableId [ `(' [Patterns] `)' ] - * | `(' [Patterns] `)' - * | (word: empty - nothing) - */ - def simplePattern(): Tree = s.token match { - case RPAREN | COMMA => - make.Sequence(s.pos, Tree.EMPTY_ARRAY) // ((nothing)) - case XMLSTART => - xmlp.xLiteralPattern - case IDENTIFIER | THIS => - if (s.name == BAR) { - make.Sequence(s.pos, Tree.EMPTY_ARRAY); // ((nothing)) - } else { - var t = stableId(); - s.token match { - case INTLIT | LONGLIT | FLOATLIT | DOUBLELIT => - t match { - case Tree.Ident(name) if name == Names.MINUS => - return literal(true, true); - case _ => - } - case _ => - } - while (s.token == LPAREN) { - var ts = Tree.EMPTY_ARRAY; - accept(LPAREN); - if (s.token != RPAREN) - ts = patterns(); - accept(RPAREN); - t = make.Apply(s.pos, convertToTypeId(t), ts); - } - t - } - case USCORE => - make.Ident(s.skipToken(), Names.PATTERN_WILDCARD) - case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | - STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL => - literal(true, false) - case LPAREN => - val p = s.pos; - s.nextToken(); - val ts = if (s.token == RPAREN) Tree.EMPTY_ARRAY else patterns(); - var t: Tree = null; - if (ts.length == 1 && !ts(0).isInstanceOf[Tree.Alternative]) { - t = ts(0); - } else { - t = pN.flattenSequence(make.Sequence(s.pos, ts)); - t = pN.elimSequence(t); - } - accept(RPAREN); - t - case _ => - syntaxError("illegal start of pattern", true); - make.Ident(s.pos, Names.PATTERN_WILDCARD) - } - -////////// MODIFIERS //////////////////////////////////////////////////////////// - - /** Modifiers ::= {Modifier} - * Modifier ::= final - * | private - * | protected - * | override - * | abstract - */ - def modifiers(): Int = { -// pushComment(); - var mods = 0; - while (true) { - var mod = 0; - s.token match { - case ABSTRACT => - mod = Modifiers.ABSTRACT; - case FINAL => - mod = Modifiers.FINAL; - case SEALED => - mod = Modifiers.SEALED; - case PRIVATE => - mod = Modifiers.PRIVATE; - case IMPLICIT => - mod = 0; - case PROTECTED => - mod = Modifiers.PROTECTED; - case OVERRIDE => - mod = Modifiers.OVERRIDE; - case _ => - return mods; - } - if ((mods & mod) != 0) - syntaxError(s.pos, "repeated modifier", false); - mods = mods | mod; - s.nextToken(); - } - 0 //dummy - } - - /** LocalModifiers ::= {LocalModifier} - * LocalModifier ::= final - * | private - */ - def localClassModifiers(): Int = { - var mods = 0; - while (true) { - var mod = 0; - s.token match { - case ABSTRACT => - mod = Modifiers.ABSTRACT; - case FINAL => - mod = Modifiers.FINAL; - case SEALED => - mod = Modifiers.SEALED; - case _ => - return mods; - } - if ((mods & mod) != 0) - syntaxError(s.pos, "repeated modifier", false); - mods = mods | mod; - s.nextToken(); - } - 0 //dummy - } - -//////// PARAMETERS ////////////////////////////////////////////////////////// - - // invariant: only only activation record of paramClauses on stack - var paramClauses_buffer = new mutable.ArrayBuffer[Array[Tree.ValDef]](); - - /** ParamClauses ::= {ParamClause} - */ - def paramClauses(): Array[Array[Tree.ValDef]] = { //pre: buffer empty - while (s.token == LPAREN) - paramClauses_buffer += paramClause(false); - - val res = new Array[Array[Tree.ValDef]](paramClauses_buffer.length); - paramClauses_buffer.elements.copyToArray(res, 0); - paramClauses_buffer.clear; //post: buffer empty - res - } - - /** ParamClauseOpt ::= [ParamClause] - */ - def paramClauseOpt(ofPrimaryConstructor: boolean): Array[Array[Tree.ValDef]] = - if (s.token == LPAREN) NewArray.ValDefArray(paramClause(ofPrimaryConstructor)) - else Tree.ValDef_EMPTY_ARRAY_ARRAY; - - /** ParamClause ::= `(' [Param {`,' Param}] `)' - * ClassParamClause ::= `(' [ClassParam {`,' ClassParam}] `)' - */ - def paramClause(ofPrimaryConstructor: boolean): Array[Tree.ValDef] = { - val pos = accept(LPAREN); - val params = new myTreeList(); - if (s.token != RPAREN) { - params.append(param(ofPrimaryConstructor)); - while (s.token == COMMA) { - s.nextToken(); - params.append(param(ofPrimaryConstructor)); - } - } - accept(RPAREN); - params.copyTo(new Array[Tree.ValDef](params.length())) - } - - /** Param ::= Id `:' ParamType - * ParamType ::= Type | Type `*' | `=>' Type - * ClassParam ::= [[modifiers] val] Param - */ - def param(ofPrimaryConstructor: boolean): Tree.ValDef = { - val pos = s.pos; - var mods = if (ofPrimaryConstructor) modifiers() | Modifiers.PARAM else Modifiers.PARAM; - if (ofPrimaryConstructor) { - if (s.token == VAL) { - s.nextToken(); mods = mods | Modifiers.PARAMACCESSOR; - } else if (mods != Modifiers.PARAM) { - accept(VAL); - } - } - if (s.token == DEF) { - mods = mods | Modifiers.DEF; - //if (ofPrimaryConstructor) - s.unit.warning(s.pos, "def-parameter syntax `def x: T' is deprecated \n" + - "use `x: => T' instead"); - s.nextToken(); - } - val name = ident(); - accept(COLON); - var tp: Tree = null; - if (s.token == ARROW) { - mods = mods | Modifiers.DEF; - s.nextToken(); - tp = typ(); - } else { - tp = typ(); - if (s.token == IDENTIFIER && s.name == STAR) { - s.nextToken(); - mods = mods | Modifiers.REPEATED; - tp = make.AppliedType( - tp.pos, - scalaDot(tp.pos, Names.Seq.toTypeName()), - NewArray.Tree(tp)); - } - } - make.ValDef(pos, mods, name, tp, Tree.Empty) - } - - /** TypeParamClauseOpt ::= [`[' TypeParam {`,' TypeParam} `]'] - * FunTypeParamClauseOpt ::= [`[' FunTypeParam {`,' FunTypeParam} `]'] - */ - def typeParamClauseOpt(variant: boolean): Array[Tree.AbsTypeDef] = { - val params = new myTreeList(); - if (s.token == LBRACKET) { - s.nextToken(); - params.append(typeParam(variant)); - while (s.token == COMMA) { - s.nextToken(); - params.append(typeParam(variant)); - } - accept(RBRACKET); - } - params.copyTo(new Array[Tree.AbsTypeDef](params.length())) - } - - /** TypeParam ::= [`+' | `-'] FunTypeParam - * FunTypeParam ::= Id TypeBounds - */ - def typeParam(variant: boolean): Tree = { - var mods = Modifiers.PARAM; - if (variant && s.token == IDENTIFIER) { - if (s.name == PLUS) { - s.nextToken(); - mods = mods | Modifiers.COVARIANT; - } else if (s.name == MINUS) { - s.nextToken(); - mods = mods | Modifiers.CONTRAVARIANT; - } - } - typeBounds(s.pos, mods, ident()) - } - - /** TypeBounds ::= [`>:' Type] [`<:' Type | `<%' Type] - */ - def typeBounds(pos: Int, _mods: Int, name: Name): Tree = { - var mods = _mods; - val lobound = - if (s.token == SUPERTYPE) { s.nextToken(); typ() } - else scalaDot(pos, Names.All.toTypeName()); - val hibound = - if (s.token == SUBTYPE) { - s.nextToken(); - typ() - } else if ((mods & Modifiers.PARAM) != 0 && s.token == VIEWBOUND) { - mods = mods | Modifiers.VIEWBOUND; - s.nextToken(); - typ() - } else - scalaDot(pos, Names.Any.toTypeName()); - make.AbsTypeDef(pos, mods, name.toTypeName(), hibound, lobound) - } - -//////// DEFS //////////////////////////////////////////////////////////////// - - /** Import ::= import ImportExpr {`,' ImportExpr} - */ - def importClause(): Array[Tree] = { - accept(IMPORT); - val ts = new myTreeList(); - ts.append(importExpr()); - while (s.token == COMMA) { - s.nextToken(); - ts.append(importExpr()); - } - ts.toArray() - } - - /** ImportRef ::= StableId `.' (Id | `_' | ImportSelectors) - */ - def importExpr(): Tree = { - var t: Tree = null; - val startpos = s.pos; - var pos = 0; - if (s.token == THIS) { - t = make.This(s.skipToken(), TypeNames.EMPTY); - t = make.Select(accept(DOT), t, ident()); - pos = accept(DOT); - } else { - val i: Tree.Ident = make.Ident(s.pos, ident()); - pos = accept(DOT); - if (s.token == THIS) { - s.nextToken(); - t = make.This(i.pos, i.name.toTypeName()); - t = make.Select(accept(DOT), t, ident()); - pos = accept(DOT); - } else { - t = i; - } - } - while (true) { - if (s.token == USCORE) { - s.nextToken(); - return make.Import(startpos, t, NewArray.Name(Names.IMPORT_WILDCARD)); - } else if (s.token == LBRACE) { - return make.Import(startpos, t, importSelectors()); - } else { - val name = ident(); - if (s.token == DOT) { - t = make.Select(pos, t, name); - pos = accept(DOT); - } else { - return make.Import(startpos, t, NewArray.Name(name, name)); - } - } - } - null //dummy - } - - /** ImportSelectors ::= `{' {ImportSelector `,'} (ImportSelector | `_') `}' - */ - def importSelectors(): Array[Name] = { - val names = new ListBuffer[Name](); - accept(LBRACE); - var isLast = importSelector(names); - while (!isLast && s.token == COMMA) { - s.nextToken(); - isLast = importSelector(names); - } - accept(RBRACE); - names.copyToArray(new Array[Name](names.length), 0) - } - - /** ImportSelector ::= Id [`=>' Id | `=>' `_'] - */ - def importSelector(names: ListBuffer[Name]): boolean = - if (s.token == USCORE) { - s.nextToken(); - names += Names.IMPORT_WILDCARD; - true - } else { - val name = ident(); - names += name; - if (s.token == ARROW) { - s.nextToken(); - if (s.token == USCORE) { - s.nextToken(); - names += Names.IMPORT_WILDCARD; - } else { - names += ident(); - } - } else { - names += name; - } - false - } - - /** Def ::= val PatDef - * | var VarDef - * | def FunDef - * | type TypeDef - * | ClsDef - * Dcl ::= val ValDcl - * | var ValDcl - * | def FunDcl - * | type TypeDcl - */ - def defOrDcl(mods: Int): Array[Tree] = { - s.token match { - case VAL => - patDefOrDcl(mods); - case VAR => - varDefOrDcl(mods); - case DEF => - funDefOrDcl(mods); - case TYPE => - s.nextToken(); - val ts = new myTreeList(); - ts.append(typeDefOrDcl(mods)); - ts.toArray() - case _ => - clsDef(mods) - } - } - - /** ClsDef ::= ([case] class | trait) ClassDef {`,' ClassDef} - * | [case] object ObjectDef {`,' ObjectDef} - */ - def clsDef(mods: Int): Array[Tree] = { - s.token match { - case TRAIT => - classDef(mods | Modifiers.TRAIT | Modifiers.ABSTRACT); - case CLASS => - classDef(mods); - case CASECLASS => - classDef(mods | Modifiers.CASE); - case OBJECT => - objectDef(mods); - case CASEOBJECT => - objectDef(mods | Modifiers.CASE); - case _ => - syntaxError("illegal start of definition", true); - Tree.EMPTY_ARRAY - } - } - - /** PatDef ::= Pattern2 [`:' Type] `=' Expr - * ValDcl ::= Id `:' Type - */ - def patDefOrDcl(mods: Int): Array[Tree] = { - var lhs = new myTreeList(); - do { - s.nextToken(); - val pat = pattern2(); - pN.check(pat); // bq: to catch `val y + = 3' bug #371 - lhs.append(pat); - } while (s.token == COMMA); - val tp = typedOpt(); - val rhs = if (tp == Tree.Empty || s.token == EQUALS) equalsExpr() else Tree.Empty; - val ls = lhs.toArray(); - val ts = new myTreeList(); - var i = 0; - if (rhs == Tree.Empty) { - while (i < ls.length) { - ls(i) match { - case Tree.Ident(name) => - ts.append( - make.ValDef(ls(i).pos, mods | Modifiers.DEFERRED, name, tp.duplicate(), Tree.Empty)); - case t => - syntaxError(t.pos, "cannot defer pattern definition", false); - } - i = i + 1; - } - } else { - while (i < ls.length) { - ls(i) match { - case Tree.Ident(name) => - ts.append( - make.ValDef(ls(i).pos, mods, name, tp.duplicate(), rhs.duplicate())); - case t => - ts.append( - make.PatDef(t.pos, mods, t, rhs.duplicate())); - } - i = i + 1; - } - } - ts.toArray() - } - - /** VarDef ::= Id [`:' Type] `=' Expr - * | Id `:' Type `=' `_' - * VarDcl ::= Id `:' Type - */ - def varDefOrDcl(mods: Int): Array[Tree] = { - var newmods = mods | Modifiers.MUTABLE; - val names = new ListBuffer[Pair[Int, Name]]; - do { - s.nextToken(); - names.append(Pair(s.pos, ident())); - } while (s.token == COMMA); - val tp = typedOpt(); - val rhs = if (tp == Tree.Empty || s.token == EQUALS) { - accept(EQUALS); - if (tp != Tree.Empty && s.token == USCORE) { - s.nextToken(); - Tree.Empty - } else - expr(); - } else { - newmods = newmods | Modifiers.DEFERRED; - Tree.Empty; - } - val ts = new myTreeList(); - names foreach { case Pair(p, n) => - ts.append( - make.ValDef(p, newmods, n, tp.duplicate(), rhs.duplicate())); - } - ts.toArray() - } - - /** FunDef ::= Id [FunTypeParamClause] {ParamClauses} [`:' Type] `=' Expr - * | this ParamClause `=' ConstrExpr - * FunDcl ::= Id [FunTypeParamClause] {ParamClauses} `:' Type - */ - def funDefOrDcl(mods: Int): Array[Tree] = { - val ts = new myTreeList(); - s.nextToken(); - if (s.token == THIS) { - val pos = s.pos; - s.nextToken(); - val vparams = NewArray.ValDefArray(paramClause(false)); - accept(EQUALS); - ts.append( - make.DefDef( - pos, mods, Names.CONSTRUCTOR, - Tree.AbsTypeDef_EMPTY_ARRAY, vparams, Tree.Empty, - constrExpr())); - } else { - var newmods = mods; - val lhs = new ListBuffer[Tuple4[Int, Name, Array[Tree.AbsTypeDef], Array[Array[Tree.ValDef]]]]; - var loop = true; - while (loop) { - lhs.append(Tuple4(s.pos, ident(), - typeParamClauseOpt(false), - paramClauses())); - if (s.token == COMMA) - s.nextToken(); - else - loop = false; - } - val restype = typedOpt(); - val rhs = if (restype == Tree.Empty || s.token == EQUALS) { - equalsExpr(); - } else { - newmods = newmods | Modifiers.DEFERRED; - Tree.Empty; - } - lhs foreach { case Tuple4(p, n, tp, vp) => - ts.append( - make.DefDef(p, newmods, n, tp, vp, restype.duplicate(), - rhs.duplicate())); - } - } - ts.toArray() - } - - /** ConstrExpr ::= SelfInvocation - * | `{' SelfInvocation {`;' BlockStat} `}' - * SelfInvocation ::= this ArgumentExpr - */ - def constrExpr(): Tree = - if (s.token == LBRACE) { - val pos = s.skipToken(); - val statlist = new myTreeList(); - statlist.append(selfInvocation()); - val stats = - if (s.token == SEMI) { s.nextToken(); blockStatSeq(statlist) } - else statlist.toArray(); - accept(RBRACE); - block(pos, stats) - } else { - selfInvocation() - } - - /** SelfInvocation ::= this ArgumentExprs - */ - def selfInvocation(): Tree = { - val pos = s.pos; - accept(THIS); - make.Apply( - s.pos, make.Ident(pos, Names.CONSTRUCTOR), argumentExprs()); - } - - /** TypeDef ::= Id `=' Type - * TypeDcl ::= Id TypeBounds - */ - def typeDefOrDcl(mods: Int): Tree = { - val pos = s.pos; - val name = ident().toTypeName(); - s.token match { - case LBRACKET => - val tparams = typeParamClauseOpt(true); - accept(EQUALS); - make.AliasTypeDef(pos, mods, name, tparams, typ()) - case EQUALS => - s.nextToken(); - make.AliasTypeDef(pos, mods, name, Tree.AbsTypeDef_EMPTY_ARRAY, typ()) - case SUPERTYPE | SUBTYPE | VIEWBOUND | SEMI | COMMA | RBRACE => - typeBounds(pos, mods | Modifiers.DEFERRED, name) - case _ => - syntaxError("`=', `>:', or `<:' expected", true); - Tree.Empty; - } - } - - /** ClassDef ::= Id [TypeParamClause] [ClassParamClause] [`:' SimpleType] ClassTemplate - */ - def classDef(mods: Int): Array[Tree] = { - val lhs = new ListBuffer[Tuple4[Int, Name, Array[Tree.AbsTypeDef], Array[Array[Tree.ValDef]]]]; - do { - s.nextToken(); - lhs.append(Tuple4(s.pos, - ident().toTypeName(), - typeParamClauseOpt(true), - paramClauseOpt(true))); - } while (s.token == COMMA); - val thistpe = simpleTypedOpt(); - val template = classTemplate((mods & Modifiers.CASE) != 0); - - val ts = new myTreeList(); - lhs foreach { case Tuple4(p, n, tp, vp) => - ts.append( - make.ClassDef(p, mods, n, tp, vp, - thistpe.duplicate(), - template.duplicate().asInstanceOf[Tree.Template])); - } - ts.toArray() - } - - /** ObjectDef ::= Id { , Id } [`:' SimpleType] ClassTemplate - */ - def objectDef(mods: Int): Array[Tree] = { - val lhs = new ListBuffer[Pair[Int, Name]]; - do { - s.nextToken(); - lhs.append(Pair(s.pos, ident())); - } while (s.token == COMMA); - val thistpe = simpleTypedOpt(); - val template = classTemplate((mods & Modifiers.CASE) != 0); - val ts = new myTreeList(); - lhs foreach { case Pair(p, n) => - ts.append( - make.ModuleDef( - p, mods, n, thistpe.duplicate(), - template.duplicate().asInstanceOf[Tree.Template])); - } - ts.toArray() - } - - /** ClassTemplate ::= ['extends' Constr] {'with' Constr} [TemplateBody] - */ - def classTemplate(isCaseClass: Boolean): Tree.Template = { - val pos = s.pos; - val parents = new myTreeList(); - if (s.token == EXTENDS) { - s.nextToken(); - parents.append(constr()); - } else { - parents.append(scalaAnyRefConstr(pos)); - } - parents.append(scalaObjectConstr(pos)); - if (isCaseClass) { - parents.append(caseClassConstr(pos)); - } - if (s.token == WITH) { - s.nextToken(); - template(parents) - } else if (s.token == LBRACE) { - make.Template(pos, parents.toArray(), templateBody()); - } else { - if (!(s.token == SEMI || s.token == COMMA || s.token == RBRACE)) - syntaxError("`extends' or `{' expected", true); - make.Template( - pos, parents.toArray(), Tree.EMPTY_ARRAY); - } - } - -////////// TEMPLATES //////////////////////////////////////////////////////////// - - - /** Template ::= Constr {'with' Constr} [TemplateBody] - */ - def template(): Tree.Template = - template(new myTreeList()); - - def template(parents: myTreeList): Tree.Template = { - val pos = s.pos; - parents.append(constr()); - while (s.token == WITH) { - s.nextToken(); - parents.append(constr()); - } - val stats = if (s.token == LBRACE) templateBody() else Tree.EMPTY_ARRAY; - make.Template(pos, parents.toArray(), stats) - } - - /** Constr ::= StableId [TypeArgs] [`(' [Exprs] `)'] - */ - def constr(): Tree = { - var t: Tree = convertToConstr(stableId()); - if (s.token == LBRACKET) - t = make.AppliedType(s.pos, t, typeArgs()); - if (s.token == LPAREN) - t = make.Apply(s.pos, t, argumentExprs()); - applyConstr(t) - } - - /** TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}' - */ - def templateBody(): Array[Tree] = { - accept(LBRACE); - var body = templateStatSeq(); - if (body.length == 0) - body = NewArray.Tree(Tree.Empty); - accept(RBRACE); - body - } - - /** Refinement ::= `{' [RefineStat {`;' RefineStat}] `}' - */ - def refinement(): Array[Tree] = { - accept(LBRACE); - val body = refineStatSeq(); - accept(RBRACE); - body - } - -/////// STATSEQS ////////////////////////////////////////////////////////////// - - /** Packaging ::= package QualId `{' TopStatSeq `}' - */ - def packaging(): Tree = { - val pos = accept(PACKAGE); - val pkg = qualId(); - accept(LBRACE); - val stats = topStatSeq(); - accept(RBRACE); - makePackaging(pos, pkg, stats); - } - - /** TopStatSeq ::= [TopStat {`;' TopStat}] - * TopStat ::= AttributeClauses Modifiers ClsDef - * | Packaging - * | Import - * | - */ - def topStatSeq(): Array[Tree] = { - val stats = new myTreeList(); - while (s.token != RBRACE && s.token != EOF) { - if (s.token == PACKAGE) { - stats.append(packaging()); - } else if (s.token == IMPORT) { - stats.append(importClause()); - } else if (s.token == CLASS || - s.token == CASECLASS || - s.token == TRAIT || - s.token == OBJECT || - s.token == CASEOBJECT || - s.token == LBRACKET || - isModifier()) { - stats.append( - joinAttributes( - attributeClauses(), - joinComment(clsDef(modifiers())))); - } else if (s.token != SEMI) { - syntaxError("illegal start of class or object definition", true); - } - if (s.token != RBRACE && s.token != EOF) accept(SEMI); - } - stats.toArray() - } - - /** TemplateStatSeq ::= TemplateStat {`;' TemplateStat} - * TemplateStat ::= Import - * | AttributeClauses Modifiers Def - * | AttributeClauses Modifiers Dcl - * | Expr - * | - */ - def templateStatSeq(): Array[Tree] = { - val stats = new myTreeList(); - while (s.token != RBRACE && s.token != EOF) { - if (s.token == IMPORT) { - stats.append(importClause()); - } else if (isExprIntro()) { - stats.append(expr()); - } else if (isDefIntro() || isModifier() || s.token == LBRACKET) { - stats.append( - joinAttributes( - attributeClauses(), - joinComment(defOrDcl(modifiers())))) - } else if (s.token != SEMI) { - syntaxError("illegal start of definition", true); - } - if (s.token != RBRACE) accept(SEMI); - } - stats.toArray() - } - - /** AttributeClauses ::= {AttributeClause} - * AttributeClause ::= `[' Attribute {`,' Attribute} `]' - * Attribute ::= Constr - */ - def attributeClauses(): List[Tree] = { - var attrs: List[Tree] = List(); - while (s.token == LBRACKET) { - s.nextToken(); - attrs = constr() :: attrs; - while (s.token == COMMA) { - s.nextToken(); - attrs = constr() :: attrs; - } - accept(RBRACKET); - } - attrs - } - def joinAttributes(attrs: List[Tree], defs: Array[Tree]): Array[Tree] = attrs match { - case List() => - defs - case attr :: attrs1 => - var i = 0; while (i < defs.length) { - defs(i) = make.Attributed(attr.pos, attr, defs(i)); - i = i + 1; - } - joinAttributes(attrs1, defs) - } - - /** RefineStatSeq ::= RefineStat {`;' RefineStat} - * RefineStat ::= Dcl - * | type TypeDef - * | - */ - def refineStatSeq(): Array[Tree] = { - val stats = new myTreeList(); - while (s.token != RBRACE && s.token != EOF) { - if (isDclIntro()) { - stats.append(joinComment(defOrDcl(0))); - } else if (s.token != SEMI) { - syntaxError("illegal start of declaration", true); - } - if (s.token != RBRACE) accept(SEMI); - } - stats.toArray() - } - - /** BlockStatSeq ::= { BlockStat `;' } [Expr] - * BlockStat ::= Import - * | Def - * | LocalModifiers ClsDef - * | Expr - * | - */ - def blockStatSeq(stats: myTreeList): Array[Tree] = { - while ((s.token != RBRACE) && (s.token != EOF) && (s.token != CASE)) { - if (s.token == IMPORT) { - stats.append(importClause()); - accept(SEMI); - } else if (isExprIntro()) { - stats.append(expr(false, true)); - if (s.token != RBRACE && s.token != CASE) accept(SEMI); - } else if (isDefIntro()) { - stats.append(joinComment(defOrDcl(0))); - accept(SEMI); - if (s.token == RBRACE || s.token == CASE) { - stats.append(gen.mkUnitLit(s.pos)); - } - } else if (isLocalModifier()) { - stats.append(joinComment(clsDef(localClassModifiers()))); - accept(SEMI); - if (s.token == RBRACE || s.token == CASE) { - stats.append(gen.mkUnitLit(s.pos)); - } - } else if (s.token == SEMI) { - s.nextToken(); - } else { - syntaxError("illegal start of statement", true); - } - } - stats.toArray() - } - - /** CompilationUnit ::= [ package QualId ( `;' | `{' TopStatSeq `}' ) ] TopStatSeq . - */ - def compilationUnit(): Array[Tree] = { - if (s.token == PACKAGE) { - val pos = s.skipToken(); - val pkg = qualId(); - if (s.token == SEMI) { - s.nextToken(); - NewArray.Tree(makePackaging(pos, pkg, topStatSeq())); - } else { - val stats = new myTreeList(); - accept(LBRACE); - stats.append(makePackaging(pos, pkg, topStatSeq())); - accept(RBRACE); - stats.append(topStatSeq()); - stats.toArray() - } - } else { - topStatSeq() - } - } - -} // class Parser - -} diff --git a/sources/scala/tools/scalac/ast/parser/ParserPhase.scala b/sources/scala/tools/scalac/ast/parser/ParserPhase.scala deleted file mode 100644 index 2885ea10bf..0000000000 --- a/sources/scala/tools/scalac/ast/parser/ParserPhase.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global} -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -package scala.tools.scalac.ast.parser { - -class ParserPhase(global: scalac_Global, descriptor: PhaseDescriptor) extends Phase(global, descriptor) { - - override def apply(unit: CompilationUnit): Unit = { - global.timer.start(); - unit.body = new Parser(unit).parse(); - global.timer.stop("parsed " + unit.source); - } -} -} diff --git a/sources/scala/tools/scalac/ast/parser/PatternNormalizer.scala b/sources/scala/tools/scalac/ast/parser/PatternNormalizer.scala deleted file mode 100644 index 18b07049b3..0000000000 --- a/sources/scala/tools/scalac/ast/parser/PatternNormalizer.scala +++ /dev/null @@ -1,607 +0,0 @@ -/* __ *\ -** ______________ _/ /___ ______ ** -** / ___/ ___/ __ `/ / __ `/ ___/ (c) 2002-2004, LAMP/EPFL ** -** (__ ) /__/ /_/ / / /_/ / /__ ** -** /____/\___/\__,_/_/\__,_/\___/ ** -** ** -** $Id$ ** -\* */ - -import scalac.ast._; -import scalac._; -import scala.Iterator; -import scala.tools.scalac.util.NewArray; -import scala.collection.immutable.ListMap ; -import scala.collection.mutable.Buffer; - -import java.util.HashMap; -import scalac.util.Names; - -/* -import scalac.CompilationUnit; -import scalac.ast.*; -import scalac.util.Name; -import Tree.*; -*/ - -package scala.tools.scalac.ast.parser { - - import scala.tools.scalac.ast.{TreeList => myTreeList} - - /** contains algorithms for `checking' and `normalizing' patterns - * - * @author Burak Emir - * @version 1.0 - */ - - class PatternNormalizer( unit:CompilationUnit ) { - - val make = unit.global.make ; - - // - ///////// CHECKING patterns for well-formedness /////////////////////////////// - // - - var seqDepth:int = 0; - - /** checks whether TO DO TO DO TO DO - * - @-recursion occurs only at the end just below a sequence - * returns true if the tree is ok. - * inSeq: flag, true if we are in a sequence '[' ... ']' - * t: the tree to be checked - */ - protected def check1( t:Tree , inAlt:boolean ):boolean = { - t match { - - case Tree$Literal( _ ) => true; - - case Tree$Apply( _, args ) => - seqDepth = seqDepth + 1; - val res = check1( args, inAlt ); - seqDepth = seqDepth - 1; - res; - - case Tree$Sequence( trees ) => // this is a hack to disallow deep binding - seqDepth = seqDepth + 1; - val res = check1( trees, inAlt ); - seqDepth = seqDepth - 1; - res; - - case Tree$Alternative( trees ) => - check1( trees, true ); - - case Tree$Bind( vble, tree ) => - if(( inAlt )&&( vble.toString().lastIndexOf("$") == -1)) { - - unit.error( t.pos, "variable binding not allowed under alternative"); - false; - - } else if(( seqDepth > 2 )&&( vble.toString().lastIndexOf("$") == -1)) { - unit.error( t.pos, - "sorry, deep binding not implemented"); - return false; - } else { - this.boundVars.put( vble, false ); - /* - boolean result = check( tree, inSeq ); - if(((Boolean) this.boundVars.get( t.symbol() )) - .booleanValue()) { // occurs recursively - // do something to RESTRICT recursion - } - */ - check1( tree, inAlt ); - } - case Tree$Typed( _, _ ) => true - - case Tree$Ident( vble ) => - if (inAlt && vble.isVariable() && vble != Names.PATTERN_WILDCARD && - vble.lastIndexOf('$') == -1) { - unit.error( t.pos, "variable not allowed under alternative"); - return false; - } else if(( this.boundVars.containsKey( vble /*t.symbol()*/ )) - &&( vble.toString().lastIndexOf("$") == -1)) { - unit.error( t.pos, "recursive patterns not allowed"); - false - //this.boundVars.put( t.symbol(), Boolean.TRUE ); //mark recursive - //System.out.println( t.symbol() + "occurs recursively"); - } - else true; - - case Tree$Select( _, _ ) => true; - - case _ => /* never happens */ - unit.error( t.pos, "unexpected tree" + t ); - false - } - } - - /** checkPat for every tree in array of trees, see below - */ - protected def check1( trees:Array[Tree], inAlt:boolean ):boolean = { - var res = true; - var i:int = 0; while (( i < trees.length ) && res) { - res = check1( trees( i ), inAlt ); - i = i + 1; - } - res - } - - // if this map contains a symbol as a key, it is bound. - // if this symbol is mapped to Boolean.True, it occurs recursively - /*Name=>Boolean*/ var boundVars:HashMap = _; - - /** method - */ - def check( pat:Tree ):boolean = { - this.boundVars = new HashMap(); - - if(TreeInfo.isSequenceValued( pat )) - unit.error( pat.pos, "sequence pattern not allowed here"); - - //reject top-level sequence patterns - /* - pat match { - case Tree$Sequence( _ ) => - unit.error( pat.pos, "sequences not allowed here"); false; - - case Tree$Alternative( args ) => - var res = true; - var i = 0; while( res && (i < args.length )) { - args( i ) match { - case Tree$Sequence( _ ) => - unit.error( args( i ).pos, "sequences not allowed here"); - res = false; - case _ => - }; - i = i + 1 - } - - case Tree$Bind(_, x) => - if(TreeInfo.isSequenceValued( pat )) - unit.error( pat.pos, "sequence pattern not allowed here"); - case _ => - } - */ - // reject deep binding - if( TreeInfo.isRegularPattern( pat ) ) - this.seqDepth = 0; - else - this.seqDepth = -32; // don't care about sequences. see above - check1( pat, false ); - } - - - // - /////////////// NORMALIZING patterns ///////////////////////////////////////////////////////////// - // - - def isEmptySequence( tree:Tree ):boolean = { - tree match { - case Tree$Sequence( trees ) => - //return ((trees.length == 1)&&( trees[ 0 ] == Tree.Empty )); - trees.length == 0; - case _ => - false; - } - } - - def isSequence( tree:Tree ):boolean = { - tree match { - case Tree$Sequence( _ ) => true - case _ => false; - } - } - - /** appends every non-empty tree in trees to ts - */ - def appendNonEmpty( ts:myTreeList, trees:Array[Tree] ):unit = { - var i = 0; while ( i < trees.length ) { - if( !isEmptySequence( trees( i ) ) ) - ts.append( trees( i ) ); - i = i + 1 - } - } - - /** appends tree to ts if it is non-empty, leaves ts unchanged. - */ - def appendNonEmpty( ts:myTreeList, tree:Tree ) = { - if ( !isEmptySequence(tree)) - ts.append( tree ); - } - - /** takes a (possibly empty) myTreeList and make a Sequence out of it - */ - def treeListToSequence( pos:int , ts:myTreeList ):Tree = { - make.Sequence( pos, ts.toArray() ); - } - - - /** (1) nested `Alternative' nodes are flattened (( tree traversal with clique contraction )) - * if all branches are empty, empty subsequence is returned. - * variables x are replaced by bindings x @ _ - */ - - // apply `flattenAlternative' to each tree in ts - def flattenAlternatives( ts:Array[Tree] ):Array[Tree] = { - val res = new Array[Tree]( ts.length ); - var i = 0; while( i < ts.length ) { - res( i ) = flattenAlternative( ts( i ) ); - i = i + 1 ; - } - res; - } - - // main algo for (1) - def flattenAlternative( tree:Tree ):Tree = { - tree match { - case Tree$Alternative( choices:Array[Tree] ) => - val cs = new myTreeList(); - var i = 0; while( i < choices.length ) { - val child = choices( i ); - child match { - case Tree$Alternative( child_choices ) => // grab its flattened children - cs.append( flattenAlternativeChildren( child_choices ) ); - case _ => - cs.append( child ); - } - i = i + 1; - } - val newtrees = cs.toArray(); - newtrees.length match { - case 1 => newtrees( 0 ); - case 0 => make.Sequence( tree.pos, Tree.EMPTY_ARRAY ); - case _ => make.Alternative( tree.pos, cs.toArray() ); - } - - // recursive call - case Tree$Sequence( trees) => - make.Sequence( tree.pos, flattenAlternatives( trees )); - case Tree$Bind( vble, body ) => - make.Bind( tree.pos, vble, flattenAlternative( body )); - case _ => - tree; // no alternatives can occur - } - } - - // main algo for (1), precondition: choices are children of an Alternative node - def flattenAlternativeChildren( choices:Array[Tree] ):myTreeList = { - var allEmpty = true; - val cs = new myTreeList(); - var j = 0; while( j < choices.length ) { - val tree = flattenAlternative( choices( j ) ); // flatten child - tree match { - case Tree$Alternative( child_choices:Array[Tree] ) => - val tmp = cs.length(); - appendNonEmpty( cs, child_choices ); - if( cs.length() != tmp ) - allEmpty = false; - case _ => - cs.append( tree ); - allEmpty = allEmpty && TreeInfo.isEmptySequence( tree ); - } - j = j + 1; - } - if( allEmpty ) { - cs.clear(); - cs.append(make.Sequence(choices( 0 ).pos, Tree.EMPTY_ARRAY)); - } - cs - } - - /** (2) nested `Sequence' nodes are flattened (( clique elimination )) - * nested empty subsequences get deleted - * for Apply nodes, sequence arguments are removed - */ - - // apply `flattenSequence' to each tree in trees - def flattenSequences( trees:Array[Tree] ):Array[Tree] = { - val res = new Array[Tree]( trees.length ); - var i = 0;while( i < trees.length ) { - res( i ) = flattenSequence( trees( i ) ); - i = i + 1; - } - res - } - // main algo for (2) - def flattenSequence( tree:Tree ):Tree = { - tree match { - case Tree$Apply( fn, trees:Array[Tree] ) => - var li:List[Tree] = Nil; - var i = 0; while( i < trees.length ) { - trees(i) match { - case Tree$Sequence( trees2:Array[Tree] ) => - Iterator.fromArray( flattenSequenceChildren( trees2 ).toArray() ).foreach { - x:Tree => li = x::li; - } - case z => li = z::li; - } - i = i + 1; - } - val newtrees:Array[Tree] = new Array[Tree]( li.length ); - i = 0; - for( val nt <- li.reverse.elements ) { - newtrees( i ) = nt; - i = i + 1; - } - make.Apply( tree.pos, fn, newtrees ) - /* - case Sequence( Tree[] trees ): - trees = flattenSequences( trees ); - if(( trees.length == 1 )&&( isEmptySequence( trees[ 0 ] ))) - trees = Tree.EMPTY_ARRAY; - return make.Sequence( tree.pos, trees ); - */ - case Tree$Sequence( trees:Array[Tree] ) => - val ts = new myTreeList(); - var i = 0; while( i < trees.length ) { - val child = trees( i ); - child match { - case Tree$Sequence( child_trees ) => // grab its flattened children - ts.append( flattenSequenceChildren( child_trees ) ); - case _ => - ts.append( child ); - } - i = i + 1; - } - /* - System.out.print("ts = "); - for(int jj = 0; jj<ts.length(); jj++) { - System.out.print(ts.get( jj ).toString()+" "); - } - System.out.println(); - */ - val t = treeListToSequence( tree.pos, ts ) ; - t - case Tree$Alternative( choices ) => - make.Alternative( tree.pos, flattenSequences( choices )); - case Tree$Bind( vble, body ) => - make.Bind( tree.pos, vble, flattenSequence( body )); - case _ => tree; - } - } - - // main algo for (2), precondition: trees are children of a Sequence node - def flattenSequenceChildren( trees:Array[Tree] ):myTreeList = { - val ts = new myTreeList(); - var j = 0; while( j < trees.length ) { - val tree = flattenSequence( trees( j ) ); - tree match { - case Tree$Sequence( child_trees ) => - appendNonEmpty( ts, child_trees ); - case _ => - appendNonEmpty( ts, tree ); - } - j = j + 1; - } - ts; - } - - - /** (3) in `Sequence': - * children of direct successor nodes labelled `Sequence' are moved up - * (( tree traversal, left-to-right traversal )) - */ - - /** applies `elimSequence' to each tree is ts - */ - def elimSequences( ts:Array[Tree] ):Array[Tree] = { - val res = new Array[Tree] ( ts.length ); - var i = 0; while( i < ts.length ) { - res( i ) = elimSequence( ts( i ) ); - i = i + 1 - } - res; - } - - def elimSequence( tree:Tree ):Tree = { - tree match { - case Tree$Sequence( trees ) => - // might be empty ... - val newtrees = mergeHedge( trees ).toArray(); - if(( newtrees.length == 1 )&&( isEmptySequence( newtrees( 0 ) ))) - make.Sequence( tree.pos, Tree.EMPTY_ARRAY ); - else - make.Sequence( tree.pos, newtrees ); - - // recurse - //case Sequence( Array[Tree] trees ): // after normalization (2), Sequence is flat - /* - myTreeList ts = new myTreeList(); - for( int i = 0; i < trees.length; i++ ) { - Tree t = trees[ i ]; - //if( t != Tree.Empty ) // forget empty subsequences - ts.append( elimSequence( t )); // recurse - } - return treeListToSequence( tree.pos, ts ); - */ - //return make.Sequence( tree.pos, elimSequences( trees )); - case Tree$Alternative( choices ) => - val result = make.Alternative( tree.pos, elimSequences( choices ) ); - flattenAlternative( result ); // apply - case Tree$Bind( vble, body ) => - make.Bind( tree.pos, vble, elimSequence( body )); - case _ => - tree; // nothing to do - } - } - - /** runs through an array of trees, merging adjacent `Sequence' nodes if possible - * returns a (possibly empty) myTreeList - * precondition: trees are children of a Sequence node - */ - def mergeHedge( trees:Array[Tree] ):myTreeList = { - val ts = new myTreeList(); - if( trees.length > 1 ) { // more than one child - var left = trees( 0 ); - var right:Tree = null;; - var merge:Tree = null; - var i = 0; while( i < trees.length - 1 ) { - right = trees( i + 1 ); - merge = mergeThem( left, right ); - if( merge != null ) { - left = merge; - } else { - ts.append( left ); - left = right; - } - i = i + 1; - } - if( merge!= null ) { - ts.append( merge ); - } else if( right != null ) { - ts.append( right ); - } - } else if ( trees.length == 1 ) { - //if( trees[ 0 ] != Tree.Empty ) - ts.append( trees( 0 ) ); // append the single child - } - ts; - } - - /** if either left or right are subsequences, returns a new subsequences node - * with the children of both, where any occurences of Tree.Empty are removed - * otherwise, returns null. "move concatenation to the top" - */ - def mergeThem( left:Tree, right:Tree ):Tree = { - left match { - case Tree$Sequence( treesLeft ) => // left tree is subsequence - val ts = new myTreeList(); - appendNonEmpty( ts, treesLeft ); - right match { - case Tree$Sequence( treesRight ) => // subsequence - appendNonEmpty( ts, treesRight ); - case _ => // atom - ts.append( right ); - }; - treeListToSequence( left.pos, ts ); - - case _ => // left tree is atom - right match { - case Tree$Sequence( treesRight ) => - val ts = new myTreeList(); - ts.append( left ); - appendNonEmpty( ts, treesRight ); // ...and right tree is subsequence - treeListToSequence( left.pos, ts ); - case _ => // right tree is atom -- no merge - null - } - } - } - - - - /* (4) If `Alternative' at least one subsequence branch, then we wrap every atom that may - * occur in a `Sequence' tree - * (( tree traversal )) - */ - - /** applies `warpAlternative' to each tree is ts - */ - def wrapAlternatives( trees:Array[Tree] ):Array[Tree] = { - val newts = new Array[Tree]( trees.length ); - var i = 0; while( i < trees.length ) { - newts( i ) = wrapAlternative( trees( i ) ); - i = i + 1; - } - newts; - } - - /** main algo for (4) - */ - def wrapAlternative( tree:Tree ):Tree = { - tree match { - case Tree$Alternative( choices ) => - make.Alternative( tree.pos, wrapAlternativeChildren( choices )); - // recursive - case Tree$Sequence( trees ) => - make.Sequence( tree.pos, wrapAlternatives( trees )); - case Tree$Bind( vble, body ) => - make.Bind( tree.pos, vble, wrapAlternative( body )); - - case Tree$Ident( name ) => - /* - System.out.println( "in case Ident, name" +name); - if ( name != Name.fromString("_") - && ( boundVars.get( tree.symbol() ) == null )) { - - System.out.println("TRANSF, name:"+name); - - return make.Bind( tree.pos, - name, - make.Ident( tree.pos, - Name.fromString("_") )) - .symbol( tree.symbol() ) - .type( tree.type ); - } - */ - tree; - - case _ => - tree; - - } - } - - /** algo for (4), precondition: choices are direct successors of an `Alternative' node - */ - def wrapAlternativeChildren( choices:Array[Tree] ):Array[Tree] = { - val newchoices = new Array[Tree]( choices.length ); - - var i = 0;while( i < choices.length ) { - newchoices( i ) = wrapAlternative( choices( i ) ); // recursive call - i = i + 1; - } - - if( hasSequenceBranch( newchoices )) { - var i = 0; while( i < choices.length ) { - newchoices( i ) = wrapElement( choices( i ) ); - i = i + 1; - } - } - newchoices - } - - /** returns true if at least one tree in etrees is a subsequence value - */ - def hasSequenceBranch( trees:Array[Tree] ):boolean = { - var isSubseq = false; - var i = 0; while( i < trees.length && !isSubseq ) { - isSubseq = isSequenceBranch( trees( i ) ); - i = i + 1; - } - isSubseq; - } - - /* returns true if the argument is a subsequence value, i.e. if - * is is labelled `Sequence' or a `Bind' or an `Alternative' with a `Sequence' node below - * precondition: choices are in normal form w.r.t. to (4) - */ - def isSequenceBranch( tree:Tree ):boolean = { - tree match { - case Tree$Sequence( _ ) => - true; - case Tree$Alternative( trees:Array[Tree] )=> // normal form -> just check first child - trees( 0 ) match { - case Tree$Sequence( _ ) => true; - case _ => false; - } - case Tree$Bind( _, body ) => - isSequenceBranch( body ); - case _ => - false; - } - } - - def wrapElement( tree:Tree ):Tree = { - tree match { - case Tree$Sequence(_) => - tree; - case _ => - make.Sequence(tree.pos, {val t = new Array[Tree]( 1 );t(0) = tree; t } ); - } - } - - } /*class PatternNormalizer */ - -} /* package */ - diff --git a/sources/scala/tools/scalac/ast/parser/Scanner.scala b/sources/scala/tools/scalac/ast/parser/Scanner.scala deleted file mode 100644 index 09b4e45960..0000000000 --- a/sources/scala/tools/scalac/ast/parser/Scanner.scala +++ /dev/null @@ -1,998 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -import scalac._; -import scalac.util.{Name, Names}; -import scalac.util.SourceRepresentation; - -package scala.tools.scalac.ast.parser { - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -/** A scanner for the programming language Scala. - * - * @author Matthias Zenger, Martin Odersky, Burak Emir - * @version 1.1 - */ -class Scanner(_unit: CompilationUnit) extends TokenData { - - import Tokens._; - import java.lang.{Integer, Long, Float, Double} - - val unit = _unit; - - val cbuf = new StringBuffer(); - - /** buffer for the documentation comment - */ - var docBuffer: StringBuffer = null; - - /** add the given character to the documentation buffer - */ - protected def addCharToDoc(ch: Char): unit = - if (docBuffer != null) docBuffer.append(ch); - - /** layout & character constants - */ - val tabinc = 8; - val LF = SourceFile.LF; - val FF = SourceFile.FF; - val CR = SourceFile.CR; - val SU = SourceFile.SU; - - /** we need one token lookahead - */ - val next = new TokenData(); - val prev = new TokenData(); - - /** the first character position after the previous token - */ - var lastpos = 0; - - /** the last error position - */ - var errpos = -1; - - /** the input buffer: - var buf: Array[Char] = unit.source.getContent(); - var bp: Int = -1; - */ - - class SourceIterator(charArray: Array[Char]) extends Iterator[Char] { - val buf: Array[Char] = charArray; - var bp: Int = -1; - /* inv: true if buf( bp ) is last of an odd number of ASCII '\' */ - var odd = false; - var unicode1: Int = 0; - var unicode2: Int = 0; - def hasMore(i: Int, j: Int) = i + j < buf.length; - def hasMore(j: Int) = bp + j < buf.length; - def hasNext = hasMore(1); - - /** - * Gets next char, handles unicode transform - */ - def next: Char = { - bp = bp + 1; - val ch = buf(bp); - odd = (ch == '\\') && !odd; - if (odd && hasNext && 'u' == buf(bp + 1)) { - val Pair(newch, offset) = nextUnicode(bp + 1); - bp = bp + offset; - ccol = ccol + offset; - odd = false; - newch - } else { - ch - } - } - def raw: Char = { bp = bp + 1; buf(bp) } - - /** precondition: hasNext - */ - def lookahead1 = { - val ahead1 = buf( bp + 1 ); - if (ahead1 == '\\' && !odd && hasMore(2) && 'u' == buf(bp + 1)) { - val Pair(newch, offset) = nextUnicode(bp + 1); - unicode1 = offset; - bp = bp + offset; - newch; - } - else { - unicode1 = 0; - ahead1 - } - } - - /** precondition: hasMore( 2 ) */ - def lookahead2 = { - val j = bp + unicode1 + 1 + 1; - val ahead2 = buf( j ); - val even1 = unicode1 > 0 || '\\' != buf(j - 1) || odd; - if (ahead2 == '\\' && even1 && hasMore(j, 1) && 'u' == buf(j + 1)) { - val Pair(newch, offset) = nextUnicode(j + 1); - unicode2 = offset; - newch; - } - else { - ahead2 - } - } - - /** precondition: hasMore( 3 ) */ - def lookahead3 = { - val j = bp + unicode1 + 1 + unicode2 + 1 + 1; - val ahead3 = buf( j ); - var even2 = unicode2 > 0 || '\\' != buf( j - 1 ) || '\\' == buf( j - 2 ); - - if (ahead3 == '\\' && even2 && hasMore( j, 1 ) && 'u' == buf(j + 1)) { - val Pair(newch, offset) = nextUnicode(j + 1); - newch; - } else { - ahead3 - } - } - - import SourceRepresentation.digit2int; - - /** returns unicode and offset of next character */ - def nextUnicode(p: Int): Pair[Char,Int] = { - var j = p; - while ( buf(j) == 'u' ) { j = j + 1 }; - if (j + 4 >= buf.length) syntaxError("incomplete unicode escape"); - def munch = { - val i = digit2int( buf(j), 16 ); - if (i == -1) { - syntaxError("error in unicode escape"); - }; - j = j + 1; - i - } - var code:Int = munch; - //Console.println("nextUnicode2, code =" + code); - code = (code << 4) + munch; - code = (code << 4) + munch; - code = (code << 4) + munch; - Pair(code.asInstanceOf[Char], j - p) - } - - } /* class SourceIterator */ - - /** the input iterator. Converts unicode characters as in Java spec (3.3) - */ - var srcIterator:SourceIterator = new SourceIterator(unit.source.getContent()); - - /** the current character - */ - var ch: Char = _; - - /** the last character (needed by XMLSTART) - */ - var lastch: Char = _; - - /** the line and column position of the current character - */ - var cline: Int = 1; - var ccol: Int = 0; - - /** a buffer for character and string literals - */ - var lit = new Array[char](64); - - - /** INIT: Construct a scanner from a file input stream. - */ - token = EMPTY; - nextch(); - Tokens; // initialize tokens - nextToken(); - - def nextch(): unit = { - lastch = ch; - ch = srcIterator.next; - ccol = ccol + 1; - //System.out.print("[" + ch + "]");//DEBUG - } - - /** read next token and return last position - */ - def skipToken(): Int = { - val p = pos; nextToken(); p - } - - def nextToken(): unit = { - if (token == RBRACE) { - val prevpos = pos; - fetchToken(); - token match { - case ELSE | EXTENDS | WITH | YIELD | CATCH | FINALLY | - COMMA | SEMI | DOT | COLON | EQUALS | ARROW | - LARROW | SUBTYPE | SUPERTYPE | HASH | AT | - RPAREN | RBRACKET | RBRACE => - case _ => - if (token == EOF || - ((pos >>> Position.COLUMN_BITS) > - (prevpos >>> Position.COLUMN_BITS))) { - next.copyFrom(this); - this.token = SEMI; - this.pos = prevpos; - } - } - } else { - if (next.token == EMPTY) { - fetchToken(); - } else { - copyFrom(next); - next.token = EMPTY - } - if (token == CASE) { - prev.copyFrom(this); - fetchToken(); - if (token == CLASS) { - token = CASECLASS; - } else if (token == OBJECT) { - token = CASEOBJECT; - } else { - next.copyFrom(this); - this.copyFrom(prev); - } - } - else if (token == SEMI) { - prev.copyFrom(this); - fetchToken(); - if (token != ELSE) { - next.copyFrom(this); - this.copyFrom(prev); - } - } - //Console.println("<" + token2string(token) + ":" + name + ">");//DEBUG - } - } - - /** read next token - */ - private def fetchToken(): unit = { - if (token == EOF) return; - lastpos = Position.encode(cline, ccol); - //var index = bp; - while (true) { - ch match { - case ' ' => - nextch(); - case '\t' => - ccol = ((ccol - 1) / tabinc * tabinc) + tabinc; - nextch(); - case CR => - cline = cline + 1; - ccol = 0; - nextch(); - if (ch == LF) { - ccol = 0; - nextch(); - } - case LF | FF => - cline = cline + 1; - ccol = 0; - nextch(); - case _ => - pos = Position.encode(cline, ccol); - //index = bp; - ch match { - case '\u21D2' => - nextch(); - token = ARROW; - return; - case 'A' | 'B' | 'C' | 'D' | 'E' | - 'F' | 'G' | 'H' | 'I' | 'J' | - 'K' | 'L' | 'M' | 'N' | 'O' | - 'P' | 'Q' | 'R' | 'S' | 'T' | - 'U' | 'V' | 'W' | 'X' | 'Y' | - 'Z' | '$' | '_' | - 'a' | 'b' | 'c' | 'd' | 'e' | - 'f' | 'g' | 'h' | 'i' | 'j' | - 'k' | 'l' | 'm' | 'n' | 'o' | - 'p' | 'q' | 'r' | 's' | 't' | - 'u' | 'v' | 'w' | 'x' | 'y' | // scala-mode: need to understand multi-line case patterns - 'z' => - putChar(ch); - nextch(); - getIdentRest; // scala-mode: wrong indent for multi-line case blocks - return; - case _ if (Character.isUnicodeIdentifierStart(ch)) => - putChar(ch); - nextch(); - getIdentRest; - return; - - case '<' => // is XMLSTART? - var last = lastch; - nextch(); - last match { - case ' '|'\t'|'\n'|'{'|'('|'>' if xml.Parsing.isNameStart(ch) => - token = XMLSTART; - case _ => - putChar('<'); - getOperatorRest; - } - return; - - case '~' | '!' | '@' | '#' | '%' | - '^' | '*' | '+' | '-' | /* '<' | */ - '>' | '?' | ':' | '=' | '&' | - '|' | '\\' => - putChar( ch ); - nextch(); - getOperatorRest; // XXX - return; - case '/' => - nextch(); - if (! skipComment()) { - putChar('/'); - getOperatorRest; - return; - } - case '0' => - putChar(ch); - nextch(); - if (ch == 'x' || ch == 'X') { - nextch(); - base = 16; - getNumber; - } else { - base = 8; - getNumber; - } - return; // scala-mode: return is a keyword - case '1' | '2' | '3' | '4' | - '5' | '6' | '7' | '8' | '9' => - base = 10; - getNumber; - return; - case '`' => //" scala-mode: need to understand literals - getStringLit('`'); - token = IDENTIFIER; - return; - case '\"' => //" scala-mode: need to understand literals - getStringLit('\"'); - return; - case '\'' => - nextch(); - ch match { - case 'A' | 'B' | 'C' | 'D' | 'E' | - 'F' | 'G' | 'H' | 'I' | 'J' | - 'K' | 'L' | 'M' | 'N' | 'O' | - 'P' | 'Q' | 'R' | 'S' | 'T' | - 'U' | 'V' | 'W' | 'X' | 'Y' | - 'Z' | '$' | '_' | - 'a' | 'b' | 'c' | 'd' | 'e' | - 'f' | 'g' | 'h' | 'i' | 'j' | - 'k' | 'l' | 'm' | 'n' | 'o' | - 'p' | 'q' | 'r' | 's' | 't' | - 'u' | 'v' | 'w' | 'x' | 'y' | - 'z' => - cbuf.setLength(0); - putChar(ch); - nextch(); - if (ch != '\'') { - getIdentRest; - token = SYMBOLLIT; - return; - } - case _ if (Character.isUnicodeIdentifierStart(ch)) => - cbuf.setLength(0); - putChar(ch); - nextch(); - if (ch != '\'') { - getIdentRest; - token = SYMBOLLIT; - return; - } - case _ => - getlitch(); - } - if (ch == '\'') { - nextch(); - token = CHARLIT; - name = Name.fromString(cbuf.toString()); - cbuf.setLength(0); - } - else { - syntaxError("unclosed character literal"); - } - return; - case '.' => - nextch(); - if (('0' <= ch) && (ch <= '9')) { - putChar('.'); - getFraction; - } else token = DOT; - return; - case ';' => - nextch(); token = SEMI; - return; - case ',' => - nextch(); token = COMMA; - return; - case '(' => //scala-mode: need to understand character quotes - nextch(); token = LPAREN; - return; - case '{' => - nextch(); token = LBRACE; - return; - case ')' => - nextch(); token = RPAREN; - return; - case '}' => - nextch(); token = RBRACE; - return; - case '[' => - nextch(); token = LBRACKET; - return; - case ']' => - nextch(); token = RBRACKET; - return; - case SU => - if (! srcIterator.hasNext) - token = EOF; - else { - syntaxError("illegal character"); - nextch(); - } - return; - case _ => - if (Character.isUnicodeIdentifierStart(ch)) { - putChar(ch); - nextch(); - getIdentRest; - } - else if (isSpecial(ch)) { - putChar(ch); - getOperatorRest; - } - else { - syntaxError("illegal character"); - nextch(); - } - return; - } - } - } - } - - private def skipComment(): Boolean = { - if (ch == '/') { - do { - nextch(); - } while ((ch != CR) && (ch != LF) && (ch != SU)); - true - } - else if (ch == '*') { - docBuffer = null; - var openComments = 1; - nextch(); - if (ch == '*') { - docBuffer = new StringBuffer("/**"); - } - while (openComments > 0) { - do { - do { - if (ch == CR) { - cline = cline + 1; - ccol = 0; - nextch(); addCharToDoc(ch); - if (ch == LF) { - ccol = 0; - nextch(); addCharToDoc(ch); - } - } else if (ch == LF) { - cline = cline + 1; - ccol = 0; - nextch(); addCharToDoc(ch); - } else if (ch == '\t') { - ccol = ((ccol - 1) / tabinc * tabinc) + tabinc; - nextch(); addCharToDoc(ch); - } else if (ch == '/') { - nextch(); addCharToDoc(ch); - if (ch == '*') { - nextch(); addCharToDoc(ch); - openComments = openComments + 1; - } - } else if ((ch != '*')&&(ch != SU)) { - nextch(); addCharToDoc(ch); - } - } while ((ch != '*') && (ch != SU)); - while (ch == '*') { - nextch(); addCharToDoc(ch); - } - } while (ch != '/' && ch != SU); - if (ch == '/') nextch(); - else syntaxError("unclosed comment"); - openComments = openComments - 1; - } - lastch = ' '; - true; - } else { - false - } - } - -// Identifiers --------------------------------------------------------------- - - def isIdentStart(c: char): boolean = - ('A' <= c && c <= 'Z') || - ('a' <= c && c <= 'a') || - (c == '_') || (c == '$') || - Character.isUnicodeIdentifierStart(c); - - def isIdentPart(c: char) = - isIdentStart(c) || - ('0' <= c && c <= '9') || - Character.isUnicodeIdentifierPart(c); - - def isSpecial(c: char) = { - val chtp = Character.getType(c); - chtp == Character.MATH_SYMBOL || chtp == Character.OTHER_SYMBOL; - } - - private def getIdentRest: Unit = { - while (true) { - ch match { - case 'A' | 'B' | 'C' | 'D' | 'E' | - 'F' | 'G' | 'H' | 'I' | 'J' | - 'K' | 'L' | 'M' | 'N' | 'O' | - 'P' | 'Q' | 'R' | 'S' | 'T' | - 'U' | 'V' | 'W' | 'X' | 'Y' | - 'Z' | '$' | - 'a' | 'b' | 'c' | 'd' | 'e' | - 'f' | 'g' | 'h' | 'i' | 'j' | - 'k' | 'l' | 'm' | 'n' | 'o' | - 'p' | 'q' | 'r' | 's' | 't' | - 'u' | 'v' | 'w' | 'x' | 'y' | - 'z' | - '0' | '1' | '2' | '3' | '4' | - '5' | '6' | '7' | '8' | '9' => - putChar( ch ); - nextch(); - case '_' => - putChar(ch); - nextch(); - getIdentOrOperatorRest; - return; - case SU => - // true == Character.isUnicodeIdentifierPart(SU) - treatIdent; - return; - - case _ if (Character.isUnicodeIdentifierPart(ch)) => - putChar(ch); - nextch(); - case _ => - treatIdent; - return; - } - } - } - - private def getOperatorRest: unit = { - while (true) { - ch match { - case '~' | '!' | '@' | '#' | '%' | - '^' | '*' | '+' | '-' | '<' | - '>' | '?' | ':' | '=' | '&' | - '|' | '\\' => - putChar(ch); - nextch(); - case '/' => - nextch(); - if (skipComment()) { - treatIdent; - return; - } else { - putChar( '/' ); - } - case _ => - if (isSpecial(ch)) { - putChar(ch); - nextch(); - } else { - treatIdent; - return; - } - } - } - } - - private def getIdentOrOperatorRest: unit = { - if (isIdentPart(ch)) - getIdentRest - else ch match { - case '~' | '!' | '@' | '#' | '%' | - '^' | '*' | '+' | '-' | '<' | - '>' | '?' | ':' | '=' | '&' | - '|' | '\\' | '/' => - getOperatorRest; - case _ => - if (isSpecial(ch)) { - getOperatorRest; - } else { - treatIdent; - } - } - } - - private def getStringLit(delimiter: Char): unit = { - nextch(); - while (srcIterator.hasNext && ch != delimiter && ch != CR && ch != LF) { - getlitch(); - } - if (ch == delimiter) { - token = STRINGLIT; - name = Name.fromString( cbuf.toString() ); - cbuf.setLength(0); - nextch(); - } - else { - syntaxError("unclosed string literal"); - name = Names.ERROR; - } - } - - def treatIdent = { - name = Name.fromString( cbuf.toString() ); -/* not yet! - if (name.length() > 1 && name.charAt(name.length() - 1) == '_') - syntaxError("identifier may not end in a '_'"); -*/ - token = name2token(name); - cbuf.setLength(0); - } - - /** generate an error at the given position - */ - def syntaxError(pos: Int, msg: String) = { - unit.error(pos, msg); - token = ERROR; - errpos = pos; - } - - /** generate an error at the current token position - */ - def syntaxError(msg: String): unit = syntaxError(pos, msg); - - /** append Unicode character to "lit" buffer - */ - private def putChar(ch: Char) = cbuf.append(ch); - /* - if (litlen == lit.length) { - val newlit = new Array[char](lit.length * 2); - System.arraycopy(lit, 0, newlit, 0, lit.length); - lit = newlit; - } - lit(litlen) = c; - litlen = litlen + 1; - }*/ - - /** return true iff next 6 characters are a valid unicode sequence: - protected def isUnicode() = - (bp + 6) < buf.length && - (buf(bp) == '\\') && - (buf(bp+1) == 'u') && - (SourceRepresentation.digit2int(buf(bp+2), 16) >= 0) && - (SourceRepresentation.digit2int(buf(bp+3), 16) >= 0) && - (SourceRepresentation.digit2int(buf(bp+4), 16) >= 0) && - (SourceRepresentation.digit2int(buf(bp+5), 16) >= 0); - */ - - /** precondition: isUnicode() == true - protected def getUnicodeChar(): Char = { - var i : Int = 0; - var k = bp + 2; - while( k < bp + 6 ) { - i = 16 * i + SourceRepresentation.digit2int(buf(k), 16); - k = k + 1; - }; - i.asInstanceOf[char] - } -*/ - /** read next character in character or string literal: - */ - protected def getlitch() = - if (ch == '\\') { - /* - if (isUnicode()) { - nextch(); - nextch(); - var code: int = 0; - code = (code << 4) + SourceRepresentation.digit2int(ch, 16); nextch(); - code = (code << 4) + SourceRepresentation.digit2int(ch, 16); nextch(); - code = (code << 4) + SourceRepresentation.digit2int(ch, 16); nextch(); - code = (code << 4) + SourceRepresentation.digit2int(ch, 16); nextch(); - putChar(code.asInstanceOf[char]); - } else { - */ - nextch(); - if ('0' <= ch && ch <= '7') { - val leadch: Char = ch; - var oct: Int = SourceRepresentation.digit2int(ch, 8); - nextch(); - if ('0' <= ch && ch <= '7') { - oct = oct * 8 + SourceRepresentation.digit2int(ch, 8); - nextch(); - if (leadch <= '3' && '0' <= ch && ch <= '7') { - oct = oct * 8 + SourceRepresentation.digit2int(ch, 8); - nextch(); - } - } - putChar(oct.asInstanceOf[Char]); - } else if (ch != SU) { - ch match { - case 'b' => putChar('\b') - case 't' => putChar('\t') - case 'n' => putChar('\n') - case 'f' => putChar('\f') - case 'r' => putChar('\r') - case '\"' => putChar('\"') - case '\'' => putChar('\'') - case '`' => putChar('`') /* tentative */ - case '\\' => putChar('\\') - case _ => - syntaxError(Position.encode(cline, ccol) - 1, "invalid escape character"); - putChar(ch); - } - nextch(); - } - /* } */ - } - else { - putChar(ch); - nextch(); - } - - /** read fractional part of floating point number; - */ - protected def getFraction = { - while (SourceRepresentation.digit2int(ch, 10) >= 0) { - putChar(ch); - nextch(); - } - token = DOUBLELIT; - if ((ch == 'e') || (ch == 'E')) { - putChar( ch ); - val c1 = srcIterator.lookahead1; - val c2 = srcIterator.lookahead2; - if ((c1 == '+') || (c1 == '-') && ('0' >= c2) || (c2 <= '9')) { - nextch(); - putChar(ch); - nextch(); - } else - nextch(); - while (SourceRepresentation.digit2int(ch, 10) >= 0) { - putChar(ch); - nextch(); - } - } - if ((ch == 'd') || (ch == 'D')) { - putChar( ch ); - nextch(); - } else if ((ch == 'f') || (ch == 'F')) { - putChar(ch); - token = FLOATLIT; - nextch(); - } - name = Name.fromString( cbuf.toString() ); - cbuf.setLength( 0 ); - } - - /** convert name, base to long value - * base = the base of the number; one of 8, 10, 16. - */ - def intVal(negated: boolean): long = { - import SourceRepresentation.digit2int; - - if (token == CHARLIT && !negated) { - if (name.length() > 0) - name.charAt(0) - else - 0 - } else { - - var value: long = 0; - val divider = if (base == 10) 1 else 2; - val limit: long = if (token == LONGLIT) Long.MAX_VALUE else Integer.MAX_VALUE; - var i = 0; - val len = name.length(); - while (i < len) { - val d = digit2int( name.charAt(i), base ); - if (d < 0) { - syntaxError("malformed integer number"); - return 0; - } - if (value < 0 || - limit / (base / divider) < value || - limit - (d / divider) < value * (base / divider) && - !(negated && limit == value * base - 1 + d)) { - syntaxError("integer number too large"); - return 0; - } - value = value * base + d; - i = i + 1; - } - if (negated) -value else value - } - } - - def intVal: long = intVal(false); - - /** convert name, base to double value - */ - def floatVal(negated: boolean): double = { - val limit: double = - if (token == DOUBLELIT) Double.MAX_VALUE else Float.MAX_VALUE; - try { - val value = Double.valueOf(name.toString()).doubleValue(); - if (value > limit) - syntaxError("floating point number too large"); - if (negated) -value else value - } - catch { - case _: NumberFormatException => - syntaxError("malformed floating point number"); - 0.0 - } - } - - def floatVal: double = floatVal(false); - - - /** see Java spec 3.10.2 */ - def exponentPart(c1: Char, c2: Char) = - (c1 == 'e' || c1 == 'E') && - ((c2 >= '0' && c2 <= '9') || (c2 == '+' || c2 == '-')) ; - - /** see Java spec 3.10.2 */ - def floatTypeSuffix(c1: Char) = - (c1 == 'f' || c1 == 'F' || - c1 == 'd' || c1 == 'D'); - - /** read a number into name and set base - */ - protected def getNumber:unit = { - import SourceRepresentation.digit2int; - while (digit2int(ch, if (base == 8) 10 else base) >= 0) { - putChar( ch ); - nextch(); - } - if (base <= 10 && ch == '.') { // '.' c1 c2 - val c1 = srcIterator.lookahead1; - if (c1 >= '0' && c1 <= '9') { - putChar(ch); - nextch(); - getFraction; - } - else { - val c2 = srcIterator.lookahead2; - if (exponentPart(c1,c2)) { - putChar(ch);// + - getFraction; - return; - } - if (isIdentStart(c1)&&isIdentPart(c2)) { // is select - name = Name.fromString( cbuf.toString() ); - cbuf.setLength( 0 ); - token = INTLIT; - return; - } - else { - putChar(ch); - nextch(); - getFraction; - } - } - } else if (base <= 10 && - (ch == 'e' || ch == 'E' || - ch == 'f' || ch == 'F' || - ch == 'd' || ch == 'D')) { - getFraction; - } - else { - if (ch == 'l' || ch == 'L') { - name = Name.fromString(cbuf.toString()); - cbuf.setLength(0); - nextch(); - token = LONGLIT; - } else { - name = Name.fromString(cbuf.toString()); - cbuf.setLength(0); - token = INTLIT; - } - } - } - - // start XML tokenizing methods - // prod. [i] refers to productions in http://www.w3.org/TR/REC-xml - - /** calls nextToken, starting the scanning of Scala tokens, - * after XML tokens. - */ - def xSync = { - token = SEMI; // avoid getting SEMI from nextToken if last was RBRACE - //nextch(); - nextToken(); - } - - def xSync2 = fetchToken(); - - def xLookahead = srcIterator.lookahead1; - - /** read the next character. do not skip whitespace. - * treat CR LF as single LF. update ccol and cline - * - * @todo: may XML contain SU, in CDATA sections ? - */ - def xNext = { - lastpos = pos; - ch = srcIterator.raw; ccol = ccol + 1; // = nextch() without unicode - ch match { - case SU => - //syntaxError( lastpos, "missing end tag in XML literal" ); - token = EOF; - case LF => - ccol = 0; cline = cline + 1; - case CR => - if( LF == srcIterator.lookahead1 ) { - srcIterator.raw; ccol = 0; cline = cline + 1; - } - case _ => - //Console.print(ch.asInstanceOf[Char]); // DEBUG - } - pos = Position.encode(cline, ccol); - //Console.print(ch); - } - - /* OBSOLETE - final val LT = Name.fromString("<"); - - def xStartsXML = { - /* unit.global.xmlMarkup && */ ( token == IDENTIFIER ) &&( name == LT ); - /* || // support for proc instr, cdata, comment... ? - {val s = name.toString(); - s.charAt(0) == '<' && (s.charAt(1)=='?' || s.charAt(1)=='!')}) */ - } - */ - // end XML tokenizing - - - override def toString() = token match { - case IDENTIFIER => - "id(" + name + ")" - case CHARLIT => - "char(" + intVal + ")" - case INTLIT => - "int(" + intVal + ")" - case LONGLIT => - "long(" + intVal + ")" - case FLOATLIT => - "float(" + floatVal + ")" - case DOUBLELIT => - "double(" + floatVal + ")" - case STRINGLIT => - "string(" + name + ")" - case SEMI => - ";" - case COMMA => - "," - case _ => - token2string(token) - } - -} - -} // package - diff --git a/sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala b/sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala deleted file mode 100644 index 8a76eeaa59..0000000000 --- a/sources/scala/tools/scalac/ast/parser/SymbolicXMLBuilder.scala +++ /dev/null @@ -1,673 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.ast._; -import scalac.atree.AConstant; -import scalac._; -import scalac.symtab.Modifiers; -import scala.tools.util.Position; -import java.lang.{Integer, Long, Float, Double}; -import scala.Iterator; -import scala.tools.scalac.util.NewArray; -import scala.collection.immutable.{ Map, ListMap }; -import scala.collection.mutable; -import scala.xml.{Text,TextBuffer}; -import scalac.util.{ Name, Names, TypeNames } ; - -package scala.tools.scalac.ast.parser { - -/** this class builds instance of Tree that represent XML */ -class SymbolicXMLBuilder(make: TreeFactory, gen: TreeGen, p: Parser, preserveWS: Boolean ) { - - import scala.tools.scalac.ast.{TreeList => myTreeList} - - var isPattern:Boolean = _; - - val _ArrayBuffer = Name.fromString("ArrayBuffer"); - val _Attribute = Name.fromString("Attribute"); - val _MetaData = Name.fromString("MetaData"); - val _NamespaceBinding = Name.fromString("NamespaceBinding"); - val _NodeBuffer = Name.fromString("NodeBuffer"); - val _NoAttributes = Name.fromString("NoAttributes"); - - val _Null = Name.fromString("Null"); - - val _PrefixedAttribute = Name.fromString("PrefixedAttribute"); - val _UnprefixedAttribute = Name.fromString("UnprefixedAttribute"); - val _TreeMap = Name.fromString("TreeMap"); - val _Elem = Name.fromString("Elem"); - val _Seq = Name.fromString("Seq"); - val _String = Name.fromString("String"); - val _immutable = Name.fromString("immutable"); - val _mutable = Name.fromString("mutable"); - val _append = Name.fromString("append"); - val _plus = Name.fromString("$amp$plus"); - val _collection = Name.fromString("collection"); - val _toList = Name.fromString("toList"); - val _xml = Name.fromString("xml"); - val _Comment = Name.fromString("Comment"); - val _CharData = Name.fromString("CharData"); - val _Node = Name.fromString("Node"); - val _None = Name.fromString("None"); - val _Some = Name.fromString("Some"); - val _ProcInstr = Name.fromString("ProcInstr"); - val _Text = Name.fromString("Text"); - val _EntityRef = Name.fromString("EntityRef"); - - // convenience methods - private def _scala( pos: int, name: Name ) = - make.Select( pos, make.Ident( pos, Names.scala ), name ); - - private def _scala_Seq( pos: int ) = - p.convertToTypeId( _scala( pos, _Seq )); - - - private def _scala_None( pos: int ) = - _scala( pos, _None ) ; - - private def _scala_Some(pos: int) = - p.convertToConstr(_scala(pos, _Some)); - - - private def _string(pos: int) = - p.convertToTypeId(make.Ident(pos, _String)); - - private def _scala_xml(pos: int, name: Name) = - make.Select( pos, _scala(pos, _xml), name ); - - private def _scala_xml_MetaData(pos: int) = - p.convertToTypeId(_scala_xml( pos, _MetaData )); - - private def _scala_xml_NamespaceBinding( pos: int ) = - p.convertToTypeId(_scala_xml( pos, _NamespaceBinding )); - - private def _scala_xml_Null( pos: int ) = - _scala_xml( pos, _Null ); - - private def _scala_xml_PrefixedAttribute( pos: int ) = - p.convertToConstr( _scala_xml( pos, _PrefixedAttribute )); - - private def _scala_xml_UnprefixedAttribute( pos: int ) = - p.convertToConstr( _scala_xml( pos, _UnprefixedAttribute )); - - private def _scala_xml_Node( pos: int ) = - _scala_xml( pos, _Node ); - - private def _scala_xml_Node_NoAttributes( pos: int ) = - make.Select( pos, _scala_xml( pos, _Node ), _NoAttributes ); - - private def _scala_xml_NodeBuffer( pos: int ) = - p.convertToConstr( _scala_xml( pos, _NodeBuffer )); - - private def _scala_xml_EntityRef( pos: int ) = - p.convertToConstr( _scala_xml( pos, _EntityRef )); - - private def _scala_xml_Comment( pos: int ) = - p.convertToConstr( _scala_xml( pos, _Comment )); - - private def _scala_xml_CharData( pos: int ) = - p.convertToConstr( _scala_xml( pos, _CharData )); - - private def _scala_xml_ProcInstr( pos: int ) = - p.convertToConstr( _scala_xml( pos, _ProcInstr )); - - private def _scala_xml_Text(pos: int) = - _scala_xml( pos, _Text ); - - - private def _scala_collection(pos: int, name: Name) = - make.Select( pos, _scala( pos, _collection ), name ); - - private def _scala_collection_mutable(pos: int, name: Name) = - make.Select(pos, _scala_collection(pos, _mutable ), name); - - private def _scala_collection_immutable(pos: int, name: Name) = - make.Select(pos, _scala_collection(pos, _immutable), name); - - private def _scala_collection_mutable_ArrayBuffer(pos: int) = - make.Apply( pos, - make.AppliedType(pos, - p.convertToConstr( - _scala_collection_mutable(pos, _ArrayBuffer )), - Predef.Array[Tree]( - convertToTypeId( - _scala_xml_Node(pos) )) - ), - Tree.EMPTY_ARRAY ); - - private def _scala_collection_immutable_TreeMap(pos: int) = - make.Apply( pos, - make.AppliedType(pos, - p.convertToConstr( - _scala_collection_immutable(pos, _TreeMap )), - Predef.Array[Tree]( - _string( pos ), - _string( pos ) - ) - ), - Tree.EMPTY_ARRAY ); - - private def _emptyMap(pos: Int) = { - make.New( pos,_scala_collection_immutable_TreeMap( pos: int )); - } - - private def _scala_Tuple2(pos: Int) = - _scala( pos, Names.Tuple2 ); - - private def _scala_xml_Elem(pos: Int) = - _scala_xml( pos, _Elem ); - - private def _scala_xml_Attribute(pos: Int) = - _scala_xml( pos, _Attribute ); - - - private def bufferToArray(buf: mutable.Buffer[Tree]): Array[Tree] = { - val arr = new Array[Tree]( buf.length ); - var i = 0; - for (val x <- buf.elements) { arr(i) = x; i = i + 1; } - arr; - } - - /** convenience method */ - def convertToTypeId(t: Tree): Tree = t match { - case Tree$Ident(name) => - make.Ident(t.pos, name.toTypeName()) - case Tree$Select(qual, name) => - make.Select(t.pos, qual, name.toTypeName()) - case _ => - t - } - - // create scala xml tree - - /** - * @arg namespace: a Tree of type defs.STRING_TYPE - * @arg label: a Tree of type defs.STRING_TYPE - * @todo map: a map of attributes !!! - */ - - protected def mkXML(pos: int, isPattern: boolean, pre: Tree, label: Tree, attrs: /*Array[*/Tree/*]*/ , scope:Tree, children: mutable.Buffer[Tree]): Tree = { - if( isPattern ) { - val ts = new mutable.ArrayBuffer[Tree](); - ts.append( pre ); - ts.append( label ); - ts.append( new Tree$Ident( Names.PATTERN_WILDCARD ) ); // attributes? - ts.append( new Tree$Ident( Names.PATTERN_WILDCARD ) ); // scope? - convertToTextPat( children ); - ts ++ children; - make.Apply(pos, - convertToTypeId( _scala_xml_Elem( pos ) ), - bufferToArray( ts )) - } else { - val ab = new scala.collection.mutable.ArrayBuffer[Tree](); - ab + pre; - ab + label; - ab + attrs; - ab + scope; - - /* - if(( attrs.length ) == 0 ) - ab + _scala_xml_Node_NoAttributes( pos ) - else - ab + make.Apply(pos, - make.Select( pos, - _scala_xml_Node_NoAttributes( pos ), - Names.PERCENT ), - attrs); - */ - if(( children.length ) > 0 ) - ab + make.Typed(pos, - makeXMLseq( pos, children ), - make.Ident(pos, TypeNames.WILDCARD_STAR)); - val arr:Array[Tree] = new Array[Tree]( ab.length ); - ab.elements.copyToArray( arr, 0 ); - make.Apply( pos, _scala_xml_Elem( pos ), arr ) - } - } - - final def entityRef( pos:int, n: String ) = { - val constr = make.Apply( pos, - _scala_xml_EntityRef( pos ), - Predef.Array[Tree]( gen.mkStringLit( pos, n ))); - - make.New( pos, constr ); - }; - // create scala.xml.Text here <: scala.xml.Node - final def text( pos: int, txt:String ):Tree = { - //makeText( pos, isPattern, gen.mkStringLit( pos, txt )); - val txt1 = gen.mkStringLit( pos, txt ); - if( isPattern ) - makeTextPat( pos, txt1 ); - else - makeText1( pos, txt1 ); - } - - // create scala.xml.Text here <: scala.xml.Node -/* - protected def makeText( pos: int, isPattern:Boolean, txt:Tree ):Tree = { - if( isPattern ) - makeTextPat( pos, txt ); - else - makeText1( pos, txt ); - } -*/ - // create scala.xml.Text here <: scala.xml.Node - def makeTextPat( pos: int, txt:Tree ):Tree = { - return make.Apply(pos, - p.convertToConstr( _scala_xml_Text( pos ) ), - Predef.Array[Tree]( txt )); - } - - def makeText1( pos: int, txt:Tree ):Tree = { - val constr = make.Apply(pos, - p.convertToConstr( _scala_xml_Text( pos )), - Predef.Array[Tree]( txt )); - make.New( pos, constr ); - } - - // code to create attribute - /* - scala.xml.Attribute(uri, "key", [value]) - */ - - def makeAttribute( pos: int, ns:String, key:String, value:Tree ):Tree = - make.Apply(pos, - _scala_xml_Attribute(pos), - Predef.Array[Tree] ( - make.Ident( pos, Name.fromString( ns )), - gen.mkStringLit( pos, key ), - value - ) - ); - - // create - def comment( pos: int, text: String ):Tree = - Comment( pos, gen.mkStringLit( pos, text )); - - // create - def charData( pos: int, txt: String ):Tree = - CharData( pos, gen.mkStringLit( pos, txt )); - - // create scala.xml.Text here <: scala.xml.Node - def procInstr( pos: int, target: String, txt: String ):Tree = - ProcInstr(pos, - gen.mkStringLit( pos, target ), - gen.mkStringLit( pos, txt )); - - def makeNone( pos: int ):Tree = _scala_None( pos ); - - def makeSome( pos: int, txt:Tree ):Tree = { - val constr = make.Apply( pos, - _scala_Some( pos ), - Predef.Array[Tree] ( txt )); - make.New( pos, constr ); - } - - def makeNodeBuffer(pos: int): Tree = { - val constr = make.Apply( pos, - _scala_xml_NodeBuffer( pos ), - Tree.EMPTY_ARRAY); - make.New( pos, constr ); - } - - protected def CharData(pos: int, txt: Tree):Tree = { - val constr = make.Apply( pos, - _scala_xml_CharData( pos ), - Predef.Array[Tree] ( txt )); - make.New( pos, constr ); - } - - protected def Comment(pos: int, txt: Tree):Tree = { - val constr = make.Apply( pos, - _scala_xml_Comment( pos ), - Predef.Array[Tree] ( txt )); - make.New( pos, constr ); - } - - protected def ProcInstr(pos: int, target: Tree, txt: Tree): Tree = { - val constr = make.Apply( pos, - _scala_xml_ProcInstr( pos ), - Predef.Array[Tree] ( target, txt )); - make.New( pos, constr ); - } - - /** @todo: attributes */ - def makeXMLpat(pos: int, n: String, args: mutable.Buffer[Tree]): Tree = - mkXML(pos, - true, - new Tree$Ident( Names.PATTERN_WILDCARD ):Tree, - gen.mkStringLit( pos, n ):Tree, - null, //Predef.Array[Tree](), - null, - args); - - protected def convertToTextPat(t: Tree): Tree = t match { - case _:Tree$Literal => makeTextPat(t.pos, t); - case _ => t - } - - protected def convertToTextPat(buf: mutable.Buffer[Tree]): Unit = { - var i = 0; while( i < buf.length ) { - val t1 = buf( i ); - val t2 = convertToTextPat( t1 ); - if (!t1.eq(t2)) { - buf.remove(i); - buf.insert(i,t2); - } - i = i + 1; - } - } - - def isEmptyText(t:Tree) = t match { - case Tree$Literal(atree.AConstant.STRING("")) => true; - case _ => false; - } - def makeXMLseq( pos:int, args:mutable.Buffer[Tree] ) = { - val ts = new TreeList(); - //val blocArr = new Array[Tree] ( 1 + args.length ); - //val constr = _scala_collection_mutable_ArrayBuffer( pos ); - var _buffer = makeNodeBuffer( pos ); - val n = p.fresh(); - val nIdent = make.Ident(pos, n); - //blocArr( 0 ) - ts.append( make.ValDef(pos, - 0, n, Tree.Empty, - _buffer)); - - val it = args.elements; - while( it.hasNext ) { - val t = it.next; - val tpos = t.pos; - if( !isEmptyText( t )) { - _buffer = make.Apply( tpos, - make.Select( tpos, _buffer, _plus ), - Predef.Array[Tree]( t )); - } - } - - _buffer = make.Select( pos, _buffer, _toList ); - - _buffer; - } - - def makeXMLseqPat( pos:int, args:Array[Tree] ) = { - make.Apply( pos, _scala_Seq( pos ), args ); - } - - - - /** returns Some(prefix) if pre:name, None otherwise */ - def getPrefix( name:String ):Option[String] = { - val i = name.indexOf(':'); - if( i != -1 ) Some( name.substring(0, i) ) else None - } - - /** splits */ - protected def qualifiedAttr( pos:Int, namespace:String, name:String ):Pair[String,String] = { - getPrefix( name ) match { - case Some( pref ) => - val newLabel = name.substring( pref.length()+1, name.length() ); - // if( newLabel.indexOf(':') != -1 ) syntaxError - Pair( "namespace$"+pref, newLabel ); - case None => - Pair( namespace, name ); - } - } - protected def qualified( pos:Int, name:String ):Pair[String,String] = - getPrefix( name ) match { - case Some( pref ) => - val newLabel = name.substring( pref.length()+1, name.length() ); - // if( newLabel.indexOf(':') != -1 ) syntaxError - Pair( "namespace$"+pref, newLabel ); - case None => - Pair( "namespace$default", name ); - } - - final val _md = Name.fromString("$md"); - final val _scope = Name.fromString("$scope"); - final val _tmpscope = Name.fromString("$tmpscope"); - - /** makes an element */ - def element(pos: int, qname: String, attrMap: mutable.Map[String,Tree], args: mutable.Buffer[Tree]): Tree = { - //Console.println("SymbolicXMLBuilder::element("+pos+","+qname+","+attrMap+","+args+")"); - var setNS = new mutable.HashMap[String, Tree]; - - val tlist = new myTreeList(); - val tlist2 = new myTreeList(); - - def handleNamespaceBinding(pre:String, uri:Tree): Unit = { - val t = make.Assign(pos, - make.Ident(pos, _tmpscope), - make.New(pos, - make.Apply( - pos, - p.convertToConstr(_scala_xml( pos, _NamespaceBinding )), - Predef.Array[Tree]( - {if(pre==null) - gen.mkNullLit(pos) - else - gen.mkStringLit(pos, pre)} , - uri, - make.Ident(pos, _tmpscope))) - ) - ); - tlist.append( t ); - //Console.println("SymbolicXMLBuilder::handleNamespaceBinding:"); - //Console.println(t.toString()); - - } - - /* DEBUG */ - val attrIt = attrMap.keys; - while( attrIt.hasNext ) { - val z = attrIt.next; - if( z.startsWith("xmlns") ) { // handle namespace - val i = z.indexOf(':'); - if( i == -1 ) - handleNamespaceBinding(null, attrMap( z )); - //setNS.update("default", attrMap( z ) ); - else { - val zz = z.substring( i+1, z.length() ); - //setNS.update( zz, attrMap( z ) ); - handleNamespaceBinding(zz, attrMap( z )); - } - attrMap -= z; - } - } - - val moreNamespaces = (0 < tlist.length()); - - /* */ - val i = qname.indexOf(':'); - - var newlabel = qname; - val pre = getPrefix(qname) match { - case Some(p) => - newlabel = qname.substring(p.length()+1, qname.length()); - p; - case None => - null - } - //val Pair( pre, newlabel ) = qualified( pos, label ); - //Console.println("SymbolicXMLBuilder::(489) "+pre); - - // make attributes - - def handlePrefixedAttribute(pre:String, key:String, value:Tree): Unit = { - val t = - make.Assign(pos, - make.Ident(pos, _md), - make.New(pos, - make.Apply(pos, - _scala_xml_PrefixedAttribute(pos), - Predef.Array[Tree]( - gen.mkStringLit(pos,pre), - gen.mkStringLit(pos,key), - value, - make.Ident(pos, _md) - ) - ) - ) - ); - tlist2.append( t ); - // Console.println("SymbolicXMLBuilder::handlePrefixed :"); - // Console.println(t.toString()); - } - - def handleUnprefixedAttribute(key:String, value:Tree): Unit = { - val t = make.Assign(pos, - make.Ident(pos, _md), - make.New(pos, - make.Apply(pos, - _scala_xml_UnprefixedAttribute(pos), - Predef.Array[Tree]( - gen.mkStringLit(pos,key), - value, - make.Ident(pos, _md) - ) - ) - ) - ); - tlist2.append(t); - //Console.println("SymbolicXMLBuilder::handlePrefixed :"); - //Console.println(t.toString()); - - } - - //var attr:Array[Tree] = - // if( attrMap.isEmpty ) - // Tree.EMPTY_ARRAY ; //gen.mkNullLit(pos); // - // else { - // val attrs:Array[Tree] = new Array[Tree](attrMap.size); - /* DEBUG */ - // var k = 0; - var it = attrMap.elements; - while (it.hasNext) { - val ansk = it.next; - - getPrefix(ansk._1) match { - case Some(pre) => - val key = ansk._1.substring(pre.length()+1, ansk._1.length()); - handlePrefixedAttribute(pre, key, ansk._2); - case None => - handleUnprefixedAttribute(ansk._1, ansk._2); - } - //val Pair( ns, aname ) = qualifiedAttr( pos, namespace, ansk._1 ); - //attrs( k ) = makeAttribute( pos, ns, aname, ansk._2 ); - //k = k + 1; - } - /* */ - // attrs - - // } - - val moreAttributes = (0 < tlist2.length()); - - val ts = new mutable.ArrayBuffer[Tree](); - - if (moreNamespaces) { - ts + make.ValDef(pos, - Modifiers.MUTABLE, - _tmpscope, - _scala_xml_NamespaceBinding(pos), - make.Ident(pos, _scope)); - ts ++ tlist; - } - - //Console.println("printing ts"); - //for(val t <- ts) - // Console.println(t.toString()); - - val ts2 = new mutable.ArrayBuffer[Tree](); - - if(moreNamespaces) { - ts2 + make.ValDef(pos, 0, _scope, Tree.Empty, make.Ident(pos, _tmpscope)); - } - if(moreAttributes) { - ts2 + make.ValDef(pos, - Modifiers.MUTABLE, - _md, - _scala_xml_MetaData(pos), - _scala_xml_Null(pos)); - ts2 ++ tlist2; - } - //Console.println("printing ts2"); - //for(val t <- ts2) - // Console.println(t.toString()); - - val stms:Array[Tree] = new Array[Tree]( ts.length ); - ts.elements.copyToArray( stms, 0 ); - - val stms2:Array[Tree] = new Array[Tree]( ts2.length ); - ts2.elements.copyToArray( stms2, 0 ); - - val makeSymbolicPrefix = { - if (null == pre) - gen.mkNullLit(pos) - else - gen.mkStringLit(pos,pre) - } - - val makeSymbolicAttrs = { - if (moreAttributes) - make.Ident(pos, _md) //attr:Array[Tree], - else - _scala_xml_Null(pos) - } - - var t = mkXML(pos, - false, - makeSymbolicPrefix, - gen.mkStringLit(pos, newlabel):Tree, - makeSymbolicAttrs, - make.Ident(pos, _scope), - args); - /* - Console.println("printing _pre"); - Console.println({if(null == pre) "null" else pre.toString()}); - Console.println("printing newlabel"); - Console.println(newlabel.toString()); - Console.println("printing _scope"); - Console.println(_scope.toString()); - Console.println("printing t"); - Console.println(t.toString()); - */ - - if (0 < stms2.length) { - t = make.Block(pos, stms2, t); - } - ; - if (0 < stms.length) { - t = make.Block(pos, stms, t); - } - ; - //Console.println("SymbolicXMLBuilder::element returns :"); - //Console.println(res.toString()); - - t - /* DEBUG - if (! setNS.isEmpty) { - val nsStms = new Array[Tree](setNS.size); - var i = 0; - for (val Pair(ns:String, uri:Tree) <- setNS.toList) { - nsStms( i ) = setNamespacePrefix(pos, ns, uri ); - i = i + 1; - } - make.Block( pos, nsStms, t ) - } else { - t - } */ - - } - - def setNamespacePrefix(pos:Int, pref:String, uri:Tree) = - make.ValDef(pos, 0, Name.fromString("namespace$"+pref), Tree.Empty, uri); - -} - -} // package diff --git a/sources/scala/tools/scalac/ast/parser/TokenData.scala b/sources/scala/tools/scalac/ast/parser/TokenData.scala deleted file mode 100644 index 43f11e18de..0000000000 --- a/sources/scala/tools/scalac/ast/parser/TokenData.scala +++ /dev/null @@ -1,45 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -import scalac.util.Name; - -package scala.tools.scalac.ast.parser { - -/** A class for representing a token's data. - * - * @author Matthias Zenger - * @version 1.0 - */ -class TokenData { - - import Tokens._; - - /** the next token - */ - var token: int = EMPTY; - - /** the token's position. pos = line << Position.LINESHIFT + col - */ - var pos: int = 0; - - /** the name of an identifier or token - */ - var name: Name = null; - - /** the base of a number - */ - var base: int = 0; - - def copyFrom(td: TokenData) = { - this.token = td.token; - this.pos = td.pos; - this.name = td.name; - this.base = td.base; - } -} -} diff --git a/sources/scala/tools/scalac/ast/parser/Tokens.scala b/sources/scala/tools/scalac/ast/parser/Tokens.scala deleted file mode 100644 index a01f093c94..0000000000 --- a/sources/scala/tools/scalac/ast/parser/Tokens.scala +++ /dev/null @@ -1,240 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -import scalac.util.Name; - -package scala.tools.scalac.ast.parser { - -object Tokens { - - /** The token names */ - private var tokenName = new Array[Name](128); - private var numToken = 0; - - /** Keyword array; maps from name indices to tokens */ - private var key: Array[byte] = _; - private var maxKey = 0; - - /** special tokens */ - val EMPTY = -3; - val UNDEF = -2; - val ERROR = -1; - val EOF = 0; - - /** literals */ - val CHARLIT = 1; - val INTLIT = 2; - val LONGLIT = 3; - val FLOATLIT = 4; - val DOUBLELIT = 5; - val STRINGLIT = 6; - val SYMBOLLIT = 7; - - /** identifier */ - val IDENTIFIER = 10; - - /** keywords */ - val IF = 20; - val FOR = 21; - val ELSE = 22; - val THIS = 23; - val NULL = 24; - val NEW = 25; - val WITH = 26; - val SUPER = 27; - val CASE = 28; - val CASECLASS = 29; - val CASEOBJECT = 30; - val VAL = 31; - val ABSTRACT = 32; - val FINAL = 33; - val PRIVATE = 34; - val PROTECTED = 35; - val OVERRIDE = 36; - val VAR = 37; - val DEF = 38; - val TYPE = 39; - val EXTENDS = 40; - val TRUE = 41; - val FALSE = 42; - val OBJECT = 43; - val CLASS = 44; - val IMPLICIT = 45; - - val IMPORT = 46; - val PACKAGE = 47; - val YIELD = 48; - val DO = 49; - val TRAIT = 50; - val SEALED = 51; - val THROW = 52; - val TRY = 53; - val CATCH = 54; - val FINALLY = 55; - val WHILE = 56; - val RETURN = 57; - - /** special symbols */ - val COMMA = 61; - val SEMI = 62; - val DOT = 63; - val USCORE = 64; - val COLON = 65; - val EQUALS = 66; - val LARROW = 67; - val ARROW = 68; - val SUBTYPE = 69; - val SUPERTYPE = 70; - val HASH = 71; - val AT = 72; - val VIEWBOUND = 73; - - /** parenthesis */ - val LPAREN = 90; - val RPAREN = 91; - val LBRACKET = 92; - val RBRACKET = 93; - val LBRACE = 94; - val RBRACE = 95; - - /** XML mode */ - val XMLSTART = 96; - - /** Returns true if argument corresponds to a keyword. */ - def isKeyword(str: String) = Name.fromString(str).index <= maxKey; - - /** Returns the token corresponding to given name. */ - def name2token(name: Name): int = - if (name.index <= maxKey) key(name.index) else IDENTIFIER; - - /** Returns the string representation of given token. */ - def token2string(token: int): String = token match { - case IDENTIFIER => - "identifier"/* + \""+name+"\""*/ - case CHARLIT => - "character literal" - case INTLIT => - "integer literal" - case LONGLIT => - "long literal" - case FLOATLIT => - "float literal" - case DOUBLELIT => - "double literal" - case STRINGLIT => - "string literal" - case SYMBOLLIT => - "symbol literal" - case LPAREN => - "'('" - case RPAREN => - "')'" - case LBRACE => - "'{'" - case RBRACE => - "'}'" - case LBRACKET => - "'['" - case RBRACKET => - "']'" - case EOF => - "eof" - case ERROR => - "something" - case SEMI => - "';'" - case COMMA => - "','" - case CASECLASS => - "case class" - case CASEOBJECT => - "case object" - case XMLSTART => - "$XML<" - case _ => - try { - "'" + tokenName(token).toString() + "'" - } catch { - case _: ArrayIndexOutOfBoundsException => - "'<" + token + ">'" - case _: NullPointerException => - "'<(" + token + ")>'" - } - } - - // Enter keywords - enterKeyword("abstract", ABSTRACT); - enterKeyword("case", CASE); - enterKeyword("class", CLASS); - enterKeyword("catch", CATCH); - enterKeyword("def", DEF); - enterKeyword("do", DO); - enterKeyword("else", ELSE); - enterKeyword("extends", EXTENDS); - enterKeyword("false", FALSE); - enterKeyword("final", FINAL); - enterKeyword("finally", FINALLY); - enterKeyword("for", FOR); - enterKeyword("if", IF); - enterKeyword("implicit", IMPLICIT); - enterKeyword("import", IMPORT); - enterKeyword("new", NEW); - enterKeyword("null", NULL); - enterKeyword("object", OBJECT); - enterKeyword("override", OVERRIDE); - enterKeyword("package", PACKAGE); - enterKeyword("private", PRIVATE); - enterKeyword("protected", PROTECTED); - enterKeyword("return", RETURN); - enterKeyword("sealed", SEALED); - enterKeyword("super", SUPER); - enterKeyword("this", THIS); - enterKeyword("throw", THROW); - enterKeyword("trait", TRAIT); - enterKeyword("true", TRUE); - enterKeyword("try", TRY); - enterKeyword("type", TYPE); - enterKeyword("val", VAL); - enterKeyword("var", VAR); - enterKeyword("with", WITH); - enterKeyword("while", WHILE); - enterKeyword("yield", YIELD); - enterKeyword(".", DOT); - enterKeyword("_", USCORE); - enterKeyword(":", COLON); - enterKeyword("=", EQUALS); - enterKeyword("=>", ARROW); - enterKeyword("<-", LARROW); - enterKeyword("<:", SUBTYPE); - enterKeyword(">:", SUPERTYPE); - enterKeyword("<%", VIEWBOUND); - enterKeyword("#", HASH); - enterKeyword("@", AT); - - // Build keyword array - key = new Array[byte](maxKey+1); - for (val i <- Iterator.range(0, maxKey)) - key(i) = IDENTIFIER; - for (val j <- Iterator.range(0, numToken)) - if (tokenName(j) != null) key(tokenName(j).index) = j.asInstanceOf[byte]; - - private def enterKeyword(s: String, tokenId: int) = { - while (tokenId > tokenName.length) { - val newTokName = new Array[Name](tokenName.length * 2); - System.arraycopy(tokenName, 0, newTokName, 0, newTokName.length); - tokenName = newTokName; - } - val n = Name.fromString(s); - tokenName(tokenId) = n; - if (n.index > maxKey) maxKey = n.index; - if (tokenId >= numToken) numToken = tokenId + 1; - } - -} - -} diff --git a/sources/scala/tools/scalac/ast/printer/HTMLPrinter.scala b/sources/scala/tools/scalac/ast/printer/HTMLPrinter.scala deleted file mode 100644 index fd63b075c6..0000000000 --- a/sources/scala/tools/scalac/ast/printer/HTMLPrinter.scala +++ /dev/null @@ -1,171 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -import scalac.CompilationUnit; -import scalac.symtab._; -import scalac.ast.Tree; -import scalac.{Global => scalac_Global, Phase}; - -package scala.tools.scalac.ast.printer { - - -import java.io.OutputStream; -import java.io.PrintWriter; -import java.lang.Math; -import java.util.HashMap; - -/** - * HTML pretty printer for Scala abstract syntax trees. - * - * @author Michel Schinz - * @version 1.0 - */ - -class HTMLTreePrinter(global0: scalac_Global, out0: PrintWriter) - extends TextTreePrinter(global0, out0) -{ - protected var outSectionLevel = 1; - protected var started = false; - - override def begin(): Unit = { - assert(!started); - - super.begin(); - out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); - out.println("<html>"); - out.println("<head>"); - out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">"); - out.println("<link rel=\"stylesheet\" href=\"scala.css\" type=\"text/css\">"); - out.println("<title>Scala tree</title>"); - out.println("</head>"); - out.println("<body>"); - - started = true; - } - - override def end(): Unit = { - assert(started); - - out.println("</body>"); - out.println("</html>"); - super.end(); - - started = false; - } - - override def beginSection(level: Int, title: String) = { - outSectionLevel = Math.min(level, 4); - beginSection1(outSectionLevel, title); - } - - protected def beginSection1(level: Int, title: String): Unit = { - if (level == 1) - out.println("<hr/>"); - val tag: String = "h" + level; - startTag(tag); - print(Simple(title)); - endTag(tag); - } - - protected def startTag(tag: String): Unit = { - out.print('<'); out.print(tag); out.print('>'); - } - - protected def startTag(tag: String, attr1: String, val1: String): Unit = { - out.print('<'); - out.print(tag); - out.print(' '); - out.print(attr1); - out.print("=\""); - out.print(val1); - out.print("\">"); - } - - protected def endTag(tag: String): Unit = { - out.print("</"); out.print(tag); out.print(">"); - } - - protected def startSpan(cls: String): Unit = { - startTag("span", "class", cls); - } - - protected def endSpan(): Unit = { - endTag("span"); - } - - override protected def printString(str: String): Unit = { - for (val i <- Iterator.range(0, str.length())) { - val c = str.charAt(i); - val entity: String = c match { - case '<' => "lt"; - case '>' => "gt"; - case '&' => "amp"; - case _ => null - } - if (entity != null) { - out.print('&'); - out.print(entity); - out.print(';'); - } else { - out.print(c); - } - } - } - - protected val symAnchors = new HashMap/*<Symbol,Integer>*/(); - - protected def symbolAnchor(sym: Symbol, usage: SymbolUsage): String = { - var anchorId = symAnchors.get(sym).asInstanceOf[Integer]; - if (anchorId == null) { - anchorId = new Integer(symAnchors.size()); - symAnchors.put(sym, anchorId); - } - if (usage == Definition) - return anchorId.toString(); - else - return "#" + anchorId.toString(); - } - - override protected def print(text: Text): Unit = text match { - case Keyword(name) => - startSpan("kw"); - printString(name); - endSpan(); - case Literal(str) => - startSpan("lit"); - printString(str); - endSpan(); - case Identifier(symbol, name, usage) => - val defined = (usage == Definition); - if (defined) startSpan("idDef"); - if (symbol != null) { - val attr = if (defined) "name" else "href"; - startTag("a", attr, symbolAnchor(symbol, usage)); - if (usage == Use) - printString(symbol.simpleName().toString()); - else - printString(symbol.name.toString()); - endTag("a"); - } else - printString(name.toString()); - if (defined) endSpan(); - case _ => - super.print(text); - } - - override def printUnitHeader(unit: CompilationUnit): Unit = { - beginSection1(outSectionLevel + 1, unit.source.toString()); - startTag("pre"); - } - - override def printUnitFooter(unit: CompilationUnit): Unit = { - endTag("pre"); - } -} -} diff --git a/sources/scala/tools/scalac/ast/printer/SwingPrinter.scala b/sources/scala/tools/scalac/ast/printer/SwingPrinter.scala deleted file mode 100644 index 57cb7ee2db..0000000000 --- a/sources/scala/tools/scalac/ast/printer/SwingPrinter.scala +++ /dev/null @@ -1,264 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - - -import scalac.CompilationUnit; -import scalac.symtab._; -import scalac.ast.Tree; -import scalac.ast.printer._; - -import scalac.{Global => scalac_Global, Phase}; -import scalac.CompilationUnit; -import scalac.util.Name; -import scalac.util.TypeNames; - -import scala.concurrent._; - -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.HashMap; - -import javax.swing.tree._; -import javax.swing.event.TreeModelListener; -import javax.swing._; - -import java.awt.{List => awtList, _}; -import java.awt.event._; - -package scala.tools.scalac.ast.printer { - -/** - * Java Swing pretty printer for Scala abstract syntax trees. - * - * @author Iulian Dragos - * @version 0.2 - */ -class SwingTreePrinter(global0: scalac_Global) extends TreePrinter { - val global = global0; - - def begin() = (); - def end() = (); - def flush() = (); - - - /** print the whole program */ - def print(units: Array[CompilationUnit]): Unit = { - val phase: Phase = global.currentPhase; - - val tm = new ASTTreeModel(); - - for (val i <- Iterator.range(0, units.length)) - tm.addUnit(units(i)); - - val frame = new WindowFrame(); - frame.setTreeModel(tm); - - val lock = new Lock(); - frame.createFrame(lock); - - // wait for the frame to be closed - lock.acquire; - } - - def print(tree: Tree): Unit = (); - -} - -/** Tree model for abstract syntax trees */ -class ASTTreeModel extends TreeModel { - var listeners: List[TreeModelListener] = Nil; - var units: List[CompilationUnit] = Nil; - - def addUnit(c: CompilationUnit): Unit = units = c :: units; - - /** Add a listener to this tree */ - def addTreeModelListener(l : TreeModelListener): Unit = listeners = l :: listeners; - - /** Return the index'th child of parent */ - def getChild(parent: Any, index: Int): AnyRef = { - packChildren(parent).drop(index).head; - } - - /** Return the number of children this 'parent' has */ - def getChildCount(parent: Any): Int = - packChildren(parent).length; - - /** Return the index of the given child */ - def getIndexOfChild(parent: Any, child: Any): Int = - packChildren(parent).dropWhile(c => c != child).length; - - /** Return the root node */ - def getRoot(): AnyRef = units; - - /** Test whether the given node is a leaf */ - def isLeaf(node: Any): Boolean = packChildren(node).length == 0; - - def removeTreeModelListener(l: TreeModelListener): Unit = - listeners remove (x => x == l); - - /** we ignore this message for now */ - def valueForPathChanged(path: TreePath, newValue: Any) = (); - - /** Return a list of objects for the current node. We have to - * take care of the "top" of the tree, which is not made of case - * classes of Tree. Therefore, instanceOf is used to differentatiate - * between "true" tree nodes, and "logical" ones (CompilationUnit and - * Program). - * - * @todo A type-safe version of this. However, new case classes of Tree - * cannot be derived in Scala because of "final" method getType of - * Tree, which overlaps with scala runtime types. - */ - def packChildren(t: Any): List[AnyRef] = - if (t.isInstanceOf[CompilationUnit]) { - val cu = t.asInstanceOf[CompilationUnit]; - List.fromArray(cu.body) - } else if (t.isInstanceOf[Tree]) - TreeInfo.packTreeChildren(t.asInstanceOf[Tree]); - else if (t.isInstanceOf[List[CompilationUnit]]) - t.asInstanceOf[List[CompilationUnit]]; - else - Nil; - -} - - -/** a window that can host the Tree widget and provide methods for - * displaying information */ -class WindowFrame { - val frame = new JFrame("Scala AST"); - val topPane = new JPanel(new BorderLayout()); - val topRightPane = new JPanel(new BorderLayout()); - val bottomPane = new JPanel(new BorderLayout()); - var splitPane: JSplitPane = _; - var treeModel: TreeModel = _; - - val textArea: JTextArea = new JTextArea(20, 50); - val infoPanel = new InfoPanel(); - - - /** Create a frame that displays the AST. - * - * @param lock The lock is used in order to stop the compilation thread - * until the user is done with the tree inspection. Swing creates its - * own threads when the frame is packed, and therefore execution - * would continue. However, this is not what we want, as the tree and - * especially symbols/types would change while the window is visible. - */ - def createFrame(lock: Lock): Unit = { - lock.acquire; // keep the lock until the user closes the window - - frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - - frame.addWindowListener(new WindowAdapter() { - /** Release the lock, so compilation may resume after the window is closed. */ - override def windowClosed(e: WindowEvent): Unit = lock.release; - }); - - val tree = new JTree(treeModel) { - /** Return the string for a tree node. */ - override def convertValueToText(value: Any, sel: Boolean, - exp: Boolean, leaf: Boolean, - row: Int, hasFocus: Boolean) = { - if (value.isInstanceOf[List[CompilationUnit]]) - "Program" - else if (value.isInstanceOf[CompilationUnit]) - "CompilationUnit" - else { - val Pair(cls, name) = TreeInfo.treeName(value.asInstanceOf[Tree]); - if (name != TreeInfo.NO_NAME) - cls + "[" + name.toString() + "]"; - else - cls; - } - } - } - - tree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() { - def valueChanged(e: javax.swing.event.TreeSelectionEvent): Unit = { - textArea.setText(e.getPath().getLastPathComponent().toString()); - infoPanel.update(e.getPath().getLastPathComponent()); - } - }); - - val topSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, topPane, topRightPane); - topPane.add(new JScrollPane(tree), BorderLayout.CENTER); - - topRightPane.add(new JScrollPane(infoPanel), BorderLayout.CENTER); - - bottomPane.add(new JScrollPane(textArea), BorderLayout.CENTER); - textArea.setFont(new Font("monospaced", Font.PLAIN, 14)); - textArea.setEditable(false); - - splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topSplitPane, bottomPane); - frame.getContentPane().add(splitPane); - frame.pack(); - frame.setVisible(true); - } - - def setTreeModel(tm: TreeModel): Unit = treeModel = tm; -} - -/** Pannel that shows some information about the selected - * tree node (like symbol, type, etc) */ -class InfoPanel extends JPanel() { - val symbolLine = Box.createHorizontalBox(); - val symbolAttLine = Box.createHorizontalBox(); - val symbolTypeLine = Box.createHorizontalBox(); - val treeTypeLine = Box.createHorizontalBox(); - - val symLabel = new JLabel(""); - val attLabel = new JLabel(""); - val stypeLabel = new JLabel(""); - val ttypeLabel = new JLabel(""); - - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - - symbolLine.add(new JLabel("Symbol: ")); - symbolLine.add(symLabel); - symbolLine.add(Box.createHorizontalGlue()); - - symbolAttLine.add(new JLabel("Symbol attributes: ")); - symbolAttLine.add(attLabel); - symbolAttLine.add(Box.createHorizontalGlue()); - - symbolTypeLine.add(new JLabel("Symbol type: ")); - symbolTypeLine.add(stypeLabel); - symbolTypeLine.add(Box.createHorizontalGlue()); - - treeTypeLine.add(new JLabel("Tree type: ")); - treeTypeLine.add(ttypeLabel); - treeTypeLine.add(Box.createHorizontalGlue()); - - add(symbolLine); - add(symbolAttLine); - add(symbolTypeLine); - add(treeTypeLine); - - def update(v: AnyRef): Unit = - if (v.isInstanceOf[Tree]) { - val t = v.asInstanceOf[Tree]; - - symLabel.setText(TreeInfo.symbolText(t)); - stypeLabel.setText(TreeInfo.symbolTypeText(t)); - attLabel.setText(TreeInfo.symbolAttributes(t)); - ttypeLabel.setText(t.getType().toString()); - } else - reset; - - def reset: Unit = { - symLabel.setText(""); - stypeLabel.setText(""); - ttypeLabel.setText(""); - attLabel.setText(""); - } -} - -} // package - diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala deleted file mode 100644 index fc6b66e559..0000000000 --- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala +++ /dev/null @@ -1,1055 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - - -import java.io.PrintWriter; -import java.util.ArrayList; - -import scalac.CompilationUnit; -import scalac.{Global => scalac_Global, Phase}; -import scalac.ast._; -import scalac.ast.printer._; -import scalac.symtab._; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.TypeNames; - -package scala.tools.scalac.ast.printer { - -/** - * Text pretty printer for Scala abstract syntax trees. - * - * @author Michel Schinz, Matthias Zenger - * @version 1.0 - */ -class TextTreePrinter(global0: scalac_Global, out0: PrintWriter) - extends TreePrinter -{ - //########################################################################## - // Public Fields - - val global: scalac_Global = global0; - val out: PrintWriter = out0; - - //########################################################################## - // Protected Fields - - protected var indentMargin = 0; - protected val INDENT_STEP = 2; - protected var INDENT_STRING = " "; - protected val MAX_INDENT = INDENT_STRING.length(); - - //########################################################################## - // Public Methods - TreePrinter interface - - def begin(): Unit = (); - def end(): Unit = flush(); - def flush(): Unit = out.flush(); - - def print(units: Array[CompilationUnit]): Unit = printUnits(units); - def print(tree: Tree): Unit = printTree(tree); - - //########################################################################## - - def beginSection(level: Int, title: String) = { - out.println("[[" + title + "]]"); - flush(); - } - - protected def indent() = { - indentMargin = indentMargin + Math.min(MAX_INDENT, INDENT_STEP); - } - - protected def undent() = { - indentMargin = indentMargin - Math.max(0, INDENT_STEP); - } - - protected def print(str: String): Unit = { - out.print(str); - } - - protected def printString(str: String) = { - out.print(str); - } - - protected def printNewLine() = { - out.println(); - while (indentMargin > INDENT_STRING.length()) { - INDENT_STRING = INDENT_STRING + INDENT_STRING; - } - if (indentMargin > 0) - out.write(INDENT_STRING, 0, indentMargin); - } - - abstract class Text; - case object None extends Text; - case object Space extends Text; - case object Newline extends Text; - case class Simple(str: String) extends Text; - case class Literal(str: String) extends Text; - case class Keyword(name: String) extends Text; - case class Identifier(symbol: Symbol, name: Name, usage: SymbolUsage) - extends Text; - case class Sequence(elements: List[Text]) extends Text; - - abstract class SymbolUsage; - case object Definition extends SymbolUsage; - case object Use extends SymbolUsage; - - protected def print(text: Text): Unit = text match { - case None => ; - case Space => printString(" ") - case Newline => printNewLine() - case Simple(str) => printString(str) - case Literal(str) => printString(str) - case Keyword(name) => printString(name) - case Identifier(sym, name, usage) => - - if (sym != null) { - if (usage == Use) - printString(sym.simpleName().toString()); - else - printString(sym.name.toString()); - if (global.uniqid) - printUniqueIdOf(sym) - } else { - printString(name.toString()); - } - case Sequence(elements) => print(elements) - } - - protected def print(texts: List[Text]): Unit = - for (val text <- texts) print(text); - - protected final val KW_ABSTRACT = Keyword("abstract"); - protected final val KW_CASE = Keyword("case"); - protected final val KW_CLASS = Keyword("class"); - protected final val KW_DEF = Keyword("def"); - protected final val KW_DO = Keyword("do"); - protected final val KW_ELSE = Keyword("else"); - protected final val KW_EXTENDS = Keyword("extends"); - protected final val KW_FINAL = Keyword("final"); - protected final val KW_FOR = Keyword("for"); - protected final val KW_IF = Keyword("if"); - protected final val KW_IMPLICIT = Keyword("implicit"); - protected final val KW_IMPORT = Keyword("import"); - protected final val KW_INTERFACE = Keyword("interface"); - protected final val KW_MATCH = Keyword("match"); - protected final val KW_NEW = Keyword("new"); - protected final val KW_NULL = Keyword("null"); - protected final val KW_OBJECT = Keyword("object"); - protected final val KW_OUTER = Keyword("outer"); - protected final val KW_OVERRIDE = Keyword("override"); - protected final val KW_PACKAGE = Keyword("package"); - protected final val KW_PRIVATE = Keyword("private"); - protected final val KW_PROTECTED = Keyword("protected"); - protected final val KW_RETURN = Keyword("return"); - protected final val KW_SEALED = Keyword("sealed"); - protected final val KW_STATIC = Keyword("static"); - protected final val KW_SUPER = Keyword("super"); - protected final val KW_THIS = Keyword("this"); - protected final val KW_TYPE = Keyword("type"); - protected final val KW_VAL = Keyword("val"); - protected final val KW_VAR = Keyword("var"); - protected final val KW_WITH = Keyword("with"); - protected final val KW_YIELD = Keyword("yield"); - - protected final val TXT_ERROR = Simple("<error>"); - protected final val TXT_UNKNOWN = Simple("<unknown>"); - protected final val TXT_NULL = Simple("<null>"); - protected final val TXT_OBJECT_COMMENT = Simple("/*object*/ "); - protected final val TXT_EMPTY = Simple("<empty>"); - protected final val TXT_TEMPLATE = Simple("<template>"); - - protected final val TXT_QUOTE = Simple("\""); - protected final val TXT_PLUS = Simple("+"); - protected final val TXT_COLON = Simple(":"); - protected final val TXT_SEMICOLON = Simple(";"); - protected final val TXT_DOT = Simple("."); - protected final val TXT_COMMA = Simple(","); - protected final val TXT_EQUAL = Simple("="); - protected final val TXT_SUPERTYPE = Simple(">:"); - protected final val TXT_SUBTYPE = Simple("<:"); - protected final val TXT_VIEWBOUND = Simple("<%"); - protected final val TXT_HASH = Simple("#"); - protected final val TXT_RIGHT_ARROW = Simple("=>"); - protected final val TXT_LEFT_PAREN = Simple("("); - protected final val TXT_RIGHT_PAREN = Simple(")"); - protected final val TXT_LEFT_BRACE = Simple("{"); - protected final val TXT_RIGHT_BRACE = Simple("}"); - protected final val TXT_LEFT_BRACKET = Simple("["); - protected final val TXT_RIGHT_BRACKET = Simple("]"); - protected final val TXT_BAR = Simple("|"); - protected final val TXT_AT = Simple("@"); - - protected final val TXT_WITH_SP = - Sequence(List(Space, KW_WITH, Space)); - protected final val TXT_BLOCK_BEGIN = - Sequence(List(TXT_LEFT_BRACE, Newline)); - protected final val TXT_BLOCK_END = - Sequence(List(Newline, TXT_RIGHT_BRACE)); - protected final val TXT_BLOCK_SEP = - Sequence(List(TXT_SEMICOLON, Newline)); - protected final val TXT_COMMA_SP = - Sequence(List(TXT_COMMA, Space)); - protected final val TXT_ELSE_NL = - Sequence(List(KW_ELSE, Newline)); - protected final val TXT_BAR_SP = - Sequence(List(Space, TXT_BAR, Space)); - - //########################################################################## - // Public Methods - Printing Units - - def printUnits(units: Array[CompilationUnit]): Unit = { - val phase: Phase = global.currentPhase; - beginSection(1, "syntax trees at " + phase + " (after " + phase.prev + ")"); - for (val i <- Iterator.range(0, units.length)) - printUnit(units(i)); - } - - def printUnit(unit: CompilationUnit): Unit = { - printUnitHeader(unit); - if (unit.body != null) { - for (val i <- Iterator.range(0, unit.body.length)) { - print(unit.body(i)); - print(TXT_BLOCK_SEP); - } - } else { - print(TXT_NULL); - } - printUnitFooter(unit); - flush(); - } - - def printUnitHeader(unit: CompilationUnit): Unit = - print(Simple("// Scala source: " + unit.source + "\n")); - - def printUnitFooter(unit: CompilationUnit): Unit = - print(Newline); - - //########################################################################## - // Public Methods - Printing trees - - def printTree(tree: Tree): Unit = { - val symbol = tree.symbol(); - val attributed = symbol != null && ( - !tree.definesSymbol() - || global.currentPhase.id > global.PHASE.ANALYZER.id() - || symbol.isInitialized()); - if (attributed) printATree(tree, symbol) else printSTree(tree); - if (global.printtypes && tree.isTerm()) printTypeOf(tree); - } - - def printTypeOf(tree: Tree): Unit = { - val tpe = tree.`type`; - if (tpe != Type.NoType) { - print(TXT_LEFT_BRACE); - if (tpe != null) printType(tpe) else print(TXT_NULL); - print(TXT_RIGHT_BRACE); - } - } - - def printATree(tree: Tree, symbol: Symbol): Unit = tree match { - case Tree.ClassDef(_, _, _, _, _, impl) => - printAttributes(symbol); - printAModifiers(symbol); - print(if (symbol.isInterface()) KW_INTERFACE else KW_CLASS); - print(Space); - printSymbol(symbol, Definition); - printAParams(symbol.primaryConstructor().info()); - if (symbol.thisSym() != symbol) - { print(TXT_COLON); print(Space); printType(symbol.typeOfThis()); } - printTemplate(symbol, impl); - - case Tree.ModuleDef(_, _, _, impl) => - printAttributes(symbol); - printAModifiers(symbol); - print(KW_OBJECT); - print(Space); - printSymbol(symbol, Definition); - val clasz = symbol.moduleClass(); - if (clasz.thisSym() != clasz) - { print(TXT_COLON); print(Space); printType(clasz.typeOfThis()); } - printTemplate(clasz, impl); - - case Tree.ValDef(_, _, _, rhs) => - printAttributes(symbol); - printAModifiers(symbol); - if (symbol.isModule()) print(TXT_OBJECT_COMMENT); - print(if (symbol.isVariable()) KW_VAR else KW_VAL); - print(Space); - printSymbol(symbol, Definition); - print(TXT_COLON); - print(Space); - printType(symbol.info()); - if (rhs != Tree.Empty || !symbol.isDeferred()) { - print(Space); print(TXT_EQUAL); print(Space); - if (rhs == Tree.Empty) print("_"); else print(rhs); - } - - case Tree.DefDef(_, _, _, _, _, rhs) => - printAttributes(symbol); - printAModifiers(symbol); - print(KW_DEF); - print(Space); - if (symbol.isConstructor()) print(KW_THIS); - else printSymbol(symbol, Definition); - printAParams(symbol.info()); - if (!symbol.isConstructor()) { - print(TXT_COLON); - print(Space); - printType(symbol.info().resultType()); - } - printOpt(TXT_EQUAL, rhs, true); - - case Tree.AbsTypeDef(_, _, _, _) => - printAttributes(symbol); - printAModifiers(symbol); - print(KW_TYPE); - print(Space); - printSymbol(symbol, Definition); - printABoundsOf(symbol); - - case Tree.AliasTypeDef(_, _, _, _) => - printAttributes(symbol); - printAModifiers(symbol); - print(KW_TYPE); - print(Space); - printSymbol(symbol, Definition); - printATypeParams(symbol.typeParams()); - print(Space); - print(TXT_EQUAL); - print(Space); - printType(symbol.info()); - - case Tree.Template(_, _) => - print(TXT_TEMPLATE); - printTemplate(symbol.owner(), tree.asInstanceOf[Tree.Template]); - - case Tree.LabelDef(_, params, rhs) => - printSymbol(symbol, Definition); - printArray(params.asInstanceOf[Array[Tree]], TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - print(rhs); - - case Tree.Bind(_, rhs) => - printSymbol(symbol, Definition); - print(Space); - print(TXT_AT); - print(Space); - print(rhs); - - case Tree.Return(expr) => - print(KW_RETURN); - printString("/*"); - printSymbol(symbol, Use); - printString("*/"); - print(Space); - print(expr); - - case Tree.Create(qualifier, targs) => - if (qualifier != Tree.Empty) { - print(qualifier); - print(TXT_DOT); - } - printSymbol(symbol, Use); - if (targs.length != 0 || !global.debug) - printArray(targs, TXT_LEFT_BRACKET, TXT_RIGHT_BRACKET, TXT_COMMA_SP); - - case Tree.Super(_, mixin) => - printSymbol(symbol, Use); - print(TXT_DOT); - print(KW_SUPER); - if (mixin != TypeNames.EMPTY) { - print(TXT_LEFT_PAREN); - print(mixin.toString()); - print(TXT_RIGHT_PAREN); - } - - case Tree.This(_) => - printSymbol(symbol, Use); - print(TXT_DOT); - print(KW_THIS); - - case Tree.Select(qualifier, _) => - if (!symbol.owner().isRoot() && !global.debug) { - print(qualifier); - print(TXT_DOT); - } - printSymbol(symbol, Use); - - case Tree.Ident(_) => - printSymbol(symbol, Use); - - case Tree.SelectFromType(qualifier, _) => - print(qualifier); - print(Space); print(TXT_HASH); print(Space); - printSymbol(symbol, Use); - - case _ => - printSTree(tree); - } - - def printSTree(tree: Tree): Unit = tree match { - case Tree.Empty => - print(TXT_EMPTY); - - case Tree.Attributed(attr, definition) => - print(TXT_LEFT_BRACKET); - print(attr); - print(TXT_RIGHT_BRACKET); - printNewLine(); - print(definition); - - case Tree.DocDef(comment, definition) => - print(comment); - printNewLine(); - print(definition); - - case Tree.ClassDef(mods, name, tparams, vparams, tpe, impl) => - printSModifiers(mods); - print(if ((mods & Modifiers.INTERFACE) != 0) KW_INTERFACE else KW_CLASS); - print(Space); - printName(tree, name, Definition); - printSTypeParams(tparams); - printSValueParams(vparams); - printOpt(TXT_COLON, tpe, false); - printTemplate(tree.symbol(), impl); - - case Tree.PackageDef(packaged, impl) => - print(KW_PACKAGE); - print(Space); - print(packaged); - printTemplate(null, impl); - - case Tree.ModuleDef(mods, name, tpe, impl) => - printSModifiers(mods); - print(KW_OBJECT); - print(Space); - printName(tree, name, Definition); - printOpt(TXT_COLON, tpe, false); - printTemplate(null, impl); - - case Tree.ValDef(mods, name, tpe, rhs) => - printSModifiers(mods); - if ((mods & Modifiers.MODUL) != 0) print(TXT_OBJECT_COMMENT); - print(if ((mods & Modifiers.MUTABLE) != 0) KW_VAR else KW_VAL); - print(Space); - printName(tree, name, Definition); - printOpt(TXT_COLON, tpe, false); - if ((mods & Modifiers.DEFERRED) == 0) { - print(Space); print(TXT_EQUAL); print(Space); - if (rhs == Tree.Empty) print("_"); - else print(rhs); - } - - case Tree.PatDef(mods, pat, rhs) => - printSModifiers(mods); - print(KW_VAL); - print(Space); - print(pat); - printOpt(TXT_EQUAL, rhs, true); - - case Tree.DefDef(mods, name, tparams, vparams, tpe, rhs) => - printSModifiers(mods); - print(KW_DEF); - print(Space); - if (name.isTypeName()) print(KW_THIS); - else printName(tree, name, Definition); - printSTypeParams(tparams); - printSValueParams(vparams); - printOpt(TXT_COLON, tpe, false); - printOpt(TXT_EQUAL, rhs, true); - - case Tree.AbsTypeDef(mods, name, rhs, lobound) => - printSModifiers(mods); - print(KW_TYPE); - print(Space); - printName(tree, name, Definition); - printSBounds(lobound, rhs, mods); - - case Tree.AliasTypeDef(mods, name, tparams, rhs) => - printSModifiers(mods); - print(KW_TYPE); - print(Space); - printName(tree, name, Definition); - printSTypeParams(tparams); - printOpt(TXT_EQUAL, rhs, true); - - case Tree.Import(expr, selectors) => - print(KW_IMPORT); - print(Space); - print(expr); - print(TXT_DOT); - print(TXT_LEFT_BRACE); - var i = 0; - while (i < selectors.length) { - if (i > 0) print(TXT_COMMA_SP); - print(selectors(i).toString()); - if (i + 1 < selectors.length && selectors(i) != selectors(i+1)) { - print(TXT_RIGHT_ARROW); - print(selectors(i+1).toString()); - } - i = i + 2; - } - print(TXT_RIGHT_BRACE); - - case Tree.Template(_, _) => - val local = tree.symbol(); - val clasz = if (local != null) local.owner() else null; - print(TXT_TEMPLATE); - printTemplate(local, tree.asInstanceOf[Tree.Template]); - - case Tree.CaseDef(pat, guard, body) => - print(KW_CASE); - print(Space); - print(pat); - printOpt(KW_IF, guard, true); - print(Space); - print(TXT_RIGHT_ARROW); - print(Space); - print(body); - - case Tree.LabelDef(name, params, rhs) => - printName(tree, name, Definition); - printArray(params.asInstanceOf[Array[Tree]], TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - print(rhs); - - case Tree.Block(stats, value) => - printArray(stats, TXT_BLOCK_BEGIN, TXT_SEMICOLON, TXT_BLOCK_SEP); - indent(); - printNewLine(); - print(value); - undent(); - print(TXT_BLOCK_END); - - case Tree.Sequence(trees) => - printArray(trees, TXT_LEFT_BRACKET, TXT_RIGHT_BRACKET, TXT_COMMA_SP); - - case Tree.Alternative(trees) => - printArray(trees, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_BAR_SP); - - case Tree.Bind(name, t) => - printName(tree, name, Definition); - print(Space); - print(TXT_AT); - print(Space); - print( t ); - - case Tree.Visitor(cases) => - printArray(cases.asInstanceOf[Array[Tree]], TXT_BLOCK_BEGIN, TXT_BLOCK_END, Newline); - - case Tree.Function(vparams, body) => - print(TXT_LEFT_PAREN); - printSValueParams(vparams); - print(Space); - print(TXT_RIGHT_ARROW); - print(Space); - print(body); - print(TXT_RIGHT_PAREN); - - case Tree.Assign(lhs, rhs) => - print(lhs); - print(Space); - print(TXT_EQUAL); - print(Space); - print(rhs); - - case Tree.If(cond, thenp, elsep) => - print(KW_IF); - print(Space); - print(TXT_LEFT_PAREN); - print(cond); - print(TXT_RIGHT_PAREN); - indent(); print(Newline); - print(thenp); - undent(); print(Newline); - indent(); printOpt(TXT_ELSE_NL, elsep, false); undent(); - - case Tree.Switch(expr, tags, bodies, defaultBody) => - print("<switch>"); - print(Space); - print(TXT_LEFT_PAREN); - print(expr); - print(TXT_RIGHT_PAREN); - print(Space); - indent(); - print(TXT_BLOCK_BEGIN); - for (val i <- Iterator.range(0, tags.length)) { - print(KW_CASE); - print(Space); - print("" + tags(i)); - print(Space); - print(TXT_RIGHT_ARROW); - print(Space); - print(bodies(i)); - print(Newline); - } - print("<default> => "); - print(defaultBody); - undent(); - print(TXT_BLOCK_END); - - case Tree.Return(expr) => - print(KW_RETURN); - print(Space); - print(expr); - - case Tree.New(init) => - print(KW_NEW); - print(Space); - print(init); - - case Tree.Typed(expr, tpe) => - print(TXT_LEFT_PAREN); - print(expr); - print(TXT_RIGHT_PAREN); - print(Space); - print(TXT_COLON); - print(Space); - print(tpe); - - case Tree.TypeApply(fun, targs) => - print(fun); - printArray(targs, TXT_LEFT_BRACKET, TXT_RIGHT_BRACKET, TXT_COMMA_SP); - - case Tree.Apply(fun, vargs) => - if (fun.isInstanceOf[Tree.TypeTerm]) { - val result = fun.`type`.resultType(); - print(Type.appliedType(result, Type.EMPTY_ARRAY).toString()); - } - else - print(fun); - printArray(vargs, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - - case Tree.Super(qualifier, mixin) => - if (qualifier != TypeNames.EMPTY) { - printName(tree, qualifier, Use); - print(TXT_DOT); - } - print(KW_SUPER); - if (mixin != TypeNames.EMPTY) { - print(TXT_LEFT_PAREN); - print(mixin.toString()); - print(TXT_RIGHT_PAREN); - } - - case Tree.This(name) => - if (name != TypeNames.EMPTY) { - printName(tree, name, Use); - print(TXT_DOT); - } - print(KW_THIS); - - case Tree.Select(qualifier, name) => - if (global.debug || qualifier.symbol() == null || !qualifier.symbol().isRoot()) { - print(qualifier); - print(TXT_DOT); - } - printName(tree, name, Use); - - case Tree.Ident(name) => - printName(tree, name, Use); - - case Tree.Literal(obj) => - print(Literal(obj.toString())); - - case Tree.TypeTerm() => - printType(tree.`type`); - - case Tree.SingletonType(ref) => - print(ref); - print(TXT_DOT); print(KW_TYPE); - - case Tree.SelectFromType(qualifier, selector) => - print(qualifier); - print(Space); print(TXT_HASH); print(Space); - printName(tree, selector, Use); - - case Tree.FunType(argtpes, restpe) => - printArray(argtpes, TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); - print(TXT_RIGHT_ARROW); - print(restpe); - - case Tree.CompoundType(baseTypes, refinements) => - printArray(baseTypes, None, None, TXT_WITH_SP); - printArray(refinements, TXT_BLOCK_BEGIN, TXT_BLOCK_END, Newline); - - case Tree.AppliedType(tpe, args) => - print(tpe); - indent(); - print(TXT_LEFT_BRACKET); - for (val i <- Iterator.range(0, args.length)) { - if (i > 0) print(TXT_COMMA_SP); - print(args(i)); - } - undent(); - print(TXT_RIGHT_BRACKET); - - case _ => - print(TXT_UNKNOWN); - } - - //########################################################################## - // Public Methods - Printing symbols and names - - /** Print symbol. */ - def printSymbol(symbol: Symbol, usage: SymbolUsage): Unit = - print(Identifier(symbol, symbol.name, usage)); - - /** Print unique identifier of symbol */ - def printUniqueIdOf(symbol: Symbol): Unit = { - print(TXT_HASH); - printString(String.valueOf(symbol.id)); - } - - /** Print name. */ - def printName(name: Name, usage: SymbolUsage): Unit = - print(Identifier(null, name, usage)); - - /** Print name. */ - def printName(tree: Tree, name: Name, usage: SymbolUsage): Unit = - if (tree.symbol() != null) printSymbol(tree.symbol(), usage) - else printName(name, usage); - - //########################################################################## - // Public Methods - Printing modifiers - - /** Print syntactic modifiers. */ - def printSModifiers(flags: Int): Unit = { - if ((flags & Modifiers.ABSTRACT) != 0) { - print(KW_ABSTRACT); - print(Space); - } - if ((flags & Modifiers.FINAL) != 0) { - print(KW_FINAL); - print(Space); - } - if ((flags & Modifiers.SEALED) != 0) { - print(KW_SEALED); - print(Space); - } - if ((flags & Modifiers.PRIVATE) != 0) { - print(KW_PRIVATE); - print(Space); - } - if ((flags & Modifiers.PROTECTED) != 0) { - print(KW_PROTECTED); - print(Space); - } - if ((flags & Modifiers.OVERRIDE) != 0) { - print(KW_OVERRIDE); - print(Space); - } - if ((flags & Modifiers.CASE) != 0) { - print(KW_CASE); - print(Space); - } - if ((flags & Modifiers.DEF) != 0) { - print(KW_DEF); - print(Space); - } - } - - /** Print attributed modifiers. */ - def printAModifiers(symbol: Symbol): Unit = { - if (symbol.isAbstractClass()) { - print(KW_ABSTRACT); - print(Space); - } - if (symbol.isFinal()) { - print(KW_FINAL); - print(Space); - } - if (symbol.isSealed()) { - print(KW_SEALED); - print(Space); - } - if (symbol.isPrivate()) { - print(KW_PRIVATE); - print(Space); - } - if (symbol.isProtected()) { - print(KW_PROTECTED); - print(Space); - } - if (symbol.isOverride()) { - print(KW_OVERRIDE); - print(Space); - } - if (symbol.isCaseClass()) { - print(KW_CASE); - print(Space); - } - if (symbol.isDefParameter()) { - print(KW_DEF); - print(Space); - } - } - - def printAttributes(symbol: Symbol): Unit = { - val attrs = global.getAttributes(symbol); - if (attrs != null) { - print(attrs.toString()); - print(Newline); - } - } - - //########################################################################## - // Public Methods - Printing templates - - /** Print template. */ - def printTemplate(clasz: Symbol, template: Tree.Template): Unit = { - val local = template.symbol(); - val constructors = if (clasz == null) null else clasz.allConstructors(); - val primary = if (clasz == null) null else clasz.primaryConstructor(); - val parents = template.parents; - val body = template.body; - val types = new ArrayList(); - // collect type members - if (clasz != null) { - if (global.currentPhase.id > global.PHASE.ADDACCESSORS.id()) { - val i = clasz.members().iterator(); - while (i.hasNext()) { - val member = i.next(); - if (member.isTypeAlias() || member.isAbstractType()) - types.add(member); - } - } - } - // print parents - if (parents.length > 0) { - print(Space); - print(KW_EXTENDS); - print(Space); - printArray(parents, None, None, TXT_WITH_SP); - } - // print local - if (global.uniqid && (local != null || constructors != null)) { - print(Space); - printString("/*"); - if (constructors != null) { - printString("constructors"); - printUniqueIdOf(constructors); - printString(",primary"); - printUniqueIdOf(primary); - } - if (local != null) { - if (constructors != null) printString(","); - printString("local"); - printUniqueIdOf(local); - } - printString("*/"); - } - // print body - if (body.length > 0 || types.size() > 0) { - print(Space); - indent(); - print(TXT_BLOCK_BEGIN); - if (types.size() > 0) { - val printer = - new SymbolTablePrinter(INDENT_STRING.substring(0, indentMargin)); - printer.indent(); - var i: Int = 0; - while (i < types.size()) { - if (i > 0) printer.line(); - val type0 = types.get(i).asInstanceOf[Symbol]; - printer.printSignature(type0).print(';'); - i = i + 1; - } - printer.undent(); - print(printer.toString().substring(indentMargin)); - print(Newline); - } - var i: Int = 0; - while (i < body.length) { - if (i > 0) print(TXT_BLOCK_SEP); - print(body(i)); - i = i + 1; - } - undent(); - print(TXT_BLOCK_END); - } - } - - //########################################################################## - // Public Methods - Printing parameters - - /** Print attributed parameter lists. */ - def printAParams(tpe: Type): Unit = tpe match { - case Type.PolyType(params, result) => - printATypeParams(params); - printAParams(result); - case Type.MethodType(params, result) => - printAValueParams(params); - printAParams(result); - case _ => - } - - /** Print attributed type parameter list. */ - def printATypeParams(tparams: Array[Symbol]): Unit = - if (tparams.length > 0 && !global.debug) { - print(TXT_LEFT_BRACKET); - for (val i <- Iterator.range(0, tparams.length)) { - if (i > 0) print(TXT_COMMA_SP); - printATypeParam(tparams(i)); - } - print(TXT_RIGHT_BRACKET); - } - - /** Print attributed type parameter. */ - def printATypeParam(tparam: Symbol): Unit = { - printAModifiers(tparam); - printSymbol(tparam, Definition); - printABoundsOf(tparam); - } - - /** Print attributed value parameter list. */ - def printAValueParams(vparams: Array[Symbol]): Unit = { - print(TXT_LEFT_PAREN); - for (val i <- Iterator.range(0, vparams.length)) { - if (i > 0) print(TXT_COMMA_SP); - printAValueParam(vparams(i)); - } - print(TXT_RIGHT_PAREN); - } - - /** Print attributed value parameter. */ - def printAValueParam(vparam: Symbol): Unit = { - printAModifiers(vparam); - if (vparam.hasParamAccessorFlag()) { - print(KW_VAL); print(Space); - } - printSymbol(vparam, Definition); - print(TXT_COLON); - print(Space); - printType(vparam.info()); - } - - /** Print syntactic type parameter list. */ - def printSTypeParams(tparams: Array[Tree.AbsTypeDef]): Unit = - if (tparams.length > 0) { - print(TXT_LEFT_BRACKET); - for (val i <- Iterator.range(0, tparams.length)) { - if (i > 0) print(TXT_COMMA_SP); - printSTypeParam(tparams(i)); - } - print(TXT_RIGHT_BRACKET); - } - - /** Print syntactic type parameter. */ - def printSTypeParam(tparam: Tree.AbsTypeDef): Unit = { - printSModifiers(tparam.mods); - printName(tparam, tparam.name, Definition); // !!! - printSBounds(tparam.lobound, tparam.rhs, tparam.mods); - } - - /** Print syntactic value parameter lists. */ - def printSValueParams(vparamss: Array[Array[Tree.ValDef]]): Unit = - for (val i <- Iterator.range(0, vparamss.length)) - printSValueParams(vparamss(i)); - - /** Print syntactic value parameter list. */ - def printSValueParams(vparams: Array[Tree.ValDef]): Unit = { - print(TXT_LEFT_PAREN); - for (val i <- Iterator.range(0, vparams.length)) { - if (i > 0) print(TXT_COMMA_SP); - printSValueParam(vparams(i)); - } - print(TXT_RIGHT_PAREN); - } - - /** Print syntactic value parameter. */ - def printSValueParam(vparam: Tree.ValDef): Unit = { - printSModifiers(vparam.mods); - if ((vparam.mods & Modifiers.PARAMACCESSOR) != 0) { - print(KW_VAL); print(Space); - } - printName(vparam, vparam.name, Definition); // !!! - printOpt(TXT_COLON, vparam.tpe, false); - } - - //########################################################################## - // Public Methods - Printing types and bounds - - /** Print attributed type. */ - def printType(tp: Type): Unit = { - print(tp.toString()); - } - - /** Print attributed bound. */ - def printABound(kind: Text, bound: Type, default: Symbol): Unit = { - if (bound.symbol() != default && !global.debug) { - print(Space); - print(kind); - print(Space); - printType(bound); - } - } - - /** Print attributed lower bound. */ - def printALoBound(lobound: Type): Unit = - printABound(TXT_SUPERTYPE, lobound, global.definitions.ALL_CLASS); - - /** Print attributed view bound. */ - def printAVuBound(vubound: Type): Unit = - printABound(TXT_VIEWBOUND, vubound, global.definitions.ANY_CLASS); - - /** Print attributed higher bound. */ - def printAHiBound(hibound: Type): Unit = - printABound(TXT_SUBTYPE, hibound, global.definitions.ANY_CLASS); - - /** Print attributed bounds of symbol. */ - def printABoundsOf(symbol: Symbol): Unit = { - printALoBound(symbol.loBound()); - if (symbol.isViewBounded()) printAVuBound(symbol.vuBound()); - printAHiBound(symbol.info()); - } - - /** Print syntactic bounds. */ - def printSBounds(lobound: Tree, hibound: Tree, mods: Int): Unit = { - if (lobound.getType() != null) - printALoBound(lobound.getType()); - else if (!"scala.All".equals(lobound.toString()) && !global.debug) - printOpt(TXT_SUPERTYPE, lobound, true); - val isViewBounded = (mods & Modifiers.VIEWBOUND) != 0; - if (hibound.getType() != null) - if (isViewBounded) - printAVuBound(hibound.getType()); - else - printAHiBound(hibound.getType()); - else if (!"scala.Any".equals(hibound.toString()) && !global.debug) - printOpt(if (isViewBounded) TXT_VIEWBOUND else TXT_SUBTYPE,hibound,true); - } - - //########################################################################## - // Public Methods - Helper methods - - def printArray(trees: Array[Tree], open: Text, close: Text, sep: Text):Unit={ - indent(); - print(open); - for (val i <- Iterator.range(0, trees.length)) { - if (i > 0) print(sep); - print(trees(i)); - } - undent(); - print(close); - } - - def printOpt(prefix: Text, tree: Tree, spaceBefore: boolean): Unit = - if (tree != Tree.Empty) { - if (spaceBefore) - print(Space); - print(prefix); - print(Space); - print(tree); - } - - //########################################################################## -} -} diff --git a/sources/scala/tools/scalac/ast/printer/TreeInfo.scala b/sources/scala/tools/scalac/ast/printer/TreeInfo.scala deleted file mode 100644 index e83ef5535c..0000000000 --- a/sources/scala/tools/scalac/ast/printer/TreeInfo.scala +++ /dev/null @@ -1,419 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ -import scalac.CompilationUnit; -import scalac.symtab._; -import scalac.ast.Tree; - -import scalac.{Global => scalac_Global, Phase}; -import scalac.CompilationUnit; -import scalac.util.Name; -import scalac.util.TypeNames; - -import java.io.OutputStream; -import java.io.PrintWriter; -import java.lang.Math; -import java.util.HashMap; - -import javax.swing.tree._; -import javax.swing.event.TreeModelListener; -import javax.swing._; - -import java.awt.BorderLayout; - -package scala.tools.scalac.ast.printer { - - -/** Computes different information about a tree node. It - is used as central place to do all pattern matching against - Tree. -*/ -object TreeInfo { - val NO_NAME = Name.fromString(""); - - /** Return the case class name and the Name, if the node defines one */ - def treeName(t: Tree): Pair[String, Name] = t match { - case Tree.Attributed(attribute, definition) => - Pair("Attributed", NO_NAME); - - case Tree.DocDef(comment, definition) => - Pair("DocDef", NO_NAME); - - case Tree.ClassDef(mods, name, tparams, vparams, tpe, impl) => - Pair("ClassDef", name); - - case Tree.PackageDef(packaged, impl) => - Pair("PackageDef", NO_NAME); - - case Tree.ModuleDef(mods, name, tpe, impl) => - Pair("ModuleDef", name); - - case Tree.ValDef(mods, name, tpe, rhs) => - Pair("ValDef", name); - - case Tree.PatDef(mods, pat, rhs) => - Pair("PatDef", NO_NAME); - - case Tree.DefDef(mods, name, tparams, vparams, tpe, rhs) => - Pair("DefDef", name); - - case Tree.AbsTypeDef(mods, name, rhs, lobound) => - Pair("AbsTypeDef", name); - - case Tree.AliasTypeDef(mods, name, tparams, rhs) => - Pair("AliasTypeDef", name); - - case Tree.Import(expr, selectors) => - Pair("Import", Name.fromString(selectors.toString())); - - case Tree.CaseDef(pat, guard, body) => - Pair("CaseDef", NO_NAME); - - case Tree.Template(parents, body) => - Pair("Template", NO_NAME); - - case Tree.LabelDef(name, params, rhs) => - Pair("LabelDef", name); - - case Tree.Block(stats, expr) => - Pair("Block", NO_NAME); - - case Tree.Sequence(trees) => - Pair("Sequence", NO_NAME); - - case Tree.Alternative(trees) => - Pair("Alternative", NO_NAME); - - case Tree.Bind(name, rhs) => - Pair("Bind", name); - - case Tree.Visitor(cases) => - Pair("Visitor", NO_NAME); - - case Tree.Function(vparams, body) => - Pair("Function", NO_NAME); - - case Tree.Assign(lhs, rhs) => - Pair("Assign", NO_NAME); - - case Tree.If(cond, thenp, elsep) => - Pair("If", NO_NAME); - - case Tree.Switch(test, tags, bodies, otherwise) => - Pair("Switch", NO_NAME); - - case Tree.Return(expr) => - Pair("Return", NO_NAME); - - case Tree.Throw(expr) => - Pair("Throw", NO_NAME); - - case Tree.New(init) => - Pair("New", NO_NAME); - - case Tree.Create(qualifier, targs) => - Pair("Create", NO_NAME); - - case Tree.Typed(expr, tpe) => - Pair("Typed", NO_NAME); - - case Tree.TypeApply(fun, args) => - Pair("TypeApply", NO_NAME); - - case Tree.Apply(fun, args) => - Pair("Apply", NO_NAME); - - case Tree.Super(qualif, mixin) => - Pair("Super", Name.fromString(qualif.toString() + ", mixin: " + mixin.toString())); - - case Tree.This(qualifier) => - Pair("This", qualifier); - - case Tree.Select(qualifier, selector) => - Pair("Select", selector); - - case Tree.Ident(name) => - Pair("Ident", name); - - case Tree.Literal(value) => - Pair("Literal", NO_NAME); - - case Tree.TypeTerm() => - Pair("TypeTerm", NO_NAME); - - case Tree.SingletonType(ref) => - Pair("SingletonType", NO_NAME); - - case Tree.SelectFromType(qualifier, selector) => - Pair("SelectFromType", selector); - - case Tree.FunType(argtpes, restpe) => - Pair("FunType", NO_NAME); - - case Tree.CompoundType(parents, refinements) => - Pair("CompoundType", NO_NAME); - - case Tree.AppliedType(tpe, args) => - Pair("AppliedType", NO_NAME); - - case Tree.Try(block, catcher, finalizer) => - Pair("Try", NO_NAME); - - case Tree.Empty => - Pair("Empty", NO_NAME); - } - - /** Generate a list that contains all the elements of an Array of Array */ - def flattenArrays[a <: AnyRef](as: Array[Array[a]]): List[a] = { - def flattenArrays0[a <: AnyRef](as: Array[Array[a]], i: Int): List[a] = - if (as.length - i == 0) - Nil; - else if (as.length - i == 1) - List.fromArray(as(i)); - else - List.fromArray(as(i)) ::: flattenArrays0(as, i + 1); - - flattenArrays0(as, 0); - } - - /** Return a list of children for the given tree node */ - def packTreeChildren(t: Tree): List[Tree] = t match { - case Tree.Attributed(attribute, definition) => - List(attribute, definition); - - case Tree.DocDef(comment, definition) => - List(definition); - - case Tree.ClassDef(mods, name, tparams, vparams, tpe, impl) => { - var children: List[Tree] = List(); - children = List.fromArray(tparams) ::: children; - children = flattenArrays(vparams) ::: children; - tpe :: impl :: children - } - - case Tree.PackageDef(packaged, impl) => - List(packaged, impl); - - case Tree.ModuleDef(mods, name, tpe, impl) => - List(tpe, impl); - - case Tree.ValDef(mods, name, tpe, rhs) => - List(tpe, rhs); - - case Tree.PatDef(mods, pat, rhs) => - List(pat, rhs); - - case Tree.DefDef(mods, name, tparams, vparams, tpe, rhs) => { - var children: List[Tree] = List(); - children = List.fromArray(tparams) ::: children; - children = flattenArrays(vparams) ::: children; - tpe :: rhs :: children - } - - case Tree.AbsTypeDef(mods, name, rhs, lobound) => - List(rhs, lobound); - - case Tree.AliasTypeDef(mods, name, tparams, rhs) => { - var children: List[Tree] = List(); - children = List.fromArray(tparams) ::: children; - rhs :: children - } - - case Tree.Import(expr, selectors) => { - var children: List[Tree] = List(expr); - children - } - - case Tree.CaseDef(pat, guard, body) => - List(pat, guard, body); - - case Tree.Template(parents, body) => - List.fromArray(parents) ::: List.fromArray(body); - - case Tree.LabelDef(name, params, rhs) => - List.fromArray(params) ::: List(rhs); - - case Tree.Block(stats, expr) => - List.fromArray(stats) ::: List(expr); - - case Tree.Sequence(trees) => - List.fromArray(trees); - - case Tree.Alternative(trees) => - List.fromArray(trees); - - case Tree.Bind(name, rhs) => - List(rhs); - - case Tree.Visitor(cases) => - List.fromArray(cases); - - case Tree.Function(vparams, body) => - List.fromArray(vparams) ::: List(body); - - case Tree.Assign(lhs, rhs) => - List(lhs, rhs); - - case Tree.If(cond, thenp, elsep) => - List(cond, thenp, elsep); - - case Tree.Switch(test, tags, bodies, otherwise) => - test :: List.fromArray(bodies) ::: List(otherwise); - - case Tree.Return(expr) => - List(expr); - - case Tree.Throw(expr) => - List(expr); - - case Tree.New(init) => - List(init); - - case Tree.Create(qualif, targs) => - List(qualif) ::: List.fromArray(targs); - - case Tree.Typed(expr, tpe) => - List(expr, tpe); - - case Tree.TypeApply(fun, args) => - List(fun) ::: List.fromArray(args); - - case Tree.Apply(fun, args) => - List(fun) ::: List.fromArray(args); - - case Tree.Super(qualif, mixin) => - Nil; - - case Tree.This(qualif) => - Nil - - case Tree.Select(qualif, selector) => - List(qualif); - - case Tree.Ident(name) => - Nil; - - case Tree.Literal(value) => - Nil; - - case Tree.TypeTerm() => - Nil; - - case Tree.SingletonType(ref) => - List(ref); - - case Tree.SelectFromType(qualif, selector) => - List(qualif); - - case Tree.FunType(argtpes, restpe) => - List.fromArray(argtpes) ::: List(restpe); - - case Tree.CompoundType(parents, refinements) => - List.fromArray(parents) ::: List.fromArray(refinements); - - case Tree.AppliedType(tpe, args) => - tpe :: List.fromArray(args); - - case Tree.Try(block, catcher, finalizer) => - List(block, catcher, finalizer); - - case Tree.Empty => - Nil; - } - - /** Return a textual representation of this t's symbol */ - def symbolText(t: Tree): String = { - var prefix = ""; - - if (t.hasSymbol()) - prefix = "[has] "; - if (t.definesSymbol()) - prefix = "[defines] "; - - prefix + t.symbol() - } - - /** Return t's symbol type */ - def symbolTypeText(t: Tree): String = { - val s = t.symbol(); - if (s != null) -// s.`type`().toString(); - TypePrinter.apply(s.getType()); - else - ""; - } - - /** Return a textual representation of (some of) the symbol's - * attributes */ - def symbolAttributes(t: Tree): String = { - val s = t.symbol(); - var att = ""; - - if (s != null) { - if (s.isType()) - att = att + "type "; - if (s.isFinal()) - att = att + "final "; - if (s.isSynthetic()) - att = att + "synth "; - if (s.isExternal()) - att = att + "external "; - - att - } - else ""; - } -} - - object TypePrinter { - def apply(t: Type): String = t match { - case Type.ThisType(s) => "ThisType(" + s.name + ")\n"; - case Type.SingleType(pre, s) => "SingleType(" + apply(pre) + ", " + s.name + ")\n"; - case Type.ConstantType(base, value) => "ConstantType(" + apply(base) + ", " + value + ")\n"; - case Type.TypeRef(pre, s, args) => "TypeRef(" + apply(pre) + ", " + s.name + ", " + apply(args) + ")\n)"; - case Type.CompoundType(parts, members) => "CompoundType(" + apply(parts) + ", [members])\n"; - case Type.MethodType(vparams, result) => "MethodType( (" + apply(vparams) + "), " + apply(result) + ")\n"; - case Type.PolyType(tparams, result) => "PolyType( (" + apply(tparams) + "), " + apply(result) + ")\n"; - case Type.OverloadedType(alts, alttypes) => "OverloadedType()"; - case Type.LazyType() => "LazyType()\n"; - case Type.TypeVar(orig, constr) => "TypeVar()"; - case Type.UnboxedType(tag) => "UnboxedType(" + tag + ");\n"; - case Type.UnboxedArrayType(tag) => "UnboxedArrayType(" + tag + ")\n"; - case _ => "<unknown case>[" + t + "]"; - } - - def apply(ts: Array[Type]): String = { - var s: StringBuffer = new StringBuffer(); - var i: Int = 0; - - while (i < ts.length) { - s.append(apply(ts(i))); - if (i != ts.length - 1) - s.append(", "); - i = i + 1; - } - s.toString(); - } - - def apply(ts: Array[Symbol]): String = { - var s: StringBuffer = new StringBuffer(); - var i: Int = 0; - - while (i < ts.length) { - s.append(apply(ts(i).getType())); - if (i != ts.length - 1) - s.append(", "); - i = i + 1; - } - s.toString(); - } - - } - - -} // package diff --git a/sources/scala/tools/scalac/backend/GenJVMFromICode.scala b/sources/scala/tools/scalac/backend/GenJVMFromICode.scala deleted file mode 100644 index 3ad109b379..0000000000 --- a/sources/scala/tools/scalac/backend/GenJVMFromICode.scala +++ /dev/null @@ -1,758 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.symtab._; -import scalac.{Global => scalac_Global}; -import scalac.atree._; -import scalac.CompilationUnit; -import scalac.util.Debug; -import scala.tools.scalac.icode._; -import ch.epfl.lamp.fjbg._; -import scala.collection.mutable.HashMap; - -import java.util.StringTokenizer; -import java.io.File; - -package scala.tools.scalac.backend { - -object GenJVMFromICode { - def translate(global: scalac_Global, units: Array[CompilationUnit]): Unit = { - val translator = new GenJVMFromICode(global); - var i = 0; - while (i < units.length) { translator.translate(units(i)); i = i + 1; } - } -} - -/* This class implements the backend which create - * Java Virtual Machine's bytecode with - * The Intermediate Code of the compiler */ -class GenJVMFromICode(global: scalac_Global) { - - // ################################################## - // Private fields - Utils - - private val defs = global.definitions; - - private val fjbgContext = new FJBGContext(); - - private val typer = defs.atyper; - - // ################################################## - // Private fields - Data - private var currentSrcFileName: String = null; - - private val clasz = new HashMap[Symbol, JVMClass]; - - private val nameMap = new HashMap[Symbol, String]; - - private val typeMap = new HashMap[Symbol, JType]; - - // ################################################## - // Constructor code - initTypeMap; - - // ################################################## - // Public methods - - /* This method generates byte code for a single unit */ - def translate(unit: CompilationUnit) = { - global.log("Jvm.translate() called"); - currentSrcFileName = unit.source.toString(); - // 1. ##### Generate the structure - val classes_it = Iterator.fromArray(unit.repository.classes()); - classes_it.foreach(genClass(null)); - dumpStructure; - // 2. ##### Generate the code & Save the classes - var pairs_it = clasz.elements; - pairs_it.foreach ((p: Pair[Symbol, JVMClass]) => { - val sym = p._1; - val jvmClass = p._2; - val methods_it = jvmClass.methods.values; - global.log("Jvm.translate: translating class "+sym); - methods_it.foreach ((m: JVMMethod) => if(!m.aMethod.isAbstract()) genCode(m)); - }); - pairs_it = clasz.elements; - pairs_it.foreach ((p: Pair[Symbol, JVMClass]) => { - val sym = p._1; - val jvmClass = p._2; - val fileName = javaFileName(javaName(sym)); - global.log("Jvm.translate: writing class "+sym); - jvmClass.jClass.writeTo(fileName); - }); - global.operation("Generation of "+currentSrcFileName+" succeded."); - - currentSrcFileName = null; - } - - // ################################################## - // Private methods - Generate code - - /* Generate a class */ - private def genClass (parent: JVMClass)(aClass: AClass) : unit = { - // 1. ##### Create JClass object - val sym : Symbol = aClass.symbol(); - val thisClassName : String = javaName(sym); - val flags : int = JAccessFlags.ACC_SUPER | // The way it has to be - (if (aClass.isPublic()) JAccessFlags.ACC_PUBLIC else 0) | - (if (aClass.isPrivate()) JAccessFlags.ACC_PRIVATE else 0) | - (if (aClass.isProtected()) JAccessFlags.ACC_PROTECTED else 0) | - (if (aClass.isFinal()) JAccessFlags.ACC_FINAL else 0) | - (if (aClass.isAbstract()) JAccessFlags.ACC_ABSTRACT else 0) | - (if (aClass.isInterface()) JAccessFlags.ACC_INTERFACE else 0); - - global.log("genClass: parents(): "); - val prnt_it = Iterator.fromArray(aClass.parents()); // debug - prnt_it.foreach((t: Type) => {global.log(" "+t.toString())}); // debug - - val baseTps = Iterator.fromArray(aClass.parents()); - assert (baseTps.hasNext, "Jvm::genClass: Invalid number of parents. "+Debug.show(sym)); - - var superClassName : String = null; - - val firstParent : Type = aClass.parents()(0); - - if (aClass.isInterface()) { - if (firstParent.isSameAs(defs.ANY_TYPE())) { - baseTps.drop(1); - } - superClassName = JAVA_LANG_OBJECT; - } else { - superClassName = javaName(baseTps.next.symbol()); - } - - var interfaceNames_l : List[String] = Nil; - - baseTps.foreach((aParentType : Type) => - interfaceNames_l = javaName(aParentType.symbol())::interfaceNames_l); - val interfaceNames_a = new Array[String](interfaceNames_l.length); - interfaceNames_l.reverse.copyToArray(interfaceNames_a,0); - - val jclass : JClass = fjbgContext.JClass(flags, - thisClassName, - superClassName, - interfaceNames_a, - currentSrcFileName); - - // 2. ##### Visits the class - - val jvmClass = new JVMClass(parent); - clasz += aClass.symbol() -> jvmClass; - jvmClass.jClass = jclass; - //classFields = new HashMap[Symbol, JField](); - - // 2.1 ##### Access the inner classes - val classes_it = Iterator.fromArray(aClass.classes()); - classes_it.foreach(genClass(jvmClass)); - - // 2.2. ##### Add fields of the class - val fields_it = Iterator.fromArray(aClass.fields()); - fields_it.foreach(genField(jvmClass)); - - // 2.3 ##### Setup the stucture, records methods - val methods_it = Iterator.fromArray(aClass.methods()); - global.log(" number of methods: "+aClass.methods().length); // Debug - methods_it.foreach(genMethod(jvmClass)); - } - - /* Add a field to a class */ - private def genField(jvmClass : JVMClass)(aField : AField) : unit = { - val flags = (if (aField.isPublic()) JAccessFlags.ACC_PUBLIC else 0) | - (if (aField.isPrivate()) JAccessFlags.ACC_PRIVATE else 0) | - (if (aField.isProtected()) JAccessFlags.ACC_PROTECTED else 0) | - (if (aField.isStatic()) JAccessFlags.ACC_STATIC else 0) | - (if (aField.isFinal()) JAccessFlags.ACC_FINAL else 0) | - (if (aField.isVolatile()) JAccessFlags.ACC_VOLATILE else 0) | - (if (aField.isTransient()) JAccessFlags.ACC_TRANSIENT else 0); - jvmClass.fields += aField.symbol() -> - jvmClass.jClass.addNewField(flags, - aField.symbol().name.toString(), - typeStoJ(aField.symbol().info())); - } - - /* Generate a method */ - private def genMethod(jvmClass: JVMClass)(aMethod: AMethod): unit = { - // 1. ##### Create JMethod object - - val flags = (if (aMethod.isPublic()) JAccessFlags.ACC_PUBLIC else 0) | - (if (aMethod.isPrivate()) JAccessFlags.ACC_PRIVATE else 0) | - (if (aMethod.isProtected()) JAccessFlags.ACC_PROTECTED else 0) | - (if (aMethod.isStatic()) JAccessFlags.ACC_STATIC else 0) | - (if (aMethod.isFinal()) JAccessFlags.ACC_FINAL else 0) | - (if (aMethod.isNative()) JAccessFlags.ACC_NATIVE else 0) | - (if (aMethod.isAbstract()) JAccessFlags.ACC_ABSTRACT else 0) | - (if (aMethod.isStrictFP()) JAccessFlags.ACC_STRICT else 0); - - var argTypes_l : List[JType] = Nil; - var argNames_l : List[String] = Nil; - - val vparams_it = Iterator.fromArray(aMethod.vparams()); - vparams_it.foreach((sym: Symbol) => { - argTypes_l = typeStoJ(sym.info())::argTypes_l; - argNames_l = sym.name.toString()::argNames_l; - }); - - val argTypes_a = new Array[JType](argTypes_l.length); - val argNames_a = new Array[String](argNames_l.length); - argTypes_l.reverse.copyToArray(argTypes_a,0); - argNames_l.reverse.copyToArray(argNames_a,0); - val jMethod : JMethod = jvmClass.jClass.addNewMethod(flags, - aMethod.symbol().name.toString(), - typeStoJ(aMethod.result()), - argTypes_a, - argNames_a); - - - // 2. ##### Visits the method items - - val jvmMethod = new JVMMethod(aMethod, jvmClass); - jvmClass.methods += aMethod.symbol() -> jvmMethod; - jvmMethod.jMethod = jMethod; - - var index : int = 1; - vparams_it.foreach((sym: Symbol) => { - jvmMethod.args += sym -> index; - index = index + 1; - }); - - if (! jvmMethod.aMethod.isAbstract()) { - jvmMethod.jCode = jMethod.getCode().asInstanceOf[JExtendedCode]; - - - - // 2.1 ##### Generate labels for the basic blocks - - jvmMethod.aMethod.icode.asInstanceOf[ICode].icTraverse((bb : IBasicBlock) => { - val blockLabel : JCode$Label = jvmMethod.jCode.newLabel(); - jvmMethod.labels += bb -> blockLabel; - }); - } - } - - /* Translate code */ - private def genCode(jvmMethod : JVMMethod) = { - val icode : ICode = jvmMethod.aMethod.icode.asInstanceOf[ICode]; - var stack : ICTypeStack = new ICTypeStack(); - val jCode = jvmMethod.jCode; - - // * IMPORTANT NOTICE * - // Here we assume the icTraverse method uses *preorder* - // I.e. The next translated block will be successor of the currently emmited block - // It avoids to put the goto instruction since the successor is not already emmited - // In the case of a CJUMP ICInstruction, the preorder ensures the next traversed block - // will be the failure block. - icode.icTraverseFeedBack((bb: IBasicBlock, hm: HashMap[IBasicBlock, boolean]) => { - val blockLabel = jvmMethod.labels.apply(bb); - blockLabel.anchorToNext(); - bb.bbTraverse((ic : ICInstruction) => stack = emitICInstruction(jvmMethod, stack)(ic)); - - bb.getLastInstruction match { - case CJUMP(_,failure,_) => - if (hm(failure)) - jCode.emitGOTO(jvmMethod.labels(failure)); - case CZJUMP(_,failure,_) => - if (hm(failure)) - jCode.emitGOTO(jvmMethod.labels(failure)); - case JUMP(where) => - if (hm(where)) - jCode.emitGOTO(jvmMethod.labels(where)); - case _ => - ; - } - }); - } - - /* Translate an ICInstruction into a JVM instruction */ - private def emitICInstruction(jvmMethod: JVMMethod, stack: ICTypeStack)(instruction: ICInstruction) : ICTypeStack = { - val jcode = jvmMethod.jCode; - instruction match { - case THIS(_) => - jcode.emitALOAD_0(); - - - case CONSTANT(AConstant$BOOLEAN(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$BYTE(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$SHORT(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$CHAR(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$INT(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$LONG(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$FLOAT(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$DOUBLE(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant$STRING(v)) => - jcode.emitPUSH(v); - case CONSTANT(AConstant.NULL) => - jcode.emitACONST_NULL(); - case CONSTANT(AConstant.UNIT) => - ; //throw(Debug.abort("Illegal constant type: UNIT")); - // Here, we dissable the error message until the unboxed types - // are introduced. - case CONSTANT(AConstant.ZERO) => - throw(Debug.abort("Illegal constant type: ZERO")); - - case LOAD_ARRAY_ITEM() => { - val elementType = typer.getArrayElementType(stack.tail.head); - jcode.emitALOAD(typeStoJ(elementType)); - } - - case LOAD_LOCAL(local, false) => - jcode.emitLOAD(jvmMethod.locals.apply(local)); - - case LOAD_LOCAL(local, true) => - jcode.emitLOAD(jvmMethod.args(local), typeStoJ(local.getType())); - - case LOAD_FIELD(field, static) => { - val className = javaName(field.owner()); - val fieldName = field.name.toString(); - if (static) - jcode.emitGETSTATIC(className, fieldName, typeStoJ(field.getType())); - else - jcode.emitGETFIELD(className, fieldName, typeStoJ(field.getType())); - } - - case STORE_ARRAY_ITEM() => - jcode.emitASTORE(typeStoJ(stack.head)); - - case STORE_LOCAL(local, false) => { - val jLocal : JLocalVariable = - if (jvmMethod.locals.contains(local)) - jvmMethod.locals.apply(local); - else { - val newLocal = jvmMethod.jMethod.addNewLocalVariable(typeStoJ(local.getType()), local.name.toString()); - jvmMethod.locals += local -> newLocal; - newLocal; - } - jcode.emitSTORE(jLocal); - } - - case STORE_FIELD(field, static) => { - val className = javaName(field.owner()); - val fieldName = field.name.toString(); - if (static) - jcode.emitPUTSTATIC(className, fieldName, typeStoJ(field.getType())); - else - jcode.emitPUTFIELD(className, fieldName, typeStoJ(field.getType())); - } - - case CALL_PRIMITIVE(APrimitive$Negation(ATypeKind.I4)) => jcode.emitINEG(); - case CALL_PRIMITIVE(APrimitive$Negation(ATypeKind.I8)) => jcode.emitLNEG(); - case CALL_PRIMITIVE(APrimitive$Negation(ATypeKind.R4)) => jcode.emitFNEG(); - case CALL_PRIMITIVE(APrimitive$Negation(ATypeKind.R8)) => jcode.emitDNEG(); - - case CALL_PRIMITIVE(APrimitive$Test(op, typ, false)) => { - // !!! Not all type cases are handeled here - // !!! TODO - - val condTag = condAtoJ(op); - val thenLabel : JCode$Label = jvmMethod.jCode.newLabel(); - val contLabel : JCode$Label = jvmMethod.jCode.newLabel(); - - typ match { - case ATypeKind.REF => jcode.emitIF_ACMP(condTag, thenLabel); - case ATypeKind.I4 => jcode.emitIF_ICMP(condTag, thenLabel); - case _ => throw(Debug.abort("Unexpected type for the Test primitive.")); // !!! - } - jcode.emitPUSH(false); - jcode.emitGOTO(contLabel); - thenLabel.anchorToNext(); - jcode.emitPUSH(true); - contLabel.anchorToNext(); - } - - case CALL_PRIMITIVE(APrimitive$Comparison(AComparisonOp.CMPL, ATypeKind.R4)) => jcode.emitFCMPL(); - case CALL_PRIMITIVE(APrimitive$Comparison(AComparisonOp.CMPG, ATypeKind.R4)) => jcode.emitFCMPG(); - case CALL_PRIMITIVE(APrimitive$Comparison(AComparisonOp.CMP, ATypeKind.R4)) => jcode.emitFCMPG(); // Default is 1 - case CALL_PRIMITIVE(APrimitive$Comparison(AComparisonOp.CMPL, ATypeKind.R8)) => jcode.emitDCMPL(); - case CALL_PRIMITIVE(APrimitive$Comparison(AComparisonOp.CMPG, ATypeKind.R8)) => jcode.emitDCMPG(); - case CALL_PRIMITIVE(APrimitive$Comparison(AComparisonOp.CMP, ATypeKind.R8)) => jcode.emitDCMPG(); // Default is 1 - - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.ADD, ATypeKind.I4)) => jcode.emitIADD(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.ADD, ATypeKind.I8)) => jcode.emitLADD(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.ADD, ATypeKind.R4)) => jcode.emitFADD(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.ADD, ATypeKind.R8)) => jcode.emitDADD(); - - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.SUB, ATypeKind.I4)) => jcode.emitISUB(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.SUB, ATypeKind.I8)) => jcode.emitLSUB(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.SUB, ATypeKind.R4)) => jcode.emitFSUB(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.SUB, ATypeKind.R8)) => jcode.emitDSUB(); - - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.MUL, ATypeKind.I4)) => jcode.emitIMUL(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.MUL, ATypeKind.I8)) => jcode.emitLMUL(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.MUL, ATypeKind.R4)) => jcode.emitFMUL(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.MUL, ATypeKind.R8)) => jcode.emitDMUL(); - - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.DIV, ATypeKind.I4)) => jcode.emitIDIV(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.DIV, ATypeKind.I8)) => jcode.emitLDIV(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.DIV, ATypeKind.R4)) => jcode.emitFDIV(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.DIV, ATypeKind.R8)) => jcode.emitDDIV(); - - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.REM, ATypeKind.I4)) => jcode.emitIREM(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.REM, ATypeKind.I8)) => jcode.emitLREM(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.REM, ATypeKind.R4)) => jcode.emitFREM(); - case CALL_PRIMITIVE(APrimitive$Arithmetic(AArithmeticOp.REM, ATypeKind.R8)) => jcode.emitDREM(); - - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.AND, ATypeKind.I4)) => jcode.emitIAND(); - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.AND, ATypeKind.BOOL)) => jcode.emitIAND(); - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.AND, ATypeKind.I8)) => jcode.emitLAND(); - - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.OR, ATypeKind.I4)) => jcode.emitIOR(); - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.OR, ATypeKind.BOOL)) => jcode.emitIOR(); - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.OR, ATypeKind.I8)) => jcode.emitLOR(); - - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.XOR, ATypeKind.I4)) => jcode.emitIXOR(); - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.XOR, ATypeKind.BOOL)) => jcode.emitIXOR(); - case CALL_PRIMITIVE(APrimitive$Logical(ALogicalOp.XOR, ATypeKind.I8)) => jcode.emitLXOR(); - - case CALL_PRIMITIVE(APrimitive$Shift(AShiftOp.LSL, ATypeKind.I4)) => jcode.emitISHL(); - case CALL_PRIMITIVE(APrimitive$Shift(AShiftOp.LSL, ATypeKind.I8)) => jcode.emitLSHL(); - - case CALL_PRIMITIVE(APrimitive$Shift(AShiftOp.ASR, ATypeKind.I4)) => jcode.emitISHR(); - case CALL_PRIMITIVE(APrimitive$Shift(AShiftOp.ASR, ATypeKind.I8)) => jcode.emitLSHR(); - - case CALL_PRIMITIVE(APrimitive$Shift(AShiftOp.LSR, ATypeKind.I4)) => jcode.emitIUSHR(); - case CALL_PRIMITIVE(APrimitive$Shift(AShiftOp.LSR, ATypeKind.I8)) => jcode.emitLUSHR(); - - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I4, ATypeKind.I8)) => jcode.emitI2L(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I4, ATypeKind.R4)) => jcode.emitI2F(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I4, ATypeKind.R8)) => jcode.emitI2D(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I8, ATypeKind.I4)) => jcode.emitL2I(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I8, ATypeKind.R4)) => jcode.emitL2F(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I8, ATypeKind.R8)) => jcode.emitL2D(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.R4, ATypeKind.I4)) => jcode.emitF2I(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.R4, ATypeKind.I8)) => jcode.emitF2L(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.R4, ATypeKind.R8)) => jcode.emitF2D(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.R8, ATypeKind.I4)) => jcode.emitD2I(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.R8, ATypeKind.I8)) => jcode.emitD2L(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.R8, ATypeKind.R4)) => jcode.emitD2F(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I4, ATypeKind.I1)) => jcode.emitI2B(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I4, ATypeKind.U2)) => jcode.emitI2C(); - case CALL_PRIMITIVE(APrimitive$Conversion(ATypeKind.I4, ATypeKind.I2)) => jcode.emitI2S(); - - case CALL_PRIMITIVE(APrimitive$ArrayLength(_)) => jcode.emitARRAYLENGTH(); - - //case CALL_PRIMITIVE(APrimitive$StringConcat(ATypeKind.REF,ATypeKind.REF)) => - // !!! TODO !!! - - case CALL_METHOD(method, style) => { - var calledMethod : JMethod = null; - val clasz_it = clasz.values; - var aJvmClass : JVMClass = null; - // Is the method a method of the current unit ? - while (clasz_it.hasNext && calledMethod == null) { - aJvmClass = clasz_it.next; - if (aJvmClass.methods.contains(method)) - calledMethod = aJvmClass.methods.apply(method).jMethod; - } - if (calledMethod != null) - jcode.emitINVOKE(calledMethod); - else { - // normal case - val methodName = method.name.toString(); - val className = javaName(method.owner()); - val methodType = typeStoJ(method.info()).asInstanceOf[JMethodType]; - style match { - case AInvokeStyle.Dynamic => - if (method.owner().isInterface()) - jcode.emitINVOKEINTERFACE(className, methodName, methodType); - else - jcode.emitINVOKEVIRTUAL(className, methodName, methodType); - case AInvokeStyle.StaticInstance => - jcode.emitINVOKESPECIAL(className, methodName, methodType); - case AInvokeStyle.StaticClass => - jcode.emitINVOKESTATIC(className, methodName, methodType); - } - } - } - - case NEW(clasz) => - jcode.emitNEW(javaName(clasz)); - - case CREATE_ARRAY(element) => - jcode.emitNEWARRAY(typeStoJ(element)); - - case IS_INSTANCE(typ) => - jcode.emitINSTANCEOF(typeStoJ(typ).asInstanceOf[JReferenceType]); - - case CHECK_CAST(typ) => - jcode.emitCHECKCAST(typeStoJ(typ).asInstanceOf[JReferenceType]); - - case SWITCH(tags,blocks) => { - val casesTags : List[Array[int]] = List.fromArray(tags,0,tags.length); - val casesLabels = blocks.take(blocks.length-1); - val defaultBranch = jvmMethod.labels(blocks.last); - - val tagsAndLabels = casesTags.zip(casesLabels); - var keys_l : List[int] = Nil; - var branches_l : List[JCode$Label] = Nil; - - tagsAndLabels.foreach ((p: Pair[Array[Int], IBasicBlock]) => { - val tags = p._1; - val label = jvmMethod.labels(p._2); - val tag_it = Iterator.fromArray(tags); - tag_it.foreach((tag: int) => { - keys_l = tag::keys_l; - branches_l = label::branches_l; - }); - }); - - val keys_a = new Array[int](keys_l.length); - val branches_a = new Array[JCode$Label](branches_l.length); - keys_l.copyToArray(keys_a,0); - branches_l.copyToArray(branches_a,0); - - jcode.emitSWITCH(keys_a, branches_a, defaultBranch, 0.65); - } - - case JUMP(basicBlock) => - ; // goto instructions are generated by the genCode method. - - case CJUMP(success, failure, cond) => { - // !!! Type cases are missing - // TODO (same as CALL_PRIMITIVE(Test)) - val condTag : int = condAtoJ(cond); - val typ = typeStoJ(stack.head); - if (typ.getTag() == JType.T_REFERENCE) - jcode.emitIF_ACMP(condTag, jvmMethod.labels(success)); - else if (typ.getTag() == JType.T_INT) - jcode.emitIF_ICMP(condTag, jvmMethod.labels(success)); - - } - - case CZJUMP(success, failure, cond) => { - val condTag = condAtoJ(cond); - jcode.emitIF(condTag, jvmMethod.labels.apply(success)); - jcode.emitGOTO(jvmMethod.labels.apply(failure)); - } - - case RETURN() => { - if (stack.isEmpty) - jcode.emitRETURN(JType.VOID); - else - jcode.emitRETURN(typeStoJ(stack.head)); - } - - case THROW() => jcode.emitATHROW; - - case DROP(typ) => { - val jtyp = typeStoJ(typ); - val jtypTag : int = jtyp.getTag(); - if (jtyp.isObjectType() || - jtyp.isReferenceType() || - jtyp.isArrayType()) - jcode.emitPOP(); - else - jtypTag match { // cf. VM spec 3.11.1 - case JType.T_BOOLEAN => jcode.emitPOP(); - case JType.T_CHAR => jcode.emitPOP(); - case JType.T_BYTE => jcode.emitPOP(); - case JType.T_SHORT => jcode.emitPOP(); - case JType.T_INT => jcode.emitPOP(); - case JType.T_FLOAT => jcode.emitPOP(); - case JType.T_REFERENCE => jcode.emitPOP(); - case JType.T_ADDRESS => jcode.emitPOP(); - case JType.T_LONG => jcode.emitPOP2(); - case JType.T_DOUBLE => jcode.emitPOP2(); - } - } - - case DUP(typ) => { - val jtyp = typeStoJ(typ); - val jtypTag : int = jtyp.getTag(); - if (jtyp.isObjectType() || - jtyp.isReferenceType() || - jtyp.isArrayType()) - jcode.emitDUP(); - else - jtypTag match { // cf. VM spec 3.11.1 - case JType.T_BOOLEAN => jcode.emitDUP(); - case JType.T_CHAR => jcode.emitDUP(); - case JType.T_BYTE => jcode.emitDUP(); - case JType.T_SHORT => jcode.emitDUP(); - case JType.T_INT => jcode.emitDUP(); - case JType.T_FLOAT => jcode.emitDUP(); - case JType.T_REFERENCE => jcode.emitDUP(); - case JType.T_ADDRESS => jcode.emitDUP(); - case JType.T_LONG => jcode.emitDUP2(); - case JType.T_DOUBLE => jcode.emitDUP2(); - } - } - - case MONITOR_ENTER() => jcode.emitMONITORENTER(); - - case MONITOR_EXIT() => jcode.emitMONITOREXIT(); - - case _ => throw(Debug.abort("Invalid ICInstruction for the JVMBackend", instruction)); - } - return stack.eval(instruction); - } - - /* Translate an ATree Test operation to the FJBG type */ - private def condAtoJ(cond : ATestOp) : int = cond match { - case ATestOp.EQ => JExtendedCode.COND_EQ; - case ATestOp.NE => JExtendedCode.COND_NE; - case ATestOp.GE => JExtendedCode.COND_GE; - case ATestOp.LT => JExtendedCode.COND_LT; - case ATestOp.LE => JExtendedCode.COND_LE; - case ATestOp.GT => JExtendedCode.COND_GT; - } - - // ################################################## - // Private methods - Debugging - - private def dumpStructure = { - Debug.log("### Dumping structure ###"); - val sym_it = clasz.keys; - sym_it.foreach((sym: Symbol) => { - val jvmClass = clasz.apply(sym); - Debug.log ("Classfile: ", sym); - Debug.log ("/fileds:"); - val fields_it = jvmClass.fields.keys; - fields_it.foreach((f: Symbol) => { - Debug.log(" ", f); - }); - Debug.log ("/methods:"); - val methods_it = jvmClass.methods.keys; - methods_it.foreach((m: Symbol) => { - Debug.log(" ", m); - }); - }); - Debug.log("#########################"); - } - - //################################################## - // Private methods & fields - // translated from GenJVM - M. Schinz - - private val JAVA_LANG_OBJECT = "java.lang.Object"; - - private def initTypeMap = { - typeMap += defs.ANY_CLASS -> JObjectType.JAVA_LANG_OBJECT; - typeMap += defs.ANYREF_CLASS -> JObjectType.JAVA_LANG_OBJECT; - } - - /** - * Return a Java-compatible version of the name of the given - * symbol. The returned name is mangled and includes the names of - * the owners. - */ - private def javaName(sym: Symbol) = - nameMap.get(sym) match { - case Some(name) => name; - case None => { - val name = global.primitives.getJREClassName(sym); - nameMap += sym -> name; - name; - } - } - - /** - * Return the name of the file in which to store the given class. - */ - private def javaFileName(className : String) = { - val tokens = new StringTokenizer(className, " "); - var file = new File(global.outpath); - while (tokens.hasMoreElements()) { - file = new File(file, tokens.nextToken()); - } - file.getPath()+".class"; - } - - /** - * Return the Java type corresponding to the given Scala type. - */ - private def typeStoJ(tp: Type) : JType = tp match { - case Type$TypeRef(_, sym, _) => - typeMap.get(sym) match { - case Some(jTp) => jTp - case None => { - val jTp = new JObjectType(javaName(sym)); - typeMap += sym -> jTp; - jTp; - } - } - case Type$UnboxedType(TypeTags.BYTE) => JType.BYTE; - case Type$UnboxedType(TypeTags.CHAR) => JType.CHAR; - case Type$UnboxedType(TypeTags.SHORT) => JType.SHORT; - case Type$UnboxedType(TypeTags.INT) => JType.INT; - case Type$UnboxedType(TypeTags.LONG) => JType.LONG; - case Type$UnboxedType(TypeTags.FLOAT) => JType.FLOAT; - case Type$UnboxedType(TypeTags.DOUBLE) => JType.DOUBLE; - case Type$UnboxedType(TypeTags.BOOLEAN) => JType.BOOLEAN; - case Type$UnboxedType(TypeTags.UNIT) => JType.VOID; - case Type$UnboxedType(TypeTags.STRING) => JObjectType.JAVA_LANG_STRING; - case Type$UnboxedArrayType(elementType) => new JArrayType(typeStoJ(elementType)); - - case Type$MethodType(vparams: Array[Symbol], result: Type) => { - val argTypes_a = new Array[JType](vparams.length); - val vparams_it = Iterator.fromArray(vparams); - //val argTypes_it = vparams_it.map((s: Symbol) => typeStoJ(s.info())); - var argTypes_l : List[JType] = Nil; - vparams_it.foreach((s: Symbol) => argTypes_l = typeStoJ(s.info())::argTypes_l); - argTypes_l.reverse.copyToArray(argTypes_a,0); - new JMethodType(typeStoJ(result), argTypes_a); - } - - case _ => - throw Debug.abort("invalid type", tp); - } -} - - -//################################################## -// Data structures - - /* This class represents a Class Context */ -class JVMClass(theParent: JVMClass) { - - /* Methods of the class */ - val methods = new HashMap[Symbol, JVMMethod]; - - /* Fields of the class */ - val fields = new HashMap[Symbol, JField]; - - /* The JClass object corresponding of this class */ - var jClass : JClass = null; - - /* The inner classes of the class */ - var innerClasses : HashMap[Symbol, JVMClass] = null; - - /* The parent class of the class */ - val parent : JVMClass = theParent -} - - /* This class represents a Method context */ -class JVMMethod(theAMethod : AMethod, theOwner : JVMClass){ - - /* The ATree object representing this method */ - val aMethod : AMethod = theAMethod; - - /* The FJBG's object representing this method */ - var jMethod : JMethod = null; - - /* The locals variables of the method */ - val locals = new HashMap[Symbol, JLocalVariable]; - - /* The arguments of the method */ - val args = new HashMap[Symbol, int]; - - /* The JVM code of the method */ - var jCode : JExtendedCode = null; - - /* The owner class of the method */ - val owner : JVMClass = theOwner; - - /* The labels of the IBasicBlock's composing the ICode */ - val labels = new HashMap[IBasicBlock, JCode$Label]; -} - } diff --git a/sources/scala/tools/scalac/icode/IBasicBlock.scala b/sources/scala/tools/scalac/icode/IBasicBlock.scala deleted file mode 100644 index 6eb073468f..0000000000 --- a/sources/scala/tools/scalac/icode/IBasicBlock.scala +++ /dev/null @@ -1,143 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - - -// $Id$ - -import scalac.symtab._; -import scalac.atree._; - -package scala.tools.scalac.icode { - - - - -/** This class represents a basic block */ -class IBasicBlock (theLabel: int) { - - //################################################## - // Public fields - - /* The type stack at the begining of the block */ - var initialStack : ICTypeStack = null; - - /* The label of the block */ - val label = theLabel; - - /* The substitute variables of the block - * in the case of a recursive method */ - var substituteVars : List[Symbol] = null; - - /* The stack at the end of the block */ - var endStack : ICTypeStack = null; - - - - /* The successors of this block */ - //var successors : List[IBasicBlock] = Nil; - - /* Is the block closed*/ - //var isClosedBlock : boolean = false; - - //################################################## - // Private fields - - /* ICode instructions */ - private var instructions : List[ICInstruction] = Nil; - - private var lastInstruction : ICInstruction = null; - - private var closed : boolean = false; - - //################################################## - // Public methods - - /* Compute an hashCode for the block */ - override def hashCode() = label; - - /* Apply a function to all the instructions of the block*/ - def bbTraverse(f: ICInstruction => unit) = - instructions.reverse.foreach(f); - - - /* Initialize the stack of the block, must be done before evaluing - * the type stack */ - def initStack(stack : ICTypeStack) = { - if (initialStack == null) { - initialStack = stack; - endStack = null; - } - } - - /* Add a new instruction at the end of the block */ - def emit(instr: ICInstruction) = { - assert (!closed, "IBasicBlock closed."); - instructions = instr::instructions; - lastInstruction = instr; - } - - /* Compute the type stack of the block */ - def typeBlock = { - assert(initialStack != null, "Stack not initialized"); - endStack = initialStack; - bbTraverse((ic : ICInstruction) => endStack = endStack.eval(ic)); - } - - /* Add a successor to the block */ - //def addSuccessor(s: IBasicBlock) = - // if (!successors.contains(s)) - // successors = s::successors; - - /* Add a list of successors to the block */ - //def addSuccessors(ss: List[IBasicBlock]) = - // ss.reverse.foreach(addSuccessor); - - /* Close the block */ - def close = { - //successors; // assertion - closed = true; - } - - def isClosedBlock = closed; - - def getLastInstruction = lastInstruction; - - def successors : List[IBasicBlock] = // here order will count - lastInstruction match { - case JUMP (where) => List(where); - case CJUMP(success, failure, _) => failure::success::Nil; - case CZJUMP(success, failure, _) => failure::success::Nil; - case SWITCH(_,labels) => labels; - case _ => { - assert ((lastInstruction.isInstanceOf[RETURN]), "The last instruction is not a control flow instruction"); - Nil; - } - } - - - //################################################## - // Public methods - printing (used for debbuging) - // Instead of it, rather use a printer - def print() : unit = print(System.out); - - def print(out: java.io.PrintStream) : unit = { - out.println("block #"+label+" :"); - instructions.reverse.foreach( - (i: ICInstruction) => out.println(" "+i)); - out.print("Successors: "); - successors.foreach((x: IBasicBlock) => out.print(" "+x.label.toString())); - out.println(); - } - - // ################################################## - // Private methods - - // none. - -} - -} - diff --git a/sources/scala/tools/scalac/icode/ICInstruction.scala b/sources/scala/tools/scalac/icode/ICInstruction.scala deleted file mode 100644 index db1ed3c180..0000000000 --- a/sources/scala/tools/scalac/icode/ICInstruction.scala +++ /dev/null @@ -1,358 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - - -// $Id$ - - -import scalac.symtab._; - -import scalac.atree._; - -package scala.tools.scalac.icode { - - - - -/** This class represents an instruction of intermediate code */ -abstract class ICInstruction { - - /** This abstract method returns the number of used elements on the stack */ - def consumed : int = 0; // !!! - - /** This abstract method returns the number of produced elements on the stack */ - def produced : int = 0; // !!! - - /** This method returns the difference of size of the stack when the instruction is used */ - def difference = produced-consumed; -} - -//################################################## -// Instruction cases - -/** This class represents a THIS instruction - * Stack: ... - * ->: ...:ref - */ -case class THIS(clasz: Symbol) extends ICInstruction { - /** Returns a string representation of this constant */ - override def toString(): String = "THIS"; - - override def consumed = 0; - override def produced = 1; -} - -/** This class retpresents a CONSTANT instruction - * Stack: ... - * ->: ...:constant - */ -case class CONSTANT(constant: AConstant) extends ICInstruction{ - /** Returns a string representation of this constant */ - override def toString(): String = "CONSTANT ("+constant.toString()+")"; - - override def consumed = 0; - override def produced = 1; -} - -/** This class represents a LOAD_ARRAY_ITEM instruction - * Stack: ...:array[a](Ref):index(Int) - * ->: ...:element(a) - */ -case class LOAD_ARRAY_ITEM() extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "LOAD_ARRAY_ITEM"; - - override def consumed = 2; - override def produced = 1; -} - -/** This class represents a LOAD_LOCAL instruction - * Stack: ... - * ->: ...:value - */ -case class LOAD_LOCAL(local: Symbol, isArgument: boolean) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "LOAD_LOCAL "+local.toString(); //+isArgument?" (argument)":""; - - override def consumed = 0; - override def produced = 1; -} - -/** This class represents a LOAD_FIELD instruction - * Stack: ...:ref - * ->: ...:value - */ -case class LOAD_FIELD(field: Symbol, isStatic: boolean) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "LOAD_FIELD "+field.toString(); //+isStatic?" (static)":""; - - override def consumed = 1; - override def produced = 1; -} - -/** This class represents a STORE_ARRAY_ITEM instruction - * Stack: ...:array[a](Ref):index(Int):value(a) - * ->: ... - */ -case class STORE_ARRAY_ITEM() extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "STORE_ARRAY_ITEM"; - - override def consumed = 3; - override def produced = 0; -} - -/** This class represents a STORE_LOCAL instruction - * Stack: ...:value - * ->: ... - */ -case class STORE_LOCAL(local: Symbol, isArgument: boolean) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "STORE_LOCAL "+local.toString(); //+isArgument?" (argument)":""; - - override def consumed = 1; - override def produced = 0; -} - -/** This class represents a STORE_FIELD instruction - * Stack: ...:ref:value - * ->: ... - */ -case class STORE_FIELD(field: Symbol, isStatic: boolean) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "STORE_FIELD "+field.toString(); //+isStatic?" (static)":""; - - override def consumed = 2; - override def produced = 0; -} - -/** This class represents a CALL_PRIMITIVE instruction - * Stack: ...:arg1:arg2:...:argn - * ->: ...:result - */ -case class CALL_PRIMITIVE(primitive: APrimitive) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="CALL "+primitive.toString(); - - override def consumed = primitive match { - case (APrimitive$Negation(_)) => 1; - case (APrimitive$Test(_,_,true)) => 1; - case (APrimitive$Test(_,_,false)) => 2; - case (APrimitive$Comparison(_,_)) => 2; - case (APrimitive$Arithmetic(_,_)) => 2; - case (APrimitive$Logical(_,_)) => 2; - case (APrimitive$Shift(_,_)) => 2; - case (APrimitive$Conversion(_,_)) => 1; - case (APrimitive$ArrayLength(_)) => 1; - case (APrimitive$StringConcat(_,_)) => 2; - } - override def produced = 1; -} - -/** This class represents a CALL_METHOD instruction - * STYLE: dynamic / static(StaticInstance) - * Stack: ...:ref:arg1:arg2:...:argn - * ->: ...:result - * - * STYLE: new - unused by jvm - * Stack: ...:arg1:arg2:...:argn - * ->: ...:ref - * - * STYLE: static(StaticClass) - * Stack: ...:arg1:arg2:...:argn - * ->: ...:result - * - */ -case class CALL_METHOD(method: Symbol, style: AInvokeStyle) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="CALL_METHOD "+method.toString()+" ("+style.toString()+")"; - - override def consumed = { - var result = method.getType().valueParams().length; - result = result + (style match - {case(AInvokeStyle.Dynamic) => 1 - case(AInvokeStyle.StaticInstance) => 1 - case(_) => 0 }); - result; - } - override def produced = 1; -} - -/** This class represents a NEW instruction - * Stack: ...: - * ->: ...:ref - */ - case class NEW(clasz: Symbol) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String = "NEW "+clasz.toString(); - - override def consumed = 0; - override def produced = 1; - } - - - /** This class represents a CREATE_ARRAY instruction - * Stack: ...:size(int) - * ->: ...:arrayref - */ -case class CREATE_ARRAY(element: Type) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="CREATE_ARRAY "+element.toString(); - - override def consumed = 1; - override def produced = 1; -} - - /** This class represents a IS_INSTANCE instruction - * Stack: ...:ref - * ->: ...:result(boolean) - */ -case class IS_INSTANCE(typ: Type) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="IS_INSTANCE "+typ.toString(); - - override def consumed = 1; - override def produced = 1; -} - -/** This class represents a CHECK_CAST instruction - * Stack: ...:ref(oldtype) - * ->: ...:ref(typ <=: oldtype) - */ -case class CHECK_CAST(typ: Type) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="CHECK_CAST "+typ.toString(); - - override def consumed = 1; - override def produced = 1; -} - -/** This class represents a SWITCH instruction - * Stack: ...:index(int) - * ->: ...: - */ -case class SWITCH(tags: Array[Array[int]], labels: List[IBasicBlock]) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="SWITCH ..."; - - override def consumed = 1; - override def produced = 0; -} - -/** This class represents a JUMP instruction - * Stack: ... - * ->: ... - */ -case class JUMP(where: IBasicBlock) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="JUMP "+where.label; - - override def consumed = 0; - override def produced = 0; -} - -/** This class represents a CJUMP instruction - * It compares the two values on the stack with the 'cond' test operator - * Stack: ...:value1:value2 - * ->: ... - */ -case class CJUMP(successBlock: IBasicBlock, failureBlock: IBasicBlock, cond: ATestOp) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="CJUMP "+cond.toString()+" ? "+successBlock.label+" : "+failureBlock.label; - - override def consumed = 2; - override def produced = 0; -} - -/** This class represents a CZJUMP instruction - * It compares the one value on the stack and zero with the 'cond' test operator - * Stack: ...:value: - * ->: ... - */ -case class CZJUMP(successBlock: IBasicBlock, failureBlock: IBasicBlock, cond: ATestOp) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="CZJUMP "+cond.toString()+" ? "+successBlock.label+" : "+failureBlock.label; - - override def consumed = 1; - override def produced = 0; -} - - -/** This class represents a RETURN instruction - * Stack: ... - * ->: ... - */ -case class RETURN() extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="RETURN"; - - override def consumed = 0; - override def produced = 0; -} - -/** This class represents a THROW instruction - * Stack: ...:Throwable(Ref) - * ->: ...: - */ -case class THROW() extends ICInstruction { -/** Returns a string representation of this instruction */ - override def toString(): String ="THROW"; - - override def consumed = 1; - override def produced = 0; -} - -/** This class represents a DROP instruction - * Stack: ...:something - * ->: ... - */ -case class DROP (typ: Type) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="DROP "+typ.toString(); - - override def consumed = 1; - override def produced = 0; -} - - /** This class represents a DUP instruction - * Stack: ...:something - * ->: ...:something:something - */ - case class DUP (typ: Type) extends ICInstruction { - /** Returns a string representation of this instruction */ - override def toString(): String ="DUP"; - - override def consumed = 1; - override def produced = 2; - } - - /** This class represents a MONITOR_ENTER instruction - * Stack: ...:object(ref) - * ->: ...: - */ - case class MONITOR_ENTER() extends ICInstruction { - - /** Returns a string representation of this instruction */ - override def toString(): String ="MONITOR_ENTER"; - - override def consumed = 1; - override def produced = 0; - } - - /** This class represents a MONITOR_EXIT instruction - * Stack: ...:object(ref) - * ->: ...: - */ - case class MONITOR_EXIT() extends ICInstruction { - - /** Returns a string representation of this instruction */ - override def toString(): String ="MONITOR_EXIT"; - - override def consumed = 1; - override def produced = 0; - } - -} diff --git a/sources/scala/tools/scalac/icode/ICTypeStack.scala b/sources/scala/tools/scalac/icode/ICTypeStack.scala deleted file mode 100644 index c7b2110190..0000000000 --- a/sources/scala/tools/scalac/icode/ICTypeStack.scala +++ /dev/null @@ -1,147 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.atree._; -import scalac.symtab._; -import scalac.{Global => scalac_Global}; - -package scala.tools.scalac.icode { - - - -/* This class simulates the type of the opperand - * stack of the ICode. */ -class ICTypeStack() { - - // ################################################## - // Private fields - private var stack : List[Type] = Nil; - - private val global = scalac_Global.instance; - - private val definitions = global.definitions; - - private val typer = definitions.atyper; // !!! Using atree typer ! - - // ################################################## - // Private constructor - - private def this(stack : List[Type]) = { - this(); - this.stack = stack; - } - - // ################################################## - // Public method - - /* This methods simulate the effect of an ICInstruction - * on the stack. It returns the new stack */ - def eval(instr: ICInstruction) : ICTypeStack = { - global.log(instr.toString()); - if (stack.length < instr.consumed) { - global.log("Invalid instruction :"+instr+" for stack "+toString()); - this; - } else { - val result = new ICTypeStack(erase(production(instr)):::stack.drop(instr.consumed)); /// !!! Opt - global.log("\t-> "+result.toString()); - result; - } - } - - // ################################################## - // Public methods - Operation on the stack - - /* Push a new type */ - def push(t: Type) = stack = t::stack; - - /* Returns the topmost type of the stack */ - def head = stack.head; - - /* Returns the stack without the topmost element */ - def tail = stack.tail; - - /* Is the stack empty ? */ - def isEmpty = stack.isEmpty; - - // ################################################## - // Private methods - - /* Compute what type(s) the instruction produce on the stack */ - private def production(instr: ICInstruction) : List[Type] = instr match { - case THIS(clasz) => clasz.thisType()::Nil; - - case CONSTANT(aConstant) => typer.computeType(aConstant)::Nil; - - case LOAD_ARRAY_ITEM() => typer.getArrayElementType(stack.tail.head)::Nil; - - case LOAD_LOCAL(local, _) => local.getType()::Nil; - - case LOAD_FIELD(field, _) => stack.head.memberStabilizedType(field)::Nil; // ?? - - case STORE_ARRAY_ITEM() => Nil; - - case STORE_LOCAL(_,_) => Nil; - - case STORE_FIELD(_,_) => Nil; - - case CALL_PRIMITIVE(p) => typer.computeType(p)::Nil; - - case CALL_METHOD(method, style) => style match { - //case AInvokeStyle.Dynamic => stack.head.memberStabilizedType(method)::Nil; // ??? - //case AInvokeStyle.Dynamic => stack.drop(method.getType().valueParams().length).head.resultType()::Nil; - case AInvokeStyle.New => method.owner().thisType()::Nil; - - case _ => method.resultType()::Nil; // Valable pour Dynamic - //case _ => method.owner().thisType().memberStabilizedType(method)::Nil; // ??? - } - case NEW(clasz) => clasz.getType()::Nil; - - case CREATE_ARRAY(element) => definitions.array_TYPE(element)::Nil; - - case IS_INSTANCE(_) => definitions.boolean_TYPE()::Nil; - - case CHECK_CAST(typ) => typ::Nil; - - case SWITCH(_,_) => Nil; - - case JUMP(_) => Nil; - - case CJUMP(_,_,_) => Nil; - - case CZJUMP(_,_,_) => Nil; - - case RETURN() => Nil; - - case THROW() => Nil; - - case DROP(_) => Nil; - - case DUP(_) => stack.head::stack.head::Nil; - - case MONITOR_ENTER() => Nil; - - case MONITOR_EXIT() => Nil; - } - - /* This method kill all the produced *Unit* elements */ - // !!! Hack - private def erase(production : List[Type]) = production.filter((t: Type) => t match { - case Type$UnboxedType(TypeTags.UNIT) => false; - case _ => true - }); - - /* This method returns a String representation of the stack */ - // !!! POUAH SALE ! - override def toString() = { - var ret : String = ""; - stack.foreach((t: Type) => ret=(t.toString()+"::")+ret); - ret; - - } -} -} diff --git a/sources/scala/tools/scalac/icode/ICode.scala b/sources/scala/tools/scalac/icode/ICode.scala deleted file mode 100644 index 514c15e0e5..0000000000 --- a/sources/scala/tools/scalac/icode/ICode.scala +++ /dev/null @@ -1,492 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global} - -import scala.collection.mutable.HashMap; -import scala.collection.mutable.HashSet; - -import scalac.symtab._; -import scalac.atree._; -import scalac.util.Debug; - -package scala.tools.scalac.icode { - - - -/** This class represents the intermediate code of a method*/ -class ICode(label: String, global: scalac_Global) { - - //################################################## - // Public fields - - /* The set of all blocks */ - val blocks: HashSet[IBasicBlock] = new HashSet; - - /* The start block of the method */ - var startBlock : IBasicBlock = null; - - /* The stack produced by this method */ - var producedStack : ICTypeStack = null; - - //################################################## - // Private fields - private var currentLabel : int = 0; - - private var aTreeLabels : HashMap[Symbol, IBasicBlock] = new HashMap; - - //################################################## - // Constructor code - - startBlock = newBlock; - startBlock.initStack(new ICTypeStack); - - //################################################## - // Public methods - - /** This method produce the intermediate code for - * the given ATree */ - def generate(acode : ACode) = { - val ctx = gen(acode, new GenContext(startBlock, null)); - - ctx.emit(RETURN()); // ??? RETURN instruction rather come from ATree - genTypeStack; - - producedStack = ctx.currentBlock.endStack; - } - - def icTraverse(f: IBasicBlock => unit) = icTraverseFeedBack((bb: IBasicBlock, hm: HashMap[IBasicBlock, boolean]) => f(bb)); - - /* This method applies the given function to all the block */ - def icTraverseFeedBack(f: (IBasicBlock, HashMap[IBasicBlock, boolean]) => unit) = { - // ?? Define order (actually preorder) - val visited : HashMap[IBasicBlock, boolean] = new HashMap; - visited ++= blocks.elements.map(x => Pair(x, false)); - - var blockToVisit : List[IBasicBlock] = startBlock::Nil; - - while (blockToVisit != Nil) { - blockToVisit match { - case b::xs => { - if (!visited(b)) { - f(b, visited); - blockToVisit = b.successors:::xs; - visited += b -> true; - } else - blockToVisit = xs; - } - } - } - } - - - /** This methods returns a string representation of the ICode */ - override def toString() : String = "ICode '"+label+"'"; // - - //################################################## - // Public method - printing (for debug use) - - /** This method print the code */ - def print() : unit = print(System.out); - - def print(out: java.io.PrintStream) : unit = { - icTraverse((bb: IBasicBlock) => { - out.println("Block #"+bb.label); - out.println("Substituable variables : "); - if (bb.substituteVars != null) - bb.substituteVars.foreach(out.print); - else - out.println(" {Empty} "); - out.println("Instructions:"); - bb.bbTraverse((ici: ICInstruction) => - out.println(" "+ici.toString())); - out.print ("Successors: "); - bb.successors.foreach((bb: IBasicBlock) => out.print(bb.label+", ")); - out.println (""); // ?? Del - out.println (); - }); - } - - - def logType = { - global.log ("// Typing "+toString()); - this.icTraverse((bb: IBasicBlock) => { - global.log ("Typing block #"+bb.label); - var typer = new ICTypeStack; - bb.bbTraverse((ic: ICInstruction) => { - typer = typer.eval(ic); - global.log(ic.toString()+" -> "+typer.toString()); - }); - - }); - } - - //################################################## - // Private methods - - /* Compute a unique new label */ - private def nextLabel = { - currentLabel = currentLabel + 1; - currentLabel; - } - - /* This method : - * 1/ create a new block - * 2/ add the new block to the set - * 3/ return the new block - */ - private def newBlock : IBasicBlock = { - val block = new IBasicBlock(nextLabel); - blocks += block; - block; - } - - /* Generate the code from a given ATree */ - private def gen(aCode: ACode, ctx: GenContext) : GenContext = - aCode match { - case ACode.Void => { - global.log ("ICodeGenerator::emit: Void node found"); - ctx; - } - - case ACode$This(clasz) => - ctx.emit(THIS(clasz)); - - case ACode$Constant(c) => - ctx.emit(CONSTANT(c)); - - case ACode$Load(ALocation$Module(_)) => { - global.log ("ICodeGenerator::emit: Load(Module) node found"); - ctx; - } - - case ACode$Load(ALocation$Field(obj, field ,isStatic)) => { - var ctx1 = gen(obj, ctx); - ctx.emit(LOAD_FIELD(field, isStatic)); - } - - case ACode$Load(ALocation$Local(local,isArgument)) => - ctx.emit(LOAD_LOCAL(local, isArgument)); - - case ACode$Load(ALocation$ArrayItem(array, index)) => { - var ctx1 = gen(array, ctx); - ctx1 = gen(index, ctx1); - ctx1.emit(LOAD_ARRAY_ITEM()); - } - - case ACode$Store(ALocation$Module(_),_) => { - global.log ("ICodeGenerator::emit: Store(Module(_)) node found"); - ctx; - } - - case ACode$Store(ALocation$Field(obj, field, isStatic), value) => { - var ctx1 = gen(obj, ctx); - ctx1 = gen(value, ctx1); - ctx1.emit(STORE_FIELD(field, isStatic)); - } - - case ACode$Store(ALocation$Local(local, isArgument), value) => { - val ctx1 = gen(value, ctx); - ctx1.emit(STORE_LOCAL(local, isArgument)); - } - - case ACode$Store(ALocation$ArrayItem(array, index), value) => { - var ctx1 = gen(array, ctx); - ctx1 = gen(index, ctx1); - ctx1 = gen(value, ctx1); - ctx1.emit(STORE_ARRAY_ITEM()); - } - - case ACode$Apply(AFunction$Method(_,sym,AInvokeStyle.New),_,vargs) => { - val vargs_it = Iterator.fromArray(vargs); - // !!! Depend the backend in use - ctx.emit(NEW(sym.owner())); - ctx.emit(DUP(sym.owner().getType())); - var ctx1 = ctx; - vargs_it.foreach((varg: ACode) => ctx1 = gen(varg, ctx1)); - ctx1.emit(CALL_METHOD(sym,AInvokeStyle.StaticInstance)); - } - - case ACode$Apply(AFunction$Method(obj,sym,style),_,vargs) => { - val vargs_it = Iterator.fromArray(vargs); - var ctx1 = ctx; - style match { - case AInvokeStyle.StaticClass => - ; // NOP - case _ => - ctx1 = gen(obj, ctx1); - } - vargs_it.foreach((varg: ACode) => ctx1 = gen(varg, ctx1)); - ctx1.emit(CALL_METHOD(sym,style)); - } - - case ACode$Apply(AFunction$Primitive(p),_,vargs) => { - val vargs_it = Iterator.fromArray(vargs); - var ctx1 = ctx; - - vargs_it.foreach((varg: ACode) => ctx1 = gen(varg, ctx1)); - ctx1.emit(CALL_PRIMITIVE(p)); - } - - case ACode$Apply(AFunction$NewArray(element),_,vargs) => { - var ctx1 = gen(vargs(0), ctx); // The size is given as first argument - ctx1.emit(CREATE_ARRAY(element)); - } - - case ACode$IsAs(value,typ,false) => { - var ctx1 = gen(value, ctx); - ctx1.emit(IS_INSTANCE(typ)); - } - - case ACode$IsAs(value,typ,true) => { - var ctx1 = gen(value, ctx); - ctx1.emit(CHECK_CAST(typ)); - } - - case ACode$If(test, success, failure) => { - genAlt(test, success, failure, ctx, newBlock); - } - - case ACode$Switch(test,tags,bodies) => { - - val switchBodies = List.fromArray(bodies, 0, bodies.length); - var switchBlocks: List[IBasicBlock] = Nil; - for (val i : ACode <- switchBodies) switchBlocks = newBlock::switchBlocks; - val switchPairs = switchBodies.zip(switchBlocks); - - val nextBlock = newBlock; - - var ctx1 = gen(test, ctx); - ctx1.emit(SWITCH(tags, switchBlocks)); - //ctx1.currentBlock.addSuccessors(switchBlocks); - - switchPairs.foreach((p: Pair[ACode, IBasicBlock]) => { - val code = p._1; - val block = p._2; - - val ctx2 = gen(code, new GenContext(block, nextBlock)); - ctx2.closeBlock; - }); - - ctx1.changeBlock(nextBlock); - } - - case ACode$Synchronized(lock, value) => { - var ctx1 = gen(lock, ctx); - ctx1.emit(MONITOR_ENTER()); - ctx1 = gen(value,ctx); - ctx1 = gen(lock, ctx); - ctx1.emit(MONITOR_EXIT()); - } - - case ACode$Block(_,statements,value) => { - val statements_it = Iterator.fromArray(statements); - var ctx1 = ctx; - statements_it.foreach((st: ACode) => ctx1 = gen(st, ctx1)); - ctx1 = gen(value, ctx1); - ctx1; - } - - case ACode$Label(label, locals, value) => { - global.log("Add new label: "+label); - - val loopBlock = newBlock; - var ctx1 = ctx.changeBlock(loopBlock); - ctx.nextBlock = loopBlock; - ctx.closeBlock; - - aTreeLabels += label -> loopBlock; - - loopBlock.substituteVars = List.fromIterator(Iterator.fromArray(locals)); - gen(value, ctx1); - } - - case ACode$Goto(label,vargs) => { - - val vargs_it = Iterator.fromArray(vargs); - global.log("Current label mapping: "+aTreeLabels.keys.foreach((s: Symbol) => global.log(s.toString()))); - global.log("Looking for sym: "+label); - val gotoBlock = aTreeLabels(label); - var ctx1 = ctx; - - // Stack-> : - vargs_it.foreach((varg: ACode) => ctx1 = gen(varg, ctx1)); - - // Stack-> :varg0:varg1:...:vargn - // We should have the same number of varg that substitute vars - - gotoBlock.substituteVars.reverse.foreach( - (varg: Symbol) => ctx1.emit(STORE_LOCAL(varg, false)) // ?? false - ); - ctx1.nextBlock = gotoBlock; - ctx1.closeBlock; - - ctx1; - } - - case ACode$Return(_,value) => { - var ctx1 = gen(value, ctx); - ctx1.emit(RETURN()); - } - case ACode$Throw(value) => { - var ctx1 = gen(value, ctx); - ctx1.emit(THROW()); - } - - case ACode$Drop(value, typ) => { - var ctx1 = gen(value, ctx); - //global.log("Type de Drop: "+typ+" = unboxed:"+typ.unbox() ); - if (! typ.isSameAs(global.definitions.void_TYPE())) - typ.unbox() match { // !!! Hack - case Type$UnboxedType(TypeTags.UNIT) => - global.log("it matches UNIT !"); // debug ; // NOP - case _ => - ctx1.emit(DROP(typ)); - } - else - global.log("it matches SCALAC_UNIT :-("); - ctx1; - } - } - - /* This method genrates an alternative. In the case of an if instruction - * It looks at the kind of alternatives and creates new basic blocks - * - * @param nextBlock : represents the block where alternatives meet again*/ - private def genAlt (cond : ACode, success: ACode, failure: ACode, ctx: GenContext, nextBlock: IBasicBlock) : GenContext = { - val successBlock = success match { - case ACode.Void => nextBlock; - - case ACode$If(test, innerSuccess, innerFailure) => { - val ctx1 = new GenContext(newBlock, null); - val ctx2 = genAlt(test, innerSuccess, innerFailure, ctx1, nextBlock); - //ctx2.closeBlock; // or close when CJUMP is emitted - ctx1.currentBlock; - } - - case _ => { - val ctx1 = new GenContext(newBlock, nextBlock); - val ctx2 = gen(success, ctx1); - ctx2.closeBlock; - ctx1.currentBlock; - } - } - - val failureBlock = failure match { - case ACode.Void => nextBlock; - - case ACode$If(test, innerSuccess, innerFailure) => { - val ctx1 = new GenContext(newBlock, null); - val ctx2 = genAlt(test, innerSuccess, innerFailure, ctx1, nextBlock); - //ctx2.closeBlock; // or close when CJUMP is emitted - ctx1.currentBlock; - } - - case _ => { - val ctx1 = new GenContext(newBlock, nextBlock); - val ctx2 = gen(failure, ctx1); - ctx2.closeBlock; - ctx1.currentBlock; - } - } - - var ctx1 = genCond(cond, successBlock, failureBlock, ctx); - ctx1.changeBlock(nextBlock); - } - - /* This methods generate the test and the jump instruction */ - private def genCond(cond: ACode, successBlock: IBasicBlock, failureBlock: IBasicBlock, ctx: GenContext) : GenContext= { - var ctx1 = ctx; - cond match { - case ACode$Apply(AFunction$Primitive(APrimitive$Test(op,_,zero)),_, vargs) => { - ctx1 = gen(vargs(0),ctx1); - if (zero) - ctx1.emit(CZJUMP(successBlock, failureBlock, op)); - else { - ctx1 = gen(vargs(1), ctx1); - ctx1.emit(CJUMP(successBlock, failureBlock, op)); - } - //ctx1.currentBlock.addSuccessors(failureBlock::successBlock::Nil); - } - - case ACode$Apply(AFunction$Primitive(APrimitive$Negation(_)),_,vargs) => - ctx1 = genCond(vargs(0), failureBlock, successBlock, ctx1); - // ??? Test with TestOp opposite ? - case _ => { - ctx1 = gen(cond, ctx1); - //ctx1.emit(CONSTANT(AConstant.INT(1))); - // We have a boolean value - ctx1.emit(CZJUMP(successBlock, failureBlock, ATestOp.NE)); - //ctx1.currentBlock.addSuccessors(failureBlock::successBlock::Nil); - } - } - ctx1; - } - - /* This method generate the type stacks of all the blocks - * of this method.*/ - private def genTypeStack = { - icTraverse((bb: IBasicBlock) => { - global.log("// Typing block #"+bb.label); - global.log("\t-> "+bb.endStack); - bb.typeBlock; - // !!! Here we must test if all the meeting blocks have the - // !!! same stack. - bb.successors.foreach((suc: IBasicBlock) => suc.initStack(bb.endStack)); - }); - } - -} - - /* This class represents the context of generating icode */ - class GenContext(current: IBasicBlock, next: IBasicBlock) { - - // ################################################## - // Public fields - - /* The block in which we add instructions */ - val currentBlock = current; - - /* The block were we jump at the end of the current block - * It can be the *null* value */ - var nextBlock = next; - - // ################################################## - // Constructor code - - assert(current != null, "No current block"); - - // ################################################## - // Public methods - - /* append an instruction at the end of the current block */ - def emit(instr: ICInstruction) : GenContext = { - currentBlock.emit(instr); - this; - } - - /* Split the current block. The next block is still the same */ - def changeBlock(bb: IBasicBlock) = { - new GenContext(bb, next); - } - - /* Close the current block. If there's a known next block - * It append a jump instruction to the block. - * This method do something only the first time it's called */ - def closeBlock = { - if (!currentBlock.isClosedBlock) { - if (nextBlock != null) { - emit(JUMP(nextBlock)); - //currentBlock.addSuccessor(nextBlock); - } - currentBlock.close; - } - } - } - -} // package diff --git a/sources/scala/tools/scalac/icode/ICodePhase.scala b/sources/scala/tools/scalac/icode/ICodePhase.scala deleted file mode 100644 index d0408b5544..0000000000 --- a/sources/scala/tools/scalac/icode/ICodePhase.scala +++ /dev/null @@ -1,67 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.symtab._; -import scalac.transformer.{ICodePhase => scalac_ICodePhase} -import scalac.{Global => scalac_Global} -import scalac.CompilationUnit; -import scalac.PhaseDescriptor; -import scalac.Phase; -import scalac.atree._; - -import ch.epfl.lamp.util.CodePrinter; - -package scala.tools.scalac.icode { - - - - -/** This class represents the ICode phase. This phase use the ATrees - * that represents the code with some primitives backends-like - * and convert them in a inline form: The ICode (for intermediate - * code). The ICode will be produced in the icode variable - * of all AMethod objects. */ -class ICodePhase(global: scalac_Global, descriptor: PhaseDescriptor) extends scalac_ICodePhase (global, descriptor) { - - // ################################################## - // Public methods - - /** Applies this phase to the given compilation unit. */ - override def apply(unit: CompilationUnit): Unit = translate(unit); - - /** Prints the given compilation units. */ - override def print(units: Array[CompilationUnit], printer: CodePrinter):Unit= - new ICodePrinter(global, printer).printUnits(units); - - // ################################################## - // Private methods - - /** This method translates a single unit, it traverses all methods and - * generates ICode for each of them */ - private def translate(u: CompilationUnit) : unit = { - def genClass(c: AClass) : unit = { - val nestedClasses_it = Iterator.fromArray(c.classes()); - nestedClasses_it.foreach(genClass); - val methods_it = Iterator.fromArray(c.methods()); - methods_it.foreach((m: AMethod) => { - val label : String = m.symbol().name.toString(); - - val ic : ICode = new ICode(label, global); - ic.generate(m.code()); - - // save the produced ICode - m.icode = ic; - - }); - } - val classes_it = Iterator.fromArray(u.repository.classes()); - classes_it.foreach(genClass); - } - -} -} diff --git a/sources/scala/tools/scalac/icode/ICodePrinter.scala b/sources/scala/tools/scalac/icode/ICodePrinter.scala deleted file mode 100644 index 81bac0a996..0000000000 --- a/sources/scala/tools/scalac/icode/ICodePrinter.scala +++ /dev/null @@ -1,71 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.CompilationUnit; -import scalac.{Global => scalac_Global} - -package scala.tools.scalac.icode { - -/** This class implements a Printer for the ICode. */ -class ICodePrinter(global0: scalac_Global, printer0: CodePrinter) { - - //########################################################################## - // Public Fields - - val global: scalac_Global = global0; - val printer: CodePrinter = printer0; - - //########################################################################## - // Public Methods - - /** Prints the ICode of the given units. */ - def printUnits(units: Array[CompilationUnit]): Unit = { - val phase = global.currentPhase; - printer.println("[[ICode at "+phase+" (after "+phase.prev+")]]"); - Iterator.fromArray(units).foreach(printUnit); - } - - /** Prints the ICode of the given unit. */ - def printUnit(unit: CompilationUnit): Unit = { - printer.println ("// Scala source: "+unit.source); - val classes_it = Iterator.fromArray(unit.repository.classes()); - classes_it.foreach(c => { - printer.println (""); - printer.println ("// ICode for class <"+c.symbol().name+">"); - val methods_it = Iterator.fromArray(c.methods()); - methods_it.foreach(m => { - val icode : ICode = m.icode.asInstanceOf[ICode]; - printer.println ("// ::"+m.symbol().name); - icode.icTraverse((bb: IBasicBlock) => { - printer.println("Block #"+bb.label); - printer.println("Initial stack -> "+bb.initialStack); - printer.println("Substituable variables : "); - if (bb.substituteVars != null) - bb.substituteVars.foreach(s => printer.print(s.name.toString())); - else - printer.println(" {Empty} "); - printer.println("Instructions:"); - printer.indent(); - bb.bbTraverse((ici: ICInstruction) => - printer.println(ici.toString())); - printer.undent(); - printer.println("End stack -> "+bb.endStack); - printer.print ("Successors: "); - bb.successors.foreach((bb: IBasicBlock) => printer.print(bb.label+", ")); - printer.println (""); // ?? Del - printer.println (); - }); - }); - }); - } - - //########################################################################## -} -} diff --git a/sources/scala/tools/scalac/transformer/TransMatch.scala b/sources/scala/tools/scalac/transformer/TransMatch.scala deleted file mode 100644 index 509e922e32..0000000000 --- a/sources/scala/tools/scalac/transformer/TransMatch.scala +++ /dev/null @@ -1,401 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import java.io._; -import java.util.HashMap; -import scalac.{Global => scalac_Global}; -import scalac._; -import scalac.ast._; -import scalac.symtab._; -import scalac.util._; // Names - -import scalac.transformer.{ OwnerTransformer => scalac_transformer_OwnerTransformer }; - - -//import scalac.transformer.matching.PatternMatcher ; -//import scalac.transformer.matching.AlgebraicMatcher ; - -/** A transformer for expanding match expressions into - * flat sequences of .is and .as method calls - * - * @author Matthias Zenger, Burak Emir - * @version 1.1 - */ -package scala.tools.scalac.transformer { - - import matching.PatternMatcher ; - import matching.PartialMatcher ; -//import matching.FullRegularTranslator ; - -class TransMatch( global:scalac_Global ) - extends scalac_transformer_OwnerTransformer( global ) { - - import Tree._ ; - - var cunit:CompilationUnit = null; - - - //def debugLog(s:String) = { - //if(currentOwner.toString().indexOf("fetchToken") != -1) { - //Console.println(s); - //} - //} - - override def apply( cunit:CompilationUnit ):unit = { - this.cunit = cunit; - super.apply( cunit ); - } - - def isRegular(ps:Array[Tree]):Boolean = { - var res = false; - val pats = scala.Iterator.fromArray( ps ); - while (!res && pats.hasNext ) - res = isRegular( pats.next ); - res - } - - def isRegular(pat:Tree):Boolean = pat match { - //case Alternative(_) => true - case Alternative(trees) => - isRegular(trees) - case Bind( n, pat1 ) => - TreeInfo.isNameOfStarPattern( n ) - || TreeInfo.isEmptySequence( pat1 ) - || isRegular( pat1 ) - case Ident(n) => false - case Sequence( trees ) => - ( trees.length == 0 ) || isRegular( trees ); - case Apply( fn, trees ) => - isRegular( trees ) && - !((trees.length == 1) && TreeInfo.isEmptySequence( trees( 0 ))) - case Literal(_) => false; - case Select(_,_) => false; - case Typed(_,_) => false; - case _ => error("in TransMatch.isRegular phase: unknown node"+pat.getClass()); - } - - def nilVariables( pat:Tree ) = { - var res:List[Symbol] = Nil; - def getNilVars1( ps:Array[Tree] ):scala.Unit = { - val z:Seq[Tree] = ps; z.elements.foreach( x => getNilVars( x )); - } - def getNilVars( p:Tree ):scala.Unit = p match { - case Alternative( _ ) => /* no bind allowed! */ - case Bind( _, pat ) => - getNilVars(pat); - if( TreeInfo.isEmptySequence( pat ) ) - res = p.symbol() :: res; - case Ident(_) => - case Sequence( trees ) => getNilVars1( trees ) - case Apply( _, args ) => getNilVars1( args ) - case Literal(_) => - case Select(_,_) => - case Typed(_,_) => - case _ => error("in TransMatch.nilVariables: unknown node"+pat.getClass()); - } - getNilVars( pat ); - res - } - - // 2do: remove binds from pattern - def handleNilVariables( cse: CaseDef ): Unit = { - val nilvars = nilVariables(cse.pat); - if( !nilvars.isEmpty ) { - val newBody = new Array[Tree]( nilvars.length ); - var j=0; - for( val v <- nilvars.elements ) { - val n = gen.mkNil( cse.pos ); - newBody( j ) = gen.ValDef( v, n ); - j = j + 1; - } - cse.body = gen.mkBlock( newBody, cse.body ); - } - } - - - /** removes alternative notes by unfolding them, adding casedefs, - * and duplication righthand sides - * - * @pre cases are all nonregular - */ - def removeAlterns(cases: Array[CaseDef]) = { - - //debugLog("removeAlterns called![ currentOwner = "+currentOwner+" ["); - // var jjj = 0; while (jjj<cases.length) { - // debugLog(cases(jjj).toString()); - // jjj = jjj + 1; - //} - //debugLog("]"); - - def lst2arr(l:List[Tree]):Array[Tree] = { - val res = new Array[Tree](l.length); - val it = l.elements; var i = 0; while(it.hasNext) { - res(i) = it.next; - i = i + 1; - } - res - } - def select(j:int, expanded:Array[List[Tree]]): List[List[Tree]] = { - if( j == expanded.length ) - List(scala.Nil); - else { - val rest:List[List[Tree]] = select(j+1, expanded); - //expanded(j) map { x:Tree => rest map { xs:List[Tree] => x :: xs }} - for(val t <- expanded(j); - val zs <- rest) - yield t :: zs; - } - } - - def newCloner() = { - val sc = new SymbolCloner(); - sc.owners.put(currentOwner,currentOwner); - - new GenTreeCloner(global, Type.IdMap, sc) { - - override def getSymbolFor(tree:Tree): Symbol = { - //Console.println("getSymbolFor "+tree.getClass()); - tree match { - case Bind(_,_) => - val symbol = cloner.cloneSymbol(tree.symbol()); - - //System.out.println("TreeCloner: Bind"+symbol); - //System.out.println("TreeCloner: Bind - old owner "+tree.symbol().owner()); - //System.out.println("TreeCloner: Bind - new owner "+symbol.owner()); - //Console.println("in TreeCloner: type = "+symbol.getType()); - symbol.setType(transform(symbol.getType())); - //Console.println("in TreeCloner: type (post) = "+symbol.getType()); - //System.out.println("done TreeCloner: Bind"+symbol); - return symbol; - - case _ : ClassDef => - - throw new ApplicationError("sorry, cannot compile this correctly in this scala version. Move your classes, fundefs etc out of the pattern body, please, and wait for nsc."); - case _ : DefDef => - throw new ApplicationError("sorry, cannot compile this correctly in this scala version. Move your classes, fundefs etc out of the pattern body, please, and wait for nsc."); - // tree.symbol(); - - case Ident(_) if tree.symbol() == global.definitions.PATTERN_WILDCARD => - tree.symbol() - - case _ => - super.getSymbolFor(tree); - } - - } - } - } - - def remove(pat:Tree): List[Tree] = { - //Console.println("remove("+pat+"), currentOwner = "+currentOwner); - val res = pat match { - case Alternative( branches ) => // no bind allowed! - val z: Seq[Tree] = branches; - List.flatten(z.toList.map( remove )); - case b @ Bind( n, pat ) => - //Console.println("remove-Bind sym-owner: "+b.symbol().owner()); - remove(pat) match { - case List(r) if (r eq pat) => - List(b); - case zs => - //Console.println("remove-Bind sym: "+b.symbol()); - //Console.println("remove-Bind sym-type: "+b.symbol().getType()); - //Console.println("rb-(case zs)"+zs); - zs map { x => //Console.println(b.symbol()); - val r = new ExtBind(b.symbol(),x); - r.setType(b.getType()); - //Console.println("rrrrr ="+ r.getType()); - r - }; - } - case Sequence( trees ) => - val expanded = new Array[List[Tree]](trees.length); - var i = 0; while( i < trees.length) { - expanded(i) = remove(trees(i)); - i = i + 1; - } - select(0, expanded) map { x:List[Tree] => - //Console.println("remove:Sequence, type = "+pat.getType()); - val res = Sequence(lst2arr(x)).setType(pat.getType()); - //Console.println("remove:Sequence RETURNS "+res); - res - } - - case Apply( fn, trees ) => - val expanded = new Array[List[Tree]](trees.length); - var i = 0; while( i < trees.length) { - expanded(i) = remove(trees(i)); - i = i + 1; - } - - select(0, expanded) map { x => new Apply(fn, lst2arr(x)) - .setType(pat.getType()) } - - case Ident(_) => List(pat); - case Literal(_) => List(pat); - case Select(_,_) => List(pat); - case Typed(_,_) => - List(pat); - case _ => error("in TransMatch.nilVariables: unknown node"+pat.getClass()); - - - } - //Console.println("end remove("+pat+")"); - res - } - val zs:Seq[CaseDef] = cases; - val ncases: List[List[Tree]] = zs.toList map { - x => x match { - case CaseDef(pat,guard,body) => - - //debugLog("removeAlterns - ("+x+")"); - remove(pat) match { - case List(p) => List(x); - case pats => - //debugLog("removal yields patterns (before trans) in "+cunit); - //debugLog( pats.mkString("","\n","") ); - pats map { - npat => - val tc = newCloner(); - //Console.println("start cloning! casedef in "+cunit); - val res = tc.transform(new CaseDef(npat, - guard.duplicate(), - body.duplicate())); - /*Console.println(sc.owners);*/res} - } - } - } - - lst2arr(List.flatten(ncases)); - } - - //val bsf = new scala.util.automaton.BerrySethi[ matching.PatternTest ]( pe ); - - def transform( root:Tree, cases:Array[CaseDef], restpe:Type ):Tree = { - - if( global.newMatch ) { - //val fm = new FullRegularTranslator( global ); - //val gram = fm.MakeGrammar( scala.Iterator.fromArray( cases ) ); - //Console.println("writing out the grammar to /tmp/encodedGrammar.bin"); - ////val f = new FileOutputStream(new File("/tmp/encodedGrammar.bin")); - ////f.write( gram.encode ); - ////f.close(); - //// val gram = Predef.decode( Predef.Array[] ); - //Console.println( gram.encode); - - throw new ApplicationError("not impl."); - }; - - var containsReg = false; - var i = 0; - while (i < cases.length) { - if(isRegular(cases( i ).pat)) { - containsReg = true; - handleNilVariables(cases( i )); - } - i = i+1; - } - //Console.println("TransMatch: "); - //for(val ci <- cases) Console.println(ci); - if( containsReg ) { - //Console.println("TransMatch: isRegular!"); - /* - val pe = new matching.PatternExp(global.definitions); // TEST - var j = 0; - val pat = new Array[pe.RegExp](cases.length); - while( j < cases.length) { - pat(j) = pe.fromTree(cases(j).pat); - j = j + 1; - } // TEST - */ - //debugLog("containsReg!"); - val am = new matching.AlgebraicMatcher( cunit ); - val matcher = new PartialMatcher( currentOwner, root, restpe ); - am.construct( matcher, cases.asInstanceOf[ Array[Tree] ] ); - matcher.tree - } else { - //Console.println("TransMatch: NOT regular"); - val pm = new matching.PatternMatcher( cunit ); - pm.initialize(root, currentOwner, restpe, true ); - try{ - - val ncases = removeAlterns(cases); - //if(ncases.length > cases.length) { - // debugLog("did some removal!"); - // var kk = 0; while (kk<ncases.length) { - // debugLog(ncases(kk).toString()); - // kk = kk + 1; - // } - //} else - //else debugLog("did NOT do removal!"); - - pm.construct( ncases.asInstanceOf[Array[Tree]] ); - } catch { - case e:Throwable => - e.printStackTrace(); - Console.print("failed on pats "+scala.Iterator.fromArray(cases).toList.mkString("","\n","")+", message\n"+e.getMessage()); - Console.print(" unit "+cunit); - Console.println(" with exception:"+e.getMessage()); - //e.printStackTrace(); - System.exit(-1); //Debug.abort() - } - if (global.log()) { - global.log("internal pattern matching structure"); - pm.print(); - } - pm.toTree(); - } - } - /** evil hack. OwnerTransformer should have this function */ - def transform1(ts:Array[CaseDef]):Array[CaseDef] = { - var i = 0; - while( i < ts.length ) { - val t = transform(ts( i )); - if (t != ts( i )) { - val res = new Array[CaseDef](ts.length); - System.arraycopy(ts, 0, res, 0, i); - res( i ) = t.asInstanceOf[CaseDef]; - i = i + 1; - while(i < ts.length) { - res( i ) = transform(ts( i )).asInstanceOf[CaseDef]; - i = i + 1 - }; - return res; - }; - i = i + 1; - } - return ts; - } - - override def transform( tree: Tree ):Tree = { - if (tree == null) - return null; - else - tree match { - case Apply(Select( receiver, Names._match ), args) => - if ((args != null) && (args.length == 1)) - args( 0 ) match { - case Visitor( cases ) => - return transform(transform(receiver), transform1(cases), tree.getType()); - } - return tree; - - case Apply(TypeApply(Select( receiver, Names._match ), targs), args) => - if ((args != null) && (args.length == 1)) - args( 0 ) match { - case Visitor( cases ) => - return transform(transform(receiver), transform1(cases), tree.getType()); - } - return tree; - case _ => - super.transform(tree); - } - } -} - -} diff --git a/sources/scala/tools/scalac/transformer/TransMatchPhase.scala b/sources/scala/tools/scalac/transformer/TransMatchPhase.scala deleted file mode 100644 index 23dad47306..0000000000 --- a/sources/scala/tools/scalac/transformer/TransMatchPhase.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global} -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -package scala.tools.scalac.transformer { - -class TransMatchPhase(global:scalac_Global, descriptor:PhaseDescriptor ) - extends Phase(global, descriptor) { - - /** Applies this phase to the given compilation unit. */ - override def apply(unit: CompilationUnit): Unit = - new TransMatch(global).apply(unit); - - } -} - - diff --git a/sources/scala/tools/scalac/transformer/UnCurry.scala b/sources/scala/tools/scalac/transformer/UnCurry.scala deleted file mode 100644 index 243f534da9..0000000000 --- a/sources/scala/tools/scalac/transformer/UnCurry.scala +++ /dev/null @@ -1,406 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{CompilationUnit, ApplicationError}; -import scalac.{Global => scalac_Global}; -import scalac.util._; -import scalac.ast._; -import scalac.symtab._; -import Tree._; -import scalac.transformer.OwnerTransformer; - -package scala.tools.scalac.transformer { - -import scalac.util.NewArray; -/*<export>*/ -/** - uncurry all symbol and tree types (@see UnCurryPhase) - * - for every curried parameter list: (ps_1) ... (ps_n) ==> (ps_1, ..., ps_n) - * - for every curried application: f(args_1)...(args_n) ==> f(args_1, ..., args_n) - * - for every type application: f[Ts] ==> f[Ts]() unless followed by parameters - * - for every use of a parameterless function: f ==> f() and q.f ==> q.f() - * - for every def-parameter: def x: T ==> x: () => T - * - for every use of a def-parameter: x ==> x.apply() - * - for every argument to a def parameter `def x: T': - * if argument is not a reference to a def parameter: - * convert argument `e' to (expansion of) `() => e' - * - for every argument list that corresponds to a repeated parameter - * (a_1, ..., a_n) => (Sequence(a_1, ..., a_n)) - * - for every argument list that is an escaped sequence - * (a_1:_*) => (a_1) - */ -/*</export>*/ -class UnCurry(global: scalac_Global, descr: UnCurryPhase) extends OwnerTransformer(global) { - - import Modifiers._; - - private var unit: CompilationUnit = _; - private var inPattern: boolean = false; - private var inArray: boolean = false; - - override def apply(unit: CompilationUnit): unit = { - this.unit = unit; - super.apply(unit); - } - - /** (ps_1) ... (ps_n) => (ps_1, ..., ps_n) - */ - private def uncurry(params: Array[Array[ValDef]]): Array[Array[ValDef]] = { - var n = 0; - { var i = 0; while (i < params.length) { - n = n + params(i).length; - i = i + 1 - }} - val ps = new Array[ValDef](n); - var j = 0; - var i = 0; while (i < params.length) { - System.arraycopy(params(i), 0, ps, j, params(i).length); - j = j + params(i).length; - i = i + 1 - } - NewArray.ValDefArray(ps) - } - - /** tree of non-method type T ==> same tree with method type ()T - */ - private def asMethod(tree: Tree): Tree = tree.getType() match { - case Type$MethodType(_, _) => - tree - case _ => - tree.setType( - new Type.MethodType(Symbol.EMPTY_ARRAY, tree.getType().widen())) - } - - /** apply parameterless functions and def parameters - */ - private def applyDef(tree: Tree): Tree = { - assert(tree.symbol() != null, tree); - tree.symbol().getType() match { - case Type$PolyType(tparams, restp) => - if (tparams.length > 0 || (restp.isInstanceOf[Type$MethodType])) tree - else gen.Apply(asMethod(tree), Tree.EMPTY_ARRAY) - case _ => - if (tree.symbol().isDefParameter()) { - tree.setType(global.definitions.FUNCTION_TYPE( - Type.EMPTY_ARRAY, tree.getType().widen())); - gen.Apply(gen.Select(tree, global.definitions.FUNCTION_APPLY(0))); - } else tree - } - } - - /** - uncurry all symbol and tree types (@see UnCurryPhase) - * - for every curried parameter list: (ps_1) ... (ps_n) ==> (ps_1, ..., ps_n) - * - for every curried application: f(args_1)...(args_n) ==> f(args_1, ..., args_n) - * - for every type application: f[Ts] ==> f[Ts]() unless followed by parameters - * - for every use of a parameterless function: f ==> f() and q.f ==> q.f() - * - for every def-parameter: def x: T ==> x: () => T - * - for every use of a def-parameter: x ==> x.apply() - * - for every argument to a def parameter `def x: T': - * if argument is not a reference to a def parameter => - * convert argument `e' to (expansion of) `() => e' - * - for every argument list that corresponds to a repeated parameter - * (a_1, ..., a_n) => (Sequence(a_1, ..., a_n)) - */ - override def transform(tree: Tree): Tree = { - var prevtype: Type = tree.getType(); - if (prevtype != null) { - if (prevtype.isInstanceOf[Type$OverloadedType]) { - assert(tree.symbol() != null); - prevtype = tree.symbol().removeInheritedOverloaded(prevtype); - } - tree.setType(descr.uncurry(prevtype)); - } - tree match { - case Tree$ClassDef(_, _, tparams, vparams, tpe, impl) => - val clazz: Symbol = tree.symbol(); - val elems = clazz.members().elements(); - var i = 0; while (i < elems.length) { - checkNoDoubleDef(clazz, elems(i)); - i = i + 1 - } - copy.ClassDef( - tree, clazz, tparams, - uncurry(transform(vparams, clazz)), - tpe, - transform(impl, clazz)); - - case Tree$DefDef(_, _, tparams, vparams, tpe, rhs) => - val sym: Symbol = tree.symbol(); - if (descr.isUnaccessedConstant(sym)) gen.mkUnitLit(tree.pos) - else { - val rhs1: Tree = transform(rhs, sym); - copy.DefDef( - tree, sym, tparams, uncurry(transform(vparams, sym)), tpe, rhs1) - } - - case Tree$ValDef(_, _, tpe, rhs) => - val sym: Symbol = tree.symbol(); - if (descr.isUnaccessedConstant(sym)) gen.mkUnitLit(tree.pos) - else if (sym.isDefParameter()) { - val newtype: Type = global.definitions.FUNCTION_TYPE(Type.EMPTY_ARRAY, tpe.getType()); - val tpe1: Tree = gen.mkType(tpe.pos, newtype); - copy.ValDef(tree, tpe1, rhs).setType(newtype) - } else - super.transform(tree) - - case Tree$TypeApply(fn, args) => - val tree1: Tree = asMethod(super.transform(tree)); - gen.Apply(tree1, new Array[Tree](0)) - - case Tree$Apply(fn, args) => - // f(x)(y) ==> f(x, y) - // argument to parameterless function e => ( => e) - val ftype: Type = fn.getType(); - val fn1: Tree = transform(fn); - val myInArray: boolean = - TreeInfo.methSymbol(fn1) == global.definitions.PREDEF_ARRAY(); - val old = inArray; - inArray = myInArray; // a hack to communicate with toSequence. - val args1 = transformArgs(tree.pos, args, ftype); - inArray = old; - if (myInArray) { - args1(0).getType().baseType(global.definitions.ARRAY_CLASS) match { - case Type.NoType => - copy.Apply(tree,fn, Predef.Array[Tree]{args1(0)}); - case _ => fn1 match { - case Tree$Apply(TypeApply(Select(fn2, _), targs), _) => - return gen.mkBlock(args1(0).pos, fn2, args1(0)) - case _ => - assert(false, "dead") - } - } - } - if (TreeInfo.methSymbol(fn1) == global.definitions.ANY_MATCH && !(args1(0).isInstanceOf[Tree.Visitor])) { - TreeInfo.methPart(fn1) match { - case Tree$Select(qual, name) => - assert(name == Names._match); - gen.postfixApply(qual, args1(0), currentOwner) - case _ => - throw new ApplicationError("illegal prefix for match: " + tree); - } - } else { - fn1 match { - case Tree$Apply(fn2, args2) => - val newargs = new Array[Tree](args1.length + args2.length); - System.arraycopy(args2, 0, newargs, 0, args2.length); - System.arraycopy(args1, 0, newargs, args2.length, args1.length); - copy.Apply(tree, fn2, newargs); - case _ => - copy.Apply(tree, fn1, args1); - } - } - - case Tree$Select(_, _) => - applyDef(super.transform(tree)) - - case Tree$Ident(name) => - if (name == TypeNames.WILDCARD_STAR) { - unit.error(tree.pos, " argument does not correspond to `*'-parameter"); - tree - } else if (tree.symbol() == global.definitions.PATTERN_WILDCARD) { - tree - } else { - applyDef(super.transform(tree)) - } - - case Tree$CaseDef(pat, guard, body) => - inPattern = true; - val pat1: Tree = transform( pat ); - inPattern = false; - val guard1: Tree = transform( guard ); - val body1: Tree = transform( body ); - copy.CaseDef(tree, pat1, guard1, body1) - - case _ => - super.transform(tree) - } - } - - /** Transform arguments `args' to method with type `methtype'. - */ - private def transformArgs(pos: int, args: Array[Tree], methtype: Type): Array[Tree] = { - methtype match { - case Type$MethodType(params, _) => - val args0 = - if (params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) - toSequence(pos, params, args) - else args; - var args1 = args0; - var i = 0; while (i < args0.length) { - val arg: Tree = args0(i); - val arg1: Tree = transformArg(arg, params(i)); - if (arg1 != arg && args1 == args0) { - args1 = new Array[Tree](args0.length); - System.arraycopy(args0, 0, args1, 0, i); - } - args1(i) = arg1; - i = i + 1 - } - args1; - case Type$PolyType(_, restp) => - transformArgs(pos, args, restp) - case _ => - if (args.length == 0) args; // could be arguments of nullary case pattern - else throw new ApplicationError(methtype); - } - } - - /** converts `a_1,...,a_n' to Seq(a_1,...,a_n) - * if a_n is an escaped sequence x:_*, takes care of escaping - * - * precondition: params[params.length-1].flags & REPEATED != 0 - */ - private def toSequence(pos: int, params: Array[Symbol], args: Array[Tree]): Array[Tree] = { - val result = new Array[Tree](params.length); - System.arraycopy(args, 0, result, 0, params.length - 1); - assert(args.length != params.length - || !(args(params.length-1).isInstanceOf[Tree.Sequence]) - || TreeInfo.isSequenceValued(args(params.length-1))); - if (args.length == params.length) { - args(params.length-1) match { - case Tree$Typed(arg, Ident(TypeNames.WILDCARD_STAR)) => // seq:_* escape - result(params.length-1) = arg; - return result; - case _ => - } - } - var args1 = args; - if (params.length != 1) { - args1 = new Array[Tree](args.length - (params.length - 1)); - System.arraycopy(args, params.length - 1, args1, 0, args1.length); - } - val theType: Type = params(params.length-1).getType(); - result(params.length-1) = - if (inPattern) - make.Sequence(pos, args1).setType(theType) - else if (inArray) - gen.mkNewArray(pos, theType.typeArgs()(0), args1, currentOwner) - else - gen.mkNewList(pos, theType.typeArgs()(0), args1); - result - } - - /** for every argument to a def parameter `def x: T': - * if argument is not a reference to a def parameter => - * convert argument `e' to (expansion of) `() => e' - */ - private def transformArg(arg: Tree, formal: Symbol): Tree = - if ((formal.flags & DEF) == 0) - transform(arg) - else { - val sym: Symbol = arg.symbol(); - if (sym == null || (sym.flags & DEF) == 0) - transform( - gen.mkUnitFunction(arg, descr.uncurry(arg.getType().widen()), - currentOwner, true)) - else { - val arg1: Tree = transform(arg); - arg1 match { - case Tree$Apply(Select(qual, name), args1) => - assert(name == Names.apply && args1.length == 0); - qual - case _ => - System.err.println(arg1);//debug - throw new ApplicationError(); - } - } - } - -// Double Definition Checking ----------------------------------------------- - - private def checkNoDoubleDef(clazz: Symbol, sym: Symbol): unit = { - - def checkNoDoubleDef(sym1: Symbol, sym2: Symbol, type1: Type, type2: Type): unit = { - - def conflictError(phase: String): unit = { - if (sym1.owner() == clazz && sym2.owner() == clazz) - unit.error(sym2.pos, - "Double declaration:\n" + - sym1 + ": " + type1 + " and\n" + - sym2 + ": " + type2 + " have same types after " + phase); - else if (sym1.owner() == clazz) - unit.error(sym1.pos, - "Accidental override:\n" + - sym1 + ": " + type1 + " has same type after " + phase + " as\n" + - sym2 + ": " + type2 + " which is inherited from " + sym2.owner()); - else if (sym2.owner() == clazz) - unit.error(sym2.pos, - "Accidental override:\n" + - sym2 + ": " + type2 + " has same type after " + phase + " as\n" + - sym1 + ": " + type1 + " which is inherited from " + sym1.owner()); - else - unit.error(clazz.pos, - "Inheritance conflict: inherited members\n" + - sym1 + ": " + type1 + sym1.locationString() + " and\n" + - sym2 + ": " + type2 + sym2.locationString() + " have same types after " + phase); - } - - val newtype1: Type = descr.uncurry(type1); - val newtype2: Type = descr.uncurry(type2); - if (sym1.owner() != sym2.owner() && - (newtype1.overrides(newtype2) || newtype2.overrides(newtype1))) - conflictError("uncurry") - else if (erasureConflict(newtype1, newtype2)) - conflictError("erasure") - } - - sym.getType() match { - case Type$OverloadedType(alts, alttypes) => - var i = 0; while (i < alttypes.length) { - var j = i + 1; while (j < alttypes.length) { - checkNoDoubleDef(alts(i), alts(j), alttypes(i), alttypes(j)); - j = j + 1 - } - i = i + 1 - } - case _ => - } - } - - private def erasureConflict(type1: Type, type2: Type): boolean = type1 match { - case Type$PolyType(_, restype1) => - erasureConflict(restype1, type2) - - case Type$MethodType(params1, restype1) => - type2 match { - case Type$PolyType(_, restype2) => - erasureConflict(type1, restype2) - - case Type$MethodType(params2, restype2) => - if (params1.length != params2.length) return false; - var i = 0; while (i < params1.length) { - if (!params1(i).nextInfo().erasure().isSameAs( - params2(i).nextInfo().erasure())) return false; - i = i + 1 - } - restype1.erasure().isSameAs(restype2.erasure()) - - case _ => - false - } - - case _ => - type2 match { - case Type$PolyType(_, _) | Type$MethodType(_, _) => - erasureConflict(type2, type1); - case _ => - true - } - } - - override def transform(templ: Tree$Template, sym: Symbol): Tree$Template = - super.transform(templ, sym); - - override def transform(tree: Tree, sym: Symbol): Tree = - super.transform(tree, sym); - - override def transform(trees: Array[Array[Tree$ValDef]], sym: Symbol): Array[Array[Tree$ValDef]] = - super.transform(trees, sym); - - -} -} diff --git a/sources/scala/tools/scalac/transformer/UnCurryPhase.scala b/sources/scala/tools/scalac/transformer/UnCurryPhase.scala deleted file mode 100644 index 00843bb542..0000000000 --- a/sources/scala/tools/scalac/transformer/UnCurryPhase.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global, _}; -import scalac.symtab._; - -package scala.tools.scalac.transformer { - -import scalac.util.NewArray; - -class UnCurryPhase(global: scalac_Global, descriptor: PhaseDescriptor) extends Phase(global, descriptor) { - - import Modifiers._; - - /** Applies this phase to the given compilation unit. */ - override def apply(unit: CompilationUnit): Unit = - new UnCurry(global, this).apply(unit); - - /** - return symbol's transformed type, - * - if symbol is a def parameter with transformed type T, return () => T - */ - override def transformInfo(sym: Symbol, tp0: Type): Type = { - val tp1 = uncurry(tp0); - if (sym.isDefParameter()) global.definitions.FUNCTION_TYPE(Type.EMPTY_ARRAY, tp1); - else tp1 - } - - /** - (ps_1)...(ps_n)T ==> (ps_1,...,ps_n)T - */ - def uncurry(tp: Type): Type = tp match { - case Type$MethodType(params, tp1) => - uncurry(tp1) match { - case Type$MethodType(params1, tp2) => - val newparams = new Array[Symbol](params.length + params1.length); - System.arraycopy(params, 0, newparams, 0, params.length); - System.arraycopy(params1, 0, newparams, params.length, params1.length); - new Type.MethodType(newparams, tp2); - case newtp1 => - if (newtp1 == tp1) tp; - else new Type.MethodType(params, newtp1); - } - case Type$PolyType(tparams, tp1) => - uncurry(tp1) match { - case newtp1 @ Type$MethodType(_, _) => - if (newtp1 == tp1) tp - else new Type.PolyType(tparams, newtp1) - case newtp1 => - val newtp2 = Type.MethodType(Symbol.EMPTY_ARRAY, newtp1); - if (tparams.length == 0) newtp2; - else Type.PolyType(tparams, newtp2) - } - case Type$OverloadedType(_, _) => - new Type$Map() { - override def apply(t: Type) = uncurry(t) - }.map(tp); - case Type$ConstantType(base, _) => - base - case Type$CompoundType(parents, scope) => - val symbol = tp.symbol(); - // todo: why not remove all inherited alternatives here? - if (!symbol.isClass() || symbol.isCompoundSym()) tp - else { - val clone = new Scope(); - val it = scope.iterator(); - while (it.hasNext()) { - val member = it.next(); - if (!isUnaccessedConstant(member) && - (!member.isCaseFactory() || member.isModule())) - clone.enterOrOverload(member); - } - Type.compoundType(parents, clone, symbol) - } - case _ => - tp - } - - def isUnaccessedConstant(symbol: Symbol): boolean = - symbol.isTerm() && - (symbol.flags & ACCESSED) == 0 && - (symbol.getType() match { - case Type$PolyType(params, Type$ConstantType(_, _)) => - params.length == 0 - case Type$ConstantType(_, _) => - true - case _ => - false - }); - -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala b/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala deleted file mode 100644 index 4764e14fca..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala +++ /dev/null @@ -1,189 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import java.io._; -import java.util._; - -import scalac.{Global => scalac_Global}; -import scalac._; -import scalac.ast._; -import scalac.symtab._; -import scalac.util._; // Names - -import scala.tools.scalac.util.NewArray; -import scalac.transformer.{ OwnerTransformer => scalac_transformer_OwnerTransformer }; - -//import scalac.transformer.matching.PatternNode ; -//import scalac.transformer.matching.SequenceMatcher ; -//import PatternNode._ ; - -package scala.tools.scalac.transformer.matching { - - /** Matthias' algebraic pattern matcher, with some things factored out, - * then translated to scala - * @author Matthias Zenger, Burak Emir - */ - class AlgebraicMatcher(unit: CompilationUnit) extends PatternMatcher(unit) { - -/* -import scalac.*; -import scalac.ast.*; -import scalac.atree.AConstant; -import scalac.symtab.*; - -import Tree.*; - -import scalac.util.Name ; -import scalac.util.Names ; - -import java.util.Vector ; -import java.util.Iterator ; -*/ - - var _m:PartialMatcher = _; - - this.delegateSequenceMatching = true; - this.optimize = false; - - /** constructs an algebraic pattern matcher from cases - */ - def construct(m: PartialMatcher, cases:Array[Tree]): Unit = { - construct(m, cases, true); - } - - /** constructs an algebraic pattern matcher from cases - */ - def construct(m: PartialMatcher, cases: Array[Tree], doBinding: Boolean): Unit = { - this._m = m; - super.initialize( _m.selector, _m.owner, _m.resultType, doBinding ); - var i = 0; while (i < cases.length) { - enter(cases(i)); //(CaseDef) cases[i], i); - i = i + 1; - } - if (unit.global.log()) { - unit.global.log("internal pattern matching structure"); - print(); - } - _m.tree = toTree(); - } - - - /** initializes this AlgebraicMatcher, see Matcher.initialize - void initialize() {} - */ - /* - def isStarApply(tree: Tree.Apply): Boolean = { - val params:Array[Symbol] = tree.fun.getType().valueParams(); - //System.err.println( tree.fun.type.resultType().symbol() ); - (tree.args.length == 1) - && (tree.getType().symbol().flags & Modifiers.CASE) != 0 - && params.length > 0 - && (params(params.length-1).flags & Modifiers.REPEATED) != 0; - } -*/ -//////////// generator methods - - override def toTree(): Tree = { - val ts = NewArray.Tree ( - gen.ValDef(root.symbol(), _m.selector), - gen.ValDef(resultVar, - gen.mkDefaultValue(_m.pos, resultVar.info()) )); - val res = gen.If( super.toTree(root.and), - gen.Ident( _m.pos, resultVar ), - cf.ThrowMatchError( _m.pos, _m.resultType )); - /* - gen.If( - _m.pos, - toTree(root.and), - gen.Ident( _m.pos, resultVar ), - cf.ThrowMatchError( _m.resultType )); - */ - gen.mkBlock(_m.pos, ts, res); - } - - protected override def toTree(node: PatternNode, selector: Tree): Tree = { - //System.err.println("AM.toTree called"+node); - if (node == null) - gen.mkBooleanLit(_m.pos, false); - else node match { - case SeqContainerPat( _, _ ) => - callSequenceMatcher( node, - selector ); - case _ => - super.toTree( node, selector ); - } - } - - /** collects all sequence patterns and returns the default - */ - def collectSeqPats(node1: PatternNode, seqPatNodes: Vector, bodies: Vector): PatternNode = { - var node = node1; - var defaultNode: PatternNode = null; - var exit = false; - do { - if( node == null ) - exit=true;//defaultNode = node; // break - else - node match { - case SeqContainerPat( _, _ ) => - seqPatNodes.add( node ); - bodies.add( super.toTree( node.and ) ); - node = node.or; - exit//defaultNode = node; // break; - - case _ => - defaultNode = node; - } - } while (!exit && (null == defaultNode)) ; - - defaultNode; - } - - def callSequenceMatcher(node: PatternNode, selector: Tree): Tree = { - - //Console.println("calling sequent matcher for"+node); - /* ???????????????????????? necessary to test whether is a Seq? - gen.If(selector.pos, maybe cf.And( cf.Is(selector, seqpat.type()) )???) - */ - - // translate the _.and subtree of this SeqContainerPat - - val seqPatNodes = new Vector(); - val bodies = new Vector(); - - var defaultNode = collectSeqPats(node, seqPatNodes, bodies); - - val defaultCase = toTree(defaultNode, selector); - - val wordRec = new SequenceMatcher(unit); - - val m = new PartialMatcher(_m.owner, selector, defs.boolean_TYPE()); - - val pats = new Array[Tree](seqPatNodes.size()); - val body = new Array[Tree](seqPatNodes.size()); - - val tmp = bodies.toArray(); - var j = 0; - val it = seqPatNodes.iterator(); - while (it.hasNext()) { - pats(j) = it.next().asInstanceOf[SeqContainerPat].seqpat; - body(j) = tmp(j).asInstanceOf[Tree]; - j = j + 1; - } - //Tree defaultTree = toTree(node.or, selector); // cdef.body ; - - wordRec.construct(m, pats, body, defaultCase, doBinding); - - //_m.defs.addAll(m.defs); - - m.tree; - } - - } - -} diff --git a/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala b/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala deleted file mode 100644 index eac38280ae..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala +++ /dev/null @@ -1,207 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global}; -import scalac._; -import scalac.ast._; -import scalac.symtab._; -import scalac.util._; // Names - -import scalac.transformer.{ OwnerTransformer - => scalac_transformer_OwnerTransformer }; - -import Tree._; - -import java.util._ ; - -import scala.tools.util.Position; - -package scala.tools.scalac.transformer.matching { - - /** @param owner owner of the pattern matching expression - */ - class Autom2Scala(val dfa: DetWordAutom, val elementType: Type, val owner: Symbol, val cf: CodeFactory) extends PatternTool(cf.unit) { - - protected var optimize = true; - - final val FAIL = -1; - - /** symbol of the matcher DefDef or Label */ - var funSym:Symbol = _; - - /** symbol of the iterator ( scala.SequenceIterator ) */ - var iterSym: Symbol = _; - - /** symbol of the switching result ( scala.Int ) */ - var resultSym: Symbol = _; - - /** symbol of the state variable ( scala.Int ) */ - var stateSym: Symbol = _; - - /** symbol of variable holding current label */ - var curSym: Symbol = _; - - /** symbol of boolean variable that indicates we have not reached end of sequence */ - var hasnSym: Symbol = _; - - val am = new AlgebraicMatcher( cf.unit ); - - var pos: Int = Position.FIRSTPOS; - - def funRetType(): Type = { - funSym.getType() match { - case Type.MethodType( _, retType )=> - retType; - case _ => throw new RuntimeException(); - } - } - - def callFun(args: Array[Tree]): Tree = { - gen.mkApply_V(gen.Ident(pos, funSym), args); - } - - // overridden in RightTracerInScala - def loadCurrentElem(body: Tree): Tree = { - gen.mkBlock( Predef.Array[Tree] ( - cf.gen.ValDef(this.hasnSym, - cf._hasNext( _iter() ) ), - cf.gen.ValDef(this.curSym, - gen.If(gen.Ident( pos, hasnSym ), - cf._next( _iter() ), - gen.mkDefaultValue(cf.pos,curSym.getType()))) - ), - body ); - } - - /** bug ?? */ - def currentElem() = { gen.Ident( cf.pos, curSym ).setType( curSym.getType() ); } - - def currentMatches(label: Label): Tree = { - label match { - case TreeLabel( pat ) => - _cur_match( pat ); - case SimpleLabel(lit: Tree.Literal) => - cf.Equals( currentElem(), lit ); - case _ => // cannot happen - throw new ApplicationError("expected either algebraic or simple label:"+label); - } - } - - // - // translation of automata to scala code - // - - - /** `[switchResult]' */ - def _swres(): Tree = { gen.Ident( pos, resultSym );} - - /** `<state>' param */ - def _state(): Tree = { gen.Ident( pos, stateSym ); } - - /** `<iterator>' param */ - def _iter(): Tree = { gen.Ident( pos, iterSym ); } - - /** simple optimization: if we are in a sink state, stop traversing sequence - */ - def stateWrap(i: Int): Tree = { - if( dfa.isSink( i )) - run_finished( i ); // state won't change! optimization - else - gen.If( cf.Negate( gen.Ident( pos, hasnSym )), - run_finished( i ), - code_state_NEW( i )); - } - - /** body of the matcherDefFun - */ - def code_body_NEW(): Tree = { - val tags = new Array[Int](dfa.nstates()); - val bodies = new Array[Tree](dfa.nstates()); - var i = 0; while (i < dfa.nstates()) { - tags( i ) = i; - bodies( i ) = stateWrap( i ); - i = i + 1; - } - //if( optimize ) - loadCurrentElem( gen.Switch( _state(), - tags, - bodies, - code_error(), // cannot happen - funRetType())); - /* - Tree res = code_error(); - for( int i = dfa.nstates-2; i>= 0; i-- ) - res = gen.If( cf.Equals( _state(), gen.mkIntLit( cf.pos, i )), - bodies[ i ] , - res ); - - return loadCurrentElem( res ); - */ - } - - /* calling the (AlgebraicMatcher)PatternMatcher here */ - def _cur_match(pat: Tree): Tree = { - val m = new PartialMatcher( this.funSym, /* owner*/ - currentElem(), /* root */ - cf.defs.boolean_TYPE() /* restype */); - - am.construct( m, Predef.Array[Tree] ( - cf.gen.CaseDef( pat, - gen.mkBooleanLit( pat.pos, true )), - cf.gen.CaseDef( cf.gen.Ident(pat.pos, cf.defs.PATTERN_WILDCARD), - gen.mkBooleanLit( pat.pos, false )) ), - false); - am.toTree(); - } - - // @todo should be abstract - def code_delta( i:Int, label: Label): Tree = { - throw new RuntimeException(); - } - - /** some error happened which is due to bug in translation/automaton - */ - final def code_error(): Tree = { - cf.ThrowMatchError( pos, funRetType() ); - } - - def code_fail(): Tree = { - gen.mkIntLit(Position.FIRSTPOS, FAIL ); - } - - /** code for the return value of the automaton translation - */ - def run_finished(state: Int): Tree = { - if( dfa.isFinal( state )) - gen.mkIntLit(Position.FIRSTPOS, dfa.finals.get( new Integer( state ) ).asInstanceOf[Integer].intValue() ); - else - gen.mkIntLit( Position.FIRSTPOS, FAIL ); - } - - def code_state_NEW(i: Int): Tree = { - var stateBody = code_delta( i, DefaultLabel() ); - if( stateBody == null ) - stateBody = code_fail(); - val trans = dfa.deltaq( i ); - - val labs = dfa.labels().iterator(); - while(labs.hasNext()) { - val label = labs.next(); - val next = trans.get( label ).asInstanceOf[Integer]; - val action = code_delta( i, label.asInstanceOf[Label] ); - if( action != null ) { - /*assert*/ //stateBody != null : "stateBody is null"; - stateBody = gen.If( currentMatches(label.asInstanceOf[Label] ), - action, - stateBody); - } - } - stateBody; - } - } -} diff --git a/sources/scala/tools/scalac/transformer/matching/BerrySethi.scala b/sources/scala/tools/scalac/transformer/matching/BerrySethi.scala deleted file mode 100644 index d0515adab9..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/BerrySethi.scala +++ /dev/null @@ -1,669 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -import scalac.CompilationUnit; -import scalac.ApplicationError; -import scalac.ast.Tree; -import scalac.ast.TreeInfo; -import scalac.util.Name; -import Tree._; - -import java.util._; - -//import scala.compiler.printer.XMLAutomPrinter; - -/** a Berry-Sethi style construction for nfas. - * this class plays is the "Builder" for the "Director" class WordRecognizer. - */ -package scala.tools.scalac.transformer.matching { - -class BerrySethi(val unit: CompilationUnit ) { - - def isStar(n: Name): boolean = { - TreeInfo.isNameOfStarPattern(n); - } - /* - - String s = n.toString(); - return (s.indexOf("$") != -1) - &&(!s.startsWith("nest")); - } - */ - - var labels: HashSet = _; - - var pos: int = _; - // maps a literal pattern to an Integer ( the position ) - // is not *really* needed (postfix order determines position!) - var posMap: HashMap = _; // pos: Patterns -> Positions - // don't let this fool you, only labelAt is a real, surjective mapping - var labelAt: HashMap= _; // chi: Positions -> Obj - - var globalFirst: TreeSet= _; - - // results which hold all info for the NondetWordAutomaton - - var follow: HashMap= _; // follow: Positions -> Set[Positions] - - - // Unit test ? - def nullable(pat: Tree): Boolean = { - //System.out.print("<nullable>"); - //DEBUG.print( pat ); - //System.out.println("</nullable>"); - pat match { - case Apply(_, _) => - return false; - - case Sequence( trees ) => - return (trees.length == 0) || nullable(trees); - //case Subsequence(Tree[] trees): - //return - case Bind(n, t) => - /* - if (isStar(n)) // generated for star/plus(?) - return true; - */ - return nullable( t ); - case Alternative(choices) => - var result = false; - var i = 0; - while(i < choices.length && !result) { - result = result || nullable(choices(i)); - i = i + 1 - } - return result; - case _ => - return false; - } - } - - - /** returns true if a Sequence pattern matches the empty sequence - * @param pat the sequence pattern. - */ - def nullableSequence(pat: Tree): Boolean = { - pat match { - case Sequence(pats) => - return nullable(pats); - } - return false; - } - - /** returns true if a sequence of patterns (usually children of a - * sequence or subsequence node) is nullable. - * @param pats the sequence of patterns - */ - def nullable(pats: Array[Tree]): Boolean = { - var result = true; - var i = 0; - while(i < pats.length && result){ - result = result && nullable( pats( i ) ); - i = i + 1 - } - return result; - } - - /** computes first( alpha ) where alpha is a word regexp - */ - - def compFirst( pat:Tree ): TreeSet = { - //System.out.print("<compFirst>"); - //DEBUG.print( pat ); - //System.out.println("</compFirst>"); - pat match { - case Sequence( trees ) => - return compFirst( trees ); - case Typed(_,_) | Select(_,_) | Apply(_, _) => - val tmp = new TreeSet(); - tmp.add( posMap.get( pat ).asInstanceOf[Integer]); // singleton set - return tmp; - - case Literal( _ ) => - val tmp = new TreeSet(); - tmp.add( posMap.get( pat ).asInstanceOf[Integer]); // singleton set - return tmp; - //case Subsequence( Tree[] trees ) => - //return compFirst( trees ); - case Alternative( trees ) => - val tmp = new TreeSet(); - var i = 0; - while(i < trees.length) { - tmp.addAll( compFirst( trees( i ) )); - i = i + 1 - } - return tmp; - - case Bind(_, tree) => - return compFirst(tree); - - case Ident( name ) => - //if (name != Name.fromString("_")) - // throw new ApplicationError("unexpected pattern"); - val tmp = new TreeSet(); - tmp.add( posMap.get( pat ).asInstanceOf[Integer]); // singleton set - return tmp; - - case _ => - throw new ApplicationError("unexpected pattern"); - } - } - - - - /** computes last( alpha ) where alpha is a word regexp - */ - def compLast(pat: Tree): TreeSet = { - //System.out.print("<last>"); - //DEBUG.print( pat ); - //System.out.println("</compLast>"); - pat match { - case Sequence( _ ) | Apply(_, _) => - val tmp = new TreeSet(); - tmp.add(posMap.get( pat ).asInstanceOf[Integer]); // singleton set - return tmp; - - case Literal( _ ) => - val tmp = new TreeSet(); - tmp.add( posMap.get( pat ).asInstanceOf[Integer]); // singleton set - return tmp; - - case Alternative( trees ) => - val tmp = new TreeSet(); - var i = 0; - while(i < trees.length) { - tmp.addAll( compLast( trees )); - i = i + 1 - } - return tmp; - - case Bind( _, tree ) => - return compLast( tree ); - - case _ => - throw new ApplicationError("unexpected pattern"); - } - } - - - /** computes first(w) where w=alpha_1...alpha_n are successors of a - * sequence node - */ - def compFirst( pats:Array[Tree] ): TreeSet = { - if( pats.length == 0 ) - return new TreeSet(); - - var i = 0; - var tmp = pats( i ); - val result = compFirst( tmp ); - i = i + 1; - while( nullable(tmp) && (i < pats.length )) { - tmp = pats( i ); - result.addAll( compFirst( tmp )); - i = i + 1; - } - return result; - } - - // Unit test ? - - /** computes last(w) where w are successors of a sequence node - */ - def compLast(pats: Array[Tree]): TreeSet = { - /* - System.out.print("<last>"); - for( int k = 0; k<pats.length; k++) { - DEBUG.print( pats[k] ); - System.out.print(" "); - } - System.out.println(); - */ - if( pats.length == 0 ) - return new TreeSet(); - - var i = pats.length - 1; - var tmp = pats( i ); - val result = compLast( tmp ); - i = i - 1; - while( nullable(tmp) && (i >= 0 )) { - tmp = pats( i ); - result.addAll( compLast( tmp )); - i = i + 1; - } - return result; - } - - // starts from the right-to-left - // precondition: pos is final - // pats are successor patterns of a Sequence node - // returns first-set (== follow set of initial state) - def compFollow(pats: Array[Tree]): TreeSet = { - var first:TreeSet = null; - this.recVars = new HashMap(); - var fol = new TreeSet(); - if( pats.length > 0 ) {//non-empty expr - var i = pats.length; - fol.add( new Integer( pos )); // don't modify pos ! - do { - i = i - 1; - first = compFollow1( fol, pats( i ) ); - if( nullable( pats( i ) )) - fol.addAll( first ); - else - fol = first; - //System.out.println("in compFollow: first"+first); - //System.out.println("in compFollow: fol"+fol); - - } while( i > 0 ); - } - this.follow.put(new Integer( 0 ), fol); - return fol; - } - - var recVars: HashMap = _; - - /** returns the first set of an expression, setting the follow set along - * the way - */ - def compFollow1( fol1:TreeSet , pat:Tree ): TreeSet = { - var fol = fol1; - //System.out.println("compFollow1("+fol+","+pat+")"); - pat match { - case Sequence( trees ) => - var first: TreeSet = null; - var i = trees.length; - if( i > 0 ) { // is nonempty - do { - i = i - 1; - first = compFollow1(fol, trees( i )); - if( nullable( trees( i ) )) - fol.addAll( first ); - else - fol = first; - } while( i > 0 ) ; - } - if( null == first ) first = new TreeSet(); - return first; - - case Alternative( choices ) => - val first = new TreeSet(); - var i = choices.length - 1; - while(i >= 0) { - first.addAll( compFollow1( fol, choices( i ) )); - i = i - 1; - } - return first; - - case Bind( n, t ) => // == can also be star - - val first = compFirst( t ); - //System.out.print("BIND" + first); - recVars.put( pat.symbol(), first ); - - // if( appearsRightmost( n, t )) - // follow = oldfollw + ownfirst - if( isStar( n ) ) - fol.addAll( first ); // an iterated pattern - - // continue to compute follow sets with adjusted fol - return compFollow1( fol, t ); - - case Ident( n ) => - if ((pat.symbol() != null ) - && pat.symbol().isPrimaryConstructor()) { - // same as Apply - val pos = this.posMap.get( pat ).asInstanceOf[Integer]; - val tset = fol.clone().asInstanceOf[TreeSet]; - this.follow.put( pos, tset ); - val first = new TreeSet(); - first.add( pos ); - return first; - } - - if ( recVars.keySet().contains( pat.symbol() )) { // grammar - val first = recVars.get( pat.symbol() ).asInstanceOf[TreeSet]; - val follow = fol.clone().asInstanceOf[TreeSet]; - first.addAll( follow ); - //recVars.put//this.follow.put( pat.symbol(), follow ); - return first; - } - - // --- --- only happens when called from BindingBerrySethi - // [... x ...] changed to [... x@_ ...] - - // non-generated, non-recursive variable should not appear, - // so this is a wildcard pattern _ - - val pos = this.posMap.get( pat ).asInstanceOf[Integer]; - val tset = fol.clone().asInstanceOf[TreeSet]; - this.follow.put( pos, tset ); - val first = new TreeSet(); - first.add( pos ); - //System.out.println("Ident("+n+",...) first:"+first); - //System.out.println("Ident("+n+",...) follow:"+tset); - return first; - - case Apply(_, _) | Literal( _ ) | Typed(_,_) | Select(_,_) => - val pos = this.posMap.get( pat ).asInstanceOf[Integer]; - val tset = fol.clone().asInstanceOf[TreeSet]; - this.follow.put( pos, tset ); - val first = new TreeSet(); - first.add( pos ); - return first; - - case _ => - throw new ApplicationError("unexpected pattern: "+pat.getClass()); - } - } - - /** called at the leaves of the regexp - */ - def seenLabel( pat:Tree , i:Integer , label:Label ): Unit = { - this.posMap.put( pat, i ); - this.labelAt.put( i, label ); - if( label != DefaultLabel() ) { - /* - if( this.labels.contains( label ) ) { - switch(label) { - case TreeLabel(Apply(_, Tree[] args)) => - if( args.length > 0 ) { - unit.warning(pat.pos, "if this pattern in nondeterminism, it will not compile correctly"); - } - } - } - */ - this.labels.add( label ); - } - - } - - /** overriden in BindingBerrySethi - */ - def seenLabel( pat:Tree , label:Label ): Unit = { - seenLabel( pat, new Integer( {pos = pos + 1; pos} ), label ); - } - - /** returns "Sethi-length" of a pattern, creating the set of position - * along the way - */ - - var activeBinders:Vector = _; - - // todo: replace global variable pos with acc - def traverse( pat:Tree ): Unit = { - pat match { - - // (is tree automaton stuff, more than Berry-Sethi) - case Apply( _, _ ) | Typed( _, _ )| Select( _, _ ) => - val label = new TreeLabel( pat ); - seenLabel( pat, label ) ; - return ; - - case p @ Literal( _ ) => - val label = new SimpleLabel( p ); - seenLabel( pat, label ) ; - - return ; - - case Sequence( trees ) => - var i = 0; - while(i < trees.length) { - traverse( trees( i ) ); - i = i + 1 - } - return ; - - case Alternative( trees ) => - var i = 0; - while(i < trees.length) { - traverse( trees( i ) ); - i = i + 1 - } - return ; - - case Bind( name, body) => - recVars.put( pat.symbol(), java.lang.Boolean.TRUE ); - if( !isStar( name ) ) { - activeBinders.add( pat.symbol() ); - traverse( body ); - activeBinders.remove( pat.symbol() ); - } - else - traverse( body ); - return ; - - case Ident(name) => - if ((pat.symbol() != null ) - && pat.symbol().isPrimaryConstructor()) { - // same as Apply - val label = new TreeLabel( pat ); - seenLabel( pat, label ) ; - - return ; - } - - - if( null != recVars.get( pat.symbol() ) ) { - return ; - } - // _ and variable x ( == x @ _ ) - val label = DefaultLabel(); - seenLabel( pat, label ); - - return ; - - } - } - - - var finals: TreeMap = _; // final states - - //TreeSet initialsRev; // final states - - var deltaq:Array[HashMap] = _; // delta - - - - var defaultq: Array[Vector] = _; // default transitions - - - //HashMap deltaqRev[]; // delta of Rev - //Vector defaultqRev[]; // default transitions of Rev - - - def makeTransition(srcI:Integer, destI:Integer, label: Label): Unit = { - var src = srcI.intValue() ; - var dest = destI.intValue() ; - var arrows: Vector = _; //, revArrows; - //Label revLabel = new Pair( srcI, label ); - label match { - case DefaultLabel() => - arrows = defaultq( src ); - //revArrows = defaultqRev[ dest ]; - case _ => - arrows = deltaq( src ).get( label ).asInstanceOf[Vector]; - if( arrows == null ) - deltaq( src ).put( label, - {arrows = new Vector(); arrows} ); - /* - revArrows = (Vector) deltaqRev[ dest ].get( revLabel ); - if( revArrows == null ) - deltaqRev[ dest ].put( revLabel, - revArrows = new Vector() ); - */ - } - arrows.add( destI ); - //revArrows.add( srcI ); - } - - - var initials: TreeSet = _; - //NondetWordAutom revNfa ; - - def initialize( subexpr:Array[Tree] ): Unit = { - this.posMap = new HashMap(); - this.labelAt = new HashMap(); - - - this.follow = new HashMap(); - this.labels = new HashSet(); - this.recVars = new HashMap(); - this.pos = 0; - // determine "Sethi-length" of the regexp - activeBinders = new Vector(); - var i = 0; - while(i < subexpr.length ) { - traverse( subexpr( i )); - //assert ( activeBinders.isEmpty() ) - i = i + 1; - } - - this.initials = new TreeSet(); - initials.add( new Integer( 0 )); - - } - - def initializeAutom(): Unit = { - - finals = new TreeMap(); // final states - deltaq = new Array[HashMap]( pos ); // delta - defaultq = new Array[Vector]( pos ); // default transitions - - var j = 0; - while(j < pos) { - deltaq( j ) = new HashMap(); - defaultq( j ) = new Vector(); - j = j + 1; - } - } - - def collectTransitions(): Unit = { // make transitions - var j = 0; - while(j < pos) { - val q = new Integer( j ); - - //System.out.print( "--q="+q ); - //System.out.println(" labelAt:"+labelAt.get( q )); - - val fol = this.follow.get( q ).asInstanceOf[TreeSet]; - //assert fol != null; - val it = fol.iterator(); - while(it.hasNext()) { - val p = it.next().asInstanceOf[Integer]; - //System.out.println( "-- -- p="+p ); - if( p.intValue() == pos ) { - finals.put( q, finalTag ); - } else { - makeTransition( new Integer(j), p, - labelAt.get( p ).asInstanceOf[Label]); - } - } - j = j + 1 - } - } - - var finalTag: Integer = _; - - def automatonFrom(pat: Tree , finalTag: Integer): NondetWordAutom = { - - this.finalTag = finalTag; - - //System.out.println( "enter automatonFrom("+pat+","+finalTag+")"); // UNIT TEST - //System.out.println( pat ); - //System.out.println( nullableSequence( pat )); // UNIT TEST - pat match { - case Sequence( subexpr ) => - initialize( subexpr ); - - - // (1) compute first - - //globalFirst = compFirst( subexpr ); - //System.out.println(globalFirst); - - // (2) compute follow; - pos = pos + 1; - //Set ignore = compFollow( subexpr ); - //System.out.println(ignore); - //System.exit(0); - //assert (ignore.equals( globalFirst )); - - globalFirst = compFollow( subexpr ); - - //System.out.print("someFirst:");debugPrint(someFirst); - - // construct the automaton's explicit representation - - initializeAutom(); - - - // defaultqRev = new Vector[pos]; // default transitions - - collectTransitions(); - - if (nullable(subexpr)) // initial state is final - finals.put(new Integer(0), finalTag); - - //TreeSet initials = new TreeSet(); - //initials.add(new Integer(0)); - - val result = - new NondetWordAutom(pos, // = nstates - labels, - initials, - finals, - deltaq, - defaultq, - null/*(Object) qbinders*/); - - /* - System.out.println("inBerrySethi"); - XMLAutomPrinter pr = new XMLAutomPrinter( System.out ); - pr.begin(); - pr.print(result); - pr.print(revNfa); - pr.end(); - System.out.println("initialsRev = "+initialsRev); - System.out.println("outBerrySethi"); - */ - //System.exit(0); - //result.print(); - return result; - } - - throw new ApplicationError("expected a sequence pattern"); - } - - def print1(): Unit = { - Console.println("after sethi-style processing"); - Console.println("#positions:" + pos); - Console.println("posMap:"); - - var it = this.posMap.keySet().iterator(); - while(it.hasNext()) { - val t = it.next().asInstanceOf[Tree]; - t match { - case Literal( _ ) => - Console.print( "(" + t.toString() + " -> "); - val s2 = (posMap.get(t).asInstanceOf[Integer]).toString(); - Console.print( s2 +") "); - } - } - Console.println("\nfollow: "); - var j = 1; - while(j < pos ) { - val fol = this.follow.get(new Integer(j)).asInstanceOf[TreeSet]; - Console.print("("+j+" -> "+fol.toString()+") "); - //debugPrint( fol ); - Console.println; - j = j + 1; - } - - } -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/BindingBerrySethi.scala b/sources/scala/tools/scalac/transformer/matching/BindingBerrySethi.scala deleted file mode 100644 index b3e0cdb716..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/BindingBerrySethi.scala +++ /dev/null @@ -1,177 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -import scalac.CompilationUnit; -import scalac.Global ; -import scalac.ApplicationError ; -import scalac.ast.Tree ; -import scalac.util.Name ; -import scalac.util.Names ; -import Tree._ ; - -import java.util._ ; - -//import scala.compiler.printer.XMLTreePrinter ; -//import scala.compiler.printer.XMLAutomPrinter ; - -package scala.tools.scalac.transformer.matching { -/** a Berry-Sethi style construction for nfas. - * this class plays is the "Builder" for the "Director" class - * WordRecognizer. - */ - -class BindingBerrySethi(unit:CompilationUnit) extends BerrySethi(unit) { - - // variables - - var deltaqRev : Array[HashMap] = _; // delta of Rev - var defaultqRev: Array[Vector] = _; // default transitions of Rev - var qbinders : Array[Vector] = _; // transitions <-> variables - var revnfa : NondetWordAutom = _ ; - var varAt : HashMap = _; // chi: Positions -> Vars (Symbol) - - override def makeTransition(srcI: Integer, destI: Integer, label: Label): Unit = { - val src = srcI.intValue() ; - val dest = destI.intValue() ; - var arrows: Vector = _; - var revArrows: Vector = _; - val revLabel = new LPair(srcI, label); - label match { - case DefaultLabel() => - arrows = defaultq(src); - revArrows = defaultqRev(dest); - - case _ => - arrows = deltaq(src).get(label).asInstanceOf[Vector]; - if (arrows == null) - deltaq(src).put(label, - {arrows = new Vector(); arrows} ); - revArrows = deltaqRev(dest).get(revLabel).asInstanceOf[Vector]; - if (revArrows == null) - deltaqRev(dest).put(revLabel, {revArrows = new Vector(); revArrows} ); - } - arrows.add(destI); - revArrows.add(srcI); - } - - override def seenLabel(pat: Tree, label: Label): Unit = { - var i = new Integer({pos = pos + 1; pos} ); - seenLabel( pat, i, label ); - pat match { - case Apply(_, _) | Literal( _ ) | Select(_, _) | Typed(_,_) => - this.varAt.put( i, activeBinders.clone() ); // below @ ? - - case Ident( name ) => - //assert ( pat.symbol() == Global.instance.definitions.PATTERN_WILDCARD )||( name.toString().indexOf("$") > -1 ) : "found variable label "+name; - - val binders = activeBinders.clone().asInstanceOf[Vector]; - /* - if( pat.symbol() != Global.instance.definitions.PATTERN_WILDCARD) { - binders.add( pat.symbol() ); - } - */ - this.varAt.put( i, binders ); - } - } - - override def initialize( pats:Array[Tree] ): Unit = { - this.varAt = new HashMap(); // Xperiment - super.initialize( pats ); - } - - override def initializeAutom(): Unit = { - super.initializeAutom(); - deltaqRev = new Array[HashMap](pos); // deltaRev - defaultqRev = new Array[Vector](pos); // default transitions - qbinders = new Array[Vector](pos); // transitions <-> variables - - var j = 0; - while (j < pos) { - deltaqRev(j) = new HashMap(); - defaultqRev(j) = new Vector(); - qbinders(j) = varAt.get(new Integer(j)).asInstanceOf[Vector]; - j = j + 1; - } - varAt.clear(); // clean up - } - - - override def automatonFrom(pat: Tree, finalTag: Integer): NondetWordAutom = { - this.finalTag = finalTag ; - //System.out.println("enter automatonFrom("+ pat +")"); - pat match { - case Sequence(subexpr) => - - initialize(subexpr); - - // (1) compute first + follow; - pos = pos + 1; - - globalFirst = compFollow( subexpr ); - - - - initializeAutom(); // explicit representation - - collectTransitions(); - - val result = - new NondetWordAutom(pos, // = nstates - labels, - initials, - finals, - deltaq, - defaultq, - qbinders); - - result.leftTrans = true; - - val revInitials = new TreeSet(finals.keySet()); - /* - pos++; // adding a state - HashSet deltaqRev2[] = new HashSet[ deltaqRev.length + 1]; - HashSet defaultqRev2[] = new HashSet[ deltaqRev.length + 1]; - HashSet qbinders[] = new HashSet[ deltaqRev.length + 1]; - for (Iterator it = finals.keySet().iterator(); it.hasNext(); ) { - - } - */ - val revFinals = new TreeMap(); - var it = initials.iterator(); - while(it.hasNext()) { - revFinals.put(it.next(), finalTag); - } - revnfa = new NondetWordAutom(pos, - labels, - revInitials, - revFinals, - deltaqRev, - defaultqRev, - qbinders); - - revnfa.rightTrans = true; - - /* - System.out.println("inBerrySethi"); - XMLAutomPrinter pr = new XMLAutomPrinter(System.out); - pr.begin(); - pr.print(result); - pr.print(revnfa); - pr.end(); - System.out.println("initialsRev = " + initialsRev); - System.out.println("outBerrySethi"); - */ - //System.exit(0); - return result; //print(); - } - } - -} - -} - diff --git a/sources/scala/tools/scalac/transformer/matching/CaseEnv.scala b/sources/scala/tools/scalac/transformer/matching/CaseEnv.scala deleted file mode 100644 index 2d3a283dac..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/CaseEnv.scala +++ /dev/null @@ -1,73 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - - -import scalac._; -import scalac.ast._; -import scalac.util._; -import scalac.symtab._; -import Tree.ValDef; - -package scala.tools.scalac.transformer.matching { - -/** the environment for a body of a case - * @param owner the owner of the variables created here - */ -class CaseEnv(val owner:Symbol, unit:CompilationUnit) { - - private var boundVars:scala.Array[ValDef] = new Array[ValDef](4); - private var numVars = 0; - - /** substitutes a symbol on the right hand side of a ValDef - */ - def substitute(oldSym: Symbol, newInit: Tree): Unit = { - var i = 0; while( i < numVars) { - if( boundVars(i).rhs.symbol() == oldSym ) { - boundVars(i).rhs = newInit; - return; - } - i = i + 1; - } - } - - def newBoundVar(sym:Symbol, tpe: Type, init:Tree ): Unit = { - sym.setOwner( owner ); // FIXME should be corrected earlier - if (numVars == boundVars.length) { - val newVars = new Array[ValDef](numVars * 2); - System.arraycopy(boundVars, 0, newVars, 0, numVars); - this.boundVars = newVars; - } - sym.setType(tpe); - this.boundVars(numVars) = unit.global.treeGen.ValDef(sym, init.duplicate()); - numVars = numVars + 1; - } - - def getBoundVars(): Array[ValDef] = { - val newVars = new Array[ValDef](numVars); - System.arraycopy(boundVars, 0, newVars, 0, numVars); - return newVars; - } - - override def equals(obj: Any): Boolean = { - if (!(obj.isInstanceOf[CaseEnv])) - return false; - val env = obj.asInstanceOf[CaseEnv]; - if (env.numVars != numVars) - return false; - var i = 0; while(i < numVars) { - if ((boundVars(i).name != env.boundVars(i).name) || - !boundVars(i).tpe.getType().isSameAs(env.boundVars(i).tpe.getType()) || - (boundVars(i).rhs != env.boundVars(i).rhs)) - return false; - i = i + 1; - } - return true; - } - -} // class CaseEnv -} diff --git a/sources/scala/tools/scalac/transformer/matching/CodeFactory.scala b/sources/scala/tools/scalac/transformer/matching/CodeFactory.scala deleted file mode 100644 index 70df601f3a..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/CodeFactory.scala +++ /dev/null @@ -1,287 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - - -import scala.tools.util.Position; - -import scalac._; -import scalac.ast._; -import scalac.atree.AConstant._; -import scalac.util._; -import scalac.symtab._; -//import PatternNode._; -import Tree._; -package scala.tools.scalac.transformer.matching { - -class CodeFactory(val unit: CompilationUnit, pos1: Int) extends PatternTool(unit) { - - var pos = pos1; - - // --------- these are new - - /** a faked switch statement - */ - def Switch(condition: Array[Tree], body: Array[Tree], defaultBody: Tree): Tree = { - //assert condition != null:"cond is null"; - //assert body != null:"body is null"; - //assert defaultBody != null:"defaultBody is null"; - var result = defaultBody; - - var i = condition.length-1; - while (i >= 0) { - result = gen.If(condition(i), body(i), result); - i = i - 1 - } - - return result ; - } - - /** returns `List[ Tuple2[ scala.Int, <elemType> ] ]' */ - def SeqTraceType( elemType: Type ): Type = { - defs.LIST_TYPE(pairType(defs.int_TYPE(), elemType)); - } - - /** returns `Iterator[ elemType ]' */ - def _seqIterType( elemType: Type ): Type = { - defs.ITERATOR_TYPE(elemType); - } - - /** returns `<seqObj.elements>' */ - def newIterator( seqObj:Tree , elemType:Type ): Tree = { - gen.mkApply__(gen.Select(seqObj, defs.ITERABLE_ELEMENTS())); - } - - /** returns code `<seqObj>.elements' - * the parameter needs to have type attribute `Sequence[<elemType>]' - */ - def newIterator( seqObj:Tree ): Tree = { - newIterator( seqObj, getElemType_Sequence( seqObj.getType() )); - } - - // EXPERIMENTAL - def newRef(init: Tree): Tree = { - //System.out.println( "hello:"+refSym().type() ); - gen.New( gen.mkApplyTV( gen.mkPrimaryConstructorGlobalRef( pos, defs.REF_CLASS), - Predef.Array[Type] ( init.getType() ), - Predef.Array[Tree] ( init ) )); - } - - /** returns A for T <: Sequence[ A ] - */ - def getElemType_Sequence( tpe: Type): Type = { - //System.err.println("getElemType_Sequence("+tpe.widen()+")"); - val tpe1 = tpe.widen().baseType( defs.SEQ_CLASS ); - - if( tpe1 == Type.NoType ) - throw new ApplicationError("arg "+tpe+" not subtype of Seq[ A ]"); - - return tpe1.typeArgs()( 0 ); - } - - /** returns A for T <: Iterator[ A ] - */ - def getElemType_Iterator( tpe: Type ): Type = { - //System.err.println("getElemType_Iterator("+tpe+")"); - - val tpe1 = tpe.widen().baseType( defs.ITERATOR_CLASS ); - - tpe1 match { - case Type.TypeRef(_,_,args) => - return args( 0 ); - case _ => - throw new ApplicationError("arg "+tpe+" not subtype of Iterator[ A ]"); - } - - } - - /** `it.next()' - */ - def _next( iter: Tree ): Tree = { - gen.mkApply__(gen.Select(iter, defs.ITERATOR_NEXT())); - } - - /** `it.hasNext()' - */ - def _hasNext( iter: Tree ): Tree = { - gen.mkApply__(gen.Select(iter, defs.ITERATOR_HASNEXT())); - } - - /** `!it.hasCur()' - */ - def _not_hasNext( iter:Tree ): Tree = { - gen.mkApply__(gen.Select(_hasNext(iter), defs.BOOLEAN_NOT())); - } - - /** `trace.isEmpty' - */ - def isEmpty( iter: Tree ): Tree = { - gen.mkApply__(gen.Select(iter, defs.LIST_ISEMPTY())); - } - - def SeqTrace_headElem( arg: Tree ): Tree = { // REMOVE SeqTrace - val t = gen.mkApply__(gen.Select(arg, defs.LIST_HEAD())); - gen.mkApply__(gen.Select(t, defs.TUPLE_FIELD(2, 2))); - } - - def SeqTrace_headState( arg: Tree ): Tree = { // REMOVE SeqTrace - val t = gen.mkApply__(gen.Select(arg, defs.LIST_HEAD())); - gen.mkApply__(gen.Select(t, defs.TUPLE_FIELD(2, 1))); - - } - - def SeqTrace_tail( arg: Tree ): Tree = { // REMOVE SeqTrace - gen.mkApply__(gen.Select(arg, defs.LIST_TAIL())); - } - - /** `<seqlist>.head()' - */ - def SeqList_head( arg: Tree ): Tree = { - gen.mkApply__(gen.Select(arg, defs.LIST_HEAD())); - } - - def Negate(tree: Tree): Tree = { - tree match { - case Literal(BOOLEAN(value))=> - gen.mkBooleanLit(tree.pos, !value); - case _ => - gen.mkApply__(gen.Select(tree, defs.BOOLEAN_NOT())); - } - } - - /*protected*/ def And(left: Tree, right: Tree): Tree = { - left match { - case Literal(BOOLEAN(value)) => - return if(value) right else left; - case _ => - } - right match { - case Literal(BOOLEAN(value)) => - if (value) return left; - case _ => - } - gen.mkApply_V(gen.Select(left, defs.BOOLEAN_AND()), Predef.Array[Tree](right)); - } - - /*protected*/ def Or(left: Tree, right: Tree): Tree = { - left match { - case Literal(BOOLEAN(value))=> - return if(value) left else right; - case _ => - } - right match { - case Literal(BOOLEAN(value)) => - if (!value) return left; - case _ => - } - gen.mkApply_V(gen.Select(left, defs.BOOLEAN_OR()), Predef.Array[Tree](right)); - } - - // used by Equals - private def getCoerceToInt(left: Type): Symbol = { - val sym = left.lookupNonPrivate(Names.coerce); - //assert sym != Symbol.NONE : Debug.show(left); - val syms = sym.alternativeSymbols(); - var i = 0; while( i < syms.length) { - syms(i).info() match { - case Type.MethodType(vparams, restpe) => - if (vparams.length == 0 && restpe.isSameAs(defs.INT_TYPE())) - return syms(i); - case _ => - } - i = i + 1; - } - //assert false : Debug.show(left); - throw new ApplicationError(left); - } - - // used by Equals - private def getEqEq(left: Type, right: Type): Symbol = { - val sym = left.lookupNonPrivate(Names.EQEQ); - //assert sym != Symbol.NONE - // : Debug.show(left) + "::" + Debug.show(left.members()); - var fun: Symbol = null; - var ftype:Type = defs.ANY_TYPE(); - val syms = sym.alternativeSymbols(); - var i = 0; while(i < syms.length) { - val vparams = syms(i).valueParams(); - if (vparams.length == 1) { - val vptype = vparams(0).info(); - if (right.isSubType(vptype) && vptype.isSubType(ftype)) { - fun = syms(i); - ftype = vptype; - } - } - i = i + 1 - } - //assert fun != null : Debug.show(sym.info()); - fun; - } - - /*protected*/ def Equals(left1:Tree , right1:Tree ): Tree = { - var left = left1; - var right = right1; - val ltype = left.getType().widen(); - var rtype = right.getType().widen(); - if (ltype.isSameAs(rtype) - && (ltype.isSameAs(defs.CHAR_TYPE()) - || ltype.isSameAs(defs.BYTE_TYPE()) - || ltype.isSameAs(defs.SHORT_TYPE()))) - { - right = gen.mkApply__(gen.Select(right, getCoerceToInt(rtype))); - rtype = defs.INT_TYPE(); - } - val eqsym = getEqEq(ltype, rtype); - gen.mkApply_V(gen.Select(left, eqsym), Predef.Array[Tree](right)); - } - - /*protected*/ def ThrowMatchError(pos: Int, tpe: Type ): Tree = { - gen.mkApplyTV( - gen.mkGlobalRef(pos, defs.MATCHERROR_FAIL()), - Predef.Array[Tree](gen.mkType(pos, tpe)), - Predef.Array[Tree]( - gen.mkStringLit(pos, unit.toString()), - gen.mkIntLit(pos, Position.line(pos)) - )); - } - - def ThrowMatchError(pos:int , tpe:Type , tree:Tree ): Tree = { - gen.mkApplyTV( - gen.mkGlobalRef(pos, defs.MATCHERROR_REPORT()), - Predef.Array[Tree](gen.mkType(pos, tpe)), - Predef.Array[Tree]( - gen.mkStringLit(pos, unit.toString()), - gen.mkIntLit(pos, Position.line(pos)), - tree - )); - } - - def Error(pos: Int, tpe: Type): Tree = { - gen.mkApplyTV( - gen.mkGlobalRef(pos, defs.MATCHERROR_FAIL()), - Predef.Array[Tree](gen.mkType(pos, tpe)), - Predef.Array[Tree]( - gen.mkStringLit(pos, unit.toString()), - gen.mkIntLit(pos, Position.line(pos)) - )); - } - - - def pairType(left: Type, right: Type): Type = { - defs.TUPLE_TYPE(Predef.Array[Type] ( left, right ) ); - } - - def newPair(left: Tree, right: Tree): Tree = { - gen.New( - gen.mkApplyTV( - gen.mkPrimaryConstructorGlobalRef( pos, defs.TUPLE_CLASS(2)), - Predef.Array[Type] ( left.getType(), right.getType() ), - Predef.Array[Tree] ( left, right ))); - } - -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/DetWordAutom.scala b/sources/scala/tools/scalac/transformer/matching/DetWordAutom.scala deleted file mode 100644 index ef2c61f7e6..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/DetWordAutom.scala +++ /dev/null @@ -1,890 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -import scalac.ast.Tree ; -import Tree._ ; - -import java.util._ ; - -import scalac.ApplicationError ; - -package scala.tools.scalac.transformer.matching { - -class DetWordAutom { - - /** determinization -- standard algorithm considering only - * reachable states - */ - def this(nfa: NondetWordAutom) = { - this(); - //Console.println("DWA:this(.)"); - //Console.println(nfa.nstates); - //nfa.print(); - determinize( nfa ); - //Console.println(_nstates); - } - - //final static Integer FINTAG = new Integer(0); - - /** number of states */ - var _nstates:int =0; - - /** the 'alphabet' */ - var _labels:HashSet = _; - - /** the set of final states, here as a TreeMap */ - /*protected*/ var finals:TreeMap = _; - - /** dfa: HashMap trans: Object -> Integer - * nfa: HashMap trans: Object -> Vector [ Integer ] - * - * nfa: Integer ->(Object -> Vector [ Int ]) - * [q] |->( a |-> { q' | (q,a,q') in \deltaright } ) - * - * dfa: Integer ->(Object -> Int) - * [q] |->( a |-> q' | \deltaright(q,a) = q' } ) - */ - - var _deltaq: Array[HashMap] = _; - - var _defaultq: Array[Integer] = _; // this gives the default transitions - - //protected HashMap deltaq[]; - - // --- accessor methods - - /** returns number of states - */ - def nstates(): Int = _nstates; - - /** returns the labels - */ - def labels(): HashSet = _labels; - - /** returns the transitions - */ - def deltaq( state:int ): HashMap = _deltaq( state ); - - /** returns the transitions - */ - def deltaq( state:Integer ): HashMap = _deltaq( state.intValue() ); - - - /** for a set of nfa states (that must exist), returns its transitions - */ - def deltaq(nset: TreeSet): HashMap = - deltaq( indexMap.get( nset ).asInstanceOf[Integer] ); - - /** for a set of nfa states (that must exist), returns its transitions - */ - def defaultq( nset:TreeSet ): Integer = - defaultq( indexMap.get( nset ).asInstanceOf[Integer] ); - - /** returns the transitions - */ - def defaultq( state: int ): Integer = - _defaultq( state ); - - /** returns the transitions - */ - def defaultq( state: Integer ): Integer = - _defaultq( state.intValue() ); - - /** returns true if the state is final - */ - def isFinal(state: int): boolean = - ((finals != null) - && (finals.get( new Integer( state )) != null)); - - /** returns true if the state is final - */ - def isFinal(state: Integer): boolean = { - return ((finals != null) && finals.containsKey( state )); - } - - /** returns true if the state is final - */ - def finalTag( state:Integer ): Integer = { - return finals.get( state ).asInstanceOf[Integer]; - } - - - def finalTag( state: int ): Integer = { - return finals.get( new Integer (state )).asInstanceOf[Integer]; - } - - /** returns true if the set of states contains at least one final state - */ - def containsFinal( Q: TreeSet ): boolean = { - val it = Q.iterator(); - while(it.hasNext()) { - if( isFinal(it.next().asInstanceOf[Integer])) - return true; - } - return false; - } - - - /** returns true if there are no finite states - */ - def isEmpty(): boolean = { - return finals.isEmpty(); - } - - // END stuff from FiniteAutom - - final val FIRST: int = 0; - final val LAST: int = FIRST + 1; - - //static final int WHICH_LONGEST_MATCH = FIRST ; - final val WHICH_LONGEST_MATCH:int = LAST ; - - // inherited from FiniteAutom: - - // int nstates; // number of states - // HashSet labels;// the alphabet - // TreeMap finals; - - // HashMap deltaq[]; - //Integer defaultq[]; - - - // TEMPORARY VAR used only during determinization and debug printing - // Q -> (Label -> Q ) - var delta: HashMap = _; - // Q -> Integer; - var indexMap: HashMap = _; - - // Integer -> Q - var invIndexMap: HashMap = _; - - // only not null if this is a right-transducer - var qbinders: Array[Vector] = _; - - final val NODEFAULT: Integer = new Integer( -1 ); - - def isSink( i:int ): boolean = { - return ( _deltaq( i ).keySet().isEmpty() - && (_defaultq != null ) - && (_defaultq( i ).intValue() == i) ); - } - - def hasDefault( i:int ): boolean = { - return _defaultq( i ) != NODEFAULT; - } - - def determinize( nfa: NondetWordAutom ): Unit = { - //Console.println("DetWordAutom:determinize"); - //System.out.println("nfa:");nfa.print(); - var states:TreeSet = _; // temp: Set[Set[Integer]] - var deftrans:HashMap = _; // Set[Integer] -> Int - - var trans: HashMap = _; // always points to a mapping ( Label -> Q ) - var ix = 0; // state index - - this._labels = nfa.labels; - ////System.out.println("Labels: "+labels); - this.delta = new HashMap(); - //this.dead = -1; - - states = new TreeSet( new StateSetComparator() ); - deftrans = new HashMap(); - // temporarily: Map[Set[Integer]] later: Map[Integer] - this.finals = new TreeMap( new StateSetComparator() ); - this.invIndexMap = new HashMap(); - this.indexMap = new HashMap(); - - // new initial state (singleton set { q0 } by construction) - val q0 = new TreeSet(); - q0.addAll( nfa.initials ); /*new Integer( 0 )); */ - states.add( q0 ); - - val empty = new TreeSet(); - deftrans.put( q0, empty ); - states.add( empty ); - deftrans.put( empty, empty ); - - val rest = new Stack(); - if( nfa.isFinal( 0 ) ) - this.finals.put( q0, nfa.finalTag( 0 ) ); - - //Console.println("...beginning"); - - rest.push( empty ); - rest.push( q0 ); - //Console.println("...beginning 2" ); - while( !rest.empty() ) { - //Console.println("...beginning 3" ); - val P1 = rest.pop().asInstanceOf[TreeSet]; - - //System.out.println("states:"+ states); - //System.out.println("P1:"+ P1); - - invIndexMap.put( new Integer( ix ), P1 ); - indexMap.put( P1, new Integer( ix )); - ix = ix + 1; - delta.put( P1, {trans = new HashMap(); trans}); - - //Console.println("...beginning 4" ); - // labelled transitions - val it = _labels.iterator(); - //Console.println("it = "+it ); - //Console.println(it.hasNext()); - - while( it.hasNext() ) { - //Console.println("...beginning 5" ); - //Console.flush; - val label = it.next(); - //Console.print( "Label: " + label +" "); - // Qdest will contain all states reachable via `label' - // from some nfa state in P1; - val Qdest = nfa.getSide( P1, label ); - //Console.println("Qdest:"+Qdest); - if( !states.contains( Qdest ) ) { - states.add( Qdest ); - ////System.out.print(" (added)" ); - rest.push( Qdest ); - ////System.out.print(" (pushed)"); - - //Console.println("nfa.containsFinal("+Qdest+") =="+nfa.containsFinal( Qdest )); - - if( nfa.containsFinal( Qdest ) ) - this.finals.put( Qdest, nfa.finalTag( Qdest )); - ////System.out.print(" (added final)"); - - } - ////System.out.println(".Qdest"); - - trans.put( label, Qdest ); - // //System.out.println( "Qdest: " + Qdest); - //Console.println("Y marks"); - } - - // default transitions - - val defTarget: TreeSet = nfa.defaultq( P1 ).asInstanceOf[TreeSet]; - //System.out.println("defTarget:"+defTarget); - deftrans.put( P1, defTarget ); - - //Console.println("X marks 0"); - - if( !states.contains( defTarget ) ) { - //Console.println("X marks 1"); - - states.add( defTarget ); - rest.push( defTarget ); - //Console.println("nfa.containsFinal("+defTarget+")"+nfa.containsFinal( defTarget )); - if( nfa.containsFinal( defTarget ) ) - this.finals.put( defTarget, nfa.finalTag( defTarget )); - } - - //Console.println("X marks"); - } - - //Console.println("...continuing"); - - // <DEBUG> - //printBefore( states, deftrans ); - - // </DEBUG> do not call printBefore after this point - // //System.out.println("indexMap: "+indexMap); - - this._nstates = states.size(); - _deltaq = new Array[HashMap]( _nstates ); - _defaultq = new Array[Integer]( _nstates ); - - // we replace Set[Set[Integer]] by its index and clean up - - val jt = states.iterator(); - while(jt.hasNext()) { - val state = jt.next().asInstanceOf[TreeSet]; - val state_x = indexMap.get( state ).asInstanceOf[Integer]; - - val defTarget = deftrans.get( state ).asInstanceOf[TreeSet]; - var defTarget_x: Integer = _; - if( null != defTarget) { - defTarget_x = indexMap.get( defTarget ).asInstanceOf[Integer]; - ////System.out.println("deftarget" + defTarget); - } else - defTarget_x = NODEFAULT; - - ////System.out.print(state.toString() + " --> " + state_x); - //System.out.println(" deftarget " + defTarget + " --> "+defTarget_x); - - trans = delta.get( state ).asInstanceOf[HashMap]; - val newTrans = new HashMap(); - val labs = _labels.iterator(); - while(labs.hasNext()) { - val label = labs.next(); - val target = trans.get( label ).asInstanceOf[TreeSet]; - var target_x: Integer = _; - if( null != target ) { - // //System.out.println("target :"+target); - target_x = indexMap.get( target ).asInstanceOf[Integer]; - - if( target_x.intValue() != defTarget_x.intValue() ) { - // replace target by target_x - // (use type-unawareness) - newTrans.put( label, target_x ); - } - trans.remove( label ); - } - - } - _deltaq( state_x.intValue() ) = newTrans; - _defaultq( state_x.intValue() ) = defTarget_x; - - delta.remove( state ); - deftrans.remove( state ); - - } - //Console.println("determinize::: finals"+finals); - val oldfin: TreeMap = finals; - this.finals = new TreeMap(); - var kt = oldfin.keySet().iterator(); - while(kt.hasNext()) { - val state = kt.next().asInstanceOf[TreeSet]; - val state_x = indexMap.get( state ).asInstanceOf[Integer];; - this.finals.put( state_x, oldfin.get( state ) ); // conserve tags - } - - // clean up, delete temporary stuff - /* - // we cannot clean up, indexmap is needed later - for( Iterator it = states.iterator(); it.hasNext(); ) { - ((TreeSet) it.next()).clear(); - } - */ - states.clear(); - - //Console.println("...done"); - //minimize(); - } - - - - def isDead(state: Int): Boolean = { - return state == _nstates - 1; // by construction - } - - def isDead(state: Integer): Boolean = { - return state.intValue() == _nstates - 1; // by construction - } - - - /** returns target of the transition from state i with label label. - * null if no such transition exists. - */ - def delta(i: Int, label: Label): Integer = { - var target:Integer =_; - label match { - case DefaultLabel() => - if (! hasDefault(i)) - return null; - return _defaultq( i ).asInstanceOf[Integer] ; - case SimpleLabel( _ ) | TreeLabel( _ ) => - return _deltaq( i ).get( label ).asInstanceOf[Integer] ; - /*case LPair( Integer state, Label lab ): - return state; - */ - case _ => - throw new ApplicationError("whut's this: label="+label+", class "+label.getClass()); - } - } - - def delta(i: Integer, label: Label): Integer = - delta(i.intValue(), label); - - /** should maybe in nfa, not here - */ - /*static */ - protected def smallestFinal( nfa: NondetWordAutom, states:TreeSet ): Integer = { - - var min = Integer.MAX_VALUE ; - val it = states.iterator(); - while (it.hasNext()) { - val state = it.next().asInstanceOf[Integer]; - if( nfa.isFinal( state ) && (state.intValue() < min )) - min = state.intValue(); - } - if (min == Integer.MAX_VALUE) - throw new ApplicationError("I expected a final set of states"); - return new Integer( min ); - } - - protected def allSetsThatContain( ndstate: Integer ): Vector = { - val v = new Vector(); - val it = indexMap.keySet().iterator(); - while(it.hasNext()) { - val ndstateSet = it.next().asInstanceOf[TreeSet]; - if( ndstateSet.contains( ndstate )) - v.add( ndstateSet ); - } - return v; - } - - - protected def filterItOutQuoi( dLeft: DetWordAutom, npTarget: Npair,lab:LPair , nsrc:TreeMap ):Unit = { - val theLabel = lab.lab; - val ntarget = lab.state; - - // e.g.[2,(3),4] --> 7 - val dstate = dLeft.indexMap.get( npTarget.nset ).asInstanceOf[Integer]; - - // eg. 3 -> [3] [2,3] - val targets:Vector = dLeft.allSetsThatContain( ntarget ); - - ////System.out.println( targets+", of these " ) ; - - // filter out those source states which arrive here... - val su = targets.iterator(); - while(su.hasNext()) { - val nset = su.next().asInstanceOf[TreeSet]; - val ddelta = dLeft.deltaq( nset ).asInstanceOf[HashMap]; - - // ... at THIS dstate - if(ddelta.get( theLabel ).asInstanceOf[Integer] == dstate ) { - - val np1 = new Npair( ntarget, nset ); - - ////System.out.print( np1.toString( dLeft.indexMap )); - - if( WHICH_LONGEST_MATCH == FIRST ) - addTransitionFLM( nsrc, np1 ); - else - addTransitionLLM( nsrc, np1 ); - } - - } - } - - /** all default transitions from sets that contain nq to npTarget - */ - protected def filterItOutQuoiDefault( dLeft: DetWordAutom ,npTarget:Npair , nq:Integer , nsrc:TreeMap ): Unit = { - - - ////System.out.println( "npTarget = " + npTarget ) ; - - val allSources = dLeft.allSetsThatContain( npTarget.nstate ); - val it = allSources.iterator(); - while(it.hasNext()) { - - // e.g.[2,(3),4] --> 7 - //Integer dstate = (Integer) dLeft.indexMap.get( npTarget.nset ); - - val dstate = dLeft.indexMap.get( it.next() ).asInstanceOf[Integer]; - - //System.out.println( "dstate = " + dstate ) ; - - //assert dstate != null; - - // eg. 3 -> [3] [2,3] - val targets = dLeft.allSetsThatContain( nq ); - - //System.out.println( "targets: " + targets ) ; - - // filter out those source states which arrive here... - val su = targets.iterator(); - while(su.hasNext()) { - val nset = su.next().asInstanceOf[TreeSet]; - val ddef = dLeft.defaultq( nset ); - - //System.out.println( "ddef ="+ddef ); - - // ... at THIS dstate - if( ddef == dstate ) { - - val np1 = new Npair( nq, nset ); - - // print target - //System.out.print( np1.toString( dLeft.indexMap )); - - if( WHICH_LONGEST_MATCH == FIRST ) - addTransitionFLM( nsrc, np1 ); - else - addTransitionLLM( nsrc, np1 ); - - } - - } - } - } - - /** this implements the first longest match policy - */ - protected def addTransitionFLM( nsrc:TreeMap , np:Npair ): Unit= { - val np2 = nsrc.get( np.nset ).asInstanceOf[Npair ]; - - // (policy) first longest match - if(( np2 == null ) - ||( np2.nstate.intValue() > np.nstate.intValue())) { - nsrc.put( np.nset, np ); - } - - } - - /** this implements the last longest match policy (!) - */ - protected def addTransitionLLM(nsrc: TreeMap, np: Npair ): Unit = { - val np2 = nsrc.get( np.nset ).asInstanceOf[Npair]; - - // (policy) first longest match - if(( np2 == null ) - ||( np2.nstate.intValue() < np.nstate.intValue())) { - nsrc.put( np.nset, np ); - } - - } - - - /** build a deterministic right to left transducer from the args - */ - def this(right: NondetWordAutom, left:NondetWordAutom, dLeft: DetWordAutom ) = { - this(); - - /* System.out.println("DetWordAutom.<init>(nfa,nfa,dfa)"); - System.out.println("nfa-left:");left.print(); - System.out.println("nfa-right:");right.print(); - System.out.println("dLeft:"+dLeft.print()); - System.out.println("dLeft.finals"+dLeft.finals); - */ - this.indexMap = dLeft.indexMap; - this.invIndexMap = dLeft.invIndexMap; - // fix indexMap - /* // unnecessary - TreeSet q0 = new TreeSet(); - q0.add( new Integer( 0 )); - indexMap.put( q0, new Integer( 0 )); - //System.out.println("check out the indexMap!" + indexMap); - */ - - val visited_n = new TreeSet( new NpairComparator() ); - val rest = new Stack(); - - // right is "nearly deterministic" - // we can follow reverse traces paths by using dLeft.indexMap - - // start with right.initials, left.final, dLeft.final - val it = dLeft.finals.keySet().iterator(); - while(it.hasNext()) { - val fstate = it.next().asInstanceOf[Integer]; - val nfstate = invIndexMap.get( fstate ).asInstanceOf[TreeSet]; - //System.out.print( "final state:"+fstate); - //System.out.print( " correspond to set of states:"+ nfstate ); - - val min_ndstate: Integer = smallestFinal( left, nfstate ); - - val npair:Npair = new Npair( min_ndstate, nfstate ); - - //System.out.println( " smallest final of these: "+ min_ndstate ); - - - //System.out.println( "push final nfa state "+npair.toString( dLeft.indexMap )); - - if( !visited_n.contains( npair )) { - visited_n.add( npair ); - rest.push( npair ); - } - } - - val ratLab = new HashMap(); // maps nset to label,HashMap - val ratDelta = new HashMap(); // maps nset to Vector[ NP ]targets - - val ratDefault = new HashMap(); // maps nset to NP (one target) - - var ix = 1; - val ix_initial = rest.clone().asInstanceOf[Stack]; - var ix_final = new TreeSet( new NpairComparator() );; - - val newIndexMap = new TreeMap( new NpairComparator() ); - - while( !rest.isEmpty() ) { - - val npair = rest.pop().asInstanceOf[Npair]; - newIndexMap.put( npair, new Integer(ix)); - - ratDelta.put( npair, new Vector() ); - - if( npair.nset.contains( new Integer( 0 )) ) { - ix_final.add( npair ); - } - ix = ix + 1; - - //System.out.println(" popped "+npair.toString( dLeft.indexMap )); - - ////System.out.print(" binders: "); - ////System.out.print( right.qbinders[ npair.nstate.intValue() ] ); - - val delta = right.deltaq( npair.nstate ); - - ////System.out.print(" we could have arrived : "); - //search the delta for target invIndexMap - - val labelToNset = new HashMap(); - val labelToFrom = new HashMap(); - - // maps nsets to the active nstates - var nsrc = new TreeMap( new StateSetComparator() ); - - // berry-sethi construction assures that - // there is only one label for outgoing transitions - var theLabel:Label = null; - - // collect all transition possible in the DFA - val jt = delta.keySet().iterator(); - while(jt.hasNext()) { - val lab = jt.next().asInstanceOf[LPair]; - - // lab.state is the target in the NFA - - if( null == theLabel ) { - ratLab.put( npair, lab.lab ); - ////System.out.print(" with \""+lab.lab+"\" "); - } - theLabel = lab.lab ; - - ////System.out.print("\nfrom n" + lab.state +" ... "); - - // these are too many, filter out those that exist in DFA - - filterItOutQuoi( dLeft, npair, lab, nsrc ); - - } - - - ////System.out.println( "---" ); - - ////System.out.println("all sources: "); - - // !! first longest match - val ut = nsrc.keySet().iterator(); - while(ut.hasNext()) { - val nset = ut.next().asInstanceOf[TreeSet]; - val np2: Npair = nsrc.get( nset ).asInstanceOf[Npair] ; - - //assert( np2 != null ); - ////System.out.println("target: n"+npair.nstate+" via: "+theLabel+" from "+ np2.toString( dLeft.indexMap ));// nset:"+nset+ " namely state n"+ dest); - - val v = ratDelta.get( npair ).asInstanceOf[Vector]; - - v.add( np2 ); - - if( !visited_n.contains( np2 ) ) { - - visited_n.add( np2 ); - rest.push( np2 ); - } - - } - - //System.out.println("default sources: "); - - // maps nsets to the active nstates - nsrc = new TreeMap( new StateSetComparator() ); - - // now for all default transitions that arrive at this nfa state - val defqs = right.defaultq( npair.nstate ); - val kt = defqs.iterator(); - while( kt.hasNext() ) { - val nq = kt.next().asInstanceOf[Integer]; - //System.out.println("checking nq="+nq); - filterItOutQuoiDefault( dLeft, npair, nq, nsrc ); - //System.out.println( "nsrc after "+nq+" is "+nsrc ); - } - - //System.out.println( "defqs :"+defqs ); - //System.out.println( "nsrc :"+nsrc ); - var nut = nsrc.keySet().iterator(); - while(nut.hasNext()) { - - val np2 = nsrc.get( nut.next() ).asInstanceOf[Npair]; - - var v = ratDefault.get( npair ).asInstanceOf[Vector] ; - if( v == null ) - ratDefault.put( npair, {v = new Vector(); v} ); - v.add( np2 ); - - if( !visited_n.contains( np2 ) ) { - - visited_n.add( np2 ); - rest.push( np2 ); - } - - } - - ////System.out.println("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"); - - } - - // Renumbering - - ////System.out.println( "output: a dfa with "+ix+"states"); - - // FIX: empty regular expression (as in "List()") is valid - //assert ( !ix_final.isEmpty() ) : "no final states found"; - - ////System.out.println( "final state:"+ix_final); - - //System.out.println( "indexMap: " +indexMap); - //System.out.println( "newIndexMap: " +newIndexMap); - this.finals = new TreeMap(); - this._nstates = ix; - val dratDelta = new Array[HashMap]( ix ); - qbinders = new Array[Vector]( ix ); - _labels = new HashSet(); - val kit = ratDelta.keySet().iterator(); - while(kit.hasNext()) { - val np = kit.next().asInstanceOf[Npair]; - - //System.out.print( "\nstate: "+np); - val ndset = np.nset; - val dstate = newIndexMap.get( np ).asInstanceOf[Integer]; - //assert dstate != null : "no dstate for "+np.toString(dLeft.indexMap); - - //System.out.print(" binders:"); - - qbinders( dstate.intValue() ) = left.qbinders( np.nstate.intValue() ); - - //System.out.print( qbinders[dstate.intValue() ]); - - //System.out.println(" transitions:"); - if( ix_final.contains( np ) ) { - val fin_ix = newIndexMap.get( np ).asInstanceOf[Integer]; - finals.put( fin_ix, new Integer( 0 )); - } - - val lab = ratLab.get( np ).asInstanceOf[Label]; - val v = ratDelta.get( np ).asInstanceOf[Vector]; - - val ddelta = new HashMap(); - - // v might be null if there are only default transitions - if( v != null ) { - val it2 = v.iterator(); - while(it2.hasNext()) { - - val np2= it2.next().asInstanceOf[Npair]; - //System.out.print( "("+lab+","+np2+") " ); - val ddestR = newIndexMap.get( np2 ).asInstanceOf[Integer]; - val ddest = indexMap.get( np2.nset ).asInstanceOf[Integer]; - //assert ddest != null : - //"no ddest for " - //+np2.toString(dLeft.indexMap); - - val newLab = new LPair(ddest, lab); - ddelta.put( newLab, ddestR ); - _labels.add( newLab ); - - } - dratDelta( dstate.intValue() ) = ddelta; - - } - } - var itt = ratDefault.keySet().iterator(); - while(itt.hasNext()) { - val np = itt.next().asInstanceOf[Npair]; - val dstate = newIndexMap.get( np ).asInstanceOf[Integer]; - - //System.out.print("\nstate: "+np+" default trans: "); - - val v = ratDefault.get( np ).asInstanceOf[Vector]; - val ut = v.iterator(); - while(ut.hasNext()) { - val np2 = ut.next().asInstanceOf[Npair]; - val targetL = indexMap.get( np2.nset ).asInstanceOf[Integer];; - val targetR = newIndexMap.get( np2 ).asInstanceOf[Integer];; - - val defLab = new LPair( targetL, DefaultLabel() ); - - _labels.add( defLab ); - //System.out.print( "("+defLab+","+np2+") " ); - - var d = dratDelta( dstate.intValue() ); - if( d == null ) - dratDelta( dstate.intValue() ) = {d = new HashMap(); d}; - - d.put( defLab, targetR ); - } - } - - _deltaq = dratDelta; - - val hmap = new HashMap(); - - // final states of left are initial states of right - // problem: still need to choose the one - - while( !ix_initial.isEmpty() ) { - val np = ix_initial.pop().asInstanceOf[Npair]; - - val i = newIndexMap.get( np ).asInstanceOf[Integer]; //R-state - val dtarget = indexMap.get( np.nset ).asInstanceOf[Integer];// left-d-state - - hmap.put( dtarget, i ); - } - _deltaq( 0 ) = hmap; // careful, this maps Int to Int - - qbinders( 0 ) = new Vector(); - //((Vector[])defaultq)[ 0 ] = new Vector(); is null - //printBeforeRAT( dratDelta ); - - } - - def printBeforeRAT1(str: String): Unit = { - val tmp = new StringBuffer( str ); - var j = tmp.length(); - while(j < 20) { - tmp.append(" "); - j = j + 1; - } - Console.println( tmp.toString() ); - } - - def printBeforeRAT( dratDelta: Array[HashMap] ): Unit = { - //System.out.println(); - printBeforeRAT1( "dratDelta" ); - printBeforeRAT1( "[index]" ); - //System.out.println(); - var i = 0; - while(i < dratDelta.length) { - if( isFinal( i )) - printBeforeRAT1( "*"+i ); - else - printBeforeRAT1( " "+i ); - - //System.out.println( dratDelta[ i ] ); - i = i + 1 - } - } - - /** you may only call this before the set[set[...]] representation - * gets flattened. - */ - def printBefore(states: TreeSet, deftrans: HashMap): Unit = { - var trans: HashMap = _; - Console.println(states); - val it = states.iterator(); - while (it.hasNext()) { - val state = it.next().asInstanceOf[TreeSet]; - Console.print("state:" + state.toString() + " transitions "); - trans = delta.get( state ).asInstanceOf[HashMap]; - val labs = _labels.iterator(); - while(labs.hasNext()) { - val label = labs.next(); - val target = trans.get( label ).asInstanceOf[TreeSet]; - Console.print( " (" + label.toString() - + "," + target.toString()+")"); - } - Console.print("default trans"+deftrans.get(state)); - Console.println; - } - Console.println("final states:" + finals); - } -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/Label.scala b/sources/scala/tools/scalac/transformer/matching/Label.scala deleted file mode 100644 index d260feded6..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/Label.scala +++ /dev/null @@ -1,136 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.ApplicationError; -import scalac.ast.Tree; -import scalac.ast.TreeInfo; -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -import Tree.Literal; - -/** - * This class represents the label that a transition in an automaton - * may carry. These get translated to specific (boolean) tests - */ -package scala.tools.scalac.transformer.matching { - -class Label { - - - //case class RLabel(Object rstate, Label lab, Symbol vars[]); - - override def hashCode(): Int = this match { - case DefaultLabel() => - return 0; - case SimpleLabel(lit) => - return lit.value.hashCode(); - case TreeLabel(pat) => - // if pat is an Apply, than this case can only be correctly - // handled there are no other similar Applys (nondeterminism) - return pat.getType().hashCode(); - case TypeLabel(tpe) => - return tpe.hashCode(); - case _ => - return super.hashCode(); - } - - override def equals( o: Any ): Boolean = { - if( !(o.isInstanceOf[Label] )) - return false; - val oL = o.asInstanceOf[Label]; - //System.out.print(this + " equals " + oL); - this match { - case DefaultLabel()=> - oL match { - case DefaultLabel() => - return true; - case _ => false; - } // - case SimpleLabel( lit ) => - oL match { - case SimpleLabel( lit2 ) => - return /*(lit.kind == lit2.kind) - && */lit.value.equals( lit2.value ); - case _ => false; - } - - case TreeLabel( pat ) => - oL match { - case TreeLabel( pat2 ) => - pat match { - case Tree.Apply( _, _ ) => - pat2 match { - case Tree.Apply( _, _ ) => - return TreeInfo.methSymbol( pat ) == TreeInfo.methSymbol( pat2 ); - } - case _ => false; - } - case _ => false - } - - case TypeLabel(tpe) => - oL match { - case TypeLabel( tpe2) => - return tpe.equals(tpe2); - case _ => false; - } - case LPair(state, lab) => - oL match { - case LPair(state2, lab2) => - return state.equals(state2) && lab.equals(lab2); - case _ => false; - } - case _ => return false; - } - } - - - def toString2(): String = { - val ext = System.getProperty("extendedMatching"); - if ((ext != null) && ext.equals("true")) { - this match { - case DefaultLabel() => - return "<>:p"+p; - case SimpleLabel( lit ) => - return lit.toString()+":p"+p; - case TreeLabel( pat ) => - return pat.getType().toString()+":p"+p; - - case _ => throw new ApplicationError("this never happens"); - } - } - throw new ApplicationError("this never happens"); - } - - override def toString(): String = this match { - case DefaultLabel() => - "<>"; - case SimpleLabel( lit) => - lit.toString(); - case TreeLabel(pat) => - pat.toString(); - case TypeLabel(tpe) => - tpe.toString(); - case LPair(state, lab) => - "(" + state.toString() + "," + lab.toString() + ")"; - case _ => - throw new ApplicationError("this never happens"); - } - - val p = -1; // tree state - only needed for extended matching - -} - -case class DefaultLabel() extends Label; -case class SimpleLabel(lit: Literal) extends Label; -case class TreeLabel(pat: Tree) extends Label; // Apply, Sequence -case class TypeLabel(tpe: Type) extends Label; // Apply, Sequence -case class LPair(state: Integer, lab: Label) extends Label; - -} // package diff --git a/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala deleted file mode 100644 index 3629f94ed6..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala +++ /dev/null @@ -1,246 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac._; -import scalac.ast._; -import scalac.symtab._; -import Tree._; -import scalac.util.Names; - -import java.util._ ; - -import scala.tools.util.Position; - -package scala.tools.scalac.transformer.matching { - -class LeftTracerInScala(dfa: DetWordAutom, elementType: Type, owner: Symbol, cf: CodeFactory, val selector: Tree) -extends TracerInScala(dfa, elementType, owner, cf) { - - //final def defs = cf.defs; - - /** symbol of the accumulator ( scala.SequenceList ) - */ - var accumSym: Symbol = _; - var accumType: Type = _; - var accumTypeArg: Type =_ ; - - def _accumType(elemType: Type): Type = { - cf.SeqTraceType( elemType ); - } - - - protected def initializeSyms(): Unit = { - this.funSym = owner.newLabel( pos, - cf.fresh.newName( "left" )); - - this.iterSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName( "iter" )) - .setType( cf._seqIterType( elementType ) ) ; - - this.stateSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName( "q" )) - .setType( defs.int_TYPE() ) ; - - this.accumType = _accumType( elementType ); - this.accumTypeArg = accumType.typeArgs()( 0 ); - this.accumSym = owner.newVariable( pos, // accumulator - Modifiers.MUTABLE, - cf.fresh.newName( "acc" )) - .setType( accumType ); - - //this.funSym - // .setType( new Type.MethodType( new Symbol[] { - // accumSym, iterSym, stateSym}, - // accumType)); - - this.funSym - .setType( new Type.MethodType( Predef.Array[Symbol] ( // dummy symbol MethodType - funSym.newVParam( pos, 0, cf.fresh.newName( "q" ), defs.int_TYPE()), - funSym.newVParam( pos, 0, cf.fresh.newName( "acc" ), accumType ) ), - accumType)); // result type = List[T] - - this.resultSym = owner.newVariable(pos, - 0, - cf.fresh.newName("trace")) - .setType( accumType ) ; - - this.curSym = owner.newVariable( pos, 0, Names.cur ) - .setType( elementType ); - - this.hasnSym = owner.newVariable( pos, 0, Names.hasNext ) - .setType( defs.boolean_TYPE() ); - - } - - /* should throw an exception here really, e.g. MatchError - */ - override def code_fail() = { - gen.Ident( accumSym.pos, accumSym ); - } - - /** returns translation of transition with label from i. - * returns null if there is no such transition(no translation needed) - */ - override def code_delta(i: Int, label: Label): Tree = { - val target = dfa.delta( i, label ); - - /* - System.out.println("LeftTracer:calling dfa.delta("+i+","+label+")"); - System.out.println("result: "+target); - */ - if( target == null ) - null; - else { - // (optimization) that one is a dead state (does not make sense for tracer) - /* - if( target == dfa.nstates - 1 ) - return code_fail(); - */ - - /* - Tree newAcc = cf.newSeqTraceCons(new Integer(i), - currentElem(), - _ref( accumSym )); - */ - val hd = cf.newPair( gen.mkIntLit(cf.pos, i), currentElem() ); - val newAcc = gen.mkNewCons( cf.pos, - accumTypeArg, - hd, - gen.Ident( cf.pos, accumSym )); - - //return callFun( new Tree[] { newAcc , _iter(), gen.mkIntLit( cf.pos, target )} ); - callFun( Predef.Array[Tree]( gen.mkIntLit( cf.pos, target.intValue() ), newAcc ) ); - } - } - - - def code_body(): Tree = { - - var body = code_error(); // never reached at runtime. - - // state [ nstates-1 ] is the dead state, so we skip it - - //`if( state == q ) <code_state> else {...}' - var i = dfa.nstates() - 2; - while (i >= 0) { - body = code_state(i, body); - i = i - 1; - } - loadCurrentElem(body); - } - - /** return code for state i of the dfa SAME AS IN SUPER, ONLY SINK IS GONE - */ - def code_state(i: Int, elseBody: Tree): Tree = { - - var runFinished: Tree = _; // holds result of the run - var finalSwRes: Int = 0; - - runFinished = run_finished(i); - - var stateBody: Tree = _ ; // action(delta) for one particular label/test - - // default action (fail if there is none) - - stateBody = code_delta( i, DefaultLabel()); - - if( stateBody == null ) - stateBody = code_fail(); - // transitions of state i - - val trans = dfa.deltaq( i ); - val labs = dfa.deltaq( i ).keySet().iterator(); - while(labs.hasNext()) { - val label = labs.next(); - val next = trans.get( label ).asInstanceOf[Integer]; - - val action = code_delta( i, label.asInstanceOf[Label] ); - - if( action != null ) { - stateBody = gen.If( currentMatches(label.asInstanceOf[Label]), - action, - stateBody); - } - } - stateBody = gen.If(cf.Negate(gen.Ident(cf.pos, hasnSym)), - runFinished, - stateBody ); - gen.If( cf.Equals( _state(), gen.mkIntLit(cf.pos, i )), - stateBody , - elseBody ); - } - - def getTrace(): Tree = { - - initializeSyms(); - - cf.gen.mkBlock(cf.pos, Predef.Array[Tree] ( - gen.ValDef( iterSym, cf.newIterator( selector, selector.getType() )), - gen.ValDef( stateSym, gen.mkIntLit( cf.pos, 0) ), - gen.ValDef( accumSym, gen.mkNil( cf.pos )), - gen.ValDef( resultSym, - gen.LabelDef( this.funSym, - Predef.Array[Ident] ( - gen.Ident( pos, stateSym ), - gen.Ident( pos, accumSym ) - ), code_body() /* code_body_new ? */ )) - ), - gen.Ident( cf.pos, resultSym )); - } - - // calling the AlgebraicMatcher here - override def _cur_match(pat: Tree): Tree = { - //return gen.mkBooleanLit(cf.pos, true); - - //System.out.println("calling algebraic matcher on type:" + pat.type); - - val m = new PartialMatcher( owner, - currentElem(), - defs.boolean_TYPE() ); - - val res1 = if(containsBinding(pat)) { - pat match { - case Sequence(pats) => - gen.mkBooleanLit(cf.pos, true); - case _ => - null - } - } else null; - - if (res1 == null) { - - am.construct(m, Predef.Array[Tree] ( - cf.gen.CaseDef( pat, - gen.mkBooleanLit( cf.pos, true )), - cf.gen.CaseDef( cf.gen.Ident( pat.pos, defs.PATTERN_WILDCARD ), - gen.mkBooleanLit( cf.pos, false)) ), - false); - val res = am.toTree(); - // debugprint ? - res; - } else null - } - - - /** return the accumulator + last state - */ - override def run_finished(state: Int): Tree = { - val hd = cf.newPair( gen.mkIntLit(cf.pos, state), - gen.mkDefaultValue(cf.pos, - elementType)); - //System.err.println(hd.type); - gen.mkNewCons(cf.pos, - accumTypeArg, - hd, - gen.Ident( cf.pos, accumSym )); - } - -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/NondetWordAutom.scala b/sources/scala/tools/scalac/transformer/matching/NondetWordAutom.scala deleted file mode 100644 index d87cee40f2..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/NondetWordAutom.scala +++ /dev/null @@ -1,527 +0,0 @@ - - -import scalac.ApplicationError ; -import scalac.ast.Tree ; -import scalac.util.Name ; -import Tree._ ; - -import java.util._ ; -package scala.tools.scalac.transformer.matching { -/** a nondeterministic word automaton. - * states are represented (implicitly) as Integer objects. - */ - -class NondetWordAutom { - // BEGIN stuff from FiniteAutom - - //final static Integer FINTAG = new Integer(0); - - /** number of states */ - var nstates: int =_; - - /** the 'alphabet' */ - var labels: HashSet = _; - - /** the set of final states, here as a TreeMap */ - var finals: TreeMap = _; - - /** dfa: HashMap trans: Object -> Integer - * nfa: HashMap trans: Object -> Vector [ Integer ] - * - * nfa: Integer ->(Object -> Vector [ Int ]) - * [q] |->( a |-> { q' | (q,a,q') in \deltaright } ) - * - * dfa: Integer ->(Object -> Int) - * [q] |->( a |-> q' | \deltaright(q,a) = q' } ) - */ - - var _deltaq:Array[HashMap] = _; - - var _defaultq:Array[Vector] = _; // this gives the default transitions - - //public HashMap deltaq[]; - - // --- accessor methods - - /** returns number of states - def nstates(): int = { - return nstates; - } - */ - - /** returns the labels - def labels(): HashSet = { - return _labels; - } - */ - - /** returns the transitions - */ - def deltaq( state: int ):HashMap = { - return _deltaq( state ); - } - - /** returns the transitions - */ - def deltaq( state: Integer ): HashMap = { - return _deltaq( state.intValue() ); - } - - /** returns the transitions - */ - def defaultq( state: int ): Vector = { - return _defaultq( state ); - } - - /** returns the transitions - */ - def defaultq( state:Integer ): Vector = { - return _defaultq( state.intValue() ); - } - - - /** returns true if the state is final - */ - def isFinal( state:int ): boolean = { - return ((finals != null) - && (finals.get( new Integer( state )) != null)); - } - - /** returns true if the state is final - */ - def isFinal( state:Integer ): boolean = { - return ((finals != null) && finals.containsKey( state )); - } - - /** returns true if the state is final - */ - def finalTag( state: Integer ): Integer = { - return finals.get( state ).asInstanceOf[Integer]; - } - - - def finalTag( state:int ): Integer = { - return finals.get( new Integer (state )).asInstanceOf[Integer]; - } - - /** returns true if the set of states contains at least one final state - */ - def containsFinal( Q:TreeSet ): boolean = { - var it = Q.iterator(); - while(it.hasNext()) { - if( isFinal( it.next().asInstanceOf[Integer])) - return true; - } - return false; - } - - - /** returns true if there are no finite states - */ - def isEmpty(): boolean = finals.isEmpty(); - - // END stuff from FiniteAutom - - - // inherited from FiniteAutom - - // set of *distinct* objects that may label transitions - // see Object.hashCode() to see why this works - - //HashSet labels; - //TreeMap finals; - - var initials: TreeSet = _; // ? need this ? - // --- - - // Object deltaq --> - // HashMap deltaq[]; // this gives the transitions of q; - - var leftTrans: boolean = _; - var rightTrans: boolean = _; - - /** if true, this automaton behaves as a special left transducer. - * if a run succeeds, the result is not "true" but the entire - * run of the automaton as a sequence of (label,state) - pairs. - * used for binding variables. - */ - def producesRun(): boolean = { - return leftTrans; - } - - def consumesRun(): boolean = { - return rightTrans; - } - - def initial( i: Integer ): boolean = { - return initials.contains( i ); - } - var qbinders: Array[Vector] = _; - - /** returns all states accessible from Qsrc via label. - * used by class DetWordAutomaton. - */ - def getSide ( Qsrc:TreeSet , label:Object ): TreeSet = { - //Console.println("NWA::getSide(Qsrc="+Qsrc); - val Qdest = new TreeSet(); - var it = Qsrc.iterator(); - while(it.hasNext()) {// state - val q = it.next().asInstanceOf[Integer].intValue(); - val ps = deltaq( q ).get( label ).asInstanceOf[Vector]; - //Console.println("deltaq(q) = "+deltaq(q)); - //Console.println("_deltaq(q) = "+_deltaq(q)); - //Console.println("ps = "+ps); - if( null != ps ) { - Qdest.addAll( ps ); - } - //Console.println("defq = "+_defaultq( q )); - Qdest.addAll( _defaultq( q ) ); - } - //Console.println("DONE-NWA::getSide"); - return Qdest; - } - - /** returns the transitions - */ - def defaultq( P1: Set ): Object = { - val defTarget = new TreeSet(); - var p1 = P1.iterator(); - while(p1.hasNext()) { - val q1 = p1.next().asInstanceOf[Integer].intValue(); - //System.out.println(" q1:"+q1+ " defa: "+defaultq( q1 )); - defTarget.addAll( _defaultq( q1 ) ); - } - return defTarget; - } - - - /** first match policy: among several final states, the smallest one is - * chosen. used by class DetWordAutomaton - */ - def finalTag( Q:Set ): Integer = { - - var min = Integer.MAX_VALUE ; - var it = Q.iterator(); - while(it.hasNext()) { - val state = it.next().asInstanceOf[Integer]; - val tag = finals.get( state ).asInstanceOf[Integer]; - if( tag != null ) { - if( tag.intValue() < min ) - min = tag.intValue(); - } - } - - if ( min == Integer.MAX_VALUE ) - throw new ApplicationError( "there should be a final state "); - - return new Integer( min ); - } - - /* - void tmap(int offs, TreeMap t) = { - TreeMap nt = new TreeMap(); - for(Iterator it = t.keySet().iterator(); it.hasNext(); ) = { - Integer key = (Integer) it.next(); - Integer newkey = new Integer( key.intValue() + offs ); - Integer val = (Integer) t.get( key ); - Integer newval = new Integer( val.intValue() + offs ); - - nt.put( newkey, newval ); - } - return nt; - } - */ - // hashmaps, treemaps - def mapmap(src:Map, offset:int , dest:Map , mapkeys:boolean , mapvals:boolean ): Map = { - var it = src.keySet().iterator(); - while(it.hasNext()) { - var key = it.next(); - var value = src.get( key ); - if( mapkeys ) key = new Integer( key.asInstanceOf[Integer].intValue() - + offset ); - if( mapvals ) value = vmap( offset, value.asInstanceOf[Vector] ) ; - /* new Integer( ((Integer)val).intValue() - + offset ); - */ - dest.put( key, value ); - } - return dest; - } - - def vmap(offs:int , v:Vector ): Vector = { - if( v == null ) - return null; - var res = new Vector( v.size() ); - var it = v.iterator(); - while(it.hasNext()) { - val item = it.next().asInstanceOf[Integer]; - res.add( new Integer( item.intValue() + offs )); - } - return res; - - } - - /* - void relocate_defaultq( int offs, Vector _defaultq[] ) = { - for( int i = 0; i < this.nstates; i++ ) = { - _defaultq[ i + offset ] = vmap( offset, ((Vector[])defaultq)[ i ]); - } - } - */ - - /** copies the values in the fields of this object into the - * arguments, possibly adding an offset. - */ - def relocate( offset:int, _finals:TreeMap, _deltaq1:Array[HashMap], _defaultq1:Array[Vector], _qbinders1:Array[Vector] ): Unit = { - - mapmap( finals, offset, _finals, true, false); - var i = 0; - while(i < this.nstates) { - - _deltaq1 ( i + offset ) = - mapmap( deltaq( i ), offset, new HashMap(), false, true).asInstanceOf[HashMap]; - - _defaultq1( i + offset ) = vmap( offset, this.defaultq( i ) ); - i = i + 1; - } - if ((_qbinders1 != null) &&( qbinders != null )) { - i = 0; - while(i < this.nstates ) { - //System.out.println("hallo"+qbinders); - //System.out.println("qbinders[ i ] :"+qbinders[ i ]); - //assert _qbinders != null; - //System.out.println("_qbinders :"+_qbinders); - - _qbinders1( i + offset ) = qbinders( i ); - i = i + 1 - } - } - } - - - /** if there is more than one initial state, a new initial state - * is created, with index 0 - */ - def normalize( initials:TreeSet , reloc:boolean ): Unit = { - //if( initials.size() == 1 ) - // return; - - var idelta = new HashMap(); - var idefault = new TreeSet(); - - var q0 = new Integer( 0 ); - - var it = initials.iterator(); - while(it.hasNext()) { - - val ostate = it.next().asInstanceOf[Integer]; - - val finTag = finals.get( ostate ).asInstanceOf[Integer] ; - if(( finTag != null ) && ( finals.get( q0 ) == null)) - finals.put( q0, finTag ); - - - var tmp = deltaq( ostate ); - - if( reloc ) - tmp = mapmap( tmp, 1, new HashMap(), false, true ).asInstanceOf[HashMap]; - - val labs = tmp.keySet().iterator(); - while(labs.hasNext()) { - val lab = labs.next(); - var itarget = idelta.get( lab ).asInstanceOf[Vector]; - if( null == itarget ) - idelta.put( lab, {itarget = new Vector(); itarget}); - val otarget = tmp.get( lab ).asInstanceOf[Vector]; - itarget.addAll( otarget ); - } - //System.out.println( "normalize:defaultq[ "+ostate+" ] "+((Vector[]) defaultq) [ ostate.intValue() ]); - if( defaultq( ostate ) != null ) - idefault.addAll( defaultq( ostate ) ); - } - - if( reloc ) { - val m = 1 + this.nstates; - val _finals = new TreeMap(); - val _deltaq = new Array[HashMap]( m ); - val _defaultq = new Array[Vector]( m ); - var _qbinders: Array[Vector] = null; - - if( qbinders != null ) - _qbinders = new Array[Vector]( m ); - - relocate( 1, _finals, _deltaq, _defaultq, _qbinders ); - - this.nstates = m; - this.finals = _finals; - this._deltaq = _deltaq; - this._defaultq = _defaultq; - this.qbinders = _qbinders; - } - - this._deltaq ( 0 ) = idelta; - //System.out.println("normalize:deltaq[ 0 ]"+ idelta ); - this._defaultq( 0 ) = new Vector( idefault ); - - //System.out.println("normalize:defaultq[ 0 ]"+ idefault ); - - this.initials = new TreeSet(); - this.initials.add( q0 ); - } - - - /** called from Berry-Sethi construction. - */ - - def this(nstates:int, _labels:HashSet, initials: TreeSet, finals:TreeMap, deltaq:Array[HashMap], defaultq:Array[Vector], qbinders:Object ) = { - this(); - //Console.println("NWA::this(. . . . )"); - this.nstates = nstates; - this.labels = _labels; - this.initials = initials; - this.finals = finals; - this._deltaq = deltaq; - this._defaultq = defaultq; - this.qbinders = qbinders.asInstanceOf[Array[Vector]]; - //print(); - //System.exit(0); - } - - - - var offset:Array[int] = _; // only used if constructed from multiple - - def collectLabels( nfa:Array[NondetWordAutom ] ): Unit = { - this.labels = new HashSet(); - var i = 0; - while(i < nfa.length) { - this.labels.addAll( nfa( i ).labels ); - i = i + 1 - } - } - - def collectOffsets( nfa:Array[NondetWordAutom] ): Unit = { - this.offset = new Array[int]( nfa.length + 1 ); - offset( 0 ) = 1; // we have a new initial state - var i = 0; - while(i < nfa.length ) { - offset( i + 1 ) = nfa( i ).nstates + offset( i ); - i = i + 1 - } - } - - /** collapses several normalized NondetWordAutom objects into one. - */ - - def this( nfa: Array[NondetWordAutom] ) = { - this(); - //Console.println("NWA::this(.)"); - - //this.m - val m = nfa.length; - //System.out.println("enter NondetWordSwitch, " - // +"combining " + m + " automata"); - - collectLabels( nfa ); - collectOffsets( nfa ); - - //Console.println(" X 1"); - - - this.nstates = offset( nfa.length ); //m - 1 ] + nfa[ m - 1 ].nstates; - - - this.finals = new TreeMap(); - - this.qbinders = new Array[Vector]( nstates ); - - // new initial state gets all transitions from all initial states - - this._deltaq = new Array[HashMap]( nstates ); - this._defaultq = new Array[Vector]( nstates ); - //Console.println(" X 2"); - - //TreeSet defaultqSet = new TreeSet(); - _deltaq( 0 ) = new HashMap(); // 0 = our new initial state - - val initials = new TreeSet(); - - var i = 0; - while(i < m) { - //System.out.println("i (current NFA):"+i); - - val n = nfa( i ); - - val offs = offset( i ); - - initials.add( new Integer( offs )); - - n.relocate( offs, - this.finals, - this._deltaq, - this._defaultq, - this.qbinders ); - i = i + 1; - } - - normalize( initials, false ); - //Console.println("Leave-NWA::this(.)"); - } - - - - - def print(): Unit = { - - Console.print("NFA on labels "+ this.labels); - - if( offset != null ) { - Console.print("offset"); - var k = 0; - while(k < offset.length) { - if( k > 0) - Console.print(", "); - Console.print(offset(k)); - k = k + 1; - } - } - Console.println; - - Console.print("max state number :" + (nstates - 1) ); - - Console.println("initials" + initials); - - Console.println("finals" + finals); - - var i = 0; - while(i < nstates) { - Console.print("state: " + i); - if( finals.containsKey( new Integer( i )) ){ - Console.print("*"); //final - } - Console.print(" transitions: {"); - var arrows:HashMap = deltaq( i ); - - var it = arrows.keySet().iterator(); - while(it.hasNext()) { - val label = it.next(); - val targets = arrows.get( label ).asInstanceOf[Vector]; - val jt = targets.iterator(); - while(jt.hasNext()) { - val p = jt.next().asInstanceOf[Integer]; - Console.print("("+label+","+p+")"); - } - } - - Console.print("} "); - Console.print(" default transitions: "+_defaultq( i )); - if( null != qbinders ) - Console.println(" binders "+qbinders( i )); - Console.println; - i = i + 1; - } - } - - -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/Npair.scala b/sources/scala/tools/scalac/transformer/matching/Npair.scala deleted file mode 100644 index a33bd7d77f..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/Npair.scala +++ /dev/null @@ -1,67 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scala.tools.scalac.transformer.matching ; - -import java.util.{ HashMap, TreeSet }; -/** cartesian - */ - -/** Int x TreeSet[ Int ] - */ -case class Npair(nstate: Integer, nset: TreeSet) { - - override def equals(that: Any): Boolean = { - this match { - case Npair(nstate, nset) => - that match { - case Npair(_nstate, _nset) => - return ((nstate == _nstate) - && (nset == _nset)); - case _ => return false - } - case _ => return false - } - } - - override def toString(): String = this match { - case Npair(nstate, nset) => - //Integer dstate = (Integer) indexMap.get(nset); - "<n" + nstate.toString() + " in " + nset /*+" = d"+dstate*/ + ">"; - case _ => null - } - - def toString(indexMap: HashMap): String = { - //assert indexMap != null; - this match { - case Npair(nstate, nset) => - //assert nstate != null; - val dstate = indexMap.get( nset ).asInstanceOf[Integer]; - return "<n" + nstate.toString() + " in " + nset + " = d" + dstate + ">"; - case _ => - return null; - } - } - - -} - -class NpairComparator extends StateSetComparator { - override def compare(o1: Any, o2: Any): Int = { - o1 match { - case Npair(nstate, nset) => o2 match { - case Npair(_nstate, _nset) => - val res = nstate.compareTo(_nstate); - if (res != 0) - return res; - else - return super.compare(nset, _nset); - } - } - } -} diff --git a/sources/scala/tools/scalac/transformer/matching/PartialMatcher.scala b/sources/scala/tools/scalac/transformer/matching/PartialMatcher.scala deleted file mode 100644 index f841427049..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/PartialMatcher.scala +++ /dev/null @@ -1,46 +0,0 @@ -import scalac.ast.Tree; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import java.util.HashMap ; - -package scala.tools.scalac.transformer.matching { - -/** container. classes AlgebraicMatcher and SequenceMatcher get input and store their results in here. - * resembles the 'Memento' design pattern, could also be named 'Liaison' - */ -class PartialMatcher(owner1: Symbol, root1: Tree, resultType1: Type) { - - /** owner of the code we create (input) - */ - var owner: Symbol = owner1; - - /** the selector value (input) - */ - var selector:Tree = root1; - - /** type of the result of the whole match (input) - */ - var resultType:Type = resultType1 ; - - /** tree representing the matcher (output) - */ - var tree: Tree = _ ; - - var pos: int = root1.pos; - - //assert( owner != null ) : "owner is null"; - //assert owner != Symbol.NONE ; - //this.owner = owner; - - //assert root != null; - //assert root.type != null; - //this.selector = root; - - //assert this.resultType != Type.NoType; - //this.resultType = resultType; - - //this.pos = root.pos; // for convenience only - - } - -} diff --git a/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala b/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala deleted file mode 100644 index 836c46f9f5..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala +++ /dev/null @@ -1,940 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - - -import scala.tools.util.Position; -import scalac._; -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.util._; -import scalac.symtab._; -//import scalac.transformer.matching.CodeFactory; -//import scalac.transformer.matching.PatternNodeCreator; -//import scalac.transformer.matching.PatternNode; -//import scalac.transformer.matching.CaseEnv; -//import scalac.transformer.matching.PatternTool; -//import PatternNode._; -import Tree._; - -package scala.tools.scalac.transformer.matching { - -class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { - - protected var optimize = true; - protected var delegateSequenceMatching = false; - protected var doBinding = true; - - /** the owner of the pattern matching expression - */ - protected var owner:Symbol = _ ; - - /** the selector expression - */ - protected var selector: Tree = _; - - /** the root of the pattern node structure - */ - protected var root: PatternNode = _; - - /** the symbol of the result variable - */ - protected var resultVar: Symbol = _; - - /** methods to generate scala code - */ - protected var cf: CodeFactory = _; - - /** methods to create pattern nodes - */ - protected var mk: PatternNodeCreator = _; - - /** init method, also needed in subclass AlgebraicMatcher - */ - def initialize(selector: Tree, owner: Symbol, - resultType: Type, doBinding: Boolean): Unit = { - this.mk = new PatternNodeCreator(unit, owner); - this.cf = new CodeFactory(unit, selector.pos); - this.root = mk.ConstrPat(selector.pos, selector.getType().widen()); - this.root.and = mk.Header(selector.pos, - selector.getType().widen(), - gen.Ident(selector.pos, root.symbol())); - this.resultVar = owner.newVariable(selector.pos, - Modifiers.MUTABLE, - Names.result); - this.resultVar.setType(resultType); - this.owner = owner; - this.selector = selector; - this.optimize = this.optimize & (unit.global.target == Global.TARGET_JVM); - this.doBinding = doBinding; - } - - /** pretty printer - */ - def print(): Unit = { - new PatternNodeDebugPrinter().print(root.and, ""); - } - - /** enters a sequence of cases into the pattern matcher - */ - def construct(cases: Array[Tree]): Unit = { - //Console.println("pattern matcher.construct "+cases); - var i = 0; while(i < cases.length) { - enter(cases(i)); - i = i + 1 - } - } - - /** enter a single case into the pattern matcher - */ - protected def enter(caseDef: Tree): Unit = { - caseDef match { - case CaseDef(pat, guard, body) => - val env = new CaseEnv(owner, unit); - // PatternNode matched = match(pat, root); - val target = enter1(pat, -1, root, root.symbol(), env); - // if (target.and != null) - // unit.error(pat.pos, "duplicate case"); - if (null == target.and) - target.and = mk.Body(caseDef.pos, env.getBoundVars(), guard, body); - else if (target.and.isInstanceOf[Body]) - updateBody(target.and.asInstanceOf[Body], env.getBoundVars(), guard, body); - else { - //Console.println("target is "+target.getClass()); - //Console.println("target.and is "+target.and.getClass()); - //Console.println("target.or is "+target.or.getClass()); - - unit.error(pat.pos, "duplicate case"); - } - } - } - - /** this method is only called if 2 patterns are redundant. In such - * a case, the right body has to be chosen by means of the guards! - * case 3 if false => "x"; - * case 3 if true => "y"; - */ - protected def updateBody(tree: Body, bound: Array[ValDef], guard: Tree , body: Tree): Unit = { - if (tree.guard(tree.guard.length - 1) == Tree.Empty) { - //unit.error(body.pos, "unreachable code"); - } else { - val bd = new Array[Array[ValDef]](tree.bound.length + 1); - val ng = new Array[Tree](tree.guard.length + 1); - val nb = new Array[Tree](tree.body.length + 1); - System.arraycopy(tree.bound, 0, bd, 0, tree.bound.length); - System.arraycopy(tree.guard, 0, ng, 0, tree.guard.length); - System.arraycopy(tree.body, 0, nb, 0, tree.body.length); - bd(bd.length - 1) = bound; - ng(ng.length - 1) = guard; - nb(nb.length - 1) = body; - tree.bound = bd ; - tree.guard = ng ; - tree.body = nb ; - } - } - - protected def patternArgs(tree: Tree):Array[Tree] = { - tree match { - case Bind(_, pat) => patternArgs(pat); - case Apply(_, args) => if ( isSeqApply(tree.asInstanceOf[Apply]) - && !delegateSequenceMatching) - args(0) match { - case Sequence(ts) => ts; - case _ => args; - } - else - args - - case Sequence(ts) => if (!delegateSequenceMatching) - ts; - else - Tree.EMPTY_ARRAY; - - case _ => Tree.EMPTY_ARRAY; - } - } - - /** returns true if apply is a "sequence apply". analyzer inserts Sequence nodes if something is a - * - * - last update: discussion with Martin 2005-02-18 - * - * - if true, tree.fn must be ignored. The analyzer ensures that the selector will be a subtype - * of fn; it thus assigns the expected type from the context (which is surely a subtype, - * but may have different flags etc. - * - * - so should be - * (( tree.args.length == 1 ) && tree.args(0).isInstanceOf[Sequence]) - * but fails - */ - protected def isSeqApply( tree: Tree.Apply ): Boolean = - (( tree.args.length == 1 ) && tree.args(0).isInstanceOf[Sequence]) - && (tree.getType().symbol().flags & Modifiers.CASE) == 0; - - protected def patternNode(tree:Tree , header:Header , env: CaseEnv ): PatternNode = { - //Console.println("patternNode("+tree+","+header+")"); - //Console.println("tree.getType()"+tree.getType()); - tree match { - case Bind(name, Typed(Ident(Names.PATTERN_WILDCARD), tpe)) => // x@_:Type - if (header.getTpe().isSubType(tpe.getType())) { - val node = mk.DefaultPat(tree.pos, tpe.getType()); - env.newBoundVar( tree.symbol(), tree.getType(), header.selector ); - node; - } - else { - val node = mk.ConstrPat(tree.pos, tpe.getType()); - env.newBoundVar( tree.symbol(), tree.getType(), gen.Ident(tree.pos, node.casted)); - node; - } - case Bind(name, Ident(Names.PATTERN_WILDCARD)) => // x @ _ - val node = mk.DefaultPat(tree.pos, header.getTpe()); - if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) - env.newBoundVar( tree.symbol(), tree.getType(), header.selector); - node; - case Bind(name, pat) => - //if ( tree.getType() == null ) throw new ApplicationError("Bind tpe is null"); // DEBUG - val node = patternNode(pat, header, env); - if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) { - val casted = node.symbol(); - val theValue = if (casted == Symbol.NONE) header.selector else gen.Ident(tree.pos, casted); - env.newBoundVar(tree.symbol(), tree.getType(), theValue); - } - node; - case t @ Apply(fn, args) => // pattern with args - if (isSeqApply(t)) { - if (!delegateSequenceMatching) { - args(0) match { - case Sequence(ts)=> - mk.SequencePat(tree.pos, tree.getType(), ts.length); - } - } else { - val res = mk.ConstrPat(tree.pos, tree.getType()); - res.and = mk.Header(tree.pos, header.getTpe(), header.selector); - res.and.and = mk.SeqContainerPat(tree.pos, tree.getType(), args(0)); - res; - } - } else if ((fn.symbol() != null) && - fn.symbol().isStable() && - !(fn.symbol().isModule() && - ((fn.symbol().flags & Modifiers.CASE) != 0))) { - mk.VariablePat(tree.pos, tree); - } - else { - /* - Console.println("apply but not seqApply"); - Console.println("tree.getType()="+tree.getType()); - Console.println("tree.symbol()="+tree.symbol()); - */ - mk.ConstrPat(tree.pos, tree.getType()); - } - case t @ Typed(ident, tpe) => // variable pattern - //Console.println("typed! header:" + header.getTpe() +" "+tpe.getType()); - val doTest = header.getTpe().isSubType(tpe.getType()); - val node = { - if(doTest) - mk.DefaultPat(tree.pos, tpe.getType()) - else - mk.ConstrPat(tree.pos, tpe.getType()); - } - if ((null != env) && (ident.symbol() != defs.PATTERN_WILDCARD)) - node match { - case ConstrPat(casted) => - env.newBoundVar(t.expr.symbol(), - tpe.getType(), - gen.Ident(tree.pos, casted)); - case _ => - env.newBoundVar(t.expr.symbol(), - tpe.getType(), - {if(doTest) header.selector else gen.Ident(tree.pos, node.asInstanceOf[ConstrPat].casted)}); - } - node; - - case Ident(name) => // pattern without args or variable - if (tree.symbol() == defs.PATTERN_WILDCARD) - mk.DefaultPat(tree.pos, header.getTpe()); - else if (tree.symbol().isPrimaryConstructor()) { - throw new ApplicationError("this may not happen"); // Burak - } else if (name.isVariable()) {// Burak - throw new ApplicationError("this may not happen"); // Burak - } else - mk.VariablePat(tree.pos, tree); - - case Select(_, name) => // variable - if (tree.symbol().isPrimaryConstructor()) - mk.ConstrPat(tree.pos, tree.getType()); - else - mk.VariablePat(tree.pos, tree); - - case Literal(value) => - mk.ConstantPat(tree.pos, tree.getType(), value); - - case Sequence(ts) => - if ( !delegateSequenceMatching ) { - //throw new ApplicationError("cannot happen:"+tree); - //Console.println("PatternMatcher:patternNode:Sequence "+tree.getType()); - mk.SequencePat(tree.pos, tree.getType(), ts.length); - } else { - mk.SeqContainerPat(tree.pos, tree.getType(), tree); - } - case Alternative(branches) => - throw new ApplicationError("kicked out Alternatives"); - /* - if(branches.length < 2) - throw new ApplicationError("ill-formed Alternative"); - val subroot = mk.ConstrPat(header.pos, header.getTpe()); - subroot.and = mk.Header(header.pos, header.getTpe(), header.selector.duplicate()); - val subenv = new CaseEnv(owner, unit); - var i = 0; while(i < branches.length) { - val target = enter1(branches(i), -1, subroot, subroot.symbol(), subenv); - target.and = mk.Body(tree.pos); - i = i + 1 - } - mk.AltPat(tree.pos, subroot.and.asInstanceOf[Header]); - */ - case _ => - throw new ApplicationError("unit = " + unit + "; tree = "+tree); - } - } - - protected def enter(pat: Tree, index: Int, target: PatternNode, casted: Symbol, env: CaseEnv ): PatternNode = { - target match { - case ConstrPat(newCasted) => - enter1(pat, index, target, newCasted, env); - case SequencePat(newCasted, len) => - enter1(pat, index, target, newCasted, env); - case _ => - enter1(pat, index, target, casted, env); - } - } - - private def newHeader(pos: Int, casted: Symbol, index: Int): Header = { - //Console.println("newHeader(pos,"+casted+","+index+")"); - //Console.println(" casted.getType()"+casted.getType()); - val ident = gen.Ident(pos, casted); - if (casted.pos == Position.FIRSTPOS) { - //Console.println("FIRSTPOS"); - val t = gen.mkApply_V( - gen.Select( ident, defs.FUNCTION_APPLY( 1 )), - Predef.Array[Tree]( gen.mkIntLit( pos, index ) )); - val seqType = t.getType(); - mk.Header( pos, seqType, t ); - } else { - //Console.println("NOT FIRSTPOS"); - val ts = casted.getType().symbol().asInstanceOf[ClassSymbol] - .caseFieldAccessor(index); - //Console.println("ts="+ts); - val accType = casted.getType().memberType(ts); - val accTree = gen.Select( ident, ts); - accType match { - // scala case accessor - case Type.MethodType(_, _) => - mk.Header(pos, accType.resultType(), gen.mkApply__(accTree)); - // jaco case accessor - case _ => - mk.Header(pos, accType, accTree); - } - } - } - - /** main enter function - * - * invariant: ( curHeader == (Header)target.and ) holds - */ - protected def enter1(pat: Tree, index: Int, target: PatternNode, casted: Symbol, env: CaseEnv): PatternNode = { - //System.err.println("enter(" + pat + ", " + index + ", " + target + ", " + casted + ")"); - val patArgs = patternArgs(pat); // get pattern arguments - var curHeader = target.and.asInstanceOf[Header]; // advance one step in IR - if (curHeader == null) { // check if we must add new header - //assert index >= 0 : casted; - if (index < 0) throw new ApplicationError("error entering:" + casted); - target.and = {curHeader = newHeader(pat.pos, casted, index); curHeader}; - curHeader.or = patternNode(pat, curHeader, env); - enter(patArgs, curHeader.or, casted, env); - - } else { - // find most recent header - while (curHeader.next != null) - curHeader = curHeader.next; - // create node - var patNode = patternNode(pat, curHeader, env); - var next: PatternNode = curHeader; - // add branch to curHeader, but reuse tests if possible - while (true) { - if (next.isSameAs(patNode)) { // patNode already present ?--> reuse - // substitute... !!! - patNode match { - case ConstrPat(ocasted) => - env.substitute(ocasted, gen.Ident(patNode.pos, - next.asInstanceOf[ConstrPat].casted)); - case _ => - } - return enter(patArgs, next, casted, env); - } else if (next.isDefaultPat() || // default case reached, or - ((next.or == null) && // no more alternatives and - (patNode.isDefaultPat() || next.subsumes(patNode)))) { - // new node is default or subsumed - var header = mk.Header(patNode.pos, - curHeader.getTpe(), - curHeader.selector); - {curHeader.next = header; header}; - header.or = patNode; - return enter(patArgs, - patNode, - casted, - env); - } - else if (next.or == null) { - return enter(patArgs, {next.or = patNode; patNode}, casted, env); // add new branch - } else - next = next.or; - } - throw new ApplicationError("must not happen"); - null // never reached - } - } - - /** calls enter for an array of patterns, see enter - */ - protected def enter(pats:Array[Tree], target1: PatternNode , casted1: Symbol , env: CaseEnv): PatternNode = { - var target = target1; - var casted = casted1; - target match { - case ConstrPat(newCasted) => - casted = newCasted; - case SequencePat(newCasted, len) => - casted = newCasted; - case _ => - } - var i = 0; while(i < pats.length) { - target = enter1(pats(i), i, target, casted, env); - i = i + 1 - } - target; - } - - protected def nCaseComponents(tree: Tree): int = { - tree match { - case Apply(fn, _) => - val tpe = tree.getType().symbol().primaryConstructor().getType(); - //Console.println("~~~ " + tree.type() + ", " + tree.type().symbol().primaryConstructor()); - tpe match { - // I'm not sure if this is a good idea, but obviously, currently all case classes - // without constructor arguments have type NoType - case Type.NoType => - throw new ApplicationError("this cannot happen"); - 0 - case Type.MethodType(args, _) => - args.length; - case Type.PolyType(tvars, Type.MethodType(args, _)) => - args.length; - case Type.PolyType(tvars, _) => - 0; - case _ => - throw new ApplicationError("not yet implemented;" + - "pattern matching for " + tree + ": " + tpe); - } - } - return 0; - } - - - //////////// generator methods - - def toTree(): Tree = { - if (optimize && isSimpleIntSwitch()) - intSwitchToTree(); - else if (false /* optimize && isSimpleSwitch() */) // disabled - switchToTree(); - else { - //print(); - generalSwitchToTree(); - } - } - - - protected def isSimpleIntSwitch(): Boolean = { - if (selector.getType().widen().isSameAs(defs.int_TYPE())) { - var patNode = root.and; - while (patNode != null) { - var node = patNode; - while (({node = node.or; node}) != null) { - node match { - case ConstantPat(_) => ; - case _ => - return false; - } - node.and match { - case _b:Body => - if ((_b.guard.length > 1) || - (_b.guard(0) != Tree.Empty) || - (_b.bound(0).length > 0)) - return false; - case _ => - return false; - } - } - patNode = patNode.nextH(); - } - return true; - } else - return false; - } - - - protected def numCases(patNode1: PatternNode): Int = { - var patNode = patNode1; - var n = 0; - while (({patNode = patNode.or; patNode}) != null) - patNode match { - case DefaultPat() => ; - case _ => - n = n + 1; - } - n; - } - - protected def _defaultBody(patNode1: PatternNode, otherwise: Tree ): Tree = { - var patNode = patNode1; - while (patNode != null) { - var node = patNode; - while (({node = node.or; node}) != null) - node match { - case DefaultPat() => - return node.and.bodyToTree(); - case _ => - } - patNode = patNode.nextH(); - } - otherwise; - } - - /** This method translates pattern matching expressions that match - * on integers on the top level. - */ - def intSwitchToTree(): Tree = { - - case class TagBodyPair(tag: Int, body: Tree, next: TagBodyPair) { - def length(): Int = { - if (null == next) 1 else (next.length() + 1); - } - } - def insert(tag: Int, body: Tree, current: TagBodyPair): TagBodyPair = { - if (current == null) - return new TagBodyPair(tag, body, null); - else if (tag > current.tag) - return new TagBodyPair(current.tag, current.body, insert(tag, body, current.next)); - else - return new TagBodyPair(tag, body, current); - } - //print(); - val ncases = numCases(root.and); - val matchError = cf.ThrowMatchError(selector.pos, resultVar.getType()); - // without a case, we return a match error if there is no default case - if (ncases == 0) - return _defaultBody(root.and, matchError); - // for one case we use a normal if-then-else instruction - else if (ncases == 1) { - root.and.or match { - case ConstantPat(value) => - return gen.If(cf.Equals(selector, - gen.Literal(root.and.or.pos, value)), - (root.and.or.and).bodyToTree(), - _defaultBody(root.and, matchError)); - case _ => - return generalSwitchToTree(); - } - } - // - // if we have more than 2 cases than use a switch statement - - val _h:Header = root.and.asInstanceOf[Header]; - val next = _h.next; - var mappings: TagBodyPair = null; - var defaultBody = matchError; - var patNode = root.and; - - // convert or-branches to sorted list of tag-body pairs - - while (patNode != null) { - var node = patNode.or; - while (node != null) { - node match { - case DefaultPat() => - if (defaultBody != null) - throw new ApplicationError(); // shouldn't happen - defaultBody = node.and.bodyToTree(); - node = node.or; - - case ConstantPat(AConstant.INT(value))=> - mappings = insert(value, node.and.bodyToTree(), mappings); - node = node.or; - - case _ => - throw new ApplicationError(node.toString()); - } - } - patNode = patNode.nextH(); - } - /* mappings != null because numCases(...) > 2 - * so there were at least 2 or-branches - */ - var n = mappings.length(); - val tags = new Array[Int](n); - val bodies = new Array[Tree](n); - n = 0; - while (mappings != null) { - tags(n) = mappings.tag; - bodies(n) = mappings.body; - n = n + 1; - mappings = mappings.next; - } - return gen.Switch(selector,tags, bodies, defaultBody, resultVar.getType()); - } - - def generalSwitchToTree(): Tree = { - val ts = Predef.Array[Tree] ( - gen.ValDef(root.symbol(), selector), - gen.ValDef(resultVar, gen.mkDefaultValue(selector.pos, resultVar.getType()))); - val res = gen.If( - selector.pos, - toTree(root.and), - gen.Ident(selector.pos, resultVar), - cf.ThrowMatchError(selector.pos, resultVar.getType(), gen.Ident(selector.pos, root.symbol()))); - return gen.mkBlock(selector.pos, ts, res); - } - - def toTree(node1: PatternNode): Tree = { - def optimize1(selType:Type, alternatives1: PatternNode ): boolean = { - var alts = alternatives1; - if (!optimize || !selType.isSubType(defs.SCALAOBJECT_TYPE())) - return false; - var cases = 0; - while (alts != null) { - alts match { - case ConstrPat(_) => - if (alts.getTpe().symbol().isCaseClass()) - cases = cases +1; - else - return false; - - case DefaultPat() => - ; - case _ => - return false; - } - alts = alts.or; - } - return cases > 2; - } - - var node = node1; - var res = gen.mkBooleanLit(node.pos, false); - - while (node != null) - node match { - case _h:Header => - val selector = _h.selector; - val next = _h.next; - //res = cf.And(mkNegate(res), toTree(node.or, selector)); - //Console.println("HEADER TYPE = " + selector.type); - - /* TEST - next match { - case _b:Body if ((_b.guard.length > 1) || - (_b.guard(0) != Tree.Empty)) => - Console.println("guard! = "+_b.guard(0)); - case _ => - } - */ - - if (optimize1(node.getTpe(), node.or)) - res = cf.Or(res, toOptTree(node.or, selector)); - else - res = cf.Or(res, toTree(node.or, selector)); - node = next; - - case _b:Body => - var bound = _b.bound; - val guard = _b.guard; - val body = _b.body; - if ((bound.length == 0) && - (guard.length == 0) && - (body.length == 0)) { - return gen.mkBooleanLit(node.pos, true); // cf.Or(res, gen.mkBooleanLit(node.pos, true)); - } else if (!doBinding) - bound = Predef.Array[Array[ValDef]]( Predef.Array[ValDef]() ); - var i = guard.length - 1; while(i >= 0) { - val ts = bound(i).asInstanceOf[Array[Tree]]; - var res0 = gen.mkBlock(gen.Assign(gen.Ident(body(i).pos, resultVar), - body(i)), - gen.mkBooleanLit(body(i).pos, true)); - if (guard(i) != Tree.Empty) - res0 = cf.And(guard(i), res0); - res = cf.Or(gen.mkBlock(body(i).pos, ts, res0), res); - i = i - 1 - } - return res; - } - return res; - } - - protected def toOptTree(node1: PatternNode, selector: Tree): Tree = { - - class TagNodePair(tag1: int, node1: PatternNode, next1: TagNodePair) { - var tag: int = tag1; - var node: PatternNode = node1; - var next: TagNodePair = next1; - - def length(): Int = { - return if (null == next) 1 else (next.length() + 1); - } - } - def insertNode(tag:int , node:PatternNode , current:TagNodePair ): TagNodePair = { - def insert(tag: Int, node: PatternNode, current: TagNodePair): TagNodePair = { - if (current == null) - return new TagNodePair(tag, node, null); - else if (tag > current.tag) - return new TagNodePair(current.tag, current.node, insert(tag, node, current.next)); - else if (tag == current.tag) { - val old = current.node; - current.node = node; - node.or = old; - return current; - } else - return new TagNodePair(tag, node, current); - } // def insert - val newnode = node.dup(); - newnode.or = null; - return insert(tag, newnode, current); - } // def insertNode - - var node = node1; - //System.err.println("pm.toOptTree called"+node); - var cases: TagNodePair = null; - var defaultCase: PatternNode = null; - while (node != null) - node match { - case ConstrPat(casted) => - cases = insertNode(node.getTpe().symbol().tag(), node, cases); - node = node.or; - - case DefaultPat() => - defaultCase = node; - node = node.or; - } - var n = cases.length(); - val tags = new Array[int](n); - val bodies = new Array[Tree](n); - n = 0; - while (null != cases) { - tags(n) = cases.tag; - bodies(n) = toTree(cases.node, selector); - n = n + 1; - cases = cases.next; - } - return gen.Switch(gen.mkApply__(gen.Select(selector.duplicate(), defs.SCALAOBJECT_TAG())), - tags, - bodies, - { if (defaultCase == null) gen.mkBooleanLit(selector.pos, false) else toTree(defaultCase.and) }, - defs.boolean_TYPE()); - } - - protected def toTree(node:PatternNode , selector:Tree ): Tree = { - //System.err.println("pm.toTree("+node+","+selector+")"); - if (node == null) - return gen.mkBooleanLit(selector.pos, false); - else - node match { - case DefaultPat() => - return toTree(node.and); - - case ConstrPat(casted) => - return gen.If(gen.mkIsInstanceOf(selector.duplicate(), node.getTpe()), - gen.mkBlock(gen.ValDef(casted, - gen.mkAsInstanceOf(selector.pos, selector.duplicate(), node.getTpe(), true)), - toTree(node.and)), - toTree(node.or, selector.duplicate())); - case SequencePat(casted, len) => - return - cf.Or( - cf.And( - cf.And(gen.mkIsInstanceOf(selector.duplicate(), node.getTpe()), - cf.Equals(gen.mkApply__(gen.Select(gen.mkAsInstanceOf(selector.pos, selector.duplicate(), node.getTpe(), true), - defs.SEQ_LENGTH())), - gen.mkIntLit(selector.pos, len))), - gen.mkBlock(gen.ValDef(casted, - gen.mkAsInstanceOf(selector.pos, selector.duplicate(), node.getTpe(), true)), - toTree(node.and))), - toTree(node.or, selector.duplicate())); - case ConstantPat(value) => - return gen.If(cf.Equals(selector.duplicate(), - gen.Literal(selector.pos, value)), - toTree(node.and), - toTree(node.or, selector.duplicate())); - case VariablePat(tree) => - return gen.If(cf.Equals(selector.duplicate(), tree), - toTree(node.and), - toTree(node.or, selector.duplicate())); - /* - case AltPat(header) => - return gen.If(toTree(header), - toTree(node.and), - toTree(node.or, selector.duplicate())); - */ - } - } - - - protected def isSimpleSwitch(): Boolean = { - /* - - case class Break(res:Boolean) extends java.lang.Throwable; - case class Break2() extends java.lang.Throwable; - - - print(); - var patNode = root.and; - while (patNode != null) { - var node = patNode; - while (({node = node.or; node}) != null) { - node match { - case VariablePat(tree) => - Console.println(((tree.symbol().flags & Modifiers.CASE) != 0)); - case ConstrPat(_) => - Console.println(node.getTpe().toString() + " / " + ((node.getTpe().symbol().flags & Modifiers.CASE) != 0)); - var inner = node.and; - def funct(inner: PatternNode): Boolean = { - //outer: while (true) { - inner match { - case _h:Header => - if (_h.next != null) - throw Break(false); - funct(inner.or) - - case DefaultPat() => - funct(inner.and); - - case b:Body => - if ((b.guard.length > 1) || - (b.guard(0) != Tree.Empty)) - throw Break(false); - - throw Break2() // break outer - case _ => - Console.println(inner); - throw Break(false); - } - } - var res = false; - var set = false; - try { - funct(inner) - } catch { - case Break(res1) => - res = res1; - set = true; - case Break2() => - } - if(set) return res; - case _ => - return false; - } - } - patNode = patNode.nextH(); - } - return true; - */ - return false; - } - - def switchToTree(): Tree = { - throw new Error(); - } - -} -} - -/* idea:: - - case class BooleanTree(x:Tree) { - def &&&(z:BooleanTree) = new BooleanTree(cf.And(x,z.x)); - def |||(z:BooleanTree) = new BooleanTree(cf.Or(x,z.x)); - } - def view(x:Tree): BooleanTree = new BooleanTree(x); - def view(x:BooleanTree): Tree = x.x; - - def view(x:Symbol): AssignableTree = new AssignableTree(x); - case class AssignableTree(x:Symbol) { - def := (z:Tree) = gen.Assign(gen.Ident(z.pos, x), z); - } - - def view(x:Tree): TestableTree = new TestableTree(x); - case class TestableTree(x:Tree) { - def __isOf__ (z:Type) = gen.mkIsInstanceOf(x, z) - } - - def view(x:Tree): CastableTree = new CastableTree(x); - case class CastableTree(x:Tree) { - def __castTo__ (z:Type) = gen.mkAsInstanceOf(x, z) - } - - def view(x:Tree): EquatableTree = new EquatableTree(x); - case class EquatableTree(x:Tree) { - def === (z:Tree) = cf.Equals(x,z) - } - - def view(x:Tree): SelectableTree = new SelectableTree(x); - case class SelectableTree(x:Tree) { - def __dot__ (z:Symbol) = gen.Select(x, z) - } - - def view(x:Symbol): ValDefableTree = new ValDefableTree(x); - case class ValDefableTree(x:Symbol) { - def __valdef__ (z:Tree) = gen.ValDef(x,z); - } - - protected def toTree(node:PatternNode , _selector:Tree ): Tree = { - - def selector() = _selector.duplicate(); - def pos() = _selector.pos; - - //System.err.println("pm.toTree("+node+","+selector+")"); - if (node == null) - return gen.mkBooleanLit(pos(), false); - else - node match { - case DefaultPat() => - return toTree(node.and); - - case ConstrPat(casted) => - return gen.If(selector() __isOf__ node.getTpe(), - gen.mkBlock(casted __valdef__ (selector() __castTo__ node.getTpe()), - toTree(node.and)), - toTree(node.or, selector())); - - case SequencePat(casted, len) => - return gen.If((selector() __isOf__ node.getTpe()) &&& - (gen.mkApply__(selector() __castTo__ node.getTpe() __dot__ (defs.SEQ_LENGTH())) === gen.mkIntLit(pos(), len)), - gen.mkBlock(casted __valdef__ (selector() __castTo__ node.getTpe()), - toTree(node.and)), - toTree(node.or, selector())); - case ConstantPat(value) => - return gen.If(selector() === gen.Literal(pos(), value), - toTree(node.and), - toTree(node.or, selector())); - case VariablePat(tree) => - return gen.If(selector() === tree, - toTree(node.and), - toTree(node.or, selector())); - case AltPat(header) => - return gen.If(toTree(header), - toTree(node.and), - toTree(node.or, selector())); - case _ => - throw new ApplicationError(); - } - } -*/ diff --git a/sources/scala/tools/scalac/transformer/matching/PatternNode.scala b/sources/scala/tools/scalac/transformer/matching/PatternNode.scala deleted file mode 100644 index f6a80be95c..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/PatternNode.scala +++ /dev/null @@ -1,249 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - - -import scala.tools.util.Position; -import scalac._; -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.symtab._; -import scalac.typechecker._; - -package scala.tools.scalac.transformer.matching { - -/** Intermediate data structure for algebraic + pattern matcher - */ - class PatternNode { - var pos = Position.FIRSTPOS; - var tpe: Type = _; - var or: PatternNode = _; - var and: PatternNode = _; - - def bodyToTree(): Tree = this match { - case _b:Body => - return _b.body(0); - } - - def getTpe(): Type = { - tpe; - } - def setType(tpe: Type): Unit = { - this.tpe = tpe; - } - - def dup(): PatternNode = { - var res: PatternNode = _; - this match { - case h:Header => - res = new Header(h.selector, h.next); - - case b:Body=> - res = new Body(b.bound, b.guard, b.body); - - case DefaultPat() => - res = DefaultPat(); - - case ConstrPat(casted) => - res = ConstrPat(casted); - - case SequencePat(casted, len) => - res = SequencePat(casted, len); - - case SeqContainerPat(casted, seqpat) => - res = SeqContainerPat(casted, seqpat); - - case ConstantPat(value) => - res = ConstantPat(value); - - case VariablePat(tree) => - res = VariablePat(tree); - - //case AltPat(subheader) => - // res = AltPat(subheader); - - case _ => - throw new ApplicationError(); - } - res.pos = pos; - res.tpe = tpe; - res.or = or; - res.and = and; - return res; - } - - def symbol(): Symbol = { - this match { - case ConstrPat(casted) => - return casted; - case SequencePat(casted, _) => - return casted; - case SeqContainerPat(casted, _) => - return casted; - case _ => - return Symbol.NONE; - } - } - - def nextH(): PatternNode = { - this match { - case _h:Header => - return _h.next; - case _ => - return null; - } - } - - def isDefaultPat(): boolean = { - this match { - case DefaultPat() => - return true; - case _ => - return false; - } - } - - /** returns true if - * p and q are equal (constructor | sequence) type tests, or - * "q matches" => "p matches" - */ - def isSameAs(q: PatternNode): boolean = { - //Console.println("isSameAs("+this+","+q+")"); - this match { - case ConstrPat(_) => - q match { - case ConstrPat(_) => - q.getTpe().isSameAs(this.getTpe()); - case _ => - false - } - case SequencePat(_, plen) => - q match { - case SequencePat(_, qlen) => - return (plen == qlen) && q.getTpe().isSameAs(this.getTpe()); - case _ => - false - } - case _ => - subsumes(q); - } - } - - /** returns true if "q matches" => "p matches" - */ - def subsumes(q:PatternNode): Boolean = { - //Console.print("subsumes("+this+","+q+")"); - /* val res = */ - this match { - case DefaultPat() => - q match { - case DefaultPat() => - true; - case _ => - false; - } - case ConstrPat(_) => - q match { - case ConstrPat(_) => - q.getTpe().isSubType(this.getTpe()); - case _ => - false; - } - case SequencePat(_, plen) => - q match { - case SequencePat(_, qlen) => - (plen == qlen) && q.getTpe().isSubType(this.getTpe()); - case _ => - false; - } - case ConstantPat(pval) => - q match { - case ConstantPat(qval) => - pval == qval; - case _ => - false; - } - case VariablePat(tree) => - q match { - case VariablePat(other) => - val treesym = tree match { - case _: Tree.Apply => TreeInfo.methSymbol( tree ); - case _ => tree.symbol() - } - val othersym = tree match { - case _: Tree.Apply => TreeInfo.methSymbol( other ); - case _ => other.symbol() - } -/* - Console.println("VPat, getc = "+tree.getClass()); - Console.println("[tree.symbol() = "+tree.symbol()); - if (tree.symbol() != null) { - Console.println("[other.symbol() = "+other.symbol()); - Console.println("[ ==? "+(tree.symbol() == other.symbol())); - - Console.println("\n\n[treesym != null? "+ tree.symbol() != null); - Console.println("\n\n[!treesym.isNone? "+ !tree.symbol().isNone()); - Console.println("\n\n[!treesym.isError? "+ !tree.symbol().isError()); - } -*/ - (treesym != null) && - (!treesym.isNone()) && - (!treesym.isError()) && - (treesym == othersym); - case _ => - false; - } - case _ => - false; - } - /*Console.println("="+res); - return res;*/ - } - - override def toString(): String = { - this match { - case _h:Header => - return "Header(" + _h.selector + ")"; - case _b:Body => - return "Body"; - case DefaultPat() => - return "DefaultPat"; - case ConstrPat(casted) => - return "ConstrPat(" + casted + ")"; - case SequencePat(casted, len) => - return "SequencePat(" + casted + ", " + len + "...)"; - case SeqContainerPat(casted, seqpat) => - return "SeqContainerPat(" + casted + ", " + seqpat + ")"; - case ConstantPat(value) => - return "ConstantPat(" + value + ")"; - case VariablePat(tree) => - return "VariablePat"; - case _ => - return "<unknown pat>"; - } - } - } - - class Header(sel1: Tree, next1: Header ) extends PatternNode { - var selector: Tree = sel1; - var next: Header = next1; - } - - class Body(bound1: Array[Array[Tree.ValDef]] , guard1:Array[Tree] , body1:Array[Tree] ) extends PatternNode { - var bound = bound1; - var guard = guard1; - var body = body1; - } - - case class DefaultPat()extends PatternNode; - case class ConstrPat(casted:Symbol )extends PatternNode; - case class ConstantPat(value:AConstant )extends PatternNode; - case class VariablePat(tree:Tree )extends PatternNode; - //case class AltPat(subheader:Header )extends PatternNode; - case class SequencePat( casted:Symbol, len:int)extends PatternNode; // only used in PatternMatcher - case class SeqContainerPat(casted:Symbol , seqpat:Tree)extends PatternNode; // in AlgebraicMatcher - } diff --git a/sources/scala/tools/scalac/transformer/matching/PatternNodeCreator.scala b/sources/scala/tools/scalac/transformer/matching/PatternNodeCreator.scala deleted file mode 100644 index fdda3f01ab..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/PatternNodeCreator.scala +++ /dev/null @@ -1,109 +0,0 @@ -import scala.tools.util.Position; - -import scalac._; -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.util._; -import scalac.symtab._; -//import PatternNode._; -import Tree._; - -import java.util.Vector ; - -package scala.tools.scalac.transformer.matching { - - /** PatternNode factory. - * we inherit the globals from PatternTool. - */ - - class PatternNodeCreator(unit:CompilationUnit, val owner:Symbol) - extends PatternTool(unit) { - - /** the owner of the variable symbols that might be created */ - //Symbol owner; - - def SequencePat(pos: Int , tpe:Type , len:int) = { - val sym = newVar(Position.FIRSTPOS, tpe); - val node = new SequencePat(sym, len); - node.pos = pos; - node.setType(tpe); - node; - } - - def SeqContainerPat(pos: int, tpe: Type, seqpat:Tree ) = { - val sym = newVar(Position.NOPOS, tpe); - val node = new SeqContainerPat(sym, seqpat); - node.pos = pos; - node.setType(tpe); - node; - } - - def DefaultPat(pos: int, tpe: Type) = { - val node = new DefaultPat(); - node.pos = pos; - node.setType(tpe); - node; - } - - def ConstrPat(pos: int, tpe: Type) = { - val node = new ConstrPat(newVar(pos, tpe)); - node.pos = pos; - node.setType(tpe); - node; - } - - def ConstantPat(pos: int, tpe: Type, value:AConstant ) = { - val node = new ConstantPat( value ); - node.pos = pos; - node.setType(tpe); - node; - } - - def VariablePat(pos: int, tree:Tree) = { - val node = new VariablePat( tree ); - node.pos = pos; - node.setType(tree.getType()); - node; - } - /* - def AltPat(pos: int, header:Header ) = { - val node = new AltPat(header); - node.pos = pos; - node.setType(header.getTpe()); - node; - } - */ - // factories - - def Header(pos: int, tpe: Type, selector:Tree) = { - val node = new Header(selector, null); - node.pos = pos; - node.setType(tpe); - node; - } - - def Body(pos: int) = { - val node = new Body(new Array[Array[ValDef]](0), new Array[Tree](0), new Array[Tree](0)); - node.pos = pos; - node; - } - - def Body(pos: int, bound:Array[ValDef] , guard:Tree, body:Tree) = { - val node = new Body(Predef.Array[Array[ValDef]](bound), Predef.Array[Tree](guard), Predef.Array[Tree](body)); - node.pos = pos; - node; - } - - def newVar(pos: int, name: Name, tpe: Type): Symbol= { - val sym = owner.newVariable(pos, 0, name); - sym.setType(tpe); - //System.out.println("PatternNodeCreator::newVar creates symbol "+sym); - //System.out.println("owner: "+sym.owner()); - sym; - } - - def newVar(pos: int, tpe: Type): Symbol = { - newVar(pos, fresh.newName("temp"), tpe); - } - } -} diff --git a/sources/scala/tools/scalac/transformer/matching/PatternNodeDebugPrinter.scala b/sources/scala/tools/scalac/transformer/matching/PatternNodeDebugPrinter.scala deleted file mode 100644 index c2a4c459e8..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/PatternNodeDebugPrinter.scala +++ /dev/null @@ -1,118 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - - -import scala.tools.util.Position; -import scalac._; -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.util._; -import scalac.symtab._; -//import scalac.transformer.matching.CodeFactory; -//import scalac.transformer.matching.PatternNodeCreator; -//import scalac.transformer.matching.PatternNode; -//import scalac.transformer.matching.CaseEnv; -//import scalac.transformer.matching.PatternTool; -//import PatternNode._; -import Tree._; - -package scala.tools.scalac.transformer.matching { - - class PatternNodeDebugPrinter() { - - def print(patNode: PatternNode, indent: String): Unit = { - - def newIndent(s: String) = { - val removeBar: Boolean = (null == patNode.or); - val sb = new StringBuffer(); - sb.append(indent); - if (removeBar) - sb.setCharAt(indent.length() - 1, ' '); - var i = 0; while (i < s.length()) { - sb.append(' '); - i = i + 1 - } - sb.toString() - } - - if (patNode == null) - System.out.println(indent + "NULL"); - else - patNode match { - - case _h: Header => - val selector = _h.selector; - val next = _h.next; - Console.println(indent + "HEADER(" + patNode.getTpe() + - ", " + selector + ")"); - print(patNode.or, indent + "|"); - if (next != null) - print(next, indent); - - case ConstrPat(casted) => - val s = "-- " + patNode.getTpe().symbol().name + - "(" + patNode.getTpe() + ", " + casted + ") -> "; - val nindent = newIndent(s); - Console.println(nindent + s); - print(patNode.and, nindent); - if (patNode.or != null) - print(patNode.or, indent); - - case SequencePat( casted, plen ) => - val s = "-- " + patNode.getTpe().symbol().name + "(" + - patNode.getTpe() + - ", " + casted + ", " + plen + ") -> "; - val nindent = newIndent(s); - Console.println(indent + s); - print(patNode.and, nindent); - if (patNode.or != null) - print(patNode.or, indent); - - case DefaultPat() => - Console.println(indent + "-- _ -> "); - print(patNode.and, indent.substring(0, indent.length() - 1) + - " "); - if (patNode.or != null) - print(patNode.or, indent); - - case ConstantPat(value) => - val s = "-- CONST(" + value + ") -> "; - val nindent = newIndent(s); - Console.println(indent + s); - print(patNode.and, nindent); - if (patNode.or != null) - print(patNode.or, indent); - - case VariablePat(tree) => - val s = "-- STABLEID(" + tree + ": " + patNode.getTpe() + ") -> "; - val nindent = newIndent(s); - Console.println(indent + s); - print(patNode.and, nindent); - if (patNode.or != null) - print(patNode.or, indent); - - /* - case AltPat(header) => - Console.println(indent + "-- ALTERNATIVES:"); - print(header, indent + " * "); - print(patNode.and, indent + " * -> "); - if (patNode.or != null) - print(patNode.or, indent); -*/ - case _b:Body => - if ((_b.guard.length == 0) && (_b.body.length == 0)) - Console.println(indent + "true"); - else - Console.println(indent + "BODY(" + _b.body.length + ")"); - - } - } // print - - } // class PatternNodeDebugPrinter - -} diff --git a/sources/scala/tools/scalac/transformer/matching/PatternTool.scala b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala deleted file mode 100644 index d71a9e384a..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/PatternTool.scala +++ /dev/null @@ -1,88 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -import scalac.ApplicationError; -import scalac.CompilationUnit; -//import scalac.ast.TreeGen; -//import scalac.util.*; -//import scalac.symtab.*; -import scalac.ast.Tree; -import scalac.symtab.Symbol; -import scalac.util.Name; - -package scala.tools.scalac.transformer.matching { -/** this class takes care of tedious stuff which has nothing to do with - * matching - */ - abstract class PatternTool(unit: CompilationUnit) { - - def containsBinding(pat: Tree): Boolean = { - var generatedVars = false; - - def handleVariableSymbol(sym: Symbol): Unit = - if (sym.name.toString().indexOf("$") == -1) { - generatedVars = true; // .add(sym); - } - - def isVariableName(name: Name): Boolean = - ( name.isVariable() ) && ( name != Name.fromString("_") ) ; - - def isVariableSymbol(sym: Symbol): Boolean = - ( sym != null )&&( !sym.isPrimaryConstructor() ); - - def traverse1(trees: Array[Tree]): Unit = { - var i = 0; while(i < trees.length) { - traverse(trees(i)); - i = i + 1 - } - } - def traverse(tree: Tree): Unit = { - - import Tree._ ; - - tree match { - case x @ Ident(name) => - if(x.symbol() != unit.global.definitions.PATTERN_WILDCARD) - throw new ApplicationError("shouldn't happen?!"); - - case Bind(name, subtree) => - var sym: Symbol = _; - - if (isVariableName(name) - && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} )) - handleVariableSymbol(sym); - - traverse( subtree ); - - // congruence - case Apply(fun, args) => - traverse1(args); - case Sequence(trees) => - traverse1(trees); - case Typed(expr, tpe) => // needed?? - traverse(expr); - case _ : Alternative | _ : Select | _ : Literal => ; // no variables - - case _ => - throw new ApplicationError( - "unknown pattern node:" + tree + " = " + tree.getClass()); - } - } - traverse(pat); - generatedVars; - } - - final def fresh = unit.fresh; - - final def gen = unit.global.treeGen; - - final def defs = unit.global.definitions; - - } // class PatternTool -} diff --git a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala deleted file mode 100644 index 2958da8e03..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala +++ /dev/null @@ -1,551 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac._; -import scalac.ast._; -import scalac.symtab._; -import Tree._; - -import java.util._ ; -import Scope.SymbolIterator; - -import scalac.util.Name ; -import scalac.util.Names ; - -import scala.tools.util.Position; - -package scala.tools.scalac.transformer.matching { - - /** translate right tracer to code - * @param dfa determinized left tracer - * @param left nondeterm. left tracer (only needed for variables!) - * @param cf ... - * @param pat ? - * @param elementType ... - */ -class RightTracerInScala(dfa: DetWordAutom, seqVars: Set, owner: Symbol, cf: CodeFactory, pat:Tree, elementType: Type) -extends TracerInScala(dfa, elementType, owner, cf) { - - - final def collectVars(pat: Tree): HashSet = { - var vars = new HashSet(); - - def handleVariableSymbol(sym: Symbol): Unit = { - vars.add( sym ); - } - def isVariableName(name: Name): Boolean = { - ( name.isVariable() ) && ( name != Name.fromString("_") ) ; - } - def isVariableSymbol(sym: Symbol): Boolean = { - ( sym != null )&&( !sym.isPrimaryConstructor() ); - } - - def traverse1(trees: Array[Tree]): Unit = { - var i = 0; while(i < trees.length) { - traverse(trees(i)); - i = i + 1 - } - } - def traverse(tree: Tree): Unit = { - import Tree._ ; - tree match { - case x @ Ident(name)=> - if(x.symbol() != cf.unit.global.definitions.PATTERN_WILDCARD) - throw new ApplicationError("shouldn't happen?!"); - case Bind(name, subtree) => - var sym: Symbol = _; - if( isVariableName( name ) - && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} )) - handleVariableSymbol( sym ); - - traverse( subtree ); - - // congruence cases - case Apply(fun, args) => - traverse1(args); - case Sequence(trees) => - traverse1(trees); - case Typed(expr, tpe) => // needed?? - traverse(expr); - case _ : Alternative | _ : Select | _ : Literal => ; // no variables - case _ => - throw new ApplicationError("unknown pattern node:"+tree+" = "+tree.getClass()); - } - } - traverse( pat ); - return vars; - } - - //final def defs = cf.defs; - - val allVars: Set = collectVars( pat ); - - var varsToExport: Set = new HashSet(); // @todo HANDLE seqVars THESE GLOBALLY INSTEAD OF LOCALLY - - varsToExport.addAll( allVars ); - varsToExport.removeAll( seqVars ); - - var targetSym:Symbol = _; - - var helpMap = new HashMap(); - var helpMap2 = new HashMap(); - var helpVarDefs = new TreeList(); - - val it = seqVars.iterator(); - while(it.hasNext()) { - makeHelpVar( it.next().asInstanceOf[Symbol] ); - } - - val jt = allVars.iterator(); - while(jt.hasNext()) { - val varSym = jt.next().asInstanceOf[Symbol]; - if(( varSym.name.toString().indexOf("$") == -1 ) - && ( !seqVars.contains( varSym ))) { - makeHelpVar( varSym, true ); - } - } - - //System.out.println("allVars: "+allVars); - //System.out.println("seqVars: "+seqVars); - //System.out.println("helpVarDefs now: "+helpVarDefs); - - initializeSyms(); - - def makeHelpVar(realVar: Symbol): Unit = { - makeHelpVar( realVar, false ); - } - - /** makes a helpvar and puts mapping into helpMap, ValDef into helpVarDefs - */ - - def makeHelpVar(realVar: Symbol, keepType: Boolean): Unit = { - val helpVar = owner.newVariable( cf.pos, - 0, - cf.fresh.newName( realVar.name - .toString()+"RTIS" )); - var rhs: Tree = _; - - //System.out.println("RTiS making helpvar : "+realVar+" -> "+helpVar); - - if( keepType ) { - helpVar.setType( realVar.getType() ); - rhs = gen.mkDefaultValue( cf.pos, realVar.getType() ); - } else { - helpVar.setType( defs.LIST_TYPE(elementType) ); - rhs = gen.mkNil( cf.pos ); - } - - helpMap.put( realVar, helpVar ); - helpVar.flags = helpVar.flags | Modifiers.MUTABLE; - val varDef = gen.ValDef( helpVar, rhs ); - //((ValDef) varDef).kind = Kinds.VAR; - helpVarDefs.append( varDef ); - - } - - def prependToHelpVar(realVar: Symbol, elem:Tree): Tree = { - val hv = refHelpVar( realVar ); - gen.Assign( hv, gen.mkNewCons( cf.pos, elementType, elem, hv )); - /* - return cf.Block(pos, - new Tree [] { - cf.debugPrintRuntime( "ASSIGN" ), - gen.Assign( hv, cf.newSeqCons( elem, hv )) - }, defs.UNIT_TYPE()); - */ - } - - protected def initializeSyms(): Unit = { - - this.funSym = owner.newLabel( pos, - cf.fresh.newName( "right" )); - - this.iterSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName("iter")) - .setType( cf.SeqTraceType( elementType )); - - this.stateSym = owner.newVariable ( pos, - Modifiers.MUTABLE, - cf.fresh.newName("q")) - .setType( defs.int_TYPE() ) ; - - this.curSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName("cur")) - .setType( elementType ) ; - - this.targetSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName("p")) - .setType( defs.int_TYPE() ) ; - - funSym.setType( new Type.MethodType( Predef.Array[Symbol] ( // dummy symbol MethodType - funSym.newVParam( pos, 0, cf.fresh.newName("iter"), cf.SeqTraceType( elementType )), - funSym.newVParam( pos, 0, cf.fresh.newName( "q" ), defs.int_TYPE()) ), - defs.void_TYPE() )); // result - - } - - // load current elem and trace - override def loadCurrentElem(body: Tree): Tree = { - gen.If( cf.isEmpty( _iter() ), - run_finished( 0 ), // we are done - gen.mkBlock( Predef.Array[Tree] ( - gen.ValDef( this.targetSym, - cf.SeqTrace_headState( gen.Ident( pos, iterSym))), - gen.ValDef( this.curSym, - cf.SeqTrace_headElem( gen.Ident( pos, iterSym )))), - body ) - ); - } - - /** see code_state0_NEW - */ - def code_state0(elseBody: Tree) = { // careful, map Int to Int - - gen.If( cf.Equals( _state(), gen.mkIntLit( cf.pos, 0 )), - code_state0_NEW(), - elseBody ); - - } - - /** this one is special, we check the first element of the trace - * and choose the next state depending only on the state part - */ - def code_state0_NEW(): Tree = { // careful, map Int to Int - - val hmap = dfa.deltaq( 0 ); // all the initial states - - var i = 0; - val n = hmap.keySet().size(); // all transitions defined - - val tmapTag = new TreeMap(); - val tmapBody = new TreeMap(); - var it = hmap.keySet().iterator(); - while(it.hasNext()) { - val targetL = it.next().asInstanceOf[Integer]; - val targetR = hmap.get( targetL ).asInstanceOf[Integer]; - - val I = new Integer( i ); - tmapTag.put( targetL, I ); - tmapBody.put( I, callFun( Predef.Array[Tree] ( - cf.SeqTrace_tail( _iter() ), - gen.mkIntLit( cf.pos, targetR.intValue() ) ))); - i = i + 1; - } - i = 0; - val tags = new Array[Int]( n ); - val targets = new Array[Tree]( n ); - var jt = tmapTag.keySet().iterator(); - while(jt.hasNext()) { - val tagI = jt.next().asInstanceOf[Integer]; - tags( i ) = tagI.intValue(); - val I = tmapTag.get( tagI ).asInstanceOf[Integer]; - targets( i ) = tmapBody.get( I ).asInstanceOf[Tree];; - i = i + 1 - } - gen.Switch( gen.Ident( pos, targetSym ), - tags, - targets, - code_error()/*cannot happen*/ ); - - } - - override def currentMatches(label: Label): Tree = { - label match { - case LPair( target, theLab ) => - cf.Equals( gen.mkIntLit( cf.pos, target.intValue() ), - current() ); - case _ => throw new ApplicationError("expected Pair label"); - } - } - - - override def code_state_NEW(i: Int): Tree = { // precondition i != 0 - var stateBody = code_delta( i, DefaultLabel() ); - if( stateBody == null ) { - stateBody = code_error(); - } - val trans = dfa.deltaq( i ); - val tmapTag = new TreeMap(); - val tmapBody = new TreeMap(); - var j = 0; - var labs = dfa.labels().iterator(); - while(labs.hasNext()) { - val label = labs.next(); - val next = trans.get( label ).asInstanceOf[Integer]; - val action = code_delta( i, label.asInstanceOf[Label] ); - - if( action != null ) { - val J = new Integer( j ); - tmapTag.put( label.asInstanceOf[LPair].state, J ); - tmapBody.put( J, action ); - - stateBody = gen.If( currentMatches( label.asInstanceOf[Label] ), - action, - stateBody); - } - j = j + 1; - } - val n = tmapTag.keySet().size(); - j = 0; - val tags = new Array[int]( n ); - val targets = new Array[Tree]( n ); - val it = tmapTag.keySet().iterator(); - while(it.hasNext()) { - val tagI = it.next().asInstanceOf[Integer]; - tags( j ) = tagI.intValue(); - val J = tmapTag.get( tagI ).asInstanceOf[Integer]; - targets( j ) = tmapBody.get( J ).asInstanceOf[Tree]; - j = j + 1; - } - if( n > 0 ) - gen.Switch( gen.Ident( pos, targetSym ), tags, targets, code_error() ); - else - code_error(); - } - - // calling the AlgebraicMatcher here - override def _cur_match(pat1: Tree): Tree = { - var pat = pat1; - //System.out.println("RTiS._cur_match("+pat.toString()+")"); - //System.out.println("calling algebraic matcher on type:"+pat.type); - - //System.err.println( "curT"+currentElem().type().widen() ); - val m = new PartialMatcher( owner, //funSym,//this.funSym, - currentElem(), - defs.boolean_TYPE() ); - - val freshenMap = new HashMap(); // sym2exp -> new sym - val helpMap3 = new HashMap(); // new sym -> original sym - - // "freshening": never use the same symbol more than once - // (in later invocations of _cur_match) - - var it = varsToExport.iterator(); - while(it.hasNext() ) { - val key = it.next().asInstanceOf[Symbol]; - if( key.name.toString().indexOf("$") == -1 ) { - this.helpMap2.put( key, helpMap.get( key )); - // "freshening" by appending string ( a bit dangerous ) - val newSym = key.cloneSymbol().setOwner( owner /*funSym*/ ); - newSym.name = Name.fromString( key.name.toString() + "%" ); - freshenMap.put( key, newSym ); - helpMap3.put( newSym, helpMap.get( key )); - //System.out.println( "key: "+ key + " key.owner:"+key.owner()); - //System.out.println( "newsym owner:"+newSym.owner()); - } else { - freshenMap.put( key, key ); - } - } - - //System.out.println("RightTracerInScala:: -pat :"+pat.toString()); - /* - System.out.println("RightTracerInScala - the seqVars"+seqVars); - System.out.println("RightTracerInScala - the varsToExport"+varsToExport); - */ - //System.out.println("RightTracerInScala::freshenMap :"+freshenMap); - - // "freshening" - - /* TEST - */ - val tc = new TreeCloner( cf.unit.global, freshenMap, Type.IdMap ); - - /* - Transformer tc = new Transformer(cf.unit.global) { - public Tree transform(Tree tree) { - tree = super.transform(tree); - if (tree.hasSymbol()) { - Object symbol = freshenMap.get(tree.symbol()); - if (symbol != null) tree.setSymbol((Symbol)symbol); - } - return tree; - } - }; - */ - pat = tc.transform( pat ); - - - //System.out.println("RightTracerInScala:: -pat( after subst ) :"+pat); - - - // val match { case <pat> => { <do binding>; true } - // case _ => false - - - val ts = new Array[Tree]( helpMap3.keySet().size() ); - var j = 0; - var jt = helpMap3.keySet().iterator(); - while(jt.hasNext()) { - val vsym = jt.next().asInstanceOf[Symbol]; - val hv = helpMap3.get( vsym ).asInstanceOf[Symbol]; - //hv.setType( defs.LIST_TYPE( elementType ) ) ; DEBUG ALARM ? - val refv = gen.Ident(cf.pos, vsym); - val refhv = gen.Ident(cf.pos, hv); - ts( j ) = gen.Assign( refhv, refv ); - j = j + 1; - // System.out.println( "the assign" + res[ j - 1 ] ); - } - - val res = gen.mkBooleanLit( cf.pos, true ); // just `true' - val theBody = gen.mkBlock(ts, res); - - am.construct( m, Predef.Array[Tree] ( - - cf.gen.CaseDef( pat, // if tree val matches pat -> update vars, return true - theBody/* "freshening */), - cf.gen.CaseDef( cf.gen.Ident( pat.pos, defs.PATTERN_WILDCARD ), - gen.mkBooleanLit( pat.pos, false )) ), // else return false - true // do binding please - ); - - am.toTree(); - } - - /** returns translation of transition with label from i. - * returns null if there is no such transition(no translation needed) - */ - override def code_delta(i: Int , label: Label ): Tree = { - val hmap = dfa.deltaq( i ); - val ntarget = hmap.get( label ).asInstanceOf[Integer]; - var algMatchTree: Tree = null; - if( ntarget == null ) - return null; - - //System.out.println("delta("+i+","+label+")" ); - var theLab: Label = null; - label match { - case LPair ( state, lab2 )=> - //assert ntarget == state; - theLab = lab2; - lab2 match { - case TreeLabel( pat ) => - algMatchTree = _cur_match( pat ); - case _ => - } - case DefaultLabel() => - throw new ApplicationError(); // should not happen - } - //assert dfa.qbinders != null : "qbinders ?"; - - var vars = dfa.qbinders(i); - - //System.out.println("dfa.qbinders[ i ]"+vars); - - if (null == vars) vars = new Vector(); // TODO: make this more consistent - //assert vars != null; - - val stms = new Array[Tree]( vars.size() - + { if (algMatchTree != null ) 1 else 0 }); - var j = 0; - var it = vars.iterator(); - while(it.hasNext()) { - val vble = it.next().asInstanceOf[Symbol]; - val rhs = gen.Ident( pos, curSym ); - stms( j ) = prependToHelpVar( vble , rhs); - j = j + 1; - } - - if( algMatchTree != null ) { - stms( j ) = algMatchTree ; - j = j + 1 - } - - val value = callFun( Predef.Array[Tree] ( cf.SeqTrace_tail( _iter() ), - gen.mkIntLit( cf.pos, ntarget.intValue() ) ) ); - - gen.mkBlock( pos, stms, value ); - } - - override def stateWrap(i: Int): Tree = { - if (i == 0) - code_state0_NEW(); - else - code_state_NEW(i); - } - - /* returns statements that do the work of the right-transducer - */ - def getStms(trace: Tree, unit: CompilationUnit, body: Tree): Tree = { - - val stms = new TreeList(); - val loopbody = code_body_NEW(); - - stms.append( gen.ValDef( iterSym, trace ) ); - stms.append( gen.ValDef( stateSym, gen.mkIntLit( cf.pos, 0 ) ) ); - stms.append( helpVarDefs ); - stms.append( gen.LabelDef( this.funSym, - Predef.Array[Ident] ( - gen.Ident( pos, iterSym ), - gen.Ident( pos, stateSym ) - ), loopbody )); - - // bind variables handled by this righttracer - var it = seqVars.iterator(); - while(it.hasNext()) { - stms.append( bindVar( it.next().asInstanceOf[Symbol] ) ); - } - - val treeCloner = new Transformer(unit.global) { - override def transform(tree1: Tree): Tree = { - val tree = super.transform(tree1); - if (tree.hasSymbol()) { - val symbol = helpMap2.get(tree.symbol()); - if (symbol != null) tree.setSymbol(symbol.asInstanceOf[Symbol]); - } - tree; - } - }; - - gen.mkBlock(stms.toArray(), treeCloner.transform( body )); - } - - - - /** return the accumulator. (same as in LeftTracerInScala) - * todo: move tree generation of Unit somewhere else - */ - override def run_finished(state: Int): Tree = { - gen.mkUnitLit(Position.FIRSTPOS); - } - - def current() = { gen.Ident( pos, targetSym );} - - def refHelpVar(realVar: Symbol) = { - val hv = helpMap.get( realVar ).asInstanceOf[Symbol]; - //assert hv != null : realVar; - gen.Ident(Position.FIRSTPOS, hv); - } - - def assignToHelpVar(realVar: Symbol, rhs: Tree): Tree = { - val hv = refHelpVar(realVar); - gen.Assign(hv, rhs); - } - - def bindVar(realVar: Symbol): Tree = { - val hv = refHelpVar(realVar); - /* - System.out.println("binding realVar.name "+realVar.name+" type:"+realVar.type()+" to hv type:"+hv.type()); - realVar.setOwner( owner ); - System.out.println("is same as realVar"+realVar.type().isSameAs( elementType )); - System.out.println("is same as hv"+realVar.type().isSameAs( hv.type() )); - if( realVar.type().isSameAs( elementType )) - return gen.ValDef( realVar, cf.SeqList_head( hv )); - else - return gen.ValDef( realVar, hv ); - */ - if( realVar.getType().isSameAs( hv.getType())) { - gen.ValDef( realVar, hv ); // e.g. x @ _* - } else - gen.ValDef( realVar, cf.SeqList_head( hv )); - } -} -} - diff --git a/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala b/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala deleted file mode 100644 index 17d840b29a..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala +++ /dev/null @@ -1,165 +0,0 @@ - - -import scalac._; -import scalac.ast.Tree; -import Tree._; - - //import scala.compiler.printer.XMLAutomPrinter ; // DEBUGGING\ - -import scalac.ast._ ; -import scalac.symtab._ ; - -import java.util._ ; - -import scala.tools.util.Position; - -package scala.tools.scalac.transformer.matching { -/** constructs a matcher for a sequence pattern. plays two roles in - * described in design pattern Builder. - * is the "Director" for "Builder" class BerrySethi. - * is the "Builder" for "Director" class TransMatch. - */ - -class SequenceMatcher(unit: CompilationUnit) extends PatternTool(unit) { - -// Console.println("CONSTR SEQUENCEMATCHER"); - final val IGNORED = new Integer(42); - - var cf: CodeFactory = _; - var _m: PartialMatcher = _; - - var bbuild: BindingBerrySethi = null; - - /** collects variables - * @return all variables bound by this binding nfa - */ - def collectNfaVariables(nfa: NondetWordAutom): Set = { - val seqVars = new HashSet(); - var j = 0; - while(j < nfa.nstates) { - if( nfa.qbinders( j ) != null ) - seqVars.addAll( nfa.qbinders( j ) ); - j = j + 1 - } - seqVars; - } - - - /** translates the det/switching automaton to scala code - * precondition: pat.type() corresponds to element type - */ - def addBinderToBody( pat:Tree , body:Tree ): Tree = { - if( bbuild == null ) - bbuild = new BindingBerrySethi(unit); - - val elementType = cf.getElemType_Sequence( pat.getType() ); - - // (a) build *binding* nfa (sequential machine) - val left = bbuild.automatonFrom( pat, IGNORED ); - val right = bbuild.revnfa; - - // (b) determinize + translate L - - val dLeft = new DetWordAutom( left ); - - val ltis = new LeftTracerInScala( dLeft, elementType, _m.owner, cf, _m.selector); - - val trace = ltis.getTrace(); - - // (c) determinize + translate R - - val dRight = new DetWordAutom( right, left, dLeft ); - - val seqVars = collectNfaVariables( left ); - //System.out.println("seqVars here are:"+seqVars); - val rtis = new RightTracerInScala( dRight, seqVars, _m.owner, - cf, pat, elementType ); - - // !!! Tree stms2 = rtis.getStms( theTrace, unit, body ); - // !!! gen.mkBlock_( body.pos, trace, stms2 ); - val stms2 = rtis.getStms( trace, unit, body ); - stms2; - } - - private def buildNfas( pat:Array[Tree] ): Array[NondetWordAutom] = { - val build = new BerrySethi(unit); - val manyNfa = new Array[NondetWordAutom]( pat.length ); - var i = 0; - while( i < pat.length ) { - manyNfa( i ) = build.automatonFrom( pat( i ), - new Integer( i )); - i = i + 1; - //manyNfa[ i ].print(); - } - manyNfa; - } - - /** constructs a word recognizer from an array of patterns which - * should all be SequencePatterns ( no wildcard * ) - * precondition: pat.type corresponds to element type - * @param _m Matcher object, holds the result - * @param pat the (Sequence) patterns - * @param body the bodies - * @param defaultCase code that is run when nothing matches. may be null, it - * becomes a ThrowMatchError then - * @param doBinding flasg that indicates whether variables should be bound - */ - def construct(_m: PartialMatcher, pat: Array[Tree] , body: Array[Tree] , defcase1: Tree, doBinding: Boolean ): Unit = { - var defaultCase = defcase1; - this._m = _m; - //assert body.length == pat.length; - if( defaultCase == null ) - defaultCase = cf.ThrowMatchError( cf.pos, _m.resultType ); - - this.cf = new CodeFactory( unit, _m.pos ); - - val seqType = pat( 0 ).getType(); - val elementType = cf.getElemType_Sequence( seqType ); - - // STEP 1 - build nfas for each pattern - - val manyNfa = buildNfas( pat ); - - // STEP 2 - recognizing - - // (a) merge nfas into one if necessary - val nfa = if(pat.length > 1) new NondetWordAutom( manyNfa ) else manyNfa( 0 ); - - //nfa.print(); - - // (b) determinize - val dfa = new DetWordAutom( nfa ); - - // (c) translate to scala code - val scalaAut = - new WordAutomInScala( dfa, - elementType, - _m.owner, - cf, - unit.global.target == Global.TARGET_JVM ); - scalaAut.translate(); - - // STEP 3 - binding - - var newbody:Array[Tree] = _; - if( !doBinding ) - newbody = body; - else { // this is done in the body of the matching case - newbody = new Array[Tree](body.length); - var i = 0; - while(i < body.length) { - if( !containsBinding( pat( i ) ) ) - newbody( i ) = body( i ); // no need for binding - else - newbody( i ) = addBinderToBody( pat( i ), body( i ) ); - i = i + 1; - } - } - _m.tree = scalaAut.getMatcherSwitch( _m.selector, - defaultCase, - newbody, - _m.resultType ); - } // construct (PartialMatcher, Tree[], Tree[], Tree, boolean ) - - } // class SequenceMatcher - } diff --git a/sources/scala/tools/scalac/transformer/matching/StateSetComparator.scala b/sources/scala/tools/scalac/transformer/matching/StateSetComparator.scala deleted file mode 100644 index c57e9c8f74..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/StateSetComparator.scala +++ /dev/null @@ -1,34 +0,0 @@ -package scala.tools.scalac.transformer.matching ; - -import java.util.{Comparator, TreeSet} ; - -class StateSetComparator extends Comparator { - // use lexicographic order - def compare(o1: Any , o2: Any ): Int = { - /* - System.out.print("lexi" ); - System.out.print( o1 +" "); - System.out.println( o2 ); - */ - val it1 = o1.asInstanceOf[TreeSet].iterator(); - val it2 = o2.asInstanceOf[TreeSet].iterator(); - while( it1.hasNext() ) { - while( it2.hasNext() ) { - if( !it1.hasNext() ) - return -1; - - val i1 = it1.next().asInstanceOf[Integer].intValue(); - val i2 = it2.next().asInstanceOf[Integer].intValue(); - if( i1 < i2 ) - return -1; - else if ( i1 > i2 ) - return 1; - } - if( it1.hasNext() ) - return 1; - } - if( it2.hasNext() ) - return -1; - return 0; - } -} diff --git a/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala deleted file mode 100644 index 448c9fb17e..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala +++ /dev/null @@ -1,14 +0,0 @@ -import scalac.ast.Tree; -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -package scala.tools.scalac.transformer.matching { -/** @todo: factor common things of LeftTracerInScala and RightTracerInScala - */ -class TracerInScala(dfa: DetWordAutom, elementType: Type, owner: Symbol, cf: CodeFactory ) -extends Autom2Scala(dfa, elementType, owner, cf) { - - override var optimize = true; - -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/VariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/VariableTraverser.scala deleted file mode 100644 index fbb385491b..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/VariableTraverser.scala +++ /dev/null @@ -1,56 +0,0 @@ -import scalac.ast.Tree; -import scalac.util.Name; -import scalac.symtab.Symbol ; -import scalac.ast.Traverser ; - -import Tree.Ident; -import Tree.Bind; -import Tree.Select; - -package scala.tools.scalac.transformer.matching { - -abstract class VariableTraverser extends Traverser { - - def isVariableName(name: Name): Boolean = { - ( name.isVariable() ) && ( name != Name.fromString("_") ) ; - } - - def isVariableSymbol(sym: Symbol): Boolean = { - ( sym != null )&&( !sym.isPrimaryConstructor() ); - } - - def handleVariableSymbol(sym: Symbol): Unit; - - override def traverse(tree: Tree): Unit = { - tree match { - case Ident(name)=> - var sym: Symbol = _; - - if( isVariableName( name ) - && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} ) ) - handleVariableSymbol( sym ); - - return; - - case Bind(name, subtree) => - var sym: Symbol = _; - - if( isVariableName( name ) - && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} )) - handleVariableSymbol( sym ); - - traverse( subtree ); - - return; - - case Select(_,_) => - return; - - case _ => - super.traverse( tree ); - } - } - - -} -} diff --git a/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala b/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala deleted file mode 100644 index 3d30cf6f91..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala +++ /dev/null @@ -1,153 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scala.tools.util.Position; - -import scalac._; -import scalac.ast.Tree; -import scalac.ast.TreeGen; -import scalac.symtab.{ Modifiers, Symbol, Type }; -import Tree._; - -import java.util._; -import scala.tools.scalac.util.NewArray; - -import scalac.util.Names; - -package scala.tools.scalac.transformer.matching { - /** translates a recognizer to scala code - */ - - /** constructor - * @param dfa the dfa that is to be translated - * @param elementType type of the objects in the sequence - * @param owner the owner of the pattern match - * @param cf code factory - * @param optim flag that indicates whether to optimize - * @return an object that translates the dfa - */ - class WordAutomInScala(dfa: DetWordAutom, elementType: Type, owner: Symbol, cf: CodeFactory, optim: Boolean ) - extends Autom2Scala(dfa, elementType, owner, cf) { - - this.optimize = this.optimize && optim; - - var theDefDef: Tree = _ ; - - def getMatcherSwitch(selector: Tree, failTree: Tree, body: Array[Tree], resultType: Type ): Tree = { - - var result: Tree = _; - val tags = new Array[int](body.length); - var i = body.length - 1; - while( i >= 0 ) { - tags(i) = i; - i = i - 1 - } - result = gen.Switch( _swres(), tags, body, failTree ); - - //} - - result = cf.gen.mkBlock( cf.pos, - NewArray.Tree ( - gen.ValDef( iterSym, cf.newIterator( selector.duplicate() )), - gen.ValDef( stateSym, gen.mkIntLit( cf.pos, 0) ), - gen.ValDef( resultSym, theDefDef )), - result ); - //unit.global.debugPrinter.print( result ); - result; - } - - protected def initializeSyms(): Unit = { // TEST - - this.funSym = owner.newLabel( pos, - cf.fresh.newName( "matcher" )); - - this.iterSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName("iter")) - .setType( cf._seqIterType( elementType ) ) ; - - this.stateSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName("q")) - .setType( defs.int_TYPE() ) ; - - this.resultSym = owner.newVariable( pos, - Modifiers.MUTABLE, - cf.fresh.newName("swRes")) - .setType( defs.int_TYPE() ) ; - - this.funSym - .setType( new Type.MethodType( Predef.Array[Symbol] ( - funSym.newVParam( pos, 0, cf.fresh.newName("q"), defs.int_TYPE()) - ), defs.int_TYPE() )); - - this.curSym = owner.newVariable( pos, 0, Names.cur ) - .setType( elementType ); - - this.hasnSym = owner.newVariable( pos, 0, Names.hasNext ) - .setType( defs.boolean_TYPE() ); - - } - - /** code for the return value of the automaton translation - */ - override def run_finished(state: Int): Tree = { // T E S T - if( dfa.isFinal(state)) - gen.mkIntLit(Position.FIRSTPOS, dfa.finals.get(new Integer(state)).asInstanceOf[Integer].intValue()); - else - gen.mkIntLit(Position.FIRSTPOS, FAIL); - } - - - // calling the /*AlgebraicMatcher*/PatternMatcher here - override def _cur_match(pat: Tree): Tree = { // TE ST - val m = new PartialMatcher(this.owner, /* owner*/ - currentElem(), /* root */ - defs.boolean_TYPE() /* restype */); - - am.construct( m, Predef.Array[Tree] ( - cf.gen.CaseDef( pat, - gen.mkBooleanLit( pat.pos, true )), - cf.gen.CaseDef( cf.gen.Ident(pat.pos, defs.PATTERN_WILDCARD), - gen.mkBooleanLit( pat.pos, false )) ), - false); - am.toTree(); - } - - /** do the translation - */ - def translate(): Unit = { - initializeSyms(); - val tb = code_body_NEW(); - //theDefDef = gen.DefDef(this.funSym, tb); - theDefDef = gen.LabelDef(this.funSym, Predef.Array[Ident] ( /*(Ident)_iter(),*/ _state().asInstanceOf[Ident] ), tb); - } - - /** ... - * @return returns translation of transition with label from i. - * returns null if there is no such transition - * (no translation needed) - */ - override def code_delta(i: Int, label: Label): Tree = { - val target = dfa.delta(i, label); - - if (target == null) - label match { - case DefaultLabel() => - code_error(); // this may not happen ! - case _ => - null; // not good - } - else if (target.intValue() == dfa.nstates() - 1) // that one is a dead state - code_fail(); - else - callFun(Predef.Array[Tree]( gen.mkIntLit( cf.pos, target.intValue() ))); - } - - } -} diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala deleted file mode 100644 index e39316a7b4..0000000000 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ /dev/null @@ -1,3153 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// todo: eliminate Typed nodes. -// todo: use SELECTOR flag to avoid access methods for privates -// todo: use mangled name or drop. -// todo: emit warnings for unchecked. -// todo: synchronize on module instantiation. -// todo: empty package - - -import java.lang.{Boolean => JBoolean, Integer, Object => JObject} -import java.util.HashMap; - -import ch.epfl.lamp.util.Pair; - -import scalac._; -import scalac.{Global => scalac_Global} -import scalac.ast._; -import scalac.atree.AConstant; -import scalac.atree.AConstant$CHAR; -import scalac.atree.AConstant$INT; -import scalac.symtab.classfile._; -import scalac.symtab._; -import scalac.util._; -import Tree._; - -import scala.tools.scalac.util.NewArray; -import scala.tools.util.Position; - -package scala.tools.scalac.typechecker { - - -/** The main attribution phase. - */ -class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(global) { - - import Modifiers._; - import Kinds._; - - private var context: Context = _; - private var pt: Type = _; - private var mode: Int = _; - - private var inAlternative: Boolean = _; - // for pattern matching; maps x to {true,false} - private val patternVars = new HashMap/*<Symbol,JBoolean>*/(); - - val definitions = global.definitions; - val infer = new scala.tools.scalac.typechecker.Infer(this) { - override def getContext = context; - override def error(pos: int, msg: String) = Analyzer.this.error(pos, msg); - } - val desugarize = new DeSugarize(make, copy, gen, infer, global); - val constfold = new ConstantFolder(global); - - var unit: CompilationUnit = _; - - def enterUnit(unit: CompilationUnit): unit = - enter( - new Context( - Tree.Empty, - if (unit.console) descr.consoleContext else descr.startContext), - unit); - - def enter(context: Context, unit: CompilationUnit): Unit = { - assert(this.unit == null, "start unit non null for " + unit); - context.infer = infer; - this.unit = unit; - this.context = context; - descr.contexts.put(unit, context); - enterSyms(unit.body); - this.unit = null; - this.context = null; - } - - def lateEnter(unit: CompilationUnit): unit = { - enterUnit(unit); - } - - def loadMixinCode(pos: Int, clasz: Symbol): unit = { - assert(clasz.isClass() && !clasz.isModuleClass(), Debug.show(clasz)); - if (clasz.isExternal()) { - var c: Symbol = clasz; - try { - while (!c.owner().isPackageClass()) c = c.owner(); - global.compileLate(global.getSourceFile(c), true); - } catch { - case exception: java.io.IOException => - if (global.debug) exception.printStackTrace(); - unit.error(pos, exception.getMessage() + "; source file for " - + c + " is needed because it is used as a mixin"); - } - } - } - - override def apply(unit: CompilationUnit): unit = { - global.log("checking " + unit); - assert(this.unit == null, "start unit non null for " + unit); - this.unit = unit; - this.context = descr.contexts.remove(unit).asInstanceOf[Context]; - assert(this.context != null, "could not find context for " + unit); - unit.body = transformStatSeq(unit.body, Symbol.NONE); - if (global.target != scalac_Global.TARGET_INT && global.reporter.errors() == 0) { - genSymData(unit.body); - } - this.unit = null; - this.context = null; - global.operation("checked " + unit); - } - - def genSymData(stats: Array[Tree]): unit = { - var i = 0; while (i < stats.length) { - stats(i) match { - case Tree.ClassDef(_, _, _, _, _, _) | Tree.ModuleDef(_, _, _, _) => - val sym = stats(i).symbol(); - val key = if (sym.isModule()) sym.moduleClass() else sym; - var termSym = sym.owner().info().lookup(sym.name.toTermName()); - var typeSym = sym.owner().info().lookup(sym.name.toTypeName()); - if (termSym.isExternal()) termSym = Symbol.NONE; - if (typeSym.isExternal()) typeSym = Symbol.NONE; - if (sym.isClass() || (sym.isModule() && typeSym.isNone())) { - val pickle: Pickle = new Pickle(); - if (!termSym.isNone()) pickle.add(termSym); - if (!typeSym.isNone()) pickle.add(typeSym); - pickle.pickle(); - global.symdata.put(key, pickle); - } - case Tree.PackageDef(packaged, templ) => - genSymData(templ.body); - case _ => - } - i = i + 1 - } - } - - /** Mode constants - */ - val NOmode = 0x000; - val EXPRmode = 0x001; // these 4 modes are mutually exclusive. - val PATTERNmode = 0x002; - val CONSTRmode = 0x004; - val TYPEmode = 0x008; - - val FUNmode = 0x10; // orthogonal to above. When set - // we are looking for a method or constructor - - val POLYmode = 0x020; // orthogonal to above. When set - // expression types can be polymorphic. - - val QUALmode = 0x040; // orthogonal to above. When set - // expressions may be packages and - // Java statics modules. - - val SUPERmode = 0x080; // Goes with CONSTRmode. When set - // we are checking a superclass - // constructor invocation. - - val baseModes = EXPRmode | PATTERNmode | CONSTRmode; - - val SEQUENCEmode = 0x1000; // only for PATTERNmode, otherwise orthogonal to above. When set - // we turn "x" into "x@_" - // and allow args to be of type Seq( a) instead of a - -// Diagnostics ---------------------------------------------------------------- - - private def errorName(tree: Tree): Name = - Name.fromString("<error: " + tree + ">"); - - private def errorTree(tree: Tree): Tree = - try { - if (tree.isType()) errorTypeTree(tree) else errorTermTree(tree); - } catch { - case ex: Type$Error => - Tree.Empty; - } - - private def errorTypeTree(tree: Tree): Tree = { - val symbol = context.owner.newErrorClass(errorName(tree).toTypeName()); - tree match { - case Tree.Ident(_) => - make.Ident(tree.pos, symbol).setType(symbol.getType()); - case Tree.Select(qualifier, _) => - make.Select(tree.pos, symbol, qualifier).setType(symbol.getType()); - case _ => - gen.mkType(tree.pos, symbol.getType()); - } - } - - private def errorTermTree(tree: Tree): Tree = - gen.mkLocalRef(tree.pos, Symbol.NONE.newErrorValue(errorName(tree))); - - private def setError(tree: Tree): Tree = { - if (tree.hasSymbol() && tree.symbol() == null) - tree.setSymbol( - if (tree.isType()) Symbol.NONE.newErrorClass(errorName(tree).toTypeName()) - else Symbol.NONE.newErrorValue(errorName(tree))); - tree.setType(Type.ErrorType); - } - - def error(pos: int, msg: String): unit = - unit.error(pos, msg); - - def typeError(pos: int, found: Type, req: Type): unit = { - if (found.isError() || req.isError()) return; - var msg: String = infer.typeErrorMsg("type mismatch", found, req); - val foundResult: Type = found.resultType(); - if (foundResult != found && infer.isCompatible(foundResult, req)) - msg = msg + "\n possible cause: missing arguments for method or constructor"; - error(pos, msg); - } - - def reportTypeError(pos: int, ex: Type$Error): unit = { - if (global.debug) ex.printStackTrace(); - if (ex.isInstanceOf[CyclicReference]) { - val cyc: CyclicReference = ex.asInstanceOf[CyclicReference]; - if (cyc.info.isInstanceOf[LazyTreeType]) { - (cyc.info.asInstanceOf[LazyTreeType]).tree match { - case Tree.ValDef(_, _, Tree.Empty, _) => - return error(pos, "recursive " + cyc.sym + " needs type"); - case Tree.DefDef(_, _, _, _, Tree.Empty, _) => - return error(pos, "recursive function " + cyc.sym.name + " needs result type"); - case _ => - } - } - } - error(pos, ex.msg); - } - - def decode(name: Name): String = - (if (name.isTypeName()) "type " else "value ") + NameTransformer.decode(name); - -// Checking methods ---------------------------------------------------------- - - /** Check that symbol's definition is well-formed. This means: - * - no conflicting modifiers - * - `abstract' modifier only for classes - * - `override' modifier never for classes - * - `def' modifier never for parameters of case classes - * - declarations only in traits or abstract classes - * - symbols with `override' modifier override some other symbol. - */ - def validate(sym: Symbol): unit = { - if ((sym.flags & (ABSTRACT | OVERRIDE)) == ABSTRACT && sym.kind != CLASS) { - error(sym.pos, "`abstract' modifier can be used only for classes; " + - "\nit should be omitted for abstract members"); - } - if (sym.isOverride() && sym.kind == CLASS) { - error(sym.pos, "`override' modifier not allowed for classes"); - } - if ((sym.flags & DEF) != 0 && sym.owner().isPrimaryConstructor() && - (sym.owner().constructorClass().flags & CASE) != 0) { - error(sym.pos, "pass-by-name arguments not allowed for case class parameters"); - } - /*!!! - if ((sym.flags & REPEATED) != 0 && sym.owner().isPrimaryConstructor()) { - error(sym.pos, "`*' modifier not allowed for class parameters"); - } - */ - if (sym.isDeferred()) { - if (sym.owner().kind != CLASS || (sym.owner().flags & MODUL) != 0 || sym.owner().isAnonymousClass()) { - error(sym.pos, - "only classes can have declared but undefined members" + - (if ((sym.flags & MUTABLE) == 0) "" - else "\n(Note that variables need to be initialized to be defined)")); - sym.flags = sym.flags & ~DEFERRED; - } - } - checkNoConflict(sym, DEFERRED, PRIVATE); - checkNoConflict(sym, FINAL, SEALED); - if ((sym.flags & MODUL) == 0) checkNoConflict(sym, FINAL, PRIVATE); - checkNoConflict(sym, PRIVATE, PROTECTED); - checkNoConflict(sym, PRIVATE, OVERRIDE); - checkNoConflict(sym, DEFERRED, FINAL); - } - - /** Check that - * - all parents are class types - * - supertype conforms to supertypes of all mixin types. - * - final classes are only inherited by classes which are - * nested within definition of base class, or that occur within same - * statement sequence. - * - self-type of current class is a subtype of self-type of each parent class. - * - parent constructors do not refer to value parameters of class. - * - no two parents define same symbol. - * - * @param constrs - * @param parents - */ - def validateParentClasses(constrs: Array[Tree], parents: Array[Type], selfType: Type): Unit = { - var i = 0; - while (i < parents.length) { - if (!checkClassType(constrs(i).pos, parents(i))) return; - val bsym: Symbol = parents(i).symbol(); - if (i > 0) { - if ((bsym.flags & (JAVA | INTERFACE)) == JAVA) - error(constrs(i).pos, "Java class may not be used as mixin"); - val grandparents = parents(i).parents(); - if (grandparents.length > 0 && !parents(0).isSubType(grandparents(0))) - error(constrs(i).pos, "illegal inheritance;\n " + parents(0) + - " does not conform to " + parents(i) + "'s supertype " + grandparents(0)); - } - if ((bsym.flags & FINAL) != 0) { - error(constrs(i).pos, "illegal inheritance from final class"); - } else if (bsym.isSealed() || - bsym.isSubClass(definitions.ANYVAL_CLASS) || - bsym.isSubClass(definitions.ARRAY_CLASS)) { - // are we in same scope as base type definition? - val e: Scope$Entry = context.scope.lookupEntry(bsym.name); - if (e.sym != bsym) { - // we are not within same statement sequence - var c: Context = context; - while (c != Context.NONE && c.owner != bsym) - c = c.outer.enclClass; - if (c == Context.NONE) { - error(constrs(i).pos, "illegal inheritance from sealed class"); - } - } - } - if (!selfType.isSubType(parents(i).instanceType())) { - error(constrs(i).pos, "illegal inheritance;\n self-type " + - selfType + " does not conform to " + parents(i) + - "'s selftype " + parents(i).instanceType()); - } - var j = 0; while (j < i) { - if (parents(i).symbol() == parents(j).symbol()) - error(constrs(i).pos, "" + parents(i).symbol() + " is inherited twice"); - j = j + 1 - } - i = i + 1; - } - } - - /** Check that type is a class type. - * - * @param pos - * @param tp - * @return - */ - private def checkClassType(pos: Int, tp: Type): Boolean = { - tp.unalias() match { - case Type$TypeRef(_, sym, _) => - if (sym.kind == CLASS) return true; - case _ => - } - if (!tp.isError()) error(pos, "class type expected"); - false - } - - /** Check that type is an object type - * - * @param pos - * @param tp - * @return - */ - private def checkObjectType(pos: Int, tp: Type): Type = - if (tp.isObjectType()) tp - else { - if (!tp.isError()) error(pos, "object type expected"); - Type.ErrorType - } - - /** Check that type is eta-expandable (i.e. no `def' or `*' parameters) - * - * @param pos - * @param tp - */ - def checkEtaExpandable(pos: Int, tp: Type): Unit = tp match { - case Type$MethodType(params, restype) => - var i = 0; while (i < params.length) { - if ((params(i).flags & DEF) != 0) - error(pos, "method with pass-by-name parameters needs to be fully applied"); - if ((params(i).flags & REPEATED) != 0) - error(pos, "method with `*' parameters needs to be fully applied"); - i = i + 1 - } - checkEtaExpandable(pos, restype); - case _ => - } - - /** Check that `sym' does not contain both `flag1' and `flag2'. - * - * @param sym - * @param flag1 - * @param flag2 - */ - def checkNoConflict(sym: Symbol, flag1: Int, flag2: Int): Unit = { - if ((sym.flags & (flag1 | flag2)) == (flag1 | flag2)) { - if (flag1 == DEFERRED) - error(sym.pos, "abstract member may not have " + - Modifiers$Helper.toString(flag2) + " modifier"); - else - error(sym.pos, "illegal combination of modifiers: " + - Modifiers$Helper.toString(flag1) + " and " + - Modifiers$Helper.toString(flag2)); - } - } - - /** Check that type `tp' is not a subtype of itself. - */ - def checkNonCyclic(pos: int, tp: Type): unit = tp match { - case Type$TypeRef(pre, sym, args) => - sym.initialize(); - if (sym.isLocked()) { - error(pos, "cyclic aliasing or subtyping involving " + sym); - } else if (sym.kind == ALIAS || sym.kind == TYPE) { - sym.flags = sym.flags | LOCKED; - //System.out.println("checking " + sym);//DEBUG - checkNonCyclic( - pos, pre.memberInfo(sym).subst(sym.typeParams(), args)); - if (sym.kind == TYPE) { - checkNonCyclic( - pos, pre.memberLoBound(sym).subst(sym.typeParams(), args)); - checkNonCyclic( - pos, pre.memberVuBound(sym).subst(sym.typeParams(), args)); - } - sym.flags = sym.flags & ~LOCKED; - } - - case Type$CompoundType(parents, members) => - var i = 0; while (i < parents.length) { - checkNonCyclic(pos, parents(i)); - i = i + 1 - } - - case Type$SingleType(pre, sym) => - sym.initialize(); - if (sym.isLocked()) { - error(pos, "cyclic aliasing or subtyping involving " + sym); - } - - case _ => - } - - /** Check that type does not refer to components defined in current scope. - * - * @param pos - * @param tp - * @return - */ - def checkNoEscape(pos: Int, tp: Type): Type = { - - val checkNoEscapeMap = new Type$Map() { - override def apply(t: Type): Type = { - t.unalias() match { - case Type$TypeRef(Type.NoPrefix, sym, args) => - checkNoEscape(t, sym); - case Type$SingleType(Type.NoPrefix, sym) => - checkNoEscape(t, sym); - case _ => - } - return map(t); - } - private def checkNoEscape(t: Type, sym: Symbol): unit = { - val e: Scope$Entry = context.scope.lookupEntry(sym.name); - if (e.sym == sym && e.owner == context.scope && - !e.sym.isTypeParameter()) { - throw new Type$Error( - "type " + t + " escapes its defining scope"); - } - } - }; - - try { - checkNoEscapeMap.apply(tp) - } catch { - case ex: Type$Error => - if ((mode & EXPRmode) != 0 && infer.isFullyDefined(pt)) pt - else { - error(pos, ex.msg + " as part of " + tp.unalias()); - Type.ErrorType - } - } - } - - /** Check that there are no dependent parameter types among parameters. - * - * @param vparams - */ - def checkNoEscapeParams(vparams: Array[Array[Tree.ValDef]]): Unit = { - var i = 0; while (i < vparams.length) { - var j = 0; while (j < vparams(i).length) { - checkNoEscape(vparams(i)(j).pos, vparams(i)(j).tpe.getType()); - j = j + 1 - } - i = i + 1 - } - } - - /** Check that tree represents a legal trait definition. - * - * @param pos - * @param clazz - * @param templ - */ - def checkTraitDef(pos: Int, clazz: Symbol, templ: Tree.Template): Unit = { - - /** Check that type does not have value parameters - */ - def checkNoParams(tpe: Type): Unit = tpe match { - case Type$MethodType(vparams, _) => - if (vparams.length > 0) - error(pos, "trait may not have value parameters") - case Type$PolyType(tparams, restpe) => - checkNoParams(infer.skipViewParams(tparams, restpe)) - case _ => - } - - /** Check that tree represents a pure constructor. - */ - def checkPureConstr(tree: Tree): Unit = { - if (!TreeInfo.isPureConstr(tree) && !tree.getType().isError()) - error(tree.pos, "" + clazz + " may invoke only pure superclass constructors"); - } - - /** Check that tree refers to a trait - */ - def checkTraitRef(tree: Tree): Unit = { - if (!tree.getType().symbol().isTrait() && !tree.getType().isError()) - error(tree.pos, " " + clazz + " may inherit only traits as mixins"); - } - - /** Check that tree represents a pure definition. - */ - def checkPureDef(tree: Tree): unit = { - if (!TreeInfo.isPureDef(tree) && !tree.getType().isError()) - error(tree.pos, "" + clazz + " may contain only pure definitions"); - } - - checkNoParams(clazz.primaryConstructor().getType()); - var i = 0; while (i < templ.parents.length) { - checkPureConstr(templ.parents(i)); - if (i >= 1) checkTraitRef(templ.parents(i)); - i = i + 1 - } - var j = 0; while (j < templ.body.length) { - checkPureDef(templ.body(j)); - j = j + 1 - } - } - - /** Check that tree is a stable expression .p - * - * @param tree - * @return the validated tree - */ - def checkStable(tree: Tree): Tree = - if (TreeInfo.isPureExpr(tree) || tree.getType().isError()) tree; - else { - error(tree.pos, "stable identifier required, but " + tree + " found."); - errorTermTree(tree); - } - - /** Check that class can be instantiated. - * - * @param pos - * @param tp - */ - def checkInstantiatable(pos: Int, tp: Type): Unit = { - val clazz: Symbol = tp.symbol(); - if (clazz.kind == CLASS) { - if (clazz.isAbstractClass()) - error(pos, "" + clazz + " is abstract, so it cannot be instantiated"); - else if (!tp.isSubType(tp.instanceType())) - error(pos, "" + tp + " does not conform to its self-type " + - tp.instanceType() + ", so it cannot be instantiated"); - } - } - - /** Check that all subtrees have their types defined. - * Used for asserting an internal invariant - */ - private class CheckDefined extends Traverser { - var all: Tree = null; - override def traverse(tree: Tree): unit = { - if (tree.getType() == null) assert(false, "" + tree + " in " + all); - if (!tree.getType().isError()) - super.traverse(tree); - } - } - - private val checkDefined: CheckDefined = new CheckDefined(); - - // Helper definitions for calculating types ----------------------------------------- - - /** The qualifier type of a potential application of the `match' method. - * or NoType, if this is something else. - */ - private def matchQualType(fn: Tree): Type = { - fn match { - case Tree.Select(qual, _) => - if (fn.symbol() == definitions.ANY_MATCH) - return qual.getType().widen(); - - case Tree.TypeApply(fn1, _) => - return matchQualType(fn1); - - case Tree.Ident(_) => - if (fn.symbol() == definitions.ANY_MATCH) - return context.enclClass.owner.typeOfThis(); - - case _ => - } - if (fn.getType().isError()) Type.ErrorType else Type.NoType - } - - private def isSetterMethod(sym: Symbol): boolean = - sym != null && - !sym.isLocal() && - !sym.isStable() && - sym.getType().isInstanceOf[Type$PolyType] && - sym.typeParams().length == 0; - - /** - * Returns true if the adaption 'from => to' corresponds to a delegate - * forward view. - * - * TODO: The check should probably be deeper than just for a function type - * because the user might introduce a view from a delegate type to a - * function type himself, which is okay as long as it doesn't collide with - * the forward view. - */ - private def isDelegateForwardView(from: Type, to: Type): boolean = - definitions.DELEGATE_TYPE() != null && - from.isSubType(definitions.DELEGATE_TYPE()) && - to.isFunctionType(); - -// Views ----------------------------------------------------------------------- - - private def applyView(v: View, tree: Tree, mode: int, pt: Type): Tree = { - val vexpr = infer.viewExpr(tree.pos, v); - val vapp = transform( - make.Apply(tree.pos, vexpr, NewArray.Tree(tree)), mode, pt); - if (v.symtype.isObjectType()) { - val tree1 = gen.mkAsInstanceOf(tree.duplicate(), vapp.getType()); - gen.If( - gen.Apply( - gen.Select( - vexpr.duplicate(), - definitions.ANY_EQEQ), - NewArray.Tree(gen.mkNullLit(tree.pos))), - tree1, - vapp) - } else vapp - } - -// Contexts ------------------------------------------------------------------ - - /** Push new context associated with given tree, owner, and scope on stack. - */ - def pushContext(tree: Tree, owner: Symbol, scope: Scope): Context = { - val prevContext = context; - context = new Context(tree, owner, scope, context); - prevContext - } - -// Lazy Types ---------------------------------------------------------------- - - /** A lazy type which, when forced returns the type of a symbol defined - * in `tree'. - */ - class LazyTreeType(_tree: Tree) extends Type$LazyType { - val tree: Tree = _tree; - val u: CompilationUnit = unit; - val c: Context = context; - - override def complete(sym: Symbol): unit = { - defineSym(tree, u, c); - } - } - - /** A lazy type for case constructor methods (whose name is a term name) - * which sets the method's type to the class constructor type. - */ - class LazyConstrMethodType(_tree: Tree) extends LazyTreeType(_tree) { - override def complete(sym: Symbol): unit = { - val constr: Symbol = tree.symbol().primaryConstructor(); - if (!sym.isInitialized()) - sym.setInfo(constr.getType().instanceType().cloneType(constr, sym)); - } - } - - /** A lazy type for self types - */ - class LazySelfType(clazz: Symbol, tree: Tree) extends LazyTreeType(tree) { - override def complete(sym: Symbol): unit = { - defineSelfType(sym, clazz, tree, u, c); - } - } - -// Entering Symbols ---------------------------------------------------------- - - def transformPackageId(tree: Tree): Tree = { - if (tree.getType() != null) return tree; - tree match { - case Tree.Ident(name) => - tree - .setSymbol(packageSymbol(tree.pos, context.owner, name)) - .setType(tree.symbol().getType()) - - case Tree.Select(qual, name) => - val qual1: Tree = transformPackageId(qual); - val sym: Symbol = packageSymbol(tree.pos, qual1.symbol().moduleClass(), name); - copy.Select(tree, sym, qual1).setType(sym.getType()) - - case _ => - transform(tree); - } - } - - def packageSymbol(pos: int, base: Symbol, name: Name): Symbol = { - var p: Symbol = base.members().lookup(name); - if (p.isNone()) { - p = base.newPackage(pos, name); - base.members().enterNoHide(p); - } else if (p.isPackage()) { - // as the package is used, we change its position to make sure - // its symbol is not reused for a module definition with the - // same name - p.pos = Position.FIRSTPOS; - p.moduleClass().pos = Position.FIRSTPOS; - } else { - val dst = if ((p.flags & CASE) != 0) "case class " + name; - else "" + p; - error(pos, "package " + name + " has the same name as existing " + dst); - p = base.newPackage(pos, name); - } - p - } - - def moduleSymbol(pos: int, name: Name, owner: Symbol, flags: int, scope: Scope): Symbol = { - val symbol = termSymbolOrNone(scope, pos, name, flags | MODUL | FINAL); - if (symbol.isNone()) owner.newModule(pos, flags, name) else symbol; - } - - def termSymbol(pos: int, name: Name, owner: Symbol, flags: int, scope: Scope): Symbol = { - val symbol = termSymbolOrNone(scope, pos, name, flags); - if (symbol.isNone()) owner.newTerm(pos, flags, name) else symbol - } - - def classSymbol(pos: int, name: Name, owner: Symbol, flags: int, scope: Scope): Symbol = { - val symbol = typeSymbolOrNone(scope, pos, CLASS, name, flags); - if (symbol.isNone()) owner.newClass(pos, flags, name) else symbol - } - - def typeAliasSymbol(pos: int, name: Name, owner: Symbol, flags: int, scope: Scope): Symbol = { - val symbol = typeSymbolOrNone(scope, pos, ALIAS, name, flags); - if (symbol.isNone()) owner.newTypeAlias(pos, flags, name) else symbol - } - - def absTypeSymbol(pos: int, name: Name, owner: Symbol, flags: int, scope: Scope): Symbol = { - val symbol = typeSymbolOrNone(scope, pos, TYPE, name, flags); - if (symbol.isNone()) owner.newAbstractType(pos, flags, name) else symbol - } - - def termSymbolOrNone(scope: Scope, pos: int, name: Name, flags: int): Symbol = { - var symbol = getDefinedSymbol(scope, VAL, name); - if (!symbol.isNone()) { - if (symbol.isInitialized()) { - symbol.getType() match { - case Type$OverloadedType(alts, _) => - var i = 0; - while (i < alts.length && !alts(i).isExternal()) i = i + 1; - if (i == alts.length) - throw Debug.abort("missing alternative", Debug.show(symbol)); - if (i == alts.length - 1) symbol.pos = pos; - symbol = alts(i); - case _ => - } - } - updateFlagsAndPos(symbol, pos, flags); - } - symbol - } - - def typeSymbolOrNone(scope: Scope, pos: int, kind: int, name: Name, flags: int): Symbol = { - val symbol = getDefinedSymbol(scope, kind, name); - if (!symbol.isNone()) { - updateFlagsAndPos(symbol, pos, flags); - symbol.allConstructors().pos = pos; - } - symbol - } - - def getDefinedSymbol(scope: Scope, kind: int, name: Name): Symbol = { - val entry = scope.lookupEntry(name); - val symbol = entry.sym; - if (entry.owner == scope && symbol.isExternal() && symbol.kind == kind) { - symbol - } else { - Symbol.NONE; - } - } - - def updateFlagsAndPos(symbol: Symbol, pos: int, flags: int): unit = { - symbol.pos = pos; - val oldflags = symbol.flags & (INITIALIZED | LOCKED); - val newflags = flags & ~(INITIALIZED | LOCKED); - symbol.flags = oldflags | newflags; - if (symbol.isModule()) { - // here we repeat what is done in the constructor of ModuleClassSymbol - val clasz = symbol.moduleClass(); - val classFlags = (flags & MODULE2CLASSFLAGS) | MODUL | FINAL; - updateFlagsAndPos(clasz, pos, classFlags); - clasz.primaryConstructor().flags = - clasz.primaryConstructor().flags | PRIVATE; - } - if (symbol.isType()) { - // here we repeat what is done in the constructor of TypeSymbol - val constr = symbol.primaryConstructor(); - val constrFlags = flags & CONSTRFLAGS; - updateFlagsAndPos(constr, pos, constrFlags); - } - } - - /** Enter symbol `sym' in current scope. Check for double definitions. - * Handle overloading. - * - * @param sym - */ - def enterInScope(sym: Symbol): Unit = { - - def covers(presym: Symbol, newsym: Symbol) = { - if (presym == newsym) true - else if (!presym.isInitialized()) false - else presym.getType() match { - case Type$OverloadedType(alts, _) => - var i = 0; - while (i < alts.length && alts(i) != newsym) i = i + 1; - i < alts.length - case _ => - false - } - } - - // handle double and overloaded definitions - val e: Scope$Entry = context.scope.lookupEntry(sym.name); - val other: Symbol = e.sym; - if (covers(other, sym)) { - if (global.debug) global.log("redefined: " + sym + ":" + sym.rawInfo()); - } else if (e.owner == context.scope) { - assert(!other.isExternal(), other); - if (sym.owner().isPackageClass()) { - if (other.isPackage()) { - val src = if ((sym.flags & CASE) != 0) "case class " + sym.name; - else "" + sym; - error(sym.pos, "" + src + " has the same name as existing " + other); - } else { - if (global.compiledNow.get(other) != null) { - error(sym.pos, "" + sym + " is compiled twice"); - } - context.scope.unlink(e); - context.scope.enter(sym); - } - } else if (context.owner.kind == CLASS && - sym.kind == VAL && other.kind == VAL && - ((sym.flags & ACCESSOR) == 0 || (other.flags & ACCESSOR) == 0) - || - (sym.name == Names.view && - (sym.flags & (PARAM | SYNTHETIC)) == (PARAM | SYNTHETIC))) { - e.setSymbol(other.overloadWith(sym)); - } else if (context.owner.kind == CLASS) - error(sym.pos, - sym.nameString() + " is already defined as " + - other + other.locationString()); - else - error(sym.pos, - sym.nameString() + - " is already defined in local scope"); - } else { - context.scope.enter(sym); - } - if (sym.owner().isPackageClass()) - global.compiledNow.put(sym, unit.source); - } - - def outerEnterSym(tree: Tree): Symbol = enterSym(tree); - - /** If `tree' is a definition, create a symbol for it with a lazily - * constructed type, and enter into current scope. - */ - def enterSym(tree: Tree): Symbol = { - - /** Enter `sym' in current scope and make it the symbol of `tree'. - */ - def enterSym(tree: Tree, sym: Symbol): Symbol = { - //if (global.debug) System.out.println("entering " + sym);//DEBUG - if (!sym.isInitialized()) { - sym.setInfo(new LazyTreeType(tree)); - } - if (!sym.isConstructor()) { - val owner: Symbol = sym.owner(); - if (sym.kind == VAL && (sym.flags & (PRIVATE | SEALED)) == 0 && - owner != null && owner.kind == CLASS && - (owner.flags & FINAL) != 0) - sym.flags = sym.flags | FINAL; - enterInScope(sym); - } - tree.setSymbol(sym); - sym - } - - /** Make `sym' the symbol of import `tree' and push an - * import context. - * - * @param tree - * @param sym - * @return - */ - def enterImport(tree: Tree, sym: Symbol): Symbol = { - sym.setInfo(new LazyTreeType(tree)); - tree.setSymbol(sym); - pushContext(tree, context.owner, context.scope); - sym - } - - val owner: Symbol = context.owner; - tree match { - case Tree.PackageDef(_packaged, templ) => - var packaged = _packaged; - templ match { - case Tree.Template(_, body) => - val prevContext = pushContext(tree, context.owner, context.scope); - packaged = transformPackageId(packaged); - tree.asInstanceOf[Tree.PackageDef].packaged = packaged; - context = prevContext; - val pkg: Symbol = checkStable(packaged).symbol(); - if (pkg != null && !pkg.isError()) { - if (pkg.isPackage()) { - val prevContext = pushContext(templ, pkg.moduleClass(), pkg.members()); - enterSyms(body); - context = prevContext; - } else { - error(tree.pos, "only Java packages allowed for now"); - } - } - templ.setSymbol(Symbol.NONE); - null - case _ => - throw new ApplicationError(); - } - - case Tree.Attributed(attr, definition) => - outerEnterSym(definition); - - case Tree.DocDef(comment, definition) => - val sym = outerEnterSym(definition); - global.mapSymbolComment.put(sym, new Pair(comment, unit)); - sym - - case Tree.ClassDef(mods, name, tparams, vparams, _, templ) => - val clazz = - if (mods == SYNTHETIC && name == Names.ANON_CLASS_NAME.toTypeName()) - context.owner.newAnonymousClass(templ.pos, name) - else - classSymbol(tree.pos, name, owner, mods, context.scope); - clazz.setOrigin(SymbolOrigin.ScalaUnit(unit)); - if (!clazz.primaryConstructor().isInitialized()) - clazz.primaryConstructor().setInfo(new LazyTreeType(tree)); - if ((mods & CASE) != 0) { - if ((mods & ABSTRACT) == 0) { - // enter case constructor method. - val cf: Symbol = termSymbol( - tree.pos, name.toTermName(), owner, - mods & ACCESSFLAGS | CASE, context.scope); - enterInScope(cf); - if (!cf.isInitialized() || cf.info().symbol().isModuleClass()) { - cf.setInfo(new LazyConstrMethodType(tree)); - } - } - } - enterSym(tree, clazz) - - case Tree.ModuleDef(mods, name, _, _) => - var modul = moduleSymbol(tree.pos, name, owner, mods, context.scope); - if (!modul.isPackage() || modul.getOrigin() == SymbolOrigin.Unknown) - modul.moduleClass().setOrigin(SymbolOrigin.ScalaUnit(unit)); - val clazz: Symbol = modul.moduleClass(); - if (!clazz.isInitialized()) { - val info = new LazyTreeType(tree); - clazz.setInfo(info); - modul.setInfo(info); - } - enterSym(tree, modul) - - case Tree.ValDef(mods, name, _, _) => - enterSym(tree, termSymbol(tree.pos, name, owner, mods, context.scope)) - - case Tree.DefDef(mods, name, _, _, _, _) => - var sym: Symbol = null; - if (name == Names.CONSTRUCTOR) { - var c = context; - while (c.isImportContext) c = c.outer; - val clazz: Symbol = c.enclClass.owner; - if (!(c.tree.isInstanceOf[Tree.Template]) || - clazz.isModuleClass() || - clazz.isAnonymousClass() || - clazz.isCompoundSym() || - clazz.isPackageClass()) - error(tree.pos, "constructor definition not allowed here"); - sym = clazz.newConstructor(tree.pos, clazz.flags & CONSTRFLAGS); - clazz.addConstructor(sym); - sym.flags = sym.flags | mods; - } else { - sym = termSymbol(tree.pos, name, owner, mods, context.scope); - } - enterSym(tree, sym); - - case Tree.AliasTypeDef(mods, name, _, _) => - val tsym: Symbol = typeAliasSymbol(tree.pos, name, owner, mods, context.scope); - if (!tsym.primaryConstructor().isInitialized()) - tsym.primaryConstructor().setInfo(new LazyTreeType(tree)); - enterSym(tree, tsym) - - case Tree.AbsTypeDef(mods, name, _, _) => - enterSym( - tree, - absTypeSymbol(tree.pos, name, owner, mods, context.scope)) - - case Tree.Import(expr, selectors) => - enterImport(tree, - Symbol.NONE.newTerm( - tree.pos, SYNTHETIC, Name.fromString("import " + expr))) - - case _ => - null - } - } - - /** Enter all symbols in statement list - */ - def enterSyms(stats: Array[Tree]): unit = { - var i = 0; while (i < stats.length) { - stats(i) = desugarize.Definition(stats(i)); - enterSym(stats(i)); - i = i + 1 - } - } - - def enterParams[t <: Tree](params: Array[t]): Array[Symbol] = { - var i = 0; while (i < params.length) { - enterSym(params(i)); - (params(i) : Tree) match { - case Tree.ValDef(mods, _, _, _) => - if ((mods & REPEATED) != 0 && i != params.length - 1) - error(params(i).pos, - "`*' parameter must be the last parameter of a `('...`)' section"); - case _ => - } - i = i + 1 - } - Tree.symbolOf(params.asInstanceOf[Array[Tree]]) - } - - def enterParams(vparams: Array[Array[Tree.ValDef]]): Array[Array[Symbol]] = { - val vparamSyms = new Array[Array[Symbol]](vparams.length); - var i = 0; while (i < vparams.length) { - vparamSyms(i) = enterParams(vparams(i)); - i = i + 1 - } - vparamSyms - } - - /** Re-enter type parameters in current scope. - * - * - */ - def reenterParams(tparams: Array[Tree.AbsTypeDef], tsyms: Array[Symbol]): unit = { - var i = 0; while (i < tparams.length) { - tsyms(i).pos = tparams(i).pos; - tsyms(i).name = tparams(i).name; - //necessary since tsyms might have been unpickled - tparams(i).setSymbol(tsyms(i)); - context.scope.enter(tsyms(i)); - i = i + 1 - } - } - - /** Re-enter type and value parameters in current scope. - */ - def reenterParams(tparams: Array[Tree.AbsTypeDef], vparamss: Array[Array[Tree.ValDef]], mt: Type): unit = { - var rest: Type = mt; - rest match { - case Type$PolyType(tsyms, restp) => - reenterParams(tparams, tsyms); - rest = restp; - case _ => - } - var j = 0; while (j < vparamss.length) { - val vparams = vparamss(j); - rest match { - case Type$MethodType(vsyms, restp) => - var i = 0; while (i < vparams.length) { - vsyms(i).pos = vparams(i).pos; - vsyms(i).name = vparams(i).name; - //necessary since vsyms might have been unpickled - vparams(i).setSymbol(vsyms(i)); - //potential overload in case this is a view parameter - context.scope.enterOrOverload(vsyms(i)); - i = i + 1 - } - rest = restp; - case _ => - } - j = j + 1 - } - } - - def addInheritedOverloaded(sym: Symbol, tp: Type): unit = - if (sym.owner().kind == CLASS && - !sym.isConstructor() && - sym.owner().lookup(sym.name) == sym) - // it's a class member which is not an overloaded alternative - sym.addInheritedOverloaded(tp); - -// Definining Symbols ------------------------------------------------------- - - /** Define symbol associated with `tree' using given `unit' and `context'. - */ - def defineSym(tree: Tree, unit: CompilationUnit, curcontext: Context): unit = { - val savedUnit: CompilationUnit = this.unit; - this.unit = unit; - val savedContext: Context = this.context; - this.context = curcontext; - val savedMode: int = this.mode; - this.mode = EXPRmode; - val savedPt: Type = this.pt; - this.pt = Type.AnyType; - - try { - val sym: Symbol = tree.symbol(); - if (global.debug) global.log("defining " + sym); - var owntype: Type = null; - tree match { - case Tree.ClassDef(mods, name, tparams, vparams, tpe, templ) => - val prevContext = pushContext( - tree, sym.primaryConstructor(), new Scope(context.scope)); - val tparamSyms = enterParams(tparams); - var vparamSyms = enterParams(vparams); - if (vparamSyms.length == 0) { - vparamSyms = NewArray.SymbolArray{Symbol.EMPTY_ARRAY}; - } else if (infer.isViewBounded(tparamSyms) && vparamSyms.length == 1) { - val vparamSyms1 = new Array[Array[Symbol]](2); - vparamSyms1(0) = vparamSyms(0); - vparamSyms1(1) = Symbol.EMPTY_ARRAY; - vparamSyms = vparamSyms1 - } - if (vparams.length > 0) - templ.body = desugarize.addParamAccessors( - templ.body, vparams(vparams.length - 1)); - - val constrtype: Type = makeMethodType( - tparamSyms, - vparamSyms, - Type.typeRef(sym.owner().thisType(), sym, Symbol.getType(tparamSyms))); - //System.out.println("set info " + sym.constructor() + " to " + constrtype + " was " + sym.constructor().rawInfo());//DEBUG - sym.primaryConstructor().setInfo(constrtype); - // necessary so that we can access tparams - sym.primaryConstructor().flags = - sym.primaryConstructor().flags | INITIALIZED; - - if (tpe != Tree.Empty) - sym.setTypeOfThis(new LazySelfType(sym, tpe)); - - defineTemplate(templ, sym, new Scope()); - owntype = templ.getType(); - context = prevContext; - - case Tree.ModuleDef(mods, name, _tpe, templ) => - var tpe = _tpe; - val clazz: Symbol = sym.moduleClass(); - val prevContext = pushContext( - tree, clazz.primaryConstructor(), context.scope); - defineTemplate(templ, clazz, new Scope()); - context = prevContext; - clazz.setInfo(templ.getType()); - tpe = transform(tpe, TYPEmode); - (tree.asInstanceOf[Tree.ModuleDef]).tpe = tpe; - if (tpe != Tree.Empty) - clazz.setTypeOfThis(new LazySelfType(sym, tpe)); - owntype = if (tpe == Tree.Empty) clazz.getType() else tpe.getType(); - - case Tree.DefDef(mods, name, tparams, vparams, _tpe, _rhs) => - var tpe = _tpe; - var rhs = _rhs; - var restype: Type = null; - val prevContext = pushContext(tree, sym, new Scope(context.scope)); - val tparamSyms = enterParams(tparams); - val vparamSyms = enterParams(vparams); - if (tpe != Tree.Empty) { - tpe = transform(tpe, TYPEmode); - (tree.asInstanceOf[Tree.DefDef]).tpe = tpe; - restype = tpe.getType(); - } else if (name == Names.CONSTRUCTOR) { - if (context.enclClass.owner.typeParams().length != 0) - error(tree.pos, "secondary constructors for parameterized classes not yet implemented"); - restype = context.enclClass.owner.getType();/*.subst( - context.enclClass.owner.typeParams(), tparamSyms)*/; - } else { - if (sym.hasParamAccessorFlag()) { - rhs.setType(rhs.symbol().getType()); - } else { - rhs = transform(rhs, EXPRmode); - (tree.asInstanceOf[Tree.DefDef]).rhs = rhs; - } - restype = rhs.getType(); - if (!sym.isFinal()) restype = restype.deconst(); - } - restype = checkNoEscape(tpe.pos, restype); - if (name == Names.view && - infer.containsSymbol(tparamSyms, restype.symbol())) { - error(tree.pos, "result type of view may not be a type variable"); - restype = definitions.ANY_TYPE(); - } - context = prevContext; - - owntype = makeMethodType(tparamSyms, vparamSyms, restype); - //System.out.println("methtype " + name + ":" + owntype);//DEBUG - addInheritedOverloaded(sym, owntype); - - case Tree.ValDef(mods, name, _tpe, _rhs) => - var tpe = _tpe; - var rhs = _rhs; - if (tpe != Tree.Empty) { - tpe = transform(tpe, TYPEmode); - (tree.asInstanceOf[Tree.ValDef]).tpe = tpe; - owntype = tpe.getType(); - } else { - val prevContext = pushContext(tree, sym, context.scope); - if (rhs == Tree.Empty) { - if (sym.owner().isAccessor()) { - // this is the parameter of a variable setter method. - assert(sym.isParameter()); - owntype = sym.owner().accessed().getType(); - } else { - error(tree.pos, "missing parameter type"); - owntype = Type.ErrorType; - } - } else { - rhs = transform(rhs, EXPRmode); - (tree.asInstanceOf[Tree.ValDef]).rhs = rhs; - owntype = rhs.getType(); - if (sym.isVariable() || !sym.isFinal()) - owntype = owntype.deconst(); - } - context = prevContext; - addInheritedOverloaded(sym, owntype); - } - - case Tree.AliasTypeDef(mods, name, tparams, _rhs) => - var rhs = _rhs; - val prevContext = - pushContext(tree, sym.primaryConstructor(), new Scope(context.scope)); - val tparamSyms = enterParams(tparams); - rhs = transform(rhs, TYPEmode); - (tree.asInstanceOf[Tree.AliasTypeDef]).rhs = rhs; - owntype = rhs.getType(); - sym.primaryConstructor().setInfo( - new Type$PolyType(tparamSyms, owntype)); - context = prevContext; - - case Tree.AbsTypeDef(mods, name, _rhs, _lobound) => - var rhs = _rhs; - var lobound = _lobound; - //can't have `sym' as owner since checkNonCyclic would fail. - rhs = transform(rhs, TYPEmode); - tree.asInstanceOf[Tree.AbsTypeDef].rhs = rhs; - lobound = transform(lobound, TYPEmode); - (tree.asInstanceOf[Tree.AbsTypeDef]).lobound = lobound; - if (sym.isViewBounded()) { - sym.setVuBound(rhs.getType()); - owntype = definitions.ANY_TYPE(); - } else { - owntype = rhs.getType(); - } - sym.setLoBound(lobound.getType()); - owntype.symbol().initialize();//to detect cycles todo: needed? - - case Tree.Import(_expr, selectors) => - val expr = transform(_expr, EXPRmode | QUALmode); - tree.asInstanceOf[Tree.Import].expr = expr; - checkStable(expr); - owntype = expr.getType(); - val tp: Type = owntype.widen(); - { var i = 0; while (i < selectors.length) { - if (selectors(i) != Names.IMPORT_WILDCARD && - tp.lookup(selectors(i)) == Symbol.NONE && - tp.lookup(selectors(i).toTypeName()) == Symbol.NONE) - error(tree.pos, "" + NameTransformer.decode(selectors(i)) + " is not a member of " + expr); - i = i + 2 - }} - case _ => - throw new ApplicationError(); - } - sym.setInfo(owntype); - validate(sym); - if (global.debug) global.log("defined " + sym); - } catch { - case ex: Type$Error => - reportTypeError(tree.pos, ex); - setError(tree); - if (tree.hasSymbol()) { - tree.symbol().setInfo(Type.ErrorType); - } - } - - this.unit = savedUnit; - this.context = savedContext; - this.mode = savedMode; - this.pt = savedPt; - } - - /** Definition phase for a template. This enters all symbols in template - * into symbol table. - */ - def defineTemplate(templ: Tree.Template, clazz: Symbol, members: Scope): Unit = { - // attribute parent constructors - templ.parents = transformConstrInvocations(templ.pos, templ.parents); - if (templ.parents.length > 0 && - (templ.parents(0).getType().symbol().flags & (JAVA | INTERFACE)) == (JAVA | INTERFACE)) { - val constrs1 = new Array[Tree](templ.parents.length + 1); - constrs1(0) = gen.mkApply__( - gen.mkPrimaryConstructorGlobalRef( - templ.parents(0).pos, definitions.OBJECT_CLASS)); - System.arraycopy(templ.parents, 0, constrs1, 1, templ.parents.length); - templ.parents = constrs1; - } - val parents = Tree.typeOf(templ.parents); - - // enter all members - val prevContext = pushContext(templ, clazz, members); - templ.body = desugarize.Statements(unit, templ.body, false); - enterSyms(templ.body); - context = prevContext; - templ.setType(Type.compoundType(parents, members, clazz)); - } - - def makeMethodType(tparams: Array[Symbol], vparams: Array[Array[Symbol]], restpe: Type): Type = - if (tparams.length == 0 && vparams.length == 0) { - new Type$PolyType(tparams, restpe); - } else { - var result: Type = restpe; - var i = vparams.length - 1; - while (i >= 0) { - result = new Type$MethodType(vparams(i), result); - i = i - 1; - } - if (tparams.length != 0) - result = new Type$PolyType(tparams, result); - result - } - - /** Define self type of class or module `sym' - * associated with `tree' using given `unit' and `context'. - * - * @param sym - * @param clazz - * @param tree - * @param unit - * @param curcontext - */ - def defineSelfType(sym: Symbol, clazz: Symbol, tree: Tree, unit: CompilationUnit, curcontext: Context): Unit = { - val savedUnit: CompilationUnit = this.unit; - this.unit = unit; - val savedContext: Context = this.context; - this.context = curcontext; - - val selftype: Type = transform(tree, TYPEmode).getType(); - //todo: can we really make a compound type with class - val selftype1: Type = - if (clazz.getType().isSubType(selftype)) - clazz.getType() - else if (selftype.isSubType(clazz.getType())) - selftype - else if (selftype.isSingletonType() && selftype.singleDeref().symbol().isSubClass(clazz)) - selftype - else - selftype match { - case Type$CompoundType(parts, members) => - val parts1 = new Array[Type](parts.length + 1); - System.arraycopy(parts, 0, parts1, 0, parts.length); - parts1(parts.length) = clazz.getType(); - Type.compoundTypeWithOwner(clazz.owner().enclClass(), parts1, members); - - case _ => - Type.compoundTypeWithOwner( - clazz.owner().enclClass(), NewArray.Type(selftype, clazz.getType()), Scope.EMPTY); - } - if (global.debug) global.log("assigning self type " + selftype1); - sym.setInfo(selftype1); - - this.unit = savedUnit; - this.context= savedContext; - } - -// Attribution and Transform ------------------------------------------------- - - /** Turn tree type into stable type if possible and required by - * context. - */ - def mkStable(tree: Tree, pre: Type, mode: int, pt: Type): Tree = { - tree.getType() match { - case Type$ConstantType(_, value) => - return make.Literal(tree.pos, value).setType(tree.getType()) - case Type$PolyType(tparams, restp) => - if (tparams.length == 0) { - restp match { - case Type$ConstantType(_, value) => - return make.Literal(tree.pos, value).setType(tree.getType()); - case _ => - } - } - case _ => - } - if ((pt != null && pt.isStable() || - (mode & QUALmode) != 0 || - tree.getType().symbol().isModuleClass()) && - (pre != null) && pre.isStable()) { - var sym: Symbol = tree.symbol(); - tree.getType() match { - case Type$OverloadedType(alts, alttypes) => - if ((mode & FUNmode) == 0) { - try { - infer.exprAlternative(tree, alts, alttypes, pt); - sym = tree.symbol(); - } catch { - case ex: Type$Error => - reportTypeError(tree.pos, ex); - } - } - case _ => - } - if (sym.isStable()) { - tree.setType(Type.singleType(pre, sym)); - } - } - tree - } - - /** The qualifying class of a this or super - */ - def qualifyingClass(tree: Tree, name: Name): Symbol = { - if (name == TypeNames.EMPTY) { - val clazz: Symbol = context.enclClass.owner; - if (clazz != null) - clazz - else { - error(tree.pos, "" + tree + - " can be used only in a class, object, or template"); - Symbol.NONE - } - } else { - var i: Context = context; - while (i != Context.NONE && - !(i.owner.kind == CLASS && i.owner.name == name)) - i = i.outer.enclClass; - if (i != Context.NONE) - i.owner - else { - error(tree.pos, "" + name + " is not an enclosing class"); - Symbol.NONE - } - } - } - - /** Adapt tree to given mode and given prototype. - * - * @param tree - * @param mode - * @param pt - * @return - */ - def adapt(tree: Tree, mode: Int, pt: Type): Tree = { - //System.out.println(tree + ":" + tree.getType() + " adapt " + pt + " " + mode);//DEBUG - tree.getType() match { - case Type$OverloadedType(alts, alttypes) => - // resolve overloading - if ((mode & FUNmode) == 0) { - try { - infer.exprAlternative(tree, alts, alttypes, pt); - } catch { - case ex: Type$Error => - reportTypeError(tree.pos, ex); - } - tree.getType() match { - case Type$OverloadedType(_, _) => - // overload resolution failed bcs no alternative matched prototype. - typeError(tree.pos, tree.getType(), pt); - return errorTermTree(tree); - case _ => - } - return adapt(tree, mode, pt); - } - - case Type$PolyType(tparams, restp) => - // apply parameterless functions - // instantiate polymorphic expressions - if (tparams.length == 0) { - return adapt(constfold.tryToFold(tree.setType(restp)), mode, pt); - } else if ((mode & (FUNmode | POLYmode)) == 0) { - var tree1: Tree = null; - try { - tree1 = infer.exprInstance(tree, tparams, restp, pt); - } catch { - case ex: Type$Error => - error(tree.pos, ex.msg); - tree1 = errorTermTree(tree); - } - return adapt(tree1, mode, pt); - } - - case Type$MethodType(_, _) => - // convert unapplied methods to functions. - if ((mode & (EXPRmode | FUNmode)) == EXPRmode && - (infer.isCompatible(tree.getType(), pt))) { - checkEtaExpandable(tree.pos, tree.getType()); - if (TreeInfo.methPart(tree).symbol() == definitions.ANY_MATCH) { - error(tree.pos, "`match' needs to be applied fully"); - return errorTree(tree) - } else { - return transform(desugarize.etaExpand(tree, tree.getType()), mode, pt); - } - } else if ((mode & (CONSTRmode | FUNmode)) == CONSTRmode) { - error(tree.pos, "missing arguments for class constructor"); - return errorTermTree(tree); - } - - case _ => - } - if ((mode & PATTERNmode) != 0) { - if (tree.isType()) { - val clazz: Symbol = tree.getType().withDefaultArgs().unalias().symbol(); - - if (clazz.isCaseClass()) { - // set type to instantiated case class constructor - tree.setType(tree.getType().prefix().memberType(clazz.primaryConstructor())); - // MZ: this is a hack, but I didn't know how to do it better - if ((clazz.flags & (JAVA | CASE)) == (JAVA | CASE)) { - val altconstr = clazz.allConstructors().alternativeSymbols(); - tree.setType(tree.getType().prefix().memberType( - altconstr(altconstr.length - 1))); - } - tree.getType() match { - case Type$PolyType(tparams, restp) => - try { - infer.constructorInstance(tree, tparams, restp, pt); - //System.out.println("constr inst " + ArrayApply.toString(tparams) + restp + " against " + pt + " = " + tree.getType());//DEBUG - } catch { - case ex: Type$Error => - if (!pt.isError()) error(tree.pos, ex.msg); - setError(tree); - } - case _ => - } - } else if (clazz.isSubClass(definitions.SEQ_CLASS)) { - // set type to instantiated sequence class constructor - // todo: should we admit even supertypes of the target type? - val seqtp: Type = pt.baseType(clazz); - if (seqtp != Type.NoType) { - def seqConstructorType(paramtp: Type, resulttp: Type) = { - val constr: Symbol = resulttp.symbol().primaryConstructor(); - val param: Symbol = constr.newVParam( - tree.pos, REPEATED, Names.PATTERN_WILDCARD, - paramtp.baseType(definitions.SEQ_CLASS)); - new Type$MethodType(NewArray.Symbol(param), resulttp); - } - tree.setType(seqConstructorType(seqtp, pt)); - } else { - error(tree.pos, "expected pattern type " + pt + - " does not conform to sequence " + clazz); - return errorTermTree(tree); - } - } else if (!tree.getType().isError()) { - error(tree.pos, "" + tree.getType().symbol() + - " is neither a case class constructor nor a sequence class constructor"); - return errorTermTree(tree); - } - } - if ((mode & FUNmode) != 0) { - return tree; - } else { - val sym: Symbol = tree.symbol(); - // check that idents or selects are stable. - tree match { - case Tree.Ident(_) | Tree.Select(_, _) => - checkStable(tree); - case _ => - } - } - } else if ((mode & EXPRmode) != 0) { - if ((mode & FUNmode) != 0) { - if (tree.getType().isObjectType()) { - // insert apply method - val applyMeth: Symbol = tree.getType().lookup(Names.apply); - if (applyMeth != Symbol.NONE) { - val applyType: Type = infer.checkAccessible( - tree.pos, applyMeth, tree.getType().memberType(applyMeth), - tree, tree.getType()); - val tree1 = make.Select(tree.pos, tree, Names.apply) - .setSymbol(applyMeth) - .setType(applyType); - return adapt(tree1, mode, pt); - } - } - } else if ((mode & QUALmode) == 0) { - // check that packages and static modules are not used as values - tree match { - case Tree.Ident(_) | Tree.Select(_, _) => - val sym: Symbol = tree.symbol(); - if (sym != null && !sym.isError() && !sym.isValue()) { - error(tree.pos, "" + tree.symbol() + " is not a value"); - return errorTermTree(tree); - } - case _ => - } - } - } - - var owntype: Type = tree.getType(); - if ((mode & (CONSTRmode | FUNmode)) == (CONSTRmode) && pt != Type.AnyType) { - owntype = owntype.instanceType(); - // this works as for superclass constructor calls the expected - // type `pt' is always AnyType (see transformConstrInvocations). - } - if (!(owntype.isInstanceOf[Type$PolyType] || owntype.isSubType(pt))) { - tree match { - case Tree.Literal(constant) => - var n: int = constant match { - case AConstant$INT(value) => value - case AConstant$CHAR(value) => value - case _ => Integer.MAX_VALUE - } - val value1: AConstant = - if (pt.symbol() == definitions.BYTE_CLASS && -128 <= n && n <= 127) - AConstant.BYTE(n.asInstanceOf[byte]) - else if (pt.symbol() == definitions.SHORT_CLASS && -32768 <= n && n <= 32767) - AConstant.SHORT(n.asInstanceOf[short]) - else if (pt.symbol() == definitions.CHAR_CLASS && 0 <= n && n <= 65535) - AConstant.CHAR(n.asInstanceOf[char]) - else null; - if (value1 != null) - return gen.Literal(tree.pos, value1); - case _ => - } - if ((mode & EXPRmode) != 0) { - if (pt.isInstanceOf[Type$TypeRef] && pt.symbol() == definitions.UNIT_CLASS && tree.getType().isSubType(definitions.ANY_TYPE())) { - return gen.mkUnitBlock(tree); - } else if (infer.isCompatible(tree.getType(), pt)) { - tree match { - case Tree.Literal(value) => - val value1 = constfold.cast(value, pt); - if (value1 != null) - return adapt(gen.Literal(tree.pos, value1), mode, pt); - case _ => - } - val v = infer.bestView(tree.getType(), pt, Names.EMPTY); - // Convert views of delegate types to closures wrapped around - // the expression's apply method. - if(global.target == scalac_Global.TARGET_MSIL && - v != null && isDelegateForwardView(tree.getType(), pt)) { - val meth: Symbol = tree.symbol().lookup(Names.apply); - return adapt(gen.Select(tree, meth), mode, pt); - } - if (v != null) return applyView(v, tree, mode, pt); - // todo: remove - val coerceMeth: Symbol = tree.getType().lookup(Names.coerce); - if (coerceMeth != Symbol.NONE) { - val coerceType = infer.checkAccessible( - tree.pos, coerceMeth, tree.getType().memberType(coerceMeth), - tree, tree.getType()); - val tree1 = make.Select(tree.pos, tree, Names.coerce) - .setSymbol(coerceMeth) - .setType(coerceType); - return adapt(tree1, mode, pt); - } - } - } - if ((mode & CONSTRmode) == 0) { - typeError(tree.pos, owntype, pt); - Type.explainTypes(owntype, pt); - setError(tree); - } // for constructors, delay until after the `new'. - } - tree - } - - /** Attribute an identifier consisting of a simple name or an outer reference. - * @param tree The tree representing the identifier. - * @param name The name of the identifier. - */ - def transformIdent(_tree: Tree, name: Name): Tree = { - var tree = _tree; - //System.out.println("transforming " + name);//DEBUG - // find applicable definition and assign to `sym' - var sym: Symbol = Symbol.NONE; - var pre: Type = null; - var qual: Tree = Tree.Empty; - var stopPos: int = Integer.MIN_VALUE; - var nextcontext: Context = context; - while (sym.kind == NONE && nextcontext != Context.NONE) { - sym = nextcontext.scope.lookup(name); - if (sym.kind != NONE) { - stopPos = sym.pos; - } else { - nextcontext = nextcontext.enclClass; - if (nextcontext != Context.NONE) { - sym = nextcontext.owner.typeOfThis().lookup(name); - if (sym.kind != NONE) { - stopPos = nextcontext.owner.pos; - } else { - nextcontext = nextcontext.outer; - } - } - } - } - - if (stopPos > tree.pos) { - // set stopPos to beginning of block enclosed in the scope which defines the - // referenced symbol. - var lastc = Context.NONE; - var c = nextcontext; - while (c.outer.scope != null && c.outer.scope.lookup(name) == sym) { - c.tree match { - case Tree.Block(_, _) | Tree.CaseDef(_, _, _) | Tree.ClassDef(_, _, _, _, _, _) | Tree.ModuleDef(_, _, _, _) => - lastc = c; - case _ => - } - c = c.outer - } - if (lastc != Context.NONE) { - //System.out.println("revising stop to [" + lastc.tree + "]; symbol = " + sym + ", context = " + nextcontext);//DEBUG - stopPos = lastc.tree.pos; - } - } - - var impcontext: Context = context.prevImport; - var lastimpcontext: Context = null; - var sym1: Symbol = Symbol.NONE; - while (sym1.kind == NONE && impcontext != Context.NONE && impcontext.tree.pos > stopPos) { - sym1 = impcontext.importedSymbol(name); - lastimpcontext = impcontext; - impcontext = impcontext.outer.prevImport; - } - - // evaluate what was found - if (sym1.kind == NONE) { - if (sym.kind == NONE) { - //System.out.println(name);//DEBUG - error(tree.pos, "not found: " + decode(name)); - return errorTree(tree); - } else { - if (sym.owner().kind == CLASS) { - pre = nextcontext.enclClass.owner.thisType(); - if (!sym.owner().isPackageClass()) { - val qual1: Tree = gen.This(tree.pos, nextcontext.enclClass.owner); - tree = make.Select(tree.pos, qual1, name); - //System.out.println(name + " :::> " + tree + " " + qual1.symbol());//DEBUG - } - } else { - pre = Type.NoPrefix; - } - } - } else if (sym.kind != NONE && !sym.isExternal()) { - error(tree.pos, - "reference to " + name + " is ambiguous;\n" + - "it is both defined in " + sym.owner() + - " and imported subsequently by \n" + lastimpcontext.tree); - return errorTree(tree); - } else { - // check that there are no other applicable imports in same scope. - while (impcontext != Context.NONE && impcontext.scope == lastimpcontext.scope) { - if (!impcontext.sameImport(lastimpcontext) && impcontext.importedSymbol(name).kind != NONE) { - error(tree.pos, - "reference to " + name + " is ambiguous;\n" + - "it is imported twice in the same scope by\n " + - lastimpcontext.tree + "\nand " + impcontext.tree); - return errorTree(tree); - } - impcontext = impcontext.outer.prevImport; - } - sym = sym1; - qual = lastimpcontext.importPrefix().duplicate(); - pre = qual.getType(); - //System.out.println(name + " => " + lastimpcontext.tree + "." + name);//DEBUG - tree = make.Select(tree.pos, qual, name); - } - - var symtype: Type = - (if (sym.isType()) sym.typeConstructor() else sym.getType()) - .asSeenFrom(pre, sym.owner()); - symtype = infer.checkAccessible( - tree.pos, sym, symtype, qual, - if (qual == Tree.Empty && sym.owner().isPackageClass()) sym.owner().getType() - else qual.getType()); - if (symtype == Type.NoType) { - error(tree.pos, "not found: " + decode(name)); - return errorTree(tree); - } - //System.out.println(name + ":" + symtype);//DEBUG - mkStable(tree.setSymbol(sym).setType(symtype), pre, mode, pt) - } - - /** Attribute a selection where `tree' is `qual.name'. - * `qual' is already attributed. - */ - def transformSelect(tree: Tree, _qual: Tree, name: Name): Tree = { - var qual = _qual; - var uninst: Array[Symbol] = Symbol.EMPTY_ARRAY; - qual.getType() match { - case Type$PolyType(tparams, restype) => - qual = infer.mkTypeApply(qual, tparams, restype, Symbol.getType(tparams)); - uninst = tparams; - case _ => - } - var sym: Symbol = qual.getType().lookup(name); - if (sym.kind == NONE) { - if (name != Names.view) { - val qtype = qual.getType().singleDeref(); - val v = infer.bestView(qtype, Type.AnyType, name); - if (v != null) { - qual = applyView(v, qual.setType(qtype), EXPRmode, Type.AnyType); - sym = qual.getType().lookup(name); - assert(sym.kind != NONE); - } else { - //System.out.println(qual.getType() + " has members " + qual.getType().members());//DEBUG - error(tree.pos, - decode(name) + " is not a member of " + qual.getType().widen()); - return errorTree(tree); - } - } - } - val qualtype = - if (qual.isInstanceOf[Tree.Super]) context.enclClass.owner.thisType() - else qual.getType(); - var symtype: Type = - (if (sym.isType()) sym.typeConstructor() else sym.getType()) - .asSeenFrom(qualtype, sym.owner()); - if (symtype == Type.NoType) { - error(tree.pos, "not found: " + decode(name)); - return errorTree(tree); - } else - symtype = infer.checkAccessible(tree.pos, sym, symtype, qual, qualtype); - //System.out.println(sym.name + ":" + symtype);//DEBUG - if (uninst.length != 0) { - def polymorphize(tp: Type): Type = tp match { - case Type$PolyType(tparams, restype) => - new Type$PolyType(tparams, polymorphize(restype)) - case Type$OverloadedType(alts, alttypes) => - val alttypes1 = new Array[Type](alttypes.length); - var i = 0; while (i < alttypes.length) { - alttypes1(i) = polymorphize(alttypes(i)); - i = i + 1 - } - new Type$OverloadedType(alts, alttypes1) - case _ => - new Type$PolyType(uninst, tp); - } - symtype = polymorphize(symtype); - } - //System.out.println(qual.getType() + ".member: " + sym + ":" + symtype);//DEBUG - val tree1: Tree = tree match { - case Tree.Select(_, _) => - copy.Select(tree, sym, qual); - case Tree.SelectFromType(_, _) => - copy.SelectFromType(tree, sym, qual) - } - mkStable(tree1.setType(symtype), qualtype, mode, pt) - } - - /** Attribute a pattern matching expression where `pattpe' is the - * expected type of the patterns and `pt' is the expected type of the - * results. - */ - def transformVisitor(tree: Tree, pattpe: Type, pt: Type): Tree = - //System.out.println("trans visitor with " + pattpe + "," + pt);//DEBUG - tree match { - case Tree.Visitor(cases) => - val cases1 = cases; - var i = 0; while (i < cases.length) { - cases1(i) = transformCase(cases(i), pattpe, pt); - i = i + 1 - } - return copy.Visitor(tree, cases1) - .setType(Type.lub(Tree.typeOf(cases1.asInstanceOf[Array[Tree]]))); - case _ => - throw new ApplicationError(); - } - - /** Attribute a case where `pattpe' is the expected type of the pattern - * and `pt' is the expected type of the result. - */ - def transformCase(tree: Tree.CaseDef, pattpe: Type, pt: Type): Tree.CaseDef = - tree match { - case Tree.CaseDef(pat, guard, body) => - val prevContext = pushContext(tree, context.owner, new Scope(context.scope)); - this.inAlternative = false; // no vars allowed below Alternative - val pat1: Tree = transform(pat, PATTERNmode, pattpe); - val guard1: Tree = - if (guard == Tree.Empty) Tree.Empty - else transform(guard, EXPRmode, definitions.boolean_TYPE()); - val body1: Tree = transform(body, EXPRmode, pt); - context = prevContext; - return copy.CaseDef(tree, pat1, guard1, body1) - .setType(body1.getType()).asInstanceOf[Tree.CaseDef]; - } - - def transformStatSeq(stats: Array[Tree], exprOwner: Symbol): Array[Tree] = { - var stats1 = stats; - var i = 0; while (i < stats.length) { - val stat: Tree = stats(i); - if (context.owner.isCompoundSym() && !TreeInfo.isDeclaration(stat)) { - error(stat.pos, "only declarations allowed here"); - } - val mode: int = if (TreeInfo.isDefinition(stat)) NOmode else EXPRmode; - var stat1: Tree = null; - if (exprOwner.kind != NONE && !TreeInfo.isDefinition(stat)) { - val prevContext = pushContext(stat, exprOwner, context.scope); - stat1 = transform(stat, mode); - context = prevContext; - } else { - stat1 = transform(stat, mode); - } - // todo: if we comment next 4 lines out, test/pos/scoping2 fails. - // find out why - if (stat1 != stat && stats1 == stats) { - stats1 = new Array[Tree](stats.length); - System.arraycopy(stats, 0, stats1, 0, i); - } - stats1(i) = stat1; - i = i + 1 - } - stats1 - } - - /** Attribute a sequence of constructor invocations. - * - * @param pos - * @param constrs - * @return - */ - def transformConstrInvocations(pos: Int, constrs: Array[Tree]): Array[Tree] = { - var i = 0; while (i < constrs.length) { - constrs(i) = transform(constrs(i), CONSTRmode | SUPERmode, Type.AnyType); - val f: Symbol = TreeInfo.methSymbol(constrs(i)); - if (f != null) { - val cSym: Symbol = f.constructorClass(); - if (cSym.kind == CLASS) { - cSym.initialize();//to detect cycles - if (i > 0 && (cSym.flags & JAVA) == 0) loadMixinCode(pos, cSym); - } - } - i = i + 1 - } - constrs - } - - def transformConstrInvocationArgs(constrs: Array[Tree]): Unit = { - var i = 0; while (i < constrs.length) { - constrs(i) match { - case Tree.Apply(fn, args) => - if (fn.getType().isInstanceOf[Type$MethodType]) - transformArgs( - constrs(i).pos, TreeInfo.methSymbol(fn), Symbol.EMPTY_ARRAY, - fn.getType(), EXPRmode, args, Type.AnyType); - case _ => - } - i = i + 1 - } - } - - /** Attribute a template - */ - def transformTemplate(templ: Tree.Template, owner: Symbol): Tree.Template = { - //if (global.debug) global.log("transforming template of " + owner);//DEBUG - if (templ.getType() == null) - defineTemplate(templ, owner, owner.members());//may happen for mixins - //System.out.println(owner.info());//DEBUG - val parents = templ.parents; - transformConstrInvocationArgs(parents); - if (!owner.isError()) { - validateParentClasses( - parents, owner.info().parents(), owner.thisType()); - } - val prevContext = pushContext(templ, owner, owner.members()); - /* - val params: Scope = new Scope(); - def computeParams(t: Type): unit = t match { - case Type$PolyType(tparams, t1) => - var i = 0; while (i < tparams.length) { - params.enter(tparams(i)); - i = i + 1; - } - computeParams(t1); - case Type$MethodType(vparams, _) => - var i = 0; while (i < vparams.length) { - params.enter(vparams(i)); - i = i + 1; - } - case _ => - } - computeParams(owner.primaryConstructor().getType()); - val prevContext = pushContext(templ, owner.primaryConstructor(), params); - */ - templ.setSymbol(owner.newLocalDummy()); - val body1 = transformStatSeq(templ.body, templ.symbol()); - /* - context = prevContext; - */ - context = prevContext; - val templ1: Tree.Template = copy.Template(templ, parents, body1); - templ1.setType(owner.getType()); - // initialize all members; necessary to initialize overloaded symbols - val members: Array[Symbol] = owner.members().elements(); - var i = 0; while (i < members.length) { - val sym = members(i); - sym.initialize(); - //System.out.println(owner.toString() + " defines " + sym + ":" + sym.getType());//DEBUG - i = i + 1 - } - templ1 - } - - /** Attribute an argument list. - * @param pos Position for error reporting - * @param meth The symbol of the called method, or `null' if none exists. - * @param tparams The type parameters that need to be instantiated - * @param methtype The method's type w/o type parameters - * @param argMode The argument mode (either EXPRmode or PATTERNmode) - * @param args The actual arguments - * @param pt The proto-resulttype. - * @return The vector of instantiated argument types, or null if error. - */ - def transformArgs(pos: int, meth: Symbol, tparams: Array[Symbol], methtype: Type, argMode: int, args: Array[Tree], pt: Type): Array[Type] = { - //System.out.println("trans args " + meth + ArrayApply.toString(tparams.asInstanceOf[Array[Object]]) + ":" + methtype + "," + pt);//DEBUG - val argtypes = new Array[Type](args.length); - methtype match { - case Type$MethodType(params, restp) => - val formals = infer.formalTypes(params, args.length); - if (formals.length != args.length) { - error(pos, "wrong number of arguments for " + - (if (meth == null) "<function>" else meth) + - ArrayApply.toString(formals.asInstanceOf[Array[Object]], "(", ",", ")")); - return null; - } - if (tparams.length == 0) { - var i = 0; while (i < args.length) { - args(i) = transform(args(i), argMode, formals(i)); - argtypes(i) = args(i).getType().deconst(); - i = i + 1 - } - } else { - // targs: the type arguments inferred from the prototype - val targs: Array[Type] = infer.protoTypeArgs(tparams, restp, pt, params); - - // argpts: prototypes for arguments - val argpts = new Array[Type](formals.length); - var i = 0; while (i < formals.length) { - argpts(i) = formals(i).subst(tparams, targs); - i = i + 1 - } - - // transform arguments with (targs/tparams)formals as prototypes - { var i = 0; while (i < args.length) { - args(i) = transform( - args(i), argMode | POLYmode, formals(i).subst(tparams, targs)); - i = i + 1 - }} - - // targs1: same as targs except that every AnyType is mapped to - // formal parameter type. - val targs1 = new Array[Type](targs.length); - { var i = 0; while (i < targs.length) { - targs1(i) = if (targs(i) != Type.AnyType) targs(i) - else tparams(i).getType(); - i = i + 1 - }} - - { var i = 0; while (i < args.length) { - argtypes(i) = args(i).getType().deconst(); - argtypes(i) match { - case Type$PolyType(tparams1, restype1) => - argtypes(i) = infer.argumentTypeInstance( - tparams1, restype1, - formals(i).subst(tparams, targs1), - argpts(i)); - case _ => - } - i = i + 1 - }} - } - // desugarizing ident patterns - if (params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) { - if ((mode & PATTERNmode) != 0) { - def desug_allIdentPatterns(trees: Array[Tree], currentOwner: Symbol): unit = { - var i = 0; while (i < trees.length) { - trees(i) match { - case Tree.Ident(name) => - if (name != Names.PATTERN_WILDCARD) { - val vble: Symbol = context.scope.lookup(name); - trees(i) = desugarize.IdentPattern(trees(i)).setSymbol(vble) - .setType(vble.getType()); - } else { - trees(i) = gen.Ident(trees(i).pos, definitions.PATTERN_WILDCARD); - } - case _ => - } - i = i + 1 - } - } - desug_allIdentPatterns(args, context.owner); - } else { - assert(args.length != params.length || - !(args(params.length-1).isInstanceOf[Tree.Sequence])); - } - } - argtypes; - - case Type$PolyType(tparams1, restp) => - var tparams2: Array[Symbol] = tparams1; - if (tparams.length != 0) { - tparams2 = new Array[Symbol](tparams.length + tparams1.length); - System.arraycopy(tparams, 0, tparams2, 0, tparams.length); - System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); - } - transformArgs(pos, meth, tparams2, - infer.skipViewParams(tparams2, restp), argMode, args, pt) - - case Type.ErrorType => - var i = 0; while (i < args.length) { - args(i) = transform(args(i), argMode, Type.ErrorType); - argtypes(i) = args(i).getType().deconst(); - i = i + 1 - } - argtypes - - case Type.OverloadedType(alts, alttypes) if (alts.length == 1) => - transformArgs(pos, alts(0), tparams, alttypes(0), argMode, args, pt) - - case _ => - var i = 0; while (i < args.length) { - args(i) = transform(args(i), argMode, Type.AnyType); - argtypes(i) = args(i).getType().deconst(); - i = i + 1 - } - argtypes - } - } - - /** Atribute an expression or pattern with prototype `pt'. - * Check that expression's type conforms to `pt'. - * Resolve overloading and apply parameterless functions. - * Insert `apply' function if needed. - */ - def transform(tree: Tree, mode: int, pt: Type): Tree = { - val savedMode: int = this.mode; - val savedPt: Type = this.pt; - this.mode = mode; - this.pt = pt; - val tree1: Tree = adapt(transform(tree), mode, pt); - - //System.out.println(tree1 + ": " + tree1.getType());//DEBUG - - this.mode = savedMode; - this.pt = savedPt; - tree1 - } - - /** Transform expression or type with a given mode. - * - * @param tree - * @param mode - * @return - */ - def transform(tree: Tree, mode: Int): Tree = { - if ((mode & (EXPRmode | PATTERNmode | CONSTRmode)) != 0) - return transform(tree, mode, Type.AnyType); - - val savedMode: Int = this.mode; - this.mode = mode; - val tree1: Tree = transform(tree); - this.mode = savedMode; - - if ((mode & TYPEmode) != 0) { - val sym: Symbol = tree1.symbol(); - def typeParamCount = sym.primaryConstructor().rawInfo() match { - case t: LazyTreeType => - t.tree match { - case Tree.ClassDef(_, _, tparams, _, _, _) => tparams.length - case Tree.AliasTypeDef(_, _, tparams, _) => tparams.length - case _ => 0 - } - case _ => sym.typeParams().length - } - if ((mode & FUNmode) == 0 && sym != null && typeParamCount != 0) { - error(tree.pos, "" + sym + " takes type parameters."); - return errorTree(tree); - } -// else if (tree1.isType()) -// return gen.mkType(tree1.pos, tree1.getType()); - } - tree1 - } - - def transform(trees: Array[Tree], mode: Int): Array[Tree] = { - var i = 0; while (i < trees.length) { - trees(i) = transform(trees(i), mode); - i = i + 1 - } - trees - } - - override def transform(trees: Array[Tree]): Array[Tree] = - super.transform(trees); - - override def transform(trees: Array[Tree.CaseDef]): Array[Tree.CaseDef] = - super.transform(trees); - - override def transform(trees: Array[Tree.AbsTypeDef]): Array[Tree.AbsTypeDef] = - super.transform(trees); - - override def transform(trees: Array[Tree.ValDef]): Array[Tree.ValDef] = - super.transform(trees); - - override def transform(trees: Array[Array[Tree.ValDef]]): Array[Array[Tree.ValDef]] = - super.transform(trees); - - /** The main attribution function - * - * @param tree - * @return - */ - override def transform(tree: Tree): Tree = { - //System.out.println("transforming " + tree + ":" + pt);//DEBUG - if (tree.getType() != null) { - checkDefined.all = tree; checkDefined.traverse(tree);//debug - return tree; - } - val sym: Symbol = tree.symbol(); - if (sym != null && !sym.isInitialized()) sym.initialize(); - if (global.debug && TreeInfo.isDefinition(tree)) - global.log("transforming definition of " + sym); - try { - tree match { - case Tree.Empty => - tree.setType(Type.NoType) - - case Tree.Attributed(attr, definition) => - - def attrInfo(attr: Tree): Tuple2[Symbol, Array[AConstant]] = attr match { - case Tree.Ident(_) | Tree.Select(_, _) => - Tuple2(attr.symbol(), AConstant.EMPTY_ARRAY) - case Tree.Apply(fn, args) => - Tuple2(attrInfo(fn)._1, attrArgInfos(args)) - case _ => - unit.error(attr.pos, "malformed attribute"); - Tuple2(Symbol.NONE.newErrorClass(errorName(attr).toTypeName()), - AConstant.EMPTY_ARRAY) - } - - def attrArgInfos(args: Array[Tree]): Array[AConstant] = { - val infos = new Array[AConstant](args.length); - var i = 0; while (i < args.length) { - args(i) match { - case Tree.Literal(value) => infos(i) = value; - case _ => unit.error(args(i).pos, - "attribute argument needs to be a constant; found: " + args(i) + " " + args(i).getClass()); - } - i = i + 1 - } - infos - } - - val attr1 = transform(attr, CONSTRmode, definitions.ATTRIBUTE_TYPE()); - val res = transform(definition); - val defsym = res.symbol(); - val attrpair = attrInfo(attr1); - global.addAttribute(defsym, attrpair._1, attrpair._2); - res - - case Tree.DocDef(comment, definition) => - transform(definition) - - case Tree.PackageDef(pkg, templ @ Tree.Template(parents, body)) => - val pkgSym: Symbol = pkg.symbol(); - if (pkgSym != null && pkgSym.isPackage()) { - val prevContext = pushContext(templ, pkgSym.moduleClass(), pkgSym.members()); - val body1: Array[Tree] = transform(body); - context = prevContext; - val templ1: Tree.Template = copy.Template(templ, parents, body1); - templ1.setType(Type.NoType).setSymbol(Symbol.NONE); - copy.PackageDef(tree, pkg, templ1) - .setType(Type.NoType); - } else { - setError(tree); - } - - case Tree.PackageDef(_, _) => - setError(tree) - - case Tree.ClassDef(_, _, tparams, vparams, tpe, templ) => - val prevContext = pushContext( - tree, sym.primaryConstructor(), new Scope(context.scope)); - reenterParams(tparams, vparams, sym.primaryConstructor().getType()); - val tparams1 = transform(tparams); - val vparams1 = transform(vparams); - checkNoEscapeParams(vparams1); - val tpe1: Tree = transform(tpe, TYPEmode); - if (vparams.length > 0 && templ.getType() == null) - templ.body = desugarize.addParamAccessors( - templ.body, vparams(vparams.length - 1)); - - val templ1: Tree.Template = transformTemplate(templ, sym); - if (sym.isTrait()) checkTraitDef(tree.pos, sym, templ1); - checkNoEscape(tree.pos, sym.info()); - context = prevContext; - copy.ClassDef(tree, sym, tparams1, vparams1, tpe1, templ1) - .setType(Type.NoType); - - case Tree.ModuleDef(_, _, tpe, templ) => - val clazz = sym.moduleClass(); - clazz.initialize(); - val prevContext = pushContext( - tree, clazz.primaryConstructor(), context.scope); - val tpe1: Tree = transform(tpe, TYPEmode); - context = prevContext; - val templ1: Tree.Template = transformTemplate(templ, sym.moduleClass()); - if (tpe1 != Tree.Empty && !templ1.getType().isSubType(tpe1.getType())) - error(tree.pos, "" + sym + " does not implement " + tpe1.getType()); - - val lclass = sym.linkedClass(); - // Taken from SymbolLoader.initializeRoot() - if (lclass != null) { - if (lclass.rawInfo().isInstanceOf[SymbolLoader]) { - lclass.setInfo(Type.ErrorType); - val allConstr = lclass.allConstructors(); - allConstr.setInfo(Type.ErrorType); - allConstr.flags = allConstr.flags | Modifiers.PRIVATE; - } - } - - copy.ModuleDef(tree, sym, tpe, templ1) - .setType(Type.NoType); - - case Tree.DefDef(_, name, tparams, vparams, tpe, rhs) => - val prevContext = pushContext(tree, sym, new Scope(context.scope)); - reenterParams(tparams, vparams, sym.getType()); - if (name == Names.CONSTRUCTOR) { - val enclClass = context.enclClass.owner; - enclClass.flags = - enclClass.flags | INCONSTRUCTOR; - enclClass.primaryConstructor().flags = - enclClass.primaryConstructor().flags | INCONSTRUCTOR; - } - val tparams1 = transform(tparams); - val vparams1 = transform(vparams); - checkNoEscapeParams(vparams1); - val tpe1: Tree = - if (tpe == Tree.Empty) gen.mkType(tree.pos, sym.getType().resultType()) - else transform(tpe, TYPEmode); - var rhs1: Tree = - if (rhs == Tree.Empty) rhs - else transform( - rhs, - if (name == Names.CONSTRUCTOR) CONSTRmode else EXPRmode, - if (name == Names.CONSTRUCTOR) definitions.void_TYPE() else tpe1.getType()); - context = prevContext; - if (name == Names.CONSTRUCTOR) { - val enclClass = context.enclClass.owner; - enclClass.flags = - enclClass.flags & ~ INCONSTRUCTOR; - enclClass.primaryConstructor().flags = - enclClass.primaryConstructor().flags & ~ INCONSTRUCTOR; - } - sym.flags = sym.flags | LOCKED; - checkNonCyclic(tree.pos, tpe1.getType()); - sym.flags = sym.flags & ~LOCKED; - copy.DefDef(tree, sym, tparams1, vparams1, tpe1, rhs1) - .setType(Type.NoType); - - case Tree.ValDef(_, _, tpe, rhs) => - assert(sym != null, tree); - val tpe1: Tree = - if (tpe == Tree.Empty) gen.mkType(tree.pos, sym.getType()) - else transform(tpe, TYPEmode); - var rhs1: Tree = rhs; - if (rhs != Tree.Empty) { - val prevContext = pushContext(tree, sym, context.scope); - rhs1 = transform(rhs, EXPRmode, tpe1.getType()); - context = prevContext; - } else if ((sym.flags & (MUTABLE | DEFERRED)) == MUTABLE) { - rhs1 = gen.mkDefaultValue(tree.pos, sym.getType()); - } - sym.flags = sym.flags | LOCKED; - checkNonCyclic(tree.pos, tpe1.getType()); - sym.flags = sym.flags & ~LOCKED; - copy.ValDef(tree, sym, tpe1, rhs1) - .setType(Type.NoType); - - case Tree.AbsTypeDef(_, _, rhs, lobound) => - val rhs1: Tree = transform(rhs, TYPEmode); - val lobound1: Tree = transform(lobound, TYPEmode); - checkNonCyclic(tree.pos, sym.getType()); - copy.AbsTypeDef(tree, sym, rhs1, lobound1) - .setType(Type.NoType); - - case Tree.AliasTypeDef(_, _, tparams, rhs) => - val prevContext = pushContext(tree, sym.primaryConstructor(), new Scope(context.scope)); - reenterParams(tparams, sym.typeParams()); - val tparams1 = transform(tparams); - val rhs1: Tree = transform(rhs, TYPEmode); - context = prevContext; - checkNonCyclic(tree.pos, sym.getType()); - copy.AliasTypeDef(tree, sym, tparams1, rhs1) - .setType(Type.NoType); - - case Tree.Import(expr, selectors) => - pushContext(tree, context.owner, context.scope); - Tree.Empty -/* - - case _ => - transform1(tree, sym) - } - } - - // extracted from transform0 to avoid overflows in GenJVM - private def transform1(tree: Tree, sym: Symbol): Tree = { - - tree match { -*/ - case Tree.Block(stats, value) => - val prevContext = pushContext(tree, context.owner, new Scope(context.scope)); - val newContext = context; - val stats1 = desugarize.Statements(unit, stats, true); - enterSyms(stats1); - context = newContext; - val curmode: int = mode; - var start: Int = 0; - var valuemode: Int = curmode; - if ((curmode & CONSTRmode) != 0) { - stats1(0) = transform(stats1(0), curmode, pt); - context.enclClass.owner.flags = context.enclClass.owner.flags & ~INCONSTRUCTOR; - start = 1; - valuemode = (curmode & ~CONSTRmode) | EXPRmode; - } - var i = start; while (i < stats1.length) { - stats1(i) = transform(stats1(i), EXPRmode); - i = i + 1 - } - val value1: Tree = transform(value, valuemode & ~(FUNmode | QUALmode), pt); - val owntype: Type = - checkNoEscape(tree.pos, value1.getType().deconst()); - context = prevContext; - copy.Block(tree, stats1, value1) - .setType(owntype); - - case Tree.Sequence(trees) => - var i = 0; while (i < trees.length) { - trees(i) = transform(trees(i), - this.mode | SEQUENCEmode, - pt); - i = i + 1 - } - copy.Sequence(tree, trees).setType(pt); - - case Tree.Alternative(choices) => - val save: boolean = this.inAlternative; - this.inAlternative = true; - - val newts = new Array[Tree](choices.length); - var i = 0; while (i < choices.length) { - newts(i) = transform(choices(i), this.mode, pt); - i = i + 1 - } - - //val tpe: Type = Type.lub(Tree.typeOf(newts)); - - this.inAlternative = save; - copy.Alternative(tree, newts).setType(pt); - - case Tree.Bind(name, body) => - var vble: Symbol = null; - if (name != Names.PATTERN_WILDCARD) { - vble = context.owner.newPatternVariable(tree.pos, name).setType(pt); - enterInScope(vble); - //System.out.println("Bind("+name+",...) enters in scope:"+Debug.show(vble)); - - patternVars.put(vble, new JBoolean(this.inAlternative)); - //System.out.println("case Bind.. put symbol vble="+vble+" in scope and patternVars."); - } - val body1: Tree = transform(body); - if (name == Names.PATTERN_WILDCARD) body1 - else { - //assert body1.getType() != null; - if(TreeInfo.isSequenceValued(body1)) { - vble.setType(definitions.LIST_TYPE(pt)); - } else { - vble.setType(body1.getType()); - } - copy.Bind(tree, name, body1) - .setSymbol(vble).setType(body1.getType()); - } - - case Tree.Visitor(cases) => - if (pt.symbol().isSubClass(definitions.PARTIALFUNCTION_CLASS)) { - val pft: Type = pt.baseType(definitions.PARTIALFUNCTION_CLASS); - val pftargs = pft.typeArgs(); - if (pftargs.length == 2 && infer.isFullyDefined(pftargs(0))) { - val pattype: Type = pftargs(0); - var restype: Type = pftargs(1); - val isDefinedAtVisitor: Tree = transformVisitor( - desugarize.isDefinedAtVisitor(tree), - pattype, definitions.boolean_TYPE()); - val applyVisitor: Tree = transformVisitor(tree, pattype, restype); - if (!infer.isFullyDefined(restype)) - restype = applyVisitor.getType().deconst(); - loadMixinCode(tree.pos, definitions.PARTIALFUNCTION_CLASS); - gen.mkPartialFunction( - tree.pos, applyVisitor, isDefinedAtVisitor, - pattype, restype, context.owner); - } else { - error(tree.pos, "expected pattern type of cases could not be determined"); - errorTermTree(tree) - } - } else { - transform(desugarize.Visitor(unit, tree)) - } - - case Tree.Assign(Tree.Apply(_, _), _) => - transform(desugarize.Update(tree)) - - case Tree.Assign(lhs, rhs) => - val lhs1: Tree = transform(lhs, EXPRmode); - val varsym: Symbol = lhs1.symbol(); - if (isSetterMethod(varsym)) { - // todo: change this to require setters in same template - transform(desugarize.Assign(tree.pos, lhs, rhs)); - } else if (varsym != null && (varsym.flags & MUTABLE) != 0) { - val rhs1: Tree = transform(rhs, EXPRmode, lhs1.getType()); - copy.Assign(tree, lhs1, rhs1) - .setType(definitions.void_TYPE()); - } else { - if (!lhs1.getType().isError()) - error(tree.pos, "assignment to non-variable "); - gen.mkUnitLit(tree.pos) - } - - case Tree.If(cond, thenp, elsep) => - val cond1: Tree = transform(cond, EXPRmode, definitions.boolean_TYPE()); - var thenp1: Tree = _; - var elsep1: Tree = _; - if (elsep == Tree.Empty) { - thenp1 = transform(thenp, EXPRmode, definitions.void_TYPE()); - elsep1 = gen.mkUnitLit(tree.pos); - } else { - thenp1 = transform(thenp, EXPRmode, pt); - elsep1 = transform(elsep, EXPRmode, pt); - } - copy.If(tree, cond1, thenp1, elsep1) - .setType(Type.lub(NewArray.Type(thenp1.getType(), elsep1.getType()))); - - case Tree.Throw(expr) => - val expr1: Tree = transform( - expr, EXPRmode, definitions.THROWABLE_TYPE()); - gen.Select(tree.pos, expr1, definitions.THROWABLE_THROW); - - case Tree.Return(expr) => - if (!context.owner.isInitialized()) { - error(tree.pos, "method with return needs result type"); - errorTermTree(tree) - } else { - val enclFun: Symbol = context.owner.enclMethod(); - if (enclFun.kind == VAL && !enclFun.isConstructor()) { - val expr1: Tree = transform( - expr, EXPRmode, enclFun.getType().resultType()); - copy.Return(tree, expr1) - .setSymbol(enclFun).setType(definitions.ALL_TYPE()); - } else { - error(tree.pos, "return outside method definition"); - errorTermTree(tree) - } - } - - case Tree.New(init) => - val init1: Tree = transform(init, CONSTRmode, pt); - checkInstantiatable(tree.pos, init1.getType()); - val tree1 = gen.New(tree.pos, init1); - val clazz = tree1.getType().symbol(); - if (clazz.isAnonymousClass()) { - val parentTypes = clazz.info().parents(); - val refinement: Scope = new Scope(); - val base: Type = Type.compoundTypeWithOwner(context.enclClass.owner, parentTypes, Scope.EMPTY); - val it: Scope$SymbolIterator = clazz.members().iterator(); - while (it.hasNext()) { - val sym1: Symbol = it.next(); - val basesym1: Symbol = base.lookupNonPrivate(sym1.name); - if (!basesym1.isNone() && - sym1.kind != VAL && // todo: remove once refinements work! - !base.symbol().thisType().memberType(basesym1) - .isSameAs(sym1.getType())) - refinement.enter(sym1); - } - val owntype = - if (refinement.isEmpty() && parentTypes.length == 1) - parentTypes(0) - else - checkNoEscape( - tree.pos, - Type.compoundTypeWithOwner( - context.enclClass.owner, parentTypes, refinement)); - gen.Typed(tree1, owntype) - } else - tree1 - - case Tree.Typed(expr, tpe) => - expr match { - case Tree.Ident(n) - if (n != Names.PATTERN_WILDCARD && (mode & PATTERNmode) != 0) => - transform(desugarize.TypedPattern(tree.asInstanceOf[Tree.Typed]), - mode, - pt); - case _ => - var expr1: Tree = _; - var tpe1: Tree = _; - tpe match { - case Tree.Ident(TypeNames.WILDCARD_STAR) => - expr1 = transform( - expr, mode & baseModes, definitions.SEQ_TYPE(pt)); - val elemtps = - expr1.getType().baseType(definitions.SEQ_CLASS).typeArgs(); - val elemtp: Type = if (elemtps.length == 1) elemtps(0) - else Type.ErrorType; - - tpe1 = tpe.setType(elemtp); - case _ => - tpe1 = transform(tpe, TYPEmode); - expr1 = transform(expr, mode & baseModes, tpe1.getType()); - } - copy.Typed(tree, expr1, tpe1).setType(tpe1.getType()) - } - - case Tree.Function(vparams, body) => - val prevContext = pushContext(tree, context.owner, new Scope(context.scope)); - var restype: Type = desugarize.preFunction(vparams, pt); - enterParams(vparams); - val vparams1 = transform(vparams); - val body1: Tree = transform(body, EXPRmode, restype); - if (!infer.isFullyDefined(restype)) - restype = body1.getType().deconst(); - restype = checkNoEscape(tree.pos, restype); - context = prevContext; - gen.mkFunction(tree.pos, vparams1, body1, restype, context.owner, false); - - case Tree.TypeApply(fn, args) => - - val fn1: Tree = transform( - fn, (mode & (EXPRmode | CONSTRmode)) | FUNmode, Type.AnyType); - val args1 = transform(args, TYPEmode); - val argtypes = Tree.typeOf(args1); - - // propagate errors in arguments - var i = 0; - while (i < argtypes.length && !argtypes(i).isError()) - i = i + 1; - if (i < argtypes.length) - setError(tree); - else { - - // resolve overloading - fn1.getType() match { - case Type$OverloadedType(alts, alttypes) => - try { - infer.polyAlternative(fn1, alts, alttypes, args.length); - } catch { - case ex: Type$Error => reportTypeError(tree.pos, ex); - } - case _ => - } - - // match against arguments - fn1.getType() match { - case Type$PolyType(tparams, restp) if (tparams.length == argtypes.length) => - constfold.tryToFold( - infer.completeTypeApply( - copy.TypeApply(tree, fn1, args1) - .setType(restp.subst(tparams, argtypes)))); - - case Type.ErrorType => - setError(tree) - - case fn1tp => - if (!fn1tp.isError()) error(tree.pos, - infer.toString(fn1.symbol(), fn1.getType()) + - " cannot be applied to " + - ArrayApply.toString( - argtypes.asInstanceOf[Array[Object]], "(", ",", ")")); - errorTermTree(tree) - } - } - case Tree.Apply(fn, args) if ((mode & PATTERNmode) != 0) => - val fn1 = transform(fn, mode | FUNmode, pt); - val argMode = PATTERNmode; - // type arguments with formals as prototypes if they exist. - fn1.setType(infer.freshInstance(fn1.getType())); - val argtypes = transformArgs( - tree.pos, fn1.symbol(), Symbol.EMPTY_ARRAY, fn1.getType(), argMode, args, pt); - - - if (argtypes == null) - setError(tree) - else { - var i: int = 0; - while (i < argtypes.length && !argtypes(i).isError()) - i = i + 1; - if (i < argtypes.length) setError(tree); - - fn1.getType() match { - case Type$MethodType(params, restp) => - copy.Apply(tree, fn1, args).setType(restp); - case _ => - if (!fn1.getType().isError()) - error( - tree.pos, - infer.applyErrorMsg( - "", fn1, " cannot be applied to ", argtypes, pt)); - errorTermTree(tree) - } - } - - - case Tree.Apply(fn, args) => - mode = mode & ~SEQUENCEmode; - var fn1: Tree = _; - var argMode: int = _; - var selfcc: boolean = false; - //todo: Should we pass in both cases a methodtype with - // AnyType's for args as a prototype? - if ((mode & EXPRmode) != 0) { - fn1 = transform(fn, mode | FUNmode, Type.AnyType); - argMode = EXPRmode; - } else if ((mode & PATTERNmode) != 0) { - fn1 = transform(fn, mode | FUNmode, pt); - argMode = PATTERNmode; - } else { - assert((mode & CONSTRmode) != 0); - fn1 = transform(fn, mode | FUNmode, Type.AnyType); - argMode = EXPRmode; - - // convert type to constructor - val tsym: Symbol = TreeInfo.methSymbol(fn1); - if (!tsym.isError()) { - assert(tsym.isType(), tsym); - fn1.getType().withDefaultArgs().unalias() match { - case Type$TypeRef(pre, c, argtypes) => - if (c.kind != CLASS) { - error(tree.pos, - "" + tsym + " is not a class; cannot be instantiated"); - } else if (!pre.isStable()) { - error(tree.pos, "" + pre + " is not a legal prefix for a constructor"); - } else { - c.initialize(); - val constr: Symbol = c.allConstructors(); - val fn0: Tree = fn1; - fn1 = gen.mkRef(fn1.pos, pre, constr); - var enclClassOrConstructorContext = Context.NONE; - if (constr.owner().isPackageClass()) { - var c = context; - while (c != Context.NONE && - !c.tree.isInstanceOf[Tree.ClassDef] && - !c.tree.isInstanceOf[Tree.ModuleDef] && - !c.tree.isInstanceOf[Tree.Template]) - c = c.outer; - enclClassOrConstructorContext = c - } - if (enclClassOrConstructorContext == Context.NONE) { - fn1 match { - case Tree.Select(fn1qual, _) => - fn1.setType(infer.checkAccessible( - fn1.pos, constr, fn1.getType(), fn1qual, fn1qual.getType())); - case _ => - if (constr.owner().isPackageClass()) - fn1.setType(infer.checkAccessible( - fn1.pos, constr, fn1.getType(), Tree.Empty, constr.owner().getType())); - } - } else { - val cowner = enclClassOrConstructorContext.owner; - if (cowner.isConstructor()) - // we are in a superclass constructor call - fn1.setType( - infer.checkAccessible( - fn1.pos, constr, fn1.getType(), - make.Super(tree.pos, - Names.EMPTY.toTypeName(), - Names.EMPTY.toTypeName()), - cowner.constructorClass().typeConstructor())); - else - fn1.setType(infer.checkAccessible( - fn1.pos, constr, fn1.getType(), - enclClassOrConstructorContext.tree, - cowner.typeConstructor())); - } - if (tsym == c) { - fn0 match { - case Tree.AppliedType(_, targs) => - fn1 = infer.completeTypeApply(gen.TypeApply(fn1, targs)); - case _ => - } - } else { - // it was an alias type - // todo: handle overloaded constructors - if (argtypes.length != 0) - fn1 = gen.TypeApply( - fn1, gen.mkTypes(fn1.pos, argtypes)); - if (tsym.typeParams().length != 0 && - !(fn0.isInstanceOf[Tree.AppliedType])) - fn1.setType(new Type$PolyType( - tsym.typeParams(), fn1.getType())); - } - //System.out.println(TreeInfo.methSymbol(fn1) + ":" + tp + " --> " + fn1.getType() + " of " + fn1);//DEBUG - selfcc = TreeInfo.isSelfConstrCall(fn0); - } - - case _ => - error(tree.pos, - "" + tsym + " is not a class; cannot be instantiated"); - } - } - } - - // if function is overloaded with one alternative - // whose arity matches argument length and whose result type matches prototype, - // preselect this alternative. - fn1.getType() match { - case Type$OverloadedType(alts, alttypes) => - val argtypes = new Array[Type](args.length); - { var i = 0; while (i < argtypes.length) { - argtypes(i) = definitions.ALL_TYPE(); i = i + 1 - }} - var matching1: Int = -1; - var matching2: Int = -1; - { var i = 0; while (i < alttypes.length) { - if (infer.isApplicable(alttypes(i), argtypes, pt)) { - //System.out.println("matches: " + alttypes(i) + " with " + pt);//debug - matching2 = matching1; - matching1 = i; - } - i = i + 1; - }} - if (matching1 >= 0 && matching2 < 0) { - fn1.setSymbol(alts(matching1)).setType(alttypes(matching1)); - } - case _ => - } - - def handleApply: Tree = { - // handle the case of application of match to a visitor specially - if (args.length == 1 && args(0).isInstanceOf[Tree.Visitor]) { - val pattp: Type = matchQualType(fn1); - if (pattp.isError()) { - return setError(tree) - } else if (pattp != Type.NoType) { - if (infer.isFullyDefined(pattp) && - !(fn1.getType().isInstanceOf[Type$PolyType] && - pattp.containsSome(fn1.getType().typeParams()))) { - val fn2: Tree = desugarize.postMatch(fn1, context.enclClass.owner); - val arg1: Tree = transformVisitor(args(0), pattp, pt); - return copy.Apply(tree, fn2, NewArray.Tree(arg1)) - .setType(arg1.getType()); - } else { - error(tree.pos, "expected pattern type of cases could not be determined"); - return errorTermTree(tree) - } - } - } - - // return prematurely if function is a superclass constructor - // and no type arguments need to be inferred. - if ((mode & SUPERmode) != 0 && fn1.getType().isInstanceOf[Type$MethodType]) { - return copy.Apply(tree, fn1, args).setType(fn1.getType().resultType()) : Tree; - } - - // type arguments with formals as prototypes if they exist. - fn1.setType(infer.freshInstance(fn1.getType())); - val argtypes = transformArgs( - tree.pos, fn1.symbol(), Symbol.EMPTY_ARRAY, fn1.getType(), argMode, args, pt); - - if (argtypes == null) - return setError(tree) - else { - var i: int = 0; - while (i < argtypes.length && !argtypes(i).isError()) - i = i + 1; - if (i < argtypes.length) return setError(tree); - } - - // resolve overloading1g - fn1.getType() match { - case Type$OverloadedType(alts, alttypes) => - try { - infer.methodAlternative(fn1, alts, alttypes, argtypes, pt); - } catch { - case ex: Type$Error => reportTypeError(tree.pos, ex); - } - case _ => - } - - // check that self constructors go backwards. - if (selfcc) { - val constr: Symbol = TreeInfo.methSymbol(fn1); - if (constr != null && constr.kind == VAL && - !(constr.getType().isInstanceOf[Type$OverloadedType]) && - constr.pos > tree.pos) - error(tree.pos, - "illegal forward reference to self constructor"); - } - - fn1.getType() match { - case Type$PolyType(tparams, restp) => - // if method is polymorphic, - // infer instance, and adapt arguments to instantiated formals - try { - fn1 = infer.methodInstance(fn1, tparams, restp, argtypes, pt); - //System.out.println(fn1 + ":" + fn1.getType());//DEBUG - } catch { - case ex: Type$Error => - //ex.printStackTrace();//DEBUG - reportTypeError(tree.pos, ex); - } - case _ => - } - - fn1.getType() match { - case Type$MethodType(params, restp) => { - if ((mode & PATTERNmode) != 0) - return copy.Apply(tree, fn1, args).setType(restp); - if(global.target == scalac_Global.TARGET_MSIL) { - fn1 match { - case Tree.Select(qual, name) => - if (qual.getType().isSubType(definitions.DELEGATE_TYPE()) - && (name == Names.PLUSEQ || name == Names.MINUSEQ)) { - val n = if (name == Names.PLUSEQ) Names.PLUS else Names.MINUS; - val fun = make.Select(fn1.pos, qual, n); - val rhs = copy.Apply(tree, fun, args); - return transform(make.Assign(fn1.pos, qual, rhs)); - } - case _ => - } - } - val formals = infer.formalTypes(params, args.length); - if (formals.length == args.length) { - var i = 0; while (i < args.length) { - args(i) = adapt(args(i), argMode, formals(i)); - args(i) match { - case Tree.Typed( arg, Tree.Ident( TypeNames.WILDCARD_STAR ) ) => - if( i != args.length - 1 ) { - error( arg.pos, "escape only allowed in last position"); - } else if ( args.length > params.length ) { - error( arg.pos, "escaping cannot be mixed with values"); - } - case _ => /* nop */ - } - i = i + 1 - } - } - return constfold.tryToFold( - copy.Apply(tree, fn1, args) - .setType(restp)); - } - case _ => - } - - if (!fn1.getType().isError()) - error( - tree.pos, - infer.applyErrorMsg( - "", fn1, " cannot be applied to ", argtypes, pt)); - errorTermTree(tree) - } - - handleApply - - case Tree.Super(qualifier, mixin) => - val clazz: Symbol = qualifyingClass(tree, qualifier); - if (clazz.isNone()) { - setError(tree); - } else { - tree.setSymbol(clazz); - val parents = clazz.parents(); - if (mixin == TypeNames.EMPTY) { - tree.setType(parents(0).instanceType()); - } else { - var i = 0; - while (i < parents.length && parents(i).symbol().name != mixin) - i = i + 1; - if (i < parents.length) - tree.setType(parents(i).instanceType()); - else { - error(tree.pos, - "" + mixin + " does not name a mixin base class of " + clazz); - errorTermTree(tree) - } - } - } - - case Tree.This(name) => - val clazz: Symbol = qualifyingClass(tree, name); - if (clazz.isNone()) - setError(tree) - else { - tree.setSymbol(clazz); - tree.setType( - if (pt != null && pt.isStable() || (mode & QUALmode) != 0) clazz.thisType() - else clazz.typeOfThis()); - } - - case Tree.Select(qual, name) => - val qualmode: int = if (name == Names._match) EXPRmode - else EXPRmode | POLYmode | QUALmode; - var qual1: Tree = transform(qual, qualmode); - if (name.isTypeName()) - qual1 = checkStable(qual1); - transformSelect( - tree, adapt(qual1, qualmode, Type.AnyType), name); - - case Tree.Ident(name) => - if (name == Names.CONSTRUCTOR) { - assert((mode & CONSTRmode) != 0, tree); - copy.Ident(tree, context.enclClass.owner) - .setType(context.enclClass.owner.getType()); - } else if (((mode & (PATTERNmode | FUNmode)) == PATTERNmode) && name.isVariable()) { - var vble: Symbol = null; - var vble2: Symbol = null; - - // if vble is bound with @, there is already a symbol - if (name != Names.PATTERN_WILDCARD) { - vble2 = context.scope.lookup(name); - } - var tree1 = tree; - if (patternVars.containsKey(vble2)) - vble = vble2; - else { - vble = - if (name == Names.PATTERN_WILDCARD) - definitions.PATTERN_WILDCARD - else context.owner.newPatternVariable(tree.pos, name).setType(pt); - //if(((mode & SEQUENCEmode) != 0)&&(name != Names.PATTERN_WILDCARD)) { - if(name != Names.PATTERN_WILDCARD) { - // x => x @ _ in sequence patterns - tree1 = desugarize.IdentPattern(tree); - } - } - if (name != Names.PATTERN_WILDCARD) enterInScope(vble); - tree1.setSymbol(vble).setType(pt); - } else { - transformIdent(tree, name) - } - - case Tree.Literal(value) => - tree.setType(Type.constantType(value)) - - case Tree.LabelDef(name, params, body) => - assert(params.length == 0); - val prevContext = pushContext(tree, context.owner, new Scope(context.scope)); - val lsym: Symbol = context.owner.newLabel(tree.pos, name); - lsym.setInfo( - new Type$MethodType(Symbol.EMPTY_ARRAY, definitions.void_TYPE())); - context.scope.enter(lsym); - val body1: Tree = transform(body, mode, pt); - context = prevContext; - copy.LabelDef(tree, lsym, params, body1) - .setSymbol(lsym).setType(definitions.void_TYPE()); - - case Tree.TypeTerm() => - tree - - case Tree.SingletonType(ref) => - val ref1: Tree = checkStable( - transform(ref, EXPRmode | QUALmode, definitions.ANYREF_TYPE())); - copy.SingletonType(tree, ref1) - .setType(ref1.getType().resultType()); - - case Tree.SelectFromType(qual, name) => - val qual1: Tree = transform(qual, TYPEmode); - transformSelect(tree, qual1, name); - - case Tree.CompoundType(parents, refinements) => - val parents1 = transform(parents, TYPEmode); - val ptypes = new Array[Type](parents1.length); - { var i = 0; while (i < parents1.length) { - val tp = parents(i).getType(); - if (i > 0 || tp.unalias().symbol().kind != TYPE) - checkClassType(parents(i).pos, tp); - ptypes(i) = tp; - i = i + 1 - }} - val members: Scope = new Scope(); - val cowner = - if (context.owner.isPrimaryConstructor() && context.owner.owner().isPackageClass()) - context.owner.constructorClass() - else context.enclClass.owner; - val self: Type = Type.compoundTypeWithOwner(cowner, ptypes, members); - val clazz: Symbol = self.symbol(); - val prevContext = pushContext(tree, clazz, members); - { var i = 0; while (i < refinements.length) { - val m = enterSym(refinements(i)); - m.flags = m.flags | OVERRIDE; - i = i + 1 - }} - val refinements1 = transformStatSeq(refinements, Symbol.NONE); - context = prevContext; - copy.CompoundType(tree, parents1, refinements1) - .setType(self) - - case Tree.AppliedType(tpe, args) => - val tpe1: Tree = transform(tpe, mode | FUNmode); - val args1 = transform(args, TYPEmode); - val argtypes = Tree.typeOf(args); - val tparams = tpe1.getType().symbol().typeParams(); - var owntype: Type = Type.ErrorType; - if (!tpe1.getType().isError()) { - if (tparams.length == args.length) - owntype = Type.appliedType(tpe1.getType(), argtypes); - else if (tparams.length == 0) - error(tree.pos, "" + tpe1.getType() + " does not take type parameters"); - else - error(tree.pos, "wrong number of type arguments for " + - tpe1.getType()); - } - copy.AppliedType(tree, tpe1, args1).setType(owntype); - - case Tree.FunType(_, _) => - transform(desugarize.FunType(tree)) - - case _ => - throw new ApplicationError("illegal tree: " + tree) - } - } catch { - case ex: Type$Error => - reportTypeError(tree.pos, ex); - errorTree(tree) - } - } - -} - -} - -// LocalWords: SOcos diff --git a/sources/scala/tools/scalac/typechecker/AnalyzerPhase.scala b/sources/scala/tools/scalac/typechecker/AnalyzerPhase.scala deleted file mode 100644 index 288b2e0e3f..0000000000 --- a/sources/scala/tools/scalac/typechecker/AnalyzerPhase.scala +++ /dev/null @@ -1,83 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scala.tools.util.Position; -import scalac._; -import scalac.symtab._; -import scalac.util._; -import scalac.ast._; -import java.util.HashMap; -import java.util.ArrayList; -import scala.tools.scalac.util.NewArray; -import scalac.typechecker.{AnalyzerPhase => scalac_AnalyzerPhase} -import scalac.{Global => scalac_Global} - -package scala.tools.scalac.typechecker { - -class NamerPhase(global0: scalac_Global, descriptor0: PhaseDescriptor) - extends Phase(global0, descriptor0) -{ - override def apply(unit: CompilationUnit): Unit = { - // change phase to make sure that no setInfo occurs before phase ANALYZER - val analyzer = global.PHASE.ANALYZER.phase().asInstanceOf[AnalyzerPhase]; - val backup = global.currentPhase; - global.currentPhase = analyzer; - new Analyzer(global, analyzer).lateEnter(unit); - global.currentPhase = backup; - } -} - -class AnalyzerPhase(global: scalac_Global, descriptor: PhaseDescriptor) extends scalac_AnalyzerPhase(global, descriptor) { - - var startContext = new Context( - Tree.Empty, - global.definitions.ROOT_CLASS, - global.definitions.ROOT_CLASS.members(), - Context.NONE); - startContext.enclClass = startContext; - - if (!global.noimports) { - startContext = addImport(startContext, global.definitions.JAVALANG); - startContext = addImport(startContext, global.definitions.SCALA); - } - - if (!global.noimports && !global.nopredefs) { - startContext = addImport(startContext, global.definitions.PREDEF); - } - - startContext = new Context( - Tree.Empty, - startContext.owner, - global.definitions.ROOT_CLASS.members(), - startContext); - - var consoleContext = new Context( - Tree.Empty, - global.definitions.ROOT_CLASS, - global.definitions.ROOT_CLASS.members(), - startContext); - - val contexts = new HashMap/*<CompilationUnit,Context>*/(); - - override def addConsoleImport(module: Symbol): unit = - consoleContext = addImport(consoleContext, module); - - private def addImport(context: Context, module: Symbol): Context = { - global.prevPhase(); - val tree = gen.mkImportAll(Position.NOPOS, module); - global.nextPhase(); - val c = new Context(tree, context.owner, new Scope(), context); - c.depth = context.depth; - c - } - - override def apply(unit: CompilationUnit): Unit = - new Analyzer(global, this).apply(unit); - -} -} diff --git a/sources/scala/tools/scalac/typechecker/ConstantFolder.scala b/sources/scala/tools/scalac/typechecker/ConstantFolder.scala deleted file mode 100644 index b8510ca0a9..0000000000 --- a/sources/scala/tools/scalac/typechecker/ConstantFolder.scala +++ /dev/null @@ -1,329 +0,0 @@ -/* ************************************************************************ - * Pizza constant folder - * by Martin Odersky - * - * Copyright (C) 1996,97 Martin Odersky. All rights reserved. - * Permission is hereby granted to modify and use this software for research - * and teaching purposes. Modification for commercial purposes requires - * prior written permission by the author. - * The software, or modifications thereof, may be redistributed only - * if this copyright notice stays attached. - *************************************************************************/ - -import java.lang.Object; - -import scalac.symtab._; -import scalac.{Global => scalac_Global} -import scalac.util.Name; -import scalac.util.Names; -import scalac.ast._; -import scalac.ast.TreeGen; -import scalac.atree._; -import scalac.atree.ATypeKind; -import scalac.atree.ATypeKind._; - -package scala.tools.scalac.typechecker { - -class ConstantFolder(global: scalac_Global) { - - //######################################################################## - // Private Fields - - /** The global definitions */ - private val definitions: Definitions = global.definitions; - - /** The tree generator */ - private val gen: TreeGen = global.treeGen; - - //######################################################################## - // Public Methods - - /** - * Attempts to constant fold given tree. Returns the input tree if - * constant folding fails. - */ - def tryToFold(tree: Tree): Tree = { - val value: AConstant = evaluate(tree); - if (value != null) gen.Literal(tree.pos, value) else tree; - } - - /** - * Evaluates the expression represented by the tree and returns - * the resulting value. Returns null if the evaluation can't be - * performed. - */ - def evaluate(tree: Tree): AConstant = tree match { - case Tree$TypeApply(Tree$Select(qualifier, Names.asInstanceOf), args) if args.length == 1 => - qualifier.getType() match { - case Type$ConstantType(_, lvalue) => cast(lvalue, args(0).getType()); - case _ => null; - } - - case Tree$Apply(Tree$Select(qualifier, op), args) if args.length == 1=> - qualifier.getType() match { - case Type$ConstantType(_, lvalue) => - args(0).getType() match { - case Type$ConstantType(_, rvalue) => evaluate(op, lvalue, rvalue) - case _ => null - } - case _ => null - } - - case Tree$Select(qualifier, op) => - qualifier.getType() match { - case Type$ConstantType(_, lvalue) => evaluate(op, lvalue) - case _ => null - } - - case _ => null - } - - /** - * Evaluates the unary operation and returns the resulting value. - * Returns null if the evaluation can't be performed. - */ - def evaluate(op: Name, value: AConstant): AConstant = kind(value) match { - case ATypeKind.BOOL => - val v = value.booleanValue(); - if (op == Names.ZNOT) AConstant.BOOLEAN(!v) - else null - case ATypeKind.I4 => - val v = value.intValue(); - if (op == Names.ADD) AConstant.INT(+v) - else if (op == Names.SUB) AConstant.INT(-v) - else if (op == Names.NOT) AConstant.INT(~v) - else null; - case ATypeKind.I8 => - val v = value.longValue(); - if (op == Names.ADD) AConstant.LONG(+v) - else if (op == Names.SUB) AConstant.LONG(-v) - else if (op == Names.NOT) AConstant.LONG(~v) - else null; - case ATypeKind.R4 => - val v = value.floatValue(); - if (op == Names.ADD) AConstant.FLOAT(+v) - else if (op == Names.SUB) AConstant.FLOAT(-v) - else null - case ATypeKind.R8 => - val v = value.doubleValue(); - if (op == Names.ADD) AConstant.DOUBLE(+v) - else if (op == Names.SUB) AConstant.DOUBLE(-v) - else null - case _ => - null - } - - /** - * Evaluates the binary operation and returns the resulting value. - * Returns null if the evaluation can't be performed. - */ - def evaluate(op: Name, lvalue: AConstant, rvalue: AConstant): AConstant = { - val k = kind(lvalue, rvalue); - if (k == null) return null; - k match { - case ATypeKind.I4 => - val l = lvalue.intValue(); - val r = rvalue.intValue(); - if (op == Names.OR ) AConstant.INT(l | r) - else if (op == Names.AND) AConstant.INT(l & r) - else if (op == Names.XOR) AConstant.INT(l ^ r) - else if (op == Names.ADD) AConstant.INT(l + r) - else if (op == Names.SUB) AConstant.INT(l - r) - else if (op == Names.MUL) AConstant.INT(l * r) - else if (op == Names.DIV) if (r == 0) null else AConstant.INT(l / r) - else if (op == Names.MOD) if (r == 0) null else AConstant.INT(l % r) - else if (op == Names.EQ ) AConstant.BOOLEAN(l == r) - else if (op == Names.NE ) AConstant.BOOLEAN(l != r) - else if (op == Names.LT ) AConstant.BOOLEAN(l < r) - else if (op == Names.GT ) AConstant.BOOLEAN(l > r) - else if (op == Names.LE ) AConstant.BOOLEAN(l <= r) - else if (op == Names.GE ) AConstant.BOOLEAN(l >= r) - else if (op == Names.LSL) AConstant.INT(l << r) - else if (op == Names.LSR) AConstant.INT(l >>> r) - else if (op == Names.ASR) AConstant.INT(l >> r) - else null - - case ATypeKind.I8 => - val l = lvalue.longValue(); - val r = rvalue.longValue(); - if (op == Names.OR ) AConstant.LONG(l | r) - else if (op == Names.AND) AConstant.LONG(l & r) - else if (op == Names.XOR) AConstant.LONG(l ^ r) - else if (op == Names.ADD) AConstant.LONG(l + r) - else if (op == Names.SUB) AConstant.LONG(l - r) - else if (op == Names.MUL) AConstant.LONG(l * r) - else if (op == Names.DIV) if (r == 0) null else AConstant.LONG(l / r) - else if (op == Names.MOD) if (r == 0) null else AConstant.LONG(l % r) - else if (op == Names.EQ ) AConstant.BOOLEAN(l == r) - else if (op == Names.NE ) AConstant.BOOLEAN(l != r) - else if (op == Names.LT ) AConstant.BOOLEAN(l < r) - else if (op == Names.GT ) AConstant.BOOLEAN(l > r) - else if (op == Names.LE ) AConstant.BOOLEAN(l <= r) - else if (op == Names.GE ) AConstant.BOOLEAN(l >= r) - else if (kind(lvalue) == ATypeKind.I4) { - val li = lvalue.intValue(); - if (op == Names.LSL) AConstant.INT(li << r) - else if (op == Names.LSR) AConstant.INT(li >>> r) - else if (op == Names.ASR) AConstant.INT(li >> r) - else null - } else { - if (op == Names.LSL) AConstant.LONG(l << r) - else if (op == Names.LSR) AConstant.LONG(l >>> r) - else if (op == Names.ASR) AConstant.LONG(l >> r) - else null - } - - case ATypeKind.R4 => - val l = lvalue.floatValue(); - val r = rvalue.floatValue(); - if (op == Names.ADD) AConstant.FLOAT(l + r) - else if (op == Names.SUB) AConstant.FLOAT(l - r) - else if (op == Names.MUL) AConstant.FLOAT(l * r) - else if (op == Names.DIV) AConstant.FLOAT(l / r) - else if (op == Names.MOD) AConstant.FLOAT(l % r) - else if (op == Names.EQ ) AConstant.BOOLEAN(l == r) - else if (op == Names.NE ) AConstant.BOOLEAN(l != r) - else if (op == Names.LT ) AConstant.BOOLEAN(l < r) - else if (op == Names.GT ) AConstant.BOOLEAN(l > r) - else if (op == Names.LE ) AConstant.BOOLEAN(l <= r) - else if (op == Names.GE ) AConstant.BOOLEAN(l >= r) - else null - - case ATypeKind.R8 => - val l = lvalue.doubleValue(); - val r = rvalue.doubleValue(); - if (op == Names.ADD) AConstant.DOUBLE(l + r) - else if (op == Names.SUB) AConstant.DOUBLE(l - r) - else if (op == Names.MUL) AConstant.DOUBLE(l * r) - else if (op == Names.DIV) AConstant.DOUBLE(l / r) - else if (op == Names.MOD) AConstant.DOUBLE(l % r) - else if (op == Names.EQ ) AConstant.BOOLEAN(l == r) - else if (op == Names.NE ) AConstant.BOOLEAN(l != r) - else if (op == Names.LT ) AConstant.BOOLEAN(l < r) - else if (op == Names.GT ) AConstant.BOOLEAN(l > r) - else if (op == Names.LE ) AConstant.BOOLEAN(l <= r) - else if (op == Names.GE ) AConstant.BOOLEAN(l >= r) - else null - - case ATypeKind.BOOL => - val l = lvalue.booleanValue(); - val r = rvalue.booleanValue(); - if (op == Names.ZOR ) AConstant.BOOLEAN(l | r) - else if (op == Names.OR ) AConstant.BOOLEAN(l | r) - else if (op == Names.ZAND) AConstant.BOOLEAN(l & r) - else if (op == Names.AND ) AConstant.BOOLEAN(l & r) - else if (op == Names.XOR ) AConstant.BOOLEAN(l ^ r) - else if (op == Names.EQ ) AConstant.BOOLEAN(l == r) - else if (op == Names.NE ) AConstant.BOOLEAN(l != r) - else null - - case ATypeKind.STR => - if (op == Names.ADD) AConstant.STRING(lvalue.stringValue()+rvalue.stringValue()) - else null - - case _ => - null - } - } - - /** - * Casts the value to given type and returns the resulting value. - * Returns null if the cast can't be performed. - */ - def cast(value: AConstant, tpe: Type): AConstant = value.kind() match { - case UNIT => - if (tpe.isSameAs(definitions.void_TYPE())) value // !!! -> UNIT_TYPE() - else null - case BOOL => - if (tpe.isSameAs(definitions.boolean_TYPE())) value - else null - case U1 | U2 | U4 | U8 | I1 | I2 | I4 | I8 | R4 | R8 => - if (tpe.isSameAs(definitions.byte_TYPE())) - AConstant.BYTE(value.byteValue()) - else if (tpe.isSameAs(definitions.short_TYPE())) - AConstant.SHORT(value.shortValue()) - else if (tpe.isSameAs(definitions.char_TYPE())) - AConstant.CHAR(value.charValue()) - else if (tpe.isSameAs(definitions.int_TYPE())) - AConstant.INT(value.intValue()) - else if (tpe.isSameAs(definitions.long_TYPE())) - AConstant.LONG(value.longValue()) - else if (tpe.isSameAs(definitions.float_TYPE())) - AConstant.FLOAT(value.floatValue()) - else if (tpe.isSameAs(definitions.double_TYPE())) - AConstant.DOUBLE(value.doubleValue()) - else null - case STR => - if (tpe.isSameAs(definitions.STRING_TYPE())) value - else null - case _ => - null - } - - //######################################################################## - // Private Methods - - /** Returns the kind of given value. */ - private def kind(value: AConstant): ATypeKind = { - val k = value.kind(); - k match { - case I1 | I2 | U2 => - ATypeKind.I4 - case _ => - k - } - } - - /** - * Returns the combined kind of given values or null if the values - * can't be combined. - */ - private def kind(lvalue: AConstant, rvalue: AConstant): ATypeKind = { - val lkind = kind(lvalue); - val rkind = kind(rvalue); - if (lkind == rkind) lkind - else if (lkind == ATypeKind.ZERO) null - else if (rkind == ATypeKind.ZERO) null - else if (lkind == ATypeKind.STR) lkind - else if (rkind == ATypeKind.STR) rkind - else lkind match { - case I4 => - rkind match { - case I4 => lkind - case I8 => rkind - case R4 => rkind - case R8 => rkind - case _ => null - } - case I8 => - rkind match { - case I4 => lkind - case I8 => lkind - case R4 => rkind - case R8 => rkind - case _ => null - } - case R4 => - rkind match { - case I4 => lkind - case I8 => lkind - case R4 => lkind - case R8 => rkind - case _ => null - } - case R8 => - rkind match { - case I4 => lkind - case I8 => lkind - case R4 => lkind - case R8 => lkind - case _ => null - } - case _ => - null - } - } - - //######################################################################## -} -} diff --git a/sources/scala/tools/scalac/typechecker/Context.scala b/sources/scala/tools/scalac/typechecker/Context.scala deleted file mode 100644 index ceedc3c2e0..0000000000 --- a/sources/scala/tools/scalac/typechecker/Context.scala +++ /dev/null @@ -1,146 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ -import scalac.symtab._; -import scalac.ast._; -import scalac.util.Names; -import scalac.util.Name; -import scalac.{Global => scalac_Global} - -package scala.tools.scalac.typechecker { - -object Context { - val NONE = new Context(); - NONE.viewCache = List(); -} - -class Context { - - import Kinds._; - - var tree: Tree = _; // Tree associated with this context - var owner: Symbol = _; // The current owner - var scope: Scope = _; // The current scope - var outer: Context = _; // The next outer context - var enclClass: Context = this; // The next outer context whose tree - // is a class template - var prevImport: Context = this; // the next outer import context - var variance: int = _; // Variance relative to enclosing class. - var constructorClass: Symbol = _; // Class for auxiliary constructor - var viewCache: List[View] = null; // View symbols visible in scope - var infer: Infer = null; // Type inferencer - var depth: int = 0; - - def this(tree: Tree, owner: Symbol, scope: Scope, outer: Context) = { - this(); - this.tree = tree; - this.owner = owner; - this.scope = scope; - this.enclClass = if ((tree.isInstanceOf[Tree$Template] || - tree.isInstanceOf[Tree$CompoundType]) && - tree != outer.tree) this - else outer.enclClass; - this.prevImport = if (isImportContext && tree != outer.tree) this - else outer.prevImport; - this.variance = outer.variance; - this.constructorClass = outer.constructorClass; - this.infer = outer.infer; - this.depth = outer.depth + 1; - this.outer = outer; - } - - def this(tree: Tree, outer: Context) = - this(tree, outer.owner, outer.scope, outer); - - def outerContext(clazz: Symbol): Context = { - var c = this; - while (c != Context.NONE && c.owner != clazz) c = c.outer.enclClass; - c - } - - def isTopLevel(): boolean = tree match { - case Tree$Block(_,_) => - false - case Tree$Template(_, _) => - outer.tree.isInstanceOf[Tree$PackageDef] - case Tree.Empty => - true - case _ => - outer.isTopLevel() - } - - def isImportContext: boolean = tree.isInstanceOf[Tree$Import]; - - def importString(): String = - if (prevImport == Context.NONE) "" - else - prevImport.outer.importString() + - prevImport.tree.symbol().toString() + ";"; - - override def toString(): String = { - if (this == Context.NONE) "Context.NONE"; - else tree.toString() + "\n:: " + outer.toString() - } - - def importPrefix(): Tree = tree match { - case Tree$Import(expr, _) => expr - } - - def importType(): Type = - tree.symbol().getType(); - - def sameImport(that: Context): boolean = - this.importType().isSameAs(that.importType()); - - def importedSymbol(name: Name): Symbol = { - return TreeInfo.importedSymbol(tree, name); - } - - def viewMeths: List[View] = { - - def addView(sym: Symbol, symtype: Type, qual: Tree): unit = symtype match { - case Type$OverloadedType(alts, alttypes) => - var i = alts.length - 1; - while (i >= 0) { - addView(alts(i), alttypes(i), qual); - i = i - 1; - } - case _ => - /* - def isUnShadowed(view: View) = - view.context == this || !infer.specializes(view.symtype, symtype); - */ - if (viewCache.forall(v => v.sym != sym)) { - val v = View(sym, symtype, qual, this); - //System.out.println("VIEW " + sym + ":" + symtype + " " + qual);//DEBUG - viewCache = v :: viewCache;//.filter(isUnShadowed); - } - } - - if (viewCache == null) { - viewCache = outer.viewMeths; - if (enclClass == this) { - val sym = owner.typeOfThis().lookup(Names.view); - if (sym.kind == VAL) { - addView(sym, owner.thisType().memberType(sym), - scalac_Global.instance.treeGen.This(owner.pos, owner)); - } - } else if (scope != outer.scope) { - val e = scope.lookupEntry(Names.view); - if (e.owner == scope && e.sym.kind == VAL) - addView(e.sym, e.sym.getType(), Tree.Empty); - } - if (prevImport == this) { - val sym = importedSymbol(Names.view); - if (sym.kind == VAL) - addView(sym, importType().memberType(sym), importPrefix()); - } - } - viewCache - } -} -} diff --git a/sources/scala/tools/scalac/typechecker/DeSugarize.scala b/sources/scala/tools/scalac/typechecker/DeSugarize.scala deleted file mode 100644 index c860ae84db..0000000000 --- a/sources/scala/tools/scalac/typechecker/DeSugarize.scala +++ /dev/null @@ -1,641 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -import java.io._; -import java.lang.Object; -import java.util.ArrayList; - -import scalac._; -import scalac.{Global => scalac_Global, CompilationUnit => scalac_CompilationUnit} -import scalac.ast._; -import scalac.symtab._; -import scalac.typechecker.Infer; -import scalac.util._; - -import scala.tools.scalac.util.NewArray; - -package scala.tools.scalac.typechecker { - -/** A transformer for removing syntactic sugar. This transformer does - * not need any type or symbol-table information. - * - * @author Martin Odersky - * @version 2.0 - */ -class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala.tools.scalac.typechecker.Infer, global: scalac_Global) { - - import Kinds._, Modifiers._; - import scalac.ast.TreeList; - - def this(analyzer: Analyzer, global: scalac_Global) = - this(analyzer.make, analyzer.copy, analyzer.gen, analyzer.infer, global); - -// Auxiliary definitions and functions ------------------------------------------- - - /** introduce fresh variable of the form "ds$56" - */ - def getvar(unit: scalac_CompilationUnit): Name = unit.fresh.newName("ds", '$'); - - def setterName(name: Name): Name = Name.fromString(name.toString() + Names._EQ); - - def parameterName(i: int): Name = Name.fromString("x$" + i); - - def tupleSelectorName(i: int): Name = Name.fromString("_" + i); - - /** extract variables from a pattern */ - def getVariables(tree: Tree, vars: ArrayList): unit = tree match { - case Tree$Ident(name) => - if (name.isVariable() && name != Names.PATTERN_WILDCARD) vars.add(name); - - case Tree$Typed(expr, _) => - getVariables(expr, vars); - - case Tree$Apply(fn, args) => - fn match { - case Tree$Apply(_, _) => getVariables(fn, vars); - case _ => - } - for (val i <- Iterator.range(0, args.length)) - getVariables(args(i), vars); - - case Tree$Sequence(elems) => - for (val i <- Iterator.range(0, elems.length)) - getVariables(elems(i), vars); - - case Tree$Literal( _ ) => - - case Tree$Bind(name, t) => - if (name.isVariable() && name != Names.PATTERN_WILDCARD) vars.add(name); - getVariables(t, vars); - - case Tree$Alternative(ts) => - for (val i <- Iterator.range(0, ts.length)) - getVariables(ts(i), vars); - } - -// Transform functions ----------------------------------------------------- - - /** (T_1, ..., T_N) => T ==> scala.FunctionN[T_1, ..., T_N, +T] - */ - def FunType(tree: Tree): Tree = tree match { - case Tree$FunType(argtpes, restpe) => - mkFunType(tree.pos, argtpes, restpe) - } - - def mkFunType(pos: int, argtpes: Array[Tree], restpe: Tree): Tree = { - val types = new Array[Tree](argtpes.length + 1); - System.arraycopy(argtpes, 0, types, 0, argtpes.length); - types(argtpes.length) = restpe; - make.AppliedType( - pos, - make.Select( - pos, - make.Ident(pos, Names.scala), - Name.fromString("Function" + argtpes.length).toTypeName()), - types); - } - - def mkTuple(pos: int, trees: Array[Tree]): Tree = - if (trees.length == 0) - gen.mkUnitLit(pos); - else - make.Apply( - pos, - make.Select( - pos, - make.Ident(pos, Names.scala), - Name.fromString("Tuple" + trees.length)), - trees); - - /** Convert method to function type. - */ - def meth2fun(tp: Type): Type = tp match { - case Type$MethodType(params, restype) => - global.definitions.FUNCTION_TYPE( - Symbol.getType(params), meth2fun(restype)); - case _ => - tp - } - - /** If `pt' is a matching function type insert missing parameters - * in `vparams' from it, return: and result type, - * else return AnyType. - */ - def preFunction(vparams: Array[Tree$ValDef], pt: Type): Type = pt match { - case Type$TypeRef(pre, psym, ptargs) - if (ptargs.length == vparams.length + 1 && - vparams.length < global.definitions.FUNCTION_CLASS.length && - psym == global.definitions.FUNCTION_CLASS(vparams.length)) => - - def assignType(vparam: Tree$ValDef, pt: Type): unit = - if (vparam.tpe == Tree.Empty && infer.isFullyDefined(pt)) - vparam.tpe = gen.mkType(vparam.pos, pt); - - for (val i <- Iterator.range(0, vparams.length)) - assignType(vparams(i), ptargs(i)); - - ptargs(vparams.length); - - case _ => - Type.AnyType - } - - def isDefinedAtVisitor(tree: Tree): Tree = tree match { - case Tree$Visitor(cases) => - val lastCase = cases(cases.length - 1); - lastCase match { - case Tree$CaseDef(Tree$Ident(name), Tree.Empty, expr) if (name.isVariable()) => - make.Visitor( - tree.pos, - NewArray.CaseDef( - make.CaseDef( - lastCase.pos, - lastCase.pat.duplicate(), - Tree.Empty, - gen.mkBooleanLit(lastCase.body.pos, true)))); - case _ => - val cases1 = new Array[Tree$CaseDef](cases.length + 1); - for (val i <- Iterator.range(0, cases.length)) { - cases(i) match { - case Tree$CaseDef(pat, guard, _) => - cases1(i) = make.CaseDef( - cases(i).pos, - pat.duplicate(), - guard.duplicate(), - gen.mkBooleanLit(tree.pos, true)); - } - } - cases1(cases.length) = make.CaseDef( - tree.pos, - gen.Ident(tree.pos, global.definitions.PATTERN_WILDCARD), - Tree.Empty, - gen.mkBooleanLit(tree.pos, false)); - make.Visitor(tree.pos, cases1); - } - } - - /** match => this.match - * match[targs] => this.match[targs] - * IMPORTANT: tree is already attributed and attributes need to be preserved. - */ - def postMatch(tree: Tree, currentclazz: Symbol): Tree = tree match { - case Tree$Ident(name) => - make.Select( - tree.pos, - gen.This(tree.pos, currentclazz), - name).setSymbol(tree.symbol()).setType(tree.getType()); - case Tree$TypeApply(fn, args) => - copy.TypeApply(tree, postMatch(fn, currentclazz), args); - case _ => - tree - } - - /** { cases } ==> (x => x.match {cases}) - * only called when match has to be added - * no type for parameter x - */ - def Visitor(unit: scalac_CompilationUnit, tree: Tree): Tree = tree match { - case Tree$Visitor(cases) => - val x: Name = getvar(unit); - val param: Tree$ValDef = make.ValDef( - tree.pos, PARAM, x, Tree.Empty, Tree.Empty); - val xuse: Tree = make.Ident(tree.pos, x); - // x.match {cases} - val body: Tree = make.Apply( - tree.pos, - make.Select(tree.pos, xuse, Names._match), - NewArray.Tree(tree)); - make.Function(tree.pos, NewArray.ValDef(param), body); - } - - /** e = e' ==> e_=(e') - */ - def Assign(pos: int, lhs: Tree, rhs: Tree): Tree = { - val lhs1 = lhs match { - case Tree$Ident(name) => - make.Ident(lhs.pos, setterName(name)); - case Tree$Select(qual, name) => - make.Select(lhs.pos, qual, setterName(name)); - } - make.Apply(pos, lhs1, NewArray.Tree(rhs)); - } - - /** e(args) = e' ==> e.update(args ; e') - */ - def Update(tree: Tree): Tree = tree match { - case Tree$Assign(Tree$Apply(fn, args), rhs) => - // e.update - val update: Tree = make.Select(fn.pos, fn, Names.update); - val args1 = new Array[Tree](args.length + 1); - System.arraycopy(args, 0, args1, 0, args.length); - args1(args.length) = rhs; - make.Apply(tree.pos, update, args1); - } - - /** Remove the DocDef shell, if any. - */ - def unboxDocDef(tree: Tree): Tree = tree match { - case Tree$DocDef(_, definition) => definition - case _ => tree - } - - /** If "tree" is a DocDef, add its comment to "trees". - */ - def boxDocDef(trees: Array[Tree], tree: Tree): Array[Tree] = { - tree match { - case Tree$DocDef(comment, _) => - for (val i <- Iterator.range(0, trees.length)) - trees(i) = make.DocDef(tree.pos, comment, trees(i)) - case _ => - } - trees - } - - /** expand pattern definitions and variable definitions in templates. - */ - def Statements(unit: scalac_CompilationUnit, stats: Array[Tree], isLocal: boolean): Array[Tree] = { - var change: boolean = false; - var i = 0; - while (i < stats.length && !change) { - unboxDocDef(stats(i)) match { - case Tree$PatDef(_, _, _) => - change = true; - case Tree$ValDef(_, _, _, _) => - change = !isLocal; - case _ => - } - i = i + 1 - } - if (change) { - val ts: TreeList = new TreeList(); - for (val i <- Iterator.range(0, stats.length)) { - val stat = unboxDocDef(stats(i)); - stat match { - case Tree$PatDef(_, _, _) => - ts.append(boxDocDef(Statements(unit, this.PatDef(unit, stat), isLocal), stats(i))); - case Tree$ValDef(_, _, _, _) => - if (isLocal) ts.append(stats(i)) - else ts.append(boxDocDef(this.ValDef(stat), stats(i))); - case _ => - ts.append(stats(i)); - } - } - ts.toArray() - } else { - stats; - } - } - - /** expands view-bounded class and method definitions - */ - def Definition(tree: Tree): Tree = - tree match { - case Tree$ClassDef(mods, name, tparams, vparams, tpe, templ) => - //System.out.println("DEF " + make.ClassDef(tree.pos, mods, name, tparams, addViewParams(tparams, vparams), tpe, templ));//DEBUG - make.ClassDef(tree.pos, mods, name, tparams, - addViewParams(tparams, vparams), tpe, templ); - - case Tree$DefDef(mods, name, tparams, vparams, tpe, rhs) => - //System.out.println("DEF " + make.DefDef(tree.pos, mods, name, tparams, addViewParams(tparams, vparams), tpe, rhs));//DEBUG - make.DefDef(tree.pos, mods, name, tparams, - addViewParams(tparams, vparams), tpe, rhs) - - case Tree$DocDef(comment, definition) => - make.DocDef(tree.pos, comment, Definition(definition)) - - case _ => - tree - } - - def addViewParams(tparams: Array[Tree$AbsTypeDef], vparams: Array[Array[Tree$ValDef]]): Array[Array[Tree$ValDef]] = { - var viewparams = new TreeList(); - var i = 0; - while (i < tparams.length) { - tparams(i) match { - case Tree$AbsTypeDef(mods, tname, rhs, _) if (mods & VIEWBOUND) != 0 => - viewparams.append( - make.ValDef( - tparams(i).pos, - PARAM | SYNTHETIC, - Names.view, - mkFunType( - tparams(i).pos, - NewArray.Tree(make.Ident(tparams(i).pos, tname)), - rhs.duplicate()), - Tree.Empty)); - case _ => - } - i = i + 1 - } - if (viewparams.length() > 0) { - val vparams1 = new Array[Array[Tree$ValDef]](vparams.length + 1); - vparams1(0) = new Array[Tree$ValDef](viewparams.length()); - viewparams.copyTo(vparams1(0)); - //for (val t <- vparams1(0)) System.out.println("new view param: " + t);//DEBUG - System.arraycopy(vparams, 0, vparams1, 1, vparams.length); - vparams1 - } else vparams - } - - /** expands pattern definitions - * in case pattern is a simple (typed) identifier: - * val x = e ==> val x = e - * val x: T = e ==> val x: T = e - * - * in case there are no variables in pattern - * val p = e ==> e.match (case p => ()) - * - * in case there is exactly one variable in pattern - * val x_1 = e.match (case p => (x_1)) - * - * in case there are more variables in pattern - * val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N)) - * val x_1 = t$._1 - * ... - * val x_N = t$._N - * - */ - def PatDef(unit: scalac_CompilationUnit, tree: Tree): Array[Tree] = tree match { - case Tree$PatDef(mods, Tree$Ident(name), rhs) => - // val x = e ==> val x = e - NewArray.Tree(make.ValDef(tree.pos, mods, name, Tree.Empty, rhs)) - - case Tree$PatDef(mods, Tree$Typed(Tree$Ident(name), tpe), rhs) => - // val x: T = e ==> val x: T = e - NewArray.Tree(make.ValDef(tree.pos, mods, name, tpe, rhs)) - - case Tree$PatDef(mods, pat, rhs) => - val pos: int = tree.pos; - val varlist: ArrayList = new ArrayList(); - getVariables(pat, varlist); - val vars = new Array[Name](varlist.size()); - varlist.toArray(vars.asInstanceOf[Array[Object]]); - - // Tuple_N(x_1, ..., x_N) - val vtree = new Array[Tree](vars.length); - for (val i <- Iterator.range(0, vars.length)) { - vtree(i) = make.Ident(pos, vars(i)); - } - val tuple: Tree = if (vars.length == 1) vtree(0) - else mkTuple(tree.pos, vtree); - - // e.match (case p => Tuple_N(x_1, ..., x_N)) - val cases = NewArray.CaseDef(make.CaseDef(pos, pat, Tree.Empty, tuple)); - val matchTree: Tree = make.Apply( - pos, - make.Select(pos, rhs, Names._match), - NewArray.Tree(make.Visitor(pos, cases))); - - if (vars.length == 0) { - // e.match (case p => ()) - print(pat, "patdef", matchTree); - NewArray.Tree(matchTree); - } - else if (vars.length == 1) { - // val x_1 = e.match (case p => x_1) - val valdef: Tree = make.ValDef(pos, mods, vars(0), Tree.Empty, matchTree); - print(pat, "patdef", valdef); - NewArray.Tree(valdef) - } else { - // t$ - val vble: Name = getvar(unit); - - // private synthetic val t$ = e.match (case p => (x_1, ..., x_N)) - val res = new Array[Tree](vars.length + 1); - res(0) = make.ValDef(pos, PRIVATE | SYNTHETIC, vble, Tree.Empty, matchTree); - for (val i <- Iterator.range(0, vars.length)) { - // val x_i = t$._i - res(i + 1) = make.ValDef( - pos, mods, vars(i), Tree.Empty, - make.Select(pos, make.Ident(pos, vble), tupleSelectorName(i + 1))); - } - print(pat, "patdef", new Tree$Block(res, gen.mkUnitLit(pos)));//debug - res - } - } - - def ValDef(tree: Tree): Array[Tree] = tree match { - case Tree$ValDef(mods, name, tpe, rhs) => - val valname: Name = Name.fromString("" + name + "$"); - val valdef1: Tree = copy.ValDef( - tree, (mods & (DEFERRED | MUTABLE | PARAMACCESSOR | MODUL)) | PRIVATE, - valname, tpe, rhs).setType(null); - var mods1: int = mods | ACCESSOR; - if ((mods1 & MUTABLE) == 0) mods1 = mods1 | STABLE; - val getter: Tree = make.DefDef( - tree.pos, mods1, name, - Tree.AbsTypeDef_EMPTY_ARRAY, Tree.ValDef_EMPTY_ARRAY_ARRAY, - tpe.duplicate(), - if ((mods & DEFERRED) != 0) Tree.Empty - else make.Ident(tree.pos, valname)); - if ((mods1 & MUTABLE) == 0) { - if ((mods1 & DEFERRED) != 0) - NewArray.Tree(getter) - else - NewArray.Tree(valdef1, getter) - } else { - val setter: Tree = make.DefDef( - tree.pos, mods1, setterName(name), - Tree.AbsTypeDef_EMPTY_ARRAY, - NewArray.ValDefArray( - NewArray.ValDef( - make.ValDef( - tree.pos, SYNTHETIC | PARAM, parameterName(0), - tpe.duplicate(), Tree.Empty))), - gen.mkType(tree.pos, global.definitions.void_TYPE()), - if ((mods1 & DEFERRED) != 0) Tree.Empty - else make.Assign( - tree.pos, - make.Ident(tree.pos, valname), - make.Ident(tree.pos, parameterName(0)))); - if ((mods1 & DEFERRED) != 0) - NewArray.Tree(getter, setter) - else - NewArray.Tree(valdef1, getter, setter) - } - } - - /** Expand partial function applications of type `type'. - * - * p.f(es_1)...(es_n) - * ==> { - * private synthetic val eta$f = p.f // if p is not stable - * ... - * private synthetic val eta$e_i = e_i // if e_i is not stable - * ... - * - * (ps_1 => ... => ps_m => eta$f([es_1])...([es_m])(ps_1)...(ps_m)) - * } - * tree is already attributed - */ - def etaExpand(tree: Tree, tpe: Type): Tree = { - val defs: TreeList = new TreeList(); - val lambda: Tree = - toFunction(toApply(liftoutPrefix(tree, defs), tpe), tpe); - val result: Tree = make.Block(tree.pos, defs.toArray(), lambda); - print(tree, "eta", result);//debug - result - } - - private val preName = "eta$"; - - /** Append to `defs' value definitions for all non-stable subexpressions - * of the function application `tree' - */ - def liftoutPrefix(tree: Tree, defs: TreeList): Tree = { - - def liftoutList(trees: Array[Tree], defs: TreeList): Array[Tree] = { - var trees1 = trees; - for (val i <- Iterator.range(0, trees.length)) { - val tree: Tree = trees(i); - val tree1: Tree = liftout(tree, defs); - if (tree1 != tree && trees1 == trees) { - trees1 = new Array[Tree](trees.length); - System.arraycopy(trees, 0, trees1, 0, trees.length); - } - trees1(i) = tree1; - } - trees1; - } - - def liftout(tree: Tree, defs: TreeList): Tree = - if (TreeInfo.isPureExpr(tree)) tree - else { - val vname: Name = Name.fromString(preName + defs.length()); - defs.append( - make.ValDef( - tree.pos, SYNTHETIC, vname, Tree.Empty, tree)); - make.Ident(tree.pos, vname) - } - - tree match { - case Tree$Ident(_) => - tree; - case Tree$Select(qual, _) => - copy.Select(tree, liftout(qual, defs)).setType(null); - case Tree$TypeApply(fn, args) => - copy.TypeApply(tree, liftoutPrefix(fn, defs), args).setType(null); - case Tree$Apply(fn, args) => - copy.Apply(tree, liftoutPrefix(fn, defs), liftoutList(args, defs)).setType(null); - } - } - - /** in patterns x => x @ _ - * precondition: name != '_' - * post: returns *unattributed* Bind tree - */ - - def IdentPattern(tree: Tree): Tree = tree match { - case Tree$Ident(name) => - if (name == Names.PATTERN_WILDCARD) - throw new ApplicationError("nothing to desugarize"); - make.Bind( - tree.pos, - name, - gen.Ident(tree.pos, global.definitions.PATTERN_WILDCARD)) - .setType(tree.getType()); - } - - /** in patterns x:T => x @ _ : T - * pre: t is a typed variable. - * post: returns *unattributed* Bind tree - */ - def TypedPattern(t: Tree$Typed): Tree = t match { - case Tree$Typed(Tree$Ident(name), tpe) => - make.Bind( - t.pos, - name, - make.Typed( - t.pos, - gen.Ident(t.pos, global.definitions.PATTERN_WILDCARD), - tpe)); - } - - /** f, (syms_1)...(syms_n)T ==> f(ps_1)...(ps_n) - */ - def toApply(tree: Tree, tpe: Type): Tree = tpe match { - case Type$MethodType(vparams, restpe) => - val res: Tree = make.Apply(tree.pos, tree, toIdents(vparams)); - toApply(res, restpe); - case _ => - tree - } - - /** e, (syms_1)...(syms_n)T ==> (ps_1 => ... => ps_n => e) - */ - def toFunction(tree: Tree, tpe: Type): Tree = tpe match { - case Type$MethodType(vparams, restpe) => - make.Function(tree.pos, toVparams(vparams), toFunction(tree, restpe)); - case _ => - tree - } - - /** Extract value parameters from type. - */ - def toVparams(symbols: Array[Symbol]): Array[Tree$ValDef] = { - val vpars = new Array[Tree$ValDef](symbols.length); - for (val i <- Iterator.range(0, symbols.length)) { - vpars(i) = make.ValDef( - symbols(i).pos, PARAM | SYNTHETIC, symbols(i).name, - gen.mkType(symbols(i).pos, symbols(i).getType()), - Tree.Empty); - } - vpars - } - - /** Extract value identifiers from method type. - * It is assumed that all symbols are term symbols ==> make.Ident(). - */ - def toIdents(symbols: Array[Symbol]): Array[Tree] = { - val idents = new Array[Tree](symbols.length); - for (val i <- Iterator.range(0, symbols.length)) { - idents(i) = make.Ident(symbols(i).pos, symbols(i).name); - } - idents.asInstanceOf[Array[Tree]]; - } - - /** Build value element definition name for case parameter. - */ - def addParamAccessor(ts: TreeList, vparam: Tree$ValDef): unit = { - if ((vparam.symbol().owner().constructorClass().flags & CASE) != 0) - vparam.mods = vparam.mods | PARAMACCESSOR; - if ((vparam.mods & PARAMACCESSOR) != 0) - ts.append( - make.DefDef( - vparam.pos, (vparam.mods & ~PARAM) | STABLE, vparam.name, - Tree.AbsTypeDef_EMPTY_ARRAY, Tree.ValDef_EMPTY_ARRAY_ARRAY, - Tree.Empty, - make.Ident(vparam.pos, vparam.name) - .setSymbol(vparam.symbol()))) - } - - /** add case constructor, definitions value and access functions. - */ - def addParamAccessors(body: Array[Tree], vparams: Array[Tree$ValDef]): Array[Tree] = { - val stats: TreeList = new TreeList(); - for (val i <- Iterator.range(0, vparams.length)) { - addParamAccessor(stats, vparams(i)); - } - if (stats.length() == 0) body - else { - stats.append(body); - stats.toArray() - } - } - - //debug - def print(tree: Tree, conv: String, result: Tree): unit = { - if (global.log()) { - System.out.println(tree); - System.out.println(" --" + conv + "--> "); - System.out.println(tree); - } - } -} -} diff --git a/sources/scala/tools/scalac/typechecker/ImportList.scala b/sources/scala/tools/scalac/typechecker/ImportList.scala deleted file mode 100644 index 0ff717965a..0000000000 --- a/sources/scala/tools/scalac/typechecker/ImportList.scala +++ /dev/null @@ -1,47 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ - -import scalac._; -import scalac.util._; -import scalac.symtab._; -import scalac.ast._; - -package scala.tools.scalac.typechecker { - -///////////////////////////////////////////////////////////////////////////// -// Import Lists -///////////////////////////////////////////////////////////////////////////// - -/** A class for import expressions -* @param tree The import definition -* @param enclScope The scope in which the import occurs. -* @param prev The previous active import list. -*/ -case class ImportList(tree: Tree, enclScope: Scope, prev: ImportList) { - - override def toString(): String = { - var str = tree.symbol().toString(); - if (prev != null) str = "" + prev + "; " + str; - str - } - - def importPrefix(): Tree = tree match { - case Tree$Import(expr, _) => expr - } - - def importType(): Type = - tree.symbol().getType(); - - def sameImport(that: ImportList): boolean = - this.importType().isSameAs(that.importType()); - - def importedSymbol(name: Name): Symbol = { - return TreeInfo.importedSymbol(tree, name); - } -} -} diff --git a/sources/scala/tools/scalac/typechecker/Infer.scala b/sources/scala/tools/scalac/typechecker/Infer.scala deleted file mode 100644 index 69b74f8adc..0000000000 --- a/sources/scala/tools/scalac/typechecker/Infer.scala +++ /dev/null @@ -1,1428 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import java.lang.Object; - -import scalac.{Global => scalac_Global} -import scalac.symtab._; -import scalac.typechecker.{Infer => scalac_Infer} -import scalac.ApplicationError; -import scalac.util._; -import scalac.ast._; -import scala.collection.mutable.HashMap; -import scala.tools.util.Position; - -import scala.tools.scalac.util.NewArray; - -package scala.tools.scalac.typechecker { - -class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scalac_Infer { - - import Modifiers._, Kinds._; - - val definitions: Definitions = global.definitions; - val substituter: Substituter = new Substituter(global, gen); - - def this(trans: Transformer) = this(trans.global, trans.gen, trans.make); - -// Context accessor and error function, overridable */ - - def getContext: Context = Context.NONE; - - def error(pos: int, msg: String): unit = - throw new Type$Error(msg); - - -// Error messages ------------------------------------------------------------- - - def applyErrorMsg(msg1: String, fn: Tree, msg2: String, argtypes: Array[Type], pt: Type): String = - msg1 + toString(fn.symbol(), fn.getType()) + msg2 + - ArrayApply.toString(argtypes.asInstanceOf[Array[Object]], "(", ",", ")") + - (if (pt == Type.AnyType) "" else " with expected result type " + pt); - - def typeErrorMsg(msg: String, found: Type, req: Type): String = - msg + ";\n found : " + found.toLongString() + "\n required: " + req; - - def overloadResolveErrorMsg(sym1: Symbol, tpe1: Type, sym2: Symbol, tpe2: Type): String = - "ambiguous reference to overloaded definition,\n" + - "both " + sym1 + ": " + tpe1 + "\n" + - "and " + sym2 + ": " + tpe2 + "\nmatch"; - - /** Give a string representation of symbol `sym' with type `tp' - * for error diagnostics. `sym' may be null. - */ - def toString(sym: Symbol, tp: Type): String = - (if (tp.isInstanceOf[Type$OverloadedType]) "overloaded " else "") + - (if (sym == null) "expression" else sym) + " of type " + tp; - -// Variance calculation ---------------------------------------------------------- - - private def flip(v: int): int = { - if (v == COVARIANT) CONTRAVARIANT; - else if (v == CONTRAVARIANT) COVARIANT; - else v - } - - private def cut(v: int): int = { - if (v == VARIANCES) v - else 0 - } - - /** Compute variances of all type parameters `tparams' in type `tp'. - * A variance is taken from the four point lattice - * - * 0, Modifiers.COVARIANT, Modifiers.CONTRAVARIANT, Modifiers.VARIANCES. - */ - private def variance(tparams: Array[Symbol], tp: Type): Array[int] = { - val vs: Array[int] = new Array[int](tparams.length); - { var i = 0; while (i < vs.length) { - vs(i) = variance(tparams(i), tp); - i = i + 1; - }} - vs - } - - /** Compute variances of all type parameters `tparams' in types `tps'. - */ - private def variance(tparams: Array[Symbol], tps: Array[Type]): Array[int] = { - val vs: Array[int] = new Array[int](tparams.length); - { var i = 0; while (i < vs.length) { - vs(i) = variance(tparams(i), tps); - i = i + 1; - }} - vs - } - - /** Compute variance of type parameter `tparam' in types of all symbols `sym'. - */ - private def variance(tparam: Symbol, syms: Array[Symbol]): int = { - var v: int = VARIANCES; - { var i = 0; while (i < syms.length) { - v = v & variance(tparam, syms(i)); - i = i + 1; - }} - v - } - - /** Compute variance of type parameter `tparam' in type of symbol `sym'. - */ - private def variance(tparam: Symbol, sym: Symbol): int = sym.kind match { - case VAL => - variance(tparam, sym.info()) - case TYPE => - variance(tparam, sym.info()) & - flip(variance(tparam, sym.loBound())) & - variance(tparam, sym.vuBound()) - case ALIAS => - cut(variance(tparam, sym.info())) - case _ => - 0 - } - - /** Compute variance of type parameter `tparam' in all types `tps'. - */ - private def variance(tparam: Symbol, tps: Array[Type]): int = { - var v: int = VARIANCES; - { var i = 0; while (i < tps.length) { - v = v & variance(tparam, tps(i)); - i = i + 1; - }} - v - } - - /** Compute variance of type parameter `tparam' in all type arguments - * `tps' which correspond to formal type parameters `tparams'. - */ - private def varianceInArgs(tvar: Symbol, tps: Array[Type], tparams: Array[Symbol]): int = { - var v: int = VARIANCES; - { var i = 0; while (i < tps.length) { - if ((tparams(i).flags & COVARIANT) != 0) { - v = v & variance(tvar, tps(i)); - } else if ((tparams(i).flags & CONTRAVARIANT) != 0) { - v = v & flip(variance(tvar, tps(i))); - } else { - v = v & cut(variance(tvar, tps(i))); - } - i = i + 1; - }} - v - } - - /** Compute variance of type parameter `tparam' in type `tp'. - */ - private def variance(tparam: Symbol, tp: Type): int = tp match { - case Type.ErrorType | Type.AnyType | Type.NoType | Type.NoPrefix | - Type$ThisType(_) | Type$ConstantType(_, _) => - VARIANCES - case Type$TypeRef(pre, sym, args) => - if (sym == tparam) COVARIANT - else variance(tparam, pre) & varianceInArgs(tparam, args, sym.typeParams()) - case Type$SingleType(pre, sym) => - cut(variance(tparam, pre)) - case Type$CompoundType(parts, members) => - variance(tparam, parts) & variance(tparam, members.elements()) - case Type$MethodType(params, restype) => - flip(variance(tparam, params)) & variance(tparam, restype) - case Type$PolyType(tparams, restype) => - flip(variance(tparam, tparams)) & variance(tparam, restype) - } - -// Accessibility ------------------------------------------------------------ - - /** Check that `sym' is accessible as a member of tree `site' in current context. - */ - def checkAccessible(pos: int, sym: Symbol, symtype: Type, site: Tree, sitetype: Type): Type = { - //System.out.println("check acc " + sym);//DEBUG - if ((sym.owner().flags & INCONSTRUCTOR) != 0 && - !(sym.kind == TYPE && sym.isParameter()) && - (site == Tree.Empty || site.isInstanceOf[Tree$This])) { - error(pos, "" + sym + " cannot be accessed from constructor"); - Type.ErrorType; - } else { - symtype match { - case Type$OverloadedType(alts, alttypes) => - var nacc: int = 0; - var i = 0; while (i < alts.length) { - if (isAccessible(alts(i), site, sitetype)) - nacc = nacc + 1; - i = i + 1 - } - if (nacc == 0) { - error(pos, "" + sym + " cannot be accessed in " + sitetype.widen()); - Type.ErrorType - } else { - val alts1: Array[Symbol] = new Array[Symbol](nacc); - val alttypes1: Array[Type] = new Array[Type](nacc); - nacc = 0; - var i = 0; while (i < alts.length) { - if (isAccessible(alts(i), site, sitetype)) { - alts1(nacc) = alts(i); - alttypes1(nacc) = alttypes(i); - nacc = nacc + 1; - } - i = i + 1 - } - new Type$OverloadedType(alts1, alttypes1) - } - case _ => - if (isAccessible(sym, site, sitetype)) { - symtype - } else { - error(pos, "" + sym + " cannot be accessed in " + sitetype.widen()); - Type.ErrorType - } - } - } - } - - /** Is `sym' accessible as a member of tree `site' in current context? - */ - private def isAccessible(sym: Symbol, site: Tree, sitetype: Type): boolean = { - - /** Are we inside definition of `owner'? - */ - def accessWithin(owner: Symbol): boolean = { - var c: Context = getContext; - while (c != Context.NONE && c.owner != owner) { - c = c.outer.enclClass; - } - c != Context.NONE; - } - - /** Is `clazz' a subclass of an enclosing class? - */ - def isSubClassOfEnclosing(clazz: Symbol): boolean = { - var c: Context = getContext; - while (c != Context.NONE && !clazz.isSubClass(c.owner)) { - c = c.outer.enclClass; - } - c != Context.NONE; - } - - site == Tree.Empty - || - (sym.flags & (PRIVATE | PROTECTED)) == 0 - || - {val owner = if (sym.isConstructor()) sym.constructorClass() - else sym.owner(); - accessWithin(owner) - || - ((sym.flags & PRIVATE) == 0) && - (site.isInstanceOf[Tree$Super] || - (sitetype.symbol().isSubClass(owner) && - isSubClassOfEnclosing(sitetype.symbol()))) - } - } - -// Views --------------------------------------------------------------------- - - val memberViewCache = new HashMap[Symbol, List[View]]; - - /** Return all views which are members of one of the objects associated - * with the base types of `tp'. - */ - private def memberViews(tp: Type): List[View] = { - val tpsym = tp.widen().symbol(); - memberViewCache.get(tpsym) match { - case Some(vs) => vs - case None => - var vs = companionObjViews(tp, tpsym); - val ps = tpsym.parents(); - var i = ps.length - 1; while (i >= 0) { - vs = memberViews(ps(i)) ::: vs; - i = i - 1 - } - memberViewCache.update(tpsym, vs); - vs - } - } - - /** Return all views which are member of the companion object of - * base class `clazz' of type `tp', empty if no companion object exists. - */ - private def companionObjViews(tp: Type, clazz: Symbol): List[View] = { - if (clazz.kind == CLASS && !clazz.isModuleClass() && !clazz.isCaseClass()) { - var obj = clazz.owner().info().lookupNonPrivate(clazz.name.toTermName()); - if (obj.isExternal() == clazz.isExternal()) { - //System.out.println("comp obj view " + tp + " " + obj);//DEBUG - obj.getType() match { - case Type$OverloadedType(alts, alttypes) => - var i = 0; while (i < alts.length) { - if (alts(i).isModule()) obj = alts(i); - i = i + 1 - } - case _ => - } - if (obj.isModule()) { - val qual = if (tp.prefix() == Type.NoType) Tree.Empty - else gen.mkRef(Position.NOPOS, tp.prefix(), obj); - val viewsym = obj.info().lookupNonPrivate(Names.view); - if (viewsym.kind == VAL) { - obj.getType().memberType(viewsym) match { - case Type$OverloadedType(alts, alttypes) => - var i = alttypes.length - 1; - var vs: List[View] = List(); - while (i >= 0) { - vs = View(alts(i), alttypes(i), qual, Context.NONE) :: vs; - i = i - 1 - } - vs - case viewtype => - List(View(viewsym, viewtype, qual, Context.NONE)) - } - } else List() - } else List() - } else List() - } else List() - } - - /** Return all available views for type `tp' - */ - private def availableViews(tp: Type): List[View] = { - //System.out.println("view for " + tp + " = " + (memberViews(tp) ::: getContext.viewMeths));//DEBUG - memberViews(tp) ::: getContext.viewMeths - } - - def containsSymbol(syms: Array[Symbol], sym: Symbol): boolean = { - var i = 0; - while (i < syms.length && syms(i) != sym) i = i + 1; - i < syms.length - } - - def isContractive(tp: Type): boolean = { - tp match { - case Type$PolyType(tparams, tp1) => - skipViewParams(tparams, tp1) match { - case Type$MethodType(vparams, _) => - vparams.length != 1 || - !containsSymbol(tparams, vparams(0).getType().symbol()) - case _ => true - } - case _ => true - } - } - - /** Construct a tree referring to the view method in `v' at position `pos'. - */ - def viewExpr(pos: int, v: View): Tree = { - val viewType = checkAccessible( - pos, v.sym, v.symtype, v.qual, v.qual.getType()); - v.qual match { - case Tree.Empty => - make.Ident(pos, v.sym.name) - .setSymbol(v.sym).setType(viewType) - case _ => - val qual = v.qual.duplicate(); - qual.pos = pos; - make.Select(pos, qual, v.sym.name) - .setSymbol(v.sym).setType(viewType) - } - } - - /** Construct a function value tree from method reference `meth'. - */ - private def viewObj(meth: Tree): Tree = meth.getType() match { - case Type$MethodType(params: Array[Symbol], _) => - assert(params.length == 1); - val paramsym = params(0).cloneSymbol(getContext.owner); - gen.mkFunction( - meth.pos, - NewArray.ValDef(gen.mkParam(paramsym)), - gen.Apply(meth, NewArray.Tree(gen.Ident(meth.pos, paramsym))), - meth.getType().resultType(), - getContext.owner, - false) - case _ => - meth - } - - /** Construct an implicit view argument for a formal type parameter - * with type `vtype'. `targs' is the vector of type arguments - * in the current application for which a view argument is needed. - * This is needed for error diagnostics only. - */ - private def viewArg(pos: int, vtype: Type, targs: Array[Type]): Tree = { - val vargs = vtype.typeArgs(); - if (vargs(0).isSubType(vargs(1))) { - gen.mkNullLit(pos) - } else { - val v = bestView(vargs(0), vargs(1), Names.EMPTY); - if (v != null && !v.locked) { - if (v.locked) { - error(pos, "recursive view instantiation of non-contractive " + - v.sym + v.sym.locationString() + " with type " + - v.sym.getType()); - gen.mkDefaultValue(pos, vtype) - } else { - v.locked = !isContractive(v.symtype); - var vmeth = viewExpr(pos, v); - vmeth.getType() match { - case Type$PolyType(vtparams, vrestype) => - assert(vtparams.length != 0); - vmeth = exprInstance(vmeth, vtparams, vrestype, vtype); - case _ => - } - val vobj = viewObj(vmeth); - if (!vobj.getType().isSubType(vtype)) - assert(false, "view argument " + vobj + ":" + vobj.getType() + " is not a subtype of view param type " + vtype); - v.locked = false; - vobj - } - } else { - error(pos, - "type instantiation with [" + - ArrayApply.toString(targs.asInstanceOf[Array[Object]], ",") + - "] failed since " + vargs(0) + " is not viewable as " + vargs(1)); - gen.mkDefaultValue(pos, vtype) - } - } - } - - /** Augment type application tree with implicit view arguments. - * @param tree The type application - * @param tparams The formal parameters of the application. - * @param restype The result type of the type application (which - * must be a method type containing the view parameters, - * unless it is an error type. - * @param targs The actual type arguments. - */ - private def passViewArgs(tree: Tree, tparams: Array[Symbol], restype: Type, - targs: Array[Type]): Tree = - restype match { - case Type$MethodType(params, _) => - val viewargs = new Array[Tree](params.length); - var i = 0; while (i < params.length) { - viewargs(i) = viewArg( - tree.pos, params(i).getType().subst(tparams, targs), targs); - i = i + 1 - } - //System.out.println("new view args: " + gen.Apply(tree, viewargs));//DEBUG - gen.Apply(tree, viewargs); - case Type.ErrorType => - tree - } - - /** Do type parameters `tparams' contain a view bounded parameter? - */ - def isViewBounded(tparams: Array[Symbol]) = { - var viewbounded = false; - var j = 0; while (j < tparams.length) { - viewbounded = viewbounded | tparams(j).isViewBounded(); - j = j + 1 - } - viewbounded - } - - /** Skip view parameters in type `tp' in the case where `tparams' contains - * a view bound. - */ - def skipViewParams(tparams: Array[Symbol], tp: Type): Type = tp match { - case Type$MethodType(_, restp) if isViewBounded(tparams) => - restp - case _ => - tp - } - - /** If tree is a type application, pass implicit view arguments where - * necessary. - */ - def completeTypeApply(tree: Tree): Tree = { - //System.out.println("complete type apply: " + tree + ":" + tree.getType());//DEBUG - tree match { - case Tree$TypeApply(fn, targs) => - fn.getType() match { - case Type$PolyType(tparams, restp) if tparams.length == targs.length => - if (isViewBounded(tparams)) { - val result = passViewArgs(tree, tparams, restp, Tree.typeOf(targs)); - //System.out.println("completed type apply: " + result + ":" + result.getType());//DEBUG - result - } else tree - case _ => tree - } - case _ => tree - } - } - -// Type parameter inference ----------------------------------------------------- - - private class NoInstance(msg: String) extends RuntimeException(msg); - - /** map every TypeVar to its constraint.inst field. - * throw a NoInstance exception if a NoType or AnyType is encountered. - */ - private val instantiateMap: Type$Map = new Type$Map() { - def apply(t: Type): Type = instantiate(t) - } - - private def instantiate(tp: Type): Type = tp match { - case Type.AnyType | Type.NoType => - throw new NoInstance("undetermined type"); - case Type$TypeVar(origin, constr) => - if (constr.inst != Type.NoType) instantiate(constr.inst) - else throw new NoInstance("no unique instantiation of type variable " + - origin + " could be found"); - case _ => - instantiateMap.map(tp) - } - - /** Map type variable to its instance, or, if `covariant' is true, - * to its upper bound; - */ - private def instantiateToBound(tp: Type, variance: int): Type = tp match { - case Type$TypeVar(origin, constr) => - try { - if (constr.inst != Type.NoType) { - instantiate(constr.inst) - } else if ((variance & COVARIANT) != 0 && constr.hibounds != Type$List.EMPTY) { - maximizeVar(tp); - instantiate(constr.inst) - } else if ((variance & CONTRAVARIANT) != 0 && constr.lobounds != Type$List.EMPTY) { - minimizeVar(tp); - instantiate(constr.inst) - } else { - Type.AnyType; - } - } catch { - case ex: NoInstance => Type.AnyType - } - } - - /** The formal parameter types corresponding to `params'. - * If `params' has a repeated last parameter, a list of - * (nargs - params.length + 1) copies of its type is returned. - */ - def formalTypes(params: Array[Symbol], nargs: int): Array[Type] = { - if (nargs >= params.length - 1 && params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) { - val args: Array[Type] = params(params.length-1).getType().typeArgs(); - if (args.length == 1) { - val ft: Type = args(0); // last param has type Seq[T], we need T here - val formals: Array[Type] = new Array[Type](nargs); - var i = 0; - while (i < params.length-1) { - formals(i) = params(i).getType(); - i = i + 1; - } - while (i < nargs) { - formals(i) = ft; - i = i + 1; - } - return formals; - } - } - Symbol.getType(params); - } - - /** Is type fully defined, i.e. no embedded anytypes or typevars in it? - */ - def isFullyDefined(tp: Type): boolean = { - try { - instantiate(tp); - true - } catch { - case ex: NoInstance => false - } - } - - /** Do type arguments `targs' conform to formal parameters `tparams'? - */ - private def isWithinBounds(tparams: Array[Symbol], targs: Array[Type]): boolean = { - var i = 0; - while (i < targs.length) { - val hibound: Type = tparams(i).info().subst(tparams, targs); - if (!targs(i).isSubType(hibound)) { - var j = 0; - while (j < tparams.length) { - if (hibound.symbol() == tparams(j)) - return isWithinBounds( - tparams, - Type.subst( - targs, - NewArray.Symbol(tparams(j)), - NewArray.Type(targs(i)))); - j = j + 1 - } - return false; - } - val lobound: Type = tparams(i).loBound().subst(tparams, targs); - if (!lobound.isSubType(targs(i))) { - var j = 0; - while (j < tparams.length) { - if (lobound.symbol() == tparams(j)) - return isWithinBounds( - tparams, - Type.subst( - targs, - NewArray.Symbol(tparams(j)), - NewArray.Type(targs(i)))); - j = j + 1 - } - return false - } - i = i + 1 - } - true - } - - /** throw a type error if arguments not within bounds. - */ - def checkBounds(tparams: Array[Symbol], targs: Array[Type], prefix: String): unit = - if (!isWithinBounds(tparams, targs)) - throw new Type$Error( - prefix + "type arguments " + - ArrayApply.toString(targs.asInstanceOf[Array[Object]], "[", ",", "]") + - " do not conform to " + - tparams(0).owner() + "'s type parameter bounds " + - ArrayApply.toString(Symbol.defString(tparams).asInstanceOf[Array[Object]], "[", ",", "]")); - - /** Instantiate variable to glb of its high bounds. - */ - private def maximizeVar(tp: Type): unit = tp match { - case Type$TypeVar(origin, constr) => - if (constr.inst == Type.NoType) - constr.inst = Type.glb(constr.hibounds.toArray()); - } - - /** Instantiate variable to lub of its low bounds. - */ - private def minimizeVar(tp: Type): unit = tp match { - case Type$TypeVar(origin, constr) => - if (constr.inst == Type.NoType) - constr.inst = Type.lub(constr.lobounds.toArray()); - } - - /** Solve constraint collected in types `tvars', instantiating `tvars(i)' - * in the process. - * @param tparams The type parameters corresponding to `tvars' - * @param upper When `true' search for max solution else min. - * @param variances The variances of type parameters; need to reverse - * solution direction for all contravariant variables. - * @param tvars All type variables to be instantiated. - * @param i The index of the type variable to be instantiated. - */ - private def solve(tparams: Array[Symbol], upper: boolean, variances: Array[int], tvars: Array[Type], i: int): unit = { - if (tvars(i) != Type.NoType) { - tvars(i) match { - case Type$TypeVar(origin, constr) => - if (constr.inst != Type.NoType) { - constr.inst = instantiate(constr.inst); - tvars(i) = constr.inst; - } else { - val tvar: Type = tvars(i); - val up: boolean = if (variances(i) != CONTRAVARIANT) upper - else !upper; - tvars(i) = Type.NoType; - val bound: Type = if (up) tparams(i).info() else tparams(i).loBound(); - var cyclic: boolean = false; - { var j = 0; while (j < tvars.length) { - if (bound.contains(tparams(j)) || - up && tparams(j).loBound().isSameAs(tparams(i).getType()) || - !up && tparams(j).info().isSameAs(tparams(i).getType())) { - cyclic = cyclic | tvars(j) == Type.NoType; - solve(tparams, upper, variances, tvars, j); - } - j = j + 1 - }} - if (!cyclic) { - if (up) { - if (bound.symbol() != definitions.ANY_CLASS) - constr.hibounds = new Type$List( - bound.subst(tparams, tvars), constr.hibounds); - { var j = 0; while (j < tvars.length) { - if (tparams(j).loBound().isSameAs( - tparams(i).getType())) { - constr.hibounds = new Type$List( - tparams(j).getType().subst(tparams, tvars), - constr.hibounds); - } - j = j + 1 - }} - } else { - if (bound.symbol() != definitions.ALL_CLASS) - constr.lobounds = new Type$List( - bound.subst(tparams, tvars), constr.lobounds); - { var j = 0; while (j < tvars.length) { - if (tparams(j).info().isSameAs( - tparams(i).getType())) { - constr.lobounds = new Type$List( - tparams(j).getType().subst(tparams, tvars), - constr.lobounds); - } - j = j + 1 - }} - } - } - if (up) maximizeVar(tvar); - else minimizeVar(tvar); - tvars(i) = tvar.asInstanceOf[Type$TypeVar].constr.inst; - } - case _ => - } - } - } - - /** Generate an array of fresh type variables corresponding to parameters - * `tparams' - */ - def freshVars(tparams: Array[Symbol]): Array[Type] = { - val tvars: Array[Type] = new Array[Type](tparams.length); - { var i = 0; while (i < tvars.length) { - tvars(i) = new Type$TypeVar(tparams(i).getType(), new Type$Constraint()); - i = i + 1 - }} - tvars - } - - private val freshInstanceMap: Type$Map = new Type$Map() { - def apply(t: Type): Type = t match { - case Type$PolyType(tparams, restp) => - val restp1: Type = apply(restp); - var tparams1: Array[Symbol] = Symbol.EMPTY_ARRAY; - var newparams1: Array[Symbol] = Symbol.EMPTY_ARRAY; - restp1 match { - case Type$PolyType(_, _) => - // If there is a nested polytype, we need to - // substitute also its new type parameters for its old ones - // here. Reason: The outer polytype may refer to type - // variables of the inner one. - tparams1 = restp.typeParams(); - newparams1 = restp1.typeParams(); - case _ => - } - val newparams: Array[Symbol] = new Array[Symbol](tparams.length); - { var i = 0; while (i < tparams.length) { - newparams(i) = tparams(i).cloneSymbol(); - i = i + 1 - }} - { var i = 0; while (i < tparams.length) { - newparams(i).setInfo( - newparams(i).info() - .subst(tparams, newparams) - .subst(tparams1, newparams1)); - newparams(i).setLoBound( - newparams(i).loBound() - .subst(tparams, newparams) - .subst(tparams1, newparams1)); - newparams(i).setVuBound( - newparams(i).vuBound() - .subst(tparams, newparams) - .subst(tparams1, newparams1)); - i = i + 1 - }} - new Type$PolyType(newparams, restp1.subst(tparams, newparams)) - - case Type$OverloadedType(_, _) => - map(t) - - case _ => - t - } - } - - def freshInstance(tp: Type): Type = freshInstanceMap.apply(tp); - - /** Automatically perform the following conversions on expression types: - * A method type becomes the corresponding function type. - * A nullary metAhod type becomes its result type. - */ - private def normalize(tp: Type): Type = tp match { - case Type$MethodType(params, restype) => - definitions.FUNCTION_TYPE( - Symbol.getType(params), normalize(restype)); - case Type$PolyType(tparams, restype) if (tparams.length == 0) => - normalize(restype); - case _ => - tp - } - - /** Is normalized type `tp' a subtype of prototype `pt'? - */ - def isCompatible(tp: Type, pt: Type): boolean = - isCompatible(tp, pt, true); - - def isCompatible(tp: Type, pt: Type, regularValue: boolean): boolean = { - def canView(tp: Type): boolean = tp match { - case Type$OverloadedType(_, alttypes) => - var i = 0; - while (i < alttypes.length && !canView(alttypes(i))) i = i + 1; - i < alttypes.length - case Type$PolyType(tparams, restype) if tparams.length == 0 => - restype.isSubType(pt) - case _ => - false - } - val tp1 = normalize(tp); - if (tp1.isSubType(pt)) true - else if (regularValue) { - val argtypes = NewArray.Type(tp1); - var viewMeths = availableViews(tp1); - while (!viewMeths.isEmpty && - !isApplicable(viewMeths.head.symtype, argtypes, pt, Names.EMPTY, false)) - viewMeths = viewMeths.tail; - if (!viewMeths.isEmpty) { - true - } - // todo: remove - else { - val coerceMeth: Symbol = tp1.lookup(Names.coerce); - coerceMeth.kind != NONE && canView(tp1.memberType(coerceMeth)); - } - } else false; - } - - def isCompatible(tps: Array[Type], pts: Array[Type]): boolean = - isCompatible(tps, pts, true); - - def isCompatible(tps: Array[Type], pts: Array[Type], regularValue: boolean): boolean = { - var i = 0; while (i < tps.length) { - if (!isCompatible(tps(i), pts(i), regularValue)) return false; - i = i + 1 - } - true - } - - /** Type arguments mapped to `scala.All' and not covariant in `restype' - * are taken to be uninstantiated. - * Map all those type arguments to their corresponding type parameters - * and return all these type parameters as result. - */ - private def normalizeArgs(targs: Array[Type], tparams: Array[Symbol], restype: Type): Array[Symbol] = { - var uninstantiated: Type$List = Type$List.EMPTY; - { var i = 0; while (i < targs.length) { - if (targs(i).symbol() == definitions.ALL_CLASS && - (variance(tparams(i), restype) & COVARIANT) == 0 && - !tparams(i).isViewBounded()) { - //System.out.println("normalizing " + tparams(i) + " / " + restype);//DEBUG - targs(i) = tparams(i).getType(); - uninstantiated = Type$List.append(uninstantiated, targs(i)); - } - i = i + 1 - }} - Type.symbol(uninstantiated.toArray()); - } - - /** Return inferred type arguments of polymorphic expression, given - * its type parameters and result type and a prototype `pt'. - * If no minimal type variables exist that make the - * instantiated type a subtype of `pt', return `null'. - */ - private def exprTypeArgs(tparams: Array[Symbol], restype: Type, pt: Type): Array[Type] = - exprTypeArgs(tparams, restype, pt, true); - - private def exprTypeArgs(tparams: Array[Symbol], restype: Type, - pt: Type, regularValue: boolean): Array[Type] = { - val tvars: Array[Type] = freshVars(tparams); - val insttype: Type = restype.subst(tparams, tvars); - if (isCompatible(insttype, pt, regularValue)) { - try { - val restype1 = normalize(restype); - { var i = 0; while (i < tvars.length) { - solve(tparams, false, variance(tparams, restype1), tvars, i); - i = i + 1 - }} - tvars - } catch { - case ex: NoInstance => null - } - } else { - null - } - } - - /** Return inferred proto-type arguments of function, given - * its type and value parameters and result type, and a - * prototype `pt' for the function result. - * Type arguments need to be either determined precisely by - * the prototype, or they are maximized, if they occur only covariantly - * in the value parameter list. - * If instantiation of a type parameter fails, - * take Type.AnyType for the proto-type argument. - */ - def protoTypeArgs(tparams: Array[Symbol], restype: Type, pt: Type, params: Array[Symbol]): Array[Type] = { - val tvars: Array[Type] = freshVars(tparams); - val insttype: Type = restype.subst(tparams, tvars); - val targs: Array[Type] = new Array[Type](tvars.length); - { var i = 0; while (i < tvars.length) { - targs(i) = Type.AnyType; - i = i + 1 - }} - if (isCompatible(insttype, pt)) { - try { - { var i = 0; while (i < tvars.length) { - targs(i) = instantiateToBound( - tvars(i), variance(tparams(i), params)); - i = i + 1 - }} - } catch { - case ex: NoInstance => - { var i = 0; while (i < tvars.length) { - targs(i) = Type.AnyType; - i = i + 1 - }} - } - } - targs - } - - /** Return inferred type arguments, given type parameters, formal parameters, - * argument types, result type and expected result type. - * If this is not possible, throw a `NoInstance' exception, or, if - * `needToSucceed' is false alternatively return `null'. - * Undetermined type arguments are represented by `definitions.ALL_TYPE'. - * No check that inferred parameters conform to their bounds is made here. - */ - private def methTypeArgs(tparams: Array[Symbol], params: Array[Symbol], - argtypes: Array[Type], restp: Type, - pt: Type, - needToSucceed: boolean, regularValue: boolean): Array[Type] = { - //System.out.println("methTypeArgs, tparams = " + ArrayApply.toString(tparams.asInstanceOf[Array[Object]]) + ", params = " + ArrayApply.toString(params.asInstanceOf[Array[Object]]) + ", type(params) = " + ArrayApply.toString(Symbol.getType(params).asInstanceOf[Array[Object]]) + ", argtypes = " + ArrayApply.toString(argtypes.asInstanceOf[Array[Object]]) + ", restp = " + restp + ", pt = " + pt);//DEBUG - - val tvars: Array[Type] = freshVars(tparams); - val formals: Array[Type] = formalTypes(params, argtypes.length); - if (formals.length != argtypes.length) { - if (needToSucceed) - throw new NoInstance("parameter lists differ in length"); - return null; - } - - // check first whether type variables can be fully defined from - // expected result type. - if (!isCompatible(restp.subst(tparams, tvars), pt, regularValue)) { - if (needToSucceed) - throw new NoInstance("result type " + restp + - " is incompatible with expected type " + pt); - return null; - } - { var i = 0; while (i < tvars.length) { - val tvar: Type$TypeVar = tvars(i).asInstanceOf[Type$TypeVar]; - if (!isFullyDefined(tvar)) tvar.constr.inst = Type.NoType; - i = i + 1 - }} - - // Then define remaining type variables from argument types. - var i = 0; - while (i < argtypes.length) { - if (!isCompatible(argtypes(i).deconst()/*!!!*/.subst(tparams, tvars), - formals(i).subst(tparams, tvars), - regularValue)) { - if (needToSucceed) { - if (global.explaintypes) { - Type.explainSwitch = true; - argtypes(i).deconst()/*!!!*/.subst(tparams, tvars).isSubType( - formals(i).subst(tparams, tvars)); - Type.explainSwitch = false; - } - throw new NoInstance( - typeErrorMsg( - "argument expression's type is not compatible with formal parameter type", - argtypes(i).deconst()/*!!!*/.subst(tparams, tvars), - formals(i).subst(tparams, tvars))); - } - return null; - } - i = i + 1; - } - { var i = 0; while (i < tvars.length) { - solve(tparams, false, variance(tparams, formals), tvars, i); - i = i + 1 - }} - tvars - } - - private def methTypeArgsSkipViews( - tparams: Array[Symbol], params: Array[Symbol], - argtypes: Array[Type], restpe: Type, - pt: Type, - needToSucceed: boolean, regularValue: boolean): Array[Type] = restpe match { - case Type$MethodType(params1, restpe1) if isViewBounded(tparams) => - methTypeArgs( - tparams, params1, argtypes, restpe1, pt, needToSucceed, regularValue); - case _ => - methTypeArgs( - tparams, params, argtypes, restpe, pt, needToSucceed, regularValue); - } - - /** Create and attribute type application node. Pass arguments for that - * `tparams' prefix which is owned by the tree's symbol. If there are remaining - * type parameters, substitute corresponding type arguments for them in the - * tree. Such remaining type parameters always come from an inferred PolyType. - */ - def mkTypeApply(tree: Tree, tparams: Array[Symbol], restype: Type, targs: Array[Type]): Tree = { - var tree1: Tree = tree; - val sym: Symbol = tree.symbol(); - var i: int = 0; - while (i < tparams.length && tparams(i).owner() == sym) - i = i + 1; - if (i < tparams.length) { - //System.out.println("tpar " + tparams(i) + " of " + tparams(i).owner() + " <> " + sym);//DEBUG - //new Printer().print(tree1);//DEBUG - //System.out.println(ArrayApply.toString(targs) + "/" + i + "/" + ArrayApply.toString(tparams));//DEBUG - val tparams1: Array[Symbol] = new Array[Symbol](tparams.length - i); - System.arraycopy(tparams, i, tparams1, 0, tparams1.length); - val targs1: Array[Type] = new Array[Type](tparams.length - i); - System.arraycopy(targs, i, targs1, 0, targs1.length); - tree1 = substituter.apply(tree1, tparams1, targs1); - } - if (0 < i) { - val argtrees: Array[Tree] = new Array[Tree](i); - { var j = 0; while (j < i) { - argtrees(j) = gen.mkType(tree.pos, targs(j)); - j = j + 1 - }} - completeTypeApply( - make.TypeApply(tree.pos, tree1, argtrees) - .setType(restype.subst(tparams, targs))) - } else { - tree1.setType(restype.subst(tparams, targs)); - } - } - - /** Return the instantiated and normalized type of polymorphic expression - * with type `[tparams]restype', given two prototypes `pt1', and `pt2'. - * `pt1' is the strict first attempt prototype where type parameters - * are left unchanged. `pt2' is the fall-back prototype where type parameters - * are replaced by `AnyType's. We try to instantiate first to `pt1' and then, - * if this fails, to `pt2'. If both attempts fail, a Type.Error is thrown. - */ - def argumentTypeInstance(tparams: Array[Symbol], restype: Type, pt1: Type, pt2: Type): Type = { - restype match { - case Type$PolyType(tparams1, restype1) => - val tparams2: Array[Symbol] = new Array[Symbol](tparams.length + tparams1.length); - System.arraycopy(tparams, 0, tparams2, 0, tparams.length); - System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); - argumentTypeInstance(tparams2, restype1, pt1, pt2); - - case _ => - if (tparams.length != 0) { - val skippedRestype = skipViewParams(tparams, restype); - var targs: Array[Type] = exprTypeArgs(tparams, skippedRestype, pt1); - if (targs == null) - targs = exprTypeArgs(tparams, skippedRestype, pt2); - if (targs == null) - throw new Type$Error( - typeErrorMsg( - "polymorphic argument cannot be instantiated to formal parameter type", - new Type$PolyType(tparams, restype), pt2)); - checkBounds(tparams, targs, "inferred "); - restype.subst(tparams, targs); - } else { - normalize(restype); - } - } - } - - /** Instantiate expression `tree' of polymorphic type [tparams]restype, - * using prototype `pt'. - */ - def exprInstance(tree: Tree, tparams: Array[Symbol], restype: Type, pt: Type): Tree = { - restype match { - case Type$PolyType(tparams1, restype1) => - val tparams2: Array[Symbol] = new Array[Symbol](tparams.length + tparams1.length); - System.arraycopy(tparams, 0, tparams2, 0, tparams.length); - System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); - exprInstance(tree, tparams2, restype1, pt) - case _ => - val targs: Array[Type] = - exprTypeArgs(tparams, skipViewParams(tparams, restype), pt); - if (targs == null) - throw new Type$Error( - "polymorphic expression of type " + tree.getType() + - " cannot be instantiated from expected type " + pt); - checkBounds(tparams, targs, "inferred "); - mkTypeApply(tree, tparams, restype, targs) - } - } - - /** Instantiate method `tree' of polymorphic type [tparams]restype, - * so that resulting method type can be applied to arguments with - * types `argtypes' and its result type is compatible with `pt'. - */ - def methodInstance(tree: Tree, tparams: Array[Symbol], restype: Type, argtypes: Array[Type], pt: Type): Tree = { - //System.out.println("methodinstance, tree = " + tree + ":" + tree.getType() + ", tparams = " + ArrayApply.toString(tparams.asInstanceOf[Array[Object]]) + ", restype = " + restype + ", argtypes = " + ArrayApply.toString(argtypes.asInstanceOf[Array[Object]]) + ", pt = " + pt);//DEBUG - restype match { - case Type$PolyType(tparams1, restype1) => - val tparams2: Array[Symbol] = new Array[Symbol](tparams.length + tparams1.length); - System.arraycopy(tparams, 0, tparams2, 0, tparams.length); - System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); - methodInstance(tree, tparams2, restype1, argtypes, pt) - - case Type$MethodType(params, restpe) => - var targs: Array[Type] = _; - try { - targs = methTypeArgsSkipViews( - tparams, params, argtypes, restpe, pt, true, false); - } catch { - case ex: NoInstance => - throw new Type$Error( - applyErrorMsg( - "no type parameters for ", tree, - " exist so that it can be applied to arguments ", - Type.widen(argtypes), Type.AnyType) + - "\n --- because ---\n" + ex.getMessage()); - } - val uninstantiated: Array[Symbol] = normalizeArgs(targs, tparams, restype); - checkBounds(tparams, targs, "inferred "); - val restype1: Type = - if (uninstantiated.length == 0) restype - else new Type$MethodType( - params, new Type$PolyType(uninstantiated, restpe)); - mkTypeApply(tree, tparams, restype1, targs); - case _ => - tree - } - } - - /** Instantiate constructor `tree' of polymorphic type [tparams]restype', - * so that its the result type of `restype' matches prototype `pt'. - * If constructor is polymorphic, maximize all type variables under this - * condition. - */ - def constructorInstance(tree: Tree, tparams: Array[Symbol], restype: Type, pt: Type): unit = { - restype match { - case Type$PolyType(tparams1, restype1) => - val tparams2: Array[Symbol] = new Array[Symbol](tparams.length + tparams1.length); - System.arraycopy(tparams, 0, tparams2, 0, tparams.length); - System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length); - constructorInstance(tree, tparams2, restype1, pt) - - case _ => - val tvars: Array[Type] = freshVars(tparams); - val restype0: Type = skipViewParams(tparams, restype); - val restype1: Type = restype0.subst(tparams, tvars); - val ctpe1: Type = restype1.resultType(); - if (ctpe1.isSubType(pt)) { - try { - { var i = 0; while (i < tvars.length) { - solve(tparams, true, variance(tparams, restype0.resultType()), - tvars, i); - i = i + 1 - }} - checkBounds(tparams, tvars, "inferred "); - tree.setType(restype0.subst(tparams, tvars)); - //System.out.println("inferred constructor type: " + tree.getType());//DEBUG - } catch { - case ex: NoInstance => - throw new Type$Error( - "constructor of type " + ctpe1 + - " can be instantiated in more than one way to expected type " + - pt + - "\n --- because ---\n" + ex.getMessage()); - } - } else { - throw new Type$Error( - typeErrorMsg( - "constructor cannot be instantiated to expected type", - ctpe1, pt)); - } - } - } - -// Overload Resolution ------------------------------------------------------------- - - /** Is function type `ftpe' applicable to `argtypes' and - * does its result conform to `pt'? - */ - def isApplicable(ftpe: Type, argtypes: Array[Type], pt: Type): boolean = - isApplicable(ftpe, argtypes, pt, Names.EMPTY, true); - - def isApplicable(ftpe: Type, argtypes: Array[Type], pt: Type, - fieldName: Name, regularValue: boolean): boolean = { - //if (!regularValue) System.out.println("is app " + ftpe + " to " + ArrayApply.toString(argtypes.asInstanceOf[Array[Object]]));//DEBUG - ftpe match { - case Type$MethodType(params, restpe) => - // sequences ? List( a* ) - val formals: Array[Type] = formalTypes(params, argtypes.length); - formals.length == argtypes.length && - isCompatible(argtypes, formals, regularValue) && - isCompatible(restpe, pt, regularValue) && - (fieldName == Names.EMPTY || restpe.lookup(fieldName).kind != NONE) - case Type$PolyType(tparams, Type$MethodType(params, restpe)) => - var i = 0; - while (i < argtypes.length && !argtypes(i).containsSome(tparams)) - i = i + 1; - if (i < argtypes.length) - isApplicable(freshInstance(ftpe), argtypes, pt, fieldName, regularValue); - else - try { - val targs: Array[Type] = methTypeArgsSkipViews( - tparams, params, argtypes, restpe, pt, false, regularValue); - if (targs != null) { - val uninstantiated: Array[Symbol] = normalizeArgs(targs, tparams, restpe); - val restpe1 = skipViewParams(tparams, restpe); - isWithinBounds(tparams, targs) && - exprTypeArgs(uninstantiated, - restpe1.subst(tparams, targs), pt, - regularValue) != null && - (fieldName == Names.EMPTY || - restpe1.subst(tparams, targs).lookup(fieldName).kind != NONE) - } else { - false - } - } catch { - case ex: NoInstance => false - } - case Type.ErrorType => - true - case _ => - if (!regularValue) { - val ftpe1 = applyType(ftpe); - ftpe1 != ftpe && - isApplicable(ftpe1, argtypes, pt, fieldName, false); - } else false - }} - - def applyType(tp: Type) = - if (tp.isObjectType()) { - val applyMeth: Symbol = tp.lookup(Names.apply); - if (applyMeth != Symbol.NONE) tp.memberType(applyMeth) - else tp - } else tp; - - /** Does type `ftpe1' specialize type `ftpe2' - * when both are alternatives in an overloaded function? - */ - def specializes(ftpe1: Type, ftpe2: Type): boolean = ftpe1 match { - case Type$MethodType(params, _) => - //System.out.println("does " + ftpe1 + " specialize " + ftpe2);//DEBUG - val argtypes = Symbol.getType(params); - // if both formal and actual have REPEATED flag set on corresponding parameters, - // change actual to its element type. - // this is a hack which should be corrected once REPEATED is part of a type. - if (params.length > 0 && (params(params.length-1).flags & REPEATED) != 0) { - val params2 = ftpe2.firstParams(); - if (params2.length == params.length && (params2(params2.length-1).flags & REPEATED) != 0) { - argtypes(params.length-1) = argtypes(params.length-1) - .baseType(definitions.SEQ_CLASS).typeArgs()(0); - } - } - isApplicable(ftpe2, argtypes, Type.AnyType) - case Type$PolyType(tparams, restype) => - skipViewParams(tparams, restype) match { - case Type$MethodType(params, _) => - isApplicable(ftpe2, Symbol.getType(params), Type.AnyType); - case _ => - false - } - case Type.ErrorType => - true - case _ => - false - } - - def specializesView(ftpe1: Type, ftpe2: Type): boolean = - specializes(applyType(ftpe1), applyType(ftpe2)); - - /** Assign `tree' the type of the alternative which matches - * prototype `pt', if it exists. - * If several alternatives match `pt', take unique parameterless one. - * Throw a Type.Error if several such alternatives exist. - * If no alternative matches, leave `tree' unchanged. - */ - def exprAlternative(tree: Tree, alts: Array[Symbol], alttypes: Array[Type], pt: Type): unit = { - - def improves(tp1: Type, tp2: Type): boolean = - tp2 == Type.ErrorType || - !normalize(tp2).isSubType(pt) && normalize(tp1).isSubType(pt) || - tp2.isParameterized() && - (!tp1.isParameterized() || specializes(tp1, tp2)); - - // first, catch the case of a missing parameter - // list for an overloaded constructor. - if (alts.length > 0) { - var i: int = 0; - while (i < alts.length && alts(i).isConstructor() && alttypes(i).isInstanceOf[Type$MethodType]) - i = i + 1; - if (i == alts.length) - throw new Type$Error("missing arguments for " + alts(0)); - } - // second, do the normal case. - var best: int = -1; - { var i = 0; while (i < alttypes.length) { - if (isCompatible(alttypes(i), pt) && (best < 0 || improves(alttypes(i), alttypes(best)))) { - best = i; - } - i = i + 1 - }} - { var i = 0; while (i < alttypes.length) { - if (isCompatible(alttypes(i), pt) && (best < 0 || improves(alttypes(i), alttypes(best)))) { - best = i; - } - i = i + 1 - }} - if (best >= 0) { - { var i = 0; while (i < alttypes.length) { - if (isCompatible(alttypes(i), pt) && best != i && !improves(alttypes(best), alttypes(i)) && pt != Type.ErrorType) { - throw new Type$Error( - overloadResolveErrorMsg( - alts(best), alttypes(best), alts(i), alttypes(i)) + - " expected type " + pt); - } - i = i + 1 - }} - tree.setSymbol(alts(best)).setType(alttypes(best)); - } - } - - /** Assign `tree' the type of an alternative - * which is applicable to `argtypes', and whose result type is - * a subtype of `pt' if it exists. - * If several applicable alternatives exist, take the - * most specialized one, or throw an error if no - * most specialized applicable alternative exists. - * If no alternative matches, leave `tree' unchanged, - * try to select method with pt = AnyType. - * If pt is AnyType, leave tree unchanged. - */ - def methodAlternative(tree: Tree, alts: Array[Symbol], alttypes: Array[Type], argtypes: Array[Type], pt: Type): unit = { - //System.out.println("meth alt " + ArrayApply.toString(argtypes.asInstanceOf[Array[Object]], "[", ",", "]") + pt);//debug - if (alts.length == 1) { - tree.setSymbol(alts(0)).setType(alttypes(0)); - return; - } - var best: int = -1; - { var i = 0; while (i < alttypes.length) { - if (isApplicable(alttypes(i), argtypes, pt) && - (best < 0 || specializes(alttypes(i), alttypes(best)))) - best = i; - i = i + 1 - }} - if (best >= 0) { - { var i = 0; while (i < alttypes.length) { - if (i != best && - isApplicable(alttypes(i), argtypes, pt) && - !(specializes(alttypes(best), alttypes(i)) && - !specializes(alttypes(i), alttypes(best)))) - throw new Type$Error( - overloadResolveErrorMsg( - alts(best), alttypes(best), alts(i), alttypes(i)) + - " argument types " + - ArrayApply.toString(argtypes.asInstanceOf[Array[Object]], "(", ",", ")") + - (if (pt == Type.AnyType) "" else " and expected result type " + pt)); - i = i + 1 - }} - tree.setSymbol(alts(best)).setType(alttypes(best)); - } else if (pt != Type.AnyType) { - methodAlternative(tree, alts, alttypes, argtypes, Type.AnyType); - } - } - - /** Assign `tree' the type of unique polymorphic alternative with `nparams' - * as the number of type parameters, if it exists. - * Throw error if several such polymorphic alternatives exist. - * If no alternative matches, leave `tree' unchanged. - */ - def polyAlternative(tree: Tree, alts: Array[Symbol], alttypes: Array[Type], nparams: int): unit = { - if (alts.length == 1) { - tree.setSymbol(alts(0)).setType(alttypes(0)); - return; - } - var i: int = 0; - while (i < alttypes.length && - !(alts(i).isValue() && - alttypes(i).typeParams().length == nparams)) - i = i + 1; - - if (i < alttypes.length) { - { var j = i + 1; while (j < alttypes.length) { - if (alts(j).isValue() && - alttypes(j).typeParams().length == nparams) - throw new Type$Error( - overloadResolveErrorMsg(alts(i), alttypes(i), alts(j), alttypes(j)) + - " polymorphic function with " + nparams + " parameters"); - j = j + 1 - }} - tree.setSymbol(alts(i)).setType(alttypes(i)); - } - } - - /** return view which best matches argument type `tp' and has `name' as member. - */ - def bestView(tp: Type, pt: Type, name: Name): View = { - var best: View = null; - var viewMeths = availableViews(tp); - //System.out.println("best view for " + tp + "/" + pt + "/" + name + " in " + viewMeths);//DEBUG - val argtypes = NewArray.Type(tp); - while (!viewMeths.isEmpty) { - if (isApplicable(viewMeths.head.symtype, argtypes, pt, name, false) && - (best == null || specializesView(viewMeths.head.symtype, best.symtype))) - best = viewMeths.head; - viewMeths = viewMeths.tail - } - if (best != null) { - viewMeths = availableViews(tp); - while (!viewMeths.isEmpty) { - // Ugly hack necessary for MSIL delegate support - // Used to be just: - // if (viewMeths.head != best && - // isApplicable(viewMeths.head.symtype, argtypes, pt, name, false) && - // !(specializesView(best.symtype, viewMeths.head.symtype) && - // !specializesView(viewMeths.head.symtype, best.symtype))) { - if ((if (global.target == scalac_Global.TARGET_MSIL) - viewMeths.head.sym != best.sym - else - viewMeths.head != best) && - isApplicable(viewMeths.head.symtype, argtypes, pt, name, false) && - !(specializesView(best.symtype, viewMeths.head.symtype) && - !specializesView(viewMeths.head.symtype, best.symtype))) { - throw new Type$Error( - "ambiguous view,\n" + - "both " + viewMeths.head.sym + ": " + - viewMeths.head.symtype + viewMeths.head.sym.locationString() + "\n" + - "and " + best.sym + ": " + best.symtype + best.sym.locationString() + - (if (name == Names.EMPTY) - "\nmap argument type " + tp.widen() + " to expected type " + pt - else - "\nadd member `" + name + "' to argument type " + tp.widen())) - } - viewMeths = viewMeths.tail; - } - } - best - } -} -} - diff --git a/sources/scala/tools/scalac/typechecker/RefCheck.scala b/sources/scala/tools/scalac/typechecker/RefCheck.scala deleted file mode 100644 index 56109ebf07..0000000000 --- a/sources/scala/tools/scalac/typechecker/RefCheck.scala +++ /dev/null @@ -1,1224 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - - -import scala.collection.mutable.HashMap; -import scalac._; -import scalac.util._; -import scalac.ast._; -import scalac.symtab._; -import Tree._; -import scalac.{Global => scalac_Global} - -package scala.tools.scalac.typechecker { - -import scalac.util.NewArray; -/*<export>*/ -/** Post-attribution checking and transformation. - * - * This phase performs the following checks. - * - * - All overrides conform to rules. - * - All type arguments conform to bounds. - * - All type variable uses conform to variance annotations. - * - No forward reference to a term symbol extends beyond a value definition. - * - * It performs the following transformations. - * - * - Local modules are replaced by variables and classes - * - caseArity, caseElement implementations added to case classes - * - equals, and hashCode and toString methods are added to case classes, - * unless they are defined in the class or a baseclass - * different from java.lang.Object - * - toString method is added to case objects, - * unless they are defined in the class or a baseclass - * different from java.lang.Object - * - Calls to case factory methods are replaced by new's. - * - Type nodes are replaced by TypeTerm nodes. - * - Eliminate constant definitions - */ -/*</export>*/ -class RefCheck(globl: scalac.Global) extends Transformer(globl) { - - import Modifiers._; - import Kinds._; - - private val defs: Definitions = globl.definitions; - private val infer: Infer = globl.newInfer(); - - private var unit: CompilationUnit = _; - private var enclClass: Symbol = _; - -// Forward reference checking --------------------------------------------------- - - private var levels: LevelInfo = _; - private var symIndex = new HashMap[Symbol, int]; - -// Main entry point -------------------------------------------------------------- - - override def apply(unit: CompilationUnit): unit = { - this.unit = unit; - levels = null; - unit.body = transformStats(unit.body); - symIndex.clear; - } - -// Override checking ------------------------------------------------------------ - - private val HIBOUND = 0; - private val LOBOUND = 1; - private val VUBOUND = 2; - - private def isIncomplete(sym: Symbol): boolean = - sym.isDeferred() || - sym.isAbstractOverride() && - isIncomplete(sym.overriddenSymbol(sym.owner().parents()(0))); - - /** 1. Check all members of class `clazz' for overriding conditions. - * 2. Check that only abstract classes have deferred members* - * 3. Check that every member with an `override' modifier - * overrides a concrete member. - */ - private def checkAllOverrides(pos: int, clazz: Symbol): unit = { - val closure = clazz.closure(); - var i = 0; while (i < closure.length) { - val basetype = closure(i); - val baseclazz = basetype.symbol(); - val it = basetype.members().iterator(); - while (it.hasNext()) - checkOverride(pos, clazz, it.next()); - i = i + 1 - } - - val parents = clazz.info().parents(); - val it = clazz.members().iterator(); - while (it.hasNext()) { - val sym = it.next(); - if ((sym.flags & OVERRIDE) != 0 && sym.owner() == clazz) { - var i = parents.length - 1; - while (i >= 0 && sym.overriddenSymbol(parents(i)).kind == NONE) - i = i - 1; - if (i < 0) { - unit.error(sym.pos, sym.toString() + ":" + sym.getType() + - sym.locationString() + " overrides nothing"); - sym.flags = sym.flags & ~OVERRIDE; - } else if (sym.isAbstractOverride() && sym.overriddenSymbol(parents(0)).kind == NONE) { - unit.error(sym.pos, - sym.toString() + " does not override a superclass member in " + - parents(0)); - } - } - } - } - - private def checkOverride(pos: int, clazz: Symbol, other: Symbol): unit = { - - def abstractClassError(msg: String) = { - if (clazz.isAnonymousClass() || clazz.isModuleClass()) - unit.error(clazz.pos, "object creation impossible, since " + msg); - else - unit.error(clazz.pos, - clazz.toString() + " needs to be abstract, since " + msg); - clazz.flags = clazz.flags | ABSTRACT; - } - - if (other.kind == CLASS) - return; // todo: see if we can sustain this - var member = other; - if ((other.flags & PRIVATE) == 0) { - val member1 = clazz.info().lookup(other.name); - if (member1.kind != NONE && member1.owner() != other.owner()) { - if (member1.kind == VAL) { - val self = clazz.thisType(); - val otherinfo = normalizedInfo(self, other); - member1.info() match { - case Type$OverloadedType(alts, _) => - var i = 0; while (i < alts.length) { - if (normalizedInfo(self, alts(i)).overrides(otherinfo)) { - if (member == other) - member = alts(i); - else - unit.error( - pos, - "ambiguous override: both " + - member + ":" + normalizedInfo(self, member) + - "\n and " + alts(i) + ":" + normalizedInfo(self, alts(i)) + - "\n override " + other + ":" + otherinfo + - other.locationString()); - } - i = i + 1 - } - - case _ => - if (normalizedInfo(self, member1).overrides(otherinfo)) - member = member1; - } - } else member = member1; - } - if (member != other) { - member.flags = member.flags | ACCESSED; - checkOverride(pos, clazz, member, other); - } - } - if (clazz.kind == CLASS && (clazz.flags & ABSTRACT) == 0) { - if ((member.flags & DEFERRED) != 0) { - val parents = clazz.parents(); - var i = 0; while (i < parents.length) { - val p = parents(i).symbol(); - if (p.isSubClass(member.owner()) && (p.flags & ABSTRACT) == 0) - return; // everything was already checked elsewhere - i = i + 1 - } - abstractClassError( - member.toString() + member.locationString() + " is not defined" + - (if ((member.flags & MUTABLE) == 0) "" - else "\n(Note that variables need to be initialized to be defined)")); - } else if (member.isAbstractOverride()) { - val superclazz: Type = clazz.parents()(0); - val sup = member.overriddenSymbol(superclazz, clazz); - if (clazz.kind == CLASS && (clazz.flags & ABSTRACT) == 0 && isIncomplete(sup)) - abstractClassError( - member.toString() + member.locationString() + - " is marked `abstract' and `override' and overrides an incomplete superclass member in " + superclazz); - } - } - } - - /** Check that all conditions for overriding `other' by `member' are met. - * That is for overriding member M and overridden member O: - * - * 1. M must have the same or stronger access privileges as O. - * 2. O must not be final. - * 3. O is deferred, or M has `override' modifier. - * 4. O is not a class, nor a class constructor. - * 5. If O is a type alias, then M is an alias of O. - * 6. If O is an abstract type then - * either M is an abstract type, and M's bounds are sharper than O's bounds. - * or M is a type alias or class which conforms to O's bounds. - * 7. If O and M are values, then M's type is a subtype of O's type. - * 8. If O is an immutable value, then so is M. - * 9. If O is a member of the static superclass of the class in which - * M is defined, and O is labelled `abstract override', then - * M must be labelled `abstract override'. - */ - private def checkOverride(_pos: int, clazz: Symbol, member: Symbol, other: Symbol): unit = { - - var pos = _pos; - - def overrideError(msg: String): unit = { - if (!other.getType().isError() && !member.getType().isError()) - unit.error(pos, - "error overriding " + other + other.locationString() + - ";\n " + member + member.locationString() + " " + msg); - } - - //System.out.println(member + ":" + member.getType() + member.locationString() + " overrides " + other + ":" + other.getType() + other.locationString() + " in " + clazz);//DEBUG - - if (member.owner() == clazz) pos = member.pos; - else { - if (member.owner().isSubClass(other.owner()) && - (member.flags & DEFERRED) >= (other.flags & DEFERRED)) { - //System.out.println(member + member.locationString() + " shadows1 " + other + other.locationString() + " in " + clazz);//DEBUG - return; // everything was already checked elsewhere - } - - val parents = clazz.parents(); - var memberShadowsOther = true; - var i = 0; - while (i < parents.length && memberShadowsOther) { - val p = parents(i).symbol(); - val isSubMember = p.isSubClass(other.owner()); - val isSubOther = p.isSubClass(member.owner()); - if (isSubMember != isSubOther) { - memberShadowsOther = false; - } else if (isSubMember && isSubOther && - (member.flags & DEFERRED) >= (other.flags & DEFERRED)) { - //System.out.println(member + member.locationString() + " shadows2 " + other + other.locationString() + " in " + clazz);//DEBUG - return; // everything was already checked elsewhere - } - i = i + 1 - } - if (memberShadowsOther) { - //System.out.println(member + member.locationString() + " shadows " + other + other.locationString() + " in " + clazz);//DEBUG - return; // everything was already checked elsewhere - } - } - - if ((member.flags & PRIVATE) != 0) { - overrideError("has weaker access privileges; it should not be private"); - } else if ((member.flags & PROTECTED) != 0 && (other.flags & PROTECTED) == 0) { - overrideError("has weaker access privileges; it should not be protected"); - } else if ((other.flags & FINAL) != 0) { - overrideError("cannot override final member"); -/* - } else if (other.kind == CLASS) { - overrideError("cannot override a class"); -*/ - } else if ((other.flags & DEFERRED) == 0 && ((member.flags & OVERRIDE) == 0)) { - overrideError("needs `override' modifier"); - } else if (other.isAbstractOverride() && !member.isAbstractOverride() && member.owner() == clazz && clazz.parents()(0).symbol().isSubClass(other.owner())) { - overrideError("needs `abstract' and `override' modifiers"); - } else if (other.isStable() && !member.isStable()) { - overrideError("needs to be an immutable value"); - } else if ((member.flags & DEFERRED) == 0 && (other.flags & DEFERRED) == 0 && member.owner() != clazz && !clazz.parents()(0).symbol().isSubClass(other.owner())) { - unit.error(pos, "conflict between concrete members " + - member + member.locationString() + " and " + - other + other.locationString() + - ":\n both are inherited from mixin classes; " + - "\n an overriding definition in the current template is required"); - } else { - val site: Type = clazz.thisType(); - - def overrideTypeError(boundkind: int): unit = { - - def infoString(sym: Symbol, symtype: Type): String = sym.kind match { - case Kinds.ALIAS => ", which equals " + symtype - case Kinds.TYPE => " bounded" + (if (boundkind == LOBOUND) " from below" else "") + " by " + symtype - case Kinds.VAL => " of type " + symtype - case _ => "" - } - - def oterror(memberInfo: Type, otherInfo: Type): unit = { - unit.error(pos, - member.toString() + member.locationString() + - infoString(member, memberInfo) + - "\n cannot override " + other + other.locationString() + - infoString(other, otherInfo)); - Type.explainTypes(memberInfo, otherInfo); - } - - if (!other.getType().isError() && !member.getType().isError()) { - if (boundkind == LOBOUND) { - oterror(site.memberLoBound(member), site.memberLoBound(other)) - } else if (boundkind == VUBOUND) { - oterror(site.memberVuBound(member), site.memberVuBound(other)); - } else { - oterror(normalizedInfo(site, member), normalizedInfo(site, other)) - } - } - } - - other.kind match { - case ALIAS => - if (member.typeParams().length != 0) - overrideError("may not be parameterized"); - if (other.typeParams().length != 0) - overrideError("may not override parameterized type"); - if (!site.memberType(member).isSameAs(site.memberType(other))) - overrideTypeError(HIBOUND); - - case TYPE => - if (member.typeParams().length != 0) - overrideError("may not be parameterized"); - if (!site.memberInfo(member).isSubType(site.memberInfo(other))) - overrideTypeError(HIBOUND); - if (!site.memberLoBound(other).isSubType(site.memberLoBound(member))) - overrideTypeError(LOBOUND); - if (!site.memberVuBound(member).isSubType(site.memberVuBound(other))) - overrideTypeError(VUBOUND); - - case _ => - if (other.isConstructor()) - overrideError("cannot override a class constructor"); - if (!normalizedInfo(site, member).isSubType(normalizedInfo(site, other))) - overrideTypeError(HIBOUND); - } - } - } - - private def normalizedInfo(site: Type, sym: Symbol): Type = - site.memberInfo(sym).derefDef(); - - /** compensate for renaming during addition of access functions - */ - private def normalizeName(name: Name): String = { - val string = name.toString(); - if (string.endsWith("$")) string.substring(0, string.length() - 1) - else string; - } - -// Basetype Checking -------------------------------------------------------- - - /** 1. Check that only traits are inherited several times (except if the - * inheriting instance is a compund type). - * 2. Check that later type instances in the base-type sequence - * of a class are subtypes of earlier type instances of the same trait. - * 3. Check that case classes do not inherit from case classes. - * 4. Check that at most one base type is a case-class. - */ - private def validateBaseTypes(clazz: Symbol): unit = { - - val seen = new Array[Type](clazz.closure().length); - - def validateTypes(tps: Array[Type], caseSeen: Symbol, start: int): unit = { - var i = tps.length - 1; while(i >= start) { - validateType(tps(i).unalias(), caseSeen, if (i == 0) 0 else 1); - i = i - 1 - } - } - - def validateType(tp: Type, caseSeen: Symbol, start: int): unit = { - var baseclazz = tp.symbol(); - if (baseclazz.kind == CLASS) { - val index = clazz.closurePos(baseclazz); - if (index < 0) return; - if (seen(index) != null) { - // check that only traits are inherited several times. - if (!clazz.isCompoundSym() && !baseclazz.isTrait()) { - unit.error(clazz.pos, "illegal inheritance;\n" + clazz + - " inherits " + baseclazz + " twice"); - } - // if there are two different type instances of same class - // check that second is a subtype of first. - if (!seen(index).isSubType(tp)) { - val msg = - if (clazz.isCompoundSym()) "illegal combination;\n compound type combines" - else "illegal inheritance;\n " + clazz + " inherits"; - unit.error(clazz.pos, msg + " different type instances of " + - baseclazz + ":\n" + tp + " and " + seen(index)); - } - } - // check that case classes do not inherit from case classes - var caseSeen1 = - if (baseclazz.isCaseClass()) { - if (caseSeen.isCaseClass()) - unit.error( - clazz.pos, "illegal combination of case " + - caseSeen + " and case " + baseclazz + " in one object"); - baseclazz - } else caseSeen; - - seen(index) = tp; - validateTypes(tp.parents(), caseSeen1, start); - } - } - - validateTypes(clazz.getType().parents(), clazz, 0); - } - -// Variance Checking -------------------------------------------------------- - - private val ContraVariance = -1; - private val NoVariance = 0; - private val CoVariance = 1; - private val AnyVariance = 2; - - private def varianceString(variance: int): String = - if (variance == 1) "covariant" - else if (variance == -1) "contravariant" - else "invariant"; - - /** The variance of symbol `base' relative to the class which defines `tvar'. - */ - private def flip(base: Symbol, tvar: Symbol): int = { - val clazz = tvar.owner().constructorClass(); - var sym = base; - var flip = CoVariance; - while (sym != clazz && flip != AnyVariance) { - //System.out.println("flip: " + sym + " " + sym.isParameter());//DEBUG - if (sym.isParameter()) flip = -flip; - else if (sym.owner().kind != CLASS) flip = AnyVariance; - else if (sym.kind == ALIAS) flip = NoVariance; - sym = sym.owner(); - } - flip - } - - /** Check variance of type variables in this type - */ - private def validateVariance(base: Symbol, all: Type, variance: int): unit = { - - def validateVariance(tp: Type, variance: int): unit = tp match { - case Type.ErrorType | Type.AnyType | Type.NoType | Type.NoPrefix | Type$ThisType(_) | Type$ConstantType(_, _) => - - case Type$SingleType(pre, sym) => - validateVariance(pre, variance) - - case Type$TypeRef(pre, sym, args) => - if (sym.variance() != 0) { - val f = flip(base, sym); - if (f != AnyVariance && sym.variance() != f * variance) { - //System.out.println("flip(" + base + "," + sym + ") = " + f);//DEBUG - unit.error(base.pos, - varianceString(sym.variance()) + " " + sym + - " occurs in " + varianceString(f * variance) + - " position in type " + all + " of " + base); - } - } - validateVariance(pre, variance); - validateVarianceArgs(args, variance, sym.typeParams()); - - case Type$CompoundType(parts, members) => - validateVariances(parts, variance); - - case Type$MethodType(vparams, result) => - validateVariance(result, variance); - - case Type$PolyType(tparams, result) => - validateVariance(result, variance); - - case Type$OverloadedType(alts, alttypes) => - validateVariances(alttypes, variance); - - case _ => throw new ApplicationError("unexpected type: " + tp); - } - - def validateVariances(tps: Array[Type], variance: int): unit = { - var i = 0; while (i < tps.length) { - validateVariance(tps(i), variance); - i = i + 1 - } - } - - def validateVarianceArgs(tps: Array[Type], variance: int, tparams: Array[Symbol]): unit = { - var i = 0; while (i < tps.length) { - validateVariance(tps(i), variance * tparams(i).variance()); - i = i + 1 - } - } - - validateVariance(all, variance) - } - - -// Forward reference checking --------------------------------------------------- - - case class LevelInfo(outer: LevelInfo) { - val scope: Scope = if (outer == null) new Scope() else new Scope(outer.scope); - var maxindex: int = Integer.MIN_VALUE; - var refpos: int = _; - var refsym: Symbol = _; - } - - private def pushLevel(): unit = - levels = new LevelInfo(levels); - - private def popLevel(): unit = - levels = levels.outer; - - private def enterSyms(stats: Array[Tree]): unit = { - - def enterSym(stat: Tree, index: int): unit = { - - def enterSym(sym: Symbol): unit = - if (sym.isLocal()) { - levels.scope.enter(new Scope.Entry(sym, levels.scope)); - symIndex.update(sym, index); - } - - stat match { - case Tree$ClassDef(_, _, _, _, _, _) => - enterSym(stat.symbol().primaryConstructor()) - - case DefDef(_, _, _, _, _, _) | ModuleDef(_, _, _, _) | ValDef(_, _, _, _) => - enterSym(stat.symbol()) - - case _ => - } - } - - var i = 0; while (i < stats.length) { - enterSym(stats(i), i); - i = i + 1 - } - } - -// Module eliminiation ----------------------------------------------------------- - - private def transformModule(tree: Tree, mods: int, name: Name, tpe: Tree, templ: Tree.Template): Array[Tree] = { - val sym = tree.symbol(); - val cdef = gen.ClassDef(sym.moduleClass(), templ); - if (sym.isStatic()) return NewArray.Tree{cdef}; - val alloc = - gen.New( - gen.mkApply__( - gen.mkPrimaryConstructorLocalRef(tree.pos, sym.moduleClass()))); - - // var m$: T = null; - val varname = Name.fromString(name.toString() + "$"); - val mvar = sym.owner().newFieldOrVariable( - tree.pos, PRIVATE | MUTABLE | SYNTHETIC, varname) - .setInfo(sym.getType()); - if (sym.owner().isClassType()) - sym.owner().members().enterOrOverload(mvar); - val vdef = gen.ValDef(mvar, gen.mkNullLit(tree.pos)); - - // { if (null == m$) m$ = new m$class; m$ } - val eqMethod: Symbol = getUnaryMemberMethod( - sym.getType(), Names.EQEQ, defs.ANY_TYPE()); - val body: Tree = - gen.mkBlock( - gen.If( - gen.Apply( - gen.Select(gen.mkNullLit(tree.pos), eqMethod), - NewArray.Tree{gen.mkLocalRef(tree.pos, mvar)}), - gen.Assign(gen.mkLocalRef(tree.pos, mvar), alloc), - gen.mkUnitLit(tree.pos)), - gen.mkLocalRef(tree.pos, mvar)); - - // def m: T = { if (m$ == null(T)) m$ = new m$class; m$ } - sym.flags = sym.flags | STABLE; - val ddef: Tree = gen.DefDef(sym, body); - - // def m_eq(m: T): Unit = { m$ = m } - val m_eqname = Name.fromString(name.toString() + Names._EQ); - val m_eq: Symbol = sym.owner().newMethodOrFunction( - tree.pos, PRIVATE | SYNTHETIC, m_eqname); - val m_eqarg: Symbol = m_eq.newVParam(tree.pos, SYNTHETIC, name, sym.getType()); - m_eq.setInfo( - Type.MethodType(NewArray.Symbol{m_eqarg}, defs.void_TYPE())); - val m_eqdef: Tree = gen.DefDef( - m_eq, - gen.Assign(gen.mkLocalRef(tree.pos, mvar), gen.Ident(tree.pos, m_eqarg))); - if (sym.owner().isClassType()) - sym.owner().members().enterOrOverload(m_eq); - - NewArray.Tree(cdef, vdef, ddef, m_eqdef) - } - -// Adding case methods -------------------------------------------------------------- - - private def hasImplementation(clazz: Symbol, name: Name): boolean = { - val sym = clazz.info().lookupNonPrivate(name); - sym.kind == VAL && - (sym.owner() == clazz || - !defs.OBJECT_CLASS.isSubClass(sym.owner()) && - (sym.flags & DEFERRED) == 0); - } - - private def getMember(site: Type, name: Name): Symbol = { - val sym = site.lookupNonPrivate(name); - if (sym.kind != VAL) - throw new ApplicationError("getMember failed for " + Debug.show(sym) + "; " + Debug.show(site) + "::" + name); - sym - } - - private def getMethod(site: Type, name: Name, p: Type => boolean): Symbol = { - val sym = getMember(site, name); - sym.getType() match { - case Type$OverloadedType(alts, alttypes) => - var i = 0; while (i < alts.length) { - if (p(alttypes(i))) return alts(i); - i = i + 1 - } - case _ => - } - if (p(sym.getType())) return sym; - throw new ApplicationError( - " no method " + name + " of required kind among " + sym.getType() + " at " + site); - } - - private def getNullaryMemberMethod(site: Type, name: Name): Symbol = - getMethod(site, name, - tp => tp.paramSectionCount() == 1 && tp.firstParams().length == 0); - -/* - private def getUnaryMemberMethod(site: Type, name: Name, paramtype: Type): Symbol = - getMethod(site, name, - tp => { val params = tp.firstParams(); - params.length == 1 && paramtype.isSubType(params(0).getType()) }); -*/ - - private def getUnaryMemberMethod(site: Type, name: Name, paramtype: Type): Symbol = { - val sym = getMember(site, name); - sym.getType() match { - case Type$OverloadedType(alts, alttypes) => { - var member: Symbol = null; - var memberparamtype: Type = null; - var i = 0; while (i < alts.length) { - val params = alttypes(i).firstParams(); - if (params.length == 1) { - val altparamtype = params(0).getType(); - if (paramtype.isSubType(altparamtype)) { - if (member == null || altparamtype.isSubType(memberparamtype)) { - member = alts(i); - memberparamtype = altparamtype; - } - } - } - i = i + 1 - } - if (member != null) return member; - } - case _ => - val params = sym.getType().firstParams(); - if (params.length == 1 && paramtype.isSubType(params(0).getType())) return sym; - } - System.out.println(paramtype.widen());//debug - throw new ApplicationError( - " no method " + name + " of required kind among " + sym.getType() + " at " + site.widen()); - } - - - private def caseFields(clazz: ClassSymbol): Array[Tree] = { - var ct = clazz.primaryConstructor().getType(); - ct match { - case Type$PolyType(tparams, restp) => - ct = infer.skipViewParams(tparams, restp); - case _ => - } - val vparams: Array[Symbol] = ct.firstParams(); - val fields: Array[Tree] = new Array[Tree](vparams.length); - var i = 0; while (i < fields.length) { - fields(i) = gen.mkRef(clazz.pos, clazz.thisType(), clazz.caseFieldAccessor(i)); - i = i + 1 - } - fields - } - - private def toStringMethod(clazz: ClassSymbol): Tree = { - val toStringSym = clazz.newMethod( - clazz.pos, OVERRIDE, Names.toString) - .setInfo(defs.ANY_TOSTRING.getType()); - clazz.info().members().enter(toStringSym); - val fields: Array[Tree] = caseFields(clazz); - var body: Tree = null; - if (fields.length == 0) { - body = gen.mkStringLit( - clazz.pos, NameTransformer.decode(clazz.name)); - } else { - body = gen.mkStringLit( - clazz.pos, NameTransformer.decode(clazz.name) + "("); - var i = 0; while (i < fields.length) { - val str = if (i == fields.length - 1) ")" else ","; - body = gen.Apply( - gen.Select(body, defs.STRING_PLUS), NewArray.Tree(fields(i))); - body = gen.Apply( - gen.Select(body, defs.STRING_PLUS), NewArray.Tree(gen.mkStringLit(clazz.pos, str))); - i = i + 1 - } - } - gen.DefDef(toStringSym, body) - } - - private def caseElementMethod(clazz: ClassSymbol): Tree = { - val method = - clazz.newMethod(clazz.pos, FINAL | OVERRIDE, Names.caseElement); - val seParam = - method.newVParam(clazz.pos, 0, Names.n, defs.int_TYPE()); - method.setInfo( - Type.MethodType(NewArray.Symbol(seParam), defs.ANY_TYPE())); - clazz.info().members().enter(method); - val fields: Array[Tree] = caseFields(clazz); - var body: Tree = null; - if (fields.length > 0) { // switch< n > - val tags: Array[int] = new Array[int](fields.length); - var i = 0; while (i < fields.length) { tags(i) = i; i = i + 1 } - body = gen.Switch( - gen.mkLocalRef(clazz.pos, seParam), - tags, - fields, - gen.mkNullLit(clazz.pos), - defs.ANY_TYPE()); - } else - body = gen.mkNullLit(clazz.pos); - gen.DefDef(method, body) - } - - private def caseArityMethod(clazz: ClassSymbol): Tree = { - val method = - clazz.newMethod(clazz.pos, FINAL | OVERRIDE, Names.caseArity); - method.setInfo( - Type.PolyType(Symbol.EMPTY_ARRAY, defs.int_TYPE())); - clazz.info().members().enter(method); - val fields: Array[Tree] = caseFields(clazz); - gen.DefDef(method, gen.mkIntLit(clazz.pos, fields.length)) - } - - private def readResolveMethod(clazz: ClassSymbol): Tree = { - // !!! the synthetic method "readResolve" should be private, - // but then it is renamed !!! - val method = - clazz.newMethod(clazz.pos, PROTECTED | SYNTHETIC, Names.readResolve); - method.setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, defs.OBJECT_TYPE())); - clazz.info().members().enter(method); - gen.DefDef(method, gen.mkLocalRef(clazz.pos, clazz.sourceModule())) - } - - private def equalsMethod(clazz: ClassSymbol): Tree = { - val equalsSym = clazz.newMethod(clazz.pos, OVERRIDE, Names.equals); - val equalsParam = equalsSym.newVParam( - clazz.pos, 0, Names.that, defs.ANY_TYPE()); - equalsSym.setInfo( - Type.MethodType(NewArray.Symbol(equalsParam), defs.boolean_TYPE())); - clazz.info().members().enter(equalsSym); - val fields = caseFields(clazz); - var testtp = clazz.getType(); - { - val tparams = clazz.typeParams(); - if (tparams.length != 0) { - val targs = new Array[Type](tparams.length); - var i = 0; while (i < targs.length) { - targs(i) = defs.ANY_TYPE(); - i = i + 1 - } - testtp = testtp.subst(tparams, targs); - } - } - - // if (that is C) {...} - val cond = gen.TypeApply( - gen.Select(gen.mkLocalRef(clazz.pos, equalsParam), defs.ANY_IS), - NewArray.Tree(gen.mkType(clazz.pos, testtp))); - - val thenpart = - if (fields.length == 0) { - gen.mkBooleanLit(clazz.pos, true) - } else { - // val that1 = that.asInstanceOf[C]; - val cast = - gen.TypeApply( - gen.Select( - gen.mkLocalRef(clazz.pos, equalsParam), - defs.ANY_AS_ERASED), - NewArray.Tree(gen.mkType(clazz.pos, testtp))); - val that1sym = equalsSym.newVariable(clazz.pos, 0, Names.that1) - .setType(testtp); - val that1def = gen.ValDef(that1sym, cast); - - def eqOp(l: Tree, r: Tree): Tree = { - val eqMethod = getUnaryMemberMethod(l.getType(), Names.EQEQ, r.getType()); - gen.Apply(gen.Select(l, eqMethod), NewArray.Tree(r)) - } - - def qualCaseField(qual: Tree, i: int): Tree = - gen.Select(qual, clazz.caseFieldAccessor(i)); - - // this.elem_1 == that1.elem_1 && ... && this.elem_n == that1.elem_n - var cmp: Tree = - eqOp( - fields(0), - qualCaseField(gen.mkLocalRef(clazz.pos, that1sym), 0)); - var i = 1; while (i < fields.length) { - cmp = - gen.Apply( - gen.Select(cmp, defs.BOOLEAN_AND()), - NewArray.Tree( - eqOp( - fields(i), - qualCaseField(gen.mkLocalRef(clazz.pos, that1sym), i)))); - i = i + 1 - } - gen.mkBlock(that1def, cmp) - } - - val body = gen.If(cond, thenpart, gen.mkBooleanLit(clazz.pos, false)); - - gen.DefDef(equalsSym, body) - } - - private def getTypeMethod(clazz: ClassSymbol): Tree = { - val flags = - SYNTHETIC - | (if (clazz.isSubClass(defs.SCALAOBJECT_CLASS)) OVERRIDE else 0); - val getTypeSym = clazz - .newMethod(clazz.pos, flags, Names.getScalaType) - .setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, - defs.SCALACLASSTYPE_TYPE())); - clazz.info().members().enter(getTypeSym); - // Use "null" for the RHS for now, this will get fixed by - // TypesAsValuePhase. - gen.DefDef(getTypeSym, gen.mkNullLit(clazz.pos)); - } - - private def hashCodeMethod(clazz: ClassSymbol): Tree = { - val hashCodeSym = clazz.newMethod(clazz.pos, OVERRIDE, Names.hashCode) - .setInfo(defs.ANY_HASHCODE.getType()); - clazz.info().members().enter(hashCodeSym); - val fields: Array[Tree] = caseFields(clazz); - val name: Name = if (globl.target == scalac_Global.TARGET_MSIL) Names.GetType - else Names.getClass; - val getClassMethod = getNullaryMemberMethod(clazz.getType(), name); - val addMethod = getUnaryMemberMethod(defs.int_TYPE(), Names.ADD, defs.int_TYPE()); - val mulMethod = getUnaryMemberMethod(defs.int_TYPE(), Names.MUL, defs.int_TYPE()); - var body: Tree = - gen.Apply( - gen.Select( - gen.Apply( - gen.mkRef(clazz.pos, clazz.thisType(), getClassMethod), - Tree.EMPTY_ARRAY), - getNullaryMemberMethod(getClassMethod.getType().resultType(), Names.hashCode)), - Tree.EMPTY_ARRAY); - var i = 0; while (i < fields.length) { - val operand: Tree = - gen.Apply( - gen.Select( - fields(i), - getNullaryMemberMethod(fields(i).getType(), Names.hashCode)), - Tree.EMPTY_ARRAY); - body = - gen.Apply( - gen.Select( - gen.Apply( - gen.Select(body, mulMethod), - NewArray.Tree(gen.mkIntLit(clazz.pos, 41))), - addMethod), - NewArray.Tree(operand)); - i = i + 1 - } - gen.DefDef(hashCodeSym, body) - } - - private def isTrueSubClassOfCaseClass(clazz: Symbol): boolean = { - val cl = clazz.closure(); - var i = 1; while (i < cl.length) { - if (cl(i).symbol().isCaseClass() && !cl(i).symbol().isJava()) return true; - i = i + 1 - } - false - } - - private def addSyntheticMethods(templ: Template, clazz: ClassSymbol): Template = { - val ts = new TreeList(); - if (clazz.isCaseClass()) { - global.addAttribute(clazz, defs.SCALA_SERIALIZABLE_CONSTR); - if (!hasImplementation(clazz, Names.toString)) { - ts.append(toStringMethod(clazz)); - } - if (!clazz.isModuleClass()) { - if (!hasImplementation(clazz, Names.equals)) - ts.append(equalsMethod(clazz)); - if (!hasImplementation(clazz, Names.hashCode)) - ts.append(hashCodeMethod(clazz)); - } - - // the following report error if impl exists - ts.append(caseElementMethod(clazz)); - ts.append(caseArityMethod(clazz)); - ts.append(gen.mkTagMethod(clazz)); - if (global.target != Global.TARGET_MSIL) - ts.append(getTypeMethod(clazz)); - } else if ((clazz.flags & ABSTRACT) == 0) { - if (!isTrueSubClassOfCaseClass(clazz)) { - ts.append(gen.mkTagMethod(clazz)); - } - if (global.target != Global.TARGET_MSIL) - ts.append(getTypeMethod(clazz)); - } - if (clazz.isModuleClass()) { - val serializable = - global.getAttrArguments(clazz, defs.SCALA_SERIALIZABLE_CONSTR) != null; - if (serializable) { - // If you serialize a singleton and then deserialize it twice, - // you will have two instances of your singleton, unless you implement - // the readResolve() method (see http://www.javaworld.com/javaworld/ - // jw-04-2003/jw-0425-designpatterns_p.html) - ts.append(readResolveMethod(clazz)); - } - } - copy.Template( - templ, templ.parents, - if (ts.length() > 0) { - val body1 = new Array[Tree](templ.body.length + ts.length()); - System.arraycopy(templ.body, 0, body1, 0, templ.body.length); - ts.copyTo(body1, templ.body.length); - body1 - } else templ.body); - } - -// Convert case factory calls to constructor calls --------------------------- - - /** Tree represents an application of a constructor method of a case class - * (whose name is a term name). Convert this tree to application of - * the case classe's primary constructor `constr'. - */ - private def toConstructor(tree: Tree, constr: Symbol): Tree = { - - def applyNesting(tree: Tree): int = tree match { - case Apply(fn, _) => applyNesting(fn) + 1 - case _ => 0 - } - - val missing: int = constr.getType().paramSectionCount() - applyNesting(tree); - assert(missing >= 0 && missing <= 1); - - def addEmptyParams(tp: Type): Type = tp match { - case Type$MethodType(vparams, restp) => - Type.MethodType(vparams, addEmptyParams(restp)) - case Type$PolyType(tparams, restp) => - Type.PolyType(tparams, addEmptyParams(restp)) - case _ => - Type.MethodType(Symbol.EMPTY_ARRAY, tp) - } - - def toConstructor1(tree: Tree): Tree = { - val tree1 = toConstructor2(tree); - if (missing > 0) - tree1.duplicate().setType(addEmptyParams(tree1.getType())) - else tree1 - } - - def toConstructor2(tree: Tree): Tree = tree match { - case Tree$Apply(fn, args) => - copy.Apply(tree, toConstructor1(fn), args) - case Tree$TypeApply(fn, args) => - copy.TypeApply(tree, toConstructor1(fn), args) - case Tree$Ident(_) => - copy.Ident(tree, constr) - case Tree$Select(qual, _) => - copy.Select(tree, constr, qual) - } - - val tree1 = toConstructor1(tree); - if (missing > 0) gen.Apply(tree1, Tree.EMPTY_ARRAY) else tree1 - } - //where - -// Bounds checking ----------------------------------------------------------- - - private def checkBounds(pos: int, tparams: Array[Symbol], argtypes: Array[Type]): unit = - if (tparams.length == argtypes.length) { - try { - infer.checkBounds(tparams, argtypes, ""); - } catch { - case ex: Type.Error => unit.error(pos, ex.msg); - } - } - -// Tree node simplification--------------------------------------------------- - - private def elimTypeNode(tree: Tree): Tree = { - def checkLegal(tp: Type): unit = tp match { - case Type.TypeRef(pre, sym, args) => - sym.kind match { - case ALIAS | TYPE => - checkLegal(sym.info().asSeenFrom(pre, sym.owner())); - case CLASS => - if (sym == defs.ANY_CLASS) - unit.error(tree.pos, "Array[Any] not supported"); - else if (sym == defs.ANYVAL_CLASS) - unit.error(tree.pos, "Array[AnyVal] not supported"); - case _ => - } - case _ => - } - if (tree.isType()) { - val resultType = tree.getType().deconst(); - val resultArgs = resultType.typeArgs(); - if (resultType.symbol() == defs.ARRAY_CLASS && resultArgs.length == 1 && global.runTimeTypes) { - checkLegal(resultArgs(0)) - } - gen.mkType(tree.pos, resultType); - } else tree - } - -// Transformation ------------------------------------------------------------ - - def transformStats(stats: Array[Tree]): Array[Tree] = { - pushLevel(); - enterSyms(stats); - var stats1 = stats; - var i = 0; - while (i < stats1.length) { - transformStat(stats1(i), i) match { - case newstat: Tree => - stats1(i) = newstat; - i = i + 1; - case newstats: Array[Tree] => - val stats2 = new Array[Tree](stats1.length - 1 + newstats.length); - System.arraycopy(stats1, 0, stats2, 0, i); - System.arraycopy(newstats, 0, stats2, i, newstats.length); - System.arraycopy(stats1, i + 1, stats2, i + newstats.length, - stats1.length - i - 1); - stats1 = stats2; - i = i + newstats.length; - } - } - popLevel(); - stats1 - } - - def transformStat(tree: Tree, index: int): Any = tree match { - case Tree$ModuleDef(mods, name, tpe, templ) => - transform(transformModule(tree, mods, name, tpe, templ)) - - case Tree$ValDef(mods, name, tpe, rhs) => - val sym = tree.symbol(); - validateVariance( - sym, sym.getType(), - if ((sym.flags & MUTABLE) != 0) NoVariance else CoVariance); - val tree1 = transform(tree); - //todo: handle variables - if (sym.isLocal() && !sym.isModule() && index <= levels.maxindex) { - if (globl.debug) - System.out.println(levels.refsym.toString() + ":" + levels.refsym.getType()); - val kind = if ((sym.flags & MUTABLE) != 0) "variable" else "value"; - unit.error( - levels.refpos, - "forward reference extends over definition of " + kind + " " + - normalizeName(name)); - } - tree1 - - case _ => - transform(tree) - } - - override def transform(tree: Tree): Tree = try { - val sym = tree.symbol(); - tree match { - case Tree.Empty => - tree - - case Tree$ClassDef(_, _, tparams, vparams, tpe, templ) => - val enclClassPrev = enclClass; - enclClass = sym; - validateVariance(sym, sym.info(), CoVariance); - validateVariance(sym, sym.typeOfThis(), CoVariance); - val tree1 = super.transform( - copy.ClassDef( - tree, tree.symbol(), tparams, vparams, tpe, - addSyntheticMethods( - templ, tree.symbol().asInstanceOf[ClassSymbol]))); - enclClass = enclClassPrev; - tree1 - - case Tree$DefDef(_, _, _, _, _, _) => - validateVariance(sym, sym.getType(), CoVariance); - super.transform(tree) - - case Tree$ValDef(_, _, _, _) => - validateVariance( - sym, sym.getType(), - if ((sym.flags & MUTABLE) != 0) NoVariance else CoVariance); - super.transform(tree) - - case Tree$AbsTypeDef(_, _, _, _) => - validateVariance(sym, sym.info(), CoVariance); - validateVariance(sym, sym.loBound(), ContraVariance); - validateVariance(sym, sym.vuBound(), CoVariance); - super.transform(tree) - - case Tree$AliasTypeDef(_, _, _, _) => - validateVariance(sym, sym.info(), CoVariance); - super.transform(tree) - - case Tree$Template(bases, body) => - val bases1 = transform(bases); - val body1 = transformStats(body); - if (sym.kind == VAL) { - val owner = tree.symbol().owner(); - validateBaseTypes(owner); - checkAllOverrides(tree.pos, owner); - } - copy.Template(tree, bases1, body1) - - case Tree$Block(stats, value) => - val stats1 = transformStats(stats); - val value1 = transform(value); - copy.Block(tree, stats1, value1) - - case Tree$This(_) => - tree - - case Tree$PackageDef(pkg, packaged) => - copy.PackageDef(tree, pkg, super.transform(packaged)) - - case Tree$TypeApply(fn, args) => - fn.getType() match { - case Type$PolyType(tparams, _) => - checkBounds(tree.pos, tparams, Tree.typeOf(args)); - case _ => - } - super.transform(tree) - - /* - // oops, might not work because of forward value references(test?) - // optimized, buraq 2005-02-21 [RefCheck is identity on patterns] - case Tree.CaseDef(pat, guard, body)=> - copy.CaseDef(tree, pat, transform(guard), transform(body)); - */ - case Tree$Apply(fn, args) => - // convert case methods to new's - val fsym = TreeInfo.methSymbol(fn); - assert(fsym != Symbol.NONE, tree); - if (fsym != null && fsym.isMethod() && !fsym.isConstructor() && (fsym.flags & CASE) != 0) { - val constr = fsym.getType().resultType().symbol().primaryConstructor(); - super.transform(gen.New(toConstructor(tree, constr))) - } else - super.transform(tree); - - case Tree$AppliedType(tpe, args) => - val tparams = tpe.getType().symbol().typeParams(); - checkBounds(tree.pos, tparams, Tree.typeOf(args)); - elimTypeNode(super.transform(tree)) - - case Tree$CompoundType(_, _) => - val clazz = tree.getType().symbol(); - validateBaseTypes(clazz); - checkAllOverrides(tree.pos, clazz); - elimTypeNode(super.transform(tree)) - - case Tree$Ident(name) => - if (name == TypeNames.WILDCARD_STAR) - tree - else if( sym == defs.PATTERN_WILDCARD ) - elimTypeNode(tree) - else { - //System.out.println("name: "+name); - val e = levels.scope.lookupEntry(name); - //System.out.println("sym: "+sym); - if (sym.isLocal() && sym == e.sym) { - var l = levels; - while (l.scope != e.owner) l = l.outer; - val symindex = symIndex(tree.symbol()); - if (l.maxindex < symindex) { - l.refpos = tree.pos; - l.refsym = e.sym; - l.maxindex = symindex; - } - } - sym.flags = sym.flags | ACCESSED; - elimTypeNode(tree) - } - - case Tree$Select(qual, name) => - sym.flags = sym.flags | ACCESSED; - if (!TreeInfo.isSelf(qual, enclClass)) - sym.flags = sym.flags | SELECTOR; - if ((sym.flags & DEFERRED) != 0) { - qual match { - case Tree$Super(qualifier, mixin) => - val sym1 = enclClass.thisSym().info().lookup(sym.name); - if (mixin != TypeNames.EMPTY || !isIncomplete(sym1)) - unit.error( - tree.pos, - "symbol accessed from super may not be abstract"); - case _ => - } - } - elimTypeNode(super.transform(tree)) - - case _ => - elimTypeNode(super.transform(tree)) - } - } catch { - case ex: Type$Error => - if (global.debug) ex.printStackTrace(); - unit.error(tree.pos, ex.msg); - tree - } - - override def transform(trees: Array[Tree]): Array[Tree] = - super.transform(trees); - - override def transform(trees: Array[Tree$CaseDef]): Array[Tree$CaseDef] = - super.transform(trees); - - override def transform(trees: Array[Tree$AbsTypeDef]): Array[Tree$AbsTypeDef] = - super.transform(trees); - - override def transform(trees: Array[Tree$ValDef]): Array[Tree$ValDef] = - super.transform(trees); - - override def transform(trees: Array[Array[Tree$ValDef]]): Array[Array[Tree$ValDef]] = - super.transform(trees); - -}} - diff --git a/sources/scala/tools/scalac/typechecker/RefCheckPhase.scala b/sources/scala/tools/scalac/typechecker/RefCheckPhase.scala deleted file mode 100644 index accf608d0b..0000000000 --- a/sources/scala/tools/scalac/typechecker/RefCheckPhase.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac._; -import scalac.ast._; -import scalac.symtab._; -import scalac.{Global => scalac_Global} - -package scala.tools.scalac.typechecker { - -import scalac.util.NewArray; - -class RefCheckPhase(global: scalac_Global, descriptor: PhaseDescriptor) - extends Phase(global, descriptor) { - - /** Applies this phase to the given compilation unit. */ - override def apply(unit: CompilationUnit): Unit = - new RefCheck(global.asInstanceOf[scalac.Global]).apply(unit); - - override def transformInfo(sym: Symbol, tp: Type): Type = - if (sym.isModule() && !sym.isStatic()) new Type$PolyType(Symbol.EMPTY_ARRAY, tp); - else tp; - -} -} diff --git a/sources/scala/tools/scalac/typechecker/Substituter.scala b/sources/scala/tools/scalac/typechecker/Substituter.scala deleted file mode 100644 index cb358af63a..0000000000 --- a/sources/scala/tools/scalac/typechecker/Substituter.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global}; -import scalac.symtab._; -import scalac.ApplicationError; -import scalac.util._; -import scalac.ast._; - -package scala.tools.scalac.typechecker { - -// Tree Substitution ------------------------------------------------------------- - -class Substituter(global: scalac_Global, gen: TreeGen) extends Transformer(global) { - - var tparams: Array[Symbol] = _; - var targs: Array[Type] = _; - var typeSubstituter: Type$SubstTypeMap = _; - - def apply(tree: Tree, tparams: Array[Symbol], targs: Array[Type]): Tree = { - this.tparams = tparams; - this.targs = targs; - this.typeSubstituter = new Type$SubstTypeMap(tparams, targs) { - override def matches(sym1: Symbol, sym2: Symbol): boolean = { - sym1.name == sym2.name && sym1.owner() == sym2.owner(); - } - } - transform(tree); - } - - val elimInferredPolyMap: Type$Map = new Type$Map() { - def apply(t: Type): Type = { - t match { - case Type$PolyType(tparams1: Array[Symbol], restp: Type) => - if (tparams1.length == tparams.length && tparams1(0) == tparams(0)) { - for (val i <- Iterator.range(1, tparams.length)) - assert(tparams1(i) == tparams(i)); - return apply(restp); - } - case _ => - } - map(t) - } - }; - - override def transform(trees: Array[Tree]): Array[Tree] = - super.transform(trees); - - override def transform(tree: Tree): Tree = { - // System.out.println("[" + ArrayApply.toString(targs,"",",","") + "/" + ArrayApply.toString(tparams,"",",","") + "]" + tree + "@" + tree.symbol());//DEBUG - if (tree.getType() != null) { - tree.setType( - typeSubstituter.apply(elimInferredPolyMap.apply(tree.getType()))); - } - tree match { - case Tree$Ident(name) => - if (name.isTypeName()) { - val sym: Symbol = tree.symbol(); - var i = 0; - while (i < tparams.length) { - if (sym != null && typeSubstituter.matches(tparams(i), sym)) { - return gen.mkType(tree.pos, targs(i)); - } - i = i + 1; - } - } - tree - - case Tree$TypeApply(fun, targs) => - var proceed: boolean = true; - fun.getType() match { - case Type$PolyType(tparams1, _) => - if (tparams1.length == tparams.length && tparams1(0) == tparams(0) && targs.length == tparams.length) { - proceed = false; - for (val i <- Iterator.range(0, tparams.length)) - if (!typeSubstituter.matches(targs(i).getType().symbol(), tparams(i))) - proceed = true; - } - case _ => - } - val fun1: Tree = if (proceed) transform(fun) else fun; - val targs1: Array[Tree] = transform(targs); - copy.TypeApply(tree, fun1, targs1); - - case _ => - super.transform(tree); - } - } -} -} diff --git a/sources/scala/tools/scalac/typechecker/View.scala b/sources/scala/tools/scalac/typechecker/View.scala deleted file mode 100644 index 12006c292c..0000000000 --- a/sources/scala/tools/scalac/typechecker/View.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ -import scalac.symtab._; -import scalac.ast._; - -package scala.tools.scalac.typechecker { - - - -case class View(sym: Symbol, symtype: Type, qual: Tree, context: Context) { - var locked = false; -} - -} diff --git a/sources/scala/tools/scalac/util/NewArray.scala b/sources/scala/tools/scalac/util/NewArray.scala deleted file mode 100644 index 6c55656a17..0000000000 --- a/sources/scala/tools/scalac/util/NewArray.scala +++ /dev/null @@ -1,72 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.ast._; -import scalac.symtab._; -import scalac.util.Name; - -package scala.tools.scalac.util { - -object NewArray { - - def Tree(xs: Tree*): Array[Tree] = { - val arr = new Array[Tree](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def TreeArray(xs: Array[Tree]*): Array[Array[Tree]] = { - val arr = new Array[Array[Tree]](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def ValDef(xs: Tree$ValDef*): Array[Tree$ValDef] = { - val arr = new Array[Tree$ValDef](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def ValDefArray(xs: Array[Tree$ValDef]*): Array[Array[Tree$ValDef]] = { - val arr = new Array[Array[Tree$ValDef]](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def CaseDef(xs: Tree$CaseDef*): Array[Tree$CaseDef] = { - val arr = new Array[Tree$CaseDef](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def Name(xs: Name*): Array[Name] = { - val arr = new Array[Name](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def Symbol(xs: Symbol*): Array[Symbol] = { - val arr = new Array[Symbol](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def SymbolArray(xs: Array[Symbol]*): Array[Array[Symbol]] = { - val arr = new Array[Array[Symbol]](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - - def Type(xs: Type*): Array[Type] = { - val arr = new Array[Type](xs.length); - xs.elements.copyToArray(arr, 0); - arr - } - -} -} diff --git a/sources/scala/tools/scalac/wholeprog/ApplicationBuilder.scala b/sources/scala/tools/scalac/wholeprog/ApplicationBuilder.scala deleted file mode 100644 index 77f22e356c..0000000000 --- a/sources/scala/tools/scalac/wholeprog/ApplicationBuilder.scala +++ /dev/null @@ -1,525 +0,0 @@ -// $Id$ - -import scalac.{Global => scalac_Global} -import scalac.CompilationUnit; -import scalac.atree._; -import scalac.symtab._; -import scalac.util.Name; -import scalac.util._; -import scala.collection.mutable._; -import scalac.ast._; - -package scala.tools.scalac.wholeprog { - - - -/** - * This class builds the set of classes included in the Application (whole - * program), starting with a root class, given from the outside (usually - * the user). - * - */ -class ApplicationBuilder(globall: scalac_Global) { - - private val global = globall; - var rootClassName: Name = Name.fromString(""); - //var map: SymbolMap = null; - - // algorithm data - var worklist: Set[Symbol] = new HashSet[Symbol]; - var app: Set[Symbol] = new HashSet[Symbol]; - - def finalClasses(app: Set[Symbol], units: Array[CompilationUnit]): Unit = { - val m = new MonomorphicCallSites(global, app); - m.buildClassHierarchy; - - m.hierarchy.visitDFS( (n) => { - if (m.hierarchy.inEdges(n.id).length == 0) { -// Console.println("Final class: " + n.info.name.toString()); - n.info.flags = n.info.flags | Modifiers.FINAL; - } - }); - -// val transf: GenTransformer = new GenTransformer(global); - -// units.foreach( (u) => { -// u.body.foreach( (b) => transf.transform(b) ); -// }); - - m.monomorphicCallsites(units); - } - - - /** find the whole application that is referenced by the root class */ - def buildApplication(root: String, units: Array[CompilationUnit]): unit = { - rootClassName = Name.fromString(root); - - var rootClass: Symbol = null; - try { - rootClass = global.definitions.getModule(root).moduleClass(); - } catch { - case _ => global.error(root + " is not the name of an object"); - } - - if (rootClass == Symbol.NONE) - global.error(root + " is not an object"); - - // build the map from Symbol's to AST nodes - buildCodeMap(units); -// Console.println(SymbolMap); - - worklist += rootClass; - - while (!worklist.isEmpty) - visitClass(worklist.toList.head); - - dumpApplication; - - // now we call from here the final-classes analysis, - // but we should really move it to a more sensible place, like a - // whole-program anlysis controller, or "plan", the same way the - // compiler phases are structured - finalClasses(app, units); - } - // where - def buildCodeMap(units: Array[CompilationUnit]): Unit = { - //val map = new SymbolMap(); - - def mapTree(t: Tree): unit = { - t match { - case Tree$PackageDef(pack, impl) => { - mapTree(pack); - mapTree(impl); - } - - case Tree$ClassDef(mods, name, tparams, vparams, tpe, impl) => { - SymbolMap.addSymbol(t.symbol(), t); - mapTree(impl); - } - - case Tree$Template(parents, body) => { - body.foreach( (b) => mapTree(b) ); - } - - case _ => ; - }; - } - - units.foreach( (u: CompilationUnit) => - u.body.foreach( (b) => mapTree(b) )); - } - - def dumpApplication: Unit = { - val outputFile = new java.io.File(global.args.XappFile.value); - val writer: java.io.Writer = new java.io.FileWriter(outputFile); - - app.foreach( (s: Symbol) => { - writer.write(s.name.toString() + "\n"); - }); - // if we don't flush, nothing gets written?!! - writer.flush(); - } - - def visitClass(clsSym: Symbol): unit = { - if (clsSym.isExternal()) - visitExternalClass(clsSym); - else - visitInternalClass(clsSym); - } - - def visitExternalClass(clsSym: Symbol): unit = { - assert(clsSym.isClass(), "Not a class symbol? " + clsSym); - - app += clsSym; - worklist -= clsSym; - - // parents - addTypesToWorklist(List.fromArray(clsSym.parents(), 0, clsSym.parents().length)); - -// updateClassHierarchy(clsSym); - - // members - clsSym.members().elements().foreach( (s: Symbol) => { - if (s.isClass()) - visitClass(s); - else if (s.isValue() || s.isVariable()) { - // a field - } else if (s.isMethod()) { - // a method - } - }); - } - - /** - * Visit a class declaration.. Walk all its methods and add to the Application set - * all classes referenced by a method call, instantiation or assignment. We have to - * have a source represenation of this class (it is not Java code/or external class). - * - * What we include for each class: - * - superclasses - * - field types (actually their classes) - * - return and argument types for methods (actually their classes) - * - receiver type for method calls (actually its class) - * - receiver and field type for foreign field accesses (same obs as before) - */ - def visitInternalClass(clsSym: Symbol): unit = { - var cls: Tree = null; - - app += clsSym; - worklist -= clsSym; - - SymbolMap.getDefinition(clsSym) match { - case Some(c) => cls = c; - case None => { - Console.println("Could not find symbol " + clsSym + " in code map"); - return; - } - } - - val parents = clsSym.parents(); - -// updateClassHierarchy(clsSym); - - // superclasses - addTypesToWorklist(List.fromArray(parents, 0, parents.length)); - - addReferences(cls); - } - // where -/* def updateClassHierarchy(cls: Symbol): Unit = { - val parents = cls.parents(); - var i = 1; - val subclass: Node = chGraph.getNode(cls); - - def typeToSymbol(t: Type): Symbol = { - t match { - case Type$TypeRef(_, s, _) => s; - case _ => { global.error("Cannot handle base type " + t + " for " + cls ); null } - } - } - - - if (parents.length > 0) { - chGraph.addBaseClass(subclass, chGraph.getNode(typeToSymbol(parents(0)))); - while (i < parents.length) { - chGraph.addMixin(subclass, chGraph.getNode(typeToSymbol(parents(i)))); - i = i + 1; - } - } - } - -*/ - /** - * Walk the tree and add to the worklist any class symbol that is - * referenced from this tree. - */ - def addReferences(t: Tree): unit = { - t match { - case Tree$ClassDef(mods, name, tparams, vparams, tpe, impl) => { - tparams.foreach( (tpar) => addReferences(tpar) ); - vparams.foreach( (varray) => varray.foreach( (v) => addReferences(v) ) ); - - addReferences(tpe); - addReferences(impl); - } - - case Tree$PackageDef(packaged, impl) => { - addReferences(packaged); - addReferences(impl); - } - - case Tree$ModuleDef(mods, name, tpe, impl) => { - addReferences(tpe); - addReferences(impl); - } - - case Tree$ValDef(mods, name, tpe, rhs) => { - assert(t.hasSymbol()); - - val s = t.symbol().getType(); - addTypesToWorklist(s :: Nil); - - addReferences(tpe); - addReferences(rhs); - } - - case Tree$PatDef(mods, pat, rhs) => { - assert(t.hasSymbol()); - - val s = t.symbol().getType(); - addTypesToWorklist(s :: Nil); - - addReferences(pat); - addReferences(rhs); - } - - case Tree$DefDef(mods, name, tparams, vparams, tpe, impl) => { - assert(t.hasSymbol()); - - val s = t.symbol().getType(); - addTypesToWorklist(s :: Nil); - - tparams.foreach( (tpar) => addReferences(tpar) ); - vparams.foreach( (varray) => varray.foreach( (v) => addReferences(v) ) ); - - addReferences(tpe); - addReferences(impl); - } - - case Tree$AbsTypeDef(mods, name, rhs, lobound) => { - addReferences(rhs); - addReferences(lobound); - if (t.hasSymbol()) - addTypesToWorklist(t.symbol().getType() :: Nil); - } - - case Tree$AliasTypeDef(mods, name, tparams, rhs) => { - tparams.foreach( (tt) => addReferences(tt) ); - addReferences(rhs); - } - - case Tree$Import(expr, selectors) => ; - - case Tree$CaseDef(pat, guard, body) => { - addReferences(pat); - addReferences(guard); - addReferences(body); - } - - case Tree$Template(parents, body) => { - body.foreach( (b) => addReferences(b) ); - } - - case Tree$LabelDef(name, params, rhs) => { - params.foreach( (p) => addReferences(p) ); - addReferences(rhs); - } - - case Tree$Block(stats, expr) => { - stats.foreach( (stat) => addReferences(stat) ); - addReferences(expr); - } - - case Tree$Sequence(trees) => { - trees.foreach( (t) => addReferences(t) ); - } - - case Tree$Function(vparams, body) => { - vparams.foreach( (vpar) => addReferences(vpar) ); - addReferences(body); - } - - case Tree$Assign(lhs, rhs) => { - addReferences(lhs); - addReferences(rhs); - } - - case Tree$If(cond, thenp, elsep) => { - addReferences(cond); - addReferences(thenp); - addReferences(elsep); - } - - case Tree$Switch(test, tags, bodies, otherwise) => { - addReferences(test); - bodies.foreach( (b) => addReferences(b) ); - addReferences(otherwise); - } - - case Tree$Return(expr) => addReferences(expr); - - case Tree$Throw(expr) => addReferences(expr); - - // the only place where new references can be added - case Tree$New(template) => { - addReferences(template); - -// Console.println("<new> template with type! " + template.getType()); - addTypesToWorklist(template.getType() :: Nil); - } - - case Tree$Typed(expr, tpe) => { - addReferences(expr); - addReferences(tpe); - } - - case Tree$TypeApply(fun, args) => { - addReferences(fun); - args.foreach( (a) => addReferences(a) ); - } - - case Tree$Apply(fun, args) => { - addReferences(fun); - addTypesToWorklist(fun.getType() :: Nil); - - args.foreach( (a) => addReferences(a) ); - } - - case Tree$Super(qualifier, mixin) => ; - - case Tree$This(qualifier) => ; - - case Tree$Select(qualifier, selector) => { - addTypesToWorklist(qualifier.getType() :: Nil); - - addReferences(qualifier); - } - - case Tree$Ident(name) => ; - - case Tree$Literal(value) => ; - - case Tree$TypeTerm() => { - addTypesToWorklist(t.getType() :: Nil); - } - - case Tree$SingletonType(ref) => { - addReferences(ref); - } - - case Tree$SelectFromType(qualifier, selector) => addReferences(qualifier); - - case Tree$FunType(argTypes, restpe) => { - argTypes.foreach( (a) => addReferences(a) ); - addReferences(restpe); - } - - case Tree$CompoundType(parents, refinements) => { - parents.foreach( (p) => addReferences(p) ); - refinements.foreach( (r) => addReferences(r) ); - } - - case Tree$AppliedType(tpe, args) => { - addReferences(tpe); - args.foreach( (a) => addReferences(a) ); - } - - case Tree$Try(block, catcher, finalizer) => { - addReferences(block); - addReferences(catcher); - addReferences(finalizer); - } - - case _ => ; - } - } - - def addReferencesList(trees: List[Tree]) = { - trees.foreach( (t) => addReferences(t)); - } - - def typeToSymbol(t: Type): Symbol = { - t match { - case Type$TypeRef(_, s, _) => if (s.isAbstractType()) typeToSymbol(t.bound()) else s; - case Type$SingleType(pre, sym) => typeToSymbol(sym.getType()); - case Type$ThisType(sym) => sym; - case Type$PolyType(tparams, result) => typeToSymbol(result); // attention! - case Type$ConstantType(base, value) => typeToSymbol(base); - case Type$MethodType(vparams, result) => typeToSymbol(result); - case Type$CompoundType(_, _) => t.symbol(); - case _ => { global.error("Cannot handle base type " + t); null } - } - } - - def addTypesToWorklist(types: List[Type]): unit = { - types.foreach( (t) => addSymbolToWorklist(typeToSymbol(t)) ); - } - -/* - // where - def addTypesToWorklist2(types: List[Type]): unit = { - // types have to be TypeRef really, actually class types so that we - // can identify the corresponding class and add it to our processing list - types.foreach( (t: Type) => { - t.match { - case Type$TypeRef(pre, s, args) => { - addTypesToWorklist(List.fromArray[Type](args, 0, args.length)); - addSymbolToWorklist(s); - } - - case Type$CompoundType(parts, members) => Console.println("CompoundType " + t); - - case Type$ThisType(sym) => Console.println("ThisType " + t); - - case Type$SingleType(pre, sym) => Console.println("SingleType " + t); - - case Type$ConstantType(base, value) => Console.println("ConstantType " + t); - - case Type$MethodType(vparams, result) => { - val xs = List.fromArray[Symbol](vparams, 0, vparams.length); - addTypesToWorklist(xs map { (s) => s.getType() }); - addTypesToWorklist(result :: Nil); - } - - case Type$PolyType(tparams, result) => { - val xs = List.fromArray[Symbol](tparams, 0, tparams.length); - addTypesToWorklist(xs map { (s) => s.getType() }); - addTypesToWorklist(result :: Nil); - } - - case Type$OverloadedType(alts, alttypes) => Console.println("OverloadedType " + t); - - case Type$LazyType() => Console.println("LazyType " + t); - - case Type$TypeVar(origin, constr) => Console.println("TypeVar " + t); - - case Type$UnboxedType(tag) => Console.println("UnboxedType " + t); - - case Type$UnboxedArrayType(elempt) => Console.println("UnboxedArrayType " + t); - - case _ => Console.println("[worklist] Could not handle type " + t.toString()); - } - }); - } -*/ - /** the specified symbol has to be a class symbol. It adds its corresponding - * Class symbol to the worklist if the necessary conditions are met */ - def addSymbolToWorklist(sym: Symbol): Unit = { - if (sym != null && sym.isClass()) - if (!app.contains(sym) && !worklist.contains(sym)) { - global.log("Adding type " + sym + " to worklist"); - worklist += sym; - } - } -} - -/** - * A map from Symbol values to AClass values. It is used by the ApplicationBuilder - * in order to resolve class name symbols (to find their definition) - */ -object SymbolMap { - private var map: Map[Symbol, Tree] = new HashMap[Symbol, Tree](); - - def addSymbol(s: Symbol, definition: Tree): unit = - map.update(s, definition); - - /** Return the atree for the class definition of this symbol, if - * there is one, or None otherwise */ - def getDefinition(s: Symbol): Option[Tree] = { - map.get(s); - } - - def getDefinition1(s: Symbol): Tree = { - getDefinition(s) match { - case Some(t) => t; - case _ => null; - } - } - - def elements = map.elements; - - override def toString(): String = { - var str: String = ""; - - elements.foreach( (tuple: Tuple2[Symbol, Tree]) => { - str = str.concat(SymbolPrinter.fullName(tuple._1)); - str = str.concat(" -> "); - //str = str.concat(tuple._2.toString()); - str = str.concat("\n"); - }); - str; - } -} - -} // package scala.tools.scalac.globalanalysis - diff --git a/sources/scala/tools/scalac/wholeprog/Inline.scala b/sources/scala/tools/scalac/wholeprog/Inline.scala deleted file mode 100644 index 2216064bd4..0000000000 --- a/sources/scala/tools/scalac/wholeprog/Inline.scala +++ /dev/null @@ -1,235 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -/* -** Inline methods in monomoprhic callsites -** -** [iuli] 12.05.2004 */ - -import scalac.{Global => scalac_Global} -import scalac.{CompilationUnit => scalac_CompilationUnit} -import scalac.symtab._; -import scalac.util._; -import scala.collection.mutable._; -import scalac.ast._; -import scala.tools.scalac.wholeprog.graph.{Node => GNode}; -import scala.tools.scalac.wholeprog.graph._; -import scala.tools.util._; - -package scala.tools.scalac.wholeprog { - - - -/** Perform inlining of the sites passed as parameter */ -class InlineMethods(sites: MonomorphicCallSites#InlinableCollection, - global: scalac_Global) - extends Transformer(global) { - var inlines: int = 0; - var inlinedThis: Symbol = null; - - - override def transform(tree: Tree): Tree = { - tree match { - case Tree$Apply(fun, args) => { - - sites.get(tree) match { - case Some(Tuple3(cl, ce, s)) => expand(tree, cl, ce); - case _ => super.transform(tree); - } - } - - case _ => super.transform(tree); - } - } - - def expand(tree: Tree, caller: GNode[Symbol, MethodNode], callee: GNode[Symbol, MethodNode]): Tree = { - val expr: Tree = null; - val Tree$DefDef(_, name, _, vparams, _, rhs) = callee.info.code; - val subst = new HashMap[Symbol, Symbol]; - - def createLocals(tree: Tree, calleeDef: Tree): Array[Tree] = { - val Tree$Apply(fun, args) = tree; - val Tree$DefDef(_, name, _, vparams, _, rhs) = calleeDef; - - val res: Array[Tree] = new Array[Tree](args.length + 1); // make room for $this - assert(args.length == vparams(0).length, - "Call site has different nr. of arguments than def " + fun.symbol()); - - res(0) = makeThisDef(fun); - var i: int = 1; - while (i < res.length) { - // duplicate the formal parameter of the method and create a symbol for this def - val arg = vparams(0)(i-1).duplicate().asInstanceOf[Tree$ValDef]; - val sym = caller.info.method.newVariable(fun.pos, 0, Name.fromString("$" + i)); - - // set the type of the parameter to the type of the *actual* argument -// sym.setType(args(i-1).getType()); - // or the formals? - sym.setType(arg.tpe.getType()); - -// Console.println("Type: actual " + sym.getType() + " : formal " -// + arg); - - arg.tpe.setType(sym.getType()); - // add the mapping to the substitution table of symbols - subst += arg.symbol() -> sym; - - // set the initial value to the actual parameter - arg.rhs = args(i - 1).duplicate(); - arg.setSymbol(sym); - arg.rhs.setType(sym.getType()); - - res(i) = arg; - i = i + 1; - } - - res - } - - def makeThisDef(fun: Tree): Tree = { - val Tree$Select(qualifier, selector) = fun; - -// val tpe = make.TypeTerm(fun.pos); - val sym = caller.info.method.newVariable(fun.pos, 0, Name.fromString("inthis")); -// sym.setType(qualifier.getType().singleDeref()); // it was .singleDeref() but unneded? - sym.setType(callee.info.classz.getType()); - Logger.log("[inthis] Set type to " + sym.getType()); - -// val t = make.ValDef(fun.pos, 0, Name.fromString("inthis"), tpe, qualifier.duplicate()); - val t = gen.ValDef(sym, qualifier.duplicate()); - -// tpe.setType(qualifier.getType().deconst()); -// t.setSymbol(sym); - inlinedThis = sym; - - t - } - - val locals = createLocals(tree, callee.info.code); - val updater = new UpdateAccesses(subst, caller.info.method); - val newRhs = updater.transform(rhs.duplicate()); - - Logger.log("[inline] expand reached"); - - if (updater.touchedPrivate) - tree - else { - Logger.log("Inlining at " + - caller.info.classz.name + "." + - caller.info.method.name + " [" + Position.toString(tree.pos) + "] with " + - callee.info.classz.name + "." + - callee.info.method.name); - inlines = inlines + 1; - - gen.mkBlock(locals, newRhs); - } - } - - /** Update accesses to symbols that have been replaced according to the map */ - class UpdateAccesses(subst: HashMap[Symbol, Symbol], hostMethod: Symbol) - extends GenTransformer(global) { - - var touchedPrivate: boolean = false; - - override def transform(tree: Tree): Tree = { - tree match { - case Tree$This(qualifier) => { - assert(inlinedThis != null, "<this> is null for " + tree); - gen.Ident(tree.pos, inlinedThis); - } - - // create a new symbol for the new declaration in this method - case Tree$ValDef(mods, name, tpe, rhs) => { - val newSym = hostMethod.newVariable(tree.pos, mods, name); - - newSym.setType(tpe.getType()); - subst += tree.symbol() -> newSym; - - tree.setSymbol(newSym); - - gen.ValDef(newSym, transform(rhs)); - } - - case Tree$Super(_, _) => { - Logger.log("[inline] Touched super."); - touchedPrivate = true; // not private, but still we cannot inline this function - super.transform(tree); - } - - case Tree$Return(_) => { - Logger.log("[inline] Touched return."); - touchedPrivate = true; // not private, but still we cannot inline this function - super.transform(tree); - } - - case Tree$LabelDef(name, params, rhs) => { - val newSym = hostMethod.newLabel(tree.pos, name); - - newSym.setInfo(tree.symbol().info()); - subst += tree.symbol() -> newSym; - - gen.LabelDef(newSym, super.transform(params), transform(rhs)); - } - - case Tree$PatDef(mods, pat, rhs) => { - Console.println("new pattern definition in inlined class"); - tree - } - - case Tree$DefDef(_, _, _, _, _, _) => { - assert(false, "We should be after lambda lift, so no inner function allowed"); - tree; - } - - case _ => super.transform(tree); - - } - - } - - override def getSymbolFor(tree: Tree): Symbol = { - if (!tree.symbol().isPublic() || - (tree.symbol().flags & Modifiers.PACKAGE) > 0 ) { // attention, was isPrivate() - touchedPrivate = true; - Logger.log("[inline] touched private symbol " + - SymbolPrinter.fullName(tree.symbol())); - } - - if (subst.contains(tree.symbol())) { - Logger.log("[inline] Substituted " + tree.symbol() + " with " + subst(tree.symbol())); - subst(tree.symbol()); - } - else - super.getSymbolFor(tree); - //tree.symbol(); - } - - } -} - -object Logger { - var file: java.io.Writer = null; - - def setFile(name: String): Unit = { - file = new java.io.FileWriter(name); - } - - def log(s: String): Unit = { - file.write(s + "\n"); - } - - def log(s1: String, s2: String): Unit = { - file.write(s1 + " " + "\n"); - } - - def flush: unit = { - file.flush(); - } -} - -} // package scala.tools.scalac.wholeprog diff --git a/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala b/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala deleted file mode 100644 index e71fdd2004..0000000000 --- a/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala +++ /dev/null @@ -1,443 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -/* -** The Whole Program analysis phase. -** -** Identify monomorphic call sites in classes (where the receiver -** can always be statically determined). -** -** [iuli] 2.05.2004 */ - -import scalac.{Global => scalac_Global} -import scalac.CompilationUnit; -import scalac.symtab._; -import scalac.util._; -import scala.collection.mutable._; -import scalac.ast._; -import scala.tools.scalac.wholeprog.graph.{Node => GNode}; -import scala.tools.scalac.wholeprog.graph._; - -package scala.tools.scalac.wholeprog { - - - -class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) { - type CallGraph = Graph[Symbol, MethodNode, CallEdge]; - type CallGraphNode = GNode[Symbol, MethodNode]; - type CallGraphEdge = Edge[Symbol, CallEdge]; - - type InlinableCollection = HashMap[Tree, Tuple3[CallGraphNode, CallGraphNode, CallSite]]; - - private val global = globall; - val hierarchy = new Graph[Symbol, Symbol, String]; - val callGraph = new CallGraph; - - var instantiatedClasses = new HashSet[Symbol]; - - var inlinable: InlinableCollection = new InlinableCollection; - - - /** create the class inheritance hierarchy */ - def buildClassHierarchy: Unit = { - application.foreach( (sym) => { - hierarchy.addNode(new GNode(sym, sym)); - }); - - application.foreach( (sym) => { - val parents = sym.parents(); - - // the first "parent" is always the superclass? seems to be like that - val superclass = if (parents.length > 0) parents(0) else null; - - parents.foreach( (p) => { - val e = new Edge[Symbol, String](sym, typeToSymbol(p)); - - e.info = if (p == superclass) "extends" else "with"; - hierarchy.addEdge(e); - }); - }); - - if (!global.args.XdotFile.value.equals("$")) { - val file: java.io.Writer = new java.io.FileWriter("ch.dot"); - file.write(hierarchy.toDotString); - file.flush(); - } - } - - - def typeToSymbol(t: Type): Symbol = { - t match { - case Type$TypeRef(_, s, _) => if (s.isAbstractType()) typeToSymbol(t.bound()) else s; - case Type$SingleType(pre, sym) => typeToSymbol(sym.getType()); - case Type$ThisType(sym) => sym; - case Type$PolyType(tparams, result) => typeToSymbol(result); // attention! - case Type$ConstantType(base, value) => typeToSymbol(base); - case Type$MethodType(vparams, result) => typeToSymbol(result); - case Type$CompoundType(_, _) => t.symbol(); - case _ => { global.error("* Cannot handle base type " + t); null } - } - } - - /** Identify and print monomoprhic callsites */ - def monomorphicCallsites(units: Array[CompilationUnit]): Unit = { - val cg = callGraph; - var nr: int = 0; - var views: Int = 0; - var closures: Int = 0; - - def logStatistics(e: CallGraphEdge): Unit = { - if (cg.getNode(e.to).info.method.name.toString().equals("apply")) { - closures = closures + 1; -// Console.println("[closure] " + cg.getNode(e.from).info.classz.name + "." + -// cg.getNode(e.from).info.method.name + " -> " + -// cg.getNode(e.to).info.classz.name + "." + -// cg.getNode(e.to).info.method.name); - } - if (cg.getNode(e.to).info.method.name.toString().equals("view")) - views = views + 1; - } - - def inlineCallSite(e: CallGraphEdge): Unit = { - val caller = cg.getNode(e.from); - val callee = cg.getNode(e.to); - - if (canInline(caller, callee)) - inlinable += e.info.site.t -> new Tuple3(caller, callee, e.info.site); - } - - def canInline(caller: CallGraphNode, callee: CallGraphNode): boolean = - !callee.info.method.isInitializer() && - caller.info.code != null && - callee.info.code != null && - !callee.info.method.isDeferred() && - application.contains(caller.info.classz) && - application.contains(callee.info.classz); - - Logger.setFile("inlining.log"); - - Console.println("[start build callgraph]"); StopWatch.start; - buildCallGraph(units); - Console.println("[end build callgraph] " + StopWatch.stop + " ms"); - - if (global.args.Xrta.value) { - // perform additional pruning - Console.println("[start RTA]"); - rapidTypeAnalysis(instantiatedClasses); - Console.println("[end RTA] " + StopWatch.stop + " ms"); - } - - if (!global.args.XdotFile.value.equals("$")) - dumpCallGraph; - - Console.println("[start Monomorphic call site identification]"); StopWatch.start; - cg.nodes.foreach( (id: Symbol, n: CallGraphNode) => { - n.info.callSites.foreach( (site) => { - val mcs = cg.getOutEdges(id).filter( e => e.info.site == site ); - - if (mcs.length == 1) { - inlineCallSite(mcs.head); -// Console.println("Monomorphic call-site: " + mcs.head.from + " " + mcs.head.to); - logStatistics(mcs.head); - nr = nr + 1; - } - }); - }); - Console.println("[end Monomorphic call site identification] " + StopWatch.stop + " ms"); - - Console.println("We identified " + nr + " monomorphic call-sites. (" - + inlinable.size + " inlinable)."); - Console.println("[closures = " + closures + " out of " + closuresTotal + - ", views = " + views + "out of " + viewsTotal + "]"); - - if (global.args.Xinline.value) { - Console.println("[start inlining]"); StopWatch.start; - - doInline(units, inlinable); - Console.println("[end inlining] " + StopWatch.stop + " ms"); - } - } - - /** Perform a form of rapid type analysis, as described in Sundaresan 99 - The idea is that the call graph can be signifficanly pruned if all edges that go - into a method of a class that was never instantiated in the program are removed. - - The assumption is that all "new" statements are known, and there is no other way to - instantiate classes. While the first one may be true for whole-program analysis - (and the -separate:no flag for scalac), the second might not hold: object classes - (singletons) are created "magically", and no "new" statement is parsed. - */ - def rapidTypeAnalysis(instances: Set[Symbol]): Unit = { - - /** instantiated classes include singleton classes */ - def isInstatiated(s: Symbol): boolean = - instances.contains(s) || - s.getType().isSubType(global.definitions.ANYVAL_TYPE()) || - s.isModuleClass(); - - Console.println("Printing instantiated classes"); - Logger.log("[RTA] Instantiated classes: "); - instantiatedClasses.foreach( s => Logger.log("[RTA] " + SymbolPrinter.fullName(s))); - - Console.println("[Visiting call graph]"); - - val it = callGraph.nodeIterator; - - while (it.hasNext) { - val n = it.next; - - n.info.callSites.foreach( (site) => { - val targets = callGraph.getOutEdges(n.id).filter( e => e.info.site == site ); - - if (targets.length > 1) { - // test for instantiation - targets.foreach( (t: CallGraphEdge) => if ( !isInstatiated(callGraph.getNode(t.to).info.classz) ) { - callGraph.removeEdge(t); - Logger.log("[RTA] Removed edge to " + SymbolPrinter.fullName(t.to)); - }); - } - }); - } - - } - - /** perform inlines */ - def doInline(units: Array[CompilationUnit], sites: InlinableCollection): Unit = { - val transformer: Transformer = new InlineMethods(sites, global); - - units.foreach( (u) => { - u.body = transformer.transform(u.body); - }); - - Console.println("We inlined " + transformer.asInstanceOf[InlineMethods].inlines + " callsites"); - Logger.flush; - } - - var unknown = 0; // calls to "null" methods - var closuresTotal = 0; // calls to "apply" methods - var viewsTotal = 0; // calls to "view" methods - - - def buildCallGraph(units: Array[CompilationUnit]): Unit = { - createNodes(units, callGraph); - createEdges(units, callGraph); - - // print call graph size - var nodes = 0; - var edges = 0; - var callsites = 0; - - callGraph.nodes.foreach( (id: Symbol, n: CallGraphNode) => { - nodes = nodes + 1; - callsites = callsites + n.info.callSites.length; - edges = edges + callGraph.getOutEdges(id).length; - }); - - Console.println("Call graph: " + nodes + " nodes, " + - edges + " edges, [" /* + callGraph.edges.length */ + "]" + - callsites + " callsites." + "(unknown = " + unknown + ")"); - } - - def dumpCallGraph: Unit = { - val file: java.io.Writer = new java.io.FileWriter("callGraph.dot"); - file.write(callGraph.toDotString); - file.flush(); - } - - def createNodes(units: Array[CompilationUnit], cg: CallGraph): Unit = { - val trav: Traverser = new MethodNodeCreator(cg); - - units.foreach( (u) => trav.traverse(u.body) ); - } - - def createEdges(units: Array[CompilationUnit], cg: CallGraph): Unit = { - val trav: Traverser = new CallGraphEdgeTraverser(cg); - - units.foreach( (u) => trav.traverse(u.body) ); - } - - /** Walk the nodes in the AST tree and creates nodes in the callgraph - corresponding to each method */ - class MethodNodeCreator(cg: CallGraph) extends Traverser { - - override def traverse(tree: Tree): Unit = { - tree match { - case Tree$DefDef(_, name, _, _, _, _) => { - val methSym = tree.symbol(); - - cg.addNode(new CallGraphNode(methSym, new MethodNode(methSym, methSym.enclClass(), tree))); - } - - case _ => ; - } - - super.traverse(tree); - } - } - - - /** Walk all source code and create the call graph edges. */ - class CallGraphEdgeTraverser(cg: CallGraph) extends Traverser { - var enclMethod: Symbol = null; - - override def traverse(tree: Tree): Unit = { - var oldMethod: Symbol = enclMethod; - - tree match { - case Tree$DefDef(_, name, _, _, _, _) => { - oldMethod = enclMethod; - enclMethod = tree.symbol(); - - super.traverse(tree); - } - - case Tree$Create(qualifier, targs) => { -// Console.println("Create: " + tree.symbol()); - assert(tree.symbol().isClass()); - instantiatedClasses += tree.symbol(); - - traverse(qualifier); - } - - case Tree$Apply(fun, args) => { - - if (enclMethod != null) { - val targetMeth = fun.symbol(); - - if (targetMeth != null) { - if (targetMeth.name.toString().equals("apply")) - closuresTotal = closuresTotal + 1; - else if (targetMeth.name.toString().equals("view")) - viewsTotal = viewsTotal + 1; - - createEdges(targetMeth, tree); - } - else - unknown = unknown + 1; - - -// fun match { -// case Tree$Select(qualifier, selector) => { -// val target = typeToSymbol(qualifier.getType()); - -// if (target != null) -// createEdges(target, qualifier, selector, tree); -// } -// case _ => ; -// } /* else -// Console.println("No f***ing enclosing method - " + fun); */ - } - - traverse(fun); - args.foreach( a => traverse(a)); - }; - - case _ => super.traverse(tree); - } - - enclMethod = oldMethod; - } - - /** Add edges between the callsite and all possible targets. Possible - * targets are methods in the target class (or "nearest" superclass) - * or subclasses that override the specific method */ - def createEdges(targetMeth: Symbol, t: Tree): Unit = { - val site: CallSite = new CallSite(t); - - def createEdgesForSubclasses(cls: Symbol): Unit = { - // walk all subclasses - hierarchy.getInEdges(cls).foreach( (e) => { - val c = hierarchy.nodes(e.from).info; - val it = c.members().iterator(); - - while (it.hasNext()) { - val m = it.next(); - if (m.overrides(targetMeth)) { - if (cg.getNode(m) == null) - cg.addNode(new CallGraphNode(m, new MethodNode(m, c, null))); - - cg.addEdge(enclMethod, m).info = new CallEdge(t, site); - } - } - -// else Console.println("Found a subclass that is not a subtype: " + -// SymbolPrinter.fullName(c) + "[" + c.getType() + "] not <: " + -// targetCls + "[" + refType + "]"); - - createEdgesForSubclasses(c); - }); - - } - - // add callsite to node - if (cg.getNode(enclMethod) == null) - cg.addNode(new CallGraphNode(enclMethod, new MethodNode(enclMethod, enclMethod.enclClass(), null))); - - cg.getNode(enclMethod).info.callSites = site :: cg.getNode(enclMethod).info.callSites; - - if (targetMeth != Symbol.NONE) { - if (cg.getNode(targetMeth) == null) - cg.addNode(new CallGraphNode(targetMeth, new MethodNode(targetMeth, targetMeth.enclClass(), null))); - - cg.addEdge(enclMethod, targetMeth).info = new CallEdge(t, site); - } - - createEdgesForSubclasses(targetMeth.enclClass()); - } - } - -} - -/** Class that maintains information about nodes in the callgraph */ -case class MethodNode(method: Symbol, classz: Symbol, code: Tree) { - var callSites: List[CallSite] = Nil; - - override def toString(): String = SymbolPrinter.fullName(method); -} - -case class CallSite(t: Tree) { -} - -class CallEdge(code: Tree, s: CallSite) { - val site = s; - override def toString() = "\"" + s.hashCode() + "\""; -} - - -object SymbolPrinter { - def fullName(s: Symbol): String = { - - def fullName2(post: String, s: Symbol): String = - if (s.owner().isRoot()) - s.name.toString() + "." + post - else - fullName2(s.name.toString() + "." + post, s.owner()); - - fullName2(s.name.toString(), s.owner()) - } - -} - - -object StopWatch { - var startTimeMillis: Long = 0; - - /** arm the stop watch */ - def start: Unit = { - startTimeMillis = System.currentTimeMillis(); - } - - /** Retrieve the elapsed time and arm the stopwatch again */ - def stop: Long = { - val time = System.currentTimeMillis() - startTimeMillis; - start; - time - } -} - -} // package wholeprog diff --git a/sources/scala/tools/scalac/wholeprog/PrintDotFile.scala b/sources/scala/tools/scalac/wholeprog/PrintDotFile.scala deleted file mode 100644 index 656de1b275..0000000000 --- a/sources/scala/tools/scalac/wholeprog/PrintDotFile.scala +++ /dev/null @@ -1,431 +0,0 @@ -// $Id$ - -import scalac.{CompilationUnit => scalac_CompilationUnit} -import scalac.ast._; -import scalac.util.Name; - -package scala.tools.scalac.wholeprog { - -/** - * Print the AST into a dot file, which can be used by - * the graphviz "dot" tool to build a graph image. Useful for - * understanding the Abstract Syntax Tree. - */ -class PrintDotFile(_units: Array[scalac_CompilationUnit]) { - private val units = _units; - private var writer: java.io.Writer = null; - - def makeDotFile(output: String): unit = { - val outputFile = new java.io.File(output); - writer = new java.io.FileWriter(outputFile); - - writer.write("digraph tree {\nnode [style=filled, color=cadetblue2];\n"); - - units.foreach( (u:scalac_CompilationUnit) => - u.body.foreach ( (t: Tree) => walk(t, null) ) ); - - writer.write("}\n"); - writer.close(); - } - - - def makeDotFile(output: String, tree: Tree): unit = { - writer = new java.io.FileWriter(output); - - writer.write("digraph tree {\nnode [style=filled, color=cadetblue2];\n"); - - walk(tree, null); - - writer.write("}\n"); - writer.close(); - } - - def printNode(t: Object, label: String): unit = { - writer.write(t.hashCode().toString() + " [label = \"" + label + "\"];\n"); - } - - - def printEdge(t1: Object, t2: Object, label: String): unit = { - if (t1 != null) - writer.write(t1.hashCode().toString() + " -> " + t2.hashCode().toString() + - "[label= \"" + label + "\"];\n"); - } - - def printEdge(t1: Object, t2: Object): unit = printEdge(t1, t2, ""); - - def walk(t: Tree, parent: Tree, l: String): unit = { - t match { - -// case Tree$Empty => { -// printNode(t, "Empty"); -// printEdge(parent, t); -// } - - case Tree$DocDef(comment, definition) => { - printNode(t, "DocDef"); - printEdge(parent, t); - - walk(definition, t); - } - - case Tree$ClassDef(mods, name, tparams, vparams, tpe, template) => { - printNode(t, "ClassDef: " + name.toString()); - printEdge(parent, t); - - tparams.foreach( (p: Tree) => { - walk(p, t); - }); - - vparams.foreach( (arr) => { - (p: Tree) => walk(p, t); - }); - - walk(tpe, t); - - walk(template, t); - } - - case Tree$PackageDef(packaged, impl) => { - printNode(t, "PackageDef"); - printEdge(parent, t); - - walk(packaged, t); - walk(impl, t); - } - - case Tree$ModuleDef(_, name, tpe, impl) => { - printNode(t, "ModuleDef: " + name.toString()); - printEdge(parent, t); - - walk(tpe, t); - walk(impl, t); - } - - case Tree$ValDef(_, name, tpe, rhs) => { - printNode(t, "ValDef: " + name.toString()); - printEdge(parent, t); - - walk(tpe, t); - walk(rhs, t); - } - - case Tree$PatDef(_, pat, rhs) => { - printNode(t, "PatDef"); - printEdge(parent, t); - - walk(pat, t); - walk(rhs, t); - } - - case Tree$DefDef(_, name, tparams, vparams, tpe, rhs) => { - printNode(t, "DefDef: " + name.toString()); - printEdge(parent, t); - - tparams.foreach( (tt) => walk(tt, t) ); - - vparams.foreach( (at) => at.foreach( (tt) => walk(tt, t) ) ); - walk(tpe, t); - walk(rhs, t); - } - - case Tree$AbsTypeDef(_, name, rhs, lobound) => { - printNode(t, "AbsTypeDef: " + name.toString()); - printEdge(parent, t); - - walk(rhs, t); - walk(lobound, t); - } - - case Tree$AliasTypeDef(_, name, tparams, rhs) => { - printNode(t, "AliasTypeDef: " + name.toString()); - printEdge(parent, t); - - tparams.foreach( (tt) => walk(tt, t) ); - walk(rhs, t); - } - - case Tree$Import(expr, selectors) => { - printNode(t, "Import"); - printEdge(parent, t); - - walk(expr, t); - selectors.foreach( (n: Name) => { - printNode(n, "Name: " + n); - printEdge(t, n); - }); - } - - case Tree$CaseDef(pat, guard, body) => { - printNode(t, "CaseDef"); - printEdge(parent, t); - - walk(pat, t); - walk(guard, t); - walk(body, t); - } - - case Tree$Template(parents, body) => { - printNode(t, "Template"); - printEdge(parent, t); - - parents.foreach( (tt) => { - walk(tt, t, "parent"); - }); - - body.foreach( (tt) => { - walk(tt, t, "body"); - }); - } - - case Tree$LabelDef(name, params, rhs) => { - printNode(t, "LabelDef: " + name.toString()); - printEdge(parent, t); - - params.foreach( (tt) => walk(tt, t) ); - walk(rhs, t); - } - - case Tree$Block(stats, expr) => { - printNode(t, "Block"); - printEdge(parent, t); - - stats.foreach( (tt) => walk(tt, t) ); - walk(expr, t); - } - - case Tree$Sequence(trees) => { - printNode(t, "Sequence"); - printEdge(parent, t); - - trees.foreach( (tt) => walk(tt, t) ); - } - - case Tree$Alternative(trees) => { - printNode(t, "Alternative"); - printEdge(parent, t); - - trees.foreach( (tt) => walk(tt, t) ); - } - - case Tree$Bind(name, rhs) => { - printNode(t, "Bind: " + name.toString()); - printEdge(parent, t); - - walk(rhs, t); - } - - case Tree$Visitor(cases) => { - printNode(t, "Visitor"); - printEdge(parent, t); - - cases.foreach( (tt) => walk(tt, t) ); - } - - case Tree$Function(vparams, body) => { - printNode(t, "Function"); - printEdge(parent, t); - - vparams.foreach( (tt) => walk(tt, t) ); - walk(body, t); - } - - case Tree$Assign(lhs, rhs) => { - printNode(t, "Assign"); - printEdge(parent, t); - - walk(lhs, t); - walk(rhs, t); - } - - case Tree$If(cond, thenp, elsep) => { - printNode(t, "If"); - printEdge(parent, t); - - walk(cond, t); - walk(thenp, t); - walk(elsep, t); - } - - // we ignore the "tags" array... - case Tree$Switch(test, _, bodies, otherwise) => { - printNode(t, "Switch"); - printEdge(parent, t); - - walk(test, t); - bodies.foreach( (tt) => walk(tt, t) ); - walk(otherwise, t); - } - - case Tree$Return(expr) => { - printNode(t, "Return"); - printEdge(parent, t); - - walk(expr, t); - } - - case Tree$Throw(expr) => { - printNode(t, "Throw"); - printEdge(parent, t); - - walk(expr, t); - } - - case Tree$New(template) => { - printNode(t, "New"); - printEdge(parent, t); - - walk(template, t); - } - - case Tree$Create(qualifier, targs) => { - printNode(t, "Create"); - printEdge(parent, t); - - walk(qualifier, t); - targs.foreach( (a) => walk(a, t) ); - } - - case Tree$Typed(expr, tpe) => { - printNode(t, "Typed"); - printEdge(parent, t); - - walk(expr, t); - walk(tpe, t); - } - - case Tree$TypeApply(fun, args) => { - printNode(t, "TypeApply"); - printEdge(parent, t, l); - - walk(fun, t); - - args.foreach( (tt) => walk(tt, t) ); - } - - case Tree$Apply(fun, args) => { - printNode(t, "Apply"); - printEdge(parent, t, l); - - walk(fun, t, "fun"); - - args.foreach( (tt) => walk(tt, t, "arg") ); - } - - case Tree$Super(qualifier, mixin) => { - printNode(t, "Super"); - printEdge(parent, t); - - printNode(qualifier, "Qualifier: " + qualifier.toString()); - printNode(mixin, "Mixin: " + mixin.toString()); - - printEdge(t, qualifier); - printEdge(t, mixin); - } - - case Tree$This(qualifier) => { - printNode(t, "This"); - printEdge(parent, t); - - printNode(qualifier, "Qualifier: " + qualifier); - printEdge(t, qualifier); - } - - case Tree$Select(qualifier, selector) => { - printNode(t, "Select"); - printEdge(parent, t, l); - -// printNode(qualifier, "Qualifier: " + qualifier.toString()); -// printEdge(t, qualifier); -// printNode(qualifier, "Qualifier"); -// Console.println("--qualifier: " + qualifier + " : " + selector); - walk(qualifier, t); - - printNode(selector, "Selector: " + selector.toString()); - printEdge(t, selector); - } - - case Tree$Ident(name) => { - printNode(t, "Ident"); - printEdge(parent, t); - - printNode(name, "Name: " + name); - printEdge(t, name); - } - - case Tree$Literal(value) => { - printNode(t, "Literal"); - printEdge(parent, t); - - printNode(value, "Value: " + value); - printEdge(t, value); - } - - case Tree$TypeTerm() => { - printNode(t, "TypeTerm: " + t.getType()); - printEdge(parent, t); - } - - case Tree$SingletonType(ref) => { - printNode(t, "SingletonType"); - printEdge(parent, t); - - walk(ref, t); - } - - case Tree$SelectFromType(qual, selector) => { - printNode(t, "SelectFromType"); - printEdge(parent, t); - - walk(qual, t); - printNode(selector, "Selector: " + selector); - printEdge(t, selector); - } - - case Tree$FunType(argtypes, restpe) => { - printNode(t, "FunType"); - printEdge(parent, t); - - argtypes.foreach( (tt) => walk(tt, t) ); - walk(restpe, t); - } - - case Tree$CompoundType(parents, refinements) => { - printNode(t, "CompoundType"); - printEdge(parent, t); - - parents.foreach( (tt) => walk(tt, t) ); - refinements.foreach( (tt) => walk(tt, t) ); - } - - case Tree$AppliedType(tpe, args) => { - printNode(t, "AppliedType"); - printEdge(parent, t); - - walk(tpe, t); - args.foreach( (tt) => walk(tt, t) ); - } - - case Tree$Try(block, catcher, finalizer) => { - printNode(t, "Try"); - printEdge(parent, t); - - walk(block, t); - walk(catcher, t); - walk(finalizer, t); - } - - case _ => { -// Console.println(t.toString()); -// assert(false, t.toString()); -// printNode(t.symbol().name.toString(), "Unknown"); -// if (parent != null) -// printEdge(parent.symbol().name.toString(), t.symbol().name.toString()); - } - } - } - - def walk(t: Tree, parent: Tree): unit = walk(t, parent, ""); - -} // class PrintDotFile - -} // package scala.tools.scalac.wholeprog diff --git a/sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala b/sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala deleted file mode 100644 index 4666b577a1..0000000000 --- a/sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -/* -** The Global analysis phase. -** -** We add a new phase in the compiler, WholeProgPhase. -** -** [iuli] 3.03.2004 */ - -import scalac.{Global => scalac_Global} -import scalac.transformer.{WholeProgPhase => scalac_WholeProgPhase} -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.util.Debug; - -package scala.tools.scalac.wholeprog { - -/** - * This phase analyzes the whole program and tries to derive some - * useful facts about it: which classes can be marked final, what - * methods, fields are never used, and monomorphic call-sites. - */ -class WholeProgPhase(global: scalac_Global, descriptor: PhaseDescriptor) - extends scalac_WholeProgPhase (global, descriptor) { - - - /* Apply the global analysis phase to the given units */ - def applyAll(units: Array[CompilationUnit]): unit = { - - if (!global.args.XdotFile.value.equals("$")) { - val dotFilePrinter = new PrintDotFile(units); - dotFilePrinter.makeDotFile(global.args.XdotFile.value); - } - - if (!global.args.XrootClass.value.equals("$")) { - - var builder: ApplicationBuilder = new ApplicationBuilder(global); - builder.buildApplication(global.args.XrootClass.value, units); - } - - if (!global.args.XdotFile.value.equals("$")) { - val dotFilePrinter = new PrintDotFile(units); - dotFilePrinter.makeDotFile(global.args.XdotFile.value + "2"); - } - } - - override def apply(unit: CompilationUnit): Unit = - throw Debug.abort("!!! Phase " + this + " is currently disabled"); - -} - -} diff --git a/sources/scala/tools/scalac/wholeprog/graph/Graph.scala b/sources/scala/tools/scalac/wholeprog/graph/Graph.scala deleted file mode 100644 index 59c6f3ffdb..0000000000 --- a/sources/scala/tools/scalac/wholeprog/graph/Graph.scala +++ /dev/null @@ -1,189 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scala.collection.mutable._; - -package scala.tools.scalac.wholeprog.graph { - - -/** Defualt implementation for Node objects, which can have any - * identifier */ -class Node[id_t, info_t](i: id_t, nn: info_t) { - var info: info_t = nn; - val id: id_t = i; - - override def toString(): String = "\"" + id.hashCode() + - "\"[ label = \"" + info + "\" ]"; -} - -/** Default implementation for edges. It takes two parameters, the - * start and the end identifiers for the nodes it connects */ -class Edge[id_t, info_t](start: id_t, end: id_t) { - val from = start; - val to = end; - var info: info_t = _; - - override def toString(): String = "\"" + start.hashCode() + "\" -> " + "\"" - + end.hashCode() + "\"[ label = \"" + info + "\" ]"; -} - - -class InvalidEdgeException(from: String, to: String) extends java.lang.Exception { - override def toString(): String = "Edge [" + from + " -> " + to + - "] references non existent nodes"; -} - - -/** The Graph class, parameterized with the node and edge types - * The id_t is the type of the identifier of nodes. This is used - * when retrieving nodes from the graph. The node_t is the type of - nodes, which have to subtype the Node trait. edge_t is the type - of edges, which again is a subtype of Edge. */ - -class Graph[id_t, node_info_t, edge_info_t] { - type node_t = Node[id_t, node_info_t]; - type edge_t = Edge[id_t, edge_info_t]; - - var nodes: HashMap[id_t, node_t] = new HashMap[id_t, node_t]; - var edges: List[edge_t] = Nil; - - val inEdges: HashMap[id_t, List[edge_t]] = new HashMap[id_t, List[edge_t]]; - val outEdges: HashMap[id_t, List[edge_t]] = new HashMap[id_t, List[edge_t]]; - - - def addNode(n: node_t): Unit = { - nodes += n.id -> n; - inEdges += n.id -> Nil; - outEdges += n.id -> Nil; - } - - def addEdge(from: id_t, to: id_t): edge_t = addEdge(new Edge(from, to)); - - def addEdge(e: edge_t): edge_t = { - if ((nodes contains e.from) && (nodes contains e.to)) { - edges = e :: edges; - addEdgeToIncidenceMap(outEdges, e, getNode(e.from)); - addEdgeToIncidenceMap(inEdges, e, getNode(e.to)); - } //else -// throw new InvalidEdgeException(e.start, e.end); - e - } - - def removeEdge(e: edge_t): edge_t = { - edges = edges.remove( ee => e == ee ); - outEdges += e.from -> getOutEdges(e.from).remove( ee => e == ee); - inEdges += e.to -> getInEdges(e.to).remove(ee => e == ee); - - e - } - - def removeEdges(es: List[edge_t]): Unit = es match { - case Nil => (); - case e :: ee => { removeEdge(e); removeEdges(ee) } - } - - def addEdgeToIncidenceMap(map: HashMap[id_t, List[edge_t]], e: edge_t, n: node_t): Unit = { - map.get(n.id) match { - case Some(l) => map += n.id -> (e :: l); - case None => map += n.id -> (e :: Nil); - } - } - - def getOutEdges(node: id_t): List[edge_t] = outEdges.get(node) match { - case Some(l) => l; - case None => Nil; - } - - def getInEdges(node: id_t): List[edge_t] = inEdges.get(node) match { - case Some(l) => l; - case None => Nil; - } - - def visitDFS(f: (node_t) => Unit): Unit = { - val visited = new HashSet[node_t]; - var i = nodeIterator; - - while (i.hasNext) { - visitDFS(i.next, f, visited); - } - } - - private def visitDFS(currentNode: node_t, f: (node_t) => Unit, visited: Set[node_t]): Unit = { - if (!visited.contains(currentNode)) { - visited += currentNode; - f(currentNode); - - getOutEdges(currentNode.id) foreach { (e) => { - visitDFS(getNode(e.to), f, visited); - }} - } - } - - def getNode(id: id_t): node_t = nodes.get(id) match { - case Some(n) => n; - case None => null; - } - - def getRootNodes: Iterator[node_t] = { - for (val elem <- nodes.elements; getInEdges(elem._2.id) == Nil) - yield elem._2; - } - - /** Remove all nodes with degree 0. Return the graph. */ - def prune: Graph[id_t, node_info_t, edge_info_t] = { - nodes.filter( (id, n) => inEdges(id) != Nil || outEdges(id) != Nil ); - - this - } - - /* graph visualization */ - - override def toString(): String = { - var s = ""; - - edges.foreach( (e) => s = s + e + "\n" ); - s - } - - def toDotString: String = { - var str = "digraph grph {\n"; - - val it = nodeIterator; - while (it.hasNext) { - val node = it.next; - str = str + node + "\n";// + " [label = \"" + node.id + "\"];\n"; - } - - // edges - edges.foreach( (e) => str = str + e + "\n" ); - str + "}\n"; - } - - def nodeIterator: GraphIterator = new GraphIterator(); - - /** Iterator for graph nodes */ - class GraphIterator extends Iterator[node_t] { - val elem = nodes.elements; - - override def hasNext: Boolean = elem.hasNext; - override def next: node_t = elem.next._2; - } - - - def consistencyCheck: Unit = { - edges.foreach( (e) => { - if ( !(getOutEdges(e.from) contains e) ) - Console.println("Edge " + e + " not found in out edges of " + e.from); - - if ( !(getInEdges(e.to) contains e) ) - Console.println("Edge " + e + " not found in in edges of " + e.to); - }); - } -} - -} // graph package diff --git a/sources/scala/tools/scaladoc/Comment.java b/sources/scala/tools/scaladoc/Comment.java deleted file mode 100644 index d5d71af13e..0000000000 --- a/sources/scala/tools/scaladoc/Comment.java +++ /dev/null @@ -1,259 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.util.*; -import java.util.regex.*; -import ch.epfl.lamp.util.Pair; -import scalac.symtab.Symbol; -import scalac.CompilationUnit; - -import java.io.StringReader; -import org.xml.sax.*; -import org.xml.sax.helpers.DefaultHandler; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; - -/** - * Class <code>Comment</code> contains all information in comment part. - * It allows users to get first sentence of this comment, get comment - * for different tags... - */ -public class Comment extends DefaultHandler { - - /** - * Holder of the comment. - */ - public final Symbol holder; - - /** - * CompilationUnit of the symbol associated with this comment. - */ - CompilationUnit unit; - - /** - * Raw text of the comment. - */ - public final String rawText; - - /** - * Text minus any tags. - */ - public String text; - - /** - * Tags minus text. - */ - public Tag[] tags; - - /** - * Constructor. - * - * @param holder - * @param rawText - */ - public Comment(String rawText, Symbol holder, CompilationUnit unit, HTMLValidator html) { - this.holder = holder; - this.rawText = cleanComment(rawText); - this.unit = unit; - if (!isEmpty()) - html.validate(this.rawText, this); - parseComment(); - } - - /** - * Returns true if this comment is empty. - */ - public boolean isEmpty() { - return "".equals(rawText); - } - - /** - * Tests if the comment contains a specified tag. - */ - public boolean containsTag(String name) { - name = name.startsWith("@") ? name : "@" + name; - for(int i = 0; i < tags.length; i++) - if (tags[i].name.equals(name)) - return true; - return false; - } - - /** - * Removes the leading white spaces and asterixes. - * - * @param comment - */ - public static String cleanComment(String s) { - if (s == null) - return ""; - s = s.substring(3, s.length() - 2); - StringBuffer buf = new StringBuffer(); - String regexp = "^([ \\t]*)([\\*]*)(.*)$"; - Pattern p = Pattern.compile(regexp, - Pattern.MULTILINE); - Matcher m = p.matcher(s); - - while (m.find()) { - if (m.group(2).length() == 0) - buf.append(m.group(1) + - m.group(2) + - m.group(3)); - else - buf.append(m.group(3)); - buf.append("\n"); - } - return buf.toString(); - } - - /** - * Parses the comment string separating the description - * text from tags. - */ - protected void parseComment() { - String regexp = "\n[ ]*@|\\A[ ]*@"; - String[] parts = rawText.split(regexp); - if (parts.length == 0) { - text = ""; - tags = new Tag[0]; - } - else { - int startTag; - if (parts[0].startsWith("@")) { - text = ""; - startTag = 0; - } else { - text = parts[0]; - startTag = 1; - } - List tagList = new LinkedList(); - for(int i = startTag; i < parts.length; i++) { - Pair fields = Tag.split(parts[i]); - String name = (String) fields.fst; - String description = (String) fields.snd; - tagList.add(new Tag(holder, "@" + name, description)); - } - tags = (Tag[]) tagList.toArray(new Tag[tagList.size()]); - } - } - - /** - * Returns an array of tags with text and inline. - * - * @param holder - * @param s - * @see See Tags for a Doc comment. - */ - public static Tag[] makeTags(Symbol holder, String s) { - final List tagList = new LinkedList(); - Pattern p = Pattern.compile("\\{@([^\\}]*)\\}"); - Matcher m = p.matcher(s); - - int start = 0; - while (m.find()) { - String txt = s.substring(start, m.start()); - if (!txt.equals("")) - tagList.add(new Tag(holder, "@text", txt)); - Pair fields = Tag.split(m.group(1)); - String name = (String) fields.fst; - String description = (String) fields.snd; - tagList.add(new Tag(holder, "@" + name, description)); - start = m.end(); - } - String txt = s.substring(start, s.length()); - if (!txt.equals("")) - tagList.add(new Tag(holder, "@text", txt)); - return (Tag[]) tagList.toArray(new Tag[tagList.size()]); - } - - /** - * Returns the first sentence of this comment. - */ - public String firstSentence() { - Pattern p = Pattern.compile("\\.(\\s)"); - Matcher m = p.matcher(text); - if (m.find()) { - return text.substring(0, m.start(1));; - } else - return text; - } - - // Implementation methods for the SAX error handler. - - public void warning(SAXParseException e) { - //showHtmlError(e); - } - - public void error(SAXParseException e) { - showHtmlError(e); - } - - public void fatalError(SAXParseException e) { - showHtmlError(e); - } - - void showHtmlError(SAXParseException e) { - String msg = ""; - msg += "documentation comments should be written in XHTML" + "\n"; - msg += e.getMessage() + "\n"; - msg += rawText; - if (unit != null) - unit.warning(holder.pos, msg); - } - -} - -public class HTMLValidator { - - /** The URL of the file containing the DTD. */ - String dtd; - - /** HTML parser. */ - XMLReader xmlReader; - - public HTMLValidator(String dtd) { - this.dtd = dtd; - // parser - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setValidating(true); - factory.setNamespaceAware(true); - SAXParser saxParser = factory.newSAXParser(); - xmlReader = saxParser.getXMLReader(); - } - catch(ParserConfigurationException e) { System.err.println(e.toString()); } - catch(SAXException e) { System.err.println(e.toString()); } - } - - public String makeDoc(String s) { - String doc = ""; - // specify the DTD - doc += "<?xml version=\"1.0\"?>" + "\n"; - doc += "<!DOCTYPE html SYSTEM \"" + dtd + "\">" + "\n"; - // enclose the string into a valid HTML skeletton - doc += "<html><head><title>notitle</title></head><body>" + "\n"; - doc += s + "\n"; - doc += "</body></html>" + "\n"; - return doc; - } - - public void validate(String s, ErrorHandler errorHandler) { - // source to parse - String doc = makeDoc(s); - InputSource source = new InputSource(new StringReader(doc)); - try { - xmlReader.setErrorHandler(errorHandler); - xmlReader.parse(source); - } - catch(SAXException e) { } - catch(Exception e) { System.err.println(e.toString()); } - } -} - diff --git a/sources/scala/tools/scaladoc/DocModule.java b/sources/scala/tools/scaladoc/DocModule.java deleted file mode 100644 index 7a55a4b9bb..0000000000 --- a/sources/scala/tools/scaladoc/DocModule.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import ch.epfl.lamp.util.Position; - -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.LinkedList; -import java.util.List; -import java.util.StringTokenizer; - -import scalac.Global; -import scalac.util.Debug; -import scalac.util.Reporter; - -/** - * This class is used to dynamically load a documentation module. - */ -public class DocModule { - - /** Name of the method to be called (convention). - */ - protected static final String METHOD_NAME = "apply"; - - /** - * Complete the given path with standard class paths. - * - * @param path - */ - public static String completePath(String path) { - String completePath = path; - String path1 = System.getProperty("env.class.path"); - String path2 = System.getProperty("java.class.path"); - if (path1 != null) - completePath += File.pathSeparator + path1; - if (path2 != null) - completePath += File.pathSeparator + path2; - return completePath; - } - - /** - * Get class loader from a given path. - * - * @param path - */ - public static ClassLoader getClassLoader(String path) { - List urlList = new LinkedList(); - StringTokenizer st = new StringTokenizer(path, File.pathSeparator); - try { - while (st.hasMoreTokens()) - urlList.add(new File(st.nextToken()).toURI().toURL()); - } catch(java.net.MalformedURLException e) { - throw Debug.abort(e); - } - URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]); - return new URLClassLoader(urls); - } - - /** - * Loads the class with the specified name. - * - * @param className the name of the class - * @param classLoader the class loader responsible for loading the class - * @return the resulting <code>Class</code> object - */ - public static Class getClass(String className, ClassLoader classLoader) { - Class cls = null; - try { - cls = classLoader.loadClass(className); - } catch (ClassNotFoundException exc) { - throw Debug.abort("Class not found", className); - } - return cls; - } - - /** - * Get the method. - * - * @param methodName the name of the method - * @param cls the class containing the method - * @return the resulting <code>Method</code> object - */ - public static Method getMethod(String methodName, Class cls) { - Method meth = null; - try { - meth = cls.getMethod(methodName, - new Class[] { Class.forName("scalac.Global") }); - } catch (Exception e) { - throw Debug.abort(e); - } - return meth; - } - - /** - * .. - * - * @param global - */ - public static void apply(Global global) { - assert global.args instanceof HTMLGeneratorCommand; - HTMLGeneratorCommand args = (HTMLGeneratorCommand) global.args; - - // complete path - String path = completePath(args.docmodulePath.value); - // class loader - ClassLoader classLoader = getClassLoader(args.docmodulePath.value); - // module class - Class cls = getClass(args.docmodule.value, classLoader); - // method - Method meth = getMethod(METHOD_NAME, cls); - // call method - Thread.currentThread().setContextClassLoader(classLoader); - try { - meth.invoke(null, new Object[] { global }); - } catch (Exception e) { - throw Debug.abort(e); - } - } - -} diff --git a/sources/scala/tools/scaladoc/HTMLGenerator.java b/sources/scala/tools/scaladoc/HTMLGenerator.java deleted file mode 100644 index 80a49184f4..0000000000 --- a/sources/scala/tools/scaladoc/HTMLGenerator.java +++ /dev/null @@ -1,2145 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scala.tools.scaladoc; - -import java.io.Writer; -import java.io.BufferedWriter; -import java.io.StringWriter; -import java.io.Reader; -import java.io.InputStreamReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.InputStream; -import java.io.IOException; -import java.net.URI; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Stack; -import java.util.regex.*; - -import ch.epfl.lamp.util.XMLAttribute; -import ch.epfl.lamp.util.HTMLPrinter; -import ch.epfl.lamp.util.HTMLRepresentation; -import ch.epfl.lamp.util.Pair; -import ch.epfl.lamp.util.XHTMLPrinter; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.CompilationUnit; -import scalac.symtab.Kinds; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Type.*; -import scalac.symtab.SymbolTablePrinter; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Strings; -import SymbolBooleanFunction; -import scalac.util.ScalaProgramArgumentParser; - -/** - * The class <code>HTMLGenerator</code> generates - * the HTML documentation for a given Scala library. - */ -public abstract class HTMLGenerator { - - /* - * Names of predefined page names and page sections. - */ - protected final String FRAME_PAGE = "index.html"; - protected final String ROOT_PAGE = Location.ROOT_NAME + ".html"; - protected final String PACKAGE_INDEX_PAGE = "package-index-page.html"; - protected final String HELP_PAGE = "help-page.html"; - protected final String SEARCH_SECTION = "search-section"; - protected final String INDEX_PAGE = "index-page.html"; - protected final String PACKAGE_PAGE = "package-page.html"; - - /* - * Names of frames. - */ - protected final String ROOT_FRAME = "rootFrame"; - protected final String PACKAGES_FRAME = "packagesFrame"; - protected final String CLASSES_FRAME = "classesFrame"; - protected final String SELF_FRAME = "_self"; - - /** - * HTML DTD - */ - protected final String[] HTML_DTD = new String[] { "xhtml1-transitional.dtd", - "xhtml-lat1.ent", - "xhtml-special.ent", - "xhtml-symbol.ent" }; - - /** - * HTML validator. - */ - protected HTMLValidator xhtml; - - /* - * XML attributes. - */ - protected final XMLAttribute[] ATTRS_DOCTAG = - new XMLAttribute[]{ - new XMLAttribute("style", "margin-top:10px;") - }; - protected final XMLAttribute[] ATTRS_ENTITY = - new XMLAttribute[]{ new XMLAttribute("class", "entity") }; - - protected final XMLAttribute[] ATTRS_LIST = - new XMLAttribute[] { new XMLAttribute("class", "list")}; - - protected final XMLAttribute[] ATTRS_MEMBER = - new XMLAttribute[]{ - new XMLAttribute("cellpadding", "3"), - new XMLAttribute("class", "member") - }; - protected final XMLAttribute[] ATTRS_MEMBER_DETAIL = - new XMLAttribute[]{ - new XMLAttribute("cellpadding", "3"), - new XMLAttribute("class", "member-detail") - }; - - protected final XMLAttribute[] ATTRS_MEMBER_TITLE = - new XMLAttribute[]{ new XMLAttribute("class", "member-title") }; - - protected final XMLAttribute[] ATTRS_MODIFIERS = - new XMLAttribute[]{ - new XMLAttribute("valign", "top"), - new XMLAttribute("class", "modifiers") - }; - protected final XMLAttribute[] ATTRS_NAVIGATION = - new XMLAttribute[]{ new XMLAttribute("class", "navigation") }; - - protected final XMLAttribute[] ATTRS_NAVIGATION_LINKS = - new XMLAttribute[]{ - new XMLAttribute("valign", "top"), - new XMLAttribute("class", "navigation-links") - }; - protected final XMLAttribute[] ATTRS_NAVIGATION_ENABLED = - new XMLAttribute[]{ - new XMLAttribute("class", "navigation-enabled") - }; - protected final XMLAttribute[] ATTRS_NAVIGATION_SELECTED = - new XMLAttribute[]{ - new XMLAttribute("class", "navigation-selected") - }; - protected final XMLAttribute[] ATTRS_NAVIGATION_PRODUCT = - new XMLAttribute[]{ - new XMLAttribute("align", "right"), - new XMLAttribute("valign", "top"), - new XMLAttribute("style", "white-space:nowrap;"), - new XMLAttribute("rowspan", "2") - }; - protected final XMLAttribute[] ATTRS_PAGE_TITLE = new XMLAttribute[]{ - new XMLAttribute("class", "page-title") - }; - protected final XMLAttribute[] ATTRS_SIGNATURE = - new XMLAttribute[]{ new XMLAttribute("class", "signature") }; - - protected final XMLAttribute[] ATTRS_TITLE_SUMMARY = - new XMLAttribute[]{ - new XMLAttribute("colspan", "2"), - new XMLAttribute("class", "title") - }; - protected final XMLAttribute[] ATTRS_VALIDATION = - new XMLAttribute[]{ - new XMLAttribute("style", "margin-top:5px; text-align:center; font-size:9pt;") - }; - - /** HTML meta information. - */ - public static final String PRODUCT = - System.getProperty("scala.product", "scaladoc"); - public static final String VERSION = - System.getProperty("scala.version", "unknown version"); - protected final String GENERATOR = PRODUCT + " (" + VERSION + ")"; - protected final SimpleDateFormat df = - new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy"); - protected final XMLAttribute[] ATTRS_META = - new XMLAttribute[]{ new XMLAttribute("generator", GENERATOR) }; - protected String getGenerator() { - return "Generated by " + GENERATOR + " on " + df.format(new Date()); - } - - /** Global compiler environment. - */ - protected final Global global; - - /** Directory where to put generated HTML pages. - */ - protected File directory; - - /** Comments associated with symbols. - */ - protected Map/*<Symbol, Comment>*/ comments = new HashMap(); - - /** The underlying HTML printer. - */ - public Page page; - - /** The current URI. - */ - protected URI uri; - - /** - * The underlying symbol table printer. - */ - protected MySymbolTablePrinter symtab; - - /** - * The underlying document representation of the generated documentation. - */ - protected HTMLRepresentation representation; - - /** - * The command option settings. - */ - protected String windowtitle; - protected String doctitle; - protected String stylesheet; - protected boolean noindex; - protected boolean validate; - protected boolean launchServer; - protected int port; - - /** - * HTML pages may be generated recursively, - * so we need to save active printers. - */ - protected final Stack stack = new Stack(); - - /** - * Navigation context. - */ - private final int ROOT_NAV_CONTEXT = 0; // on the root page - private final int INDEX_NAV_CONTEXT = 1; // on the index page - private final int HELP_NAV_CONTEXT = 2; // on the help page - private final int CONTAINER_NAV_CONTEXT = 3; // on a container page different from the root. - - /** - * Variables used when loading this documentation generator. - */ - public static final String DEFAULT_DOCTITLE = ""; - public static final String DEFAULT_WINDOWTITLE = "Generated Documentation"; - - /** Root scope. - */ - protected final Symbol root; - - /** Documented Symbols. - */ - protected SymbolBooleanFunction isDocumented; - - /** ML module factory. - */ - public abstract TypeIsomorphism newTypeIso(Global global); - - /** Page promises. - */ - public Map/*<String, Promise>*/ promises; - - /** - * Creates a new instance. - * - * @param global - */ - protected HTMLGenerator(Global global) { - this.global = global; - this.root = global.definitions.ROOT_CLASS; - this.uri = Location.makeURI("."); - this.promises = new HashMap(); - - assert global.args instanceof HTMLGeneratorCommand; - HTMLGeneratorCommand args = (HTMLGeneratorCommand) global.args; - this.representation = new HTMLRepresentation( - args.doctype.value, - args.docencoding.value, - HTMLRepresentation.DEFAULT_DOCLANGUAGE); - this.windowtitle = args.windowtitle.value; - this.doctitle = args.doctitle.value; - this.stylesheet = args.stylesheet.value; - this.noindex = args.noindex.value; - this.validate = args.validate.value; - this.launchServer = args.server.value; - try { - this.port = Integer.parseInt(args.port.value); - } - catch (NumberFormatException e) { - this.port = 1280; - } - Symbol[] packages = getPackages(args.packages); - final DocSyms docSyms = new DocSyms(global, packages); - this.isDocumented = new SymbolBooleanFunction() { - public boolean apply(Symbol sym) { - return docSyms.contains(sym) && ScalaSearch.isRelevant(sym) - && !getComment(sym).containsTag("@ignore"); - } - }; - } - - /** - * Adapt the URI to the use context. If the usage context is the - * server, then the URI for the page <code>index.html</code> has - * the following shape: <pre>pageServlet?page=index.html</pre>. If - * the usage context is a static page, then the URI is given - * relative to the given page: <pre>../../index.html</pre> - */ - public URI adaptURI(URI uri, URI pageUri) { - if (launchServer) - return Location.mkURI(PAGE_SERVLET_NAME + "?" +"page=" + uri.getPath() + "#" + uri.getFragment()); - else - return Location.asSeenFrom(uri, pageUri); - } - - /** - * Compute the URI for a symbol page. The URI is expressed - * relatively to the given page. - */ - protected URI definitionURI(Symbol sym, Page page) { - URI defUri = Location.getURI(sym); - return adaptURI(defUri, page.uri); - } - - /** - * Compute the URI for a symbol page. The URI is expressed - * relatively to the current page. - */ - protected URI definitionURI(Symbol sym) { - return definitionURI(sym, page); - } - - /** Get the list pf packages to be documented. - */ - protected Symbol[] getPackages(ScalaProgramArgumentParser option) { - if (option.main != null) { - Symbol[] packages = new Symbol[option.args.length + 1]; - packages[0] = global.definitions.getModule(option.main); - for (int i = 0; i < option.args.length; i++) - packages[i+1] = global.definitions.getModule(option.args[i]); - return packages; - } - else - return new Symbol[] { root }; - } - - /** Get a file writer to a page. - */ - protected static Writer fileWriter(File rootDirectory, String uri) { - try { - File f = new File(rootDirectory, uri); - f.getParentFile().mkdirs(); - return new BufferedWriter(new FileWriter(f)); - } - catch (IOException e) { - throw Debug.abort(e); - } - } - - /** - * Open a new documentation page and make it the current page. - * @param uri URL of the page - * @param title Title of the page - */ - protected void createPrinters(Writer writer, URI uri, String title, String destinationFrame) { - stack.push(page); - stack.push(symtab); - - // Create a new page. - page = new Page(writer, uri, destinationFrame, - title, representation, - adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_STYLESHEET), uri).toString(), - adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_JAVASCRIPT), uri).toString()); - // Create a printer to print symbols and types. - symtab = SymbolTablePrinterFactory.makeHTML(this, page, isDocumented); - page.open(); - } - - /** - * Close the current page. - */ - protected void closePrinters() { - //page.close(); - symtab = (MySymbolTablePrinter) stack.pop(); - page = (Page) stack.pop(); - } - - /** - * Check if the outpath is valid. - */ - private boolean checkOutpath() { - String text = "Output path \"" + global.outpath + "\" "; - boolean ok = false; - try { - directory = new File(global.outpath); - if (! directory.exists()) - global.reporter.error(null, text + "does not exist"); - else if (! directory.isDirectory()) - global.reporter.error(null, text + "is not a directory"); - else if (! directory.canWrite()) - global.reporter.error(null, text + "cannot be modified"); - else - ok = true; - } catch (NullPointerException e) { - global.reporter.error(null, e.getMessage()); - } - return ok; - } - - /** - * Main function. - */ - public void apply() { - - if (!launchServer) { - if (! checkOutpath()) - return; - } - - this.xhtml = new HTMLValidator(getResourceURL(HTML_DTD[0])); - - // Page with list of packages - Promise packageIndexPage = new PackageIndexPromise(); - promises.put(packageIndexPage.name(), packageIndexPage); - - // Class and object pages - ScalaSearch.foreach(root, - new ScalaSearch.SymFun() { - public void apply(Symbol sym) { - if (ScalaSearch.isContainer(sym) && - isDocumented.apply(sym)) { - Promise containerPage = new ContainerPromise(sym); - promises.put(containerPage.name(), containerPage); - if (sym.isPackage() || sym.isPackageClass()) { - Promise containerIndexPage = new ContainerIndexPromise(sym); - promises.put(containerIndexPage.name(), containerIndexPage); - } - } - } - } - ); - - if (!noindex) { - // Page with index of Scala documented entities - Promise indexPage = new IndexPromise(); - promises.put(indexPage.name(), indexPage); - } - - // Help page - Promise helpPage = new HelpPromise(); - promises.put(helpPage.name(), helpPage); - - // Frame description page - Promise framePage = new FramePromise(); - promises.put(framePage.name(), framePage); - - // Style sheet - Promise styleSheetPage = new ResourcePromise(HTMLPrinter.DEFAULT_STYLESHEET, null); - promises.put(styleSheetPage.name(), styleSheetPage); - - // Script - Promise javaScriptPage = new ResourcePromise(HTMLPrinter.DEFAULT_JAVASCRIPT, null); - promises.put(javaScriptPage.name(), javaScriptPage); - - if (launchServer) { - // Launch HTTP server - launchServer(); - } - else { - // Generate statically all the pages - Iterator i = promises.values().iterator(); - while(i.hasNext()) { - Promise pagePromise = (Promise) i.next(); - Writer writer = fileWriter(directory, pagePromise.name()); - pagePromise.writeOn(writer); - try { - writer.close(); - } catch(IOException e) { - e.printStackTrace(); - } - } - } - } - - /** - * Launch the HTTP server. - */ - protected void launchServer() { - Servlet pageServlet = new PageServlet(); - Servlet searchServlet = new SearchServlet(); - Servlet[] servlets = new Servlet[]{ pageServlet, searchServlet }; - try { - HTTPServer webServer = new HTTPServer(directory, port, servlets); - webServer.start(); - } - catch (IOException e) { - System.out.println("Server could not start because of an " - + e.getClass()); - System.out.println(e); - } - // to prevent going to the next phase (implies checking - // errors when parsing a type after RefCheck) - try { - synchronized(this) { wait(); } - } - catch(InterruptedException e) { - System.err.println("Error while waiting."); - System.exit(0); - } - } - - /** - * Returns the comment associated with a given symbol. - * - * @param sym - */ - protected Comment getComment(Symbol sym) { - Comment comment = (Comment) comments.get(sym); - if (comment == null) { - Pair p = (Pair) global.mapSymbolComment.get(sym); - if (p != null) { - String s = (String) p.fst; - CompilationUnit unit = (CompilationUnit) p.snd; - comment = new Comment(s, sym, unit, xhtml); - } - else { // comment inheritance - Symbol overriden = ScalaSearch.overridenBySymbol(sym); - if (overriden == Symbol.NONE) - comment = new Comment(null, sym, null, xhtml); - else - comment = getComment(overriden); - //s = "/** (Inherited comment) " + getComment(overriden).rawText + "*/"; - } - comments.put(sym, comment); - } - return comment; - } - - /** - * Filters modifiers so that modifiers added by the analyzer are - * not printed. - */ - protected String filterModifiers(Symbol sym) { - int flags = sym.flags; - if (sym.isPackage() || sym.isPackageClass()) { - if ((flags & Modifiers.FINAL) != 0) - flags = flags - Modifiers.FINAL; - } - if (sym.isModule()) { - if ((flags & Modifiers.FINAL) != 0) - flags = flags - Modifiers.FINAL; - } - if (sym.isTrait()) { - if ((flags & Modifiers.ABSTRACT) != 0) - flags = flags - Modifiers.ABSTRACT; - if ((flags & Modifiers.INTERFACE) != 0) - flags = flags - Modifiers.INTERFACE; - } - return Modifiers.Helper.toString(flags); - } - - /** - * Generates a HTML page for a class or object definition. - */ - class ContainerPromise extends Promise { - - protected Symbol sym; - - public ContainerPromise(Symbol sym) { - this.sym = sym; - } - - public String name() { return Location.getURI(sym).toString(); } - - protected void computeIn(Writer writer) { - String title = Location.getName(sym); - createPrinters(writer, Location.getURI(sym), title, SELF_FRAME); - page.printHeader(ATTRS_META, getGenerator()); - page.printOpenBody(); - - if (sym.isRoot()) - addNavigationBar(ROOT_NAV_CONTEXT); - else - addNavigationBar(CONTAINER_NAV_CONTEXT); - page.printlnHLine(); - - addTitle(sym); - addDocumentationComment(sym); - page.printlnHLine(); - - String[] titles = new String[]{ "Field", "Method", "Object", - "Trait", "Class", "Package" }; // "Constructor" - String[] inherited = new String[]{ "Fields", "Methods", "Objects", - "Traits", "Classes", "Packages" }; - Symbol[][] members = - ScalaSearch.splitMembers(ScalaSearch.members(sym, isDocumented)); - for (int i = 0; i < members.length; i++) { - addMemberSummary(members[i], titles[i] + " Summary"); - if (i == 1) addInheritedMembers(sym, inherited[i]); - } - for (int i = 0; i < titles.length; i++) - addMemberDetail(members[i], titles[i] + " Detail"); - - page.printlnHLine(); - if (sym.isRoot()) - addNavigationBar(ROOT_NAV_CONTEXT); - else - addNavigationBar(CONTAINER_NAV_CONTEXT); - if (validate) - addValidationBar(); - - page.printFootpage(); - closePrinters(); - } - } - - /** - * Writes the product name and version to the current page. - * - * @param attrs - */ - protected void addDocumentationTitle(XMLAttribute[] attrs, Page page) { - page.printlnOTag("div", attrs).indent(); - page.println(doctitle).undent(); - page.printlnCTag("div"); - } - - protected void addDocumentationTitle(XMLAttribute[] attrs) { - addDocumentationTitle(attrs, page); - } - - protected void addSearchSection(Page page) { - page.printlnOTag("form", new XMLAttribute[] { - new XMLAttribute("action", "/" + SEARCH_SERVLET_NAME), - new XMLAttribute("method", "get") }).indent(); - - page.printlnOTag("table", new XMLAttribute[] { - new XMLAttribute("border", "0") }).indent(); - - // Text field - page.printlnOTag("tr").indent(); - page.printlnOTag("td").indent(); - page.printlnSTag("input", new XMLAttribute[] { - new XMLAttribute("name", "searchString"), - new XMLAttribute("id", "word"), - new XMLAttribute("size", "100%"), - // new XMLAttribute("maxlength", "30"), - new XMLAttribute("type", "text"), - }); - // Button - page.printlnSTag("input", new XMLAttribute[] { - new XMLAttribute("type", "submit"), - new XMLAttribute("value", "Search"), - }).undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr"); - - page.printlnOTag("tr").indent(); - page.printlnOTag("td", new XMLAttribute[] { - new XMLAttribute("align", "center") }).indent(); - // by name - page.printlnSTag("input", new XMLAttribute[] { - new XMLAttribute("type", "radio"), - new XMLAttribute("checked", "true"), - new XMLAttribute("name", "searchKind"), - new XMLAttribute("id", "byName"), - new XMLAttribute("value", "byName") - }); - page.println("By name"); - // by comment - page.printlnSTag("input", new XMLAttribute[] { - new XMLAttribute("type", "radio"), - new XMLAttribute("name", "searchKind"), - new XMLAttribute("id", "byComment"), - new XMLAttribute("value", "byComment") - }); - page.println("By comment"); - // by type - page.printlnSTag("input", new XMLAttribute[] { - new XMLAttribute("type", "radio"), - new XMLAttribute("name", "searchKind"), - new XMLAttribute("id", "byType"), - new XMLAttribute("value", "byType") - }); - page.println("By type").undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table").undent(); - page.printlnCTag("form"); - } - - protected void addSearchSection() { - addSearchSection(page); - } - - /** - * Writes the navigation bar to the current page. - * - * @param sym - */ - protected void addNavigationBar(int navigationContext, Page page) { - try { - String overviewLink = adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString(); - String indexLink = adaptURI(Location.mkURI(INDEX_PAGE), page.uri).toString(); - String helpLink = adaptURI(Location.mkURI(HELP_PAGE), page.uri).toString(); - - page.printlnOTag("table", ATTRS_NAVIGATION).indent(); - page.printlnOTag("tr").indent(); - page.printlnOTag("td", ATTRS_NAVIGATION_LINKS).indent(); - page.printlnOTag("table").indent(); - page.printlnOTag("tr").indent(); - - // overview link - if (navigationContext == ROOT_NAV_CONTEXT) - page.printlnTag("td", ATTRS_NAVIGATION_SELECTED, "Overview"); - else { - page.printOTag("td", ATTRS_NAVIGATION_ENABLED); - page.printAhref(overviewLink, SELF_FRAME, "Overview"); - page.printlnCTag("td"); - } - // index link - if (navigationContext == INDEX_NAV_CONTEXT) - page.printlnTag("td", ATTRS_NAVIGATION_SELECTED, "Index"); - else { - page.printOTag("td", ATTRS_NAVIGATION_ENABLED); - page.printAhref(indexLink, SELF_FRAME, "Index"); - page.printlnCTag("td"); - } - // help link - if (navigationContext == HELP_NAV_CONTEXT) - page.printlnTag("td", ATTRS_NAVIGATION_SELECTED, "Help"); - else { - page.printOTag("td", ATTRS_NAVIGATION_ENABLED); - page.printAhref(helpLink, SELF_FRAME, "Help"); - page.printlnCTag("td"); - } - - page.undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table").undent(); - page.printlnCTag("td"); - - // product & version - page.printlnOTag("td", ATTRS_NAVIGATION_PRODUCT).indent(); - addDocumentationTitle(new XMLAttribute[]{ - new XMLAttribute("class", "doctitle")}, page); - page.undent(); - page.printlnCTag("td").undent(); - - page.printlnCTag("tr"); - - page.printlnOTag("tr").indent(); - page.printlnTag("td", " ").undent(); - page.printlnCTag("tr").undent(); - if (launchServer) { - page.printlnOTag("tr").indent(); - addSearchSection(page); - page.undent(); - page.printlnCTag("tr"); - } - page.printlnCTag("table"); - } catch(Exception e) { throw Debug.abort(e); } - } - - protected void addNavigationBar(int navigationContext) { - addNavigationBar(navigationContext, page); - } - - /** - * Writes the validation bar to the current page. - */ - protected void addValidationBar() { - page.printlnOTag("div", ATTRS_VALIDATION); - page.indent(); - page.printlnAhref( - "http://validator.w3.org/check/referer", SELF_FRAME, - "validate html"); - page.undent(); - page.printlnCTag("div"); - } - - /** - * Writes the signature of the class or object to the current page. - * - * @param sym - */ - protected void addTitle(Symbol sym) { - if (sym.isRoot()) { - page.printlnOTag("div", ATTRS_PAGE_TITLE).indent(); - page.println(doctitle.replaceAll("<.*>", " ")); - page.printlnSTag("br"); - page.println("API Specification").undent(); - page.printlnCTag("div"); - page.println("This document is the API specification for " - + doctitle.replaceAll("<.*>", " ") + "."); - page.printlnSTag("p"); - } else { - // in - page.print("in "); - printPath(sym.owner(), SELF_FRAME); - - // kind and name - page.printlnOTag("div", ATTRS_ENTITY).indent(); - page.print(symtab.getSymbolKeywordForDoc(sym) + " "); - page.printlnTag("span", ATTRS_ENTITY, sym.nameString()).undent(); - page.printlnCTag("div"); - page.printlnHLine(); - - // complete signature - // !!! page.println(printer().printTemplateHtmlSignature(sym, false).toString()); - printTemplateHtmlSignature(sym, false); - - // implementing classes or modules - // Maps classes to their direct implementing classes or modules - Map subs = ScalaSearch.subTemplates(root, isDocumented); - - if (sym.isClass()) { - List subList = (List) subs.get(sym); - if (subList != null && subList.size() != 0) { - page.printlnOTag("dl").indent(); - page.printlnOTag("dt"); - page.printlnBold("Implementing classes or objects:"); - page.printlnCTag("dt"); - Iterator it = subList.iterator(); - while (it.hasNext()) { - Pair p = (Pair) it.next(); - Symbol sub = (Symbol) p.fst; - Type tipe = (Type) p.snd; - page.printlnOTag("dd"); - - symtab.defString(sub, true /*addLink*/); - if (sub.owner() != sym.owner()) { - page.print(" in "); - printPath(sub.owner(), SELF_FRAME); - } - page.printlnCTag("dd"); - } - page.undent(); - page.printlnCTag("dl"); - } - } - } - } - - /** - * Writes a documentation comment to the current page. - * - * @param sym - */ - protected void addDocumentationComment(Symbol sym) { - Comment comment = getComment(sym); - if (!comment.isEmpty()) { - page.printlnHLine(); - addComments(comment); - } - } - - /** - * Writes a sorted list of all members with a short summary - * for each one. - * - * @param members - * @param title - */ - protected void addMemberSummary(Symbol[] members, String title) { - if (members.length > 0) { - Symbol[] sortedMembers = new Symbol[members.length]; - for (int i = 0; i < members.length; i++) { - assert members[i] != null : "HA ENFIN !"; - sortedMembers[i] = members[i]; - } - Arrays.sort(sortedMembers, ScalaSearch.symAlphaOrder); - - // open table - page.printlnOTag("table", ATTRS_MEMBER).indent(); - - // title - page.printlnOTag("tr").indent(); - page.printlnOTag("td", ATTRS_TITLE_SUMMARY).indent(); - page.println(title).undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr"); - - // members - for (int i = 0; i < members.length; i++) - addMemberSummary(sortedMembers[i]); - - // close table - page.undent(); - page.printlnCTag("table"); - page.printlnSTag("br"); - } - } - - /** - * Writes the summary of a member symbol to the current page. - * - * @param sym - */ - protected void addMemberSummary(Symbol sym) { - page.printlnOTag("tr").indent(); - - // modifiers - String mods = filterModifiers(sym); - page.printlnOTag("td", ATTRS_MODIFIERS).indent(); - if (mods.length() > 0) - page.printlnTag("code", mods); - else - page.printlnNbsp(1); - page.undent(); - page.printlnCTag("td"); - - // signature - page.printlnOTag("td", ATTRS_SIGNATURE).indent(); - page.printOTag("code"); - symtab.defString(sym, true /*addLink*/); - page.printlnCTag("code"); - - // short description - String firstSentence = firstSentence(getComment(sym)); - if (! firstSentence.equals("")) { - page.printlnSTag("br"); - page.printNbsp(4); - page.println(firstSentence); - } - page.undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr"); - } - - /** - * Adds a list of all members with all details. - * - * @param members - */ - protected void addMemberDetail(Symbol[] members, String title) { - boolean first = true; - for (int i = 0; i < members.length; i++) { - Symbol sym = members[i]; - if (!ScalaSearch.isContainer(sym)) { - if (first) { - page.printlnOTag("table", ATTRS_MEMBER_DETAIL).indent(); - page.printlnOTag("tr").indent(); - page.printlnTag("td", ATTRS_MEMBER_TITLE, title).undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table"); - first = false; - } else - page.printlnHLine(); - addMemberDetail(sym); - } - } - } - - /** - * Writes the detail of a member symbol to the page, but create - * instead a separate page for a class or an object. - * - * @param sym - */ - protected void addMemberDetail(Symbol sym) { - // title with label - // page.printlnAname(Page.asSeenFrom(Location.getURI(sym), uri).getFragment(), ""); - page.printlnAname(Location.getURI(sym).getFragment(), ""); - page.printTag("h3", sym.nameString()); - - // signature - page.printlnOTag("pre"); - String mods = filterModifiers(sym); - // String mods = Modifiers.Helper.toString(sym.flags); - if (mods.length() > 0) page.print(mods + " "); - symtab.printSignature(sym, false /*addLink*/); - page.printlnCTag("pre"); - - // comment - addComments(getComment(sym)); - } - - /** - * Add for each "strict" base type of this class or object symbol - * the members that are inherited by this class or object. - * - * @param sym - */ - protected void addInheritedMembers(Symbol sym, String inheritedMembers) { - Symbol[] syms = ScalaSearch.collectMembers(sym); - Pair grouped = ScalaSearch.groupSymbols(syms); - Symbol[] owners = (Symbol[]) grouped.fst; - Map/*<Symbol, Symbol[]>*/ group = (Map) grouped.snd; - for (int i = 0; i < owners.length; i++) { - if (owners[i] != (sym.isModule() ? sym.moduleClass() : sym)) { - page.printlnOTag("table", ATTRS_MEMBER).indent(); - - // owner - page.printlnOTag("tr").indent(); - page.printlnOTag("td", new XMLAttribute[]{ - new XMLAttribute("class", "inherited-owner")}).indent(); - page.print(inheritedMembers + " inherited from "); - printPath(owners[i], SELF_FRAME); - page.undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr"); - - // members - page.printlnOTag("tr").indent(); - page.printlnOTag("td", new XMLAttribute[]{ - new XMLAttribute("class", "inherited-members")}).indent(); - Symbol[] members = (Symbol[]) group.get(owners[i]); - for (int j = 0; j < members.length; j++) { - if (j > 0) page.print(", "); - symtab.printSymbol(members[j], true); - } - page.undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table"); - page.printlnSTag("br"); - } - } - } - - /** - * Prints the signature of a class symbol. - * - * @param symbol - * @param addLink - */ - public void printTemplateHtmlSignature(Symbol symbol, boolean addLink) { - // modifiers - String mods = filterModifiers(symbol); - // String mods = Modifiers.Helper.toString(symbol.flags); - page.printlnOTag("dl"); - page.printlnOTag("dt"); - symtab.print(mods).space(); - - // kind - String keyword = symtab.getSymbolKeywordForDoc(symbol); - if (keyword != null) symtab.print(keyword).space(); - String inner = symtab.getSymbolInnerString(symbol); - - // name - symtab.printDefinedSymbolName(symbol, addLink); - if (symbol.isClass()) { - // type parameters - Symbol[] tparams = symbol.typeParams(); - if (tparams.length != 0 || global.debug) { - symtab.print('['); - for (int i = 0; i < tparams.length; i++) { - if (i > 0) symtab.print(","); - symtab.printSignature(tparams[i], false); - } - symtab.print(']'); - } - // value parameters - symtab.printValueParams(symbol.valueParams()); - } - - // parents - Type[] parts = (symbol.isModule() ? symbol.moduleClass() : symbol).parents(); - page.printlnCTag("dt"); - for (int i = 0; i < parts.length; i++) { - page.printOTag("dd"); - symtab.print((i == 0) ? "extends " : "with "); - symtab.printType(parts[i]); - page.printlnCTag("dd"); - } - page.printCTag("dl"); - } - - /** - * Creates the page describing the different frames. - * - * @param title The page title - */ - class FramePromise extends Promise { - - public String name() { return FRAME_PAGE; } - - protected void computeIn(Writer writer) { - createPrinters(writer, Location.makeURI(FRAME_PAGE), windowtitle, ""); - page.printHeader(ATTRS_META, getGenerator()); - - page.printlnOTag("frameset", new XMLAttribute[] { - new XMLAttribute("cols", "25%, 75%")}).indent(); - page.printlnOTag("frameset", new XMLAttribute[] { - new XMLAttribute("rows", "50%, 50%")}).indent(); - - page.printlnOTag("frame", new XMLAttribute[] { - new XMLAttribute("src", adaptURI(Location.mkURI(PACKAGE_INDEX_PAGE), page.uri).toString()), - new XMLAttribute("name", PACKAGES_FRAME)}); - page.printlnOTag("frame", new XMLAttribute[] { - new XMLAttribute("src", adaptURI(Location.mkURI(PACKAGE_PAGE), page.uri).toString()), - new XMLAttribute("name", CLASSES_FRAME)}).undent(); - page.printlnCTag("frameset"); - page.printlnOTag("frame", new XMLAttribute[] { - new XMLAttribute("src", adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString()), - new XMLAttribute("name", ROOT_FRAME)}); - - page.printlnOTag("noframes").indent(); - page.printlnSTag("p"); - page.print("Here is the "); - page.printAhref(adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString(), - "non-frame based version"); - page.println(" of the documentation.").undent(); - page.printlnCTag("noframes").undent(); - - page.printlnCTag("frameset"); - page.printlnCTag("html"); - - closePrinters(); - } - } - - /** - * Get the URL (as a string) of a resource located in the - * directory "resources" relative to the classfile of this class. - */ - protected String getResourceURL(String name) { - String rsc = HTMLGenerator.class - .getResource("resources/" + name) - .toString(); - return rsc; - } - - /** - * Generates a resource file. - * - * @param name The name of the resource file - */ - class ResourcePromise extends Promise { - - protected String name; - - protected String dir; - - ResourcePromise(String name, String dir) { - this.name = name; - this.dir = dir; - } - - public String name() { return name; } - - protected void computeIn(Writer writer) { - String rsrcName = "resources/" + name; - Reader reader = new InputStreamReader(HTMLGenerator.class.getResourceAsStream(rsrcName)); - if (reader == null) - throw Debug.abort("Resource file \"" + rsrcName + "\" not found"); - try { - char[] buf = new char[1024]; - int len; - while (true) { - len = reader.read(buf, 0, buf.length); - if (len <= 0) break; - writer.write(buf, 0, len); - } - - reader.close(); - // writer.close(); - } catch (IOException exception) { - throw Debug.abort(exception); // !!! reporting an error would be wiser - } - } - } - - private String removeHtmlSuffix(String url) { - return url.substring(0, url.length() - 5); - } - - /** Returns the summary page attached to a package symbol. */ - private String packageSummaryPage(Symbol sym) { - if (sym.isRoot()) - return PACKAGE_PAGE; - else { - String packagePage = Location.getURI(sym).toString(); - // !!! separator character in URI paths is '/' - return removeHtmlSuffix(packagePage) + "/" + PACKAGE_PAGE; - } - } - - /** - * Writes a table containing a list of packages to the current page. - * - * @param syms The package list - * @param title The title of the package list - */ - private void printPackagesTable(Symbol[] syms, String title) { - if (syms.length > 0) { - page.printlnBold(title); - page.printlnOTag("table", ATTRS_LIST).indent(); - page.printlnOTag("tr").indent(); - page.printlnOTag("td", new XMLAttribute[] { - new XMLAttribute("style", "white-space:nowrap;")}).indent(); - for (int i = 1; i < syms.length; i++) { - Symbol sym = syms[i]; - page.printAhref( - adaptURI(Location.mkURI(packageSummaryPage(sym)), page.uri).toString(), - CLASSES_FRAME, - removeHtmlSuffix(Location.getURI(sym).toString())); - page.printlnSTag("br"); - } - page.undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table"); - page.printlnSTag("p"); - } - } - - /** - * Writes a table containing a list of symbols to the current page. - * - * @param syms - * @param title - */ - private void addSymbolTable(Symbol[] syms, String title, boolean useFullName) { - if (syms.length > 0) { - page.printlnBold(title); - page.printlnOTag("table", ATTRS_LIST).indent(); - page.printlnOTag("tr").indent(); - page.printlnOTag("td", new XMLAttribute[] { - new XMLAttribute("style", "white-space:nowrap;")}).indent(); - for (int i = 0; i < syms.length; i++) { - Symbol sym = syms[i]; - if (! sym.isRoot()) { - String name = sym.nameString(); - if (sym.isPackage() || sym.isPackageClass()) - page.printAhref(definitionURI(sym).toString(), CLASSES_FRAME, name); - else { - Symbol user = (useFullName) ? global.definitions.ROOT_CLASS : Symbol.NONE; - page.printAhref(definitionURI(sym).toString(), ROOT_FRAME, name); - } - page.printlnSTag("br"); - } - } - page.undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table"); - page.printlnSTag("p"); - } - } - - /** - * Creates a page with the list of packages. - * - * @param title - */ - class PackageIndexPromise extends Promise { - - public String name() { return PACKAGE_INDEX_PAGE; } - - protected void computeIn(Writer writer) { - createPrinters(writer, Location.makeURI(PACKAGE_INDEX_PAGE), "List of packages", CLASSES_FRAME); - page.printHeader(ATTRS_META, getGenerator()); - page.printOpenBody(); - - Symbol[] packages = ScalaSearch.getSortedPackageList(root, isDocumented); - - addDocumentationTitle(new XMLAttribute[]{ - new XMLAttribute("class", "doctitle-larger")}); - page.printAhref(adaptURI(Location.mkURI(PACKAGE_PAGE), page.uri).toString(), - CLASSES_FRAME, "All objects, traits and classes"); - page.printlnSTag("p"); - printPackagesTable(packages, "Packages"); - if (validate) - addValidationBar(); - - page.printFootpage(); - closePrinters(); - } - } - - /** - * Creates a page with a list of classes or objects. - * - * @param sym - */ - class ContainerIndexPromise extends Promise { - - protected Symbol sym; - - ContainerIndexPromise(Symbol sym) { - this.sym = sym; - } - - public String name() { return packageSummaryPage(sym); } - - protected void computeIn(Writer writer) { - createPrinters(writer, Location.makeURI(packageSummaryPage(sym)), Location.getName(sym), ROOT_FRAME); - page.printHeader(ATTRS_META, getGenerator()); - page.printOpenBody(); - - page.printlnOTag("table", ATTRS_NAVIGATION).indent(); - page.printlnOTag("tr").indent(); - page.printlnOTag("td", ATTRS_NAVIGATION_LINKS).indent(); - printPath(sym, ROOT_FRAME); - page.printlnCTag("td"); - page.printlnCTag("tr"); - page.printlnCTag("table"); - page.printlnSTag("p"); - - String[] titles = new String[]{ "Objects", "Traits", "Classes" }; - if (sym.isRoot()) { - Symbol[][] members = ScalaSearch.getSubContainerMembers(root, isDocumented); - for (int i = 0; i < titles.length; i++) - addSymbolTable(members[i], "All " + titles[i], true); - } else { - Symbol[][] members = ScalaSearch.splitMembers(ScalaSearch.members(sym, isDocumented)); - for (int i = 0; i < titles.length; i++) { - Arrays.sort(members[i + 2], ScalaSearch.symAlphaOrder); - addSymbolTable(members[i + 2], titles[i], false); - } - } - - if (validate) - addValidationBar(); - - page.printFootpage(); - closePrinters(); - } - } - - /** - * Creates the index page. - * - * @param title The page title - */ - class IndexPromise extends Promise { - - public String name() { return INDEX_PAGE; } - - protected void computeIn(Writer writer) { - String title = "Scala Library Index"; - createPrinters(writer, Location.makeURI(INDEX_PAGE), title, SELF_FRAME); - page.printHeader(ATTRS_META, getGenerator()); - page.printOpenBody(); - - addNavigationBar(INDEX_NAV_CONTEXT); - page.printlnHLine(); - - page.printlnOTag("table", ATTRS_MEMBER).indent(); - page.printlnOTag("tr").indent(); - page.printlnOTag("td", ATTRS_MEMBER_TITLE).indent(); - page.println("Index").undent(); - page.printlnCTag("td").undent(); - page.printlnCTag("tr").undent(); - page.printlnCTag("table"); - page.printlnSTag("br"); - - Pair index = ScalaSearch.index(root, isDocumented); - Character[] chars = (Character[]) index.fst; - Map map = (Map) index.snd; - for (int i = 0; i < chars.length; i++) - page.printlnAhref("#" + i, SELF_FRAME, HTMLPrinter.encode(chars[i])); - page.printlnHLine(); - for (int i = 0; i < chars.length; i++) { - Character car = chars[i]; - page.printlnAname(String.valueOf(i), ""); - page.printlnOTag("h2"); - page.printBold(HTMLPrinter.encode(car)); - page.printlnCTag("h2"); - page.printlnOTag("dl").indent(); - Symbol[] syms = (Symbol[]) map.get(car); - for (int j = 0; j < syms.length; j++) { - page.printOTag("dt"); - addIndexEntry(syms[j]); - page.printlnCTag("dt"); - page.printlnTag("dd", firstSentence(getComment(syms[j]))); - } - page.undent().printlnCTag("dl"); - } - - page.printlnHLine(); - addNavigationBar(INDEX_NAV_CONTEXT); - if (validate) - addValidationBar(); - - page.printFootpage(); - closePrinters(); - } - } - - /** - * Creates the help page. - * - * @param title The page title - */ - class HelpPromise extends Promise { - - public String name() { return HELP_PAGE; } - - protected void computeIn(Writer writer) { - String title = "API Help"; - createPrinters(writer, Location.makeURI(HELP_PAGE), title, ROOT_PAGE); - page.printHeader(ATTRS_META, getGenerator()); - page.printOpenBody(); - - addNavigationBar(HELP_NAV_CONTEXT); - page.printlnHLine(); - - XMLAttribute[] h3 = new XMLAttribute[]{ - new XMLAttribute("style", "margin:15px 0px 0px 0px; " - + "font-size:large; font-weight: bold;") - }; - XMLAttribute[] em = new XMLAttribute[]{ - new XMLAttribute("style", "margin:15px 0px 15px 0px; " - + "font-size:small; font-style: italic;") - }; - page.printlnTag("div", ATTRS_PAGE_TITLE, "How This API Document Is Organized"); - page.println("This API (Application Programming Interface) document " - + "has pages corresponding to the items in the navigation bar, " - + "described as follows."); - - page.printlnTag("div", h3, "Overview"); - page.printlnOTag("blockquote").indent(); - page.print("The "); - page.printAhref(adaptURI(Location.mkURI(ROOT_PAGE), page.uri).toString(), SELF_FRAME, "Overview"); - page.println(" page is the front page of this API document and " - + "provides a list of all top-level packages, classes, traits " - + "and objects with a summary for each. " - + "This page can also contain an overall description of the " - + "set of packages.").undent(); - page.printlnCTag("blockquote"); - - page.printlnTag("div", h3, "Package"); - page.printlnOTag("blockquote").indent(); - page.println("Each package has a page that contains a list of " - + "its objects, traits and classes, with a summary for each. " - + "This page can contain three categories:"); - page.printlnOTag("ul").indent(); - page.printlnTag("li", "Objects"); - page.printlnTag("li", "Traits"); - page.printlnTag("li", "Classes").undent(); - page.printlnCTag("ul").undent(); - page.printlnCTag("blockquote"); - - page.printlnTag("div", h3, "Object/Trait/Class"); - page.printlnOTag("blockquote").indent(); - page.println("Each object, trait, class, nested object, nested " - + "trait and nested class has its own separate page. Each " - + "of these pages has three sections consisting of a object" - + "/trait/class description, summary tables, and detailed " - + "member descriptions:"); - page.printlnOTag("ul").indent(); - page.printlnTag("li", "Class inheritance diagram"); - page.printlnTag("li", "Direct Subclasses"); - page.printlnTag("li", "All Known Subinterfaces"); - page.printlnTag("li", "All Known Implementing Classes"); - page.printlnTag("li", "Class/interface declaration"); - page.printlnTag("li", "Class/interface description<p/>"); - page.printlnTag("li", "Nested Class Summary"); - page.printlnTag("li", "Field Summary"); - page.printlnTag("li", "Constructor Summary"); - page.printlnTag("li", "Method Summary<p/>"); - page.printlnTag("li", "Field Detail"); - page.printlnTag("li", "Constructor Detail"); - page.printlnTag("li", "Method Detail").undent(); - page.printlnCTag("ul").undent(); - page.println("Each summary entry contains the first sentence from " - + "the detailed description for that item. The summary entries " - + "are alphabetical, while the detailed descriptions are in " - + "the order they appear in the source code. This preserves " - + "the logical groupings established by the programmer."); - page.printlnCTag("blockquote"); - - - page.printlnTag("div", h3, "Index"); - page.printlnOTag("blockquote").indent(); - page.print("The "); - page.printAhref(adaptURI(Location.mkURI(INDEX_PAGE), page.uri).toString(), SELF_FRAME, "Index"); - page.print(" contains an alphabetic list of all classes, interfaces, " - + "constructors, methods, and fields."); - page.printlnCTag("blockquote"); - - if (launchServer) { - page.printlnTag("div", h3, "Searching a definition"); - page.printlnOTag("blockquote").indent(); - page.printlnSTag("a", - new XMLAttribute[] { - new XMLAttribute("name", SEARCH_SECTION) }); - page.printlnOTag("p"); - page.println("At the top and and at the bottom of each page, there is a form that " - + "allows to search the definition of a <em>symbol</em> (field, method, " - + "package, object, type, trait or class)."); - page.printlnCTag("p"); - - page.printlnOTag("p"); - page.println("There are three ways of specifying the symbols of interest:"); - page.printlnOTag("dl"); - page.printOTag("dt"); - page.printlnTag("b", "By name"); - page.printOTag("dd"); - page.println("The search string must be a "); - page.printlnTag("a", - new XMLAttribute[] { - new XMLAttribute("href", - "http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html") }, - "regular expression"); - page.print(" that has to match a substring in the name of the searched symbol."); - page.printOTag("dt"); - page.printlnTag("b", "By comment"); - page.printOTag("dd"); - page.println("The search string must be a "); - page.printlnTag("a", - new XMLAttribute[] { - new XMLAttribute("href", - "http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html") }, - "regular expression"); - page.print(" that has to match a substring in the comments associated to the searched symbol."); - page.printOTag("dt"); - page.printlnTag("b", "By type"); - page.printOTag("dd"); - page.println("The search string must represent a Scala type. Any string "); - page.printlnTag("code", "S"); - page.println(" such that "); - page.printlnTag("pre", "def foo S;"); - page.println(" is a valid function definition is accepted. Here are some examples:"); - page.printlnOTag("ul"); - page.printOTag("li"); - page.printlnTag("code", ": int => int"); - page.printOTag("li"); - page.printlnTag("code", "[a,b]: List[a] => (a => b) => List[b]"); - page.printOTag("li"); - page.printlnTag("code", "(x: int, y: int): unit"); - page.printlnCTag("ul"); - page.println("The searched symbols must conform to the entered type modulo "); - page.printlnTag("a", - new XMLAttribute[] { - new XMLAttribute("href", - "http://www.pps.jussieu.fr/~dicosmo/Publications/ISObook.html") }, - "type isomorphism"); - page.println(". This concept allows to unify types that differ by their exact " - + "representation but not by their meaning. The order of parameters is " - + "for instance irrelevant when looking for a function. Note finally that " - + "methods of classes are interpreted as functions that would take an " - + "extra argument of the type of the class."); - page.printlnCTag("dl"); - page.printlnCTag("p"); - page.printlnCTag("blockquote"); - } - - page.printlnOTag("div", em); - page.println("This help file applies to API documentation generated " - + "using the standard doclet."); - page.printlnCTag("div"); - - page.printlnHLine(); - addNavigationBar(HELP_NAV_CONTEXT); - if (validate) - addValidationBar(); - - page.printFootpage(); - closePrinters(); - } - } - - /** - * Adds to the current page an hyperlinked path leading to a given - * symbol (including itself). - */ - protected void printPath(Symbol sym, String destinationFrame, Page page) { - String name = removeHtmlSuffix(Location.getURI(sym).toString()); - if (isDocumented.apply(sym)) { - String target = definitionURI(sym, page).toString(); - page.printlnAhref(target, destinationFrame, name); - } - else - page.println(name); - } - - protected void printPath(Symbol sym, String destinationFrame) { - printPath(sym, destinationFrame, page); - } - - /** - * Writes the string representation of a symbol entry in the index. - * - * @param symbol - */ - protected void addIndexEntry(Symbol symbol, Page page, MySymbolTablePrinter symtab) { - // kind - String keyword = symtab.getSymbolKeywordForDoc(symbol); - - if (keyword != null) page.print(keyword).space(); - // name - symtab.printDefinedSymbolName(symbol, true); - // owner - if (!symbol.isRoot()) { - page.print(" in "); - printPath(symbol.owner(), SELF_FRAME, page); - } - } - - protected void addIndexEntry(Symbol symbol) { - addIndexEntry(symbol, page, symtab); - } - - /** - * Writes documentation comments to the current page. - * - * @param comment - */ - protected void addComments(Comment comment) { - if (!comment.isEmpty()) { - page.printlnOTag("dl").indent(); - // text with inlined links - page.printlnTag("dd", inlineLinkTags(comment.holder, comment.text)); - page.undent().printlnCTag("dl"); - - // tags - addTags(comment.tags); - } - } - - /** Inline all the {@link ...} tags inside the text. - */ - protected String inlineLinkTags(Symbol holder, String text) { - StringBuffer buff = new StringBuffer(); - Tag[] tags = Comment.makeTags(holder, text); - for (int i = 0; i < tags.length; i++) { - if (tags[i].isText()) - buff.append(tags[i].text); - else if (tags[i].isReference()) - buff.append(inlineRefTag(tags[i])); - } - return buff.toString(); - } - - /** - * Returns the first sentence of a documentation comment where all - * links {@link ...} have been inlined. - * - * @param comment - */ - protected String firstSentence(Comment comment) { - return - inlineLinkTags(comment.holder, comment.firstSentence()); - } - - // TODO: remove this ! - private static String ahref(String dest, String target, String text) { - return "<a href=\"" + dest + "\" target=\"" + target + "\">" + - text + "/a>"; - } - - /** Inline a @see documentation tag. - */ - protected String inlineRefTag(Tag tag) { - switch(Tag.parseReference(tag)) { - case Bad(String ref): - return ref; - case Url(String ref): - return ref; - case Literal(String ref): - return ref; - case Scala(String container, String member, String label): - Symbol sym = findSymbolFromString(tag.holder, container, member); - if (sym == Symbol.NONE) { - System.err.println("Warning: not found " + tag); - return tag.text; - } - else if (!isDocumented.apply(sym)) { - System.err.println("Warning: not referenced " + tag); - return tag.text; - } - else { - String labl = label.equals("") ? sym.nameString() : label; - return ahref(definitionURI(sym).toString(), ROOT_FRAME, labl); - } - default: - throw Debug.abort("illegal case", tag); - } - } - - /** - * Writes a set of Scaladoc tags to a page. - * - * @param tags - */ - protected void addTags(Tag[] tags) { - if (tags.length > 0) { - Tag returnTag = null; - Tag sinceTag = null; - Tag versionTag = null; - final List paramTagList = new LinkedList();; - final List seeTagList = new LinkedList(); - final List throwsTagList = new LinkedList(); - final List authorTagList = new LinkedList(); - final List otherTagList = new LinkedList(); - - // partitioning the tags - for (int i = 0; i < tags.length; i++) { - if ("@return".equals(tags[i].name)) - returnTag = tags[i]; - else if ("@since".equals(tags[i].name)) - sinceTag = tags[i]; - else if ("@version".equals(tags[i].name)) - versionTag = tags[i]; - else if ("@param".equals(tags[i].name)) - paramTagList.add(tags[i]); - else if ("@see".equals(tags[i].name)) - seeTagList.add(tags[i]); - else if (tags[i].isException()) - throwsTagList.add(tags[i]); - else if ("@author".equals(tags[i].name)) - authorTagList.add(tags[i]); - else - otherTagList.add(tags[i]); - } - - page.printlnOTag("dl"); - - // Author. - if (authorTagList.size() > 0) { - addTagSection("Author"); - page.printlnOTag("dd").indent(); - Iterator it = authorTagList.iterator(); - Tag authorTag = (Tag) it.next(); - page.print(authorTag.text); - while (it.hasNext()) { - authorTag = (Tag) it.next(); - page.print(", " + authorTag.text); - } - page.println().undent(); - page.printlnCTag("dd"); - } - // Since. - if (sinceTag != null) { - addTagSection("Since"); - page.printlnTag("dd", sinceTag.text); - } - // Version. - if (versionTag != null) { - addTagSection("Version"); - page.printlnTag("dd", versionTag.text); - } - // Parameters. - if (paramTagList.size() > 0) { - addTagSection("Parameters"); - Iterator it = paramTagList.iterator(); - Tag paramTag = null; - while (it.hasNext()) { - paramTag = (Tag) it.next(); - Pair fields = Tag.split(paramTag.text); - String paramName = (String) fields.fst; - String paramDesc = (String) fields.snd; - page.printOTag("dd"); - page.printTag("code", paramName); - page.println(" - "); - page.println(inlineLinkTags(paramTag.holder, paramDesc)); - page.printlnCTag("dd"); - } - } - // Returns. - if (returnTag != null) { - addTagSection("Returns"); - page.printlnTag("dd", returnTag.text); - } - // Throws. - if (throwsTagList.size() > 0) { - addTagSection("Throws"); - Iterator it = throwsTagList.iterator(); - Tag throwsTag = null; - while (it.hasNext()) { - throwsTag = (Tag) it.next(); - Pair fields = Tag.split(throwsTag.text); - String exceptionName = (String) fields.fst; - String exceptionDesc = (String) fields.snd; - page.printOTag("dd"); - page.printTag("code", exceptionName); - page.println(" - "); // TODO: hypertext link - page.println(inlineLinkTags(throwsTag.holder, exceptionDesc)); - page.printlnCTag("dd"); - } - } - // See Also. - if (seeTagList.size() > 0) { - addTagSection("See Also"); - page.printlnOTag("dd"); - Iterator it = seeTagList.iterator(); - Tag seetag = (Tag) it.next(); - page.println(inlineRefTag(seetag)); - while (it.hasNext()) { - seetag = (Tag) it.next(); - page.print(", "); - page.println(inlineRefTag(seetag)); - } - page.printlnCTag("dd"); - } - // Others. - if (otherTagList.size() > 0) { - Iterator it = otherTagList.iterator(); - while (it.hasNext()) - addStandardTag((Tag) it.next()); - } - - page.printlnCTag("dl"); - } - } - - /** - * Returns the HTML representation of a documentation tag. - * - * @param tagName - */ - protected void addTagSection(String tagName) { - page.printOTag("dt", ATTRS_DOCTAG); - page.printBold(tagName + ":"); - page.printlnCTag("dt"); - } - - /** - * Returns the HTML representation of a standard documentation tag. - * - * @param tag - */ - protected void addStandardTag(Tag tag) { - String sectionName = ""; - if (tag.name.length() > 1) { - sectionName += Character.toUpperCase(tag.name.charAt(1)); - if (tag.name.length() > 2) - sectionName += tag.name.substring(2); - } - addTagSection(sectionName); - page.printTag("dd", inlineLinkTags(tag.holder, tag.text)); - } - - /** - * Returns the symbol contained in a specified class or object and - * described by its label or its name. Return Symbol.NONE if not - * found. - * - * @param context - * @param classOrObject - * @param label - */ - protected Symbol findSymbolFromString(Symbol context, String classOrObject, String label) { - /* - String path; - // absolute path - if (classOrObject.startsWith(new Character(ScalaSearch.classChar).toString()) || - classOrObject.startsWith(new Character(ScalaSearch.objectChar).toString())) - path = classOrObject; - else // relative path - path = ScalaSearch.getOwnersString(context.owner()) + classOrObject; - path = path.substring(1); - Symbol sym = ScalaSearch.lookup(global.definitions.ROOT_CLASS, path); - if (sym == Symbol.NONE) - return Symbol.NONE; - else { - if (label == null) - return sym; - else { - // look for a member in the scope that has a tag - // @label with the given label - Scope scope = sym.moduleClass().members(); - SymbolIterator it = scope.iterator(); - while (it.hasNext()) { - Symbol member = (Symbol) it.next(); - Tag[] tags = getComment(member).tags; - for (int i = 0; i < tags.length; i++) - if ("@label".equals(tags[i].name) && - label.equals(tags[i].text)) - return member; - } - // look for the first term with label as name - return sym.moduleClass().lookup(Name.fromString(label).toTermName()); - } - } - */ - return Symbol.NONE; - } - - protected void addCategory(Symbol[] symbols, String title, Page page, MySymbolTablePrinter symtab) { - if (symbols.length > 0) { - page.printlnTag("h3", title); - page.printlnOTag("dl").indent(); - for(int i = 0; i < symbols.length; i++) { - page.printOTag("dt"); - addIndexEntry(symbols[i], page, symtab); - page.printlnCTag("dt"); - page.printlnTag("dd", firstSentence(getComment(symbols[i]))); - } - page.undent().printlnCTag("dl"); - } - } - - protected void addFoundSymbols(List symbols, Page page, MySymbolTablePrinter symtab) { - // partition and sort - List fields = new LinkedList(); - List modules = new LinkedList(); - List types = new LinkedList(); - ScalaSearch.categorizeSymbols(symbols, fields, modules, types); - Symbol[] sortedFields = ScalaSearch.sortList(fields); - Symbol[] sortedModules = ScalaSearch.sortList(modules); - Symbol[] sortedTypes = ScalaSearch.sortList(types); - - addCategory(sortedFields, "val/def", page, symtab); - addCategory(sortedModules, "package/object", page, symtab); - addCategory(sortedTypes, "type/trait/class", page, symtab); - } - - protected void addResultNumber(int number, Page page) { - page.printOTag("p"); - page.printOTag("b"); - page.print("" + number + " result(s)."); - page.printCTag("b"); - page.printCTag("p"); - } - - public static String SEARCH_SERVLET_NAME = "scaladocServlet"; - public static String PAGE_SERVLET_NAME = "pageServlet"; - - public class SearchServlet extends Servlet { - - public String name() { - return SEARCH_SERVLET_NAME; - } - - public synchronized void apply(Map req, Writer out) { - // create page - String pagename = "search-page"; - URI uri = Location.makeURI(pagename + ".html"); - String destinationFrame = SELF_FRAME; - String title = pagename; - - final Page page = new Page(out, uri, destinationFrame, - title, representation, - HTMLGenerator.this.adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_STYLESHEET), - uri).toString(), - HTMLGenerator.this.adaptURI(Location.mkURI(HTMLPrinter.DEFAULT_JAVASCRIPT), - uri).toString()); - page.open(); - page.printHeader(ATTRS_META, getGenerator()); - page.printOpenBody(); - addNavigationBar(CONTAINER_NAV_CONTEXT, page); - page.printlnHLine(); - - // create symbol printer - final MySymbolTablePrinter symtab = - SymbolTablePrinterFactory.makeHTML(HTMLGenerator.this, page, isDocumented); - - // analyze the request - String searchKind = (String) req.get("searchKind"); - String searchString = (String) req.get("searchString"); - - // search summary - String searchKindSummary = null; - if (searchKind.equals("byName")) - searchKindSummary = "in defined names"; - else if (searchKind.equals("byComment")) - searchKindSummary = "in comments"; - else if (searchKind.equals("byType")) - searchKindSummary = "by type"; - String searchSummary = - "Scaladoc searched for the string (" + searchString + ") " + searchKindSummary + "."; - page.printOTag("p"); - page.printOTag("b"); - page.print(searchSummary); - page.printCTag("b"); - page.printCTag("p"); - - // Search by name. - if (searchKind.equals("byName")) { - String regexp = searchString; - final Pattern p = Pattern.compile(regexp); - - final List found = new LinkedList(); - //collect - ScalaSearch.foreach(global.definitions.ROOT_CLASS, - new ScalaSearch.SymFun() { - public void apply(Symbol sym) { - String name = sym.nameString(); - Matcher m = p.matcher(name); - if (m.find()) - found.add(sym); - } - }, - isDocumented); - addResultNumber(found.size(), page); - addFoundSymbols(found, page, symtab); - } - // Search by comment. - else if (searchKind.equals("byComment")) { - String regexp = searchString; - final Pattern p = Pattern.compile(regexp); - - final List found = new LinkedList(); - ScalaSearch.foreach(global.definitions.ROOT_CLASS, - new ScalaSearch.SymFun() { - public void apply(Symbol sym) { - Pair c = (Pair) global.mapSymbolComment.get(sym); - if (c != null) { - String comment = (String) c.fst; - Matcher m = p.matcher(comment); - if (m.find()) - found.add(sym); - } - } - }, - isDocumented); - addResultNumber(found.size(), page); - addFoundSymbols(found, page, symtab); - } - // Search by type. - else if (searchKind.equals("byType")) { - Type t = ScalaSearch.typeOfString(searchString, global); - TypeIsomorphism ml = newTypeIso(global); - - List found = new LinkedList(); - Map searchResults = new HashMap(); - Iterator it = ml.searchType(t, isDocumented); - while (it.hasNext()) { - SearchResult result = (SearchResult) it.next(); - found.add(result.symbol); - searchResults.put(result.symbol, result); - } - if (t == Type.NoType) { - page.printOTag("p"); - page.println("Scaladoc could not recognize your search string as a type, " - + "see the "); - page.printlnTag("a", - new XMLAttribute[] { - new XMLAttribute("href", HELP_PAGE + "#" + SEARCH_SECTION) }, - "help page"); - page.println(" to know which syntax to use."); - page.printCTag("p"); - } - else { - page.printOTag("p"); - page.print("You are searching for symbols with type: "); - page.print(t.toString()); - page.printCTag("p"); - - addResultNumber(found.size(), page); - - Symbol[] sortedSymbols = ScalaSearch.sortList(found); - - for(int i = 0; i < sortedSymbols.length; i++) { - Symbol sym = sortedSymbols[i]; - SearchResult result = (SearchResult) searchResults.get(sym); - Type adaptedType = result.getType; - page.printOTag("dt"); - //page.printOTag("code"); - symtab.printShortSignature(sym, true); - symtab.printSeqType(sym, adaptedType, symtab.getSymbolInnerString(sym)); - page.printlnCTag("dt"); - if (!sym.isRoot()) { - page.printOTag("dd"); - page.print("in "); - printPath(sym.owner(), SELF_FRAME, page); - if (result.isInClass && (result.tparams.length > 0)) { - page.print("["); - for(int j = 0; j < result.tparams.length; j++) { - if (j != 0) page.print(","); - page.print(result.tparams[j].nameString()); - } - page.print("]"); - } - page.printCTag("dd"); - } - String firstSent = firstSentence(getComment(sym)); - if (!firstSent.equals("")) - page.printlnTag("dd", firstSent); - //page.printlnCTag("code"); - } - } - } - // close page - page.printlnHLine(); - addNavigationBar(CONTAINER_NAV_CONTEXT, page); - page.printFootpage(); - // page.close(); - // already done by the HTTP server when closing connection - } - } - - /** - * A servlet that accepts requests for web pages registered in the - * hastable <code>promises</code>. - */ - public class PageServlet extends Servlet { - - public String name() { - return PAGE_SERVLET_NAME; - } - - public synchronized void apply(Map req, Writer out) { - // analyze the request - String pageName = (String) req.get("page"); - Promise promise = (Promise) promises.get(pageName); - promise.writeOn(out); - } - } -} - -public class SearchResult { - Symbol symbol; - Type getType; - boolean isInClass; - Symbol[] tparams; - public SearchResult(Symbol symbol, - Type getType, - boolean isInClass, - Symbol[] tparams) { - this.symbol = symbol; - this.getType = getType; - this.isInClass = isInClass; - this.tparams = tparams; - } -} - -/** - * This class represents a web page not yet printed. - */ -public abstract class Promise { - - protected StringWriter cache = null; - - /** Name of the web page. */ - public abstract String name(); - - /** - * Print the web page on the given writer. Do not forget to close - * the writer afterwards. Cache the result for further reuse. - */ - public void writeOn(Writer writer) { - if (cache == null) { - cache = new StringWriter(); - computeIn(cache); - try { - cache.close(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - try { - writer.write(cache.toString()); - } - catch (IOException e) { - e.printStackTrace(); - } - } - - /** Print the web page on the given writer. */ - protected abstract void computeIn(Writer writer); -} diff --git a/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java b/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java deleted file mode 100644 index 3ef4bc1261..0000000000 --- a/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java +++ /dev/null @@ -1,191 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.util.ArrayList; -import java.util.List; - -import ch.epfl.lamp.util.HTMLPrinter; -import ch.epfl.lamp.util.HTMLRepresentation; - -import scala.tools.util.ClassPath; -import scala.tools.util.Reporter; - -import scalac.CompilerCommand; -import scalac.CompilerPhases; -import scalac.util.BooleanOptionParser; -import scalac.util.OptionParser; -import scalac.util.StringOptionParser; -import scalac.util.ScalaProgramArgumentParser; -import scalac.util.Strings; - -/** - * The class <code>HTMLGeneratorCommand</code> describes the options - * passed as arguments to the HTML generator command. - */ -public class HTMLGeneratorCommand extends CompilerCommand { - - //######################################################################## - // Public Fields - - public final StringOptionParser docencoding; - public final StringOptionParser docmodule; - public final StringOptionParser docmodulePath; - public final StringOptionParser doctitle; - public final StringOptionParser doctype; - public final StringOptionParser stylesheet; - public final StringOptionParser windowtitle; - - public final BooleanOptionParser server; - public final StringOptionParser port; - - public final BooleanOptionParser noindex; - public final BooleanOptionParser validate; - - public final ScalaProgramArgumentParser packages; - - //######################################################################## - // Public Constructors - - /** - * Creates an instance variable for an HTML generator command. - * - * @param product - * @param version - * @param reporter - * @param phases - */ - public HTMLGeneratorCommand(String product, String version, - Reporter reporter, CompilerPhases phases) - { - this(product, version, "<source files> [-- <packages>]", reporter, phases); - } - - /** - * Creates an instance variable for an HTML generator command. - * - * @param product - * @param version - * @param syntax - * @param reporter - * @param phases - */ - public HTMLGeneratorCommand(String product, String version, String syntax, - Reporter reporter, CompilerPhases phases) - { - super(product, version, syntax, reporter, phases); - - this.docencoding = new StringOptionParser(this, - "docencoding", - "Output encoding name (" + HTMLRepresentation.DEFAULT_DOCENCODING + ", etc.)", - "name", - HTMLRepresentation.DEFAULT_DOCENCODING); - - this.docmodule = new StringOptionParser(this, - "docmodule", - "Specify module used by scaladoc", - "class", - "scala.tools.scaladoc.StandardDocModule"); - - this.docmodulePath = new StringOptionParser(this, - "docmodulepath", - "Specify where to find doc module class files", - "path", - ClassPath.DEFAULT_CLASSPATH); - - this.doctitle = new StringOptionParser(this, - "doctitle", - "Include title for the overview page", - "html-code", - HTMLGenerator.DEFAULT_DOCTITLE); - - this.doctype = new StringOptionParser(this, - "doctype", - "Output type name (" + HTMLRepresentation.DEFAULT_DOCTYPE + ", etc.)", - "name", - HTMLRepresentation.DEFAULT_DOCTYPE); - - this.stylesheet = new StringOptionParser(this, - "stylesheetfile", - "File to change style of the generated documentation", - "path", - HTMLPrinter.DEFAULT_STYLESHEET); - - this.windowtitle = new StringOptionParser(this, - "windowtitle", - "Browser window title for the documentation", - "text", - HTMLGenerator.DEFAULT_WINDOWTITLE); - - this.server = new BooleanOptionParser(this, - "server", - "Launch an HTTP server for interactive search", - false); - - this.port = new StringOptionParser(this, - "port", - "Port number for the HTTP server", - "port", - "1280"); - - this.noindex = new BooleanOptionParser(this, - "noindex", - "Do not generate index", - false); - - this.validate = new BooleanOptionParser(this, - "validate", - "Add a link at the bottom of each generated page", - false); - - this.packages = new ScalaProgramArgumentParser(this); - - remove(nowarn); - remove(verbose); - remove(debug); - remove(explaintypes); - remove(uniqid); - remove(types); - remove(prompt); - remove(separate); - remove(classpath); - remove(sourcepath); - remove(bootclasspath); - remove(extdirs); - // outpath; - remove(target); - remove(noimports); - remove(nopredefs); - remove(skip); - remove(check); - remove(print); - remove(printer); - remove(printfile); - remove(graph); - remove(stop); - remove(log); - remove(Xshortname); - - // similar order as javadoc options - add(2, windowtitle); - add(3, doctitle); - add(4, noindex); - add(5, docmodule); - add(6, docmodulePath); - add(7, stylesheet); - add(8, doctype); - add(9, docencoding); - add(10, validate); - add(11, server); - add(12, port); - add(13, packages); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scaladoc/HTTPServer.java b/sources/scala/tools/scaladoc/HTTPServer.java deleted file mode 100644 index 3943323d65..0000000000 --- a/sources/scala/tools/scaladoc/HTTPServer.java +++ /dev/null @@ -1,453 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.net.*; -import java.io.*; -import java.util.*; -import java.util.regex.*; - -/** - * A Java server that can be invoked via HTTP. - */ -abstract class Servlet { - - /** - * Name of the servlet. - */ - public abstract String name(); - - /** - * Give the servlet a request and a place where to write its - * answer. - */ - public abstract void apply(Map req, Writer out); -} - -/** - * A servlet that echoes the query to its sender. - */ -class EchoServlet extends Servlet { - - public String name() { - return "echoServlet"; - } - - public void apply(Map req, Writer out) { - printMap(req, out); - } - - /** Print a map. */ - public static void printMap(Map map, Writer out) { - Iterator i = map.keySet().iterator(); - while(i.hasNext()) { - String key = (String) i.next(); - String value = (String) map.get(key); - try { - out.write(key + " -> " + value + "\n"); - } catch (IOException e) {} - } - } -} - -/** - * HTTP server. It is in fact an extension of an example found in the - * book "Java Network Programming" by Elliotte Rusty Harold that can - * handle servlet invokations. - */ -public class HTTPServer extends Thread { - - private File documentRootDirectory; - private String indexFileName = "index.html"; - private ServerSocket server; - private int numThreads = 50; - - private Map/*<String,Servlet>*/ servletNamed; - - public HTTPServer(File documentRootDirectory, - int port, - String indexFileName) throws IOException { - - this.documentRootDirectory = - documentRootDirectory == null ? - new File(".") : - documentRootDirectory; - - if (!this.documentRootDirectory.isDirectory()) { - throw new IOException(this.documentRootDirectory - + " does not exist as a directory"); - } - this.indexFileName = indexFileName; - this.server = new ServerSocket(port); - } - - public HTTPServer(File documentRootDirectory, int port) - throws IOException { - this(documentRootDirectory, port, "index.html"); - } - - public HTTPServer(File documentRootDirectory) throws IOException { - this(documentRootDirectory, 80, "index.html"); - } - - /** - * Launch the server with a specified list of servlets. - */ - public HTTPServer(File documentRootDirectory, - int port, - Servlet[] servlets) throws IOException { - this(documentRootDirectory, port, "index.html"); - servletNamed = new HashMap(); - for (int i = 0; i < servlets.length; i++) - servletNamed.put("/" + servlets[i].name(), servlets[i]); - } - - public void run() { - - for (int i = 0; i < numThreads; i++) { - Thread t = new Thread( - new RequestProcessor(documentRootDirectory, - indexFileName, - servletNamed)); - t.start(); - } - System.out.println("Accepting connections on port " - + server.getLocalPort()); - System.out.println("Document Root: " + documentRootDirectory); - while (true) { - try { - Socket request = server.accept(); - InetSocketAddress addr = (InetSocketAddress) request.getRemoteSocketAddress(); - if (addr != null) - System.out.println("Connection from: " + addr.getAddress().getCanonicalHostName()); - RequestProcessor.processRequest(request); - } - catch (IOException e) { - } - } - } - - public static void main(String[] args) { - - // get the Document root - File docroot; - try { - docroot = new File(args[0]); - } - catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Usage: java HTTPServer docroot port indexfile"); - return; - } - - // set the port to listen on - int port; - try { - port = Integer.parseInt(args[1]); - if (port < 0 || port > 65535) port = 80; - } - catch (Exception e) { - port = 80; - } - - try { - Servlet[] servlets = new Servlet[] { new EchoServlet() }; - HTTPServer webserver = new HTTPServer(docroot, port, servlets); - webserver.start(); - } - catch (IOException e) { - System.out.println("Server could not start because of an " - + e.getClass()); - System.out.println(e); - } - } -} - -class RequestProcessor implements Runnable { - - private static final String MIME_APPLICATION_OCTET_STREAM = - "application/octet-stream"; - private static final String MIME_APPLICATION_PDF = - "application/pdf"; - private static final String MIME_APPLICATION_POSTSCRIPT = - "application/postscript"; - - private static final String MIME_IMAGE_GIF = "image/gif"; - private static final String MIME_IMAGE_JPEG = "image/jpeg"; - private static final String MIME_IMAGE_PNG = "image/png"; - - private static final String MIME_TEXT_HTML = "text/html"; - private static final String MIME_TEXT_PLAIN = "text/plain"; - - private final static String ENCODING_SCHEME = "iso-8859-1"; // "UTF-8" - - private static List pool = new LinkedList(); - private File documentRootDirectory; - private String indexFileName = "index.html"; - private Map servletNamed; - - public RequestProcessor(File documentRootDirectory, - String indexFileName, - Map servletNamed) { - - if (documentRootDirectory.isFile()) { - throw new IllegalArgumentException( - "documentRootDirectory must be a directory, not a file"); - } - this.documentRootDirectory = documentRootDirectory; - try { - this.documentRootDirectory - = documentRootDirectory.getCanonicalFile(); - } - catch (IOException e) { - } - if (indexFileName != null) this.indexFileName = indexFileName; - this.servletNamed = servletNamed; - } - - public static void processRequest(Socket request) { - synchronized (pool) { - pool.add(pool.size(), request); - pool.notifyAll(); - } - } - - /** - * Parse a non-null query and put the bindings (key, value) into - * the result map. - */ - public static Map parseQuery(String query) { - Map/*<String,String>*/ map = new HashMap(); - try { - String[] bindings = query.split("\\&"); - String regexp = "([^=]*)=([^=]*)"; - Pattern p = Pattern.compile(regexp); - for (int i = 0; i < bindings.length; i++) { - Matcher m = p.matcher(bindings[i]); - if (m.find()) { - String key = URLDecoder.decode(m.group(1), ENCODING_SCHEME); - String value = URLDecoder.decode(m.group(2), ENCODING_SCHEME); - map.put(key, value); - } - } - } - catch (UnsupportedEncodingException e) { - System.out.println("Une exception: " + e); - } - return map; - } - - private static String mkMIMEHeader(int statusCode, String statusMessage, - String contentType, int contentLength) { - StringBuffer buf = new StringBuffer(); - buf.append("HTTP/1.0 " + statusCode + " " + statusMessage + "\r\n"); - buf.append("Date: " + new Date() + "\r\n"); - buf.append("Server: HTTPServer 1.0\r\n"); - buf.append("Content-length: " + contentLength + "\r\n"); - buf.append("Content-type: " + contentType + "\r\n\r\n"); - return buf.toString(); - } - - private static void write(Writer out, String version, - int statusCode, String statusMessage, - String contentType, String contentData) { - try { - if (version.startsWith("HTTP/")) { // send a MIME header - String header = mkMIMEHeader(statusCode, statusMessage, - contentType, contentData.length()); - out.write(header); - } - out.write(contentData); - out.flush(); - } - catch (IOException e) { - } - } - - private static void writeData(OutputStream out, String version, - int statusCode, String statusMessage, - String contentType, File theFile) { - try { - DataInputStream fis = new DataInputStream(new FileInputStream(theFile)); - byte[] theData = new byte[(int) theFile.length()]; - fis.readFully(theData); - fis.close(); - if (version.startsWith("HTTP/")) { // send a MIME header - String header = mkMIMEHeader(statusCode, statusMessage, - contentType, theData.length); - out.write(header.getBytes()); - } - out.write(theData); - out.flush(); - } - catch (IOException e) { - } - } - - private static void writeError(Writer out, String version, - int statusCode, String statusMessage) { - StringBuffer buf = new StringBuffer(); - buf.append("<html>\r\n"); - buf.append("<head><title>" + statusMessage + "</title>\r\n"); - buf.append("</head>\r\n"); - buf.append("<body>"); - buf.append("<h1>HTTP Error " + statusCode + ": " + statusMessage + "</h1>\r\n"); - buf.append("</body></html>\r\n"); - write(out, version, statusCode, statusMessage, MIME_TEXT_HTML, buf.toString()); - } - - private static void writeServlet(Writer out, String version, - Servlet servlet, URI uri) { - String query = uri.getRawQuery(); - Map map = (query != null) ? parseQuery(query) : new HashMap(); - write(out, version, 200, "OK", MIME_TEXT_HTML, "<!-- generated with Scala Servlet -->\r\n"); - servlet.apply(map, out); - try { - out.write("\n"); - out.flush(); - } - catch (IOException e) { - } - } - - // See http://www.oreilly.com/catalog/javanp2/chapter/ch11.html - public void run() { - - // for security checks - String root = documentRootDirectory.getPath(); - - while (true) { - Socket connection; - synchronized (pool) { - while (pool.isEmpty()) { - try { - pool.wait(); - } - catch (InterruptedException e) { - } - } - connection = (Socket) pool.remove(0); - } - - try { - String filename; - String contentType; - OutputStream raw = - new BufferedOutputStream( - connection.getOutputStream()); - Writer out = new OutputStreamWriter(raw); - Reader in = - new InputStreamReader( - new BufferedInputStream(connection.getInputStream()), - "ASCII"); - StringBuffer requestLine = new StringBuffer(); - int c; - while (true) { - c = in.read(); - if (c == '\r' || c == '\n') break; - requestLine.append((char) c); - } - - String get = requestLine.toString(); - - // log the request - System.out.println(get); - - StringTokenizer st = new StringTokenizer(get); - String method = st.nextToken(); - String version = ""; - if (method.equals("GET")) { - filename = st.nextToken(); - - URI uri = new URI(filename); - String resource = uri.getPath(); - Servlet servlet = (Servlet) servletNamed.get(resource); - - if (servlet != null) { - // servlet invokation - writeServlet(out, "HTTP/", servlet, uri); - } - else { // not a query - if (filename.endsWith("/")) filename += indexFileName; - contentType = guessContentTypeFromName(filename); - if (st.hasMoreTokens()) { - version = st.nextToken(); - } - - File theFile = new File(documentRootDirectory, - filename.substring(1,filename.length())); - if (theFile.canRead() - // Don't let clients outside the document root - && theFile.getCanonicalPath().startsWith(root)) { - writeData(raw, version, 200, "OK", contentType, theFile); - } - else { - // can't find the file - writeError(out, version, 404, "File Not Found"); - } - } - } - else { - // method does not equal "GET" - writeError(out, version, 501, "Not Implemented"); - } - } - catch (URISyntaxException e) { - System.out.println("Une exception: " + e); - } - catch (IOException e) { - System.out.println("Une exception: " + e); - } - finally { - try { - connection.close(); - } - catch (IOException e) {} - } - - } // end while - - } // end run - - public static String guessContentTypeFromName(String name) { - int pos = name.lastIndexOf('.'); - if (pos >= 0) { - String suffix = name.substring(pos + 1).toLowerCase(); - String mime = (String) mimes.get(suffix); - return (mime == null) ? MIME_TEXT_PLAIN : mime; - } - return MIME_TEXT_PLAIN; - } - - private static final Hashtable/*<String,String>*/ mimes = new Hashtable(); - - static { - // See http://www.webmaster-toolkit.com/mime-types.shtml - mimes.put("c" , MIME_TEXT_PLAIN); - mimes.put("cc" , MIME_TEXT_PLAIN); - mimes.put("cpp" , MIME_TEXT_PLAIN); - mimes.put("class", MIME_APPLICATION_OCTET_STREAM); - mimes.put("gif" , MIME_IMAGE_GIF); - mimes.put("h" , MIME_TEXT_PLAIN); - mimes.put("htm" , MIME_TEXT_HTML); - mimes.put("html" , MIME_TEXT_HTML); - mimes.put("lst" , MIME_TEXT_PLAIN); - mimes.put("java" , MIME_TEXT_PLAIN); - mimes.put("jpe" , MIME_IMAGE_JPEG); - mimes.put("jpg" , MIME_IMAGE_JPEG); - mimes.put("jpeg" , MIME_IMAGE_JPEG); - mimes.put("pdf" , MIME_APPLICATION_PDF); - mimes.put("pl" , MIME_TEXT_PLAIN); - mimes.put("ps" , MIME_APPLICATION_POSTSCRIPT); - mimes.put("png" , MIME_IMAGE_PNG); - mimes.put("scala", MIME_TEXT_PLAIN); - mimes.put("text" , MIME_TEXT_PLAIN); - mimes.put("txt" , MIME_TEXT_PLAIN); - } - -} // end RequestProcessor diff --git a/sources/scala/tools/scaladoc/Location.java b/sources/scala/tools/scaladoc/Location.java deleted file mode 100644 index 0a2124a705..0000000000 --- a/sources/scala/tools/scaladoc/Location.java +++ /dev/null @@ -1,228 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.net.URL; -import java.net.URI; -import java.io.File; -import scalac.symtab.Symbol; -import java.util.Map; -import java.util.HashMap; -import scalac.util.Debug; - -/** - * This class manages the correspondance between a symbol and - * its URL. - */ -public class Location { - - static public final String ROOT_NAME = "root-page"; - static public final String HTML_SUFFIX = ".html"; - static public final String CLASS_SUFFIX = "-class"; - //static public final String CLASS_SUFFIX = "(class)"; - - /////////////////// UNIQUE URL ////////////////////// - - static public String get(Symbol sym) { - return getURI(sym).toString(); - } - /** Returns the URI of a given symbol. */ - static private final Map/*<Symbol, URI>*/ uris = new HashMap(); -// static public URI getURI(Symbol sym) { -// if (uris.get(sym) == null) { -// URI uri; -// try { -// if (sym.isModuleClass()) -// uri = getURI(sym.module()); -// else if (sym.isRoot() || sym.isClass() || sym.isModule() || sym.isPackage() || sym.isPackageClass()) -// uri = new URI(getPath(sym).toString() + HTML_SUFFIX); -// else if (sym.isParameter()) -// uri = getURI(sym.classOwner()); -// else -// uri = new URI(getURI(sym.owner()).toString() + "#" + nextFreeId(sym.owner())); -// uris.put(sym, uri); -// } catch(Exception e) { throw Debug.abort(sym.defString()); } -// } -// return (URI) uris.get(sym); -// } - static public URI getURI(Symbol sym) { - if (uris.get(sym) == null) { - URI uri = null; - try { - if (sym.isModule()) - uri = getURI(sym.moduleClass()); - else if (sym.isClassType()) - uri = new URI(getPath(sym).toString() + HTML_SUFFIX); - else if (sym.isParameter()) - uri = getURI(sym.classOwner()); - else - uri = new URI(getURI(sym.owner()).toString() + "#" + nextFreeId(sym.owner())); - uris.put(sym, uri); - } catch (Exception e) { throw Debug.abort(sym.defString()); } - } - return (URI) uris.get(sym); - } - // where - static private URI getPath(Symbol sym) { - assert sym.isClassType(): Debug.show(sym); - try { - if (sym.isRoot()) - return new URI(ROOT_NAME); - else if (sym.owner().isRoot()) - return new URI(getName(sym)); - else { - // !!! separator character in URI paths is '/' - return new URI(getPath(sym.owner()).toString() + "/" + getName(sym)); - } - } catch(Exception e) { return null; } - } - // where - static public String getName(Symbol sym) { - if (sym.isModule()) return getName(sym.moduleClass()); - assert sym.isClassType(): Debug.show(sym); - String name = sym.simpleName().toString(); - if (!sym.isRoot() && !sym.isModuleClass()) name += CLASS_SUFFIX; - return name; - } - // where - static private final Map/*<Symbol, Integer>*/ ids = new HashMap(); - static private int nextFreeId(Symbol sym) { - if (ids.get(sym) == null) - ids.put(sym, new Integer(0)); - int i = ((Integer) ids.get(sym)).intValue(); - ids.put(sym, new Integer(i + 1)); - return i; - } - - static protected URI makeURI(String uri) { - try { - return new URI(uri); - } - catch(Exception e) { - throw Debug.abort(e); - } - } - - /////////////////// AS SEEN FROM ////////////////////// - - /** - * Returns a representation of the URL u1 relative to u2. - * Examples: - * "A/B/C" as seen from "A" is "A/B/C" - * "A" as seen from "A/B/C" is "../../A" - * "A/B#R" as seen from "A" is "A/B#R" - */ - - static public URI asSeenFrom(URI u, URI v) { - File f_u = new File(u.getPath()); - File f_v = new File(v.getPath()); - try { - /// !!! separator character in URI paths is '/' - String uriPath = asSeenFrom(f_u, f_v).getPath().replace('\\', '/'); - return - new URI(uriPath - + (u.getFragment() != null ? "#" + u.getFragment() : "")) - .normalize(); - } - catch (Exception e) { - throw Debug.abort(e); - } - } - // where - /** f must be of the form ('.' | ['.' '/' ] A/...) */ - static private File pathToRoot(File f) { - if (f.equals(hereFile) || f.getParentFile() == null) - return new File("."); - else - return new File(pathToRoot(f.getParentFile()), ".."); - } - // where - /* - // where - static private File asSeenFrom(File f1, File f2) { - return new File(pathToRoot(f2), f1.getPath()); - } - */ - /** Compute the minimal path from one file to another. - * f1 and f2 should be of the form (A/...) - */ - static private File asSeenFrom(File f1, File f2) { - if (f1.equals(f2)) - return new File(f1.getName()); - else { - File lcp = longestCommonPrefix(f1, f2); - File relf1 = subtractPrefix(lcp, f1); - File relf2 = subtractPrefix(lcp, f2); - return new File(pathToRoot(relf2), relf1.getPath()); - } - } - // where - /** p and q should be of the form (A/...) */ - static private File longestCommonPrefix(File p, File q) { - if (prefixes(p, q)) - return p; - else if (p.getParentFile() == null) - return new File("."); - else - return longestCommonPrefix(p.getParentFile(), q); - } - // where - /** Test if p is a prefix of q. - * p and q should be of the form (A/...) - */ - static private boolean prefixes(File p, File q) { - if (p.equals(q)) - return true; - else if (q.getParentFile() == null) - return false; - else - return prefixes(p, q.getParentFile()); - } - // and - static private File hereFile = new File("."); - static private File subtractPrefix(File p, File f) { - if (p.equals(hereFile)) - return f; - else - return subtractPrefix(p, f, hereFile); - } - static private File subtractPrefix(File p, File f, File acc) { - if (p.equals(f)) - return acc; - else if (f.getParentFile() == null) - return null; - else - return subtractPrefix(p, f.getParentFile(), - (acc.equals(hereFile) ? - new File(f.getName()) : - new File(f.getName(), acc.getPath()))); - } - - static protected URI mkURI(String uri) { - try { - return new URI(uri); - } - catch (Exception e) { - throw Debug.abort(e); - } - } - - public static void main(String[] args) { - File p = new File("A", "B"); - File q = new File("A", new File("B", "C").getPath()); - File r = new File("C"); - System.out.println("" + longestCommonPrefix(p, q)); - System.out.println("" + longestCommonPrefix(p, r)); - System.out.println("" + subtractPrefix(longestCommonPrefix(p, r), p)); - - System.out.println("" + asSeenFrom(q, p)); - System.out.println("" + asSeenFrom(p, r)); - } - -} diff --git a/sources/scala/tools/scaladoc/MLType.scala b/sources/scala/tools/scaladoc/MLType.scala deleted file mode 100644 index 3dc6c89a14..0000000000 --- a/sources/scala/tools/scaladoc/MLType.scala +++ /dev/null @@ -1,690 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{symtab => scalac_symtab} -import scalac.Global; -import scalac.util.Names; - -package scala.tools.scaladoc { - - import scalac_symtab._; - import scala.collection.immutable._; - - /** - * @author Vincent Cremet - * @author Roland Tchakoute - */ - abstract class ML { - - ////////////// TYPE CONSTRUCTORS //////////////// - - trait TypeConstructor[T <: TypeConstructor[T]] { - def sameAs(that: T): boolean; - } - type TC <: TypeConstructor[TC]; - - trait MLType { - override def toString(): String = this match { - case TypeVar(n) => "x" + n - case UnitType => "unit" - case AtomicType(c, args) => c.toString() + "[" + args.mkString("", ", ","") + "]" - case ProdType(l, r) => "(" + l + " * " + r + ")" - case FunType(arg, res) => "(" + arg.toString() + " -> " + res + ")" - } - def * (that: MLType) = ProdType(this, that); - def -> (that: MLType) = FunType(this, that); - } - def x(n: int) = TypeVar(n); - val unt = UnitType; - def at(c: TC, args: MLType*) = AtomicType(c, args.asInstanceOf[List[MLType]]); - - case class TypeVar(n: int) extends MLType; - case object UnitType extends MLType; - case class AtomicType(c: TC, args: List[MLType]) extends MLType; - case class ProdType(l: MLType, r: MLType) extends MLType; - case class FunType(arg: MLType, res: MLType) extends MLType; - - val fullIso = true; - - ///////////////// NORMAL FORMS //////////////////// - - /** Transform a type into his normal form. */ - def normalForm(t: MLType): MLType = { - def normalFormAux(t: MLType): MLType = t match { - case FunType(arg, UnitType) => if (fullIso) UnitType else t - case FunType(UnitType, res) => res - case ProdType(l, UnitType) => l - case ProdType(UnitType, r) => r - case FunType(ProdType(l, r), res) => - normalFormAux(FunType(l, normalFormAux(FunType(r, res)))) - case FunType(arg, ProdType(l,r)) => - ProdType(normalFormAux(FunType(arg, l)), normalFormAux(FunType(arg, r))) - case _ => t - } - t match { - case ProdType(l, r) => - normalFormAux(ProdType(normalForm(l), normalForm(r))) - case FunType (arg, res) => - normalFormAux(FunType(normalForm(arg), normalForm(res))) - case _ => t - } - } - - type Type_coords = Pair[int, List[MLType]]; - - def rewriteType(t: MLType): Type_coords = { - def flatten(t: MLType): Type_coords = t match { - case ProdType(l,r) => { - val Pair(len1, l1) = flatten(l); - val Pair(len2, l2) = flatten(r); - Pair(len1 + len2, l1 ::: l2) - } - case _ => Pair(1, List(t)) - } - flatten(normalForm(t)) - } - - /////////////////// RENAMINGS //////////////////////// - - type Renaming = Map[int,int]; - - def rename_type(ren: Renaming): MLType => MLType = { - if (ren.isEmpty) - (x => x) - else { - case TypeVar(n) => TypeVar(ren(n)) - case UnitType => UnitType - case AtomicType(c, args) => AtomicType(c, args map rename_type(ren)) - case ProdType(l, r) => ProdType(rename_type(ren)(l), rename_type(ren)(r)) - case FunType(arg, res) => FunType(rename_type(ren)(arg), rename_type(ren)(res)) - } - } - - ///////////////// SPLIT NORMAL FORMS /////////////////// - - - def fold[a,b](l: List[a], z: b, op: (b, a) => Pair[b,a]): Pair[b, List[a]] = - l match { - case List() => Pair(z, List()) - case x :: xs => { - val Pair(z1, x1) = op(z, x); - val Pair(z2, xs1) = fold(xs, z1, op); - Pair(z2, x1 :: xs1) - } - } - - def containsProdType(t: MLType): boolean = t match { - case ProdType(_, _) => true - case TypeVar(_) => false - case UnitType => false - case AtomicType(_, _) => false - case FunType(arg, res) => containsProdType(arg) || containsProdType(res) - } - - def split_vars(start: int, t: Type_coords): Pair[Pair[int, Renaming], Type_coords] = { - /** - * Take a coordinate and return a copy with type variables renamed and - * keeping track of the renaming. - */ - def shift_compact_vars(p: Pair[int, Renaming], t: MLType) : Pair[Pair[int, Renaming], MLType] = { - if (containsProdType(t)) - Console.println("SPLIT_VARS: " + t); - val Pair(start, ren) = p; - t match { - case TypeVar(n) => - if (ren.contains(n)) - Pair(Pair(start, ren), TypeVar(ren(n))) - else - Pair(Pair(start + 1, ren.incl(Pair(n, start))), TypeVar(start)) - case UnitType => Pair(p, t) - case FunType(arg, res) => { - val Pair(Pair(new_start, new_ren), new_arg) = shift_compact_vars(Pair(start, ren), arg); - val Pair(q, new_res) = shift_compact_vars(Pair(new_start, new_ren), res); - Pair(q, FunType(new_arg, new_res)) - } - case AtomicType(c, args) => { - val Pair(p, new_args) = fold(args, Pair(start, ren), shift_compact_vars); - Pair(p, AtomicType(c, new_args)) - } - } - } - def shifter(p: Pair[int, Renaming], coord: MLType): Pair[Pair[int, Renaming], MLType] = { - val Pair(start, ren) = p; - val Pair(Pair(new_start, local_ren), new_coord) = - shift_compact_vars(Pair(start, ListMap.Empty), coord); - Pair(Pair(new_start, ren incl local_ren), new_coord) - } - - val Pair(len, coords) = t; - val Pair(p, ren_coords) = fold(coords, Pair(start, ListMap.Empty[int, int]), shifter); - Pair(p, Pair(len , ren_coords)) - } - - def splitRewrite(start: int, t: MLType): Pair[Pair[int, Renaming], Type_coords] = - split_vars(start, rewriteType(t)); - - /////////////// FUNCTIONAL TYPE FLATENING //////////////// - - type Head_type = Pair[int, MLType]; - // type Flat_type = Pair[Head_type, List[Flat_type]]; - trait Flat_type ; - case class Fl(res: Head_type, args: List[Flat_type]) extends Flat_type; - - def flatten (t: MLType): Flat_type = t match { - case FunType(args1, FunType(args2, res)) => { - val f1 = flatten(args1); - val f2 = flatten(args2); - val Fl(Pair(len, head), tail) = flatten(res); - Fl(Pair(len + 2, head), f1 :: f2 :: tail) - } - case FunType(args,res) => Fl(Pair(1, res), List(flatten(args))) - case _ => Fl(Pair(0, t), List()); - } - - ////////////// PERMUTATIONS /////////////////// - - def perms[a](l: List[a]): List[List[a]] = { - def insert(y: a)(l: List[a]): List[List[a]] = - l match { - case List() => List(List(y)) - case x :: xs => (y :: l) :: (insert(y)(xs) map { ys => x :: ys }) - } - l match { - case List() => List(List()) - case x :: xs => perms(xs) flatMap insert(x) - } - } - - ///////////////// FUNCTIONAL TYPE UNIFICATION //////////////// - - /** Global renaming. */ - var globalRen: Renaming = ListMap.Empty; - - def rename_var(x1: int, x2: int): boolean = - Pair(globalRen.get(x1), globalRen.get(x2)) match { - case Pair(Some(y1), Some(y2)) => y1 == x2 - case Pair(None, None) => { - globalRen = globalRen.incl(Pair(x1, x2), Pair(x2, x1)); - true - } - case _ => false - } - - def unify_LC (f1: Flat_type, f2: Flat_type): boolean = { - val Fl(Pair(len1, res1), args1) = f1; - val Fl(Pair(len2, res2), args2) = f2; - if(len1 != len2) - false - else { - val saved_renaming = globalRen; - if (unify_head(res1, res2)) - unify_list(args1, args2) - else { - globalRen = saved_renaming; - false - } - } - } - - case object UnifyHeadExc extends Exception; - - def unify_head(t1: MLType,t2: MLType): boolean = { - def unify_rec(p: Pair[MLType, MLType]): unit = p match { - case Pair(UnitType, UnitType) => () - case Pair(TypeVar(n), TypeVar(m)) => - if (rename_var(n,m)) - () - else - throw UnifyHeadExc - case Pair(_, TypeVar(_)) => throw UnifyHeadExc; - case Pair(TypeVar(_), _) => throw UnifyHeadExc; - case Pair(AtomicType(c1, args1), AtomicType(c2, args2)) => - if (c1 sameAs c2) - (args1 zip args2) foreach unify_rec - else - throw UnifyHeadExc - case _ => throw UnifyHeadExc - } - try{ - unify_rec(Pair(t1, t2)); - true - } - catch { - case UnifyHeadExc => false - } - } - - case object FoundExc extends Exception; - - def unify_list(fs1: List[Flat_type], fs2: List[Flat_type]): boolean = { - try{ - perms(fs1) foreach { - fs => { - val saved_renaming = globalRen; - unify_map(fs, fs2); - globalRen = saved_renaming; - } - } - false - } - catch { - case FoundExc => true; - } - } - - def unify_map (fs1: List[Flat_type], fs2: List[Flat_type]): boolean = - Pair(fs1, fs2) match { - case Pair(List(), List()) => throw FoundExc - case Pair(a :: resta, b :: restb) => - if (unify_LC(a, b)) - unify_map (resta, restb) - else - false - } - - def unify_left_commutative(f1: Flat_type, f2: Flat_type): Pair[boolean, Renaming] = { - globalRen = ListMap.Empty; - val unifiable = unify_LC(f1, f2); - Pair(unifiable, globalRen) - } - - def findiso(fs: List[Flat_type], f: Flat_type): Triple[Boolean, List[Flat_type], Renaming] = - fs match { - case List() => Triple(false, List(), ListMap.Empty) - case g :: gs => { - val Pair(unifiable, ren) = unify_left_commutative(f, g); - if (unifiable) - Triple(true, gs, ren) - else { - val Triple(b, rest, ren) = findiso(gs, f); - Triple(b, g :: rest, ren) - } - } - } - - def quadratic_test(a: List[Flat_type], b: List[Flat_type]): Option[Renaming] = { - var renaming: Renaming = ListMap.Empty; - def q_test(a: List[Flat_type], b: List[Flat_type]): Option[Renaming] = - Pair(a,b) match { - case Pair(List(), List()) => Some(renaming) - case Pair(List(), _) => None - case Pair(_, List()) => None - case Pair(fs, g :: gs) => { - val Triple(b, rest, ren) = findiso(fs, g); - if (b) { - renaming = ren incl renaming; - q_test(rest, gs) - } - else - None - } - } - q_test(a, b) - } - - def iso(a: MLType): MLType => Triple[Option[Renaming], Renaming, Renaming] = { - val Pair(Pair(start_a, ren_a), Pair(len_a, coords_a)) = splitRewrite(1, a); - val flat_coords_a = coords_a map flatten; - { - b => { - val Pair(Pair(_, ren_b), Pair(len_b, coords_b)) = splitRewrite(start_a, b); - if (len_a != len_b) - Triple(None, ren_a, ren_b) - else{ - val flat_coords_b = coords_b map flatten; - Triple(quadratic_test(flat_coords_a, flat_coords_b), ren_a, ren_b) - } - } - } - } - - def build_renaming(ren_unif: Renaming, ren_a: Renaming, ren_b: Renaming): Renaming = { - def ren_builder(r: Renaming, ren_a: Renaming)(key: int, value: int) = ren_a(r(value)); - def inverse(ren: Renaming): Renaming = (ren foldLeft (ListMap.Empty: Renaming)) { - (ren_inv, p) => (ren_inv + p._2 -> p._1) - } - ren_b map (ren_builder(ren_unif, inverse(ren_a))) - } - - def printIso(t: MLType,u: MLType): unit = { - Console.println("TEST ISO"); - Console.println(t.toString()); - Console.println(u.toString()); - iso(t)(u) match { - case Triple(None, _, _) => - Console.println("Not isomorphic."); - case Triple(Some(ren_unif), ren_a, ren_b) => { - Console.println("Isomorphic:"); - val response = rename_type(build_renaming(ren_unif, ren_a, ren_b))(u); - Console.println(response.toString()); - } - } - } - - } - - class ScalaML(global: Global) extends ML with TypeIsomorphism { - - class ScalaTC(sym: Symbol) extends TypeConstructor[ScalaTC] { - val symbol: Symbol = sym; - def sameAs(that: ScalaTC): boolean = (symbol == that.symbol); - override def toString(): String = symbol.nameString(); - } - - type TC = ScalaTC; - - /** Build a product type from a list of types. */ - def mkProd(l: List[MLType]): MLType = l match { - case List() => UnitType - case t :: List() => t - case t :: ts => ProdType(t, mkProd(ts)) - } - - ////////////////////// TESTS ///////////////////// - - /** Test if this type is "scala.Unit". */ - def is_scala_Unit(t: Type): boolean = - t.symbol() == Global.instance.definitions.UNIT_CLASS; - - /** Test if this type is "scala.Tuple_n[T_1, ..., T_n]". */ - def is_scala_Tuple(t: Type): boolean = { - val tuples = Global.instance.definitions.TUPLE_CLASS; - val arity = t.typeArgs().length; - arity < tuples.length && t.symbol() == tuples(arity); - } - - /** Test if this type is "scala.Function_n[T_1, ..., T_n, T]". */ - def is_scala_Function(t: Type): boolean = { - val functions = Global.instance.definitions.FUNCTION_CLASS; - val arity = t.typeArgs().length - 1; - 0 <= arity && arity < functions.length && t.symbol() == functions(arity); - } - - /** Test if this type is a local variable */ - def is_localVariable(t: Type): boolean = - t.symbol().isAbstractType() && t.symbol().isParameter(); - - case object TranslateExc extends Exception; - - /** Try to translate a Scala type into an ML type. */ - def translate(t: Type): Option[Pair[MLType, Map[Symbol, int]]] = { - - // global renaming - var renaming: Map[Symbol, int] = ListMap.Empty; - def renamed(sym: Symbol) = - if (renaming.contains(sym)) - renaming(sym) - else { - val len = renaming.size; - renaming = renaming.incl(Pair(sym, len)); - len - } - - def listOfArray[a](r: Array[a]): List[a] = - List.fromArray(r, 0, r.length); - - def trans(t: Type): MLType = - // scala.Unit - if (is_scala_Unit(t)) - UnitType - // scala.Tuple_n[T_1, ..., T_n] - else if (is_scala_Tuple(t)) - t match { - case Type$TypeRef(_, _, args) => mkProd(listOfArray(args) map trans) - } - // scala.Function_n[T_1, ..., T_n, T] - else if (is_scala_Function(t)) - t match { - case Type$TypeRef(_, _, args) => { - val params = listOfArray(args); - FunType(mkProd(params.init map trans), trans(params.last)) - } - } - // local variable - else if (is_localVariable(t)) - TypeVar(renamed(t.symbol())) - else - t match { - // ex: scala.List[int] - case Type$TypeRef(_, sym, args) => - AtomicType(new TC(sym), listOfArray(args) map trans_atomic) - // [a_1, ..., a_n] T - case Type$PolyType(tparams, result) => trans(result) - // (T_1, ..., T_n) => T - case Type$MethodType(vparams, result) => - FunType(mkProd(listOfArray(vparams) map { x => trans(x.getType()) }), trans(result)) - // Types that do not have ML equivalents. - case _ => throw TranslateExc - } - def trans_atomic(t: Type): MLType = - if (is_localVariable(t)) - TypeVar(renamed(t.symbol())) - else - t match { - // ex: scala.List[int] - case Type$TypeRef(_, sym, args) => - AtomicType(new TC(sym), listOfArray(args) map trans_atomic) - case _ => throw TranslateExc - } - try { - val ml_t = trans(t); - Some(Pair(ml_t, renaming)) - } - catch { - case e => { - // Console.println(e.toString()); - None - } - } - } - - def translateAndPrint(t: Type): String = translate(t).toString(); - - def isMLType(t: Type): boolean = translate(t) match { - case None => false - case _ => true - } - - def arrayOfList(l: List[Symbol]): Array[Symbol] = { - val a = new Array[Symbol](l.length); - (l foldLeft 0) { (i, x) => { a(i) = x; i + 1 } }; - a - } - - def stringOfArray(a: Array[Symbol]): String = { - val buf = new StringBuffer(); - for(val i <- List.range(0, a.length)) buf.append(a(i).toString() + ", "); - buf.toString() - } - - def foreach(a: Array[Symbol])(f: Symbol => Symbol): Array[Symbol] = { - val b = new Array[Symbol](a.length); - for(val i <- List.range(0, a.length)) b(i) = f(a(i)); - b - } - - def subst(t: Type, ren: Map[Symbol, Symbol]): Type = { - val Pair(from, to) = List.unzip(ren.toList); - val from_array = arrayOfList(from); - val to_array = arrayOfList(to); - def subst_aux(t: Type): Type = t match { - case Type$PolyType(tparams, result) => { - val substTparams = foreach(tparams) { sym => ren(sym) }; - new Type$PolyType(substTparams, subst_aux(result)) - } - case _ => t.subst(from_array, to_array) - } - val substType = subst_aux(t); - substType - } - - def searchIso(search: Type): Option[Type => Option[Map[Symbol, Symbol]]] = - translate(search) match { - case None => None - case Some(Pair(search_ml, ren_search)) => { - val iso_search = iso(search_ml); - def comp(found: Type): Option[Map[Symbol, Symbol]] = translate(found) match { - case None => None - case Some(Pair(found_ml, ren_found)) => - iso_search(found_ml) match { - case Triple(None, _, _) => None - case Triple(Some(ren_unif), ren_a, ren_b) => { - val ren_ml = build_renaming(ren_unif, ren_a, ren_b); - val ren = scalaRenaming(ren_ml, ren_search, ren_found); - Some(ren) - } - } - } - Some(comp) - } - } - - def inverseMap[a,b](map: Map[a,b]): Map[b,a] = - (map foldLeft (ListMap.Empty: Map[b,a])) { - (map_inv, p) => (map_inv + p._2 -> p._1) - } - - def composeMap[a,b,c](map1: Map[a,b], map2: Map[b,c]): Map[a,c] = - (map1 foldLeft (ListMap.Empty: Map[a,c])) { - (map_inv, p) => - if (map2.contains(p._2)) - (map_inv + p._1 -> map2(p._2)) - else - map_inv - } - - /** - * Build the renaming to represent the matching type with same - * type variables as in the request type. - */ - def scalaRenaming(ren_unif: Map[int, int], ren_search: Map[Symbol, int], ren_found: Map[Symbol, int]): Map[Symbol, Symbol] = - composeMap(ren_found, composeMap(ren_unif, inverseMap(ren_search))); - - def mkTypeVar(sym: Symbol): Type = - Type.typeRef(Type.NoPrefix, sym, Type.EMPTY_ARRAY); - - def addParamTypes(paramTypes: Array[Type], t: Type): Type = t match { - case Type$PolyType(tparams, result) => new Type$PolyType(tparams, addParamTypes(paramTypes, result)) - case Type$MethodType(vparams, result) => new Type$MethodType(vparams, addParamTypes(paramTypes, result)) - case _ => global.definitions.FUNCTION_TYPE(paramTypes, t) - } - - def addClassContext(clazz: Symbol, t: Type): Type = { - val class_tparam_symbols: Array[Symbol] = clazz.typeParams(); - val class_tparams: Array[Type] = new Array[Type](class_tparam_symbols.length); - for(val i <- List.range(0, class_tparams.length)) - class_tparams(i) = mkTypeVar(class_tparam_symbols(i)); - val class_type = Type.appliedType(clazz.typeConstructor(), class_tparams); - val paramTypes = new Array[Type](1); - paramTypes(0) = class_type; - t match { - case Type$PolyType(tparams, result) => { - val all_tparams = new Array[Symbol](class_tparam_symbols.length + tparams.length); - for(val i <- List.range(0, class_tparam_symbols.length)) all_tparams(i) = class_tparam_symbols(i); - for(val i <- List.range(0, tparams.length)) all_tparams(i + class_tparam_symbols.length) = tparams(i); - new Type$PolyType(all_tparams, addParamTypes(paramTypes, result)) - } - case _ => new Type$PolyType(class_tparam_symbols, addParamTypes(paramTypes, t)) - } - } - - /** Implement type isomorphism. */ - def searchType(t: Type, isDocumented: SymbolBooleanFunction): java.util.Iterator/*[Pair[Symbol, Type]]*/ = { - val found = new java.util.LinkedList; - searchIso(t) match { - case None => {} - case Some(test) => { - val rootNode: node.T = node.make(isDocumented)(global.definitions.ROOT_CLASS).head; - def searchInModule(m: node.T): unit = m.members foreach { - member => - if (member.symbol.isClass()) - searchInClass(member) - else if (member.symbol.isTerm()) { - test(member.symbol.getType()) match { - case None => {} - case Some(ren) => { - val adaptedType = subst(member.symbol.getType(), ren); - val result = new SearchResult(member.symbol, - adaptedType, - false, - null); - - found.add(result) - } - } - if (member.symbol.isPackage() || member.symbol.isPackageClass() || member.symbol.isModule()) - searchInModule(member) - } - } - def searchInClass(m: node.T): unit = m.members foreach { - member => - if (member.symbol.isTerm()) { - val extended_type = addClassContext(m.symbol, member.symbol.getType()); - test(extended_type) match { - case None => {} - case Some(ren) => { - val adaptedType = subst(member.symbol.getType(), ren); - val adaptedTparams = foreach(m.symbol.typeParams()) { sym => ren(sym) }; - val result = new SearchResult(member.symbol, - adaptedType, - true, - adaptedTparams); - found.add(result) - } - } - } - } - searchInModule(rootNode); - } - }; - found.iterator() - } - } - - object node { - - def listOfArray[a](r: Array[a]): List[a] = - List.fromArray(r, 0, r.length); - - /** Documentation node. */ - trait T { - val symbol: Symbol; - def members: List[T]; - } - - /** Build a node from a root symbol. */ - def make(isDocumented: SymbolBooleanFunction)(root: Symbol): List[T] = - if (ScalaSearch.isRelevant(root) && isDocumented.apply(root)) - List(new T { - val symbol = root; - def members: List[T] = listOfArray(ScalaSearch.members(root, isDocumented)) flatMap make(isDocumented); - }) - else - List(); - } - -} - - /* - object stringML extends ML with Application { - - class StringTC(s: String) extends TypeConstructor[StringTC] { - val name: String = s; - def sameAs(that: StringTC): boolean = name.equals(that.name); - override def toString(): String = name; - } - - type TC = StringTC; - - val list = new TC("List"); - val t = (at(list, x(11)) * (x(11) -> x(12))) -> at(list, x(12)); - val u = (x(13) -> x(14)) -> (at(list, x(13)) -> at(list, x(14))); - printIso(t, u); - } - */ - diff --git a/sources/scala/tools/scaladoc/Main.scala b/sources/scala/tools/scaladoc/Main.scala deleted file mode 100644 index f05b86fd84..0000000000 --- a/sources/scala/tools/scaladoc/Main.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -import scalac.{Global => scalac_Global}; -import scala.tools.scalac.{Global, CompilerPhases}; -import scala.tools.util.ConsoleReporter; - -package scala.tools.scaladoc { - -/** - * The main class for scaladoc, an HTML documentation generator - * for the programming language Scala. - * - * @author Vincent Cremet, Stephane Micheloud - * @version 1.0 - */ -object Main { - - val PRODUCT: String = - System.getProperty("scala.product", "scaladoc"); - val VERSION: String = - System.getProperty("scala.version", "1.0"); - - def main(args: Array[String]): Unit = { - val reporter = new ConsoleReporter(); - val phases = new CompilerPhases(); { - // we skip all phases between ANALYZER and TERMINAL. - val array = phases.phases(); - var i = 0; - var skip = false; - while (i < array.length - 1) { - if (skip) - array(i).addSkipFlag(); - else - skip = array(i) == phases.ANALYZER; - i = i + 1; - } - } - val command = new HTMLGeneratorCommand(PRODUCT, VERSION, reporter, phases); - if (command.parse(args) && command.files.list.size() > 0) { - val global = new Global(command); - global.compile(command.files.toArray(), false); - if (reporter.errors() == 0) { - val generator = new HTMLGenerator(global) { - def newTypeIso(global: scalac_Global): TypeIsomorphism = - new ScalaML(global); - } - generator.apply(); - } - reporter.printSummary(); - } - // System.exit(if (reporter.errors() > 0) 1 else 0); - } - -} -} diff --git a/sources/scala/tools/scaladoc/Page.java b/sources/scala/tools/scaladoc/Page.java deleted file mode 100644 index c9d4d2005c..0000000000 --- a/sources/scala/tools/scaladoc/Page.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.io.File; -import java.net.URI; -import java.io.Writer; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import ch.epfl.lamp.util.XMLAttribute; -import ch.epfl.lamp.util.HTMLPrinter; -import ch.epfl.lamp.util.HTMLRepresentation; -import scalac.util.Debug; - -/** - * This class represents a web page. The user of this class has to - * call the method <code>open</code>, then fill the page and finally - * call the method <code>close</code>. - */ -class Page extends HTMLPrinter { - - /** Page URL relative to the root directory. - */ - URI uri; - - /** Frame where to print the contents of links that appear on the - * page. - */ - public String destinationFrame; - - /** Build a page. - */ - public Page(Writer writer, URI uri, String destinationFrame, - String title, HTMLRepresentation representation, - String stylesheet, String script) { - super(writer, title, representation, stylesheet, script); - this.uri = uri; - this.destinationFrame = destinationFrame; - } - - /** Open the page. - */ - public void open() {} - - /** Close the page. - */ - public void close() { - try { - getCodePrinter().getWriter().close(); - } catch (IOException e) { - throw Debug.abort(e); - } - } -} diff --git a/sources/scala/tools/scaladoc/ScalaSearch.java b/sources/scala/tools/scaladoc/ScalaSearch.java deleted file mode 100644 index 1d2f423eff..0000000000 --- a/sources/scala/tools/scaladoc/ScalaSearch.java +++ /dev/null @@ -1,603 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.HashSet; - -import ch.epfl.lamp.util.Pair; - -import scala.tools.util.SourceFile; - -import scalac.Global; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Modifiers; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.NameTransformer; - -import java.io.*; -import scala.tools.scalac.ast.parser.Parser$class; -import scalac.CompilationUnit; - -/** - * This class contains functions to retrieve information from a Scala - * library. - */ -public class ScalaSearch { - - /////////////////// SYMBOLS TESTERS //////////////////////////// - - /** Test if the given symbol is a class, a package, or an object. - */ - static boolean isContainer(Symbol sym) { - return sym.isClass() || sym.isModule() || sym.isPackage() || sym.isPackageClass(); - } - - /** Test if the given symbol has a lazy type. - */ - static boolean isLazy(Symbol sym) { - return - (sym.rawInfo() instanceof Type.LazyType) || - ((sym.rawInfo() instanceof Type.TypeRef) && - (sym.rawInfo().symbol().rawInfo() instanceof Type.LazyType)); - } - - /** Test if the given symbol is private (without evaluating its type). - */ - static boolean isPrivate(Symbol sym) { - return (sym.flags & Modifiers.PRIVATE) != 0; - } - - /** Test if the given symbol has been generated by the compiler. - */ - public static boolean isGenerated(Symbol sym) { - return - (sym.isSynthetic() && !sym.isRoot()) || - (sym.name.indexOf('$') >= 0 && - NameTransformer.decode(sym.name).equals(sym.name.toString())) || - NameTransformer.decode(sym.name).endsWith("_="); - } - - /** Test if the given symbol is an empty java module generated to - * contain static fields and methods of a java class. - */ - public static boolean isEmptyJavaModule(Symbol sym) { - return sym.isModule() && sym.isJava() && !(sym.isPackage() || sym.isPackageClass()) && (members(sym).length == 0); - } - - /** Test if the given symbol is access method for a val. - */ - public static boolean isValMethod(Symbol sym) { - return (sym.isInitializedMethod() && (sym.flags & Modifiers.STABLE) != 0); - } - - /** Test if the given symbol is a phantom top-level class or object. - */ - public static boolean isPhantom(Symbol sym) { - return - (sym.isClass() && sym.info().isError()) || - (sym.isModule() && sym.info() == Type.NoType); - } - - /** Test if the given symbol is relevant for the documentation. - */ - public static boolean isRelevant(Symbol sym) { - return !isGenerated(sym) && !isLazy(sym) && !isPrivate(sym) && - !sym.isConstructor() && - !sym.isCaseFactory() && !isEmptyJavaModule(sym) && - !isPhantom(sym); - } - - ////////////////////////// SCOPE ITERATOR /////////////////////////////// - - static class LazySymbolIterator extends SymbolIterator { - private Symbol[] alternatives = Symbol.EMPTY_ARRAY; - private int altindex = 0; - private int elemindex = 0; - - private Scope scope; - - public LazySymbolIterator(Scope scope) { - this.scope = scope; - scope.elements(); - } - - public boolean hasNext() { - return altindex < alternatives.length || - elemindex < scope.getElemsCache().length; - } - - public Symbol next() { - if (altindex < alternatives.length) - return alternatives[altindex++]; - else { - Symbol sym = scope.getElemsCache()[elemindex++]; - if (isLazy(sym)) - return sym; - else { - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): - alternatives = alts; - altindex = 0; - return next(); - default: - return sym; - } - } - } - } - } - - ////////////////////////// TRAVERSER /////////////////////////////// - - /** Function from Symbol to void. - */ - public static abstract class SymFun { - public abstract void apply(Symbol sym); - } - - /** Apply a given function to all symbols below the given symbol - * in the symbol table. - */ - public static void foreach(Symbol sym, SymFun fun) { - if (isRelevant(sym)) { - fun.apply(sym); - Symbol[] members = members(sym); - for(int i = 0; i < members.length; i++) - foreach(members[i], fun); - } - } - - /** Return all members of a container symbol. - */ - public static Symbol[] members(Symbol sym) { - if (isContainer(sym) && !isLazy(sym)) { - List memberList = new LinkedList(); - SymbolIterator i = - new LazySymbolIterator(sym.members()); - //sym.members().iterator(); - while (i.hasNext()) { - Symbol member = i.next(); - if (isRelevant(member)) - memberList.add(member); - } - return (Symbol[]) memberList.toArray(new Symbol[memberList.size()]); - } - else - return new Symbol[0]; - } - - /** Apply a given function to all symbols below the given symbol - * in the symbol table. - */ - public static void foreach(Symbol sym, SymFun fun, - SymbolBooleanFunction isDocumented) { - if (isDocumented.apply(sym) && isRelevant(sym)) { - fun.apply(sym); - Symbol[] members = members(sym, isDocumented); - for(int i = 0; i < members.length; i++) - foreach(members[i], fun, isDocumented); - } - } - - /** Return all members of a container symbol. - */ - public static Symbol[] members(Symbol sym, - SymbolBooleanFunction isDocumented) { - if (isContainer(sym) && !isLazy(sym)) { - List memberList = new LinkedList(); - SymbolIterator i = - new LazySymbolIterator(sym.members()); - //sym.members().iterator(); - while (i.hasNext()) { - Symbol member = i.next(); - if (isDocumented.apply(member) && isRelevant(sym)) - memberList.add(member); - } - return (Symbol[]) memberList.toArray(new Symbol[memberList.size()]); - } - else - return new Symbol[0]; - } - - ///////////////////////// COMPARATORS /////////////////////////////// - - /** - * Use the simple name of symbols to order them. - */ - public static Comparator symAlphaOrder = new Comparator() { - public int compare(Object o1, Object o2) { - Symbol symbol1 = (Symbol) o1; - Symbol symbol2 = (Symbol) o2; - String name1 = symbol1.nameString(); - String name2 = symbol2.nameString(); - return name1.compareTo(name2); - } - public boolean equals(Object o) { - return false; - } - }; - - /** - * Use the fully qualified name of symbols to order them. - */ - public static Comparator symPathOrder = new Comparator() { - public int compare(Object o1, Object o2) { - int c = compare0(o1, o2); - return c; - } - public int compare0(Object o1, Object o2) { - LinkedList l1 = getOwners((Symbol)o1); - LinkedList l2 = getOwners((Symbol)o2); - for (int i = 0; true; i++) { - if (i == l1.size() || i == l2.size()) - return l1.size() - l2.size(); - Symbol s1 = (Symbol)l1.get(i); - Symbol s2 = (Symbol)l2.get(i); - if (s1 == s2) continue; - int c = s1.nameString().compareTo(s2.nameString()); - if (c != 0) return c; - if (s1.isTerm() && s2.isType()) return -1; - if (s1.isType() && s2.isTerm()) return +1; - return s1.id - s2.id; - } - } - public boolean equals(Object o) { - return false; - } - public LinkedList getOwners(Symbol symbol) { - LinkedList owners = new LinkedList(); - while (true) { - assert !symbol.isNone() && !symbol.isError(); - owners.addFirst(symbol); - if (symbol.isRoot()) break; - if (symbol.isNone()) break; - if (symbol.isError()) break; - symbol = symbol.owner(); - } - return owners; - } - }; - - ///////////////////////// COLLECTORS //////////////////////////// - - /** - * Returns the sorted list of packages from the root symbol. - * - * @param root - */ - public static Symbol[] getSortedPackageList(Symbol root, SymbolBooleanFunction isDocumented) { - final List packagesAcc = new LinkedList(); - foreach(root, - new SymFun() { - public void apply(Symbol sym) { - if (sym.isPackage() || sym.isPackageClass()) - packagesAcc.add(sym); - } - }, isDocumented); - Symbol[] packages = (Symbol[]) packagesAcc.toArray(new Symbol[packagesAcc.size()]); - Arrays.sort(packages, symPathOrder); - return packages; - } - - public static Symbol[][] getSubContainerMembers(Symbol root, SymbolBooleanFunction isDocumented) { - final List objectsAcc = new LinkedList(); - final List traitsAcc = new LinkedList(); - final List classesAcc = new LinkedList(); - foreach(root, - new SymFun() { - public void apply(Symbol sym) { - if (sym.isTrait() && !sym.isModuleClass()) - traitsAcc.add(sym); - else if (sym.isClass() && !sym.isModuleClass()) - classesAcc.add(sym); - else if (sym.isModule() && !(sym.isPackage() || sym.isPackageClass())) - objectsAcc.add(sym); - } - }, isDocumented - ); - Symbol[] objects = (Symbol[]) objectsAcc.toArray(new Symbol[objectsAcc.size()]); - Symbol[] traits = (Symbol[]) traitsAcc.toArray(new Symbol[traitsAcc.size()]); - Symbol[] classes = (Symbol[]) classesAcc.toArray(new Symbol[classesAcc.size()]); - Arrays.sort(objects, symAlphaOrder); - Arrays.sort(traits, symAlphaOrder); - Arrays.sort(classes, symAlphaOrder); - return new Symbol[][]{ objects, traits, classes }; - } - - public static Symbol[][] splitMembers(Symbol[] syms) { - List fields = new LinkedList(); - List methods = new LinkedList(); - List objects = new LinkedList(); - List traits = new LinkedList(); - List classes = new LinkedList(); - List packages = new LinkedList(); - for (int i = 0; i < syms.length; i++) { - Symbol sym = syms[i]; - if (sym.isTrait()) traits.add(sym); - else if (sym.isClass()) classes.add(sym); - else if (sym.isPackage() || sym.isPackageClass()) packages.add(sym); - else if (sym.isModule()) objects.add(sym); - else if (sym.isMethod() && !isValMethod(sym)) methods.add(sym); - else fields.add(sym); - } - return new Symbol[][] { - (Symbol[]) fields.toArray(new Symbol[fields.size()]), - (Symbol[]) methods.toArray(new Symbol[methods.size()]), - (Symbol[]) objects.toArray(new Symbol[objects.size()]), - (Symbol[]) traits.toArray(new Symbol[traits.size()]), - (Symbol[]) classes.toArray(new Symbol[classes.size()]), - (Symbol[]) packages.toArray(new Symbol[packages.size()]) - }; - } - - public static void categorizeSymbols(List symbols, List fields, List modules, List types) { - Iterator i = symbols.iterator(); - while (i.hasNext()) { - Symbol sym = (Symbol) i.next(); - if (sym.isPackage() || sym.isPackageClass() || sym.isModule()) - modules.add(sym); - else if (sym.isTerm()) - fields.add(sym); - else - types.add(sym); - } - } - - public static Symbol[] sortList(List symbols) { - Symbol[] array = (Symbol[]) symbols.toArray(new Symbol[symbols.size()]); - Arrays.sort(array, symAlphaOrder); - return array; - } - - /////////////////// IMPLEMENTING CLASSES OR OBJECTS ////////////////////// - - /** - * Returns a hashtable which maps each class symbol to the list of - * its direct sub-classes or sub-modules. We also keep track of - * the exact involved type. - * Result type = Map<Symbol, List<Pair<Symbol, Type>> - * - * @param root - */ - public static Map subTemplates(Symbol root, SymbolBooleanFunction isDocumented) { - final Map subs = new HashMap(); - foreach(root, new SymFun() { public void apply(Symbol sym) { - if (sym.isClass() || sym.isModule()) { - Type[] parents = (sym.isModule() ? sym.moduleClass(): sym).parents(); - for (int i = 0; i < parents.length; i++) { - Symbol parentSymbol = parents[i].symbol(); - List subList = (List) subs.get(parentSymbol); - if (subList == null) { - subList = new LinkedList(); - subs.put(parentSymbol, subList); - } - subList.add(new Pair(sym, parents[i])); - } - } - } - }, isDocumented); - return subs; - } - - //////////////////////// INDEX BUILDER ///////////////////////////// - - /** - * Returns the list of characters with the sorted list of - * members starting with a character. - * Result type = Pair<Character[], Map<Character, Symbol[]>> - * - * @param root - */ - public static Pair index(Symbol root, final SymbolBooleanFunction isDocumented) { - final Map index = new HashMap(); - // collecting - foreach(root, new SymFun() { public void apply(Symbol sym) { - String name = sym.nameString(); - if (name.length() > 0) { - char ch = Character.toUpperCase(name.charAt(0)); - Character unicode = new Character(ch); - List symList = (List) index.get(unicode); - if (symList == null) { - symList = new LinkedList(); - index.put(unicode, symList); - } - symList.add(sym); - } - } - }, isDocumented); - // sorting - Character[] chars = (Character[]) index.keySet() - .toArray(new Character[index.keySet().size()]); - Arrays.sort(chars); - for (int i = 0; i < chars.length; i++) { - Character car = chars[i]; - List symList = (List) index.get(car); - Symbol[] syms = (Symbol[]) symList.toArray(new Symbol[symList.size()]); - Arrays.sort(syms, symAlphaOrder); - index.put(car, syms); - } - return new Pair(chars, index); - } - - //////////////////////////// INHERITED MEMBERS ////////////////////////////// - - /** - * Finds all local and inherited members of a given class or - * object. - * - * @param sym - */ - public static Symbol[] collectMembers(Symbol sym) { - Type thistype = sym.thisType(); - Name[] names = collectNames(thistype); - List/*<Symbol>*/ members = new LinkedList(); - for (int i = 0; i < names.length; i++) { - Symbol member = thistype.lookup(names[i]); - if (member != Symbol.NONE) - members.add(member); - } - List unloadedMembers = new LinkedList(); - Iterator it = members.iterator(); - while (it.hasNext()) { - Symbol[] alts = ((Symbol) it.next()).alternativeSymbols(); - for (int i = 0; i < alts.length; i++) - if (isRelevant(alts[i])) - unloadedMembers.add(alts[i]); - } - return (Symbol[]) unloadedMembers.toArray(new Symbol[unloadedMembers.size()]); - } - - // where - protected static Name[] collectNames(Type tpe) { - List names = new LinkedList(); - collectNames(tpe, names); - return (Name[]) names.toArray(new Name[names.size()]); - } - - // where - protected static void collectNames(Type tpe, List/*<Name>*/ names) { - // local members - SymbolIterator it = - new LazySymbolIterator(tpe.members()); - //tpe.members().iterator(); - while (it.hasNext()) { - Name name = ((Symbol) it.next()).name; - if (!names.contains(name)) - names.add(name); - } - // inherited members - Type[] parents = tpe.parents(); - for (int i = 0; i < parents.length; i++) - collectNames(parents[i], names); - } - - /** - * Groups symbols with respect to their owner and sort the owners - * by name. - * - * @param syms - */ - public static Pair/*<Symbol[], Map<Symbol, Symbol[]>>*/ groupSymbols(Symbol[] syms) { - Map/*<Symbol, List>*/ groups = new HashMap(); - for (int i = 0; i < syms.length; i++) { - List group = (List) groups.get(syms[i].owner()); - if (group == null) { - group = new LinkedList(); - groups.put(syms[i].owner(), group); - } - group.add(syms[i]); - } - Symbol[] owners = - (Symbol[]) groups.keySet().toArray(new Symbol[groups.keySet().size()]); - Arrays.sort(owners, symPathOrder); - for (int i = 0; i < owners.length; i++) { - List groupList = (List) groups.get(owners[i]); - Symbol[] group = - (Symbol[]) groupList.toArray(new Symbol[groupList.size()]); - Arrays.sort(group, symAlphaOrder); - groups.put(owners[i], group); - } - return new Pair(owners, groups); - } - - //////////////////////////// OVERRIDEN SYMBOL ////////////////////////////// - - public static Symbol overridenBySymbol(Symbol sym) { - Symbol owner = sym.owner(); - if (owner.isRoot() || owner.isPackageClass()) - return Symbol.NONE; - else { - Type base = Type.compoundTypeWithOwner(owner, - sym.owner().info().parents(), - Scope.EMPTY); - return sym.overriddenSymbol(base); - } - } - - ////////////////////////// POST TYPECHECKING //////////////////////// - - public static int queryCounter = 0; - - /** - * Parse a string representing a Scala type and resolve its - * symbols. This function must be called after the typechecking - * phase. If parsing or type checking fails, return Type.NoType. - */ - public static Type typeOfString(String typeString, Global global) { - int errorNumber = global.reporter.errors(); - String unitString = "trait tmp$" + queryCounter + - " extends Option[unit] { def f" + typeString + "; }"; - // Rem: we use a dummy extends clause, otherwise the compiler - // complains. - queryCounter = queryCounter + 1; - SourceFile sourceFile = global.getSourceFile("tmp.scala", unitString); - CompilationUnit tmpUnit = new CompilationUnit(global, sourceFile, false); - tmpUnit.body = new Parser$class(tmpUnit).parse(); - global.PHASE.NAMER.phase().apply(tmpUnit); - global.PHASE.ANALYZER.phase().apply(tmpUnit); - if (global.reporter.errors() == errorNumber) { - Scope tmpScope = tmpUnit.body[0].symbol().members(); - Type res = tmpScope.lookup(Name.fromString("f")).type(); - return res; - } - else - return Type.NoType; - } - -} - -//////////////////////////// DOCUMENTED SYMBOLS ////////////////////////////// - -/** Compute documented symbols. */ -public class DocSyms { - - Set syms; - - DocSyms(Global global, Symbol[] packages) { - syms = new HashSet(); - for(int i = 0; i < packages.length; i++) { - Symbol pack = packages[i]; - // add all sub-members. - ScalaSearch.foreach(pack, - new ScalaSearch.SymFun() { - public void apply(Symbol sym) { - syms.add(sym.isModule() ? sym.moduleClass() : sym); - } - } - ); - // add all super packages. - while (!pack.isRoot()) { - pack = pack.owner(); - syms.add(pack); - } - } - } - - public boolean contains(Symbol sym) { - if (sym.isParameter()) return contains(sym.classOwner()); - if (sym.isModule()) return contains(sym.moduleClass()); - return syms.contains(sym); - } -} - -public abstract class SymbolBooleanFunction { - public abstract boolean apply(Symbol sym); -} diff --git a/sources/scala/tools/scaladoc/StandardDocModule.java b/sources/scala/tools/scaladoc/StandardDocModule.java deleted file mode 100644 index 7b77f3f000..0000000000 --- a/sources/scala/tools/scaladoc/StandardDocModule.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import scalac.Global; -import scalac.CompilationUnit; -import scalac.symtab.Symbol; -import scalac.util.Debug; - -/** - * Phase which generates HTML documentation. - */ -public class StandardDocModule { - - private final Global global; - - /** - * Constructor - * - * @param globlal - */ - public StandardDocModule(Global global) { - super(); - this.global = global; - } - - /** - * .. - */ - public void apply() { - HTMLGenerator.apply(global); - } - - /** - * .. - * - * @param global - */ - public static void apply(Global global) { - new StandardDocModule(global).apply(); - } - -} diff --git a/sources/scala/tools/scaladoc/SymbolTablePrinter.java b/sources/scala/tools/scaladoc/SymbolTablePrinter.java deleted file mode 100644 index cfce384d9d..0000000000 --- a/sources/scala/tools/scaladoc/SymbolTablePrinter.java +++ /dev/null @@ -1,203 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.io.StringWriter; - -import ch.epfl.lamp.util.CodePrinter; -import ch.epfl.lamp.util.HTMLPrinter; - -import scalac.Global; -import scalac.atree.AConstant; -import scalac.symtab.*; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.Type.Constraint; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.NameTransformer; - -// Lines modified or added by Vincent are marked "vincent". - -/** - * This class provides methods to print symbols and types. - */ -public abstract class MySymbolTablePrinter extends SymbolTablePrinter { - - //######################################################################## - // Private Fields - - /** The global environment */ - protected final Global global; - - //######################################################################## - // Public Constructors - - /** - * Creates a new instance. - * - * @param page - */ - public MySymbolTablePrinter(CodePrinter printer) { - super(printer); - this.global = Global.instance; - } - - public abstract void printSymbol(Symbol sym, boolean addLink); - - //######################################################################## - // Public Methods - Printing symbols - - /** - * Prints the name of the given symbol usage. - * - * @param symbol - */ - public SymbolTablePrinter printSymbolName(Symbol symbol) { - printSymbol(symbol, true); - printSymbolUniqueId(symbol); - return this; - } - - /** - * Prints the name of the given symbol definition. - * - * @param symbol - * @param addLink - */ - public SymbolTablePrinter printDefinedSymbolName(Symbol symbol, boolean addLink) { - printSymbol(symbol, addLink); - printSymbolUniqueId(symbol); - return this; - } - - public SymbolTablePrinter printSeqType(Symbol symbol, Type t, String inner) { - Type type = t; - boolean star = false; - if ((symbol.flags & Modifiers.REPEATED) != 0 && - type.symbol() == global.definitions.SEQ_CLASS && - type.typeArgs().length == 1) - { - type = type.typeArgs()[0]; - star = true; - } - printType(type, inner); - if (star) print("*"); - return this; - } - - /** - * Writes the string representation of the signature of a definition. - * - * @param sym - * @param addLink Generates an hypertext reference if the parameter - * <code>addLink</code> is <code>true</code> - */ - public void defString(Symbol sym, boolean addLink) { - if (sym.isRoot()) - print("Root class"); - else if (sym.isClass() || sym.isModule()) - printTemplateSignature(sym, addLink); - else if (sym.isType() && !sym.isParameter()) - printShortSignature(sym, addLink); - else - printSignature(sym, addLink); - } - - public SymbolTablePrinter printSignature(Symbol symbol) { - return printSignature(symbol, false); - } - - /** - * Prints the signature of the given symbol. - * - * @param symbol - * @param addLink - */ - public SymbolTablePrinter printSignature(Symbol symbol, boolean addLink) { - return printShortSignature(symbol, addLink) - .printSymbolType(symbol, getSymbolInnerString(symbol)); - } - - public SymbolTablePrinter printValueParams(Symbol[] vparams) { - print('('); - for (int i = 0; i < vparams.length; i++) { - if (i > 0) print(", "); - defString(vparams[i], false); - } - return print(')'); - } - - /** The keyword of a symbol from the user side. */ - public String getSymbolKeywordForDoc(Symbol symbol) { - String keyword = getSymbolKeyword(symbol); - // accessor function for a val - if (symbol.isInitializedMethod() && symbol.hasStableFlag()) - keyword = "val"; - return keyword; - } - - /** - * Prints the signature of the given symbol. - * - * @param symbol - * @param addLink - */ - public SymbolTablePrinter printShortSignature(Symbol symbol, boolean addLink) { - String keyword = getSymbolKeywordForDoc(symbol); - if (keyword != null) print(keyword).space(); - // variance - if (symbol.variance() > 0) - print("+"); - else if (symbol.variance() < 0) - print("-"); - printSymbol(symbol, addLink); - return printType(symbol.loBound(), " >: "); - } - - /** - * Prints the signature of a class symbol. - * - * @param symbol - * @param addLink - * @return the current symbol table printer - */ - public SymbolTablePrinter printTemplateSignature(Symbol symbol, boolean addLink) { - // kind - String keyword = getSymbolKeywordForDoc(symbol); - if (keyword != null) print(keyword).space(); - String inner = getSymbolInnerString(symbol); - - // name - printDefinedSymbolName(symbol, addLink); - if (symbol.isClass()) { - // type parameters - Symbol[] tparams = symbol.typeParams(); - if (tparams.length != 0 || global.debug) printTypeParams(tparams); - // value parameters - Symbol[] vparams = symbol.valueParams(); - printValueParams(vparams); - } - - // parents -// Type[] parts = symbol.moduleClass().parents(); -// if (parts.length != 0) space().print(inner).space(); -// printTypes(parts," with "); - return this; - } - - //######################################################################## - // Public Methods - Printing constants - - /** Prints the given constant value. */ - public SymbolTablePrinter printConstantValue(AConstant value) { - return this; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java b/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java deleted file mode 100644 index c00dc1db77..0000000000 --- a/sources/scala/tools/scaladoc/SymbolTablePrinterFactory.java +++ /dev/null @@ -1,138 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import scalac.Global; -import scalac.symtab.Kinds; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Type.*; -import scalac.symtab.SymbolTablePrinter; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Strings; -import SymbolBooleanFunction; - -class SymbolTablePrinterFactory { - - public static MySymbolTablePrinter makeHTML(final HTMLGenerator htmlGenerator, - final Page page, - final SymbolBooleanFunction isDocumented) { - - return new MySymbolTablePrinter(page.getCodePrinter()) { - - public void printSymbol(Symbol sym, boolean addLink) { - String name = sym.nameString(); - // remove the leading "?" for names that come from attributes - if (name.startsWith("?")) - name = name.substring(1); - if (global.debug) name = sym.name.toString(); - if (isDocumented.apply(sym)) - if (addLink) - page.printAhref(htmlGenerator.definitionURI(sym, page).toString(), - page.destinationFrame, name); - else { - page.printOTag("em"); - page.print(name); - page.printCTag("em"); - } - else - page.print(name); - } - - public Type getTypeToPrintForPrefix(Type prefix/*, sym*/) { - while (true) { - Type result = getTypeToPrintForPrefix0(prefix); - if (result == prefix || result == null) { - return - cleanPrefix(result, global, isDocumented); - } - prefix = result; - } - } - - protected String INNER_LT = "<:"; - - public String getSymbolInnerString(Symbol symbol) { - if (symbol.kind == Kinds.TYPE) - return INNER_LT; // HTML encoded "<:" symbol - else - return super.getSymbolInnerString(symbol); - } - - public SymbolTablePrinter printType(Type type, String inner) { - if ((INNER_LT.equals(inner) && type.symbol() == global.definitions.ANY_CLASS) || - (" >: ".equals(inner) && type.symbol() == global.definitions.ALL_CLASS)) - return this; - else { - printType0(getTypeToPrintForType(type), inner); - return this; - } - } - }; - } - - /** - * Removes the longest prefix of this type which corresponds to a - * nested of class and object definitions. The idea is that this - * prefix is redondant and can be recovered directly from the tree - * itself. - * - * @param prefix - */ - static protected Type cleanPrefix(Type prefix, Global global, SymbolBooleanFunction isDocumented) { - if (prefix == null) return null; - if (prefix.symbol().kind == Kinds.NONE) return null; - if (prefix.symbol().isRoot()) return null; - - // Next line should be removed in theory. - if (prefix.symbol() == global.definitions.JAVALANG) return null; - - switch(prefix) { - case ThisType(Symbol sym): - if (sym.isPackageClass() && isDocumented.apply(sym)) - return null; - else if (isDocumented.apply(sym)) - return null; - else - return prefix; - case TypeRef(Type pre, Symbol sym, Type[] args): - Type pre1 = cleanPrefix(pre, global, isDocumented); - if (pre1 == null && args.length == 0 && isDocumented.apply(sym)) - return null; - else { - pre1 = pre1 == null ? global.definitions.ROOT_CLASS.thisType() : pre1; - return Type.typeRef(pre1, sym, args); - } - case SingleType(Type pre, Symbol sym): - Type pre1 = cleanPrefix(pre, global, isDocumented); - if (pre1 == null) { - if (sym.isClass() || sym.isModule()) - if (isDocumented.apply(sym)) { - return null; - } - else - return Type.singleType(global.definitions.ROOT_CLASS.thisType(), sym); - else - return Type.singleType(global.definitions.ROOT_CLASS.thisType(), sym); - } - else - return Type.singleType(pre1, sym); - default: - return prefix; - } - } - - - -} diff --git a/sources/scala/tools/scaladoc/Tag.java b/sources/scala/tools/scaladoc/Tag.java deleted file mode 100644 index 4e71031001..0000000000 --- a/sources/scala/tools/scaladoc/Tag.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.util.regex.*; - -import ch.epfl.lamp.util.Pair; - -import scalac.ast.Tree; -import scalac.symtab.Symbol; - -import scaladoc.*; - -/** - * Documentation tag. - */ -public class Tag { - - /** - * Symbol whose comment contains the tag. - */ - public final Symbol holder; - - /** - * Name of the tag. - */ - public final String name; - - /** - * Value of the tag. - */ - public final String text; - - /** - * Constructor - * - * @param name - * @param text - */ - public Tag(Symbol holder, String name, String text) { - this.holder = holder; - this.name = name; - this.text = text; - } - - /** String representation. - */ - public String toString() { - return "Tag(" + name + ", " + text + ")"; - } - - /** - * Is this tag a param tag ? - */ - public boolean isParam() { - return name.equals("@param"); - } - - /** - * Is this tag an exception tag ? - */ - public boolean isException() { - return name.equals("@param") || name.equals("@exception"); - } - - /** - * Is this tag a reference tag ? - */ - public boolean isReference() { - return name.equals("@see") || name.equals("@link"); - } - - /** - * Is this tag a text tag ? - */ - public boolean isText() { - return name.equals("@text"); - } - - /** - * Splits a string containing spaces into two parts. - * - * @param text - */ - public static Pair split(String text) { - int length = text.length(); - int endFst = length; - int startSnd = length; - int current = 0; - while (current < length && startSnd >= length) { - char c = text.charAt(current); - if (Character.isWhitespace(c) && endFst == length) - endFst = current; - else if (!Character.isWhitespace(c) && endFst != length) - startSnd = current; - current++; - } - return new Pair(text.substring(0, endFst), - text.substring(startSnd, length)); - } - - /** - * Kind of a reference tag. - */ - public static class RefKind { - - /** Bad reference. */ - public case Bad(String ref); - - /** Reference to an URL. */ - public case Url(String ref); - - /** String literal reference. */ - public case Literal(String ref); - - /** Reference to a scala entity. */ - public case Scala(String container, String member, String label); - } - - /** - * Parses a reference tag. - * - * @param tag - */ - protected static RefKind parseReference(Tag tag) { - if (tag.text.startsWith("\"")) - return RefKind.Literal(tag.text); - else if (tag.text.startsWith("<")) - return RefKind.Url(tag.text); - else { - Pattern p = Pattern.compile("(([^#\\s]*)(#([^\\s]+))?)\\s*(.+)?"); - Matcher m = p.matcher(tag.text); - if (m.find()) { - String container = m.group(2) == null ? "" : m.group(2); - String member = m.group(3); - String label = m.group(4) == null ? "" : m.group(4); - return RefKind.Scala(container, member, label); - } else { - System.err.println("Warning: Fail to parse see tag:" + tag + " in " + tag.holder); - return RefKind.Bad(tag.text); - } - } - } - -} diff --git a/sources/scala/tools/scaladoc/TypeIsomorphism.java b/sources/scala/tools/scaladoc/TypeIsomorphism.java deleted file mode 100644 index bfbd80a3eb..0000000000 --- a/sources/scala/tools/scaladoc/TypeIsomorphism.java +++ /dev/null @@ -1,19 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scaladoc; - -import java.util.Iterator; -import scalac.symtab.Type; -import scalac.Global; - -public interface TypeIsomorphism { - - Iterator/*[Pair[Symbol, Type]]*/ searchType(Type type, SymbolBooleanFunction isDocumented); - -} diff --git a/sources/scala/tools/scaladoc/resources/script.js b/sources/scala/tools/scaladoc/resources/script.js deleted file mode 100644 index 94093ecc50..0000000000 --- a/sources/scala/tools/scaladoc/resources/script.js +++ /dev/null @@ -1,5 +0,0 @@ -<!-- -function setWindowTitle(title) { - parent.document.title = title; -} ---> diff --git a/sources/scala/tools/scaladoc/resources/style.css b/sources/scala/tools/scaladoc/resources/style.css deleted file mode 100644 index 5fecb9014e..0000000000 --- a/sources/scala/tools/scaladoc/resources/style.css +++ /dev/null @@ -1,124 +0,0 @@ -/* Scaladoc style sheet */ - -a:link { - color: #0000ee; -} - -a:visited { - color: #551a8b; -} - -a:active { - color: #0000ee; -} - -body { - background-color: #ffffff; -} - -div.entity { - margin: 18px 0px 18px 0px; - font-size: x-large; - font-weight: bold; -} - -div.doctitle { - font-weight: bold; - font-style: italic; -} - -div.doctitle-larger { - margin: 0px 0px 10px 0px; - font-size: larger; - font-weight: bold; -} - -div.page-title { - margin: 15px 0px 15px 0px; - font-size: x-large; - font-weight: bold; - text-align: center; -} - -span.entity { - color: #ff6666; -} - -table.member { - border-collapse: collapse; - border: 2px solid #888888; - background-color: #ffffff; - width: 100%; -} - -table.member-detail { - margin: 10px 0px 0px 0px; - border-collapse: collapse; - border: 2px solid #888888; - background-color: #ffffff; - width: 100%; -} - -table.navigation { - border-collapse: collapse; - width: 100%; - font-family: Arial,Helvetica,Sans-serif; -} - -table.list { - border-collapse: collapse; - border-style: none; - width: 100%; -} - -td.inherited-members { - border-top: 2px solid #888888; - border-right: 0px; -} - -td.inherited-owner { - background-color: #eeeeff; - font-weight: bold; -} - -td.member-title { - border: 2px solid #888888; - background-color: #ccccff; - font-size: x-large; - font-weight: bold; -} - -td.modifiers { - border-top: 2px solid #888888; - border-right: 2px solid #888888; - width: 50px; - text-align: right; -} - -td.navigation-enabled { - font-weight: bold; - color: #000000; - background-color: #eeeeff; -} - -td.navigation-links { - width: 100%; - background-color: #eeeeff; -} - -td.navigation-selected { - font-weight: bold; - color: #ffffff; - background-color: #00008b; -} - -td.signature { - border-top: 2px solid #888888; - width: 90%; -} - -td.title { - background-color: #ccccff; - font-size: x-large; - font-weight: bold; -} diff --git a/sources/scala/tools/scaladoc/resources/xhtml-lat1.ent b/sources/scala/tools/scaladoc/resources/xhtml-lat1.ent deleted file mode 100644 index ffee223eb1..0000000000 --- a/sources/scala/tools/scaladoc/resources/xhtml-lat1.ent +++ /dev/null @@ -1,196 +0,0 @@ -<!-- Portions (C) International Organization for Standardization 1986 - Permission to copy in any form is granted for use with - conforming SGML systems and applications as defined in - ISO 8879, provided this notice is included in all copies. ---> -<!-- Character entity set. Typical invocation: - <!ENTITY % HTMLlat1 PUBLIC - "-//W3C//ENTITIES Latin 1 for XHTML//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> - %HTMLlat1; ---> - -<!ENTITY nbsp " "> <!-- no-break space = non-breaking space, - U+00A0 ISOnum --> -<!ENTITY iexcl "¡"> <!-- inverted exclamation mark, U+00A1 ISOnum --> -<!ENTITY cent "¢"> <!-- cent sign, U+00A2 ISOnum --> -<!ENTITY pound "£"> <!-- pound sign, U+00A3 ISOnum --> -<!ENTITY curren "¤"> <!-- currency sign, U+00A4 ISOnum --> -<!ENTITY yen "¥"> <!-- yen sign = yuan sign, U+00A5 ISOnum --> -<!ENTITY brvbar "¦"> <!-- broken bar = broken vertical bar, - U+00A6 ISOnum --> -<!ENTITY sect "§"> <!-- section sign, U+00A7 ISOnum --> -<!ENTITY uml "¨"> <!-- diaeresis = spacing diaeresis, - U+00A8 ISOdia --> -<!ENTITY copy "©"> <!-- copyright sign, U+00A9 ISOnum --> -<!ENTITY ordf "ª"> <!-- feminine ordinal indicator, U+00AA ISOnum --> -<!ENTITY laquo "«"> <!-- left-pointing double angle quotation mark - = left pointing guillemet, U+00AB ISOnum --> -<!ENTITY not "¬"> <!-- not sign = angled dash, - U+00AC ISOnum --> -<!ENTITY shy "­"> <!-- soft hyphen = discretionary hyphen, - U+00AD ISOnum --> -<!ENTITY reg "®"> <!-- registered sign = registered trade mark sign, - U+00AE ISOnum --> -<!ENTITY macr "¯"> <!-- macron = spacing macron = overline - = APL overbar, U+00AF ISOdia --> -<!ENTITY deg "°"> <!-- degree sign, U+00B0 ISOnum --> -<!ENTITY plusmn "±"> <!-- plus-minus sign = plus-or-minus sign, - U+00B1 ISOnum --> -<!ENTITY sup2 "²"> <!-- superscript two = superscript digit two - = squared, U+00B2 ISOnum --> -<!ENTITY sup3 "³"> <!-- superscript three = superscript digit three - = cubed, U+00B3 ISOnum --> -<!ENTITY acute "´"> <!-- acute accent = spacing acute, - U+00B4 ISOdia --> -<!ENTITY micro "µ"> <!-- micro sign, U+00B5 ISOnum --> -<!ENTITY para "¶"> <!-- pilcrow sign = paragraph sign, - U+00B6 ISOnum --> -<!ENTITY middot "·"> <!-- middle dot = Georgian comma - = Greek middle dot, U+00B7 ISOnum --> -<!ENTITY cedil "¸"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia --> -<!ENTITY sup1 "¹"> <!-- superscript one = superscript digit one, - U+00B9 ISOnum --> -<!ENTITY ordm "º"> <!-- masculine ordinal indicator, - U+00BA ISOnum --> -<!ENTITY raquo "»"> <!-- right-pointing double angle quotation mark - = right pointing guillemet, U+00BB ISOnum --> -<!ENTITY frac14 "¼"> <!-- vulgar fraction one quarter - = fraction one quarter, U+00BC ISOnum --> -<!ENTITY frac12 "½"> <!-- vulgar fraction one half - = fraction one half, U+00BD ISOnum --> -<!ENTITY frac34 "¾"> <!-- vulgar fraction three quarters - = fraction three quarters, U+00BE ISOnum --> -<!ENTITY iquest "¿"> <!-- inverted question mark - = turned question mark, U+00BF ISOnum --> -<!ENTITY Agrave "À"> <!-- latin capital letter A with grave - = latin capital letter A grave, - U+00C0 ISOlat1 --> -<!ENTITY Aacute "Á"> <!-- latin capital letter A with acute, - U+00C1 ISOlat1 --> -<!ENTITY Acirc "Â"> <!-- latin capital letter A with circumflex, - U+00C2 ISOlat1 --> -<!ENTITY Atilde "Ã"> <!-- latin capital letter A with tilde, - U+00C3 ISOlat1 --> -<!ENTITY Auml "Ä"> <!-- latin capital letter A with diaeresis, - U+00C4 ISOlat1 --> -<!ENTITY Aring "Å"> <!-- latin capital letter A with ring above - = latin capital letter A ring, - U+00C5 ISOlat1 --> -<!ENTITY AElig "Æ"> <!-- latin capital letter AE - = latin capital ligature AE, - U+00C6 ISOlat1 --> -<!ENTITY Ccedil "Ç"> <!-- latin capital letter C with cedilla, - U+00C7 ISOlat1 --> -<!ENTITY Egrave "È"> <!-- latin capital letter E with grave, - U+00C8 ISOlat1 --> -<!ENTITY Eacute "É"> <!-- latin capital letter E with acute, - U+00C9 ISOlat1 --> -<!ENTITY Ecirc "Ê"> <!-- latin capital letter E with circumflex, - U+00CA ISOlat1 --> -<!ENTITY Euml "Ë"> <!-- latin capital letter E with diaeresis, - U+00CB ISOlat1 --> -<!ENTITY Igrave "Ì"> <!-- latin capital letter I with grave, - U+00CC ISOlat1 --> -<!ENTITY Iacute "Í"> <!-- latin capital letter I with acute, - U+00CD ISOlat1 --> -<!ENTITY Icirc "Î"> <!-- latin capital letter I with circumflex, - U+00CE ISOlat1 --> -<!ENTITY Iuml "Ï"> <!-- latin capital letter I with diaeresis, - U+00CF ISOlat1 --> -<!ENTITY ETH "Ð"> <!-- latin capital letter ETH, U+00D0 ISOlat1 --> -<!ENTITY Ntilde "Ñ"> <!-- latin capital letter N with tilde, - U+00D1 ISOlat1 --> -<!ENTITY Ograve "Ò"> <!-- latin capital letter O with grave, - U+00D2 ISOlat1 --> -<!ENTITY Oacute "Ó"> <!-- latin capital letter O with acute, - U+00D3 ISOlat1 --> -<!ENTITY Ocirc "Ô"> <!-- latin capital letter O with circumflex, - U+00D4 ISOlat1 --> -<!ENTITY Otilde "Õ"> <!-- latin capital letter O with tilde, - U+00D5 ISOlat1 --> -<!ENTITY Ouml "Ö"> <!-- latin capital letter O with diaeresis, - U+00D6 ISOlat1 --> -<!ENTITY times "×"> <!-- multiplication sign, U+00D7 ISOnum --> -<!ENTITY Oslash "Ø"> <!-- latin capital letter O with stroke - = latin capital letter O slash, - U+00D8 ISOlat1 --> -<!ENTITY Ugrave "Ù"> <!-- latin capital letter U with grave, - U+00D9 ISOlat1 --> -<!ENTITY Uacute "Ú"> <!-- latin capital letter U with acute, - U+00DA ISOlat1 --> -<!ENTITY Ucirc "Û"> <!-- latin capital letter U with circumflex, - U+00DB ISOlat1 --> -<!ENTITY Uuml "Ü"> <!-- latin capital letter U with diaeresis, - U+00DC ISOlat1 --> -<!ENTITY Yacute "Ý"> <!-- latin capital letter Y with acute, - U+00DD ISOlat1 --> -<!ENTITY THORN "Þ"> <!-- latin capital letter THORN, - U+00DE ISOlat1 --> -<!ENTITY szlig "ß"> <!-- latin small letter sharp s = ess-zed, - U+00DF ISOlat1 --> -<!ENTITY agrave "à"> <!-- latin small letter a with grave - = latin small letter a grave, - U+00E0 ISOlat1 --> -<!ENTITY aacute "á"> <!-- latin small letter a with acute, - U+00E1 ISOlat1 --> -<!ENTITY acirc "â"> <!-- latin small letter a with circumflex, - U+00E2 ISOlat1 --> -<!ENTITY atilde "ã"> <!-- latin small letter a with tilde, - U+00E3 ISOlat1 --> -<!ENTITY auml "ä"> <!-- latin small letter a with diaeresis, - U+00E4 ISOlat1 --> -<!ENTITY aring "å"> <!-- latin small letter a with ring above - = latin small letter a ring, - U+00E5 ISOlat1 --> -<!ENTITY aelig "æ"> <!-- latin small letter ae - = latin small ligature ae, U+00E6 ISOlat1 --> -<!ENTITY ccedil "ç"> <!-- latin small letter c with cedilla, - U+00E7 ISOlat1 --> -<!ENTITY egrave "è"> <!-- latin small letter e with grave, - U+00E8 ISOlat1 --> -<!ENTITY eacute "é"> <!-- latin small letter e with acute, - U+00E9 ISOlat1 --> -<!ENTITY ecirc "ê"> <!-- latin small letter e with circumflex, - U+00EA ISOlat1 --> -<!ENTITY euml "ë"> <!-- latin small letter e with diaeresis, - U+00EB ISOlat1 --> -<!ENTITY igrave "ì"> <!-- latin small letter i with grave, - U+00EC ISOlat1 --> -<!ENTITY iacute "í"> <!-- latin small letter i with acute, - U+00ED ISOlat1 --> -<!ENTITY icirc "î"> <!-- latin small letter i with circumflex, - U+00EE ISOlat1 --> -<!ENTITY iuml "ï"> <!-- latin small letter i with diaeresis, - U+00EF ISOlat1 --> -<!ENTITY eth "ð"> <!-- latin small letter eth, U+00F0 ISOlat1 --> -<!ENTITY ntilde "ñ"> <!-- latin small letter n with tilde, - U+00F1 ISOlat1 --> -<!ENTITY ograve "ò"> <!-- latin small letter o with grave, - U+00F2 ISOlat1 --> -<!ENTITY oacute "ó"> <!-- latin small letter o with acute, - U+00F3 ISOlat1 --> -<!ENTITY ocirc "ô"> <!-- latin small letter o with circumflex, - U+00F4 ISOlat1 --> -<!ENTITY otilde "õ"> <!-- latin small letter o with tilde, - U+00F5 ISOlat1 --> -<!ENTITY ouml "ö"> <!-- latin small letter o with diaeresis, - U+00F6 ISOlat1 --> -<!ENTITY divide "÷"> <!-- division sign, U+00F7 ISOnum --> -<!ENTITY oslash "ø"> <!-- latin small letter o with stroke, - = latin small letter o slash, - U+00F8 ISOlat1 --> -<!ENTITY ugrave "ù"> <!-- latin small letter u with grave, - U+00F9 ISOlat1 --> -<!ENTITY uacute "ú"> <!-- latin small letter u with acute, - U+00FA ISOlat1 --> -<!ENTITY ucirc "û"> <!-- latin small letter u with circumflex, - U+00FB ISOlat1 --> -<!ENTITY uuml "ü"> <!-- latin small letter u with diaeresis, - U+00FC ISOlat1 --> -<!ENTITY yacute "ý"> <!-- latin small letter y with acute, - U+00FD ISOlat1 --> -<!ENTITY thorn "þ"> <!-- latin small letter thorn, - U+00FE ISOlat1 --> -<!ENTITY yuml "ÿ"> <!-- latin small letter y with diaeresis, - U+00FF ISOlat1 --> diff --git a/sources/scala/tools/scaladoc/resources/xhtml-special.ent b/sources/scala/tools/scaladoc/resources/xhtml-special.ent deleted file mode 100644 index ca358b2fec..0000000000 --- a/sources/scala/tools/scaladoc/resources/xhtml-special.ent +++ /dev/null @@ -1,80 +0,0 @@ -<!-- Special characters for XHTML --> - -<!-- Character entity set. Typical invocation: - <!ENTITY % HTMLspecial PUBLIC - "-//W3C//ENTITIES Special for XHTML//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"> - %HTMLspecial; ---> - -<!-- Portions (C) International Organization for Standardization 1986: - Permission to copy in any form is granted for use with - conforming SGML systems and applications as defined in - ISO 8879, provided this notice is included in all copies. ---> - -<!-- Relevant ISO entity set is given unless names are newly introduced. - New names (i.e., not in ISO 8879 list) do not clash with any - existing ISO 8879 entity names. ISO 10646 character numbers - are given for each character, in hex. values are decimal - conversions of the ISO 10646 values and refer to the document - character set. Names are Unicode names. ---> - -<!-- C0 Controls and Basic Latin --> -<!ENTITY quot """> <!-- quotation mark, U+0022 ISOnum --> -<!ENTITY amp "&#38;"> <!-- ampersand, U+0026 ISOnum --> -<!ENTITY lt "&#60;"> <!-- less-than sign, U+003C ISOnum --> -<!ENTITY gt ">"> <!-- greater-than sign, U+003E ISOnum --> -<!ENTITY apos "'"> <!-- apostrophe = APL quote, U+0027 ISOnum --> - -<!-- Latin Extended-A --> -<!ENTITY OElig "Œ"> <!-- latin capital ligature OE, - U+0152 ISOlat2 --> -<!ENTITY oelig "œ"> <!-- latin small ligature oe, U+0153 ISOlat2 --> -<!-- ligature is a misnomer, this is a separate character in some languages --> -<!ENTITY Scaron "Š"> <!-- latin capital letter S with caron, - U+0160 ISOlat2 --> -<!ENTITY scaron "š"> <!-- latin small letter s with caron, - U+0161 ISOlat2 --> -<!ENTITY Yuml "Ÿ"> <!-- latin capital letter Y with diaeresis, - U+0178 ISOlat2 --> - -<!-- Spacing Modifier Letters --> -<!ENTITY circ "ˆ"> <!-- modifier letter circumflex accent, - U+02C6 ISOpub --> -<!ENTITY tilde "˜"> <!-- small tilde, U+02DC ISOdia --> - -<!-- General Punctuation --> -<!ENTITY ensp " "> <!-- en space, U+2002 ISOpub --> -<!ENTITY emsp " "> <!-- em space, U+2003 ISOpub --> -<!ENTITY thinsp " "> <!-- thin space, U+2009 ISOpub --> -<!ENTITY zwnj "‌"> <!-- zero width non-joiner, - U+200C NEW RFC 2070 --> -<!ENTITY zwj "‍"> <!-- zero width joiner, U+200D NEW RFC 2070 --> -<!ENTITY lrm "‎"> <!-- left-to-right mark, U+200E NEW RFC 2070 --> -<!ENTITY rlm "‏"> <!-- right-to-left mark, U+200F NEW RFC 2070 --> -<!ENTITY ndash "–"> <!-- en dash, U+2013 ISOpub --> -<!ENTITY mdash "—"> <!-- em dash, U+2014 ISOpub --> -<!ENTITY lsquo "‘"> <!-- left single quotation mark, - U+2018 ISOnum --> -<!ENTITY rsquo "’"> <!-- right single quotation mark, - U+2019 ISOnum --> -<!ENTITY sbquo "‚"> <!-- single low-9 quotation mark, U+201A NEW --> -<!ENTITY ldquo "“"> <!-- left double quotation mark, - U+201C ISOnum --> -<!ENTITY rdquo "”"> <!-- right double quotation mark, - U+201D ISOnum --> -<!ENTITY bdquo "„"> <!-- double low-9 quotation mark, U+201E NEW --> -<!ENTITY dagger "†"> <!-- dagger, U+2020 ISOpub --> -<!ENTITY Dagger "‡"> <!-- double dagger, U+2021 ISOpub --> -<!ENTITY permil "‰"> <!-- per mille sign, U+2030 ISOtech --> -<!ENTITY lsaquo "‹"> <!-- single left-pointing angle quotation mark, - U+2039 ISO proposed --> -<!-- lsaquo is proposed but not yet ISO standardized --> -<!ENTITY rsaquo "›"> <!-- single right-pointing angle quotation mark, - U+203A ISO proposed --> -<!-- rsaquo is proposed but not yet ISO standardized --> - -<!-- Currency Symbols --> -<!ENTITY euro "€"> <!-- euro sign, U+20AC NEW --> diff --git a/sources/scala/tools/scaladoc/resources/xhtml-symbol.ent b/sources/scala/tools/scaladoc/resources/xhtml-symbol.ent deleted file mode 100644 index 63c2abfa6f..0000000000 --- a/sources/scala/tools/scaladoc/resources/xhtml-symbol.ent +++ /dev/null @@ -1,237 +0,0 @@ -<!-- Mathematical, Greek and Symbolic characters for XHTML --> - -<!-- Character entity set. Typical invocation: - <!ENTITY % HTMLsymbol PUBLIC - "-//W3C//ENTITIES Symbols for XHTML//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"> - %HTMLsymbol; ---> - -<!-- Portions (C) International Organization for Standardization 1986: - Permission to copy in any form is granted for use with - conforming SGML systems and applications as defined in - ISO 8879, provided this notice is included in all copies. ---> - -<!-- Relevant ISO entity set is given unless names are newly introduced. - New names (i.e., not in ISO 8879 list) do not clash with any - existing ISO 8879 entity names. ISO 10646 character numbers - are given for each character, in hex. values are decimal - conversions of the ISO 10646 values and refer to the document - character set. Names are Unicode names. ---> - -<!-- Latin Extended-B --> -<!ENTITY fnof "ƒ"> <!-- latin small letter f with hook = function - = florin, U+0192 ISOtech --> - -<!-- Greek --> -<!ENTITY Alpha "Α"> <!-- greek capital letter alpha, U+0391 --> -<!ENTITY Beta "Β"> <!-- greek capital letter beta, U+0392 --> -<!ENTITY Gamma "Γ"> <!-- greek capital letter gamma, - U+0393 ISOgrk3 --> -<!ENTITY Delta "Δ"> <!-- greek capital letter delta, - U+0394 ISOgrk3 --> -<!ENTITY Epsilon "Ε"> <!-- greek capital letter epsilon, U+0395 --> -<!ENTITY Zeta "Ζ"> <!-- greek capital letter zeta, U+0396 --> -<!ENTITY Eta "Η"> <!-- greek capital letter eta, U+0397 --> -<!ENTITY Theta "Θ"> <!-- greek capital letter theta, - U+0398 ISOgrk3 --> -<!ENTITY Iota "Ι"> <!-- greek capital letter iota, U+0399 --> -<!ENTITY Kappa "Κ"> <!-- greek capital letter kappa, U+039A --> -<!ENTITY Lambda "Λ"> <!-- greek capital letter lamda, - U+039B ISOgrk3 --> -<!ENTITY Mu "Μ"> <!-- greek capital letter mu, U+039C --> -<!ENTITY Nu "Ν"> <!-- greek capital letter nu, U+039D --> -<!ENTITY Xi "Ξ"> <!-- greek capital letter xi, U+039E ISOgrk3 --> -<!ENTITY Omicron "Ο"> <!-- greek capital letter omicron, U+039F --> -<!ENTITY Pi "Π"> <!-- greek capital letter pi, U+03A0 ISOgrk3 --> -<!ENTITY Rho "Ρ"> <!-- greek capital letter rho, U+03A1 --> -<!-- there is no Sigmaf, and no U+03A2 character either --> -<!ENTITY Sigma "Σ"> <!-- greek capital letter sigma, - U+03A3 ISOgrk3 --> -<!ENTITY Tau "Τ"> <!-- greek capital letter tau, U+03A4 --> -<!ENTITY Upsilon "Υ"> <!-- greek capital letter upsilon, - U+03A5 ISOgrk3 --> -<!ENTITY Phi "Φ"> <!-- greek capital letter phi, - U+03A6 ISOgrk3 --> -<!ENTITY Chi "Χ"> <!-- greek capital letter chi, U+03A7 --> -<!ENTITY Psi "Ψ"> <!-- greek capital letter psi, - U+03A8 ISOgrk3 --> -<!ENTITY Omega "Ω"> <!-- greek capital letter omega, - U+03A9 ISOgrk3 --> - -<!ENTITY alpha "α"> <!-- greek small letter alpha, - U+03B1 ISOgrk3 --> -<!ENTITY beta "β"> <!-- greek small letter beta, U+03B2 ISOgrk3 --> -<!ENTITY gamma "γ"> <!-- greek small letter gamma, - U+03B3 ISOgrk3 --> -<!ENTITY delta "δ"> <!-- greek small letter delta, - U+03B4 ISOgrk3 --> -<!ENTITY epsilon "ε"> <!-- greek small letter epsilon, - U+03B5 ISOgrk3 --> -<!ENTITY zeta "ζ"> <!-- greek small letter zeta, U+03B6 ISOgrk3 --> -<!ENTITY eta "η"> <!-- greek small letter eta, U+03B7 ISOgrk3 --> -<!ENTITY theta "θ"> <!-- greek small letter theta, - U+03B8 ISOgrk3 --> -<!ENTITY iota "ι"> <!-- greek small letter iota, U+03B9 ISOgrk3 --> -<!ENTITY kappa "κ"> <!-- greek small letter kappa, - U+03BA ISOgrk3 --> -<!ENTITY lambda "λ"> <!-- greek small letter lamda, - U+03BB ISOgrk3 --> -<!ENTITY mu "μ"> <!-- greek small letter mu, U+03BC ISOgrk3 --> -<!ENTITY nu "ν"> <!-- greek small letter nu, U+03BD ISOgrk3 --> -<!ENTITY xi "ξ"> <!-- greek small letter xi, U+03BE ISOgrk3 --> -<!ENTITY omicron "ο"> <!-- greek small letter omicron, U+03BF NEW --> -<!ENTITY pi "π"> <!-- greek small letter pi, U+03C0 ISOgrk3 --> -<!ENTITY rho "ρ"> <!-- greek small letter rho, U+03C1 ISOgrk3 --> -<!ENTITY sigmaf "ς"> <!-- greek small letter final sigma, - U+03C2 ISOgrk3 --> -<!ENTITY sigma "σ"> <!-- greek small letter sigma, - U+03C3 ISOgrk3 --> -<!ENTITY tau "τ"> <!-- greek small letter tau, U+03C4 ISOgrk3 --> -<!ENTITY upsilon "υ"> <!-- greek small letter upsilon, - U+03C5 ISOgrk3 --> -<!ENTITY phi "φ"> <!-- greek small letter phi, U+03C6 ISOgrk3 --> -<!ENTITY chi "χ"> <!-- greek small letter chi, U+03C7 ISOgrk3 --> -<!ENTITY psi "ψ"> <!-- greek small letter psi, U+03C8 ISOgrk3 --> -<!ENTITY omega "ω"> <!-- greek small letter omega, - U+03C9 ISOgrk3 --> -<!ENTITY thetasym "ϑ"> <!-- greek theta symbol, - U+03D1 NEW --> -<!ENTITY upsih "ϒ"> <!-- greek upsilon with hook symbol, - U+03D2 NEW --> -<!ENTITY piv "ϖ"> <!-- greek pi symbol, U+03D6 ISOgrk3 --> - -<!-- General Punctuation --> -<!ENTITY bull "•"> <!-- bullet = black small circle, - U+2022 ISOpub --> -<!-- bullet is NOT the same as bullet operator, U+2219 --> -<!ENTITY hellip "…"> <!-- horizontal ellipsis = three dot leader, - U+2026 ISOpub --> -<!ENTITY prime "′"> <!-- prime = minutes = feet, U+2032 ISOtech --> -<!ENTITY Prime "″"> <!-- double prime = seconds = inches, - U+2033 ISOtech --> -<!ENTITY oline "‾"> <!-- overline = spacing overscore, - U+203E NEW --> -<!ENTITY frasl "⁄"> <!-- fraction slash, U+2044 NEW --> - -<!-- Letterlike Symbols --> -<!ENTITY weierp "℘"> <!-- script capital P = power set - = Weierstrass p, U+2118 ISOamso --> -<!ENTITY image "ℑ"> <!-- black-letter capital I = imaginary part, - U+2111 ISOamso --> -<!ENTITY real "ℜ"> <!-- black-letter capital R = real part symbol, - U+211C ISOamso --> -<!ENTITY trade "™"> <!-- trade mark sign, U+2122 ISOnum --> -<!ENTITY alefsym "ℵ"> <!-- alef symbol = first transfinite cardinal, - U+2135 NEW --> -<!-- alef symbol is NOT the same as hebrew letter alef, - U+05D0 although the same glyph could be used to depict both characters --> - -<!-- Arrows --> -<!ENTITY larr "←"> <!-- leftwards arrow, U+2190 ISOnum --> -<!ENTITY uarr "↑"> <!-- upwards arrow, U+2191 ISOnum--> -<!ENTITY rarr "→"> <!-- rightwards arrow, U+2192 ISOnum --> -<!ENTITY darr "↓"> <!-- downwards arrow, U+2193 ISOnum --> -<!ENTITY harr "↔"> <!-- left right arrow, U+2194 ISOamsa --> -<!ENTITY crarr "↵"> <!-- downwards arrow with corner leftwards - = carriage return, U+21B5 NEW --> -<!ENTITY lArr "⇐"> <!-- leftwards double arrow, U+21D0 ISOtech --> -<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow - but also does not have any other character for that function. So lArr can - be used for 'is implied by' as ISOtech suggests --> -<!ENTITY uArr "⇑"> <!-- upwards double arrow, U+21D1 ISOamsa --> -<!ENTITY rArr "⇒"> <!-- rightwards double arrow, - U+21D2 ISOtech --> -<!-- Unicode does not say this is the 'implies' character but does not have - another character with this function so rArr can be used for 'implies' - as ISOtech suggests --> -<!ENTITY dArr "⇓"> <!-- downwards double arrow, U+21D3 ISOamsa --> -<!ENTITY hArr "⇔"> <!-- left right double arrow, - U+21D4 ISOamsa --> - -<!-- Mathematical Operators --> -<!ENTITY forall "∀"> <!-- for all, U+2200 ISOtech --> -<!ENTITY part "∂"> <!-- partial differential, U+2202 ISOtech --> -<!ENTITY exist "∃"> <!-- there exists, U+2203 ISOtech --> -<!ENTITY empty "∅"> <!-- empty set = null set, U+2205 ISOamso --> -<!ENTITY nabla "∇"> <!-- nabla = backward difference, - U+2207 ISOtech --> -<!ENTITY isin "∈"> <!-- element of, U+2208 ISOtech --> -<!ENTITY notin "∉"> <!-- not an element of, U+2209 ISOtech --> -<!ENTITY ni "∋"> <!-- contains as member, U+220B ISOtech --> -<!ENTITY prod "∏"> <!-- n-ary product = product sign, - U+220F ISOamsb --> -<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though - the same glyph might be used for both --> -<!ENTITY sum "∑"> <!-- n-ary summation, U+2211 ISOamsb --> -<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma' - though the same glyph might be used for both --> -<!ENTITY minus "−"> <!-- minus sign, U+2212 ISOtech --> -<!ENTITY lowast "∗"> <!-- asterisk operator, U+2217 ISOtech --> -<!ENTITY radic "√"> <!-- square root = radical sign, - U+221A ISOtech --> -<!ENTITY prop "∝"> <!-- proportional to, U+221D ISOtech --> -<!ENTITY infin "∞"> <!-- infinity, U+221E ISOtech --> -<!ENTITY ang "∠"> <!-- angle, U+2220 ISOamso --> -<!ENTITY and "∧"> <!-- logical and = wedge, U+2227 ISOtech --> -<!ENTITY or "∨"> <!-- logical or = vee, U+2228 ISOtech --> -<!ENTITY cap "∩"> <!-- intersection = cap, U+2229 ISOtech --> -<!ENTITY cup "∪"> <!-- union = cup, U+222A ISOtech --> -<!ENTITY int "∫"> <!-- integral, U+222B ISOtech --> -<!ENTITY there4 "∴"> <!-- therefore, U+2234 ISOtech --> -<!ENTITY sim "∼"> <!-- tilde operator = varies with = similar to, - U+223C ISOtech --> -<!-- tilde operator is NOT the same character as the tilde, U+007E, - although the same glyph might be used to represent both --> -<!ENTITY cong "≅"> <!-- approximately equal to, U+2245 ISOtech --> -<!ENTITY asymp "≈"> <!-- almost equal to = asymptotic to, - U+2248 ISOamsr --> -<!ENTITY ne "≠"> <!-- not equal to, U+2260 ISOtech --> -<!ENTITY equiv "≡"> <!-- identical to, U+2261 ISOtech --> -<!ENTITY le "≤"> <!-- less-than or equal to, U+2264 ISOtech --> -<!ENTITY ge "≥"> <!-- greater-than or equal to, - U+2265 ISOtech --> -<!ENTITY sub "⊂"> <!-- subset of, U+2282 ISOtech --> -<!ENTITY sup "⊃"> <!-- superset of, U+2283 ISOtech --> -<!ENTITY nsub "⊄"> <!-- not a subset of, U+2284 ISOamsn --> -<!ENTITY sube "⊆"> <!-- subset of or equal to, U+2286 ISOtech --> -<!ENTITY supe "⊇"> <!-- superset of or equal to, - U+2287 ISOtech --> -<!ENTITY oplus "⊕"> <!-- circled plus = direct sum, - U+2295 ISOamsb --> -<!ENTITY otimes "⊗"> <!-- circled times = vector product, - U+2297 ISOamsb --> -<!ENTITY perp "⊥"> <!-- up tack = orthogonal to = perpendicular, - U+22A5 ISOtech --> -<!ENTITY sdot "⋅"> <!-- dot operator, U+22C5 ISOamsb --> -<!-- dot operator is NOT the same character as U+00B7 middle dot --> - -<!-- Miscellaneous Technical --> -<!ENTITY lceil "⌈"> <!-- left ceiling = APL upstile, - U+2308 ISOamsc --> -<!ENTITY rceil "⌉"> <!-- right ceiling, U+2309 ISOamsc --> -<!ENTITY lfloor "⌊"> <!-- left floor = APL downstile, - U+230A ISOamsc --> -<!ENTITY rfloor "⌋"> <!-- right floor, U+230B ISOamsc --> -<!ENTITY lang "〈"> <!-- left-pointing angle bracket = bra, - U+2329 ISOtech --> -<!-- lang is NOT the same character as U+003C 'less than sign' - or U+2039 'single left-pointing angle quotation mark' --> -<!ENTITY rang "〉"> <!-- right-pointing angle bracket = ket, - U+232A ISOtech --> -<!-- rang is NOT the same character as U+003E 'greater than sign' - or U+203A 'single right-pointing angle quotation mark' --> - -<!-- Geometric Shapes --> -<!ENTITY loz "◊"> <!-- lozenge, U+25CA ISOpub --> - -<!-- Miscellaneous Symbols --> -<!ENTITY spades "♠"> <!-- black spade suit, U+2660 ISOpub --> -<!-- black here seems to mean filled as opposed to hollow --> -<!ENTITY clubs "♣"> <!-- black club suit = shamrock, - U+2663 ISOpub --> -<!ENTITY hearts "♥"> <!-- black heart suit = valentine, - U+2665 ISOpub --> -<!ENTITY diams "♦"> <!-- black diamond suit, U+2666 ISOpub --> diff --git a/sources/scala/tools/scaladoc/resources/xhtml1-transitional.dtd b/sources/scala/tools/scaladoc/resources/xhtml1-transitional.dtd deleted file mode 100644 index ba9be610a6..0000000000 --- a/sources/scala/tools/scaladoc/resources/xhtml1-transitional.dtd +++ /dev/null @@ -1,1201 +0,0 @@ -<!-- - Extensible HTML version 1.0 Transitional DTD - - This is the same as HTML 4 Transitional except for - changes due to the differences between XML and SGML. - - Namespace = http://www.w3.org/1999/xhtml - - For further information, see: http://www.w3.org/TR/xhtml1 - - Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), - All Rights Reserved. - - This DTD module is identified by the PUBLIC and SYSTEM identifiers: - - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" - - $Revision$ - $Date$ - ---> - -<!--================ Character mnemonic entities =========================--> - -<!ENTITY % HTMLlat1 PUBLIC - "-//W3C//ENTITIES Latin 1 for XHTML//EN" - "xhtml-lat1.ent"> -%HTMLlat1; - -<!ENTITY % HTMLsymbol PUBLIC - "-//W3C//ENTITIES Symbols for XHTML//EN" - "xhtml-symbol.ent"> -%HTMLsymbol; - -<!ENTITY % HTMLspecial PUBLIC - "-//W3C//ENTITIES Special for XHTML//EN" - "xhtml-special.ent"> -%HTMLspecial; - -<!--================== Imported Names ====================================--> - -<!ENTITY % ContentType "CDATA"> - <!-- media type, as per [RFC2045] --> - -<!ENTITY % ContentTypes "CDATA"> - <!-- comma-separated list of media types, as per [RFC2045] --> - -<!ENTITY % Charset "CDATA"> - <!-- a character encoding, as per [RFC2045] --> - -<!ENTITY % Charsets "CDATA"> - <!-- a space separated list of character encodings, as per [RFC2045] --> - -<!ENTITY % LanguageCode "NMTOKEN"> - <!-- a language code, as per [RFC3066] --> - -<!ENTITY % Character "CDATA"> - <!-- a single character, as per section 2.2 of [XML] --> - -<!ENTITY % Number "CDATA"> - <!-- one or more digits --> - -<!ENTITY % LinkTypes "CDATA"> - <!-- space-separated list of link types --> - -<!ENTITY % MediaDesc "CDATA"> - <!-- single or comma-separated list of media descriptors --> - -<!ENTITY % URI "CDATA"> - <!-- a Uniform Resource Identifier, see [RFC2396] --> - -<!ENTITY % UriList "CDATA"> - <!-- a space separated list of Uniform Resource Identifiers --> - -<!ENTITY % Datetime "CDATA"> - <!-- date and time information. ISO date format --> - -<!ENTITY % Script "CDATA"> - <!-- script expression --> - -<!ENTITY % StyleSheet "CDATA"> - <!-- style sheet data --> - -<!ENTITY % Text "CDATA"> - <!-- used for titles etc. --> - -<!ENTITY % FrameTarget "NMTOKEN"> - <!-- render in this frame --> - -<!ENTITY % Length "CDATA"> - <!-- nn for pixels or nn% for percentage length --> - -<!ENTITY % MultiLength "CDATA"> - <!-- pixel, percentage, or relative --> - -<!ENTITY % Pixels "CDATA"> - <!-- integer representing length in pixels --> - -<!-- these are used for image maps --> - -<!ENTITY % Shape "(rect|circle|poly|default)"> - -<!ENTITY % Coords "CDATA"> - <!-- comma separated list of lengths --> - -<!-- used for object, applet, img, input and iframe --> -<!ENTITY % ImgAlign "(top|middle|bottom|left|right)"> - -<!-- a color using sRGB: #RRGGBB as Hex values --> -<!ENTITY % Color "CDATA"> - -<!-- There are also 16 widely known color names with their sRGB values: - - Black = #000000 Green = #008000 - Silver = #C0C0C0 Lime = #00FF00 - Gray = #808080 Olive = #808000 - White = #FFFFFF Yellow = #FFFF00 - Maroon = #800000 Navy = #000080 - Red = #FF0000 Blue = #0000FF - Purple = #800080 Teal = #008080 - Fuchsia= #FF00FF Aqua = #00FFFF ---> - -<!--=================== Generic Attributes ===============================--> - -<!-- core attributes common to most elements - id document-wide unique id - class space separated list of classes - style associated style info - title advisory title/amplification ---> -<!ENTITY % coreattrs - "id ID #IMPLIED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED" - > - -<!-- internationalization attributes - lang language code (backwards compatible) - xml:lang language code (as per XML 1.0 spec) - dir direction for weak/neutral text ---> -<!ENTITY % i18n - "lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #IMPLIED" - > - -<!-- attributes for common UI events - onclick a pointer button was clicked - ondblclick a pointer button was double clicked - onmousedown a pointer button was pressed down - onmouseup a pointer button was released - onmousemove a pointer was moved onto the element - onmouseout a pointer was moved away from the element - onkeypress a key was pressed and released - onkeydown a key was pressed down - onkeyup a key was released ---> -<!ENTITY % events - "onclick %Script; #IMPLIED - ondblclick %Script; #IMPLIED - onmousedown %Script; #IMPLIED - onmouseup %Script; #IMPLIED - onmouseover %Script; #IMPLIED - onmousemove %Script; #IMPLIED - onmouseout %Script; #IMPLIED - onkeypress %Script; #IMPLIED - onkeydown %Script; #IMPLIED - onkeyup %Script; #IMPLIED" - > - -<!-- attributes for elements that can get the focus - accesskey accessibility key character - tabindex position in tabbing order - onfocus the element got the focus - onblur the element lost the focus ---> -<!ENTITY % focus - "accesskey %Character; #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED" - > - -<!ENTITY % attrs "%coreattrs; %i18n; %events;"> - -<!-- text alignment for p, div, h1-h6. The default is - align="left" for ltr headings, "right" for rtl --> - -<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED"> - -<!--=================== Text Elements ====================================--> - -<!ENTITY % special.extra - "object | applet | img | map | iframe"> - -<!ENTITY % special.basic - "br | span | bdo"> - -<!ENTITY % special - "%special.basic; | %special.extra;"> - -<!ENTITY % fontstyle.extra "big | small | font | basefont"> - -<!ENTITY % fontstyle.basic "tt | i | b | u - | s | strike "> - -<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;"> - -<!ENTITY % phrase.extra "sub | sup"> -<!ENTITY % phrase.basic "em | strong | dfn | code | q | - samp | kbd | var | cite | abbr | acronym"> - -<!ENTITY % phrase "%phrase.basic; | %phrase.extra;"> - -<!ENTITY % inline.forms "input | select | textarea | label | button"> - -<!-- these can occur at block or inline level --> -<!ENTITY % misc.inline "ins | del | script"> - -<!-- these can only occur at block level --> -<!ENTITY % misc "noscript | %misc.inline;"> - -<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> - -<!-- %Inline; covers inline or "text-level" elements --> -<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> - -<!--================== Block level elements ==============================--> - -<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> -<!ENTITY % lists "ul | ol | dl | menu | dir"> -<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes"> - -<!ENTITY % block - "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table"> - -<!-- %Flow; mixes block and inline and is used for list items etc. --> -<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> - -<!--================== Content models for exclusions =====================--> - -<!-- a elements use %Inline; excluding a --> - -<!ENTITY % a.content - "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> - -<!-- pre uses %Inline excluding img, object, applet, big, small, - font, or basefont --> - -<!ENTITY % pre.content - "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; | - %inline.forms; | %misc.inline;)*"> - -<!-- form uses %Flow; excluding form --> - -<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*"> - -<!-- button uses %Flow; but excludes a, form, form controls, iframe --> - -<!ENTITY % button.content - "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | - table | br | span | bdo | object | applet | img | map | - %fontstyle; | %phrase; | %misc;)*"> - -<!--================ Document Structure ==================================--> - -<!-- the namespace URI designates the document profile --> - -<!ELEMENT html (head, body)> -<!ATTLIST html - %i18n; - id ID #IMPLIED - xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' - > - -<!--================ Document Head =======================================--> - -<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*"> - -<!-- content model is %head.misc; combined with a single - title and an optional base element in any order --> - -<!ELEMENT head (%head.misc;, - ((title, %head.misc;, (base, %head.misc;)?) | - (base, %head.misc;, (title, %head.misc;))))> - -<!ATTLIST head - %i18n; - id ID #IMPLIED - profile %URI; #IMPLIED - > - -<!-- The title element is not considered part of the flow of text. - It should be displayed, for example as the page header or - window title. Exactly one title is required per document. - --> -<!ELEMENT title (#PCDATA)> -<!ATTLIST title - %i18n; - id ID #IMPLIED - > - -<!-- document base URI --> - -<!ELEMENT base EMPTY> -<!ATTLIST base - id ID #IMPLIED - href %URI; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- generic metainformation --> -<!ELEMENT meta EMPTY> -<!ATTLIST meta - %i18n; - id ID #IMPLIED - http-equiv CDATA #IMPLIED - name CDATA #IMPLIED - content CDATA #REQUIRED - scheme CDATA #IMPLIED - > - -<!-- - Relationship values can be used in principle: - - a) for document specific toolbars/menus when used - with the link element in document head e.g. - start, contents, previous, next, index, end, help - b) to link to a separate style sheet (rel="stylesheet") - c) to make a link to a script (rel="script") - d) by stylesheets to control how collections of - html nodes are rendered into printed documents - e) to make a link to a printable version of this document - e.g. a PostScript or PDF version (rel="alternate" media="print") ---> - -<!ELEMENT link EMPTY> -<!ATTLIST link - %attrs; - charset %Charset; #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - type %ContentType; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - media %MediaDesc; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- style info, which may include CDATA sections --> -<!ELEMENT style (#PCDATA)> -<!ATTLIST style - %i18n; - id ID #IMPLIED - type %ContentType; #REQUIRED - media %MediaDesc; #IMPLIED - title %Text; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- script statements, which may include CDATA sections --> -<!ELEMENT script (#PCDATA)> -<!ATTLIST script - id ID #IMPLIED - charset %Charset; #IMPLIED - type %ContentType; #REQUIRED - language CDATA #IMPLIED - src %URI; #IMPLIED - defer (defer) #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!-- alternate content container for non script-based rendering --> - -<!ELEMENT noscript %Flow;> -<!ATTLIST noscript - %attrs; - > - -<!--======================= Frames =======================================--> - -<!-- inline subwindow --> - -<!ELEMENT iframe %Flow;> -<!ATTLIST iframe - %coreattrs; - longdesc %URI; #IMPLIED - name NMTOKEN #IMPLIED - src %URI; #IMPLIED - frameborder (1|0) "1" - marginwidth %Pixels; #IMPLIED - marginheight %Pixels; #IMPLIED - scrolling (yes|no|auto) "auto" - align %ImgAlign; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - > - -<!-- alternate content container for non frame-based rendering --> - -<!ELEMENT noframes %Flow;> -<!ATTLIST noframes - %attrs; - > - -<!--=================== Document Body ====================================--> - -<!ELEMENT body %Flow;> -<!ATTLIST body - %attrs; - onload %Script; #IMPLIED - onunload %Script; #IMPLIED - background %URI; #IMPLIED - bgcolor %Color; #IMPLIED - text %Color; #IMPLIED - link %Color; #IMPLIED - vlink %Color; #IMPLIED - alink %Color; #IMPLIED - > - -<!ELEMENT div %Flow;> <!-- generic language/style container --> -<!ATTLIST div - %attrs; - %TextAlign; - > - -<!--=================== Paragraphs =======================================--> - -<!ELEMENT p %Inline;> -<!ATTLIST p - %attrs; - %TextAlign; - > - -<!--=================== Headings =========================================--> - -<!-- - There are six levels of headings from h1 (the most important) - to h6 (the least important). ---> - -<!ELEMENT h1 %Inline;> -<!ATTLIST h1 - %attrs; - %TextAlign; - > - -<!ELEMENT h2 %Inline;> -<!ATTLIST h2 - %attrs; - %TextAlign; - > - -<!ELEMENT h3 %Inline;> -<!ATTLIST h3 - %attrs; - %TextAlign; - > - -<!ELEMENT h4 %Inline;> -<!ATTLIST h4 - %attrs; - %TextAlign; - > - -<!ELEMENT h5 %Inline;> -<!ATTLIST h5 - %attrs; - %TextAlign; - > - -<!ELEMENT h6 %Inline;> -<!ATTLIST h6 - %attrs; - %TextAlign; - > - -<!--=================== Lists ============================================--> - -<!-- Unordered list bullet styles --> - -<!ENTITY % ULStyle "(disc|square|circle)"> - -<!-- Unordered list --> - -<!ELEMENT ul (li)+> -<!ATTLIST ul - %attrs; - type %ULStyle; #IMPLIED - compact (compact) #IMPLIED - > - -<!-- Ordered list numbering style - - 1 arabic numbers 1, 2, 3, ... - a lower alpha a, b, c, ... - A upper alpha A, B, C, ... - i lower roman i, ii, iii, ... - I upper roman I, II, III, ... - - The style is applied to the sequence number which by default - is reset to 1 for the first list item in an ordered list. ---> -<!ENTITY % OLStyle "CDATA"> - -<!-- Ordered (numbered) list --> - -<!ELEMENT ol (li)+> -<!ATTLIST ol - %attrs; - type %OLStyle; #IMPLIED - compact (compact) #IMPLIED - start %Number; #IMPLIED - > - -<!-- single column list (DEPRECATED) --> -<!ELEMENT menu (li)+> -<!ATTLIST menu - %attrs; - compact (compact) #IMPLIED - > - -<!-- multiple column list (DEPRECATED) --> -<!ELEMENT dir (li)+> -<!ATTLIST dir - %attrs; - compact (compact) #IMPLIED - > - -<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" --> -<!ENTITY % LIStyle "CDATA"> - -<!-- list item --> - -<!ELEMENT li %Flow;> -<!ATTLIST li - %attrs; - type %LIStyle; #IMPLIED - value %Number; #IMPLIED - > - -<!-- definition lists - dt for term, dd for its definition --> - -<!ELEMENT dl (dt|dd)+> -<!ATTLIST dl - %attrs; - compact (compact) #IMPLIED - > - -<!ELEMENT dt %Inline;> -<!ATTLIST dt - %attrs; - > - -<!ELEMENT dd %Flow;> -<!ATTLIST dd - %attrs; - > - -<!--=================== Address ==========================================--> - -<!-- information on author --> - -<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*> -<!ATTLIST address - %attrs; - > - -<!--=================== Horizontal Rule ==================================--> - -<!ELEMENT hr EMPTY> -<!ATTLIST hr - %attrs; - align (left|center|right) #IMPLIED - noshade (noshade) #IMPLIED - size %Pixels; #IMPLIED - width %Length; #IMPLIED - > - -<!--=================== Preformatted Text ================================--> - -<!-- content is %Inline; excluding - "img|object|applet|big|small|sub|sup|font|basefont" --> - -<!ELEMENT pre %pre.content;> -<!ATTLIST pre - %attrs; - width %Number; #IMPLIED - xml:space (preserve) #FIXED 'preserve' - > - -<!--=================== Block-like Quotes ================================--> - -<!ELEMENT blockquote %Flow;> -<!ATTLIST blockquote - %attrs; - cite %URI; #IMPLIED - > - -<!--=================== Text alignment ===================================--> - -<!-- center content --> -<!ELEMENT center %Flow;> -<!ATTLIST center - %attrs; - > - -<!--=================== Inserted/Deleted Text ============================--> - -<!-- - ins/del are allowed in block and inline content, but its - inappropriate to include block content within an ins element - occurring in inline content. ---> -<!ELEMENT ins %Flow;> -<!ATTLIST ins - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!ELEMENT del %Flow;> -<!ATTLIST del - %attrs; - cite %URI; #IMPLIED - datetime %Datetime; #IMPLIED - > - -<!--================== The Anchor Element ================================--> - -<!-- content is %Inline; except that anchors shouldn't be nested --> - -<!ELEMENT a %a.content;> -<!ATTLIST a - %attrs; - %focus; - charset %Charset; #IMPLIED - type %ContentType; #IMPLIED - name NMTOKEN #IMPLIED - href %URI; #IMPLIED - hreflang %LanguageCode; #IMPLIED - rel %LinkTypes; #IMPLIED - rev %LinkTypes; #IMPLIED - shape %Shape; "rect" - coords %Coords; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!--===================== Inline Elements ================================--> - -<!ELEMENT span %Inline;> <!-- generic language/style container --> -<!ATTLIST span - %attrs; - > - -<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> -<!ATTLIST bdo - %coreattrs; - %events; - lang %LanguageCode; #IMPLIED - xml:lang %LanguageCode; #IMPLIED - dir (ltr|rtl) #REQUIRED - > - -<!ELEMENT br EMPTY> <!-- forced line break --> -<!ATTLIST br - %coreattrs; - clear (left|all|right|none) "none" - > - -<!ELEMENT em %Inline;> <!-- emphasis --> -<!ATTLIST em %attrs;> - -<!ELEMENT strong %Inline;> <!-- strong emphasis --> -<!ATTLIST strong %attrs;> - -<!ELEMENT dfn %Inline;> <!-- definitional --> -<!ATTLIST dfn %attrs;> - -<!ELEMENT code %Inline;> <!-- program code --> -<!ATTLIST code %attrs;> - -<!ELEMENT samp %Inline;> <!-- sample --> -<!ATTLIST samp %attrs;> - -<!ELEMENT kbd %Inline;> <!-- something user would type --> -<!ATTLIST kbd %attrs;> - -<!ELEMENT var %Inline;> <!-- variable --> -<!ATTLIST var %attrs;> - -<!ELEMENT cite %Inline;> <!-- citation --> -<!ATTLIST cite %attrs;> - -<!ELEMENT abbr %Inline;> <!-- abbreviation --> -<!ATTLIST abbr %attrs;> - -<!ELEMENT acronym %Inline;> <!-- acronym --> -<!ATTLIST acronym %attrs;> - -<!ELEMENT q %Inline;> <!-- inlined quote --> -<!ATTLIST q - %attrs; - cite %URI; #IMPLIED - > - -<!ELEMENT sub %Inline;> <!-- subscript --> -<!ATTLIST sub %attrs;> - -<!ELEMENT sup %Inline;> <!-- superscript --> -<!ATTLIST sup %attrs;> - -<!ELEMENT tt %Inline;> <!-- fixed pitch font --> -<!ATTLIST tt %attrs;> - -<!ELEMENT i %Inline;> <!-- italic font --> -<!ATTLIST i %attrs;> - -<!ELEMENT b %Inline;> <!-- bold font --> -<!ATTLIST b %attrs;> - -<!ELEMENT big %Inline;> <!-- bigger font --> -<!ATTLIST big %attrs;> - -<!ELEMENT small %Inline;> <!-- smaller font --> -<!ATTLIST small %attrs;> - -<!ELEMENT u %Inline;> <!-- underline --> -<!ATTLIST u %attrs;> - -<!ELEMENT s %Inline;> <!-- strike-through --> -<!ATTLIST s %attrs;> - -<!ELEMENT strike %Inline;> <!-- strike-through --> -<!ATTLIST strike %attrs;> - -<!ELEMENT basefont EMPTY> <!-- base font size --> -<!ATTLIST basefont - id ID #IMPLIED - size CDATA #REQUIRED - color %Color; #IMPLIED - face CDATA #IMPLIED - > - -<!ELEMENT font %Inline;> <!-- local change to font --> -<!ATTLIST font - %coreattrs; - %i18n; - size CDATA #IMPLIED - color %Color; #IMPLIED - face CDATA #IMPLIED - > - -<!--==================== Object ======================================--> -<!-- - object is used to embed objects as part of HTML pages. - param elements should precede other content. Parameters - can also be expressed as attribute/value pairs on the - object element itself when brevity is desired. ---> - -<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> -<!ATTLIST object - %attrs; - declare (declare) #IMPLIED - classid %URI; #IMPLIED - codebase %URI; #IMPLIED - data %URI; #IMPLIED - type %ContentType; #IMPLIED - codetype %ContentType; #IMPLIED - archive %UriList; #IMPLIED - standby %Text; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - name NMTOKEN #IMPLIED - tabindex %Number; #IMPLIED - align %ImgAlign; #IMPLIED - border %Pixels; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!-- - param is used to supply a named property value. - In XML it would seem natural to follow RDF and support an - abbreviated syntax where the param elements are replaced - by attribute value pairs on the object start tag. ---> -<!ELEMENT param EMPTY> -<!ATTLIST param - id ID #IMPLIED - name CDATA #REQUIRED - value CDATA #IMPLIED - valuetype (data|ref|object) "data" - type %ContentType; #IMPLIED - > - -<!--=================== Java applet ==================================--> -<!-- - One of code or object attributes must be present. - Place param elements before other content. ---> -<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*> -<!ATTLIST applet - %coreattrs; - codebase %URI; #IMPLIED - archive CDATA #IMPLIED - code CDATA #IMPLIED - object CDATA #IMPLIED - alt %Text; #IMPLIED - name NMTOKEN #IMPLIED - width %Length; #REQUIRED - height %Length; #REQUIRED - align %ImgAlign; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!--=================== Images ===========================================--> - -<!-- - To avoid accessibility problems for people who aren't - able to see the image, you should provide a text - description using the alt and longdesc attributes. - In addition, avoid the use of server-side image maps. ---> - -<!ELEMENT img EMPTY> -<!ATTLIST img - %attrs; - src %URI; #REQUIRED - alt %Text; #REQUIRED - name NMTOKEN #IMPLIED - longdesc %URI; #IMPLIED - height %Length; #IMPLIED - width %Length; #IMPLIED - usemap %URI; #IMPLIED - ismap (ismap) #IMPLIED - align %ImgAlign; #IMPLIED - border %Length; #IMPLIED - hspace %Pixels; #IMPLIED - vspace %Pixels; #IMPLIED - > - -<!-- usemap points to a map element which may be in this document - or an external document, although the latter is not widely supported --> - -<!--================== Client-side image maps ============================--> - -<!-- These can be placed in the same document or grouped in a - separate document although this isn't yet widely supported --> - -<!ELEMENT map ((%block; | form | %misc;)+ | area+)> -<!ATTLIST map - %i18n; - %events; - id ID #REQUIRED - class CDATA #IMPLIED - style %StyleSheet; #IMPLIED - title %Text; #IMPLIED - name CDATA #IMPLIED - > - -<!ELEMENT area EMPTY> -<!ATTLIST area - %attrs; - %focus; - shape %Shape; "rect" - coords %Coords; #IMPLIED - href %URI; #IMPLIED - nohref (nohref) #IMPLIED - alt %Text; #REQUIRED - target %FrameTarget; #IMPLIED - > - -<!--================ Forms ===============================================--> - -<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> - -<!ATTLIST form - %attrs; - action %URI; #REQUIRED - method (get|post) "get" - name NMTOKEN #IMPLIED - enctype %ContentType; "application/x-www-form-urlencoded" - onsubmit %Script; #IMPLIED - onreset %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - accept-charset %Charsets; #IMPLIED - target %FrameTarget; #IMPLIED - > - -<!-- - Each label must not contain more than ONE field - Label elements shouldn't be nested. ---> -<!ELEMENT label %Inline;> -<!ATTLIST label - %attrs; - for IDREF #IMPLIED - accesskey %Character; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - > - -<!ENTITY % InputType - "(text | password | checkbox | - radio | submit | reset | - file | hidden | image | button)" - > - -<!-- the name attribute is required for all but submit & reset --> - -<!ELEMENT input EMPTY> <!-- form control --> -<!ATTLIST input - %attrs; - %focus; - type %InputType; "text" - name CDATA #IMPLIED - value CDATA #IMPLIED - checked (checked) #IMPLIED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - size CDATA #IMPLIED - maxlength %Number; #IMPLIED - src %URI; #IMPLIED - alt CDATA #IMPLIED - usemap %URI; #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - accept %ContentTypes; #IMPLIED - align %ImgAlign; #IMPLIED - > - -<!ELEMENT select (optgroup|option)+> <!-- option selector --> -<!ATTLIST select - %attrs; - name CDATA #IMPLIED - size %Number; #IMPLIED - multiple (multiple) #IMPLIED - disabled (disabled) #IMPLIED - tabindex %Number; #IMPLIED - onfocus %Script; #IMPLIED - onblur %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!ELEMENT optgroup (option)+> <!-- option group --> -<!ATTLIST optgroup - %attrs; - disabled (disabled) #IMPLIED - label %Text; #REQUIRED - > - -<!ELEMENT option (#PCDATA)> <!-- selectable choice --> -<!ATTLIST option - %attrs; - selected (selected) #IMPLIED - disabled (disabled) #IMPLIED - label %Text; #IMPLIED - value CDATA #IMPLIED - > - -<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> -<!ATTLIST textarea - %attrs; - %focus; - name CDATA #IMPLIED - rows %Number; #REQUIRED - cols %Number; #REQUIRED - disabled (disabled) #IMPLIED - readonly (readonly) #IMPLIED - onselect %Script; #IMPLIED - onchange %Script; #IMPLIED - > - -<!-- - The fieldset element is used to group form fields. - Only one legend element should occur in the content - and if present should only be preceded by whitespace. ---> -<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> -<!ATTLIST fieldset - %attrs; - > - -<!ENTITY % LAlign "(top|bottom|left|right)"> - -<!ELEMENT legend %Inline;> <!-- fieldset label --> -<!ATTLIST legend - %attrs; - accesskey %Character; #IMPLIED - align %LAlign; #IMPLIED - > - -<!-- - Content is %Flow; excluding a, form, form controls, iframe ---> -<!ELEMENT button %button.content;> <!-- push button --> -<!ATTLIST button - %attrs; - %focus; - name CDATA #IMPLIED - value CDATA #IMPLIED - type (button|submit|reset) "submit" - disabled (disabled) #IMPLIED - > - -<!-- single-line text input control (DEPRECATED) --> -<!ELEMENT isindex EMPTY> -<!ATTLIST isindex - %coreattrs; - %i18n; - prompt %Text; #IMPLIED - > - -<!--======================= Tables =======================================--> - -<!-- Derived from IETF HTML table standard, see [RFC1942] --> - -<!-- - The border attribute sets the thickness of the frame around the - table. The default units are screen pixels. - - The frame attribute specifies which parts of the frame around - the table should be rendered. The values are not the same as - CALS to avoid a name clash with the valign attribute. ---> -<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> - -<!-- - The rules attribute defines which rules to draw between cells: - - If rules is absent then assume: - "none" if border is absent or border="0" otherwise "all" ---> - -<!ENTITY % TRules "(none | groups | rows | cols | all)"> - -<!-- horizontal placement of table relative to document --> -<!ENTITY % TAlign "(left|center|right)"> - -<!-- horizontal alignment attributes for cell contents - - char alignment char, e.g. char=':' - charoff offset for alignment char ---> -<!ENTITY % cellhalign - "align (left|center|right|justify|char) #IMPLIED - char %Character; #IMPLIED - charoff %Length; #IMPLIED" - > - -<!-- vertical alignment attributes for cell contents --> -<!ENTITY % cellvalign - "valign (top|middle|bottom|baseline) #IMPLIED" - > - -<!ELEMENT table - (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> -<!ELEMENT caption %Inline;> -<!ELEMENT thead (tr)+> -<!ELEMENT tfoot (tr)+> -<!ELEMENT tbody (tr)+> -<!ELEMENT colgroup (col)*> -<!ELEMENT col EMPTY> -<!ELEMENT tr (th|td)+> -<!ELEMENT th %Flow;> -<!ELEMENT td %Flow;> - -<!ATTLIST table - %attrs; - summary %Text; #IMPLIED - width %Length; #IMPLIED - border %Pixels; #IMPLIED - frame %TFrame; #IMPLIED - rules %TRules; #IMPLIED - cellspacing %Length; #IMPLIED - cellpadding %Length; #IMPLIED - align %TAlign; #IMPLIED - bgcolor %Color; #IMPLIED - > - -<!ENTITY % CAlign "(top|bottom|left|right)"> - -<!ATTLIST caption - %attrs; - align %CAlign; #IMPLIED - > - -<!-- -colgroup groups a set of col elements. It allows you to group -several semantically related columns together. ---> -<!ATTLIST colgroup - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - col elements define the alignment properties for cells in - one or more columns. - - The width attribute specifies the width of the columns, e.g. - - width=64 width in screen pixels - width=0.5* relative width of 0.5 - - The span attribute causes the attributes of one - col element to apply to more than one column. ---> -<!ATTLIST col - %attrs; - span %Number; "1" - width %MultiLength; #IMPLIED - %cellhalign; - %cellvalign; - > - -<!-- - Use thead to duplicate headers when breaking table - across page boundaries, or for static headers when - tbody sections are rendered in scrolling panel. - - Use tfoot to duplicate footers when breaking table - across page boundaries, or for static footers when - tbody sections are rendered in scrolling panel. - - Use multiple tbody sections when rules are needed - between groups of table rows. ---> -<!ATTLIST thead - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tfoot - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tbody - %attrs; - %cellhalign; - %cellvalign; - > - -<!ATTLIST tr - %attrs; - %cellhalign; - %cellvalign; - bgcolor %Color; #IMPLIED - > - -<!-- Scope is simpler than headers attribute for common tables --> -<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> - -<!-- th is for headers, td for data and for cells acting as both --> - -<!ATTLIST th - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - nowrap (nowrap) #IMPLIED - bgcolor %Color; #IMPLIED - width %Length; #IMPLIED - height %Length; #IMPLIED - > - -<!ATTLIST td - %attrs; - abbr %Text; #IMPLIED - axis CDATA #IMPLIED - headers IDREFS #IMPLIED - scope %Scope; #IMPLIED - rowspan %Number; "1" - colspan %Number; "1" - %cellhalign; - %cellvalign; - nowrap (nowrap) #IMPLIED - bgcolor %Color; #IMPLIED - width %Length; #IMPLIED - height %Length; #IMPLIED - > - diff --git a/sources/scala/tools/scalai/Code.java b/sources/scala/tools/scalai/Code.java deleted file mode 100644 index ee4e3a1a88..0000000000 --- a/sources/scala/tools/scalai/Code.java +++ /dev/null @@ -1,129 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Code.java,v 1.13 2002/09/06 13:04:01 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -public class Code { - - //######################################################################## - // Public Cases - - public case Block(Code[] stats, Code value); - - public case Label(Symbol symbol, Variable[] variables, Code expression); - - public case Create(ScalaTemplate template); - public case CreateArray(Class component, Code size); - public case Invoke(Code target, Function function, Code[] arguments, int pos); - public case Load(Code target, Variable variable); - public case Store(Code target, Variable variable, Code expression); - - public case Synchronized(Code object, Code expression); - public case If(Code cond, Code thenp, Code elsep); - public case Or(Code lf, Code rg); - public case And(Code lf, Code rg); - public case Switch(Code test, int[] tags, Code[] bodies, Code otherwise); - - public case IsAs(Code target, Type type, Class base, boolean cast); - - public case Literal(Object value); - public case Self; - public case Null; - - //######################################################################## - // Public Methods - - public String toString() { - switch (this) { - - case Block(Code[] stats, Code value): - StringBuffer buffer = new StringBuffer(); - buffer.append("Block([").append('\n'); - for (int i = 0; i < stats.length; i++) { - if (i > 0) buffer.append(",\n"); - buffer.append(stats[i]); - } - buffer.append("], ").append(value).append(")"); - return buffer.toString(); - - case Label(Symbol symbol, Variable[] variables, Code expression): - StringBuffer buffer = new StringBuffer(); - buffer.append("Label(").append(symbol).append(",["); - for (int i = 0; i < variables.length; i++) { - if (i > 0) buffer.append(",\n"); - buffer.append(variables[i]); - } - buffer.append("],").append(expression).append(")"); - return buffer.toString(); - - case Create(ScalaTemplate template): - return "Create(" + template + ")"; - - case CreateArray(Class component, Code size): - return "CreateArray(" + component.getName() + "," + size + ")"; - - case Invoke(Code target, Function function, Code[] arguments, int pos): - StringBuffer buffer = new StringBuffer(); - buffer.append("Invoke(" + target + "," + function + "," + "[\n"); - for (int i = 0; i < arguments.length; i++) { - if (i > 0) buffer.append(",\n"); - buffer.append(arguments[i]); - } - buffer.append("])"); - return buffer.toString(); - - case Load(Code target, Variable variable): - return "Load(" + target + "," + variable + ")"; - - case Store(Code target, Variable variable, Code expression): - return "Store(" + target + "," + variable + "," + expression + ")"; - - case If(Code cond, Code thenp, Code elsep): - return "If(" + cond + "," + thenp + "," + elsep + ")"; - - case Or(Code lf, Code rg): - return "Or(" + lf + "," + rg + ")"; - - case And(Code lf, Code rg): - return "And(" + lf + "," + rg + ")"; - - case Switch(Code test, int[] tags, Code[] bodies, Code otherwise): - StringBuffer buffer = new StringBuffer(); - buffer.append("Switch(" + test + ",\n"); - for (int i = 0; i < bodies.length; i++) { - buffer.append(tags[i]).append(" => ").append(bodies[i]); - buffer.append(",\n"); - } - buffer.append("_ => ").append(otherwise); - buffer.append(")"); - return buffer.toString(); - - case IsAs(Code target, Type type, Class base, boolean cast): - return "IsAs(" + type + "," + type + "," + base + "," + cast +")"; - - case Literal(Object value): - return "Literal(" + value + ")"; - - case Self: - return "Self"; - - case Null: - return "Null"; - - default: - throw Debug.abort("illegal code", this); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/CodeBuffer.java b/sources/scala/tools/scalai/CodeBuffer.java deleted file mode 100644 index 243075e9ea..0000000000 --- a/sources/scala/tools/scalai/CodeBuffer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: CodeBuffer.java,v 1.3 2002/06/13 15:24:14 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -public class CodeBuffer { - - //######################################################################## - // Private Fields - - private Code[] buffer; - private int size; - - //######################################################################## - // Public Constructors - - public CodeBuffer() { - this.buffer = null; - this.size = 0; - } - - //######################################################################## - // Public Methods - - public CodeBuffer append(Code code) { - switch (code) { - - case Block(Code[] stats, Code value): - insure(stats.length + 1); - for (int i = 0; i < stats.length; i++) buffer[size++] = stats[i]; - buffer[size++] = value; - return this; - - default: - insure(1); - buffer[size++] = code; - return this; - } - } - - public Code code(Code value) { - if (size == 0) return value; - Code[] stats = buffer; - if (size != stats.length) { - Code[] array = new Code[size]; - System.arraycopy(stats, 0, array, 0, size); - stats = array; - } - return Code.Block(stats, value); - } - - //######################################################################## - // Private Methods - - private void insure(int count) { - if (buffer == null) { - buffer = new Code[count]; - } else { - if (size + count < buffer.length) return; - Code[] array = new Code[size + Math.max(count, size)]; - System.arraycopy(buffer, 0, array, 0, size); - buffer = array; - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/CodeContainer.java b/sources/scala/tools/scalai/CodeContainer.java deleted file mode 100644 index cbbdc5a2e3..0000000000 --- a/sources/scala/tools/scalai/CodeContainer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: CodeContainer.java,v 1.1 2002/06/06 11:42:25 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scala.tools.util.SourceFile; - -import scalac.symtab.Symbol; - -public class CodeContainer { - - //######################################################################## - // Public Constructors - - public CodeContainer( - SourceFile source, Symbol symbol, Code code, int stacksize) - { - this.source = source; - this.symbol = symbol; - this.code = code; - this.stacksize = stacksize; - } - - //######################################################################## - // Public Fields - - public final SourceFile source; - public final Symbol symbol; - public final Code code; - public final int stacksize; - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/CodeGenerator.java b/sources/scala/tools/scalai/CodeGenerator.java deleted file mode 100644 index 2da6143da2..0000000000 --- a/sources/scala/tools/scalai/CodeGenerator.java +++ /dev/null @@ -1,20 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: CodeGenerator.java,v 1.1 2002/06/06 11:42:25 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -public abstract class CodeGenerator { - - //######################################################################## - // Public Methods - - public abstract CodeContainer generate(); - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/CodePromise.java b/sources/scala/tools/scalai/CodePromise.java deleted file mode 100644 index 362d765f64..0000000000 --- a/sources/scala/tools/scalai/CodePromise.java +++ /dev/null @@ -1,45 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: CodePromise.java,v 1.1 2002/06/06 11:42:25 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -public final class CodePromise { - - //######################################################################## - // Private Fields - - private CodeGenerator generator; - private CodeContainer container; - - //######################################################################## - // Public Constructors - - public CodePromise(CodeGenerator generator) { - this.generator = generator; - this.container = null; - } - - public CodePromise(CodeContainer container) { - this.generator = null; - this.container = container; - } - - //######################################################################## - // Public Methods - - public CodeContainer force() { - if (container == null) { - container = generator.generate(); - generator = null; - } - return container; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Compiler.java b/sources/scala/tools/scalai/Compiler.java deleted file mode 100644 index d51d957097..0000000000 --- a/sources/scala/tools/scalai/Compiler.java +++ /dev/null @@ -1,414 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Compiler.java,v 1.19 2002/10/01 16:14:07 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Proxy; -import java.lang.reflect.InvocationHandler; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; -import java.util.Iterator; - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import scalac.CompilationUnit; -import scalac.Global; -import scalac.ast.Tree; -import scalac.ast.Tree.ValDef; -import scalac.ast.TreeGen; -import scalac.symtab.Definitions; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; - -import scala.runtime.RunTime; - -public class Compiler { - - //######################################################################## - - private final Global global; - private final Definitions definitions; - private final Constants constants; - private final ClassLoader loader; - private final Environment environment; - private final Map/*<Class,Set<ScalaTemplate>>*/ templates; - private final Evaluator evaluator; // !!! remove - private final Map any_methods; - private final Map sources; - - public Compiler(Global global, Map templates, Evaluator evaluator) { - this.global = global; - this.definitions = global.definitions; - this.constants = new Constants(); - this.loader = new PathClassLoader(global.classPath.getRoot()); - scala.runtime.RunTime.setClassLoader(loader); - JavaMirror mirror = new JavaMirror(definitions, loader); - this.environment = new Environment(this, mirror); - this.templates = templates; - this.evaluator = evaluator; - this.any_methods = new HashMap(); - this.sources = new HashMap(); - - SourceFile compiled = global.getSourceFile("<<compiled code>>", ""); - - environment.insertFunction(definitions.STRING_PLUS, Function.StringPlus); // !!! - // !!! ANY_PLUS_STRING is commented out in definitions - // !!! environment.insertFunction(definitions.ANY_PLUS_STRING, Function.StringPlus); // !!! - environment.insertFunction(definitions.THROWABLE_THROW, Function.Throw); - // !!! environment.insertFunction(definitions.MATCH, ...); - // !!! environment.insertFunction(definitions.IS, ...); - // !!! environment.insertFunction(definitions.AS, ...); - - java.lang.reflect.Method getInvocationHandler_method = null; - try { - getInvocationHandler_method = Proxy.class.getMethod( - "getInvocationHandler", - new Class[] {Object.class}); - } catch (Exception exception) { - throw Debug.abort("getInvocationHandler", exception); - } - - // !!! method java.lang.Object.clone() - - java.lang.reflect.Method equals_method = null; - try { - equals_method = Object.class.getMethod("equals", - new Class[] {Object.class}); - } catch (Exception exception) { - throw Debug.abort("equals", exception); - } - // !!! should we have a symbol Any.equals as for hashcode and toString? - Symbol equals_symbol = - definitions.OBJECT_CLASS.lookup(Names.equals); - assert equals_symbol != Symbol.NONE; - CodePromise equals_code = new CodePromise( - new CodeContainer( - compiled, - equals_symbol, - Code.Invoke( - Code.Invoke( - Code.Null, - Function.JavaMethod(getInvocationHandler_method), - new Code[] { - Code.Self}, - 0), - Function.JavaMethod(equals_method), - new Code[] { - Code.Load( - Code.Null, Variable.Argument(0))}, - 0), - 0)); - any_methods.put(definitions.ANY_EQUALS, equals_code); - any_methods.put(equals_method, equals_code); - environment.insertFunction(definitions.ANY_EQUALS, - Function.JavaMethod(equals_method)); - Override equals_override = Override.empty(); - equals_override.insert(equals_method).insert(definitions.ANY_EQUALS); - environment.insertOverride(definitions.ANY_EQUALS, equals_override); - - // !!! method java.lang.Object.equals(Object) - // !!! method java.lang.Object.finalize() - // !!! method java.lang.Object.getClass() - - java.lang.reflect.Method hashCode_method = null; - try { - hashCode_method = Object.class.getMethod("hashCode", new Class[0]); - } catch (Exception exception) { - throw Debug.abort("hashCode", exception); - } - CodePromise hashCode_code = new CodePromise( - new CodeContainer( - compiled, - definitions.ANY_HASHCODE, - Code.Invoke( - Code.Self, Function.HashCode, new Code[0], - 0), - 0)); - any_methods.put(definitions.ANY_HASHCODE, hashCode_code); - any_methods.put(hashCode_method, hashCode_code); - environment.insertFunction(definitions.ANY_HASHCODE, - Function.JavaMethod(hashCode_method)); - Override hashCode_override = Override.empty(); - hashCode_override.insert(hashCode_method).insert(definitions.ANY_HASHCODE); - environment.insertOverride(definitions.ANY_HASHCODE, hashCode_override); - - // !!! method java.lang.Object.notify() - // !!! method java.lang.Object.notifyAll() - - java.lang.reflect.Method toString_method = null; - try { - toString_method = Object.class.getMethod("toString", new Class[0]); - } catch (Exception exception) { - throw Debug.abort("toString", exception); - } - CodePromise toString_code = new CodePromise( - new CodeContainer( - compiled, - definitions.ANY_TOSTRING, - Code.Invoke( - Code.Self, Function.ToString, new Code[0], - 0), - 0)); - any_methods.put(definitions.ANY_TOSTRING, toString_code); - any_methods.put(toString_method, toString_code); - environment.insertFunction(definitions.ANY_TOSTRING, - Function.JavaMethod(toString_method)); - Override toString_override = Override.empty(); - toString_override.insert(toString_method).insert(definitions.ANY_TOSTRING); - environment.insertOverride(definitions.ANY_TOSTRING, toString_override); - - // !!! method java.lang.Object.wait() - // !!! method java.lang.Object.wait(long) - // !!! method java.lang.Object.wait(long, int) - - environment.insertFunction(definitions.OBJECT_EQ, Function.Eq); - Override eq_override = Override.empty().insert(definitions.OBJECT_EQ); - environment.insertOverride(definitions.OBJECT_EQ, eq_override); - - environment.insertFunction(definitions.OBJECT_NE, Function.Ne); - Override ne_override = Override.empty().insert(definitions.OBJECT_NE); - environment.insertOverride(definitions.OBJECT_NE, ne_override); - - environment.insertFunction(definitions.ANY_EQEQ, Function.EqEq); - Override eqeq_override = Override.empty().insert(definitions.ANY_EQEQ); - environment.insertOverride(definitions.ANY_EQEQ, eqeq_override); - - environment.insertFunction(definitions.ANY_BANGEQ, Function.BangEq); - Override bangeq_override = Override.empty().insert(definitions.ANY_BANGEQ); - environment.insertOverride(definitions.ANY_BANGEQ, bangeq_override); - } - - //######################################################################## - - public ScalaTemplate load(Symbol symbol, Tree.ClassDef tree) { - SourceFile source = (SourceFile)sources.remove(tree); - assert tree != null : Debug.show(symbol); - return load(source, symbol, tree); - } - - public ScalaTemplate load(SourceFile source, Symbol symbol, Tree.ClassDef tree) { - assert tree.tparams .length == 0 : Debug.show(tree); - assert tree.vparams .length == 1 : Debug.show(tree); - assert tree.vparams[0].length == 0 : Debug.show(tree); - return compileTemplate(source, symbol, tree.impl.body); - } - - public ScalaTemplate compileTemplate(SourceFile source, Symbol symbol, Tree[] body) { - Set supertypes = new HashSet(); - List interfaces = new ArrayList(); - getTypes(supertypes, interfaces, symbol); - Class[] proxytype = new Class[interfaces.size()]; - interfaces.toArray(proxytype); - Class proxy = Proxy.getProxyClass(loader, proxytype); - Function constructor = getConstructor(proxy); - Type[] bases = symbol.parents(); - Map methods; - List fields; - if (symbol.isInterface() || bases.length == 0) { - methods = new HashMap(any_methods); - fields = new ArrayList(); - } else { - Template template = environment.lookupTemplate(bases[0].symbol()); - switch (template) { - - case Global(ScalaTemplate template_): // !!! - methods = template_.getMethods(); - fields = template_.getFields(); - break; - - case JavaClass(_): - methods = new HashMap(any_methods); - fields = new ArrayList(); - break; - - default: - throw Debug.abort("illegal case", template); - } - } - for (int i = 0; i < body.length; i++) { - addTemplateMember(source, methods, fields, body[i]); - } - ScalaTemplate template = new ScalaTemplate( - evaluator, symbol, proxy, constructor, methods, fields.toArray()); - Set set = (Set)templates.get(proxy); - if (set == null) templates.put(proxy, set = new HashSet()); - set.add(template); - return template; - } - - //######################################################################## - - public Variable getModule(Symbol symbol) { - return environment.lookupVariable(symbol); - } - - public Function getMethod(Symbol symbol) { - return environment.lookupFunction(symbol); - } - - public CodePromise compile(SourceFile source, Symbol symbol, Tree.DefDef tree) { - assert tree.tparams.length == 0 : Debug.show(tree); - assert tree.vparams.length == 1 : Debug.show(tree); - return new CodePromise(new ScalaFunction(this, source, symbol, tree.vparams[0],tree.rhs)); - } - - //######################################################################## - // - - public void compile(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) declare(units[i].source, units[i].body); - } - - public CodeContainer compile(SourceFile source, Symbol owner, Tree tree, Symbol[] params) { - ExpressionContext context = new ExpressionContext(environment, source, owner); - ExpressionCompiler worker = new ExpressionCompiler(definitions, global.primitives, constants, context, params); - return worker.compile(tree); - } - - //######################################################################## - // Private Methods - - - private void declare(SourceFile source, Tree[] trees) { - for (int i = 0; i < trees.length; i++) declare(source, trees[i]); - } - - private void declare(SourceFile source, Tree tree) { - Symbol symbol = tree.symbol(); - switch (tree) { - - case Empty: - return; - - case ClassDef(_, _, _, _, _, _): - sources.put(tree, source); - environment.insertClassDef(symbol, (Tree.ClassDef)tree); - return; - - // !!! these could be removed - case PackageDef(Tree packaged, Tree.Template(Tree[] bases, Tree[] body)): - assert packaged.symbol().isPackage() : Debug.show(tree); // !!! was isJavaPackage - assert bases.length == 0 : Debug.show(tree); - declare(source, body); - return; - - default: - throw Debug.abort("illegal case"); - } - } - - //######################################################################## - // Private Methods - - - private Symbol newGlobalVariable(Type type, Object value) { - Symbol symbol = definitions.ROOT_CLASS.newField( - Position.NOPOS, 0, Name.fromString(value.toString())); - symbol.setInfo(type); - environment.insertVariable(symbol, Variable.Global(value)); - return symbol; - } - - //######################################################################## - // Private Methods - template types - - private void getTypes(Set supertypes, List interfaces, Symbol type) { - if (supertypes.contains(type)) return; else supertypes.add(type); - if (!type.isExternal()) { - Type[] basetypes = type.parents(); - for (int i = 0; i < basetypes.length; i++) { - getTypes(supertypes, interfaces, basetypes[i].symbol()); - } - return; - } else { - Template template = environment.lookupTemplate(type); - switch (template) { - case JavaClass(Class clasz): - getTypes(supertypes, interfaces, clasz); - return; - default: - Debug.abort("illegal template", template); - } - } - } - - private void getTypes(Set supertypes, List interfaces, Class type) { - if (supertypes.contains(type)) return; else supertypes.add(type); - if (type.isInterface()) { - interfaces.add(type); - } else { - Class supertype = type.getSuperclass(); - if (supertype != null) getTypes(supertypes, interfaces, supertype); - Class[] basetypes = type.getInterfaces(); - for (int i = 0; i < basetypes.length; i++) { - getTypes(supertypes, interfaces, basetypes[i]); - } - } - } - - //######################################################################## - // Private Methods - template constructors - - private static final Class[] CSTR_PARAMS = - new Class[] { InvocationHandler.class }; // !!! remove ? - - private Function getConstructor(Class proxy) { - try { - return Function.JavaConstructor(proxy.getConstructor(CSTR_PARAMS)); - } catch (NoSuchMethodException exception) { - throw Debug.abort(exception); - } - } - - //######################################################################## - // Private Methods - template members - - private void addTemplateMember(SourceFile source, Map methods, List fields, Tree tree) { - Symbol symbol = tree.symbol(); - switch (tree) { - - case Empty: - return; - - case ClassDef(_, _, _, _, _, _): - sources.put(tree, source); - environment.insertClassDef(symbol, (Tree.ClassDef)tree); - return; - - case ValDef(_, _, _, Tree body): - assert body == Tree.Empty : Debug.show(tree); - assert !symbol.isModule() : Debug.show(tree); - int index = fields.size(); - fields.add(constants.zero(symbol.type())); - environment.insertVariable(symbol, Variable.Member(index)); - return; - - case DefDef(_, _, _, _, _, _): - assert !methods.containsKey(symbol) : Debug.show(symbol); - CodePromise function = compile(source, symbol, (Tree.DefDef)tree); - Override override = environment.lookupOverride(symbol); - for (Iterator i = override.iterator(); i.hasNext(); ) { - methods.put(i.next(), function); - } - environment.insertFunction(symbol, Function.Member(symbol)); - return; - - default: - throw Debug.abort("illegal tree", tree); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Constants.java b/sources/scala/tools/scalai/Constants.java deleted file mode 100644 index 7d87d3f6ab..0000000000 --- a/sources/scala/tools/scalai/Constants.java +++ /dev/null @@ -1,97 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Constants.java,v 1.3 2002/07/09 08:35:02 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scala.runtime.RunTime; - -import scalac.symtab.Type; -import scalac.symtab.TypeTags; -import scalac.util.Debug; - -public class Constants { - - //######################################################################## - // Public Constants - kinds - - // !!! use literal constants ? - public static final int UNIT = TypeTags.UNIT; - public static final int BOOLEAN = TypeTags.BOOLEAN; - public static final int BYTE = TypeTags.BYTE; - public static final int SHORT = TypeTags.SHORT; - public static final int INT = TypeTags.INT; - public static final int LONG = TypeTags.LONG; - public static final int FLOAT = TypeTags.FLOAT; - public static final int DOUBLE = TypeTags.DOUBLE; - public static final int CHAR = TypeTags.CHAR; - public static final int STRING = TypeTags.STRING; - public static final int OBJECT = TypeTags.STRING + 1; - - //######################################################################## - // Public Methods - literal - - // !!! remove ? - public Object literal( ) { return RunTime.box_uvalue(); } - public Object literal(boolean value) { return new Boolean (value); } - public Object literal(byte value) { return new Byte (value); } - public Object literal(short value) { return new Short (value); } - public Object literal(char value) { return new Character(value); } - public Object literal(int value) { return new Integer (value); } - public Object literal(long value) { return new Long (value); } - public Object literal(float value) { return new Float (value); } - public Object literal(double value) { return new Double (value); } - public Object literal(Object value) { return value ; } - - // !!! remove ? - public Object literal(int kind, Object value) { - switch (kind) { - case UNIT : return literal(); - case BOOLEAN: return literal(((Boolean)value).booleanValue()); - case BYTE : return literal(((Number)value).byteValue()); - case SHORT : return literal(((Number)value).shortValue()); - case INT : return literal(((Number)value).intValue()); - case LONG : return literal(((Number)value).longValue()); - case FLOAT : return literal(((Number)value).floatValue()); - case DOUBLE : return literal(((Number)value).doubleValue()); - case CHAR : return literal((char)((Number)value).intValue()); - case STRING : return literal(value); - case OBJECT : return literal(value); - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Public Methods - zero - - public Object zero(Type type) { - switch (type) { - case TypeRef(_, _, _) : return literal(null); - case UnboxedArrayType(_) : return literal(null); - case UnboxedType(int kind): return zero(kind); - default: throw Debug.abort("illegal type", type); - } - } - - public Object zero(int kind) { - switch (kind) { - case UNIT : return literal(); - case BOOLEAN: return literal(false); - case BYTE : return literal((byte)0); - case SHORT : return literal((short)0); - case CHAR : return literal((char)0); - case INT : return literal((int)0); - case LONG : return literal((long)0); - case FLOAT : return literal((float)0); - case DOUBLE : return literal((double)0); - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Environment.java b/sources/scala/tools/scalai/Environment.java deleted file mode 100644 index 0099bcff3f..0000000000 --- a/sources/scala/tools/scalai/Environment.java +++ /dev/null @@ -1,251 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Environment.java,v 1.13 2002/10/01 16:14:07 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.util.Map; -import java.util.HashMap; - -import scalac.ast.Tree.ClassDef; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.util.Names; -import scalac.util.Debug; - -public class Environment { - - //######################################################################## - // Private Fields - - private final Compiler compiler; - private final JavaMirror mirror; - private final Map/*<Symbol,ClassDef>*/ classdefs; - private final Map/*<Symbol,Template>*/ templates; - private final Map/*<Symbol,Function>*/ functions; - private final Map/*<Symbol,Variable>*/ variables; - private final Map/*<Symbol,Override>*/ overrides; - - //######################################################################## - // Public Constructors - - public Environment(Compiler compiler, JavaMirror mirror) { - this.compiler = compiler; - this.mirror = mirror; - this.classdefs = new HashMap(); - this.templates = new HashMap(); - this.functions = new HashMap(); - this.variables = new HashMap(); - this.overrides = new HashMap(); - } - - //######################################################################## - // Public Methods - translate - - public Class getClass(Symbol symbol) { - assert symbol.isClass(): Debug.show(symbol); - Template value = lookupTemplate(symbol); - switch (value) { - case Global(ScalaTemplate template): - return template.getProxy(); - case JavaClass(Class clasz): - return clasz; - default: - throw Debug.abort("illegal case", value); - } - } - - public Class getClass(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, _): - return getClass(symbol); - case UnboxedType(int kind): - return mirror.getClass(kind); - case UnboxedArrayType(Type element): - return mirror.getArray(getClass(element)); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## - // Public Methods - insert - - public ClassDef insertClassDef(Symbol symbol, ClassDef classdef) { - assert symbol.isType() : Debug.show(symbol); - assert Debug.log("insert classdef: ", symbol); - Object value = classdefs.put(symbol, classdef); - assert value == null : Debug.show(symbol) + " -> " + value; - assert !templates.containsKey(symbol) : Debug.show(symbol); - return classdef; - } - - private Template insertTemplate(Symbol symbol, Template template) { - assert symbol.isType() : Debug.show(symbol); - assert Debug.log("insert template: ", symbol); - Object value = templates.put(symbol, template); - assert !classdefs.containsKey(symbol) : Debug.show(symbol); - assert value == null : Debug.show(symbol) + " -> " + value; - return template; - } - - public Function insertFunction(Symbol symbol, Function function) { - assert symbol.isTerm() : Debug.show(symbol); - assert Debug.log("insert function: ", symbol); - Object value = functions.put(symbol, function); - assert value == null : Debug.show(symbol) + " -> " + value; - return function; - } - - public Variable insertVariable(Symbol symbol, Variable variable) { - assert symbol.isTerm() : Debug.show(symbol); - assert Debug.log("insert variable: ", symbol); - Object value = variables.put(symbol, variable); - assert value == null : Debug.show(symbol) + " -> " + value; - return variable; - } - - public Override insertOverride(Symbol symbol, Override override) { - assert symbol.isTerm() : Debug.show(symbol); - assert Debug.log("insert override: ", symbol); - Object value = overrides.put(symbol, override); - assert value == null : Debug.show(symbol) + " -> " + value; - return override; - } - - //######################################################################## - // Public Methods - lookup - - public Template lookupTemplate(Symbol symbol) { - assert symbol.isType() : Debug.show(symbol); - Object value = templates.get(symbol); - if (value != null) return (Template)value; - if (symbol.isExternal()) { - Template template = Template.JavaClass(mirror.getClass(symbol)); - return insertTemplate(symbol, template); - } else { - return loadTemplate(symbol); - } - } - - public Function lookupFunction(Symbol symbol) { - assert symbol.isTerm() : Debug.show(symbol); - Object value = functions.get(symbol); - if (value != null) return (Function)value; - if (symbol.isExternal()) { - Function function = (symbol.name == Names.CONSTRUCTOR) ? - Function.JavaConstructor(mirror.getConstructor(symbol)) : - Function.JavaMethod(mirror.getMethod(symbol)); - return insertFunction(symbol, function); - } else { - return (Function)loadOwnerThenGet("function", symbol, functions); - } - } - - public Variable lookupVariable(Symbol symbol) { - assert symbol.isTerm() : Debug.show(symbol); - Object value = variables.get(symbol); - if (value != null) return (Variable)value; - if (symbol.isJava() && symbol.isModule()) { - // !!! This should never happen. This value will never be used. - Class clasz = mirror.getClass(symbol.moduleClass()); - Variable variable = Variable.Global(clasz); - return insertVariable(symbol, variable); - } else if (symbol.isExternal()) { - Variable variable = Variable.JavaField(mirror.getField(symbol)); - return insertVariable(symbol, variable); - } else if (symbol.isModule() && symbol.isStatic()) { - switch (lookupTemplate(symbol.moduleClass())) { - case Global(ScalaTemplate template): - Variable variable = Variable.Module(template, null); - return insertVariable(symbol, variable); - default: - throw Debug.abort("illegal case", symbol); - } - } else { - return (Variable)loadOwnerThenGet("variable", symbol, variables); - } - } - - public Override lookupOverride(Symbol symbol) { - assert symbol.isTerm() : Debug.show(symbol); - Object value = overrides.get(symbol); - if (value != null) return (Override)value; - return loadOwnerOverridesThenGet(symbol); - } - - //######################################################################## - // Private Methods - template loading - - private Object loadOwnerThenGet(String what, Symbol symbol, Map table) { - loadOwner(what, symbol); - Object value = table.get(symbol); - assert value != null : Debug.show(symbol) + " -> " + value; - return value; - } - - private void loadOwner(String what, Symbol symbol) { - assert Debug.log("search ", what, ": ", symbol); - assert symbol.owner().isType() : Debug.show(symbol); - assert!symbol.owner().isExternal() : Debug.show(symbol); - loadTemplate(symbol.owner()); - } - - private Template loadTemplate(Symbol symbol) { - Object test1 = classdefs.remove(symbol); - if (test1 != null) return loadTemplate(symbol, (ClassDef)test1); - loadOwner("template", symbol); - Object test2 = classdefs.remove(symbol); - if (test2 != null) return loadTemplate(symbol, (ClassDef)test2); - Object value = templates.get(symbol); - assert value != null : Debug.show(symbol) + " -> " + value; - return (Template)value; - } - - private Template loadTemplate(Symbol symbol, ClassDef classdef) { - Template template = Template.Global(compiler.load(symbol, classdef)); - return insertTemplate(symbol, template); - } - - //######################################################################## - // Private Methods - override loading - - private Override loadOwnerOverridesThenGet(Symbol symbol) { - assert Debug.log("search override: ", symbol); - assert symbol.owner().isType() : Debug.show(symbol); - loadTemplateOverrides(symbol.owner()); - Object value = overrides.get(symbol); - assert value != null : Debug.show(symbol) + " -> " + value; - return (Override)value; - } - - private void loadTemplateOverrides(Symbol symbol) { - Type[] bases = symbol.parents(); - SymbolIterator i = symbol.members().iterator(); - while (i.hasNext()) loadMethodOverride(bases, i.next()); - } - - private void loadMethodOverride(Type[] bases, Symbol symbol) { - if (!symbol.isMethod()) return; - Override override = Override.empty().insert(symbol); - if (!symbol.isInitializer()) { - if (symbol.isExternal()) override.insert(mirror.getMethod(symbol)); - for (int i = 0; i < bases.length; i++) { - Symbol overridden = symbol.overriddenSymbol(bases[i], true); - if (overridden == Symbol.NONE) continue; - assert Debug.log("update override: ",symbol," <- ",overridden); - override.insert(lookupOverride(overridden)); - } - } - insertOverride(symbol, override); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Evaluator.java b/sources/scala/tools/scalai/Evaluator.java deleted file mode 100644 index a96d60de69..0000000000 --- a/sources/scala/tools/scalai/Evaluator.java +++ /dev/null @@ -1,602 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Evaluator.java,v 1.40 2002/10/04 15:37:10 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import java.lang.reflect.Array; -import java.lang.reflect.Modifier; -import java.lang.reflect.Proxy; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import scala.runtime.RunTime; - -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Names; - -public class Evaluator { - - //######################################################################## - // Private Classes - - // !!! remove ? - // !!! is it correct to extend EvaluatorException? - private static class LabelException extends EvaluatorException { - - public final Symbol symbol; - public final Object[] args; - - public LabelException(Symbol symbol, Object[] args) { - this.symbol = symbol; - this.args = args; - } - } - - public static class EvaluationStack { - - public final EvaluationStack stack; - public final SourceFile source; - public final Symbol symbol; - public final Object self; - public final Object[] args; - public final Object[] vars; - - public int pos; - - public EvaluationStack(EvaluationStack stack, CodeContainer code, - Object self, Object[] args) - { - this.stack = stack; - this.source = code.source; - this.symbol = code.symbol; - this.self = self; - this.args = args; - this.vars = new Object[code.stacksize]; - } - - } - - //######################################################################## - // Private Fields - - private final Map/*<Class,Set<ScalaTemplate>>*/ templates; - private final EvaluatorException trace; - private EvaluationStack stack; - - //######################################################################## - // Public Constructors - - public Evaluator(Map templates) { - this.templates = templates; - this.trace = new EvaluatorException(); - this.stack = null; - } - - //######################################################################## - // Public Methods - - public Object toString(Object object) { - try { - return String.valueOf(object); - } catch (Throwable exception) { - return throw_(exception); - } - } - - public Object evaluate(Variable module) { - return load(null, module); - } - - public Object evaluate(Variable module, Function method, Object[] args) { - return invoke(load(null, module), method, args); - } - - public Object evaluate(CodeContainer code) { - return evaluate(code, null, new Object[0]); - } - - public Object evaluate(CodePromise code, Object object, Object[] args) { - return evaluate(code.force(), object, args); - } - - public Object evaluate(CodeContainer code, Object object, Object[] args) { - return trace(code, object, args); - } - - //######################################################################## - // Private Methods - trace - - private Object trace(CodeContainer code, Object object, Object[] args) { - try { - try { - stack = new EvaluationStack(stack, code, object, args); - return evaluate(code.code); - } catch (EvaluatorException exception) { - throw exception; - } catch (Throwable exception) { - return throw_(exception, "trace"); - } - } catch (EvaluatorException exception) { - StringBuffer buffer = new StringBuffer(); - buffer.append(getClassName(stack.symbol.owner())); - buffer.append('.'); - buffer.append(stack.symbol.nameString()); - buffer.append('('); - buffer.append(stack.source.getFile().getName()); - int line = Position.line(stack.pos); - if (line != 0) buffer.append(':').append(line); - buffer.append(")"); - exception.addScalaCall(buffer.toString()); - throw exception; - } finally { - stack = stack.stack; - } - } - - //######################################################################## - // Private Methods - evaluate - - private Object evaluate(Code code) { - switch (code) { - - case Block(Code[] stats, Code value): - for (int i = 0; i < stats.length; i++) evaluate(stats[i]); - return evaluate(value); - - case Label(Symbol symbol, Variable[] variables, Code expression): - while (true) - try { - return evaluate(expression); - } catch (LabelException exception) { - if (exception.symbol != symbol) throw exception; - for (int i = 0; i < variables.length; i++) { - // !!! null - store(null, variables[i], exception.args[i]); - } - } - - case Synchronized(Code object, Code expression): - Object value = evaluate(object); - synchronized (value) { return evaluate(expression); } - - case If(Code cond, Code thenp, Code elsep): - Object value = evaluate(cond); - assert value instanceof Boolean : value.getClass(); - return evaluate(((Boolean)value).booleanValue() ? thenp : elsep); - - case Switch(Code test, int[] tags, Code[] bodies, Code otherwise): - Object value = evaluate(test); - assert value instanceof Integer : value.getClass(); - int tag = ((Integer)value).intValue(); - for (int i = 0; i < tags.length; i++) - if (tags[i] == tag) return evaluate(bodies[i]); - return evaluate(otherwise); - - case Literal(Object value): - return value; - - case Load(Code target, Variable variable): - return load(evaluate(target), variable); - - case Store(Code target, Variable variable, Code expression): - store(evaluate(target), variable, evaluate(expression)); - return RunTime.box_uvalue(); - - case Invoke(Code target, Function function, Code[] arguments, int pos): - Object object = evaluate(target); - Object[] args = new Object[arguments.length]; - for (int i = 0; i < args.length; i++) - args[i] = evaluate(arguments[i]); - stack.pos = pos; - return invoke(object, function, args); - - case Create(ScalaTemplate template): - return invoke(null, template.getConstructor(), - new Object[] {template.getHandler()}); - - case CreateArray(Class component, Code size): - Object length = evaluate(size); - assert length instanceof Integer : length.getClass(); - return Array.newInstance(component, ((Integer)length).intValue()); - - case IsAs(Code target, Type type, Class clasz, boolean cast): - Object object = evaluate(target); - if (object == null) return cast ? null : Boolean.FALSE; - boolean test = isInstanceOf(object, type, clasz); - return cast - ? (test ? object : throw_(getCastException(object, type))) - : (test ? Boolean.TRUE : Boolean.FALSE); - - case Or(Code lf, Code rg): - Object object = evaluate(lf); - assert object instanceof scala.Boolean : object.getClass(); - boolean value = ((scala.Boolean)object).value; - if (value) return new Boolean(value); - return evaluate(rg); - - case And(Code lf, Code rg): - Object object = evaluate(lf); - assert object instanceof scala.Boolean : object.getClass(); - boolean value = ((scala.Boolean)object).value; - if (!value) return new Boolean(value); - return evaluate(rg); - - case Null: - return null; - - case Self: - return stack.self; - - default: - throw Debug.abort("illegal code", code); - } - } - - //######################################################################## - // Private Methods - invoke - - private Object invoke(Object object, Function function, Object[] args) { - switch (function) { - - case Global(CodePromise code): - return evaluate(code, object, args); - - case Member(Symbol symbol): - return getScalaObject(object).invoke(object, symbol, args); - - case Label(Symbol symbol): - throw new LabelException(symbol, args); - - case JavaConstructor(Constructor constructor): - return invoke(object, constructor, args); - - case JavaMethod(Method method): - return invoke(object, method, args); - - case Pos: - if (object instanceof scala.Int) { - int value = ((scala.Int)object).value; - return new Integer(value); - } else if (object instanceof scala.Long) { - long value = ((scala.Long)object).value; - return new Long(value); - } else if (object instanceof scala.Float) { - float value = ((scala.Float)object).value; - return new Float(value); - } else { - double value = ((scala.Double)object).value; - return new Double(value); - } - - case Neg: - if (object instanceof scala.Int) { - int value = ((scala.Int)object).value; - return new Integer(-value); - } else if (object instanceof scala.Long) { - long value = ((scala.Long)object).value; - return new Long(-value); - } else if (object instanceof scala.Float) { - float value = ((scala.Float)object).value; - return new Float(-value); - } else { - double value = ((scala.Double)object).value; - return new Double(-value); - } - - case Throw: - assert args.length == 0 : Debug.show(args); - assert object instanceof Throwable : object.getClass(); - return throw_((Throwable)object); - - case StringPlus: - assert args.length == 1 : Debug.show(args); - //assert object instanceof String : object.getClass().getName(); - return (String.valueOf(object)).concat(String.valueOf(args[0])); - - case Eq: - assert args.length == 1 : Debug.show(args); - return object == args[0] ? Boolean.TRUE : Boolean.FALSE; - - case Ne: - assert args.length == 1 : Debug.show(args); - return object != args[0] ? Boolean.TRUE : Boolean.FALSE; - - case EqEq: - assert args.length == 1 : Debug.show(args); - return object == null ? new Boolean(args[0] == null) : new Boolean(object.equals(args[0])); // !!! - - case BangEq: - assert args.length == 1 : Debug.show(args); - return object == null ? new Boolean(args[0] != null) : new Boolean(!object.equals(args[0])); // !!! - - case HashCode: - assert args.length == 0 : Debug.show(args); - return new Integer(getScalaObject(object).hashCode()); - - case ToString: - assert args.length == 0 : Debug.show(args); - return getScalaObject(object).toString(); - - default: - throw Debug.abort("illegal function", function); - } - } - - private Object invoke(Object object, Constructor constructor,Object[]args){ - try { - return constructor.newInstance(args); - } catch (StackOverflowError exception) { - return throw_(exception); - } catch (ExceptionInInitializerError exception) { - return throw_(exception); - } catch (InvocationTargetException exception) { - return throw_(exception); - } catch (InstantiationException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n constr = " + Debug.show(constructor); - String msg3 = "\n args = " + Debug.show(args); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } catch (IllegalAccessException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n constr = " + Debug.show(constructor); - String msg3 = "\n args = " + Debug.show(args); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } catch (IllegalArgumentException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n constr = " + Debug.show(constructor); - String msg3 = "\n args = " + Debug.show(args); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } - } - - private Object invoke(Object object, Method method, Object[] args) { - try { - return method.invoke(object, args); - } catch (StackOverflowError exception) { - return throw_(exception); - } catch (NullPointerException exception) { - return throw_(exception); - } catch (ExceptionInInitializerError exception) { - return throw_(exception); - } catch (InvocationTargetException exception) { - return throw_(exception); - } catch (IllegalAccessException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n method = " + Debug.show(method); - String msg3 = "\n args = " + Debug.show(args); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } catch (IllegalArgumentException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n method = " + Debug.show(method); - String msg3 = "\n args = " + Debug.show(args); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } - } - - //######################################################################## - // Private Methods - store - - private Object store(Object object, Variable variable, Object value) { - switch (variable) { - - case Global(_): - return ((Variable.Global)variable).value = value; - - case Module(_, _): - return ((Variable.Module)variable).value = value; - - case Member(int index): - return getScalaObject(object).variables[index] = value; - - case Argument(int index): - return stack.args[index] = value; - - case Local(int index): - return stack.vars[index] = value; - - case JavaField(Field field): - return store(object, field, value); - - default: - throw Debug.abort("illegal variable", variable); - } - } - - private Object store(Object object, Field field, Object value) { - try { - field.set(object, value); - return value; - } catch (NullPointerException exception) { - return throw_(exception); - } catch (ExceptionInInitializerError exception) { - return throw_(exception); - } catch (IllegalAccessException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n field = " + Debug.show(field); - String msg3 = "\n value = " + Debug.show(value); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } catch (IllegalArgumentException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n field = " + Debug.show(field); - String msg3 = "\n value = " + Debug.show(value); - throw Debug.abort(msg1 + msg2 + msg3, exception); - } - } - - //######################################################################## - // Private Methods - load - - private Object load(Object object, Variable variable) { - switch (variable) { - - case Global(Object value): - return value; - - case Module(ScalaTemplate template, Object value): - if (value != null) return value; - value = evaluate(Code.Create(template)); - ((Variable.Module)variable).template = null; - ((Variable.Module)variable).value = value; - Symbol clasz = template.getSymbol(); - Symbol initializer = clasz.lookup(Names.INITIALIZER); - CodePromise promise = template.getMethod(initializer); - assert promise != null: Debug.show(clasz, initializer); - evaluate(promise, value, new Object[0]); - return value; - - case Member(int index): - return getScalaObject(object).variables[index]; - - case Argument(int index): - return stack.args[index]; - - case Local(int index): - return stack.vars[index]; - - case JavaField(Field field): - return load(object, field); - - default: - throw Debug.abort("illegal variable", variable); - } - } - - private Object load(Object object, Field field) { - try { - return field.get(object); - } catch (NullPointerException exception) { - return throw_(exception); - } catch (ExceptionInInitializerError exception) { - return throw_(exception); - } catch (IllegalAccessException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n field = " + Debug.show(field); - throw Debug.abort(msg1 + msg2, exception); - } catch (IllegalArgumentException exception) { - String msg1 = "\n object = " + Debug.show(object); - String msg2 = "\n field = " + Debug.show(field); - throw Debug.abort(msg1 + msg2, exception); - } - } - - //######################################################################## - // Private Methods - throw - - private Object throw_(Throwable exception) { - return throw_(exception, null); - } - - private Object throw_(Throwable exception, String method) { - if (exception.getCause() != null && ( - exception instanceof ExceptionInInitializerError || - exception instanceof InvocationTargetException)) - exception = exception.getCause(); - if (trace.getCause() != exception) trace.reset(exception); - trace.addScalaLeavePoint(getClass().getName(), method); - throw trace; - } - - //######################################################################## - // Private Methods - !!! - - private ScalaObject getScalaObject(Object object) { - assert object instanceof Proxy: object.getClass(); - Object handler = object == null - ? throw_(new NullPointerException()) - : Proxy.getInvocationHandler(object); - assert handler instanceof ScalaObject: handler.getClass(); - return (ScalaObject)handler; - } - - private Symbol getScalaSymbol(Object object) { - Class clasz = object.getClass(); - if (!(object instanceof Proxy)) return null; - Object handler = Proxy.getInvocationHandler(object); - if (!(handler instanceof ScalaObject)) return null; - return ((ScalaObject)handler).template.getSymbol(); - } - - private boolean isInstanceOf(Object object, Type type, Class base) { - Class clasz = object.getClass(); - switch (type) { - case TypeRef(_, Symbol symbol, _): - Symbol scala = getScalaSymbol(object); - if (scala != null) return scala.isSubClass(symbol); - return base.isAssignableFrom(clasz); - case UnboxedArrayType(Type element): - return base.isAssignableFrom(clasz); - default: - throw Debug.abort("illegal case", type); - } - } - - private String getClassNameOf(Object object) { - Symbol symbol = getScalaSymbol(object); - if (symbol != null) getClassName(symbol); - Class clasz = object.getClass(); - if (!clasz.isArray()) return clasz.getName(); - return getClassName(clasz); - } - - // !!! public - public String getClassName(Symbol clasz) { - SymbolNameWriter writer = new SymbolNameWriter().setNameDecoding(true); - return writer.toString(clasz); - } - - private String getClassName(Class clasz) { - if (clasz.isArray()) - return getClassName(clasz.getComponentType()) + "[]"; - Set scalas = (Set)templates.get(clasz); - if (scalas == null) return clasz.getName(); - StringBuffer buffer = new StringBuffer(); - boolean separator = false; - if (scalas.size() != 1) buffer.append('('); - for (Iterator i = scalas.iterator(); i.hasNext(); separator = true) { - if (separator) buffer.append(" | "); - ScalaTemplate scala = (ScalaTemplate)i.next(); - buffer.append(getClassName(scala.getSymbol())); - } - if (scalas.size() != 1) buffer.append(')'); - return buffer.toString(); - } - - private String getClassName(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, _): - return getClassName(symbol); - case UnboxedArrayType(Type element): - return getClassName(element) + "[]"; - case UnboxedType(_): - return type.toString(); - default: - throw Debug.abort("illegal case"); - } - } - - private ClassCastException getCastException(Object object, Type type) { - String from = "class " + getClassNameOf(object); - String to = "class " + getClassName(type); - return new ClassCastException(from + " is not an instance of " + to); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/EvaluatorException.java b/sources/scala/tools/scalai/EvaluatorException.java deleted file mode 100644 index f8c32cca8b..0000000000 --- a/sources/scala/tools/scalai/EvaluatorException.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scalai; - -import java.io.StringWriter; -import java.io.PrintWriter; -import java.util.List; -import java.util.ArrayList; - -import scalac.Global; -import scalac.symtab.Symbol; - -public class EvaluatorException extends RuntimeException { - - //######################################################################## - // Private Fields - - private final List stack; - - private Throwable cause; - private StackTraceElement[] trace; - private int entry; - - //######################################################################## - // Public Constructors - - public EvaluatorException() { - this.stack = new ArrayList(); - } - - //######################################################################## - // Public Methods - - public void reset(Throwable cause) { - this.stack.clear(); - this.cause = cause; - this.trace = cause.getStackTrace(); - this.entry = 0; - } - - public Throwable getCause() { - return cause; - } - - public void addScalaCall(String location) { - stack.add(location); - } - - public void addScalaEntryPoint() { - // save new stack trace elements - this.trace = getCurrentTrace(); - // skip calls through interpreter - while (traceAtStartsWith(entry, "scalai.")) entry++; - // skip calls through proxy class - while (traceAtStartsWith(entry, "$Proxy")) entry++; - } - - public void addScalaLeavePoint(String clasz, String method) { - // find leave point - int leave = entry; - while (leave < trace.length && !traceAtEquals(leave, clasz, method)) - leave++; - if (leave < trace.length) { - // skip calls through reflection - while (traceAtStartsWith(leave - 1, "java.lang.reflect.")) leave--; - while (traceAtStartsWith(leave - 1, "sun.reflect.")) leave--; - } - // complete stack with java trace - for (int i = entry; i < leave; i++) stack.add(trace[i]); - if (leave == trace.length) stack.add("..."); - // free memory - this.trace = null; - this.entry = 0; - } - - public Object[] getScalaStackTrace() { - return stack.toArray(); - } - - public String getScalaErrorMessage(boolean withTrace) { - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - Throwable exception = getCause(); - writer.print(exception.toString()); - if (withTrace) { - writer.println(); - for (int i = 0; i < stack.size(); i++) { - writer.print(" at "); - writer.println(stack.get(i)); - } - Throwable cause = exception.getCause(); - if (cause != null) { - writer.print("Caused by "); - cause.printStackTrace(writer); - } - } - writer.close(); - return buffer.toString(); - } - - //######################################################################## - // Private Methods - - private boolean traceAtEquals(int index, String clasz, String method) { - if (index < 0 || trace.length <= index) return false; - if (!trace[index].getClassName().equals(clasz)) return false; - return method == null || trace[index].getMethodName().equals(method); - } - - private boolean traceAtStartsWith(int index, String prefix) { - if (index < 0 || trace.length <= index) return false; - return trace[index].getClassName().startsWith(prefix); - } - - private StackTraceElement[] getCurrentTrace() { - return new RuntimeException().getStackTrace(); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/EvaluatorResult.java b/sources/scala/tools/scalai/EvaluatorResult.java deleted file mode 100644 index 2cf6ff8e66..0000000000 --- a/sources/scala/tools/scalai/EvaluatorResult.java +++ /dev/null @@ -1,21 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scalai; - -public class EvaluatorResult { - - //######################################################################## - // Public Cases - - public case Void; - public case Value(Object value, String type); - public case Error(EvaluatorException exception); - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/ExpressionCompiler.java b/sources/scala/tools/scalai/ExpressionCompiler.java deleted file mode 100644 index 80dd874a3b..0000000000 --- a/sources/scala/tools/scalai/ExpressionCompiler.java +++ /dev/null @@ -1,308 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ExpressionCompiler.java,v 1.16 2002/10/04 15:37:10 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Constructor; -import java.util.ArrayList; - -import scalac.ast.Tree; -import scalac.atree.AConstant; -import scalac.backend.Primitives; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; - -public class ExpressionCompiler { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final Primitives primitives; - private final Constants constants; - private final ExpressionContext context; - - //######################################################################## - // Public Constructors - - public ExpressionCompiler(Definitions definitions, Primitives primitives, Constants constants, ExpressionContext context, Symbol[] params) { - this.definitions = definitions; - this.primitives = primitives; - this.constants = constants; - this.context = context; - for (int i = 0; i < params.length; i++) - context.insertVariable(params[i], Variable.Argument(i)); - } - - //######################################################################## - // Public Methods - - public CodeContainer compile(Tree tree) { - Code code = compute(tree); - return new CodeContainer( - context.source(), context.owner(), code, context.stackmax()); - } - - public CodeContainer compile(ArrayList items) { - Code value = Code.Literal(constants.literal()); - CodeBuffer buffer = new CodeBuffer(); - for (int i = 0, m = items.size(); i < m;) { - if (i > 0) buffer.append(value); - Object item = items.get(i++); - value = compute((Tree)item); - } - Code code = buffer.code(value); - return new CodeContainer( - context.source(), context.owner(), code, context.stackmax()); - } - - //######################################################################## - // Private Methods - declare - - private void declare(Tree tree, CodeBuffer buffer) { - switch (tree) { - - case Empty: - return; - - case ValDef(_, _, _, Tree body): - Symbol symbol = tree.symbol(); - Variable variable = Variable.Local(context.push()); - context.insertVariable(symbol, variable); - // !!! this should be done in an earlier phase - Code value = body != Tree.Empty ? - compute(body) : Code.Literal(constants.zero(symbol.type())); - buffer.append(Code.Store(Code.Self, variable, value)); - return; - - default: - buffer.append(compute(tree)); - return; - } - } - - //######################################################################## - // Private Methods - compute - - private Code[] compute(Tree[] trees) { - Code[] codes = new Code[trees.length]; - for (int i = 0; i < codes.length; i++) codes[i] = compute(trees[i]); - return codes; - } - - private Code compute(Tree tree) { - switch (tree) { - - case LabelDef(_, Tree.Ident[] params, Tree body): - Symbol symbol = tree.symbol(); - Variable[] vars = new Variable[params.length]; - for (int i = 0; i < params.length; i++) { - vars[i] = context.lookupVariable(params[i].symbol()); - // !!! - assert - vars[i] instanceof Variable.Argument || - vars[i] instanceof Variable.Local : - Debug.show(vars[i]); - } - context.insertLabel(symbol); - return Code.Label(symbol, vars, compute(body)); - - case Block(Tree[] stats, Tree value): - if (stats.length == 0) return compute(value); - CodeBuffer buffer = new CodeBuffer(); - int stacksize = context.stacksize(); - for (int i = 0; i < stats.length; i++) declare(stats[i], buffer); - Code result = compute(value); - context.stacksize(stacksize); - return buffer.code(result); - - case Assign(Tree lhs, Tree rhs): - return store(lhs, lhs.symbol(), compute(rhs)); - - case If(Tree cond, Tree thenp, Tree elsep): - return Code.If(compute(cond), compute(thenp), - // !!! can we remove this test ? - elsep == Tree.Empty ? Code.Literal(constants.literal()) : compute(elsep)); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - return Code.Switch( - compute(test), tags, compute(bodies), compute(otherwise)); - - case New(Tree init): - switch (context.lookupTemplate(tree.getType().symbol())) { - case Global(ScalaTemplate template): - Variable local = Variable.Local(context.push()); - Code create = Code.Create(template); - Code store = Code.Store(Code.Null, local, create); - Code load = Code.Load(Code.Null, local); - Code code = compute(init); - switch (code) { - case Invoke(Null, Function fun, Code[] args, int pos): - Code initialize = Code.Invoke(load, fun, args, pos); - return Code.Block(new Code[] {store, initialize}, load); - default: - throw Debug.abort("illegal case", code); - } - default: - return compute(init); - } - - case Apply(TypeApply(Tree tfun, Tree[] targs), Tree[] vargs): - return tapply(tfun, tfun.symbol(), targs, vargs); - - case Apply(Tree vfun, Tree[] vargs): - return vapply(vfun, vfun.symbol(), vargs); - - case This(_): - return Code.Self; - - case Literal(AConstant constant): - switch (constant) { - case UNIT: - return Code.Literal(constants.literal()); - case BOOLEAN(boolean value): - return Code.Literal(new Boolean(value)); - case BYTE(byte value): - return Code.Literal(new Byte(value)); - case SHORT(short value): - return Code.Literal(new Short(value)); - case CHAR(char value): - return Code.Literal(new Character(value)); - case INT(int value): - return Code.Literal(new Integer(value)); - case LONG(long value): - return Code.Literal(new Long(value)); - case FLOAT(float value): - return Code.Literal(new Float(value)); - case DOUBLE(double value): - return Code.Literal(new Double(value)); - case STRING(String value): - return Code.Literal(new String(value)); - case NULL: - return Code.Null; - default: - throw Debug.abort("illegal case", constant); - } - - default: - return load(tree, tree.symbol()); - } - } - - private Code object(Tree tree) { - switch (tree) { - - case Select(Super(_, _), _): - return Code.Self; - - case Select(Create(_, _), _): - return Code.Null; - - case Select(Tree expr, _): - return compute(expr); - - case Ident(_): - return Code.Null; - - default: - throw Debug.abort("illegal tree", tree); - } - } - - //######################################################################## - // Private Methods - apply - - private Code tapply(Tree target, Symbol symbol, Tree[] targs, Tree[]vargs){ - Code object = object(target); - if (symbol == definitions.ANY_IS_ERASED - || symbol == definitions.ANY_AS_ERASED) { - assert targs.length == 1: Debug.show(targs); - assert vargs.length == 0 : Debug.show(vargs); - boolean cast = symbol == definitions.ANY_AS_ERASED; - Type type = targs[0].type(); - return Code.IsAs(object, type, context.getClass(type), cast); - } - if (symbol == primitives.NEW_OARRAY) { - assert object == Code.Null: object; - assert targs.length == 1: Debug.show(targs); - assert vargs.length == 1 : Debug.show(vargs); - Type arraytype = Type.UnboxedArrayType(targs[0].type()); - Class component = context.getClass(arraytype).getComponentType(); - return Code.CreateArray(component, compute(vargs[0])); - } - throw Debug.abort("unknown method", symbol); - } - - // !!! only used for the hack in vapply => remove ! - private static final Name plus_N = Name.fromString("$plus"); - private static final Name minus_N = Name.fromString("$minus"); - - private Code vapply(Tree target, Symbol symbol, Tree[] trees) { - // !!! optimize ? - Code object = object(target); - if (symbol == definitions.BOOLEAN_OR()) { - return Code.Or(object, compute(trees[0])); - } - if (symbol == definitions.BOOLEAN_AND()) { - return Code.And(object, compute(trees[0])); - } - if (symbol == definitions.OBJECT_SYNCHRONIZED) { - return Code.Synchronized(object, compute(trees[0])); - } - // !!! System.out.println("!!! method: " + Debug.show(symbol)); - // !!! System.out.println("!!! -owner: " + Debug.show(symbol.owner())); - Function function = context.lookupFunction(symbol); - if (trees.length == 0 - && (symbol.name == plus_N || symbol.name == minus_N) - // !!! the following line does not work. why? (because of erasure?) - // !!! symbol.owner().isSubClass(definitions.DOUBLE_CLASS)) - && ( - symbol.owner().isSubClass(definitions.INT_CLASS) || - symbol.owner().isSubClass(definitions.LONG_CLASS) || - symbol.owner().isSubClass(definitions.FLOAT_CLASS) || - symbol.owner().isSubClass(definitions.DOUBLE_CLASS))) - { - function = symbol.name == plus_N ? Function.Pos : Function.Neg; - } - switch (target) { - case Select(Super(_, _), _): - Template template = context.lookupTemplate(symbol.owner()); - switch (template) { - case Global(ScalaTemplate template_): - function = Function.Global(template_.getMethod(symbol)); - break; - - case JavaClass(Class clasz): - if (symbol.isInitializer()) break; - throw Debug.abort("!!! illegal super on java class", symbol); - - default: - throw Debug.abort("illegal template", template); - } - } - Code[] args = compute(trees); - return Code.Invoke(object, function, args, target.pos); - } - - //######################################################################## - // Private Methods - load & store - - private Code load(Tree target, Symbol symbol) { - return Code.Load(object(target), context.lookupVariable(symbol)); - } - - private Code store(Tree target, Symbol symbol, Code value) { - return Code.Store(object(target),context.lookupVariable(symbol),value); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/ExpressionContext.java b/sources/scala/tools/scalai/ExpressionContext.java deleted file mode 100644 index 0dcc4f22f1..0000000000 --- a/sources/scala/tools/scalai/ExpressionContext.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ExpressionContext.java,v 1.2 2002/06/05 09:05:56 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.util.Map; -import java.util.HashMap; - -import scala.tools.util.SourceFile; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -public class ExpressionContext { - - //######################################################################## - // Private Fields - - private final Environment environment; - private final Map functions; - private final Map variables; - private final SourceFile source; - private final Symbol owner; - - private int current; - private int maximum; - - //######################################################################## - // Public Constructors - - public ExpressionContext( - Environment environment, SourceFile source, Symbol owner) - { - this.environment = environment; - this.functions = new HashMap(); - this.variables = new HashMap(); - this.source = source; - this.owner = owner; - this.current = 0; - this.maximum = 0; - } - - //######################################################################## - // Public Methods - translate - - public Class getClass(Symbol symbol) { - return environment.getClass(symbol); - } - - public Class getClass(Type type) { - return environment.getClass(type); - } - - //######################################################################## - // Public Methods - insert - - public Function insertLabel(Symbol symbol) { - Function function = Function.Label(symbol); - assert Debug.log("insert label : ", symbol); - assert !functions.containsKey(symbol) : Debug.show(symbol); - functions.put(symbol, function); - return function; - } - - public Variable insertVariable(Symbol symbol, Variable variable) { - assert Debug.log("insert variable: ", symbol); - assert !variables.containsKey(symbol) : Debug.show(symbol); - variables.put(symbol, variable); - return variable; - } - - //######################################################################## - // Public Methods - lookup - - public Template lookupTemplate(Symbol symbol) { - return environment.lookupTemplate(symbol); - } - - public Function lookupFunction(Symbol symbol) { - Object value = functions.get(symbol); - if (value != null) return (Function)value; - return environment.lookupFunction(symbol); - } - - public Variable lookupVariable(Symbol symbol) { - Object value = variables.get(symbol); - if (value != null) return (Variable)value; - return environment.lookupVariable(symbol); - } - - //######################################################################## - // Public Methods - origin - - public SourceFile source() { - return source; - } - - public Symbol owner() { - return owner; - } - - //######################################################################## - // Public Methods - stack - - public void stacksize(int size) { - assert size >= 0 : size; - maximum = Math.max(current, maximum); - current = size; - } - - public int stacksize() { - return current; - } - - public int stackmax() { - return maximum = Math.max(current, maximum); - } - - public int push() { - return current++; - } - - public int pop() { - maximum = Math.max(current, maximum); - return --current; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Function.java b/sources/scala/tools/scalai/Function.java deleted file mode 100644 index f799e6d30a..0000000000 --- a/sources/scala/tools/scalai/Function.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Function.java,v 1.5 2002/07/01 13:16:39 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Method; -import java.lang.reflect.Constructor; - -import scalac.symtab.Symbol; -import scalac.util.Debug; - -public class Function { - - //######################################################################## - // Public Cases - - public case Global(CodePromise code); - public case Member(Symbol symbol); - public case Label(Symbol symbol); - - public case JavaConstructor(Constructor constructor); - public case JavaMethod(Method method); - - public case Pos; - public case Neg; - public case Throw; - public case StringPlus; - public case Eq; - public case Ne; - public case EqEq; - public case BangEq; - public case HashCode; - public case ToString; - - //######################################################################## - // Public Methods - - public String toString() { - switch (this) { - - case Global(CodePromise code): - return "Global(" + code + ")"; - - case Member(Symbol symbol): - return "Member(" + Debug.show(symbol) + ")"; - - case Label(Symbol symbol): - return "Label(" + Debug.show(symbol) + ")"; - - case JavaMethod(Method method): - return "JavaMethod(" + method + ")"; - - case JavaConstructor(Constructor constructor): - return "JavaConstructor(" + constructor + ")"; - - case Pos: - return "Pos"; - - case Neg: - return "Neg"; - - case Throw: - return "Throw"; - - case StringPlus: - return "StringPlus"; - - case Eq: - return "Eq"; - - case Ne: - return "Ne"; - - case EqEq: - return "EqEq"; - - case BangEq: - return "BangEq"; - - case HashCode: - return "HashCode"; - - case ToString: - return "ToString"; - - default: - throw Debug.abort("illegal function", this); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Interpreter.java b/sources/scala/tools/scalai/Interpreter.java deleted file mode 100644 index 066e865454..0000000000 --- a/sources/scala/tools/scalai/Interpreter.java +++ /dev/null @@ -1,193 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Interpreter.java,v 1.63 2002/09/13 01:50:30 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.util.HashMap; -import java.util.Map; - -import scala.runtime.InterpreterSupport; -import scala.runtime.InterpreterSupport.EvaluationResult; -import scala.tools.util.Position; - -import scalac.CompilationUnit; -import scalac.Global; -import scalac.Phase; -import scalac.symtab.Definitions; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; - - -public class Interpreter { - - //######################################################################## - // Public Constants - - public static final Name MAIN_N = Name.fromString("main"); - public static final Name ARGS_N = Name.fromString("args"); - - //######################################################################## - // Private Fields - - private final Global global; - private final Compiler compiler; - private final Evaluator evaluator; - - //######################################################################## - // Public Constructors - - public Interpreter(Global global) { - this.global = global; - Map/*<Class,Set<ScalaTemplate>>*/ templates = new HashMap(); - this.evaluator = new Evaluator(templates); - this.compiler = new Compiler(global, templates, evaluator); // !!! - } - - //######################################################################## - // Public Methods - - public EvaluatorResult invoke(String main, String[]args) { - Symbol module = getMainModule(main); - if (module == null) return EvaluatorResult.Void; - Symbol method = getMainMethod(main, module); - if (method == null) return EvaluatorResult.Void; - Variable variable = compiler.getModule(module); - Function function = compiler.getMethod(method); - try { - evaluator.evaluate(variable, function, new Object[] {args}); - return EvaluatorResult.Void; - } catch (EvaluatorException exception) { - return EvaluatorResult.Error(exception); - } - } - - public EvaluatorResult interpret(String input, boolean interactive) { - return interpret("<console>", input, interactive); - } - - public EvaluatorResult interpret(String file, String input, - boolean interactive) - { - if (input.trim().length() == 0) return EvaluatorResult.Void; - return interpret( - global.compile(file, input + ";", interactive), - interactive); - } - - public EvaluatorResult interpret(String[] files, boolean interactive) { - if (files.length == 0) return EvaluatorResult.Void; - return interpret(global.compile(files, interactive), interactive); - } - - public EvaluatorResult toString(Object object, String type) { - try { - return EvaluatorResult.Value(evaluator.toString(object), type); - } catch (EvaluatorException exception) { - return EvaluatorResult.Error(exception); - } - } - - //######################################################################## - // Private Methods - - private EvaluatorResult interpret(CompilationUnit[] units, - boolean interactive) - { - compiler.compile(units); - int errors = global.reporter.errors(); - global.reporter.resetCounters(); - if (errors != 0) return EvaluatorResult.Void; - try { - if (interactive) { - Variable console = compiler.getModule(global.console); - evaluator.evaluate(console); - } - EvaluationResult result = - InterpreterSupport.getAndResetEvaluationResult(); - if (result == null) return EvaluatorResult.Void; - return EvaluatorResult.Value(result.value, result.type); - } catch (EvaluatorException exception) { - return EvaluatorResult.Error(exception); - } - } - - //######################################################################## - // Private Methods - Finding main module - - private Symbol getMainModule(String main) { - String names = main.replace('/', '.') + (main.length() > 0 ? "." : ""); - if (names.length() > 0 && names.charAt(0) == '.') { - error("illegal module name '" + main + "'"); - return null; - } - Symbol module = global.definitions.ROOT_CLASS; - for (int i = 0, j; (j = names.indexOf('.', i)) >= 0; i = j + 1) { - Name name = Name.fromString(names.substring(i, j)); - Symbol symbol = module.lookup(name); - if (symbol.isNone()) { - error("could not find module '" + main.substring(0, j) + "'"); - return null; - } - if (symbol.isModule()) { module = symbol; continue; } - switch (symbol.type()) { - case OverloadedType(Symbol[] alts, _): - for (int k = 0; k < alts.length; k++) - if (alts[k].isModule()) { module = alts[k]; continue; } - } - error("term '" + main.substring(0, j) + "' is not a module"); - return null; - } - return module; - } - - //######################################################################## - // Private Methods - Finding main method - - private Type getMainMethodType(boolean erased) { - Phase current = global.currentPhase; - if (!erased) global.currentPhase = global.PHASE.ANALYZER.phase(); - Definitions definitions = global.definitions; - Type argument = definitions.array_TYPE(definitions.STRING_TYPE()); - Type result = definitions.void_TYPE(); - Symbol formal = Symbol.NONE.newTerm( // !!! should be newVParam - Position.NOPOS, Modifiers.PARAM, ARGS_N); - formal.setInfo(argument); - global.currentPhase = current; - return Type.MethodType(new Symbol[] {formal}, result); - } - - private Symbol getMainMethod(String main, Symbol module) { - Symbol symbol = module.moduleClass().lookup(MAIN_N); - if (symbol.isNone()) { - error("module '" + main + "' has no method '" + MAIN_N + "'"); - return null; - } - Type type = getMainMethodType(true); - if (symbol.type().equals(type)) return symbol; - switch (symbol.type()) { - case OverloadedType(Symbol[] alts, _): - for (int k = 0; k < alts.length; k++) - if (alts[k].type().equals(type)) return alts[k]; - } - error("module '" + main + "' has no method '" + MAIN_N + - "' with type '" + getMainMethodType(false) + "'"); - return null; - } - - //######################################################################## - // Private Methods - Signaling errors - - private void error(String message) { - global.reporter.error(null, message); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/InterpreterCommand.java b/sources/scala/tools/scalai/InterpreterCommand.java deleted file mode 100644 index 9e8907a499..0000000000 --- a/sources/scala/tools/scalai/InterpreterCommand.java +++ /dev/null @@ -1,74 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: InterpreterCommand.java,v 1.3 2002/09/02 12:58:22 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scalac.CompilerPhases; -import scalac.CompilerCommand; -import scala.tools.util.Reporter; -import scalac.util.StringOptionParser; -import scalac.util.BooleanOptionParser; -import scalac.util.ScalaProgramArgumentParser; - -public class InterpreterCommand extends CompilerCommand { - - //######################################################################## - // Public Fields - - public final StringOptionParser script; - public final BooleanOptionParser interactive; - public final BooleanOptionParser nologo; - public final BooleanOptionParser emacs; - public final ScalaProgramArgumentParser program; - - //######################################################################## - // Public Constructors - - public InterpreterCommand(String product, String version, - Reporter reporter, CompilerPhases phases) - { - this(product, version, "<source files> [-- <module> <args>]", - reporter, phases); - } - - public InterpreterCommand(String product, String version, String syntax, - Reporter reporter, CompilerPhases phases) - { - super(product, version, syntax, reporter, phases); - - this.script = new StringOptionParser(this, - "c", "Evaluate <string> and print result", - "string", null); - - this.interactive = new BooleanOptionParser(this, - "interactive", "Start interpreter in interactive mode", - false); - - this.nologo = new BooleanOptionParser(this, - "nologo", "Print no logo at interactive interpreter start", - false); - - this.emacs = new BooleanOptionParser(this, - "emacs", "Use Emacs editing mode", - false); - - this.program = new ScalaProgramArgumentParser(this); - - remove(outpath); - remove(target); - - add(0, script); - add(1, interactive); - add(2, nologo); - add(3, emacs); - add(parsers().indexOf(unknown_options), program); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/InterpreterPrinter.java b/sources/scala/tools/scalai/InterpreterPrinter.java deleted file mode 100644 index c42afde879..0000000000 --- a/sources/scala/tools/scalai/InterpreterPrinter.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scalai; - -import java.io.PrintWriter; - -import scala.runtime.InterpreterSupport.DefinitionPrinter; - -import scalac.util.Debug; - -public class InterpreterPrinter implements DefinitionPrinter { - - //######################################################################## - // Private Fields - - private final Interpreter interpreter; - private final PrintWriter writer; - - //######################################################################## - // Public Constructors - - public InterpreterPrinter(Interpreter interpreter, PrintWriter writer) { - this.interpreter = interpreter; - this.writer = writer; - } - - //######################################################################## - // Public Methods - - public void showDefinition(String signature) { - writer.println(signature); - } - - public void showValueDefinition(String signature, Object value) { - EvaluatorResult result = interpreter.toString(value, null); - switch (result) { - case Value(Object string, _): - writer.println(signature + " = " + string); - writer.flush(); - return; - case Error(EvaluatorException exception): - writer.print(signature + " = "); - writer.print(exception.getScalaErrorMessage(true)); - writer.flush(); - return; - default: - throw Debug.abort("illegal case", result); - } - } - - public void showResult(EvaluatorResult result, boolean interactive) { - switch (result) { - case Void: - return; - case Value(Object value, String type): - if (interactive) - if (value instanceof String) - writer.println(value + ": " + type); - else - showResult(interpreter.toString(value, type), interactive); - writer.flush(); - return; - case Error(EvaluatorException exception): - String name = Thread.currentThread().getName(); - writer.print("Exception in thread \"" + name + "\" "); - writer.print(exception.getScalaErrorMessage(true)); - writer.flush(); - return; - default: - throw Debug.abort("illegal case", result); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/InterpreterShell.java b/sources/scala/tools/scalai/InterpreterShell.java deleted file mode 100644 index e032392b0d..0000000000 --- a/sources/scala/tools/scalai/InterpreterShell.java +++ /dev/null @@ -1,466 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scala.tools.scalai; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.InputStreamReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.PushbackReader; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; - -import scala.runtime.InterpreterSupport; - -import scalac.Global; -import scalac.util.Debug; -import scalac.util.PrefixMatcher; -import scalac.util.Strings; - - -public class InterpreterShell { - - //######################################################################## - // Public Constants - - public static final String PRODUCT = Main.PRODUCT; - public static final String VERSION = Main.VERSION; - public static final String COPYRIGHT = "(c) 2002-05, LAMP/EPFL"; - - //######################################################################## - // Private Constants - - private static final int QUIT = 0; - private static final int LOAD = 1; - private static final int USE = 2; - private static final int GC = 3; - private static final int MEMORY = 4; - private static final int SHOWVER = 5; - private static final int HELP = 6; - - //######################################################################## - // Private Fields - - private final boolean interactive; - private final boolean nologo; - private final boolean emacs; - private final BufferedReader reader; - private final PrintWriter writer; - private final PrefixMatcher matcher; - private final Global global; - private final Interpreter interpreter; - private final InterpreterPrinter printer; - - private String[] lfiles; - private String[] ufiles; - - //######################################################################## - // Public Constructors - - public InterpreterShell(InterpreterCommand command) { - this(command, new BufferedReader(new InputStreamReader(System.in)), - new PrintWriter(System.out, true)); - } - - public InterpreterShell(InterpreterCommand command, BufferedReader reader, - PrintWriter writer) - { - this.interactive = command.interactive.value; - this.nologo = command.nologo.value; - this.emacs = command.emacs.value; - this.reader = reader; - this.writer = writer; - this.matcher = matcher(); - this.global = new scala.tools.scalac.Global$class(command, true); - this.interpreter = new Interpreter(global); - this.printer = new InterpreterPrinter(interpreter, writer); - this.lfiles = new String[0]; - this.ufiles = new String[0]; - } - - //######################################################################## - // Public Methods - shell - - public void main(String[] files, String script, String main, String[]args){ - if (interactive && !nologo) showBanner(); - if (files.length > 0) load(lfiles = files); - if (global.reporter.errors() == 0 && script != null) eval(script); - if (global.reporter.errors() == 0 && main != null) call(main, args); - if (interactive) loop(); - } - - public void loop() { - InterpreterSupport.setDefinitionPrinter(printer); - while (handle(read())); - InterpreterSupport.setDefinitionPrinter(null); - } - - public boolean handle(String input) { - if (input == null) return exec(QUIT); - String trimed = input.trim(); - if (trimed.startsWith(":")) return exec(trimed); - eval(input); - return true; - } - - public String read() { - writer.print("> "); - writer.flush(); - StringBuffer buffer = new StringBuffer(); - for (boolean stop = false; !stop; ) { - String line; - try { - line = reader.readLine(); - } catch (IOException exception) { - writer.println(); - error(exception.toString()); - System.exit(1); - throw Debug.abort(exception); - } - - if (line == null) { writer.println(); break; } - if (emacs && line.equals("emacs:end")) break; - - if (!emacs) { - line = Strings.trimTrailing(line); - int lastChar = Strings.lastChar(line); - stop = ",;:({=|\\".indexOf(lastChar) < 0; - if (lastChar == '\\') line = line.substring(0,line.length()-1); - } - - buffer.append(line).append('\n'); - - if (!emacs && !stop) { - writer.print("| "); - writer.flush(); - } - } - return buffer.length() == 0 ? null : buffer.toString(); - } - - public void showBanner() { - writer.println(" __ __ _ _"); - writer.println(" (_ / /_|| /_| INTERPRETER"); - writer.println("___)\\__/ ||__/ | " + COPYRIGHT); - writer.println(" "); - writer.println(" version: " + VERSION); - writer.println(" type :? to get a list of all interpreter commands"); - writer.println(" "); - } - - //######################################################################## - // Public Methods - command execution - - public boolean exec(String input) { - int length = input.indexOf(' '); - length = length < 0 ? input.length() : length; - String command = input.substring(0, length); - PrefixMatcher.Entry[] entries = matcher.lookup(command); - if (entries.length != 1) { - error(matcher.getErrorMessage(command, entries, "command")); - return true; - } - try { - String[] arguments = readArguments(input.substring(length)); - return exec(((Integer)entries[0].value).intValue(), arguments); - } catch (IOException exception) { - error(exception.getMessage()); - return true; - } - } - - public boolean exec(int command) { - return exec(command, new String[0]); - } - - public boolean exec(int command, String[] args) { - switch (command) { - case QUIT: - writer.println("[Leaving " + PRODUCT + "]"); - return false; - - case LOAD: - if (args.length != 0) lfiles = args; - load(lfiles); - return true; - - case USE: - if (args.length != 0) ufiles = args; - return exec(ufiles); - - case GC: - System.gc(); - return true; - - case MEMORY: - Runtime rt = Runtime.getRuntime(); - writer.println("total memory: " + rt.totalMemory()); - writer.println("free memory : " + rt.freeMemory()); - return true; - - case SHOWVER: - writer.println(PRODUCT + " " + VERSION + " -- " + COPYRIGHT); - return true; - - case HELP: - writer.println("interpreter commands:"); - writer.println(Strings.format(matcher.getHelpStrings(" ","\t "))); - return true; - - default: - throw Debug.abort("unknown command " + command); - } - } - - public boolean exec(String[] files) { - for (int i = 0; i < files.length; i++) { - String file = files[i]; - StringBuffer blank = new StringBuffer(); - StringBuffer input = new StringBuffer(); - try { - BufferedReader reader = - new BufferedReader(new FileReader(file)); - while (true) { - String line = reader.readLine(); - if (line == null || line.trim().startsWith(":")) { - String code = input.toString(); - if (code.trim().length() > 0) eval(file, code); - if (line == null) break; - if (!exec(line.trim())) return false; - blank.append('\n'); - input.setLength(0); - input.append(blank); - } else { - blank.append('\n'); - input.append(line).append('\n'); - } - } - } catch (IOException exception) { - error(exception.getMessage()); - } - } - return true; - } - - //######################################################################## - // Public Methods - interpretation - - public void call(String main, String[] args) { - show(interpreter.invoke(main, args), false); - } - - public void load(String input) { - show(interpreter.interpret(input, false), false); - } - - public void load(String[] files) { - show(interpreter.interpret(files, false), false); - } - - public void eval(String input) { - show(interpreter.interpret(input, true), true); - } - - public void eval(String file, String input) { - show(interpreter.interpret(file, input, true), true); - } - - public void eval(String[] files) { - show(interpreter.interpret(files, true), true); - } - - public void show(EvaluatorResult result, boolean interactive) { - printer.showResult(result, interactive); - } - - //######################################################################## - // Private Methods - matcher initialization - - private PrefixMatcher matcher() { - PrefixMatcher matcher = new PrefixMatcher(); - matcher.insert(":quit", new Integer(QUIT), - "Quit interpreter"); - matcher.insert(":load", new Integer(LOAD), "<files>", - "Load files (or repeat last load if no files are given)"); - matcher.insert(":use", new Integer(USE), "<files>", - "Use files (or repeat last use if no files are given)"); - matcher.insert(":gc", new Integer(GC), - "Run garbage collector"); - matcher.insert(":memory", new Integer(MEMORY), - "Print out memory usage"); - matcher.insert(":help", new Integer(HELP), - "Print out this command summary"); - matcher.insert(":version", new Integer(SHOWVER), - "Print out product version"); - matcher.insert(":?", new Integer(HELP), - "Same as :help"); - return matcher; - } - - //######################################################################## - // Private Methods - error messages - - private void error(String message) { - writer.println("error: " + message); - } - - //######################################################################## - // Private Methods - argument parsing - - private String[] readArguments(String command) throws IOException { - return readArguments(new PushbackReader(new StringReader(command))); - } - - private String[] readArguments(PushbackReader reader) throws IOException { - List arguments = new ArrayList(); - while (true) { - int c = reader.read(); - if (c == -1) return (String[])arguments.toArray(new String[0]); - if (!Character.isWhitespace((char)c)) { - reader.unread(c); - arguments.add(readArgument(reader)); - } - } - } - - private String readArgument(PushbackReader reader) throws IOException { - StringBuffer value = new StringBuffer(); - StringBuffer token = new StringBuffer(); - while (true) { - int c = read(reader, token); - switch (c) { - case '\"': value.append(readString(reader, token)); break; - case '\\': value.append(readBackslashed(reader, token)); break; - default : - if (!Character.isWhitespace((char)c)) { - value.append((char)c); - break; - } else { - reader.unread(c); - } - case -1 : return value.toString(); - } - token.delete(0, token.length()); - } - } - - private String readBackslashed(PushbackReader reader, StringBuffer input) - throws IOException - { - int c = read(reader, input); - switch (c) { - case ' ' : return " "; - case '\"': return "\""; - case '\\': return "\\"; - default : return input.toString(); - } - } - - private String readString(PushbackReader reader, StringBuffer input) - throws IOException - { - StringBuffer value = new StringBuffer(); - StringBuffer token = new StringBuffer(); - while (true) { - int c = read(reader, token, "unterminated string '" + input + "'"); - switch (c) { - case '\"': input.append((char)c); return value.toString(); - case '\\': value.append(readEscape(reader, token)); break; - default : value.append((char)c); break; - } - input.append(token.toString()); - token.delete(0, token.length()); - } - } - - private char readEscape(PushbackReader reader, StringBuffer input) - throws IOException - { - int c = read(reader, input, - "unterminated escape sequence '" + input + "'"); - switch (c) { - case 'b' : return '\b'; - case 't' : return '\t'; - case 'n' : return '\n'; - case 'f' : return '\f'; - case 'r' : return '\r'; - case '\"': return '\"'; - case '\'': return '\''; - case '\\': return '\\'; - case 'u' : return readUnicode(reader, input); - case '0' : - case '1' : - case '2' : - case '3' : - case '4' : - case '5' : - case '6' : - case '7' : return readOctal(reader, input, c); - default : throw new IOException( - "illegal escape sequence '" + input + "'"); - } - } - - private char readUnicode(PushbackReader reader, StringBuffer input) - throws IOException - { - int value = 0; - boolean illegal = false; - for (int i = 0; i < 4; i++) { - int c = read(reader, input, - "unterminated Unicode escape sequence '" + input + "'"); - switch (c) { - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - value = (value << 4) + (c - '0'); break; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - value = (value << 4) + (c - 'A' + 0x0A); break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - value = (value << 4) + (c - 'a' + 0x0a); break; - default: - illegal = true; break; - } - } - if (illegal) throw new IOException( - "illegal Unicode escape sequence '" + input + "'"); - return (char)value; - } - - private char readOctal(PushbackReader reader, StringBuffer input,int first) - throws IOException - { - int value = first - '0'; - while (value < 32) { - int c = read(reader, input); - if (c < '0' || '7' < c) { reader.unread(c); break; } - value = (value << 3) + (c - '0'); - } - return (char)value; - } - - private int read(PushbackReader reader, StringBuffer input, String error) - throws IOException - { - int c = read(reader, input); - if (c == -1) throw new IOException(error); - return (char)c; - } - - private int read(PushbackReader reader, StringBuffer input) - throws IOException - { - int c = reader.read(); - if (c != -1) input.append((char)c); - return c; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/JavaMirror.java b/sources/scala/tools/scalai/JavaMirror.java deleted file mode 100644 index e6039e1221..0000000000 --- a/sources/scala/tools/scalai/JavaMirror.java +++ /dev/null @@ -1,274 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: JavaMirror.java,v 1.8 2002/10/01 16:14:07 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Constructor; -import java.lang.reflect.Proxy; -import java.util.Map; -import java.util.HashMap; - -import scalac.symtab.Kinds; -import scalac.symtab.TypeTags; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.Definitions; -import scalac.util.Debug; - -public class JavaMirror { - - //######################################################################## - // Private Constants - - private static final Class void_class = Void.TYPE; - private static final Class boolean_class = Boolean.TYPE; - private static final Class byte_class = Byte.TYPE; - private static final Class short_class = Short.TYPE; - private static final Class char_class = Character.TYPE; - private static final Class int_class = Integer.TYPE; - private static final Class long_class = Long.TYPE; - private static final Class float_class = Float.TYPE; - private static final Class double_class = Double.TYPE; - private static final Class Object_class = Object.class; - - //######################################################################## - // Private Fields - - private final ClassLoader loader; - - private final Map/*<Class ,Class >*/ arrays; - private final Map/*<Symbol,Class >*/ classes; - private final Map/*<Symbol,Field >*/ fields; - private final Map/*<Symbol,Method >*/ methods; - private final Map/*<Symbol,Constructor>*/ constructors; - - //######################################################################## - // Public Constructors - - public JavaMirror(Definitions definitions, ClassLoader loader) { - this.loader = loader; - this.arrays = new HashMap(); - this.classes = new HashMap(); - this.fields = new HashMap(); - this.methods = new HashMap(); - this.constructors = new HashMap(); - this.classes.put(definitions.ANY_CLASS, Object_class); - this.classes.put(definitions.ANYREF_CLASS, Object_class); - } - - //######################################################################## - // Public Methods - arrays - - public Class getArray(Class component) { - if (Proxy.isProxyClass(component)) component = Object_class; - Object value = arrays.get(component); - if (value != null) return (Class)value; - Class array = getArray0(component); - arrays.put(component, array); - return array; - } - - private Class getArray0(Class component) { - String classname = "[" + getArrayComponentName(component); - try { - return Class.forName(classname, false, loader); - } catch (ClassNotFoundException exception) { - throw Debug.abort("no such class", classname); - } - } - - private String getArrayComponentName(Class component) { - if (component.isPrimitive()) { - if (component == boolean_class) return "Z"; - if (component == byte_class) return "B"; - if (component == short_class) return "S"; - if (component == char_class) return "C"; - if (component == int_class) return "I"; - if (component == long_class) return "J"; - if (component == float_class) return "F"; - if (component == double_class) return "D"; - throw Debug.abort("unknown primitive class", component); - } - String classname = component.getName(); - return component.isArray() ? classname : "L" + classname + ";"; - } - - //######################################################################## - // Public Methods - classes - - public Class getClass(Type type) { - switch (type) { - - case UnboxedType(int kind): - return getClass(kind); - - case UnboxedArrayType(Type component): - return getArray(getClass(component)); - - case TypeRef(_, Symbol symbol, _): - return getClass(symbol); - - default: - throw Debug.abort("illegal type", type); - } - } - - public Class getClass(int kind) { - switch (kind) { - case TypeTags.UNIT : return void_class; - case TypeTags.BOOLEAN: return boolean_class; - case TypeTags.BYTE : return byte_class; - case TypeTags.SHORT : return short_class; - case TypeTags.CHAR : return char_class; - case TypeTags.INT : return int_class; - case TypeTags.LONG : return long_class; - case TypeTags.FLOAT : return float_class; - case TypeTags.DOUBLE : return double_class; - default : throw Debug.abort("kind = " + kind); - } - } - - public Class getClass(Symbol symbol) { - Object value = classes.get(symbol); - if (value != null) return (Class)value; - Class mirror = getClass0(symbol); - assert Debug.log("java mirror: ", symbol, " -> ", mirror); - classes.put(symbol, mirror); - return mirror; - } - - private Class getClass0(Symbol symbol) { - String name = getClassName(symbol, false); - try { - return Class.forName(name, false, loader); - } catch (ClassNotFoundException exception) { - throw Debug.abort("no such class", Debug.show(symbol, name)); - } - } - - private String getClassName(Symbol symbol, boolean asPrefix) { - assert symbol.kind == Kinds.CLASS : Debug.show(symbol); - String name = getPrefix(symbol.owner()) + symbol.name; - if (!asPrefix && !symbol.isJava() && symbol.isModuleClass()) - name = name + '$'; - return name; - } - - private String getPrefix(Symbol symbol) { - assert symbol.kind == Kinds.CLASS : Debug.show(symbol); - if (symbol.isRoot()) return ""; - String prefix = getClassName(symbol, true); - return prefix + (symbol.isClass() ? '$' : '.'); - } - - //######################################################################## - // Public Methods - fields - - public Field getField(Symbol symbol) { - Object value = fields.get(symbol); - if (value != null) return (Field)value; - Field mirror = getField0(symbol); - assert Debug.log("java mirror: ", symbol, " -> ", mirror); - fields.put(symbol, mirror); - return mirror; - } - - private Field getField0(Symbol symbol) { - if (symbol.isModule()) { - assert !symbol.isJava() : Debug.show(symbol); - Class owner = getClass0(symbol.moduleClass()); - return getField0(symbol, owner, "MODULE$"); - } else { - Class owner = getClass(symbol.owner()); - return getField0(symbol, owner, symbol.name.toString()); - } - } - - private Field getField0(Symbol symbol, Class owner, String name) { - try { - return owner.getField(name); - } catch (NoSuchFieldException exception) { - throw Debug.abort("no such field", symbol); - } - } - - //######################################################################## - // Public Methods - methods - - public Method getMethod(Symbol symbol) { - Object value = methods.get(symbol); - if (value != null) return (Method)value; - Method mirror = getMethod0(symbol); - assert Debug.log("java mirror: ", symbol, " -> ", mirror); - methods.put(symbol, mirror); - return mirror; - } - - private Method getMethod0(Symbol symbol) { - Class owner = getClass(symbol.owner()); - Class[] params = getVParamsOf(symbol.type()); - try { - return owner.getMethod(symbol.name.toString(), params); - } catch (NoSuchMethodException exception) { - throw Debug.abort("no such method", symbol); - } - } - - //######################################################################## - // Public Methods - constructors - - public Constructor getConstructor(Symbol symbol) { - Object value = constructors.get(symbol); - if (value != null) return (Constructor)value; - Constructor mirror = getConstructor0(symbol); - assert Debug.log("java mirror: ", symbol, " -> ", mirror); - constructors.put(symbol, mirror); - return mirror; - } - - private Constructor getConstructor0(Symbol symbol) { - Class owner = getClass(symbol.owner()); - Class[] params = getVParamsOf(symbol.type()); - try { - return owner.getConstructor(params); - } catch (NoSuchMethodException exception) { - throw Debug.abort("no such constructor", symbol); - } - } - - //######################################################################## - // Public Methods - value parameters - - public Class[] getVParamsOf(Symbol symbol) { - return getVParamsOf(symbol.type()); - } - - public Class[] getVParamsOf(Type type) { - switch (type) { - - case MethodType(Symbol[] vparams, _): - return getVParams(vparams); - - default: - throw Debug.abort("illegal type", type); - } - } - - public Class[] getVParams(Symbol[] symbols) { - Class[] vparams = new Class[symbols.length]; - for (int i = 0; i < vparams.length; i++) { - vparams[i] = getClass(symbols[i].type()); - } - return vparams; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Main.java b/sources/scala/tools/scalai/Main.java deleted file mode 100644 index 7be8114235..0000000000 --- a/sources/scala/tools/scalai/Main.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Main.java,v 1.2 2002/08/30 15:44:55 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scala.tools.scalac.CompilerPhases$class; -import scala.tools.util.ConsoleReporter; - -public class Main { - - //######################################################################## - // Public Constants - - public static final String PRODUCT = - System.getProperty("scala.product", "scala"); - public static final String VERSION = - System.getProperty("scala.version", "1.0"); - - //######################################################################## - // Public Methods - - public static void main(String[] args) { - ConsoleReporter reporter = new ConsoleReporter(); - InterpreterCommand command = new InterpreterCommand( - PRODUCT, VERSION, reporter, new CompilerPhases$class()); - if (command.parse(args)) { - InterpreterShell shell = new InterpreterShell(command); - shell.main(command.files.toArray(), command.script.value, - command.program.main, command.program.args); - reporter.printSummary(); - } - System.exit((reporter.errors() > 0) ? 1 : 0); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Override.java b/sources/scala/tools/scalai/Override.java deleted file mode 100644 index b322004c5c..0000000000 --- a/sources/scala/tools/scalai/Override.java +++ /dev/null @@ -1,65 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Override.java,v 1.2 2002/07/11 09:20:41 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Method; -import java.util.Set; -import java.util.HashSet; -import java.util.Iterator; - -import scalac.symtab.Symbol; -import scalac.util.Debug; - -public class Override { - - //######################################################################## - // Private Fields - - private final Set/*<Method|Symbol>*/ methods; - - //######################################################################## - // Public Constructors - - private Override() { - this.methods = new HashSet(); - } - - //######################################################################## - // Public Methods - - public static Override empty() { - return new Override(); - } - - public Override insert(Method method) { - methods.add(method); - return this; - } - - public Override insert(Symbol symbol) { - methods.add(symbol); - return this; - } - - public Override insert(Override override) { - methods.addAll(override.methods); - return this; - } - - public Iterator iterator() { - return methods.iterator(); - } - - public String toString() { - return "Override(" + Debug.show(methods.toArray()) + ")"; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/PathClassLoader.java b/sources/scala/tools/scalai/PathClassLoader.java deleted file mode 100644 index 34aec40a59..0000000000 --- a/sources/scala/tools/scalai/PathClassLoader.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: PathClassLoader.java,v 1.1 2002/10/01 16:09:34 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.io.File; -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -public class PathClassLoader extends ClassLoader { - - //######################################################################## - // PathClassLoader state - - private final AbstractFile root; - - //######################################################################## - // PathClassLoader constructors - - public PathClassLoader(AbstractFile root) { - this.root = root; - } - - //######################################################################## - // ClassLoader interface - - public Class findClass(String name) throws ClassNotFoundException { - String filename = name.replace('.', File.separatorChar) + ".class"; - AbstractFile file = root.lookupPath(filename, false); - if (file == null) throw new ClassNotFoundException(name); - try { - byte[] bytes = file.read(); - return defineClass(name, bytes, 0, bytes.length); - } catch (IOException exception) { - throw new ClassFormatError(name+"(Failed to read file "+file+")"); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/ScalaFunction.java b/sources/scala/tools/scalai/ScalaFunction.java deleted file mode 100644 index 37dc89f5e3..0000000000 --- a/sources/scala/tools/scalai/ScalaFunction.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ScalaFunction.java,v 1.9 2002/07/03 16:08:00 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scala.tools.util.SourceFile; - -import scalac.ast.Tree; -import scalac.ast.Tree.ValDef; -import scalac.symtab.Symbol; -import scalac.util.Debug; - -public class ScalaFunction extends CodeGenerator { - - //######################################################################## - // Private Fields - - private final Compiler compiler; - private final SourceFile source; - private final Symbol symbol; - private final ValDef[] params; - private final Tree body; - - //######################################################################## - // Public Constructors - - public ScalaFunction(Compiler compiler, SourceFile source, Symbol symbol, ValDef[] params, Tree body) { - this.compiler = compiler; - this.source = source; - this.symbol = symbol; - this.params = params; - this.body = body; - } - - //######################################################################## - // Public Methods - CodeGenerator interface - - public CodeContainer generate() { - return compiler.compile(source, symbol, body, Tree.symbolOf(params)); - } - - //######################################################################## - // Public Methods - Object interface - - // !!! - public String toString() { - return "ScalaFunction(" + Debug.show(symbol) + ")"; - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/ScalaObject.java b/sources/scala/tools/scalai/ScalaObject.java deleted file mode 100644 index 9b8f093e5c..0000000000 --- a/sources/scala/tools/scalai/ScalaObject.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ScalaObject.java,v 1.7 2002/07/11 11:46:53 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.lang.reflect.InvocationHandler; - -import scalac.symtab.Symbol; - -public class ScalaObject implements InvocationHandler { - - //######################################################################## - // Public Fields - - public final ScalaTemplate template; - public final Object[] variables; - - //######################################################################## - // Public Constructors - - public ScalaObject(ScalaTemplate template, Object[] variables) { - this.template = template; - this.variables = variables; - } - - //######################################################################## - // Public Methods - ScalaObject interface - - public Object invoke(Object self, Symbol symbol, Object[] args) { - return template.invoke(self, symbol, args); - } - - //######################################################################## - // Public Methods - InvocationHandler interface - - public Object invoke(Object self, Method method, Object[] args) - throws Throwable - { - try { - return template.invoke(self, method, args); - } catch (EvaluatorException exception) { - exception.addScalaEntryPoint(); - throw exception.getCause(); - } - } - - //######################################################################## - // Public Methods - Object interface - - public boolean equals(Object that) { - return that instanceof Proxy && Proxy.getInvocationHandler(that)==this; - } - - public String toString() { - return template.getName() + "@" + Integer.toHexString(hashCode()); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/ScalaTemplate.java b/sources/scala/tools/scalai/ScalaTemplate.java deleted file mode 100644 index 3edb48e189..0000000000 --- a/sources/scala/tools/scalai/ScalaTemplate.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ScalaTemplate.java,v 1.8 2002/07/11 11:46:53 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Method; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; - -import scalac.util.Name; -import scalac.symtab.Symbol; -import scalac.util.Debug; - -public class ScalaTemplate { - - //######################################################################## - // Private Fields - - private final Evaluator evaluator; - private final Symbol symbol; - private final Class proxy; - private final Function constructor; - private final Map/*<Method|Symbol,CodePromise>*/ vtable; - private final Object[] fields; - - //######################################################################## - // Public Constructors - - public ScalaTemplate(Evaluator evaluator, Symbol symbol, Class proxy, Function constructor, Map vtable, Object[] fields) { - this.evaluator = evaluator; - this.symbol = symbol; - this.proxy = proxy; - this.constructor = constructor; - this.vtable = vtable; - this.fields = fields; - } - - //######################################################################## - // Public Methods - ScalaTemplate interface - - public String getName() { - return evaluator.getClassName(symbol); - } - - public Symbol getSymbol() { - return symbol; - } - - public Class getProxy() { - return proxy; - } - - public Function getConstructor() { - return constructor; - } - - public Map getMethods() { - return new HashMap(vtable); - } - - public List getFields() { - List list = new ArrayList(fields.length); - for (int i = 0; i < fields.length; i++) list.add(fields[i]); - return list; - } - - public CodePromise getMethod(Symbol symbol) { - return (CodePromise)vtable.get(symbol); - } - - public ScalaObject getHandler() { - Object[] fields = new Object[this.fields.length]; - System.arraycopy(this.fields, 0, fields, 0, fields.length); - return new ScalaObject(this, fields); - } - - public Object invoke(Object self, Symbol method, Object[] args) { - CodePromise code = (CodePromise)vtable.get(method); - if (code == null) { - // !!! generalize use of overridingSymbol in interpreter - code = (CodePromise)vtable.get(method.overridingSymbol(symbol.thisType(), true)); - } - assert code != null : Debug.show(symbol) + "->" + Debug.show(method); - return evaluator.evaluate(code, self, args); - } - - public Object invoke(Object self, Method method, Object[] args) { - CodePromise code = (CodePromise)vtable.get(method); - assert code != null : Debug.show(symbol) + "->" + Debug.show(method); - return evaluator.evaluate(code, self, args); - } - - //######################################################################## - // Public Methods - Object interface - - public String toString() { - return "template " + getName(); - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Template.java b/sources/scala/tools/scalai/Template.java deleted file mode 100644 index d9ffcf1a86..0000000000 --- a/sources/scala/tools/scalai/Template.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Template.java,v 1.2 2002/06/28 17:23:59 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import scalac.util.Debug; - -public class Template { - - //######################################################################## - // Public Cases - - public case Global(ScalaTemplate template); - public case JavaClass(Class clasz); - - //######################################################################## - // Public Methods - - public String toString() { - switch (this) { - - case Global(ScalaTemplate template): - return "Global(" + template + ")"; - - case JavaClass(Class clasz): - return "JavaClass(" + clasz + ")"; - - default: - throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scala/tools/scalai/Variable.java b/sources/scala/tools/scalai/Variable.java deleted file mode 100644 index 72b9f7c10f..0000000000 --- a/sources/scala/tools/scalai/Variable.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Variable.java,v 1.4 2002/06/17 12:33:38 paltherr Exp $ -// $Id$ - -package scala.tools.scalai; - -import java.lang.reflect.Field; - -import scalac.util.Debug; - -public class Variable { - - //######################################################################## - // Public Cases - - public case Global(Object value); - public case Module(ScalaTemplate template, Object value); - public case Member(int index); - public case Argument(int index); - public case Local(int index); - public case JavaField(Field field); - - //######################################################################## - // Public Methods - - public String toString() { - switch (this) { - - case Global(Object value): - return "Global(" + Debug.show(value) + ")"; - - case Module(ScalaTemplate template, Object value): - return "Module(" + template + "," + Debug.show(value) + ")"; - - case Member(int index): - return "Member(" + index + ")"; - - case Argument(int index): - return "Context(" + index + ")"; - - case Local(int index): - return "Variable(" + index + ")"; - - case JavaField(Field field): - return "Java(" + field + ")"; - - default: - throw Debug.abort("illegal variable", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/ApplicationError.java b/sources/scalac/ApplicationError.java deleted file mode 100644 index 5c00567d50..0000000000 --- a/sources/scalac/ApplicationError.java +++ /dev/null @@ -1,59 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import scalac.util.Debug; - -public class ApplicationError extends Error { - - //######################################################################## - // Private interface - - private static String combine(String message, Object object) { - String string = Debug.show(object); - return message == null ? string : message + ": " + string; - } - - //######################################################################## - // ApplicationError constructors - - public ApplicationError() { - this((String)null, (Throwable)null); - } - - public ApplicationError(String message) { - this(message, (Throwable)null); - } - - public ApplicationError(Object object) { - this(null, object, null); - } - - public ApplicationError(Throwable cause) { - this((String)null, cause); - } - - public ApplicationError(String message, Object object) { - this(message, object, null); - } - - public ApplicationError(String message, Throwable cause) { - super(message, cause); - } - - public ApplicationError(Object object, Throwable cause) { - this(null, object, cause); - } - - public ApplicationError(String message, Object object, Throwable cause) { - this(combine(message, object), cause); - } - - //######################################################################## -} diff --git a/sources/scalac/CompilationLoop.java b/sources/scalac/CompilationLoop.java deleted file mode 100644 index 94700d355d..0000000000 --- a/sources/scalac/CompilationLoop.java +++ /dev/null @@ -1,143 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.util.ArrayList; - -import scalac.util.Debug; - -/** This class implements the scalac compilation loop. */ -public class CompilationLoop { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - /** The list of active phases */ - private final Phase[] phases; - /** The units currently associated to each active phase. */ - private final ArrayList/*<CompilationUnit>*/[] unitss; - /** The indexes of the first units that are not yet processed. */ - private final int[] indexes; - - //######################################################################## - // Private Constructors - - /** Initializes this instance. */ - public CompilationLoop(Global global) { - this.global = global; - int count = 0; - for (Phase p = global.PHASE.INITIAL.phase(); p != null; p = p.next) - count++; - this.phases = new Phase[count]; - this.unitss = new ArrayList[count]; - this.indexes = new int[count]; - Phase phase = global.PHASE.INITIAL.phase(); - for (int i = 0; i < count; i++) { - phases[i] = phase; - unitss[i] = new ArrayList(); - phase = phase.next; - } - } - - //######################################################################## - // Public Methods - - /** - * Compiles the given units and returns list of all compiled units - * including those loaded automatically. - */ - public CompilationUnit[] compile(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) unitss[0].add(units[i]); - int limit = phases.length - 1; - loop(limit, true); - return global.reporter.errors() != 0 - ? new CompilationUnit[0] - : (CompilationUnit[])unitss[limit].toArray( - new CompilationUnit[unitss[limit].size()]); - } - - /** - * Inserts the given unit and compiles it up to the current phase - * excluded. - */ - public void insert(CompilationUnit unit) { - Phase backup = global.currentPhase; - unitss[0].add(unit); - // !!! This "false" may be dangerous; it may lead to crashes - // because phases might work on trees/symbol-tables that - // contain errors (however this occurs only if the newly - // loaded code may contain errors). On the other hand "true", - // might starve some phases; if a phase requests a compilation - // unit, it may never receive it. - loop(getPhaseIndex(backup), false); - global.currentPhase = backup; - } - - //######################################################################## - // Private Methods - - /** Compiles all units up to phase "phases[limit]" excluded. */ - private void loop(int limit, boolean main) { - assert limit < phases.length: Debug.show(""+limit, phases); - for (int current = getFirstNonEmptyIndex(); current < limit; ) { - // !!! remove NAMER test ? - if (main && global.reporter.errors() != 0 - && global.currentPhase != global.PHASE.NAMER.phase()) break; - // Update the current phase pointer. - Phase phase = global.currentPhase = phases[current]; - // If the phase is not yet started, start it. - if (indexes[current] == 0) global.timer.start(); - // Apply the phase to all available units. It's important - // to not cache the result of "size()" as new units may be - // added during the loop. - for (int i = indexes[current]; i < unitss[current].size(); i++) - phase.apply((CompilationUnit)unitss[current].get(i)); - int next = getFirstNonEmptyIndex(); - // If no new units were introduced, stop the phase. - if (next == current) { - PhaseDescriptor descriptor = phase.descriptor; - global.timer.stop(descriptor.taskDescription()); - CompilationUnit[] units = - (CompilationUnit[])unitss[current].toArray( - new CompilationUnit[unitss[current].size()]); - if (descriptor.hasPrintFlag()) global.print(units); - // if (descriptor.hasGraphFlag()); // !!! - // if (descriptor.hasCheckFlag()); // !!! - if (phase == global.PHASE.PARSER.phase()) global.fix1(units); - if (phase == global.PHASE.ANALYZER.phase()) global.fix2(units); - unitss[current + 1].addAll(unitss[current]); - unitss[current].clear(); - next++; - } - indexes[current] = unitss[current].size(); - current = next; - } - } - - /** - * Returns the first index with a non-empty unit list. If there is - * no such index, returns "phases.length". - */ - private int getFirstNonEmptyIndex() { - int index = 0; - while (index < phases.length && unitss[index].isEmpty()) index++; - return index; - } - - /** Returns the index of the given phase. */ - private int getPhaseIndex(Phase phase) { - for (int index = 0; index < phases.length; index++) - if (phases[index] == phase) return index; - throw Debug.abort("phase not found", Debug.show(phase, phases)); - } - - //######################################################################## -} diff --git a/sources/scalac/CompilationUnit.java b/sources/scalac/CompilationUnit.java deleted file mode 100644 index 44e131bed7..0000000000 --- a/sources/scalac/CompilationUnit.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import scalac.ast.Tree; -import scalac.atree.ARepository; -import scalac.util.FreshNameCreator; -import java.util.HashMap; - - -/** A representation for a compilation unit in scala - * - * @author Matthias Zenger - * @version 1.0 - */ -public class CompilationUnit { - - /** the global compilation environment - */ - public final Global global; - - /** the associated source code file - */ - public final SourceFile source; - - /** does this unit come from the interpreter console - */ - public final boolean console; - - /** is this unit only there for mixin expansion? - */ - public final boolean mixinOnly; - - /** the fresh name creator - */ - public final FreshNameCreator fresh; - - /** the content of the compilation unit in tree form - */ - public Tree[] body; - public ARepository repository; - - public CompilationUnit(Global global, SourceFile source, - boolean console, boolean mixinOnly) { - this.global = global; - this.source = source; - this.console = console; - this.mixinOnly = mixinOnly; - this.fresh = new FreshNameCreator(); - } - - public CompilationUnit(Global global, SourceFile source, boolean console) { - this(global, source, console, false); - } - - /** return the position representing the given encoded position - */ - public Position position(int pos) { - return new Position(source, pos); - } - - /** issue an error in this compilation unit at a specific location - */ - public void error(int pos, String message) { - global.reporter.error(position(pos), message); - } - - /** issue a warning in this compilation unit at a specific location - */ - public void warning(int pos, String message) { - global.reporter.warning(position(pos), message); - } - - /** return a string representation - */ - public String toString() { - return source.toString(); - } - -} diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java deleted file mode 100644 index ba016b24e6..0000000000 --- a/sources/scalac/CompilerCommand.java +++ /dev/null @@ -1,369 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import scala.tools.util.ClassPath; -import scala.tools.util.Reporter; -import scala.tools.util.ConsoleReporter; - -import scalac.util.CommandParser; -import scalac.util.ArgumentParser; -import scalac.util.OptionParser; -import scalac.util.BooleanOptionParser; -import scalac.util.StringOptionParser; -import scalac.util.ChoiceOptionParser; -import scalac.util.HelpOptionParser; -import scalac.util.VersionOptionParser; -//import scalac.util.OptimizeOptionParser; -import scalac.util.PhaseSetOptionParser; -import scalac.util.PrintOptionParser; -import scalac.util.UnknownOptionParser; -import scalac.util.ScalaFileArgumentParser; -import scalac.util.UnknownArgumentParser; -import scalac.util.Strings; - -/** - * Class <code>CompilerCommand</code> describes the options - * passed as arguments to the compiler command. - */ -public class CompilerCommand extends CommandParser { - - //######################################################################## - // Public Fields - - public final CompilerPhases phases; - - public final BooleanOptionParser debuginfo; - public final BooleanOptionParser nowarn; - public final BooleanOptionParser verbose; - public final BooleanOptionParser debug; - public final BooleanOptionParser explaintypes; - public final BooleanOptionParser uniqid; - public final BooleanOptionParser types; - public final BooleanOptionParser prompt; - public final ChoiceOptionParser separate; - //public final OptimizeOptionParser optimize; - public final StringOptionParser classpath; - public final StringOptionParser sourcepath; - public final StringOptionParser bootclasspath; - public final StringOptionParser extdirs; - public final StringOptionParser outpath; - public final StringOptionParser encoding; - public final StringOptionParser assemrefs; - public final StringOptionParser assemname; - public final ChoiceOptionParser target; - public final BooleanOptionParser noimports; - public final BooleanOptionParser nopredefs; - public final PhaseSetOptionParser skip; - public final PhaseSetOptionParser check; - public final PrintOptionParser print; - public final ChoiceOptionParser printer; - public final StringOptionParser printfile; - public final PhaseSetOptionParser graph; - public final PhaseSetOptionParser stop; - public final PhaseSetOptionParser log; - public final VersionOptionParser version; - public final HelpOptionParser help; - public final UnknownOptionParser unknown_options; - public final ScalaFileArgumentParser files; - public final UnknownArgumentParser unknown_arguments; - - /* - * Non-standard options (starting with prefix "-X") - * are subject to change without notice. - */ - public final BooleanOptionParser Xshortname; - public final BooleanOptionParser Xmarkup; - public final BooleanOptionParser Xnewmatch; - public final BooleanOptionParser XpreserveWS; - public final BooleanOptionParser XrunTimeTypes; - - /* - * Whole-program optimization options - */ - public final StringOptionParser XrootClass; - public final StringOptionParser XappFile; - public final StringOptionParser XdotFile; - public final BooleanOptionParser Xrta; - public final BooleanOptionParser Xinline; - - //######################################################################## - // Public Constructors - - /** - * Creates an instance variable. - * - * @param product - * @param version - * @param reporter - * @param phases - */ - public CompilerCommand(String product, String version, - Reporter reporter, CompilerPhases phases) - { - this(product, version, "<source files>", reporter, phases); - } - - protected CompilerCommand(String product, String version, String syntax, - Reporter reporter, CompilerPhases phases) - { - super(product, version, syntax, reporter); - this.phases = phases; - - ArgumentParser[] parsers = new ArgumentParser[] { - - this.debuginfo = new BooleanOptionParser(this, - "g", "Generate debugging info", false), - - this.nowarn = new BooleanOptionParser(this, - "nowarn", "Generate no warnings", - false), - - this.verbose = new BooleanOptionParser(this, - "verbose", "Output messages about what the compiler is doing", - false), - - //this.optimize = new OptimizeOptionParser(this, - // "optimize", "optimize bytecode (-optimize:help for option list)", - // null /* todo: uncomment: phases.OPTIMIZE */), - - this.classpath = new StringOptionParser(this, - "classpath", "Specify where to find user class files", - "path", ClassPath.DEFAULT_CLASSPATH), - - this.sourcepath = new StringOptionParser(this, - "sourcepath", "Specify where to find input source files", - "path", ClassPath.DEFAULT_SOURCEPATH), - - this.bootclasspath = new StringOptionParser(this, - "bootclasspath", "Override location of bootstrap class files", - "path", ClassPath.DEFAULT_BOOTCLASSPATH), - - this.extdirs = new StringOptionParser(this, - "extdirs", "Override location of installed extensions", - "dirs", ClassPath.DEFAULT_EXTDIRS), - - this.outpath = new StringOptionParser(this, - "d", "Specify where to place generated class files", - "directory", "."), - - this.encoding = new StringOptionParser(this, - "encoding", "Specify character encoding used by source files", - "encoding", System.getProperty("file.encoding", "ISO-8859-1")), - - this.separate = new ChoiceOptionParser(this, - "separate", "Read symbol files for separate compilation: (yes, no)", - "separate", new String[]{"yes", "no"}, "default"), - - this.target = new ChoiceOptionParser(this, - "target", "Specify which backend to use (jvm, msil)", - "target", Global.TARGETS, Global.TARGET_JVM), - - this.assemrefs = new StringOptionParser(this, "r", - "Assemblies referenced by the source program (only relevant with '-target:msil')", - "assembly files", "."), - - this.assemname = new StringOptionParser(this, "o", - "Name of the output assembly (only relevant with '-target:msil')", - "assembly name", null), - - this.debug = new BooleanOptionParser(this, - "debug", "Output debugging messages", - false), - - this.explaintypes = new BooleanOptionParser(this, - "explaintypes", "Explain type errors in more detail", - false), - - this.uniqid = new BooleanOptionParser(this, - "uniqid", "Print identifiers with unique names (debugging option)", - false), - - this.types = new BooleanOptionParser(this, - "types", "Print tree types (debugging option)", - false), - - this.prompt = new BooleanOptionParser(this, - "prompt", "Display a prompt after each error (debugging option)", - false), - - this.noimports = new BooleanOptionParser(this, - "noimports", "Compile without any implicit imports", - false), - - this.nopredefs = new BooleanOptionParser(this, - "nopredefs", "Compile without any implicit predefined values", - false), - - this.skip = new PhaseSetOptionParser(this, - "skip", "Skip <phases> (see below)", - phases.phases(), PhaseDescriptor.SKIP), - - this.check = new PhaseSetOptionParser(this, - "check", "Check the tree after <phases> (see below)", - phases.phases(), PhaseDescriptor.CHECK), - - this.print = new PrintOptionParser(this, - "print", "Print out program after <phases> (see below)", - phases.phases(), PhaseDescriptor.PRINT), - - this.printer = new ChoiceOptionParser(this, - "printer", "Printer to use", - "printer", Global.PRINTERS, Global.PRINTER_TEXT), - - this.printfile = new StringOptionParser(this, - "print-file", "Specify file in which to print trees", - "file", "-"), - - this.graph = new PhaseSetOptionParser(this, - "graph", "Graph the program after <phases> (see below)", - phases.phases(), PhaseDescriptor.GRAPH), - - this.stop = new PhaseSetOptionParser(this, - "stop", "Stop after first phase in <phases> (see below)", - phases.phases(), PhaseDescriptor.STOP), - - this.log = new PhaseSetOptionParser(this, - "log", "Log operations in <phases> (see below)", - phases.phases(), PhaseDescriptor.LOG), - - this.version = new VersionOptionParser(this, - "version", "Print product version and exit", - product() + " " + version() + " -- (c) 2002-05 LAMP/EPFL"), - - this.help = new HelpOptionParser(this, - "help", "Print a synopsis of standard options"), - - this.Xshortname = new BooleanOptionParser(this, - "Xshortname", "Display short file names in error reports", - false), - - this.Xmarkup = new BooleanOptionParser(this, - "Xmarkup", "no effect, only for compatibility", - false), - - this.Xnewmatch = new BooleanOptionParser(this, - "Xnewmatch", "new pattern matching", - false), - - this.XpreserveWS = new BooleanOptionParser(this, - "XpreserveWS", "don't trim whitespace in XML literals", - false), - - this.XrootClass = new StringOptionParser(this, - "XrootClass", "Specify the root class of the global application", - "class", "$"), - - this.XappFile = new StringOptionParser(this, - "XappFile", "Specify the filename where to dump the whole-application inferred from the rootclass", - "file", "app.txt"), - - this.XdotFile = new StringOptionParser(this, - "XdotFile", "Specify the filename where to print the AST in graphviz dot format", - "file", "$"), - - this.Xrta = new BooleanOptionParser(this, - "Xrta", "Perform Rapid Type analysis for method call resolution", - false), - - this.Xinline = new BooleanOptionParser(this, - "Xinline", "Inline method calls that can be resolved statically", - false), - - this.XrunTimeTypes = new BooleanOptionParser(this, - "Xrtt", "Enable run-time types", - false), - - this.unknown_options = new UnknownOptionParser(this), - - this.files = new ScalaFileArgumentParser(this), - - this.unknown_arguments = new UnknownArgumentParser(this), - - }; - - for (int i = 0; i < parsers.length; i++) add(parsers[i]); - } - - //######################################################################## - // Public Methods - - /** - * .. - * - * @param args - */ - public boolean parse(String[] args) { - boolean result = super.parse(args); - reporter().verbose(verbose.value); - reporter().nowarn(nowarn.value); - reporter().prompt(prompt.value); - if (reporter() instanceof ConsoleReporter) - ((ConsoleReporter)reporter()).shortname = Xshortname.value; - return result; - } - - private boolean containsPhaseOptions() { - List parsers = parsers(); - for (int i = 0; i < parsers.size(); i++) { - if (parsers.get(i) instanceof PhaseSetOptionParser) return true; - } - return false; - } - - /** - * Returns the help message for this compiler command. - * - * @return a formatted string containing the help message. - */ - public String getHelpMessage() { - StringBuffer buffer = new StringBuffer(super.getHelpMessage()); - if (containsPhaseOptions()) { - buffer.append(Strings.EOL); - buffer.append("and possible compilation phases include:"); - buffer.append(Strings.EOL); - PhaseDescriptor[] array = phases.phases(); - List lines = new ArrayList(array.length); - for (int i = 0; i < array.length; i++) { - PhaseDescriptor phase = array[i]; - lines.add(" " + phase.name() + "\t " + phase.description()); - } - lines.add(" " + "all" + "\t " + "matches all phases"); - buffer.append(Strings.format(lines)); - } - return buffer.toString(); - } - - /** - * Returns the class path for this compiler command. - * - * @return the class path. - */ - public ClassPath classpath() { - return new ClassPath(classpath.value, sourcepath.value, - bootclasspath.value, extdirs.value); - } - - /** - * Returns the output path for this compiler command. - * - * @return the output path terminated by . - */ - public String outpath() { - return outpath.value + ( - outpath.value.endsWith(File.separator) ? "" : File.separator - ); - } - - //######################################################################## -} diff --git a/sources/scalac/CompilerPhases.java b/sources/scalac/CompilerPhases.java deleted file mode 100644 index 3440f9bf75..0000000000 --- a/sources/scalac/CompilerPhases.java +++ /dev/null @@ -1,231 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class defines all compiler phases and maintains a list of - * active phases. - */ -public abstract class CompilerPhases { - - //######################################################################## - // Public Fields - - /** The compiler phases. */ - public final PhaseDescriptor INITIAL; - public final PhaseDescriptor PARSER; - public final PhaseDescriptor NAMER; - public final PhaseDescriptor ANALYZER; - public final PhaseDescriptor REFCHECK; - public final PhaseDescriptor UNCURRY; - // public final PhaseDescriptor OPTIMIZE; - public final PhaseDescriptor TAILCALL; // Moved here experimentally - - public final PhaseDescriptor TRANSMATCH; - public final PhaseDescriptor LAMBDALIFT; - public final PhaseDescriptor ADDACCESSORS; - public final PhaseDescriptor EXPLICITOUTER; - public final PhaseDescriptor ADDCONSTRUCTORS; - public final PhaseDescriptor TYPESASVALUES; - - public final PhaseDescriptor WHOLEPROG; - public final PhaseDescriptor ADDINTERFACES; - public final PhaseDescriptor EXPANDMIXIN; - public final PhaseDescriptor MAKEBOXINGEXPLICIT; - public final PhaseDescriptor ERASURE; - public final PhaseDescriptor ICODE; - public final PhaseDescriptor CODEGEN; - public final PhaseDescriptor TERMINAL; - - //######################################################################## - // Private Fields - - /** The list containing the active phases */ - private final List phases; - - /** Phase names, can be overridden to install . - */ - protected abstract Class PARSER_PHASE(); - protected abstract Class NAMER_PHASE(); - protected abstract Class ANALYZER_PHASE(); - protected abstract Class REFCHECK_PHASE(); - protected abstract Class UNCURRY_PHASE(); - protected abstract Class TRANSMATCH_PHASE(); - protected Class LAMBDALIFT_PHASE() { return scalac.transformer.LambdaLiftPhase.class; } - protected Class EXPLICITOUTER_PHASE() { return scalac.transformer.ExplicitOuterClassesPhase.class; } - protected Class ADDACCESSORS_PHASE() { return scalac.transformer.AddAccessorsPhase.class; } - protected Class ADDCONSTRUCTORS_PHASE() { return scalac.transformer.AddConstructorsPhase.class; } - protected Class TYPESASVALUES_PHASE() { return scalac.transformer.TypesAsValuesPhase.class; } - protected Class TAILCALL_PHASE() { return scalac.transformer.TailCallPhase.class; } - protected abstract Class WHOLEPROG_PHASE(); - protected Class ADDINTERFACES_PHASE() { return scalac.transformer.AddInterfacesPhase.class; } - protected Class EXPANDMIXIN_PHASE() { return scalac.transformer.ExpandMixinsPhase.class; } - protected Class ERASURE_PHASE() { return scalac.transformer.ErasurePhase.class; } - protected abstract Class ICODE_PHASE(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public CompilerPhases() { - this.phases = new ArrayList(); - PhaseDescriptor[] array = { - this.INITIAL = new PhaseDescriptor( - "initial", - "initializing compiler", - "initializing compiler", - scalac.util.EmptyPhase.class), - this.PARSER = new PhaseDescriptor( - "parse", - "parse source files", - "parsed", - PARSER_PHASE()), - this.NAMER = new PhaseDescriptor( - "namer", - "create symbols", - "symbols created", - NAMER_PHASE()), - this.ANALYZER = new PhaseDescriptor( - "analyze", - "name and type analysis", - "type checking", - ANALYZER_PHASE()), - this.REFCHECK = new PhaseDescriptor( - "refcheck", - "reference checking", - "reference checking", - REFCHECK_PHASE()), - this.UNCURRY = new PhaseDescriptor( - "uncurry", - "uncurry function types and applications", - "uncurried", - UNCURRY_PHASE()), -// this.OPTIMIZE = new PhaseDescriptor( -// "optimize", -// "tree-optimizer", -// "tree optimization", -// scalac.optimizer.OptimizePhase.class), - - this.TAILCALL = new PhaseDescriptor( - "tailcall", - "add tail-calls", - "added tail-calls", - TAILCALL_PHASE()), - - this.TRANSMATCH = new PhaseDescriptor( - "transmatch", - "translate match expressions", - "translated pattern matching", - TRANSMATCH_PHASE()), - this.TYPESASVALUES = new PhaseDescriptor( - "typesasvalues", - "represent types as values", - "represented types as values", - TYPESASVALUES_PHASE()), - this.LAMBDALIFT = new PhaseDescriptor( - "lambdalift", - "lambda lifter", - "lambda lifting", - LAMBDALIFT_PHASE()), - this.ADDACCESSORS = new PhaseDescriptor( - "addaccessors", - "add accessors for constructor arguments", - "added accessors", - ADDACCESSORS_PHASE()), - this.EXPLICITOUTER = new PhaseDescriptor( - "explicitouterclasses", - "make links from inner classes to enclosing one explicit", - "made outer links explicit", - EXPLICITOUTER_PHASE()), - this.ADDCONSTRUCTORS = new PhaseDescriptor( - "addconstructors", - "add explicit constructor for each class", - "added constructors", - ADDCONSTRUCTORS_PHASE()), - this.WHOLEPROG = new PhaseDescriptor( - "wholeprog", - "perform whole program analysis", - "find monomorphic callsites and performs inlining", - WHOLEPROG_PHASE()), - this.ADDINTERFACES = new PhaseDescriptor( - "addinterfaces", - "add one interface per class", - "added interfaces", - ADDINTERFACES_PHASE()), - this.EXPANDMIXIN = new PhaseDescriptor( - "expandmixins", - "expand mixins by code copying", - "expanded mixins", - EXPANDMIXIN_PHASE()), - this.MAKEBOXINGEXPLICIT = new PhaseDescriptor( - "boxing", - "makes boxing explicit", - "made boxing explicit", - scalac.transformer.MakeBoxingExplicitPhase.class), - this.ERASURE = new PhaseDescriptor( - "erasure", - "type eraser", - "erased types", - ERASURE_PHASE()), - this.ICODE = new PhaseDescriptor( - "icode", - "generate icode", - "generated icode", - ICODE_PHASE()), - this.CODEGEN = new PhaseDescriptor( - "codegen", - "enable code generation", - "code generation enabled", - scalac.util.EmptyPhase.class), - this.TERMINAL = new PhaseDescriptor( - "terminal", - "compilation terminated", - "compilation terminated", - scalac.util.EmptyPhase.class), - }; - for (int i = 0; i < array.length; i++) phases.add(array[i]); - } - - //######################################################################## - // Public Methods - - /** Returns an array containing all active phases. */ - public PhaseDescriptor[] phases() { - PhaseDescriptor[] array = new PhaseDescriptor[phases.size()]; - phases.toArray(array); - return array; - } - - /** Freezes all active phases. */ - public void freeze() { - PhaseDescriptor[] phases = phases(); - PhaseDescriptor.freeze(phases); - } - - /** Activates phase "phase" by placing it before phase "where". */ - public int insertBefore(PhaseDescriptor phase, PhaseDescriptor where) { - int index = phases.indexOf(where); - assert index >= 0 : "could not find phase " + where; - phases.add(index, phase); - return index; - } - - /** Activates phase "phase" by placing it after phase "where". */ - public int insertAfter(PhaseDescriptor phase, PhaseDescriptor where) { - int index = phases.indexOf(where); - assert index >= 0 : "could not find phase " + where; - phases.add(index + 1, phase); - return index + 1; - } - - //######################################################################## -} diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java deleted file mode 100644 index 801883ad25..0000000000 --- a/sources/scalac/Global.java +++ /dev/null @@ -1,706 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import ch.epfl.lamp.util.CodePrinter; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; -import java.util.*; - -import scala.tools.util.AbstractFile; -import scala.tools.util.ClassPath; -import scala.tools.util.Position; -import scala.tools.util.SourceFile; -import scala.tools.util.SourceReader; -import scala.tools.util.Reporter; -import scala.tools.util.Timer; -import scala.tools.util.DummyTimer; -import scala.tools.util.ReporterTimer; - -import scalac.ast.*; -import scalac.ast.parser.*; -import scalac.ast.printer.TreePrinter; -import scalac.atree.AConstant; -import scalac.atree.ATreePrinter; -import scalac.backend.Primitives; -// !!! <<< Interpreter stuff -import scalac.symtab.*; -// !!! >>> Interpreter stuff -import scalac.symtab.Definitions; -import scalac.symtab.classfile.PackageParser; -import scalac.symtab.classfile.CLRPackageParser; -import scalac.typechecker.AnalyzerPhase; -import scalac.typechecker.Infer; -import scalac.transformer.ICodePhase; -import scalac.util.*; - -/** The global environment of a compiler run - * - * @author Matthias Zenger - * @version 1.0 - */ -public abstract class Global { - - public static Global instance; - - /** global options - */ - public final boolean noimports; - public final boolean nopredefs; - public final boolean separate; - //public final boolean optimize; - public final boolean debug; - public final boolean debuginfo; - public final boolean explaintypes; - public final boolean uniqid; - public final boolean newMatch; - public final boolean xmlPreserveWS; - public final boolean runTimeTypes; - - public final boolean printtypes; - public final boolean printtokens; - - public final String outpath; - public final String encoding; - public final String target; - - /** the message reporter - */ - public final Reporter reporter; - - /** the timer - */ - public final Timer timer; - - /** the source file charset - */ - private final Charset charset; - - /** the source file decoder - */ - private final CharsetDecoder decoder; - - /** the source file reader - */ - private final SourceReader reader; - - /** the class path - */ - public final ClassPath classPath; - - /** the global tree factory - */ - public final TreeFactory make; - - /** the tree generator - */ - public final TreeGen treeGen; - - /** the global tree printer - */ - public final PrintWriter writer; - public final TreePrinter treePrinter; - - /** documentation comments of symbols - */ - public final Map/*<Symbol, String>*/ mapSymbolComment = new HashMap(); - - /** attributes of symbols - */ - protected final Map/*<Symbol, AttributeInfo>*/ mapSymbolAttr = new HashMap(); - - /** views associated with (upper-bounded) type parameters - */ - public final Map/*<Symbol, Symbol>*/ viewOfTypeParam = new HashMap(); - - /** Pickled info of top-level symbols - */ - public final Map/*<Symbol, Pickle>*/ symdata = new HashMap(); - - - /** The compiler command arguments - */ - public final CompilerCommand args; - - /** The set of currently compiled top-level symbols - */ - public HashMap/*<Symbol,Sourcefile>*/ compiledNow = new HashMap(); - - /** The set of already compiled sourcefiles - */ - private HashSet/*<SourceFile>*/ compiledUnits = new HashSet(); - - /** the current phase - */ - public Phase currentPhase; - - /** the global definitions - */ - public Definitions definitions; - - /** the global primitives - */ - public final Primitives primitives; - - /** compilation phases. - */ - public final CompilerPhases PHASE; - - /** The current compilation loop or null */ - private CompilationLoop loop; - - /** compilation targets - */ - public static final String TARGET_INT; - public static final String TARGET_JVM; - public static final String TARGET_MSIL; - public static final String TARGET_JVMFROMICODE; - - public static final String[] TARGETS = new String[] { - TARGET_INT = "int", - TARGET_JVM = "jvm", - TARGET_MSIL = "msil", - TARGET_JVMFROMICODE = "jvmfromicode" - }; - - /** tree printers - */ - public static final String PRINTER_TEXT; - public static final String PRINTER_HTML; - public static final String PRINTER_SWING; - - public static final String[] PRINTERS = new String[] { - PRINTER_TEXT = "text", - PRINTER_HTML = "html", - PRINTER_SWING = "swing", - }; - - public static Timer getTimer(Reporter reporter) { - return reporter.verbose() - ? (Timer)new ReporterTimer(reporter) - : (Timer)DummyTimer.object; - } - - /** hooks for installing printers - */ - public abstract Infer newInfer(); - public abstract TreePrinter newTextTreePrinter(PrintWriter writer); - public abstract TreePrinter newHTMLTreePrinter(PrintWriter writer); - public abstract TreePrinter newSwingTreePrinter(PrintWriter writer); - - /** - * Creates an instance variable. - * - * @param args - * @param interpret - */ - public Global(CompilerCommand args, Timer timer, boolean interpret) { - assert Debug.initialize() || true; - if (Global.instance != null) // jaco bug: can't use assert here - /* throw */ Debug.abort("duplicate creation of Global"); - Global.instance = this; - this.args = args; - this.reporter = args.reporter(); - this.timer = timer; - this.noimports = args.noimports.value; - this.nopredefs = args.nopredefs.value; - //this.optimize = args.optimize.optimize; - this.debug = args.debug.value; - this.debuginfo = args.debuginfo.value; - this.uniqid = args.uniqid.value; - this.newMatch = args.Xnewmatch.value; - this.xmlPreserveWS = args.XpreserveWS.value; - this.runTimeTypes = args.XrunTimeTypes.value; - this.explaintypes = args.explaintypes.value; - this.printtypes = args.types.value; - this.printtokens = args.print.tokens; - this.classPath = args.classpath(); - reporter.info(null, "classpath = " + classPath, false); - this.outpath = args.outpath(); - String encoding = args.encoding.value; - Charset charset = null; - try { - charset = Charset.forName(encoding); - } catch (IllegalCharsetNameException exception) { - args.encoding.error("illegal charset name '" + encoding + "'"); - } catch (UnsupportedCharsetException exception) { - args.encoding.error("unsupported charset '" + encoding + "'"); - } - if (charset == null) { - encoding = "ISO-8859-1"; // A mandatory charset - charset = Charset.forName(encoding); - } - this.encoding = encoding; - this.charset = charset; - this.decoder = charset.newDecoder(); - this.reader = new SourceReader(decoder); - this.target = interpret ? TARGET_INT : args.target.value.intern(); - this.separate = args.separate.value.equals("yes") || - args.separate.value.equals("default") && !this.target.equals(TARGET_INT); - String printFile = args.printfile.value; - OutputStream stream; - try { - stream = "-".equals(printFile) - ? System.out - : new FileOutputStream(printFile); - } catch (FileNotFoundException e) { - error("unable to open file " + printFile + ". Printing on console"); - stream = System.out; - } - this.writer = new PrintWriter(stream, debug); - if (args.printer.value.equals(PRINTER_HTML)) { - this.treePrinter = newHTMLTreePrinter(writer); - } else if (args.printer.value.equals(PRINTER_SWING)) { - this.treePrinter = newSwingTreePrinter(writer); - } else { - if (!args.printer.value.equals(PRINTER_TEXT)) - error("unknown printer kind: " + args.printer.value); - this.treePrinter = newTextTreePrinter(writer); - } - this.make = new DefaultTreeFactory(); - this.PHASE = args.phases; - args.phases.WHOLEPROG.addSkipFlag(); // !!! - // if (!optimize) PHASE.remove(args.phases.OPTIMIZE); - // TODO: Enable TailCall for other backends when they handle LabelDefs - if (target != TARGET_JVMFROMICODE) args.phases.ICODE.addSkipFlag(); - PHASE.freeze(); - PhaseDescriptor[] descriptors = PHASE.phases(); - int i = 0; - for (; i < descriptors.length; i++) { - if (!descriptors[i].hasSkipFlag()) descriptors[i].create(this); - if (descriptors[i] == PHASE.ANALYZER) { i++; break; } - } - this.treeGen = ((AnalyzerPhase)PHASE.ANALYZER.phase()).gen; - this.primitives = new Primitives(this); - for (; i < descriptors.length; i++) - if (!descriptors[i].hasSkipFlag()) descriptors[i].create(this); - assert descriptors.length >= 2 - && descriptors[0] == PHASE.INITIAL - && descriptors[descriptors.length - 1] == PHASE.TERMINAL: - Debug.show(descriptors); - assert !PHASE.INITIAL.hasSkipFlag(); - this.currentPhase = PHASE.INITIAL.phase(); - } - - /** - * Moves to next phase. - */ - public void nextPhase() { - assert currentPhase.next != null; - currentPhase = currentPhase.next; - } - - /** Move to previous phase - */ - public void prevPhase() { - assert currentPhase.prev != null; - currentPhase = currentPhase.prev; - } - - /** Creates a virtual source file with given name and content. */ - public SourceFile getSourceFile(String sourcename, String content) { - return new SourceFile(sourcename, content.toCharArray()); - } - - /** Reads and returns the source file in file with given name. */ - public SourceFile getSourceFile(String filename) throws IOException { - AbstractFile file = AbstractFile.getFile(filename); - if (file == null) throw new FileNotFoundException( - "source file '" + filename + "' could not be found"); - return getSourceFile(file); - } - - /** Reads and returns the source file in given abstract file. */ - public SourceFile getSourceFile(AbstractFile file) throws IOException { - return new SourceFile(file, reader.read(file)); - } - - /** Reads and returns the source file of given clasz. */ - public SourceFile getSourceFile(Symbol clasz) throws IOException { - assert clasz.isClass() && clasz.isStatic(): Debug.show(clasz); - AbstractFile file = classPath.getRoot().lookupPath( - SourceRepresentation.externalizeFileName(clasz, ".scala"), false); - if (file == null) throw new FileNotFoundException( - "source file for " + clasz + " could not be found"); - return getSourceFile(file); - } - - /** Returns the root symbol loader. */ - public SymbolLoader getRootLoader() { - return target == TARGET_MSIL - ? new CLRPackageParser(this, classPath.getRoot()) - : new PackageParser(this, classPath.getRoot()); - } - - /** the top-level compilation process - */ - public CompilationUnit[] compile(String[] files, boolean console) { - reporter.resetCounters(); - // parse files - List units = new ArrayList(files.length); - for (int i = 0; i < files.length; i++) { - try { - SourceFile source = getSourceFile(files[i]); - units.add(new CompilationUnit(this, source, console)); - compiledUnits.add(source); - } catch (IOException exception) { - error("IO problem (encoding problem?) with file "+files[i] - +"\n exception was: "+exception.getMessage()); - } - } - CompilationUnit[] array = new CompilationUnit[units.size()]; - return compile((CompilationUnit[])units.toArray(array)); - } - - /** - * The top-level compilation process. - * - * @param filename - * @param input - * @param console - */ - public CompilationUnit[] compile(String filename, String input, boolean console) { - reporter.resetCounters(); - SourceFile source = getSourceFile(filename, input); - compiledUnits.add(source); - CompilationUnit[] units = {new CompilationUnit(this, source, console)}; - return compile(units); - } - - /** compile all compilation units - */ - private CompilationUnit[] compile(CompilationUnit[] units) { - this.currentPhase = PHASE.INITIAL.phase(); - treePrinter.begin(); - this.loop = new CompilationLoop(this); - loadFunctions(); - units = loop.compile(units); - this.loop = null; - if (reporter.errors() != 0) { - imports.clear(); - for (Iterator i = compiledNow.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = (Map.Entry)i.next(); - Symbol clasz = (Symbol)entry.getKey(); - AbstractFile file = ((SourceFile)entry.getValue()).getFile(); - clasz.reset(new SourceCompleter(this, file)); - } - } - compiledNow.clear(); - treePrinter.end(); - this.currentPhase = PHASE.TERMINAL.phase(); - return units; - } - - protected abstract void loadFunctions(); - - /** Compiles an additional source file. */ - public void compileLate(SourceFile source, boolean mixinOnly) { - assert loop != null: source; - if (!compiledUnits.contains(source)) { - compiledUnits.add(source); - CompilationUnit unit = new CompilationUnit(this, source, false, mixinOnly); - loop.insert(unit); - } - } - - - /** Add attribute for a symbol - * @param sym - symbol of the defininition to which the attribute is applied - * @param aSym - symbol of the constructor of the attribute class - * @param args - arguments to the attribute constructor - */ - public void addAttribute(Symbol sym, Symbol aSym, AConstant[] args) { - if (aSym != null && ! (aSym.isNone() || aSym.isError())) { - AttributeInfo attr = getAttributes(sym); - attr = new AttributeInfo(aSym, args, attr); - setAttribute(sym, attr); - } - } - - /** Add attribute with no arguments - * @param sym - symbol of the defininition to which the attribute is applied - * @param aSym - symbol of the constructor of the attribute class - */ - public void addAttribute(Symbol sym, Symbol aSym) { - addAttribute(sym, aSym, AConstant.EMPTY_ARRAY); - } - - /** Set the attributes for a given symbol - */ - public void setAttribute(Symbol sym, AttributeInfo attr) { - mapSymbolAttr.put(sym, attr); - if (sym.isModule() && !sym.isModuleClass()) - mapSymbolAttr.put(sym.moduleClass(), attr); - } - - /** Return all attributes for a given symbol - */ - public AttributeInfo getAttributes(Symbol sym) { - return (AttributeInfo)mapSymbolAttr.get(sym); - } - - /** Return attribute arguments - * @param sym - symbol of the definition - * @param aSym - symbol of the constructor of the attribute class - */ - public AConstant[] getAttrArguments(Symbol sym, Symbol aSym) { - AttributeInfo attrs = getAttributes(sym); - return attrs == null ? null : attrs.getAttrArguments(aSym); - } - - /** Remove the attributes for a given symbol - */ - public AttributeInfo removeAttributes(Symbol sym) { - return (AttributeInfo)mapSymbolAttr.remove(sym); - } - - public abstract void dump(CompilationUnit[] units); - - void print(CompilationUnit[] units) { - if (currentPhase.id == PHASE.MAKEBOXINGEXPLICIT.id()) { - boolean html = args.printer.value.equals(PRINTER_HTML); - if (html) writer.println("<pre>"); - ATreePrinter printer = new ATreePrinter(new CodePrinter(writer)); - boolean next = currentPhase.next != null; - if (next) currentPhase = currentPhase.next; - printer.printUnits(units); - if (next) currentPhase = currentPhase.prev; - if (html) writer.println("</pre>"); - } else if (currentPhase.id == PHASE.ICODE.id()) { - Phase phase = currentPhase; - boolean html = args.printer.value.equals(PRINTER_HTML); - if (html) writer.println("<pre>"); - - boolean next = currentPhase.next != null; - if (next) currentPhase = currentPhase.next; - ((ICodePhase)phase).print(units, new CodePrinter(writer)); - if (next) currentPhase = currentPhase.prev; - if (html) writer.println("</pre>"); - } else { - // go to next phase to print symbols with their new type - boolean next = currentPhase.next != null; - if (next) currentPhase = currentPhase.next; - treePrinter.print(units); - if (next) currentPhase = currentPhase.prev; - } - } - - // !!! <<< Interpreter stuff - public static final String CONSOLE_S = "$console$"; - private static final Name - SHOW_DEFINITION_N = Name.fromString("showDefinition"), - SHOW_VALUE_DEFINITION_N = Name.fromString("showValueDefinition"), - SET_EVALUATION_RESULT_N = Name.fromString("setEvaluationResult"); - private Symbol INTERPRETER; - private Symbol PRINTER; - private Symbol SHOW_VALUE; - private Symbol SET_EVALUATION_RESULT; - private Symbol SHOW_DEFINITION; - private Symbol SHOW_VALUE_DEFINITION; - - private Symbol INTERPRETER() { - if (INTERPRETER == null) - INTERPRETER = definitions.getModule("scala.runtime.InterpreterSupport"); - return INTERPRETER; - } - - private Symbol SHOW_DEFINITION() { - if (SHOW_DEFINITION == null) - SHOW_DEFINITION = INTERPRETER().lookup(SHOW_DEFINITION_N); - return SHOW_DEFINITION; - } - - private Symbol SHOW_VALUE_DEFINITION() { - if (SHOW_VALUE_DEFINITION == null) - SHOW_VALUE_DEFINITION = INTERPRETER().lookup(SHOW_VALUE_DEFINITION_N); - return SHOW_VALUE_DEFINITION; - } - - private Symbol SET_EVALUATION_RESULT() { - if (SET_EVALUATION_RESULT == null) - SET_EVALUATION_RESULT = INTERPRETER().lookup(SET_EVALUATION_RESULT_N); - return SET_EVALUATION_RESULT; - } - - private int module = 0; - private List imports = new ArrayList(); - public Symbol console; - - void fix1(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) { - if (units[i].console) fix1(units[i]); - } - nextPhase(); - for (int i = 0; i < imports.size(); i++) { - Symbol module = (Symbol)imports.get(i); - ((scalac.typechecker.AnalyzerPhase)PHASE.ANALYZER.phase()).addConsoleImport(module); - } - prevPhase(); - } - - private void fix1(CompilationUnit unit) { - unit.body = new Tree[] { - make.ModuleDef(Position.FIRSTPOS, - 0, Name.fromString(CONSOLE_S+module), Tree.Empty, - make.Template(Position.FIRSTPOS, new Tree[]{ - make.Apply(Position.FIRSTPOS, - make.Select(Position.FIRSTPOS, - make.Ident(Position.FIRSTPOS, Names.scala), - Names.AnyRef.toTypeName()), - new Tree[0])}, - unit.body))}; - module++; - } - - void fix2(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) { - if (units[i].console) fix2(units[i]); - } - } - - private void fix2(CompilationUnit unit) { - imports.clear(); - for (int i = 0; i < unit.body.length; i++) { - switch (unit.body[i]) { - case ModuleDef(_, _, _, Tree.Template impl): - Symbol symbol = unit.body[i].symbol(); - if (!symbol.name.toString().startsWith(CONSOLE_S)) break; - console = symbol; - if (impl.body.length <= 0) break; - imports.add(unit.body[i].symbol()); - Tree last = impl.body[impl.body.length - 1]; - if (last != Tree.Empty && last.isTerm()) { - impl.body[impl.body.length - 1] = - treeGen.Apply(last.pos, - treeGen.Select(last.pos, - treeGen.mkGlobalRef(last.pos, INTERPRETER()), - SET_EVALUATION_RESULT()), - new Tree[] { - last, - treeGen.mkStringLit( - last.pos, show(last.getType()))}); - } - TreeList body = new TreeList(); - for (int j = 0; j < impl.body.length; j++) - fix2(body, impl.body[j]); - impl.body = body.toArray(); - break; - } - } - } - - private void fix2(TreeList body, Tree tree) { - body.append(tree); - switch (tree) { - case PatDef(_, _, _): // !!! impossible (removed by analyzer) - assert false : Debug.show(tree); - return; - case ClassDef(_, _, _, _, _, _): - case PackageDef(_, _): - case ModuleDef(_, _, _, _): - case DefDef(_, _, _, _, _, _): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - if (!mustShow(tree.symbol())) return; - body.append( - treeGen.Apply(tree.pos, - treeGen.Select(tree.pos, - treeGen.mkGlobalRef(tree.pos, INTERPRETER()), - SHOW_DEFINITION()), - new Tree[] { - treeGen.mkStringLit(tree.pos, show(tree.symbol()))})); - return; - case ValDef(_, _, _, _): - if (!mustShow(tree.symbol())) return; - body.append( - treeGen.Apply(tree.pos, - treeGen.Select(tree.pos, - treeGen.mkGlobalRef(tree.pos, INTERPRETER()), - SHOW_VALUE_DEFINITION()), - new Tree[] { - treeGen.mkStringLit(tree.pos, show(tree.symbol())), - treeGen.Ident(tree.pos, tree.symbol())})); - return; - default: - return; - } - } - - private boolean mustShow(Symbol symbol) { - return !symbol.isAccessor(); - } - - private String show(Symbol symbol) { - return new InterpreterPrinter().printSignature(symbol).toString(); - } - - private String show(Type type) { - return new InterpreterPrinter().printType(type).toString(); - } - - private class InterpreterPrinter extends SymbolTablePrinter { - public InterpreterPrinter() { - super(" "); - } - public String getSymbolName(Symbol symbol) { - String string = super.getSymbolName(symbol); - if (!debug) { - int index = string.indexOf('$'); - if (index > 0) string = string.substring(0, index); - } - return string; - } - } - - // !!! >>> Interpreter stuff - - /** issue a global error - */ - public void error(String message) { - reporter.error(null, message); - } - - /** issue a global warning - */ - public void warning(String message) { - reporter.warning(null, message); - } - - /** issue an operation note - */ - public void operation(String message) { - reporter.info(null, "[" + message + "]", false); - } - - /** issue a debug message from currentPhase - */ - // the boolean return value is here to let one write "assert log( ... )" - public boolean log(String message) { - if (log()) { - reporter.info(null, "[log " + currentPhase + "] " + message, true); - } - return true; - } - - /** return true if logging is switched on for the current phase - */ - public boolean log() { - return currentPhase.descriptor.hasLogFlag(); - } - -} diff --git a/sources/scalac/Phase.java b/sources/scalac/Phase.java deleted file mode 100644 index 5239562e9d..0000000000 --- a/sources/scalac/Phase.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -public abstract class Phase { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - /** The phase descriptor */ - public final PhaseDescriptor descriptor; - - /** The phase identifier */ - public final int id; - - /** The previous phase */ - public final Phase prev; - - /** The next phase */ - public Phase next; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Phase(Global global, PhaseDescriptor descriptor) { - this.global = global; - this.descriptor = descriptor; - this.id = descriptor.id(); - this.prev = global.currentPhase; - if (prev != null) prev.next = this; - descriptor.initialize(this); - global.currentPhase = this; - } - - //######################################################################## - // Public Methods - - /** Does this phase precede the given phase? */ - public boolean precedes(Phase phase) { - return id < phase.id; - } - - /** - * Returns the info of `sym' after the phase. Assumes that `tp' is - * the info of symbol `sym' before this phase. - */ - public Type transformInfo(Symbol sym, Type tp) { - return tp; - } - - /** Applies this phase to the given compilation unit. */ - public abstract void apply(CompilationUnit unit); - - /** Returns the name of this phase. */ - public final String toString() { - return descriptor.name(); - } - - //######################################################################## -} diff --git a/sources/scalac/PhaseDescriptor.java b/sources/scalac/PhaseDescriptor.java deleted file mode 100644 index c93fd327ba..0000000000 --- a/sources/scalac/PhaseDescriptor.java +++ /dev/null @@ -1,233 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import scalac.util.Debug; - -/** - * Information about a compiler phase. - */ -public final class PhaseDescriptor { - - //######################################################################## - // Public Constants - - public static final int STOP = 0x0001; - public static final int SKIP = 0x0002; - public static final int PRINT = 0x0004; - public static final int GRAPH = 0x0008; - public static final int CHECK = 0x0010; - public static final int LOG = 0x0020; - - //######################################################################## - // Public Functions - - /** Freezes the given phases (patches flags and assigns ids). */ - public static void freeze(PhaseDescriptor[] phases) { - // there are at least two phases: INITIAL and TERMINAL - assert phases.length >= 2; - if (phases.length == 0) return; - // propagate STOP and SKIP - for (int i = 0; i < phases.length - 1; i++) { - phases[i].flags |= (phases[i + 1].flags >>> 16) & (STOP | SKIP); - phases[i+1].flags &= ~((STOP | SKIP) << 16); - } - // transform STOP flags into SKIP flags - boolean stop = false; - for (int i = 0; i < phases.length; i++) { - if (stop) phases[i].flags |= SKIP; - stop |= phases[i].hasStopFlag(); - if (stop) phases[i].flags &= ~STOP; - } - // remove SKIP flag on INITIAL and TERMINAL phases - phases[0].flags &= ~SKIP; - phases[phases.length - 1].flags &= ~SKIP; - // propagate other flags and freeze remaining phases - PhaseDescriptor last = null; - for (int i = 0; i < phases.length; i++) { - phases[i].id = 2 * i; - if (phases[i].hasSkipFlag()) continue; - if (last != null) last.flags |= phases[i].flags >>> 16; - phases[i].flags &= 0x0000FFFF; - if (i != phases.length - 1) last = phases[i]; - } - // place TERMINAL phase just after last active phase - phases[phases.length - 1].id = last.id + 1; - } - - //######################################################################## - // Private Fields - - /** The phase name */ - private final String name; - /** The phase description */ - private final String description; - /** The phase task description */ - private final String task; - /** The phase implementation class */ - private final Class clasz; - - /** The flags of this phase */ - private int flags; - /** The phase instance */ - private Phase phase; - /** The phase identifier */ - private int id = -1; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public PhaseDescriptor(String name, String description, String task, - Class clasz) - { - this.name = name; - this.description = description; - this.task = task; - this.clasz = clasz; - } - - //######################################################################## - // Public Methods - - /** Returns the one-word name of this phase. */ - public String name() { - return name; - } - - /** Returns a one-line description of this phase. */ - public String description() { - return description; - } - - /** Returns a one-line task description of this phase. */ - public String taskDescription() { - return task; - } - - /** Creates the object implementing this phase. */ - public Phase create(Global global) { - assert id >= 0 : "phase " + name + " not yet frozen"; - assert phase == null : "phase " + name + " already created"; - try { - Class[] params = { Global.class, PhaseDescriptor.class }; - Object[] args = { global, this }; - Object phase = clasz.getConstructor(params).newInstance(args); - assert this.phase == phase: this.phase + " != " + phase; - return this.phase; - } catch (NoSuchMethodException exception) { - throw Debug.abort(exception); - } catch (IllegalAccessException exception) { - throw Debug.abort(exception); - } catch (InstantiationException exception) { - throw Debug.abort(exception); - } catch (InvocationTargetException exception) { - throw Debug.abort(exception); - } - } - - /** Returns the object implementing this phase. */ - public Phase phase() { - assert phase != null : "phase " + name + " not yet created"; - return phase; - } - - /** Returns the identifier of this phase. */ - public int id() { - assert id >= 0 : "phase " + name + " not yet frozen"; - return id; - } - - /** Adds the given flag (to previous phase if prev is true). */ - public void addFlag(int flag, boolean prev) { - assert id < 0 : "phase " + name + " already frozen"; - flags |= flag << (prev ? 16 : 0); - } - - /** Adds the SKIP flag. */ - public void addSkipFlag() { - flags |= SKIP; - } - - /** Adds the CHECK flag. */ - public void addCheckFlag() { - flags |= CHECK; - } - - /** Adds the PRINT flag. */ - public void addPrintFlag() { - flags |= PRINT; - } - - /** Adds the GRAPH flag. */ - public void addGraphFlag() { - flags |= GRAPH; - } - - /** Adds the STOP flag. */ - public void addStopFlag() { - flags |= STOP; - } - - /** Adds the LOG flag. */ - public void addLogFlag() { - flags |= LOG; - } - - /** Has this phase the SKIP flag? */ - public boolean hasSkipFlag() { - return (flags & SKIP) != 0; - } - - /** Has this phase the CHECK flag? */ - public boolean hasCheckFlag() { - return (flags & CHECK) != 0; - } - - /** Has this phase the PRINT flag? */ - public boolean hasPrintFlag() { - return (flags & PRINT) != 0; - } - - /** Has this phase the GRAPH flag? */ - public boolean hasGraphFlag() { - return (flags & GRAPH) != 0; - } - - /** Has this phase the STOP flag? */ - public boolean hasStopFlag() { - return (flags & STOP) != 0; - } - - /** Has this phase the LOG flag? */ - public boolean hasLogFlag() { - return (flags & LOG) != 0; - } - - /** Returns the name of this phase. */ - public String toString() { - return name(); - } - - //######################################################################## - // Protected Methods - - /** Initializes this descriptor with given phase. */ - protected void initialize(Phase phase) { - assert phase != null: "illegal null phase"; - assert phase.descriptor == this: phase.descriptor.name + " != " + name; - assert this.phase == null: "phase " + name + " already initialized"; - this.phase = phase; - } - - //######################################################################## -} diff --git a/sources/scalac/Unit.java b/sources/scalac/Unit.java deleted file mode 100644 index 44e131bed7..0000000000 --- a/sources/scalac/Unit.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac; - -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import scalac.ast.Tree; -import scalac.atree.ARepository; -import scalac.util.FreshNameCreator; -import java.util.HashMap; - - -/** A representation for a compilation unit in scala - * - * @author Matthias Zenger - * @version 1.0 - */ -public class CompilationUnit { - - /** the global compilation environment - */ - public final Global global; - - /** the associated source code file - */ - public final SourceFile source; - - /** does this unit come from the interpreter console - */ - public final boolean console; - - /** is this unit only there for mixin expansion? - */ - public final boolean mixinOnly; - - /** the fresh name creator - */ - public final FreshNameCreator fresh; - - /** the content of the compilation unit in tree form - */ - public Tree[] body; - public ARepository repository; - - public CompilationUnit(Global global, SourceFile source, - boolean console, boolean mixinOnly) { - this.global = global; - this.source = source; - this.console = console; - this.mixinOnly = mixinOnly; - this.fresh = new FreshNameCreator(); - } - - public CompilationUnit(Global global, SourceFile source, boolean console) { - this(global, source, console, false); - } - - /** return the position representing the given encoded position - */ - public Position position(int pos) { - return new Position(source, pos); - } - - /** issue an error in this compilation unit at a specific location - */ - public void error(int pos, String message) { - global.reporter.error(position(pos), message); - } - - /** issue a warning in this compilation unit at a specific location - */ - public void warning(int pos, String message) { - global.reporter.warning(position(pos), message); - } - - /** return a string representation - */ - public String toString() { - return source.toString(); - } - -} diff --git a/sources/scalac/ast/DefaultTreeFactory.java.tmpl b/sources/scalac/ast/DefaultTreeFactory.java.tmpl deleted file mode 100644 index 48fa7760fa..0000000000 --- a/sources/scalac/ast/DefaultTreeFactory.java.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** The default tree factory */ -public class DefaultTreeFactory implements TreeFactory { - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/LazyTreeCopier.java.tmpl b/sources/scalac/ast/LazyTreeCopier.java.tmpl deleted file mode 100644 index 8da7facf2a..0000000000 --- a/sources/scalac/ast/LazyTreeCopier.java.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** - * A tree copier that returns a new tree only if some fields have - * changed - */ -public class LazyTreeCopier implements TreeCopier { - - //######################################################################## - // Protected Fields - - /** The tree copier used to copy trees */ - protected final TreeCopier copier; - - //######################################################################## - // Public Constructors - - public LazyTreeCopier(TreeFactory make) { - this(new StrictTreeCopier(make)); - } - - public LazyTreeCopier(TreeCopier copier) { - this.copier = copier; - } - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/StrictTreeCopier.java.tmpl b/sources/scalac/ast/StrictTreeCopier.java.tmpl deleted file mode 100644 index f82653279a..0000000000 --- a/sources/scalac/ast/StrictTreeCopier.java.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** A tree copier that returns always a new tree */ -public class StrictTreeCopier implements TreeCopier { - - //######################################################################## - // Protected Fields - - /** The tree factory used to create the tree copies */ - protected final TreeFactory make; - - //######################################################################## - // Public Constructors - - public StrictTreeCopier(TreeFactory make) { - this.make = make; - } - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/Transformer.java.tmpl b/sources/scalac/ast/Transformer.java.tmpl deleted file mode 100644 index 2fa347c305..0000000000 --- a/sources/scalac/ast/Transformer.java.tmpl +++ /dev/null @@ -1,319 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import scalac.Global; -import scalac.CompilationUnit; -import scalac.symtab.Type; -{#Imports#} - -/** - * A default transformer class. This class traverses the abstract - * syntax tree but does not do any transformations. - */ -public class Transformer { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - /** The tree factory */ - public final TreeFactory make; - - /** The tree copier */ - public final TreeCopier copy; - - /** A tree generator */ - public final TreeGen gen; - - //######################################################################## - // Public Constructors - - public Transformer(Global global) { - this(global, global.make); - } - - public Transformer(Global global, TreeFactory make) { - this(global, make, new LazyTreeCopier(make)); - } - - public Transformer(Global global, TreeFactory make, TreeCopier copy) { - this.global = global; - this.make = make; - this.copy = copy; - this.gen = global.treeGen; - } - - //######################################################################## - // Public Methods - - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - unit.body = transform(unit.body); - } - - public Tree transform(Tree tree) { - {#TreeSwitch#} - } - - public Template transform(Template tree) { - return (Template)transform((Tree)tree); - } - - {#TransformArrays#} - - //######################################################################## -} - - -public class GenTransformer { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - /** The type map */ - public final Type.Map map; - - /** A tree generator */ - public final TreeGen gen; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with an identity type map. */ - public GenTransformer(Global global) { - this(global, Type.IdMap); - } - - /** Initializes this instance with given type map. */ - public GenTransformer(Global global, Type.Map map) { - this.global = global; - this.gen = global.treeGen; - this.map = map; - } - - //######################################################################## - // Public Methods - - /** Transforms the given units. */ - public void apply(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) apply(units[i]); - } - - /** Transforms the given unit. */ - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - unit.body = transform(unit.body); - } - - /** Transforms the given symbol. */ - public Symbol getSymbolFor(Tree tree) { - return tree.symbol(); - } - - /** Transforms the given types. */ - public Type[] transform(Type[] types) { - for (int i = 0; i < types.length; i++) { - Type type = transform(types[i]); - if (type == types[i]) continue; - Type[] clones = new Type[types.length]; - for (int j = 0; j < i; j++) clones[j] = types[j]; - clones[i] = type; - for (; i < types.length; i++) clones[i] = transform(types[i]); - return clones; - } - return types; - } - - /** Transforms the given type. */ - public Type transform(Type type) { - return map.apply(type); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - // case Bad(): - - case Empty: - return tree; - - case ClassDef(_, _, _, _, _, Template impl): - Symbol symbol = getSymbolFor(tree); - if (global.currentPhase.id < global.PHASE.ADDCONSTRUCTORS.id()) { - Symbol impl_symbol = getSymbolFor(impl); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - return gen.ClassDef(symbol, parents, impl_symbol, body); - } else { - Tree[] body = transform(impl.body); - return gen.ClassDef(symbol, body); - } - - case PackageDef(Tree packaged, Template(Tree[] parents, Tree[] body)): - Symbol symbol = getSymbolFor(packaged); - assert parents.length == 0: tree; - return gen.PackageDef(symbol, transform(body)); - - // case ModuleDef(_, _, _, Template impl): - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.ValDef(symbol, transform(rhs)); - - // case PatDef(int mods, Tree pat, Tree rhs): - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.DefDef(symbol, transform(rhs)); - - case AbsTypeDef(_, _, _, _): - Symbol symbol = getSymbolFor(tree); - return gen.AbsTypeDef(symbol); - - case AliasTypeDef(_, _, _, _): - Symbol symbol = getSymbolFor(tree); - return gen.AliasTypeDef(symbol); - - case Import(Tree expr, Name[] selectors): - return gen.Import(tree.pos, transform(expr), selectors); - - case CaseDef(Tree pat, Tree guard, Tree body): - pat = transform(pat); - guard = transform(guard); - body = transform(body); - return gen.CaseDef(pat, guard, body); - - // case Template(Tree[] parents, Tree[] body): - - case LabelDef(_, Ident[] params, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.LabelDef(symbol, transform(params), transform(rhs)); - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, transform(stats), transform(value)); - - case Sequence(Tree[] trees): - trees = transform(trees); - Tree seq = new Sequence(trees); - seq.pos = tree.pos; - seq.type = tree.type; - return seq; - // case Alternative(Tree[] trees): - // case Visitor(CaseDef[] cases): - // case Function(ValDef[] vparams, Tree body): - - case Bind(Name n, Tree pat): // test - Symbol sym = getSymbolFor(tree); - global.nextPhase(); - sym.setType(tree.type); - global.prevPhase(); - Tree bind = new ExtBind(sym, transform(pat)); - bind.type = sym.getType(); - bind.pos = tree.pos; - return bind; - - - case Assign(Tree lhs, Tree rhs): - return gen.Assign(tree.pos, transform(lhs), transform(rhs)); - - case If(Tree cond, Tree thenp, Tree elsep): - cond = transform(cond); - thenp = transform(thenp); - elsep = transform(elsep); - if (tree.type().isSameAs(global.definitions.ANY_TYPE())) { - global.nextPhase(); - Type type = global.definitions.ANY_TYPE(); - global.prevPhase(); - return gen.If(tree.pos, cond, thenp, elsep, type); - } else { - return gen.If(tree.pos, cond, thenp, elsep); - } - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - test = transform(test); - bodies = transform(bodies); - otherwise = transform(otherwise); - if (tree.type().isSameAs(global.definitions.ANY_TYPE())) { - global.nextPhase(); - Type type = global.definitions.ANY_TYPE(); - global.prevPhase(); - return gen.Switch(tree.pos, test, tags, bodies,otherwise,type); - } else { - return gen.Switch(tree.pos, test, tags, bodies, otherwise); - } - - case Return(Tree expr): - Symbol symbol = getSymbolFor(tree); - return gen.Return(tree.pos, symbol, transform(expr)); - - // case Throw(Tree expr): - - case New(Tree init): - return gen.New(tree.pos, transform(init)); - - case Create(Tree qualifier, Tree[] args): - Symbol symbol = getSymbolFor(tree); - qualifier = transform(qualifier); - args = transform(args); - return gen.Create(tree.pos, qualifier, symbol, args); - - case Typed(Tree expr, Tree tpe): - return gen.Typed(tree.pos, transform(expr), transform(tpe)); - - case TypeApply(Tree fun, Tree[] args): - return gen.TypeApply(transform(fun), transform(args)); - - case Apply(Tree fun, Tree[] args): - return gen.Apply(transform(fun), transform(args)); - - case Super(_, _): - Symbol symbol = getSymbolFor(tree); - return gen.Super(tree.pos, symbol); - - case This(_): - Symbol symbol = getSymbolFor(tree); - return gen.This(tree.pos, symbol); - - case Select(Tree qualifier, _): - Symbol symbol = getSymbolFor(tree); - return gen.Select(tree.pos, transform(qualifier), symbol); - - case Ident(_): - Symbol symbol = getSymbolFor(tree); - return gen.Ident(tree.pos, symbol); - - case Literal(AConstant value): - return gen.Literal(tree.pos, value); - - case TypeTerm(): - return gen.mkType(tree.pos, transform(tree.type())); - - // case SingletonType(Tree ref): - // case SelectFromType(Tree qualifier, Name selector): - // case FunType(Tree[] argtpes, Tree restpe): - // case CompoundType(Tree[] parents, Tree[] refinements): - // case AppliedType(Tree tpe, Tree[] args): - // case Try(Tree block, Tree catcher, Tree finalizer): - - default: - throw Debug.abort("illegal case", tree); - } - } - - {#TransformArrays#} - - //######################################################################## -} diff --git a/sources/scalac/ast/Traverser.java.tmpl b/sources/scalac/ast/Traverser.java.tmpl deleted file mode 100644 index a17768e2b4..0000000000 --- a/sources/scalac/ast/Traverser.java.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import scalac.CompilationUnit; -{#Imports#} - -/** Class to traverse a tree without modifying it. */ -public class Traverser { - - //######################################################################## - // Public Methods - - public void traverse(CompilationUnit[] units) { - for (int i = 0; i < units.length; i++) traverse(units[i]); - } - - public void traverse(CompilationUnit unit) { - traverse(unit.body); - } - - public void traverse(Tree tree) { - {#TreeSwitch#} - } - - {#TraverseArrays#} - - //######################################################################## -} diff --git a/sources/scalac/ast/Tree.java.tmpl b/sources/scalac/ast/Tree.java.tmpl deleted file mode 100644 index c76c2b37d0..0000000000 --- a/sources/scalac/ast/Tree.java.tmpl +++ /dev/null @@ -1,202 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.ast.printer.TreePrinter; -import scalac.checkers.CheckTreeNodes; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Names; -{#Imports#} - -public class Tree { - - //######################################################################## - // Public Constants - - {#EmptyArrays#} - - //######################################################################## - // Public Fields - - /** The position of the tree */ - public int pos = Position.NOPOS; - - /** The type of the tree */ - public Type type; - - //######################################################################## - // Public Cases - - {#TreeCases#} - - //######################################################################## - // Public Methods - queries - - {#IsKind#} - - //######################################################################## - // Public Methods - tree type - - /** Get the type of the node. */ - public final Type getType() { - return type; - } - - /** Get the type of the node, which must be non-null. */ - public Type type() { - assert type != null : Debug.show(this); - return type; - } - - /** Set the type of the node. */ - public Tree setType(Type type) { - assert !(type instanceof Type.LazyType) : Debug.show(this); - this.type = type; - return this; - } - - /** Get types attached to array of nodes. */ - public static Type[] typeOf(Tree[] trees) { - Type[] types = new Type[trees.length]; - for (int i = 0; i < trees.length; i++) types[i] = trees[i].getType(); - return types; - } - - //######################################################################## - // Public Methods - tree symbol - - /** Has this tree a symbol field? */ - public boolean hasSymbol() { - return false; - } - - /** Tells if the tree defines a symbol. */ - public boolean definesSymbol() { - return false; - } - - /** Get symbol attached to the node, if any. */ - public Symbol symbol() { - return null; - } - - /** Set symbol attached to the node, if possible. */ - public Tree setSymbol(Symbol sym) { - throw Debug.abort("no settable symbol for node", this); - } - - /** Get symbols attached to array of nodes. */ - public static Symbol[] symbolOf(Tree[] trees) { - Symbol[] symbols = new Symbol[trees.length]; - for (int i = 0; i < trees.length; i++) symbols[i] = trees[i].symbol(); - return symbols; - } - - //######################################################################## - // Public Methods - tree to string - - /** Returns the string representation of this tree. */ - public String toString() { - StringWriter buffer = new StringWriter(); - TreePrinter printer = - Global.instance.newTextTreePrinter(new PrintWriter(buffer)); - printer.print(this); - printer.flush(); - return buffer.toString(); - } - - //######################################################################## - // Public Methods - duplication - - public static Transformer duplicator; - - /** Returns a shallow copy of the given array. */ - public static Tree[] cloneArray(Tree[] array) { - return cloneArray(0, array, 0); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items. - */ - public static Tree[] cloneArray(int prefix, Tree[] array) { - return cloneArray(prefix, array, 0); - } - - /** - * Returns a shallow copy of the given array suffixed by "suffix" - * null items. - */ - public static Tree[] cloneArray(Tree[] array, int suffix) { - return cloneArray(0, array, suffix); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items and suffixed by "suffix" null items. - */ - public static Tree[] cloneArray(int prefix, Tree[] array, int suffix) { - assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; - int size = prefix + array.length + suffix; - if (size == 0) return EMPTY_ARRAY; - Tree[] clone = new Tree[size]; - for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; - return clone; - } - - /** Returns the concatenation of the two arrays. */ - public static Tree[] concat(Tree[] array1, Tree[] array2) { - if (array1.length == 0) return array2; - if (array2.length == 0) return array1; - Tree[] clone = cloneArray(array1.length, array2); - for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; - return clone; - } - - public Tree duplicate() { - if (duplicator == null) duplicator =new Transformer( - Global.instance, Global.instance.make, - new StrictTreeCopier(Global.instance.make)); - return duplicator.transform(this); - } - - //######################################################################## - // Public Classes - - {#ExtClasses#} - - //######################################################################## - // Empty Switch - - /* - - public void foobar(Tree tree) { - - switch (tree) { - - {#EmptyCases#} - - default: - throw Debug.abort("illegal case", tree); - } - - } - - */ - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeCloner.java b/sources/scalac/ast/TreeCloner.java deleted file mode 100644 index 8d96c1b23e..0000000000 --- a/sources/scalac/ast/TreeCloner.java +++ /dev/null @@ -1,137 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import java.util.Map; - -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolCloner; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This class implements a deep tree cloner. It provides support to - * change tree symbols and tree types on the fly. This cloner never - * clones symbols, but its default implementation of getSymbolFor - * requires that all symbols that are defined by the tree to be cloned - * are present in the symbol substitution. This implies that if the - * tree to clone contains definitions, it must first be traversed to - * map all defined symbols. To do this, one can use TreeSymbolCloner. - */ -public class TreeCloner extends Transformer { - - //######################################################################## - // Private Fields - - /** The symbol substitution to apply to tree symbols */ - private final Map/*<Symbol,Symbol>*/ symbols; - - /** The type map to apply to tree types */ - private final Type.Map types; - - //######################################################################## - // Public Constructors - - /** Initializes a new instance. */ - public TreeCloner(Global global, SymbolSubstTypeMap types) { - this(global, types.getSymbols(), types); - } - - /** Initializes a new instance. */ - public TreeCloner(Global global, Map symbols, Type.Map types) { - super(global, global.make, new StrictTreeCopier(global.make)); - this.symbols = symbols; - this.types = types; - } - - //######################################################################## - // Public Methods - - /** - * Returns the symbol for the given cloned tree. The default - * implementation returns the result of the application of the - * symbol substitution to the given tree's symbol. If there is no - * mapping for that symbol returns that same symbol. - */ - public Symbol getSymbolFor(Tree tree) { - Symbol oldsym = tree.symbol(); - Symbol newsym = (Symbol)symbols.get(oldsym); - // cloned definitions must have a cloned symbol - assert newsym != null || !tree.definesSymbol() : Debug.show(oldsym); - return newsym != null ? newsym : oldsym; - } - - /** - * Returns the type for the given cloned tree. The default - * implementation returns the result of the application of the - * type map to the given tree's type. - */ - public Type getTypeFor(Tree tree) { - return types.apply(tree.getType()); - } - - /** Traverses the given tree and returns a deeply cloned one. */ - public Tree transform(Tree tree) { - tree = super.transform(tree); - if (tree.hasSymbol()) tree.setSymbol(getSymbolFor(tree)); - tree.setType(getTypeFor(tree)); - return tree; - } - - //######################################################################## -} - - -/** !!! */ -public class GenTreeCloner extends GenTransformer { - - //######################################################################## - // Public Fields - - /** The symbol cloner */ - public final SymbolCloner cloner; - - //######################################################################## - // Public Constructors - - /** Initializes a new instance. */ - public GenTreeCloner(Global global, Type.Map map, SymbolCloner cloner) { - super(global, map); - this.cloner = cloner; - } - - public GenTreeCloner(Global global, SymbolCloner cloner) { - super(global, cloner.getTypeMap()); - this.cloner = cloner; - } - - //######################################################################## - // Public Methods - - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - if (tree.symbol().owner().isClass()) break; - Symbol symbol = cloner.cloneSymbol(tree.symbol()); - symbol.setType(transform(symbol.type())); - return symbol; - case LabelDef(_, _, _): - Symbol symbol = cloner.cloneSymbol(tree.symbol()); - symbol.setType(transform(symbol.type())); - return symbol; - } - Symbol symbol = (Symbol)cloner.clones.get(tree.symbol()); - assert !tree.definesSymbol() || symbol != null: tree; - return symbol != null ? symbol : tree.symbol(); - } - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeCopier.java.tmpl b/sources/scalac/ast/TreeCopier.java.tmpl deleted file mode 100644 index 27a9cf476e..0000000000 --- a/sources/scalac/ast/TreeCopier.java.tmpl +++ /dev/null @@ -1,26 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** - * Interface for a kind of factory which, for each node constructor, - * takes an original node from which some data will be copied or - * shared. - */ -public interface TreeCopier { - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeFactory.java.tmpl b/sources/scalac/ast/TreeFactory.java.tmpl deleted file mode 100644 index 3b46970e77..0000000000 --- a/sources/scalac/ast/TreeFactory.java.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -{#Imports#} - -/** This interface describes a tree factory */ -public interface TreeFactory { - - //######################################################################## - // Public Methods - - {#TreeMethods#} - - //######################################################################## -} diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java deleted file mode 100644 index 49e97c24d7..0000000000 --- a/sources/scalac/ast/TreeGen.java +++ /dev/null @@ -1,1361 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast; - -import scalac.Global; -import scalac.ast.Tree.*; -import scalac.atree.AConstant; -import scalac.symtab.*; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.TypeNames; - -/** - * This class provides method to build attributed trees. - * - * @author Martin Odersky, Christine Roeckl - * @version 1.0 - */ -public class TreeGen implements Kinds, Modifiers, TypeTags { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The global definitions */ - private final Definitions definitions; - - /** The tree factory */ - private final TreeFactory make; - - /** Initializes this instance. */ - public TreeGen(Global global) { - this(global, global.make); - } - - /** Initializes this instance. */ - public TreeGen(Global global, TreeFactory make) { - this.global = global; - this.definitions = global.definitions; - this.make = make; - } - - //######################################################################## - // Public Methods - Building types - - /** Builds type references corresponding to given symbols. */ - public Tree[] mkTypeRefs(int pos, Symbol[] syms) { - if (syms.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[syms.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkTypeRef(pos, syms[i]); - return trees; - } - - /** Builds a type reference corresponding to given symbol. */ - public Tree mkTypeRef(int pos, Symbol sym) { - assert sym.kind == TYPE: Debug.show(sym); - sym.flags |= ACCESSED; - return mkType(pos, sym.nextType()); - } - - /** Builds trees corresponding to given types. */ - public Tree[] mkTypes(int pos, Type[] types) { - if (types.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[types.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkType(pos, types[i]); - return trees; - } - - /** Builds a tree corresponding to given type. */ - public Tree mkType(int pos, Type type) { - return TypeTerm(pos, type); - } - - /** Builds a TypeTerm node corresponding to given type. */ - public TypeTerm TypeTerm(int pos, Type type) { - TypeTerm tree = make.TypeTerm(pos); - tree.setType(type); - return tree; - } - - //######################################################################## - // Public Methods - Building constants - - /** Builds a unit literal. */ - public Tree mkUnitLit(int pos) { - return Literal(pos, AConstant.UNIT); - } - - /** Builds a boolean literal. */ - public Tree mkBooleanLit(int pos, boolean value) { - return Literal(pos, AConstant.BOOLEAN(value)); - } - - /** Builds a byte literal. */ - public Tree mkByteLit(int pos, byte value) { - return Literal(pos, AConstant.BYTE(value)); - } - - /** Builds a short literal. */ - public Tree mkShortLit(int pos, short value) { - return Literal(pos, AConstant.SHORT(value)); - } - - /** Builds a character literal. */ - public Tree mkCharLit(int pos, char value) { - return Literal(pos, AConstant.CHAR(value)); - } - - /** Builds an integer literal */ - public Tree mkIntLit(int pos, int value) { - return Literal(pos, AConstant.INT(value)); - } - - /** Builds a long literal. */ - public Tree mkLongLit(int pos, long value) { - return Literal(pos, AConstant.LONG(value)); - } - - /** Builds a float literal. */ - public Tree mkFloatLit(int pos, float value) { - return Literal(pos, AConstant.FLOAT(value)); - } - - /** Builds a double literal. */ - public Tree mkDoubleLit(int pos, double value) { - return Literal(pos, AConstant.DOUBLE(value)); - } - - /** Builds a string literal. */ - public Tree mkStringLit(int pos, String value) { - assert value != null; - return Literal(pos, AConstant.STRING(value)); - } - - /** Builds a symbol name literal. */ - public Tree mkSymbolNameLit(int pos, Symbol value) { - return Literal(pos, AConstant.SYMBOL_NAME(value)); - } - - /** Builds a null literal. */ - public Tree mkNullLit(int pos) { - return Literal(pos, AConstant.NULL); - } - - /** Builds a zero literal. */ - public Tree mkZeroLit(int pos) { - return Literal(pos, AConstant.ZERO); - } - - /** Builds a default zero value according to given type tag. */ - public Tree mkDefaultValue(int pos, int tag) { - switch (tag) { - case UNIT : return mkUnitLit(pos); - case BOOLEAN: return mkBooleanLit(pos, false); - case BYTE : return mkByteLit(pos, (byte)0); - case SHORT : return mkShortLit(pos, (short)0); - case CHAR : return mkCharLit(pos, '\0'); - case INT : return mkIntLit(pos, 0); - case LONG : return mkLongLit(pos, 0l); - case FLOAT : return mkFloatLit(pos, 0f); - case DOUBLE : return mkDoubleLit(pos, 0d); - default : throw Debug.abort("unknown type tag: " + tag); - } - } - - /** Builds a default zero value according to given type. */ - public Tree mkDefaultValue(int pos, Type type) { - switch (type.unbox()) { - case UnboxedType(int tag): return mkDefaultValue(pos, tag); - } - if (definitions.ALLREF_TYPE().isSubType(type)) return mkNullLit(pos); - return mkZeroLit(pos); - } - - /** Builds a Literal node of given value. */ - public Literal Literal(int pos, AConstant value) { - Literal tree = make.Literal(pos, value); - global.nextPhase(); - tree.setType(definitions.atyper.type(value)); - global.prevPhase(); - return tree; - } - - //######################################################################## - // Public Methods - Building references - - /** - * Builds a reference to primary constructor of given class with - * given qualifier. - */ - public Tree mkPrimaryConstructorRef(int pos, Tree qualifier, Symbol clasz){ - return mkRef(pos, qualifier, primaryConstructorOf(clasz)); - } - public Tree mkPrimaryConstructorRef(Tree qualifier, Symbol clasz) { - return mkPrimaryConstructorRef(qualifier.pos, qualifier, clasz); - } - - /** - * Builds a reference to primary constructor of given class with - * given stable prefix. - */ - public Tree mkPrimaryConstructorRef(int pos, Type stable, Symbol clasz) { - return mkRef(pos, stable, primaryConstructorOf(clasz)); - } - - /** - * Builds a local reference to primary constructor of given class. - */ - public Tree mkPrimaryConstructorLocalRef(int pos, Symbol clasz) { - return mkLocalRef(pos, primaryConstructorOf(clasz)); - } - - /** - * Builds a global reference to primary constructor of given - * class. - */ - public Tree mkPrimaryConstructorGlobalRef(int pos, Symbol clasz) { - return mkGlobalRef(pos, primaryConstructorOf(clasz)); - } - - /** Builds local references to given symbols. */ - public Tree[] mkLocalRefs(int pos, Symbol[] symbols) { - if (symbols.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[symbols.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkLocalRef(pos, symbols[i]); - return trees; - } - - /** Builds global references to given symbols. */ - public Tree[] mkGlobalRefs(int pos, Symbol[] symbols) { - if (symbols.length == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[symbols.length]; - for (int i = 0; i < trees.length; i++) - trees[i] = mkGlobalRef(pos, symbols[i]); - return trees; - } - - /** Builds a reference to given symbol with given qualifier. */ - public Tree mkRef(int pos, Tree qualifier, Symbol symbol) { - return Select(pos, qualifier, symbol); - } - public Tree mkRef(Tree qualifier, Symbol symbol) { - return mkRef(qualifier.pos, qualifier, symbol); - } - - /** - * Builds a reference to given symbol with given stable prefix. - */ - public Tree mkRef(int pos, Type stable, Symbol symbol) { - Tree qualifier = mkQualifier(pos, stable); - if (qualifier == Tree.Empty) return Ident(pos, symbol); - return mkRef(pos, qualifier, symbol); - } - - /** Builds a local reference to given symbol. */ - public Tree mkLocalRef(int pos, Symbol symbol) { - assert symbol.isTerm(): Debug.show(symbol); - Type prefix = symbol.hasStaticAttribute() - ? Type.NoPrefix - : symbol.owner().thisType(); - return mkRef(pos, prefix, symbol); - } - - /** Builds a global reference to given symbol. */ - public Tree mkGlobalRef(int pos, Symbol symbol) { - assert symbol.isTerm(): Debug.show(symbol); - global.nextPhase(); - Type prefix = symbol.owner().staticPrefix(); - global.prevPhase(); - return mkRef(pos, prefix, symbol); - } - - /** Builds a qualifier corresponding to given stable prefix. */ - public Tree mkQualifier(int pos, Type stable) { - switch (stable) { - case NoPrefix: - return Tree.Empty; - case ThisType(Symbol clasz): - return This(pos, clasz); - case SingleType(Type prefix, Symbol member): - Tree qualifier = mkRef(pos, prefix, member); - switch (qualifier.type()) { - case MethodType(Symbol[] params, _): - assert params.length == 0: qualifier.type(); - return Apply(pos, qualifier); - default: - return qualifier; - } - default: - throw Debug.abort("illegal case", stable); - } - } - - /** Builds a This node corresponding to given class. */ - public This This(int pos, Symbol clazz) { - assert clazz.isClassType(): Debug.show(clazz); - This tree = make.This(pos, clazz); - global.nextPhase(); - tree.setType(clazz.thisType()); - global.prevPhase(); - return tree; - } - - /** Builds a Super node corresponding to given class. */ - public Super Super(int pos, Symbol clazz) { - assert clazz.isClass(): Debug.show(clazz); - Super tree = make.Super(pos, clazz, TypeNames.EMPTY); - global.nextPhase(); - tree.setType(clazz.thisType()); - global.prevPhase(); - return tree; - } - - /** Builds an Ident node corresponding to given symbol. */ - public Ident Ident(int pos, Symbol sym) { - assert sym.isTerm(): Debug.show(sym); - sym.flags |= ACCESSED; - Ident tree = make.Ident(pos, sym); - global.nextPhase(); - Type type; - if (sym.isInitializer()) { - type = sym.type(); - Symbol[] tparams = sym.owner().typeParams(); - if (tparams.length != 0) type = Type.PolyType(tparams, type); - } else { - type = sym.owner().thisType().memberStabilizedType(sym); - } - tree.setType(type); - global.prevPhase(); - return tree; - } - - /** - * Builds a Select node corresponding to given symbol selected - * from given qualifier. - */ - public Select Select(int pos, Tree qualifier, Symbol sym) { - assert sym.isTerm(): Debug.show(sym); - sym.flags |= ACCESSED | SELECTOR; - Select tree = make.Select(pos, sym, qualifier); - global.nextPhase(); - tree.setType(qualifier.type.memberStabilizedType(sym)); - global.prevPhase(); - return tree; - } - public Select Select(Tree qualifier, Symbol sym) { - return Select(qualifier.pos, qualifier, sym); - } - - //######################################################################## - // Public Methods - Building applications - - /** - * Builds an application with given function, type arguments and - * value arguments. - */ - public Tree mkApplyTV(int pos, Tree fn, Type[] targs, Tree[] vargs) { - if (targs.length != 0) fn = TypeApply(pos, fn, mkTypes(pos, targs)); - if (vargs.length == 0 && fn.getType().isObjectType()) return fn; - else return Apply(pos, fn, vargs); - } - public Tree mkApplyTV(Tree fn, Type[] targs, Tree[] vargs) { - return mkApplyTV(fn.pos, fn, targs, vargs); - } - public Tree mkApplyTV(int pos, Tree fn, Tree[] targs, Tree[] vargs) { - if (targs.length != 0) fn = TypeApply(pos, fn, targs); - if (vargs.length == 0 && fn.getType().isObjectType()) return fn; - else return Apply(pos, fn, vargs); - } - public Tree mkApplyTV(Tree fn, Tree[] targs, Tree[] vargs) { - return mkApplyTV(fn.pos, fn, targs, vargs); - } - - /** - * Builds an application with given function and type arguments - * and with no value arguments. - */ - public Tree mkApplyT_(int pos, Tree fn, Type[] targs) { - return mkApplyTV(pos, fn, targs, Tree.EMPTY_ARRAY); - } - public Tree mkApplyT_(Tree fn, Type[] targs) { - return mkApplyT_(fn.pos, fn, targs); - } - public Tree mkApplyT_(int pos, Tree fn, Tree[] targs) { - return mkApplyTV(pos, fn, targs, Tree.EMPTY_ARRAY); - } - public Tree mkApplyT_(Tree fn, Tree[] targs) { - return mkApplyT_(fn.pos, fn, targs); - } - - /** - * Builds an application with given function, no type arguments - * and given value arguments. - */ - public Tree mkApply_V(int pos, Tree fn, Tree[] vargs) { - return mkApplyTV(pos, fn, Tree.EMPTY_ARRAY, vargs); - } - public Tree mkApply_V(Tree fn, Tree[] vargs) { - return mkApply_V(fn.pos, fn, vargs); - } - - /** - * Builds an application with given function and no type arguments - * and no value arguments. - */ - public Tree mkApply__(int pos, Tree fn) { - return mkApplyTV(pos, fn, Tree.EMPTY_ARRAY, Tree.EMPTY_ARRAY); - } - public Tree mkApply__(Tree fn) { - return mkApply__(fn.pos, fn); - } - - /** Builds a TypeApply node with given function and arguments. */ - public TypeApply TypeApply(int pos, Tree fn, Type[] targs) { - return TypeApply(pos, fn, mkTypes(pos, targs)); - } - public TypeApply TypeApply(Tree fn, Type[] targs) { - return TypeApply(fn.pos, fn, targs); - } - public TypeApply TypeApply(int pos, Tree fn, Tree[] targs) { - Type fnType = fn.type(); - switch (fnType) { - case Type.OverloadedType(_, _): - // TreeGen only builds trees, names must already be resolved - throw Debug.abort("unresolved name", fn + " - " + fnType); - case Type.PolyType(Symbol[] tparams, Type restpe): - global.nextPhase(); - restpe = restpe.subst(tparams, Tree.typeOf(targs)); - global.prevPhase(); - return (TypeApply)make.TypeApply(pos, fn, targs).setType(restpe); - default: - throw Debug.abort("illegal case", fn + " - " + fnType + " - " + fnType.getClass()); - } - } - public TypeApply TypeApply(Tree fn, Tree[] targs) { - return TypeApply(fn.pos, fn, targs); - } - - /** Builds an Apply node with given function and arguments. */ - public Apply Apply(int pos, Tree fn, Tree[] vargs) { - Type fnType = fn.type(); - switch (fnType) { - case Type.OverloadedType(_, _): - // TreeGen only builds trees, names must already be resolved - throw Debug.abort("unresolved name", fn + " - " + fnType); - case Type.MethodType(Symbol[] vparams, Type restpe): - return (Apply)make.Apply(pos, fn, vargs).setType(restpe); - default: - throw Debug.abort("illegal case", fn + " - " + fnType + " - " + fnType.getClass()); - } - } - public Apply Apply(Tree fn, Tree[] vargs) { - return Apply(fn.pos, fn, vargs); - } - - /** Builds an Apply node with given function and no arguments. */ - public Apply Apply(int pos, Tree fn) { - return Apply(pos, fn, Tree.EMPTY_ARRAY); - } - public Apply Apply(Tree fn) { - return Apply(fn.pos, fn); - } - - //######################################################################## - // Public Methods - Building new instances - - /** - * Builds a new instance creation with given qualifier, - * initializer, type arguments and value arguments. - */ - public Tree mkNewTV(int pos, Tree qual, Symbol init, Type[] targs, - Tree[] vargs) - { - return mkNewTV(pos, qual, init, mkTypes(pos, targs), vargs); - } - public Tree mkNewTV(Tree qual, Symbol init, Type[] targs, Tree[] vargs) { - return mkNewTV(qual.pos, qual, init, targs, vargs); - } - public Tree mkNewTV(int pos, Tree qual, Symbol init, Tree[] targs, - Tree[] vargs) - { - assert init.isInitializer(): Debug.show(init); - Tree instance = Create(pos, qual, init.owner(), targs); - return New(pos, Apply(pos, Select(pos, instance, init), vargs)); - } - public Tree mkNewTV(Tree qual, Symbol init, Tree[] targs, Tree[] vargs) { - return mkNewTV(qual.pos, qual, init, targs, vargs); - } - - /** - * Builds a new instance creation with given qualifier, - * initializer and type arguments and no value arguments. - */ - public Tree mkNewT_(int pos, Tree qual, Symbol init, Type[] targs) { - return mkNewTV(pos, qual, init, targs, Tree.EMPTY_ARRAY); - } - public Tree mkNewT_(Tree qual, Symbol init, Type[] targs) { - return mkNewT_(qual.pos, qual, init, targs); - } - public Tree mkNewT_(int pos, Tree qual, Symbol init, Tree[] targs) { - return mkNewTV(pos, qual, init, targs, Tree.EMPTY_ARRAY); - } - public Tree mkNewT_(Tree qual, Symbol init, Tree[] targs) { - return mkNewT_(qual.pos, qual, init, targs); - } - - /** - * Builds a new instance creation with given qualifier, - * initializer and value arguments and no type arguments. - */ - public Tree mkNew_V(int pos, Tree qual, Symbol init, Tree[] vargs) { - return mkNewTV(pos, qual, init, Tree.EMPTY_ARRAY, vargs); - } - public Tree mkNew_V(Tree qual, Symbol init, Tree[] vargs) { - return mkNew_V(qual.pos, qual, init, vargs); - } - - /** - * Builds a new instance creation with given qualifier, and - * initializer and no type arguments and no value arguments. - */ - public Tree mkNew__(int pos, Tree qual, Symbol init) { - return mkNewTV(pos, qual, init, Tree.EMPTY_ARRAY, Tree.EMPTY_ARRAY); - } - public Tree mkNew__(Tree qual, Symbol init) { - return mkNew__(qual.pos, qual, init); - } - - /** Builds a New node corresponding to "new <init>". */ - public New New(int pos, Tree init) { - New tree = make.New(pos, init); - tree.setType(init.type()); - // after AddConstructor use type of Create node - switch (init) { - case Apply(Select(Tree qual, _), _): - if (qual instanceof Tree.Create) tree.setType(qual.type()); - } - return tree; - } - public New New(Tree init) { - return New(init.pos, init); - } - - /** - * Builds a Create node with given qualifier, clasz and type - * arguments. - */ - public Create Create(int pos, Tree qual, Symbol clasz, Type[] targs) { - return Create(pos, qual, clasz, mkTypes(pos, targs)); - } - public Create Create(Tree qual, Symbol clasz, Type[] targs) { - return Create(qual.pos, qual, clasz, targs); - } - public Create Create(int pos, Tree qual, Symbol clasz, Tree[] targs) { - assert clasz.isClass(): Debug.show(clasz); - Create tree = make.Create(pos, clasz, qual, targs); - global.nextPhase(); - assert targs.length == clasz.typeParams().length: tree; - Type prefix = qual == Tree.Empty ? Type.NoPrefix:qual.type(); - tree.setType(Type.typeRef(prefix, clasz, Tree.typeOf(targs))); - global.prevPhase(); - return tree; - } - public Create Create(Tree qual, Symbol clasz, Tree[] targs) { - return Create(qual.pos, qual, clasz, targs); - } - - /** - * Builds a Create node with given qualifier, clasz and no type - * arguments. - */ - public Create Create(int pos, Tree qual, Symbol clasz) { - return Create(pos, qual, clasz, Tree.EMPTY_ARRAY); - } - public Create Create(Tree qual, Symbol clasz) { - return Create(qual.pos, qual, clasz); - } - - /** Builds a Create node with given type. */ - public Create Create(int pos, Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol clasz, Type[] targs): - return Create(pos, mkQualifier(pos, prefix), clasz, targs); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## - // Public Methods - Building expressions - Simple nodes - - /** Flattens the given tree array by inlining Block nodes. */ - public Tree[] flatten_(Tree[] trees) { - boolean copy = false; - int length = 0; - for (int i = 0; i < trees.length; i++) { - switch (trees[i]) { - case Empty: - copy = true; - length -= 1; - continue; - case Block(Tree[] stats, Tree value): - copy = true; - length += stats.length + 1; - continue; - } - length += 1; - } - if (!copy) return trees; - Tree[] clone = new Tree[length]; - for (int i = 0, o = 0; i < trees.length; i++) { - switch (trees[i]) { - case Empty: - continue; - case Block(Tree[] stats, Tree value): - for (int j = 0; j < stats.length; j++) clone[o++] = stats[j]; - clone[o++] = value; - continue; - } - clone[o++] = trees[i]; - } - return clone; - } - - /** Builds an import of all names of given qualifier. */ - public Import mkImportAll(int pos, Tree qualifier) { - return Import(pos, qualifier, new Name[]{Names.IMPORT_WILDCARD}); - } - public Import mkImportAll(Tree qualifier) { - return mkImportAll(qualifier.pos, qualifier); - } - public Import mkImportAll(int pos, Symbol qualifier) { - return mkImportAll(pos, mkGlobalRef(pos, qualifier)); - } - - /** Builds an instance test with given value and type. */ - public Tree mkIsInstanceOf(int pos, Tree value, Type type, boolean erased) { - Symbol sym = erased ? definitions.ANY_IS_ERASED : definitions.ANY_IS; - return mkApplyT_(pos, Select(value, sym), new Type[]{type}); - } - public Tree mkIsInstanceOf(int pos, Tree value, Type type) { - boolean afterTAV = - global.currentPhase.id >= global.PHASE.TYPESASVALUES.id(); - return mkIsInstanceOf(pos, value, type, afterTAV); - } - public Tree mkIsInstanceOf(Tree value, Type type) { - return mkIsInstanceOf(value.pos, value, type); - } - - /** Builds a cast with given value and type. */ - public Tree mkAsInstanceOf(int pos, Tree value, Type type, boolean erased) { - Symbol sym = erased ? definitions.ANY_AS_ERASED : definitions.ANY_AS; - return mkApplyT_(pos, Select(value, sym), new Type[]{type}); - } - public Tree mkAsInstanceOf(int pos, Tree value, Type type) { - boolean afterTAV = - global.currentPhase.id >= global.PHASE.TYPESASVALUES.id(); - return mkAsInstanceOf(pos, value, type, afterTAV); - } - public Tree mkAsInstanceOf(Tree value, Type type) { - return mkAsInstanceOf(value.pos, value, type); - } - - /** Builds an expression of type Unit with given statements. */ - public Tree mkUnitBlock(int pos, Tree[] stats) { - return mkBlock(pos, stats, mkUnitLit(pos)); - } - - /** Builds an expression of type Unit with given statement. */ - public Tree mkUnitBlock(int pos, Tree stat) { - return mkUnitBlock(pos, new Tree[]{stat}); - } - public Tree mkUnitBlock(Tree stat) { - return mkUnitBlock(stat.pos, stat); - } - - /** Builds an expression with given statements and value. */ - public Tree mkBlock(int pos, Tree[] stats, Tree value) { - if (stats.length == 0) return value; - return Block(pos, stats, value); // !!! add flatten? - } - public Tree mkBlock(Tree[] stats, Tree value) { - return mkBlock((stats.length!=0 ? stats[0] : value).pos, stats, value); - } - - /** Builds an expression with given statement and value. */ - public Tree mkBlock(int pos, Tree stat, Tree value) { - switch (stat) { - case Empty: - return value; - case Block(Tree[] block_stats, Tree block_value): - Tree[] stats = Tree.cloneArray(block_stats, 1); - stats[block_stats.length] = block_value; - return Block(stat.pos, stats, value); - default: - return Block(pos, new Tree[]{stat}, value); - } - } - public Tree mkBlock(Tree stat, Tree value) { - return mkBlock(stat.pos, stat, value); - } - - /** Builds an Import node with given qualifier and names. */ - public Import Import(int pos, Tree qualifier, Name[] names) { - Import tree = make.Import(pos, qualifier.symbol(), qualifier, names); - tree.setType(Type.NoType); - return tree; - } - public Import Import(Tree qualifier, Name[] names) { - return Import(qualifier.pos, qualifier, names); - } - public Import Import(int pos, Symbol qualifier, Name[] names) { - return Import(pos, mkGlobalRef(pos, qualifier), names); - } - - /** Builds a Template node with given symbol, parents and body. */ - public Template Template(int pos, Symbol local, Tree[]parents, Tree[]body){ - Template tree = make.Template(pos, local, parents, body); - tree.setType(Type.NoType); - return tree; - } - - /** Builds a Block node with given statements and value. */ - public Block Block(int pos, Tree[] stats, Tree value) { - inline: - switch (value) { - case Block(Tree[] value_stats, Tree value_value): - int count = 0; - for (int i = 0; i < value_stats.length; i++) { - if (value_stats[i].definesSymbol()) break inline; - if (value_stats[i] != Tree.Empty) count++; - } - Tree[] array = Tree.cloneArray(stats, count); - for (int i = 0, j = stats.length; i < value_stats.length; i++) { - if (value_stats[i] != Tree.Empty) array[j++] = value_stats[i]; - } - stats = array; - value = value_value; - } - Block tree = make.Block(pos, stats, value); - tree.setType(value.type()); - return tree; - } - public Block Block(Tree[] stats, Tree value) { - return Block((stats.length != 0 ? stats[0] : value).pos, stats, value); - } - - /** Builds an Assign node corresponding to "<lhs> = <rhs>". */ - public Assign Assign(int pos, Tree lhs, Tree rhs) { - Assign tree = make.Assign(pos, lhs, rhs); - global.nextPhase(); - tree.setType(definitions.void_TYPE()); - global.prevPhase(); - return tree; - } - public Assign Assign(Tree lhs, Tree rhs) { - return Assign(lhs.pos, lhs, rhs); - } - - /** Builds an If node with given components and type. */ - public If If(int pos, Tree cond, Tree thenpart, Tree elsepart, Type type) { - //if (!thenpart.type.isSubType(type)) System.out.println(type + "!>:(" + thenpart.type + "," + elsepart.type + ")");//debug - assert assertTreeSubTypeOf(thenpart, type); - assert assertTreeSubTypeOf(elsepart, type); - If tree = make.If(pos, cond, thenpart, elsepart); - tree.setType(type); - return tree; - } - public If If(Tree cond, Tree thenpart, Tree elsepart, Type type) { - return If(cond.pos, cond, thenpart, elsepart, type); - } - - /** Builds an If node with given condition and branches. */ - public If If(int pos, Tree cond, Tree thenpart, Tree elsepart) { - global.nextPhase(); - Type type = thenpart.getType().isSameAs(elsepart.getType()) - ? thenpart.type - : Type.lub(new Type[] {thenpart.getType(), elsepart.getType()}); - global.prevPhase(); - return If(pos, cond, thenpart, elsepart, type); - } - public If If(Tree cond, Tree thenpart, Tree elsepart) { - return If(cond.pos, cond, thenpart, elsepart); - } - - /** Builds a Switch node with given components and type. - * @param tags a <b>sorted</b> array of tags - */ - public Switch Switch(int pos, Tree test, int[] tags, Tree[] bodies, - Tree otherwise, Type type) - { - for (int i = 0; i < bodies.length; i++) { - assert assertTreeSubTypeOf(bodies[i], type); - assert (i==0) || ( tags[i-1] < tags[i] ) : "expecting sorted tags"; - } - assert assertTreeSubTypeOf(otherwise, type); - Switch tree = make.Switch(pos, test, tags, bodies, otherwise); - tree.setType(type); - return tree; - } - public Switch Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise, - Type type) - { - return Switch(test.pos, test, tags, bodies, otherwise, type); - } - - /** Builds a Switch node with given components. */ - public Switch Switch(int pos, Tree test, int[] tags, Tree[] bodies, - Tree otherwise) - { - Type[] types = new Type[bodies.length + 1]; - for (int i = 0; i < bodies.length; i++) types[i] = bodies[i].getType(); - types[bodies.length] = otherwise.getType(); - global.nextPhase(); - Type type = Type.lub(types); - global.prevPhase(); - return Switch(pos, test, tags, bodies, otherwise, type); - } - public Switch Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise){ - return Switch(test.pos, test, tags, bodies, otherwise); - } - - /** Builds a Return node of given method with given value. */ - public Return Return(int pos, Symbol method, Tree value) { - Return tree = make.Return(pos, method, value); - tree.setType(definitions.ALL_TYPE()); - return tree; - } - public Return Return(Symbol method, Tree value) { - return Return(value.pos, method, value); - } - - /** Builds a Typed nodes with given value and type. */ - public Typed Typed(int pos, Tree value, Tree type) { - Typed tree = make.Typed(pos, value, type); - tree.setType(type.type()); - return tree; - } - public Typed Typed(Tree value, Tree type) { - return Typed(value.pos, value, type); - } - public Typed Typed(int pos, Tree value, Type type) { - return Typed(pos, value, mkType(pos, type)); - } - public Typed Typed(Tree value, Type type) { - return Typed(value.pos, value, type); - } - - //######################################################################## - // Public Methods - Building expressions - Lists - - /** Builds an empty list. */ - public Tree mkNil(int pos) { - return mkGlobalRef(pos, definitions.NIL()); - } - - /** Builds a list with given element type, head and tail. */ - public Tree mkNewCons(int pos, Type element, Tree head, Tree tail) { - // !!! these checks can be removed once they are done in Apply - global.nextPhase(); - assert head.type().isSubType(element): - element + " -- " + head + " : " + head.type; - assert tail.type().isSubType(definitions.LIST_TYPE(element)): - element + " -- " + tail + " : " + tail.type; - global.prevPhase(); - return New( - mkApplyTV( - mkPrimaryConstructorGlobalRef(pos, definitions.CONS_CLASS()), - new Type[]{element}, - new Tree[]{head, tail})); - } - public Tree mkNewCons(Type element, Tree head, Tree tail) { - return mkNewCons(head.pos, element, head, tail); - } - - /** Builds a list with given element type and values. */ - public Tree mkNewList(int pos, Type element, Tree[] values) { - Tree list = mkNil(pos); - for (int i = values.length - 1; 0 <= i; i--) - list = mkNewCons(pos, element, values[i], list); - return list; - } - - //######################################################################## - // Public Methods - Building expressions - Arrays - - /** Builds a new array tree with given element type and length. */ - public Tree mkNewArray(int pos, Type element, Tree length) { - return New( - mkApplyTV( - mkPrimaryConstructorGlobalRef(pos, definitions.ARRAY_CLASS), - new Type[]{element}, - new Tree[]{length})); - } - public Tree mkNewArray(Type element, Tree length) { - return mkNewArray(length.pos, element, length); - } - public Tree mkNewArray(int pos, Type element, int length) { - return mkNewArray(pos, element, mkIntLit(pos, length)); - } - - /** - * Builds a new array tree with given element type and values. The - * owner must be the owner of the created code. It is needed to - * create a local variable. - */ - public Tree mkNewArray(int pos, Type element, Tree[] values, Symbol owner){ - if (values.length == 0) return mkNewArray(pos, element, 0); - Tree[] trees = new Tree[1 + values.length]; - Symbol array = newLocal( - owner, pos, FINAL, "array", definitions.array_TYPE(element)); - trees[0] = ValDef(array, mkNewArray(pos, element, values.length)); - for (int i = 0; i < values.length; i++) - trees[1 + i] = mkArraySet(Ident(pos, array), i, values[i]); - return Block(pos, trees, Ident(pos, array)); - } - - /** Builds an array length operation. */ - public Tree mkArrayLength(int pos, Tree array) { - Tree function = Select(pos, array, definitions.ARRAY_LENGTH()); - return Apply(pos, function); - } - public Tree mkArrayLength(Tree array) { - return mkArrayLength(array.pos, array); - } - - /** Builds an array get operation. */ - public Tree mkArrayGet(int pos, Tree array, Tree index) { - Tree function = Select(pos, array, definitions.ARRAY_GET()); - return Apply(pos, function, new Tree[] {index}); - } - public Tree mkArrayGet(Tree array, Tree index) { - return mkArrayGet(array.pos, array, index); - } - public Tree mkArrayGet(int pos, Tree array, int index) { - return mkArrayGet(pos, array, mkIntLit(pos, index)); - } - public Tree mkArrayGet(Tree array, int index) { - return mkArrayGet(array.pos, array, index); - } - - /** Builds an array set operation. */ - public Tree mkArraySet(int pos, Tree array, Tree index, Tree value) { - Tree function = Select(pos, array, definitions.ARRAY_SET()); - return Apply(pos, function, new Tree[] {index, value}); - } - public Tree mkArraySet(Tree array, Tree index, Tree value) { - return mkArraySet(array.pos, array, index, value); - } - public Tree mkArraySet(int pos, Tree array, int index, Tree value) { - return mkArraySet(pos, array, mkIntLit(pos, index), value); - } - public Tree mkArraySet(Tree array, int index, Tree value) { - return mkArraySet(array.pos, array, index, value); - } - - //######################################################################## - // Public Methods - Building definitions - - /** Builds the type parameter section of given symbol. */ - public AbsTypeDef[] mkTypeParamsOf(Symbol sym) { - Symbol[] tparams = sym.nextTypeParams(); - AbsTypeDef[] trees = new AbsTypeDef[tparams.length]; - for (int i = 0; i < tparams.length; i++) - trees[i] = mkTypeParam(tparams[i]); - return trees; - } - - /** Builds the value parameter section of given symbol. */ - public ValDef[][] mkParamsOf(Symbol sym) { - global.nextPhase(); - if (sym.isClass()) sym = sym.primaryConstructor(); - Type type = sym.type(); - global.prevPhase(); - ValDef[][] treess = Tree.ValDef_EMPTY_ARRAY_ARRAY; - while (true) { - switch (type) { - case PolyType(_, Type result): - type = result; - continue; - case MethodType(Symbol[] vparams, Type result): - ValDef[] trees = new ValDef[vparams.length]; - for (int i = 0; i < vparams.length; i++) - trees[i] = mkParam(vparams[i]); - ValDef[][] array = new ValDef[treess.length + 1][]; - for (int i = 0; i < treess.length; i++) array[i] = treess[i]; - array[treess.length] = trees; - treess = array; - type = result; - continue; - default: - return treess; - } - } - } - - /** Builds the type parameter corresponding to given symbol. */ - public AbsTypeDef mkTypeParam(Symbol sym) { - return AbsTypeDef(sym); - } - - /** Builds the value parameter corresponding to given symbol. */ - public ValDef mkParam(Symbol sym) { - return ValDef(sym, Tree.Empty); - } - - /** Builds a PackageDef with given package and template. */ - public PackageDef PackageDef(Tree peckage, Template template) { - PackageDef tree = make.PackageDef(peckage.pos, peckage, template); - tree.setType(Type.NoType); - return tree; - } - public PackageDef PackageDef(Symbol peckage, Template template) { - return PackageDef(mkGlobalRef(peckage.pos, peckage), template); - } - - /** Builds a PackageDef with given package and body. */ - public PackageDef PackageDef(Tree peckage, Tree[] body) { - return PackageDef( - peckage, - Template(peckage.pos, Symbol.NONE, Tree.EMPTY_ARRAY, body)); - } - public PackageDef PackageDef(Symbol peckage, Tree[] body) { - return PackageDef(mkGlobalRef(peckage.pos, peckage), body); - } - - /** Builds a ClassDef node for given class with given template. */ - public ClassDef ClassDef(Symbol clazz, Template template) { - Tree type = Tree.Empty; - if (clazz.thisSym() != clazz) { - global.nextPhase(); - type = mkType(clazz.pos, clazz.typeOfThis()); - global.prevPhase(); - } - ClassDef tree = make.ClassDef( - clazz.pos, - clazz, - mkTypeParamsOf(clazz), - mkParamsOf(clazz), - type, - template); - tree.setType(Type.NoType); - return tree; - } - - /** - * Builds a ClassDef node for given class with given parent - * constructors, local symbol and body. - */ - public ClassDef ClassDef(Symbol clazz, Tree[] constrs, Symbol local, - Tree[] body) - { - return ClassDef(clazz, Template(clazz.pos, local, constrs, body)); - } - - /** Builds a ClassDef node for given class with given body. */ - public Tree ClassDef(Symbol clazz, Tree[] body) { - for (int i = 0; i < body.length; i++) { - assert body[i] == Tree.Empty - || body[i].definesSymbol() && body[i].symbol().owner() ==clazz: - "\nclass : " + Debug.show(clazz) + - "\nmember: " + Debug.show(body[i].symbol()) + - "\nmember: " + body[i]; - } - Global.instance.nextPhase(); - Type[] parents = clazz.parents(); - Global.instance.prevPhase(); - Tree[] constrs = new Tree[parents.length]; - for (int i = 0; i < constrs.length; i++) { - switch (parents[i]) { - case TypeRef(Type prefix, Symbol parent, Type[] targs): - constrs[i] = mkApplyT_( - mkPrimaryConstructorRef(clazz.pos, prefix, parent), - targs); - continue; - default: - throw Debug.abort("invalid type", parents[i]); - } - } - return ClassDef(clazz, constrs, Symbol.NONE, body); - } - - /** Builds a ValDef node for given symbol and with given rhs. */ - public ValDef ValDef(Symbol sym, Tree rhs) { - ValDef tree = make.ValDef( - sym.pos, - sym, - TypeTerm(sym.pos, sym.nextType()), - rhs); - tree.setType(Type.NoType); - return tree; - } - - /** Builds a DefDef node for given symbol with given body. */ - public DefDef DefDef(Symbol sym, Tree body) { - DefDef tree = make.DefDef( - sym.pos, - sym, - mkTypeParamsOf(sym), - mkParamsOf(sym), - TypeTerm(sym.pos, sym.nextType().resultType()), - body); - tree.setType(Type.NoType); - return tree; - } - - /** Builds an AbsTypeDef node for given symbol. */ - public AbsTypeDef AbsTypeDef(Symbol sym) { - AbsTypeDef tree = make.AbsTypeDef( - sym.pos, - sym, - TypeTerm(sym.pos, sym.isViewBounded() ? sym.vuBound() : sym.nextInfo()), - TypeTerm(sym.pos, sym.loBound())); - tree.setType(Type.NoType); - return tree; - } - - /** Builds an AliasTypeDef node for given symbol. */ - public AliasTypeDef AliasTypeDef(Symbol sym) { - AliasTypeDef tree = make.AliasTypeDef( - sym.pos, - sym, - mkTypeParamsOf(sym), - TypeTerm(sym.pos, sym.nextInfo())); - tree.setType(Type.NoType); - return tree; - } - - /** Builds an CaseDef node with given pattern, guard and body. */ - public CaseDef CaseDef(Tree pattern, Tree guard, Tree body) { - CaseDef tree = make.CaseDef(pattern.pos, pattern, guard, body); - tree.setType(body.getType()); - return tree; - } - - /** Builds an CaseDef node with given pattern and body. */ - public CaseDef CaseDef(Tree pattern, Tree body) { - return CaseDef(pattern, Tree.Empty, body); - } - - /** - * Builds a LabelDef node for given label with given parameters - * and body. - */ - public LabelDef LabelDef(Symbol label, Ident[] params, Tree body) { - LabelDef tree = make.LabelDef(label.pos, label, params, body); - tree.setType(label.nextType().resultType()); - return tree; - } - public LabelDef LabelDef(Symbol label, Symbol[] params, Tree body) { - Ident[] idents = new Ident[params.length]; - for (int i = 0; i < params.length; i++) - idents[i] = Ident(params[i].pos, params[i]); - return LabelDef(label, idents, body); - } - - //######################################################################## - // Private Methods - - /** Asserts type of given tree is a subtype of given type. */ - private boolean assertTreeSubTypeOf(Tree tree, Type expected) { - global.nextPhase(); - assert tree.getType().isSubType(expected): - "\ntree : " + tree + - "\ntype : " + tree.getType() + - "\nexpected: " + expected; - global.prevPhase(); - return true; - } - - /** Creates a new local variable and initializes it. */ - private Symbol newLocal(Symbol owner, int pos, int flags, String prefix, - Type type) - { - Name name = Names.LOCAL(owner); // !!! create unique names ? - flags |= Modifiers.SYNTHETIC; - Symbol local = owner.newVariable(pos, flags, name); - global.nextPhase(); - local.setType(type); - global.prevPhase(); - return local; - } - - /** Returns the primary constructor of given class. */ - private Symbol primaryConstructorOf(Symbol clasz) { - global.nextPhase(); - Symbol constr = clasz.primaryConstructor(); - global.prevPhase(); - return constr; - } - - //######################################################################## - //######################################################################## - //######################################################################## - - //######################################################################## - // !!! not yet reviewed - - /** Build the expansion of (() => expr) - */ - public Tree mkUnitFunction(Tree expr, Type type, Symbol owner, - boolean tagMethod) - { - return mkFunction - (expr.pos, Tree.ValDef_EMPTY_ARRAY, expr, type, owner, tagMethod); - } - - /** Build the expansion of ((vparams_1, ..., vparams_n) => body) - * with result type `restype', where `owner' is the previous owner - * of `body'. - * This is: - * { class $anon() extends scala.Object with - * scala.Function_N[T_1, ..., T_n, restype] { - * def apply(vparams_1, ..., vparams_n) = body1 - * } - * new $anon() - * } - * where - * vparams_i: T_i - * `body1' results from `body' by changing owner of all defined - * symbols in `body' from `owner' to the apply method. - */ - public Tree mkFunction(int pos, ValDef[] vparams, Tree body, Type restype, - Symbol owner, boolean tagMethod) - { - int n = vparams.length; - Symbol[] params = new Symbol[n]; - Type[] argtypes = new Type[n]; - for (int i = 0; i < n; i++) { - params[i] = vparams[i].symbol(); - argtypes[i] = params[i].type(); - } - Type[] parentTypes = { - definitions.ANYREF_TYPE(), - definitions.FUNCTION_TYPE(argtypes, restype) }; - Name name = Names.ANON_CLASS_NAME.toTypeName(); - ClassSymbol clazz = owner.newAnonymousClass(pos, name); - clazz.setInfo(Type.compoundType(parentTypes, new Scope(), clazz)); - clazz.allConstructors().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); - global.addAttribute(clazz, definitions.SCALA_SERIALIZABLE_CONSTR); - Symbol applyMeth = clazz.newMethod(pos, FINAL, Names.apply) - .setInfo(Type.MethodType(params, restype)); - clazz.info().members().enter(applyMeth); - - for (int i = 0; i < params.length; i++) { - params[i].setOwner(applyMeth); - } - changeOwner(body, owner, applyMeth); - Tree[] memberTrees = new Tree[tagMethod ? 2 : 1]; - memberTrees[0] = DefDef(applyMeth, body); - if (tagMethod) - memberTrees[1] = mkTagMethod(clazz); - Tree classDef = ClassDef(clazz, memberTrees); - Tree alloc = New(mkApply__(mkPrimaryConstructorLocalRef(pos, clazz))); - return mkBlock(classDef, Typed(alloc, parentTypes[1])); // !!! Typed - } - - public Tree mkTagMethod(ClassSymbol clazz) { - int flags = - clazz.isSubClass(definitions.SCALAOBJECT_CLASS) ? OVERRIDE : 0; - Symbol tagSym = clazz.newMethod(clazz.pos, flags, Names.tag) - .setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, definitions.int_TYPE())); - clazz.info().members().enter(tagSym); - int tagValue = clazz.isCaseClass() ? clazz.tag() : 0; - return DefDef(tagSym, mkIntLit(clazz.pos, tagValue)); - } - - public Tree mkPartialFunction(int pos, Tree applyVisitor, Tree isDefinedAtVisitor, - Type pattype, Type restype, Symbol owner) { - Name name = Names.ANON_CLASS_NAME.toTypeName(); - Symbol clazz = owner.newAnonymousClass(pos, name); - Type[] parentTypes = { - definitions.ANYREF_TYPE(), - definitions.PARTIALFUNCTION_TYPE(pattype, restype)}; - clazz.setInfo(Type.compoundType(parentTypes, new Scope(), clazz)); - clazz.allConstructors().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); - Tree[] memberTrees = { - makeVisitorMethod(pos, Names.apply, applyVisitor, - pattype, restype, clazz, owner), - makeVisitorMethod(pos, Names.isDefinedAt, isDefinedAtVisitor, - pattype, definitions.boolean_TYPE(), clazz, owner)}; - Tree classDef = ClassDef(clazz, memberTrees); - Tree alloc = New(mkApply__(mkPrimaryConstructorLocalRef(pos, clazz))); - return mkBlock(classDef, Typed(alloc, parentTypes[1])); // !!! Typed - } - //where - private Tree makeVisitorMethod(int pos, Name name, Tree visitor, - Type pattype, Type restype, - Symbol clazz, Symbol prevOwner) { - Symbol meth = clazz.newMethod(pos, FINAL, name); - Symbol param = meth.newVParam(pos, 0, Name.fromString("x$"), pattype); - meth.setInfo(Type.MethodType(new Symbol[]{param}, restype)); - clazz.info().members().enter(meth); - changeOwner(visitor, prevOwner, meth); - Tree body = - mkApplyTV( - Select(Ident(pos, param), definitions.ANY_MATCH), - new Tree[]{mkType(pos, pattype), mkType(pos, restype)}, - new Tree[]{visitor}); - return DefDef(meth, body); - } - - /** Change owner of all defined symbols from `prevOwner' to `newOwner' - */ - public void changeOwner(Tree tree, final Symbol prevOwner, final Symbol newOwner) { - Traverser lifter = new Traverser() { - public void traverse(Tree tree) { - if (tree.definesSymbol()) { - Symbol sym = tree.symbol(); - if (sym != null && sym.owner() == prevOwner) { - sym.setOwner(newOwner); - } - } - super.traverse(tree); - } - }; - lifter.traverse(tree); - } - - /** Build a postfix function application - */ - public Tree postfixApply(Tree obj, Tree fn, Symbol owner) { - if (TreeInfo.isPureExpr(obj) || TreeInfo.isPureExpr(fn)) { - return Apply(Select(fn, definitions.FUNCTION_APPLY(1)), new Tree[]{obj}); - } else { - Symbol tmp = newLocal(owner, obj.pos, FINAL, "postfix", obj.type); - Tree expr = postfixApply(Ident(obj.pos, tmp), fn, owner); - return mkBlock(ValDef(tmp, obj), expr); - } - } - - // for insert debug printing code - - public Tree Console_print(int pos, String str) { - return Console_print( pos, mkStringLit( pos, str )); - } - - public Tree Console_print(int pos, Tree arg) { - return Apply( Select( pos, - mkGlobalRef(pos, definitions.CONSOLE), - definitions.CONSOLE_PRINT()), - new Tree[] { - arg - }); - } - -} diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java deleted file mode 100644 index caeb7d72c0..0000000000 --- a/sources/scalac/ast/TreeInfo.java +++ /dev/null @@ -1,307 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.ast; - -import scalac.ApplicationError; -import scalac.util.Name; -import scalac.util.Names; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.Modifiers; - -import java.util.LinkedList; - -public class TreeInfo { - - public static boolean isTerm(Tree tree) { - return tree.isTerm(); - } - - public static boolean isType(Tree tree) { - return tree.isType(); - } - - public static boolean isOwnerDefinition(Tree tree) { - switch (tree) { - case PackageDef(_, _): - case ClassDef(_, _, _, _, _, _): - case ModuleDef(_, _, _, _): - case DefDef(_, _, _, _, _, _): - case Import(_, _): - return true; - default: - return false; - } - } - - public static boolean isDefinition(Tree tree) { - switch (tree) { - case PackageDef(_, _): - case ClassDef(_, _, _, _, _, _): - case ModuleDef(_, _, _, _): - case DefDef(_, _, _, _, _, _): - case ValDef(_, _, _, _): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - return true; - default: - return false; - } - } - - public static boolean isDeclaration(Tree tree) { - switch (tree) { - case DefDef(_, _, _, _, _, Tree rhs): - return rhs == Tree.Empty; - case ValDef(_, _, _, Tree rhs): - return rhs == Tree.Empty; - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - return true; - default: - return false; - } - } - - /** Is tree a pure definition? - */ - public static boolean isPureDef(Tree tree) { - switch (tree) { - case Tree.Empty: - case ClassDef(_, _, _, _, _, _): - case ModuleDef(_, _, _, _): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - return true; - case DefDef(_, Name name, _, _, _, _): - return name != Names.CONSTRUCTOR; - case ValDef(int mods, _, _, Tree rhs): - return (mods & Modifiers.MUTABLE) == 0 && isPureExpr(rhs); - case DocDef(_, Tree definition): - return isPureDef(definition); - default: - return false; - } - } - - /** Is tree a stable & pure expression? - */ - public static boolean isPureExpr(Tree tree) { - switch (tree) { - case Empty: - case This(_): - case Super(_, _): - return true; - case Ident(_): - assert tree.type != null : tree.toString(); - return tree.symbol().isStable(); - case Select(Tree qual, _): - return tree.symbol().isStable() && isPureExpr(qual); - case Apply(Tree fn, Tree[] args): - return isPureExpr(fn) && args.length == 0; - case TypeApply(Tree fn, Tree[] targs): - return isPureExpr(fn); - case Typed(Tree expr, _): - return isPureExpr(expr); - case Literal(_): - return true; - default: - return false; - } - } - - /** Is tree a pure constructor? - */ - public static boolean isPureConstr(Tree tree) { - switch (tree) { - case Ident(_): - case Select(_, _): - return tree.symbol() != null && tree.symbol().isPrimaryConstructor(); - case TypeApply(Tree constr, _): - return isPureConstr(constr); - case Apply(Tree fn, Tree[] args): - return args.length == 0 && isPureConstr(fn); - default: - return false; - } - } - - /** Is tree a self constructor call? - */ - public static boolean isSelfConstrCall(Tree tree) { - switch (tree) { - case Ident(Name name): - return name == Names.CONSTRUCTOR; - case TypeApply(Tree constr, _): - return isSelfConstrCall(constr); - case Apply(Tree constr, _): - return isSelfConstrCall(constr); - default: - return false; - } - } - - /** Is tree a variable pattern - */ - public static boolean isVarPattern(Tree pat) { - switch (pat) { - case Ident(Name name): - return name.isVariable(); - default: - return false; - } - } - - /** Is tree a this node which belongs to `enclClass'? - */ - public static boolean isSelf(Tree tree, Symbol enclClass) { - switch (tree) { - case This(_): - return tree.symbol() == enclClass; - default: - return false; - } - } - - /** The method symbol of an application node, or Symbol.NONE, if none exists. - */ - public static Symbol methSymbol(Tree tree) { - Tree meth = methPart(tree); - if (meth.hasSymbol()) return meth.symbol(); - else return Symbol.NONE; - } - - /** The method part of an application node - */ - public static Tree methPart(Tree tree) { - switch (tree) { - case Apply(Tree fn, _): - return methPart(fn); - case TypeApply(Tree fn, _): - return methPart(fn); - case AppliedType(Tree fn, _): - return methPart(fn); - default: - return tree; - } - } - - /** The symbol with name `name' imported from import clause `tree'. - */ - public static Symbol importedSymbol(Tree tree, Name name) { - switch (tree) { - case Import(Tree expr, Name[] selectors): - Type pre = tree.symbol().type(); - if (pre != Type.ErrorType) { - boolean renamed = false; - for (int i = 0; i < selectors.length; i = i + 2) { - if (i + 1 < selectors.length && name.toTermName() == selectors[i + 1]) { - if (name.isTypeName()) - return pre.lookupNonPrivate(selectors[i].toTypeName()); - else - return pre.lookupNonPrivate(selectors[i]); - } else if (name.toTermName() == selectors[i]) { - renamed = true; - } else if (selectors[i] == Names.IMPORT_WILDCARD && !renamed) { - return pre.lookupNonPrivate(name); - } - } - } - return Symbol.NONE; - default: - throw new ApplicationError(); - } - } - - - /** returns true if the tree is a sequence-valued pattern. - * precondition: tree is a pattern. - * calls isSequenceValued( Tree, List ) because needs to remember bound - * values. - */ - public static boolean isSequenceValued( Tree tree ) { - return isSequenceValued( tree, new LinkedList() ); - } - - /** returns true if the tree is a sequence-valued pattern. - * precondition: tree is a pattern - */ - public static boolean isSequenceValued( Tree tree, LinkedList recVars ) { - switch( tree ) { - case Bind(_, Tree t): - recVars.addFirst( tree.symbol() ); - boolean res = isSequenceValued( t ); - recVars.removeFirst(); - return res; - case Sequence(_): - return true; - case Alternative(Tree[] ts): - for( int i = 0; i < ts.length; i++ ) { - if( isSequenceValued( ts[ i ] ) ) - return true; - } - return false; - case Ident(Name n): // if Ident is a recursive var, then true - return recVars.contains( tree.symbol() ); - case Apply( _, _ ): - case Literal( _ ): - case Select(_,_): - case Typed(_,_): - return false; - default: - throw new scalac.ApplicationError("Unexpected pattern "+tree.getClass()); - } - } - - /** returns true if the argument is an empty sequence pattern - */ - public static boolean isEmptySequence( Tree tree ) { - switch( tree ) { - case Sequence( Tree ts[] ): - return ( ts.length == 0 ); - default: - return false; - } - } - /** this test should correspond to the one used in TransMatch phase */ - public static boolean isRegularPattern( Tree tree ) { - switch (tree) { - case Alternative(_): - return true; - case Bind(_, Tree pat): - return isRegularPattern( pat ); - case Ident(_): - return false; - case CaseDef(Tree pat, _, _): - isRegularPattern(pat); - break; - case Sequence( Tree[] trees): - return true; - case Apply( _, Tree[] trees ): - for( int i = 0; i < trees.length; i++ ) - if( isRegularPattern( trees[i] ) ) - return true; - case Literal( _ ): - return false; - - } - return false; - } - - /** @todo replace with cleaner test (e.g. of a symbol flag) - */ - public static boolean isNameOfStarPattern( Name n ) { - String s = n.toString(); - return (s.indexOf("$") != -1) - &&(!s.startsWith("nest")); - } - -} diff --git a/sources/scalac/ast/TreeList.java b/sources/scalac/ast/TreeList.java deleted file mode 100644 index bf4550c632..0000000000 --- a/sources/scalac/ast/TreeList.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -\* */ - -// $Id$ - -package scalac.ast; - -/** List of trees. - */ - -public final class TreeList { - Tree[] trees; - int len; - - public TreeList(Tree[] ts) { - trees = ts; - len = ts.length; - } - - public TreeList() { - clear(); - } - - public void append(Tree tree) { - if (len == trees.length) { - Tree[] ts = new Tree[len == 0 ? 4 : len * 2]; - System.arraycopy(trees, 0, ts, 0, len); - trees = ts; - } - trees[len++] = tree; - } - - public void append(Tree[] ts) { - for (int j = 0; j < ts.length; j++) - append(ts[j]); - } - - public void append(TreeList tl) { - for (int j = 0; j < tl.len; j++) - append(tl.trees[j]); - } - - public void clear() { - trees = new Tree[4]; - len = 0; - } - - public int length() { - return len; - } - - public Tree get(int i) { - return trees[i]; - } - - public Tree first() { - return trees[0]; - } - - public Tree removeLast() { - return trees[--len]; - } - - public Tree[] toArray() { - Tree[] ts = new Tree[len]; - System.arraycopy(trees, 0, ts, 0, len); - return ts; - } - - public Tree[] copyTo(Tree[] ts) { - return copyTo(ts, 0); - } - - public Tree[] copyTo(Tree[] ts, int from) { - System.arraycopy(trees, 0, ts, from, len); - return ts; - } -} diff --git a/sources/scalac/ast/printer/TreePrinter.java b/sources/scalac/ast/printer/TreePrinter.java deleted file mode 100644 index a0884b0b2a..0000000000 --- a/sources/scalac/ast/printer/TreePrinter.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.ast.printer; - -import scalac.Global; -import scalac.CompilationUnit; -import scalac.ast.Tree; - -/** - * Interface for all abstract tree printers. - * - * @author Michel Schinz - * @version 1.0 - */ -public interface TreePrinter { - public void begin(); - public void end(); - public void flush(); - - public void print(CompilationUnit[] units); - public void print(Tree tree); -} diff --git a/sources/scalac/atree/AArithmeticOp.java b/sources/scalac/atree/AArithmeticOp.java deleted file mode 100644 index 1627ca1ad9..0000000000 --- a/sources/scalac/atree/AArithmeticOp.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents an arithmetic operation. */ -public class AArithmeticOp { - - //######################################################################## - // Public Cases - - /** An arithmetic addition operation */ - public case ADD; - - /** An arithmetic subtraction operation */ - public case SUB; - - /** An arithmetic multiplication operation */ - public case MUL; - - /** An arithmetic division operation */ - public case DIV; - - /** An arithmetic remainder operation */ - public case REM; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case ADD: return "ADD"; - case SUB: return "SUB"; - case MUL: return "MUL"; - case DIV: return "DIV"; - case REM: return "REM"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AClass.java b/sources/scalac/atree/AClass.java deleted file mode 100644 index 66cf4693e1..0000000000 --- a/sources/scalac/atree/AClass.java +++ /dev/null @@ -1,139 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import java.util.Map; -import java.util.LinkedHashMap; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** This class represents an attributed class. */ -public class AClass extends ARepository { - - //######################################################################## - // Private Fields - - /** The class symbol */ - private final Symbol symbol; - - /** The symbol to field map */ - private final Map/*<Symbol,AField>*/ fields; - - /** The symbol to method map */ - private final Map/*Symbol,AMethod*/ methods; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AClass(Symbol symbol) { - this.symbol = symbol; - this.fields = new LinkedHashMap(); - this.methods = new LinkedHashMap(); - } - - //######################################################################## - // Public Methods - - /** Returns the symbol of this class. */ - public Symbol symbol() { - return symbol; - } - - /** Is this class public? */ - public boolean isPublic() { - return symbol().isPublic(); - } - - /** Is this class private? */ - public boolean isPrivate() { - return symbol().isPrivate(); - } - - /** Is this class protected? */ - public boolean isProtected() { - return symbol().isProtected(); - } - - /** Is this class final? */ - public boolean isFinal() { - return false; // !!! - } - - /** Is this class abstract? */ - public boolean isAbstract() { - return symbol.isAbstractClass(); - } - - /** Is this class an interface? */ - public boolean isInterface() { - return symbol.isInterface(); - } - - /** Is this class deprecated? */ - public boolean isDeprecated() { - return false; // !!! - } - - /** Is this class synthetic? */ - public boolean isSynthetic() { - return symbol().isSynthetic(); - } - - /** Adds the given field to this class. */ - public void addField(AField field) { - assert !fields.containsKey(field.symbol()): field; - fields.put(field.symbol(), field); - } - - /** Adds the given method to this class. */ - public void addMethod(AMethod method) { - assert !methods.containsKey(method.symbol()): method; - methods.put(method.symbol(), method); - } - - /** Returns the fields of this class. */ - public AField[] fields() { - return (AField[])fields.values().toArray(new AField[fields.size()]); - } - - /** Returns the methods of this class. */ - public AMethod[] methods() { - return(AMethod[])methods.values().toArray(new AMethod[methods.size()]); - } - - /** Returns the type parameters of this class. */ - public Symbol[] tparams() { - return symbol.typeParams(); - } - - /** Returns the value parameters of this class. */ - public Symbol[] vparams() { - return symbol.valueParams(); - } - - /** Returns the parent types of this class. */ - public Type[] parents() { - switch (symbol.info()) { - case CompoundType(Type[] parts, _): - return parts; - default: - throw Debug.abort("illegal case", symbol.info()); - } - } - - /** Returns a string representation of this class. */ - public String toString() { - return new ATreePrinter().printClass(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ACode.java b/sources/scalac/atree/ACode.java deleted file mode 100644 index 3e65d41829..0000000000 --- a/sources/scalac/atree/ACode.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class represents attributed code. */ -public class ACode { - - //######################################################################## - // Public Constants - - public static final ACode[] EMPTY_ARRAY = new ACode[0]; - - //######################################################################## - // Public Cases - - // jvm : - - public case Void; - - // jvm : aload_0 - public case This(Symbol clasz); - - // jvm : {b, s}ipush, ldc{ ,_w, 2_w}, aconst_null - // jvm : iconst_{m1, 2, 3, 4, 5}, {i, l, f, d}const_{0, 1}, fconst_2 - public case Constant(AConstant constant); - - // jvm : get{static, field} - // jvm : {i, l, f, d, a}load{, _0, _1, _2, _3} - // jvm : {i, l, f, d, a, b, c, s}aload - public case Load(ALocation location); - - // jvm : put{static, field} - // jvm : {i, l, f, d, a}store{, _0, _1, _2, _3} - // jvm : {i, l, f, d, a, b, c, s}store - public case Store(ALocation location, ACode value); - - // jvm : new, invoke{static, virtual, interface, special}, {, a}newarray - // jvm : <see also in APrimitive> - public case Apply(AFunction function, Type[] targs, ACode[] vargs); - - // jvm : instanceof, checkcast - public case IsAs(ACode value, Type type, boolean cast); - - // jvm : - - public case If(ACode test, ACode success, ACode failure); - - // jvm : {tables, lookup}switch - public case Switch(ACode test, int[][] tags, ACode[] bodies); - - // jvm : monitor{enter, exit} - public case Synchronized(ACode lock, ACode value); - - // jvm : - - public case Block(Symbol[] locals, ACode[] statements, ACode value); - - // jvm : - - public case Label(Symbol label, Symbol[] locals, ACode value); - - // jvm : goto, goto_w - public case Goto(Symbol label, ACode[] vargs); - - // jvm : {i, l, f, d, a, }return - public case Return(Symbol function, ACode value); - - // jvm : athrow - public case Throw(ACode value); - - // jvm : pop, pop2 - public case Drop(ACode value, Type type); - - // jvm : nop, dup{, _x1, _x2, 2, 2_x1, 2_x2}, swap - // jvm : multianewarray, iinc, jsr{, _w}, ret, wide - // NOT MAPPED - - //######################################################################## - // Public Fields - - /** The source file position */ - public int pos; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this code. */ - public String toString() { - return new ATreePrinter().printCode(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AComparisonOp.java b/sources/scalac/atree/AComparisonOp.java deleted file mode 100644 index 1e7bcf1bcd..0000000000 --- a/sources/scalac/atree/AComparisonOp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a comparison operation. */ -public class AComparisonOp { - - //######################################################################## - // Public Cases - - /** A comparison operation with -1 default for NaNs */ - public case CMPL; - - /** A comparison operation with no default for NaNs */ - public case CMP; - - /** A comparison operation with +1 default for NaNs */ - public case CMPG; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case CMPL: return "CMPL"; - case CMP : return "CMP"; - case CMPG: return "CMPG"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AConstant.java b/sources/scalac/atree/AConstant.java deleted file mode 100644 index 12c58d5889..0000000000 --- a/sources/scalac/atree/AConstant.java +++ /dev/null @@ -1,404 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; -import scalac.symtab.Symbol; - -/** This class represents a constant. */ -public class AConstant { - - public static final AConstant[] EMPTY_ARRAY = new AConstant[0]; - - //######################################################################## - // Public Cases - - public case UNIT; - public case BOOLEAN(boolean value); - public case BYTE(byte value); - public case SHORT(short value); - public case CHAR(char value); - public case INT(int value); - public case LONG(long value); - public case FLOAT(float value); - public case DOUBLE(double value); - public case STRING(String value); - public case SYMBOL_NAME(Symbol value); - public case NULL; - public case ZERO; - - //######################################################################## - // Public Methods - - /** Returns the type kind of this constant. */ - public ATypeKind kind() { - switch (this) { - case UNIT: - return ATypeKind.UNIT; - case BOOLEAN(_): - return ATypeKind.BOOL; - case BYTE(_): - return ATypeKind.I1; - case SHORT(_): - return ATypeKind.I2; - case CHAR(_): - return ATypeKind.U2; - case INT(_): - return ATypeKind.I4; - case LONG(_): - return ATypeKind.I8; - case FLOAT(_): - return ATypeKind.R4; - case DOUBLE(_): - return ATypeKind.R8; - case STRING(_): - case SYMBOL_NAME(_): - return ATypeKind.STR; - case NULL: - return ATypeKind.NULL; - case ZERO: - return ATypeKind.ZERO; - default: - throw Debug.abort("unknown case", this); - } - } - - - /** Converts this constant to a boolean value. */ - public boolean booleanValue() { - switch (this) { - case BOOLEAN(boolean value): - return value; - default: - throw Debug.abort("not convertible to boolean", this); - } - } - - /** Converts this constant to a byte value. */ - public byte byteValue() { - switch (this) { - case BYTE(byte value): - return (byte)value; - case SHORT(short value): - return (byte)value; - case CHAR(char value): - return (byte)value; - case INT(int value): - return (byte)value; - case LONG(long value): - return (byte)value; - case FLOAT(float value): - return (byte)value; - case DOUBLE(double value): - return (byte)value; - default: - throw Debug.abort("not convertible to byte", this); - } - } - - /** Converts this constant to a short value. */ - public short shortValue() { - switch (this) { - case BYTE(byte value): - return (short)value; - case SHORT(short value): - return (short)value; - case CHAR(char value): - return (short)value; - case INT(int value): - return (short)value; - case LONG(long value): - return (short)value; - case FLOAT(float value): - return (short)value; - case DOUBLE(double value): - return (short)value; - default: - throw Debug.abort("not convertible to short", this); - } - } - - /** Converts this constant to a char value. */ - public char charValue() { - switch (this) { - case BYTE(byte value): - return (char)value; - case SHORT(short value): - return (char)value; - case CHAR(char value): - return (char)value; - case INT(int value): - return (char)value; - case LONG(long value): - return (char)value; - case FLOAT(float value): - return (char)value; - case DOUBLE(double value): - return (char)value; - default: - throw Debug.abort("not convertible to char", this); - } - } - - /** Converts this constant to a int value. */ - public int intValue() { - switch (this) { - case BYTE(byte value): - return (int)value; - case SHORT(short value): - return (int)value; - case CHAR(char value): - return (int)value; - case INT(int value): - return (int)value; - case LONG(long value): - return (int)value; - case FLOAT(float value): - return (int)value; - case DOUBLE(double value): - return (int)value; - default: - throw Debug.abort("not convertible to int", this); - } - } - - /** Converts this constant to a long value. */ - public long longValue() { - switch (this) { - case BYTE(byte value): - return (long)value; - case SHORT(short value): - return (long)value; - case CHAR(char value): - return (long)value; - case INT(int value): - return (long)value; - case LONG(long value): - return (long)value; - case FLOAT(float value): - return (long)value; - case DOUBLE(double value): - return (long)value; - default: - throw Debug.abort("not convertible to long", this); - } - } - - /** Converts this constant to a float value. */ - public float floatValue() { - switch (this) { - case BYTE(byte value): - return (float)value; - case SHORT(short value): - return (float)value; - case CHAR(char value): - return (float)value; - case INT(int value): - return (float)value; - case LONG(long value): - return (float)value; - case FLOAT(float value): - return (float)value; - case DOUBLE(double value): - return (float)value; - default: - throw Debug.abort("not convertible to float", this); - } - } - - /** Converts this constant to a double value. */ - public double doubleValue() { - switch (this) { - case BYTE(byte value): - return (double)value; - case SHORT(short value): - return (double)value; - case CHAR(char value): - return (double)value; - case INT(int value): - return (double)value; - case LONG(long value): - return (double)value; - case FLOAT(float value): - return (double)value; - case DOUBLE(double value): - return (double)value; - default: - throw Debug.abort("not convertible to double", this); - } - } - - /** Converts this constant to a String value. */ - public String stringValue() { - switch (this) { - case UNIT: - return "()"; - case BOOLEAN(boolean value): - return String.valueOf(value); - case BYTE(byte value): - return String.valueOf(value); - case SHORT(short value): - return String.valueOf(value); - case CHAR(char value): - return String.valueOf(value); - case INT(int value): - return String.valueOf(value); - case LONG(long value): - return String.valueOf(value); - case FLOAT(float value): - return String.valueOf(value); - case DOUBLE(double value): - return String.valueOf(value); - case STRING(String value): - return value; - case SYMBOL_NAME(Symbol value): - return value.name.toString(); - case NULL: - return String.valueOf(null); - default: - throw Debug.abort("not convertible to String", this); - } - } - - /** Tests whether this constant equals given Object. */ - public boolean equals(Object that) { - if (this == that) return true; - return (that instanceof AConstant) && this.equals((AConstant)that); - } - - /** Tests whether this constant equals given one. */ - public boolean equals(AConstant that) { - if (this == that) return true; - if (null == that) return false; - switch (this) { - case UNIT: - return false; - case BOOLEAN(boolean ivalue): - switch (that) { - case BOOLEAN(boolean avalue): - return ivalue == avalue; - default: - return false; - } - case BYTE(byte ivalue): - switch (that) { - case BYTE(byte avalue): - return ivalue == avalue; - default: - return false; - } - case SHORT(short ivalue): - switch (that) { - case SHORT(short avalue): - return ivalue == avalue; - default: - return false; - } - case CHAR(char ivalue): - switch (that) { - case CHAR(char avalue): - return ivalue == avalue; - default: - return false; - } - case INT(int ivalue): - switch (that) { - case INT(int avalue): - return ivalue == avalue; - default: - return false; - } - case LONG(long ivalue): - switch (that) { - case LONG(long avalue): - return ivalue == avalue; - default: - return false; - } - case FLOAT(float ivalue): - switch (that) { - case FLOAT(float avalue): - return ivalue == avalue; - default: - return false; - } - case DOUBLE(double ivalue): - switch (that) { - case DOUBLE(double avalue): - return ivalue == avalue; - default: - return false; - } - case STRING(String ivalue): - switch (that) { - case STRING(String avalue): - return ivalue.equals(avalue); - default: - return false; - } - case SYMBOL_NAME(Symbol ivalue): - switch (that) { - case SYMBOL_NAME(Symbol avalue): - return ivalue == avalue; - default: - return false; - } - case NULL: - return false; - case ZERO: - return false; - default: - throw Debug.abort("unknown case", this); - } - } - - /** Returns the hash code of this constant. */ - public int hashCode() { - switch (this) { - case UNIT: - return 4041; - case BOOLEAN(boolean value): - return value ? 1231 : 1237; - case BYTE(byte value): - return value; - case SHORT(short value): - return value; - case CHAR(char value): - return value; - case INT(int value): - return value; - case LONG(long value): - long bits = value; - return (int)(bits ^ (bits >>> 32)); - case FLOAT(float value): - int bits = java.lang.Float.floatToIntBits(value); - return bits; - case DOUBLE(double value): - long bits = java.lang.Double.doubleToLongBits(value); - return (int)(bits ^ (bits >>> 32)); - case STRING(String value): - return value.hashCode(); - case SYMBOL_NAME(Symbol value): - return value.hashCode(); - case NULL: - return 0; - case ZERO: - return 0; - default: - throw Debug.abort("unknown case", this); - } - } - - /** Returns a string representation of this constant. */ - public String toString() { - return new ATreePrinter().printConstant(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AField.java b/sources/scalac/atree/AField.java deleted file mode 100644 index bbc27f7063..0000000000 --- a/sources/scalac/atree/AField.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class represents an attributed field. */ -public class AField extends AMember { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AField(Symbol symbol, boolean isStatic) { - super(symbol, isStatic); - } - - //######################################################################## - // Public Methods - - /** Is this field final? */ - public boolean isFinal() { - return false; // !!! - } - - /** Is this field volatile? */ - public boolean isVolatile() { - return false; // !!! - } - - /** Is this field transient? */ - public boolean isTransient() { - return false; // !!! - } - - /** Returns the type of this field. */ - public Type type() { - return symbol().type(); - } - - /** Returns a string representation of this field. */ - public String toString() { - return new ATreePrinter().printField(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AFunction.java b/sources/scalac/atree/AFunction.java deleted file mode 100644 index 2970222a2c..0000000000 --- a/sources/scalac/atree/AFunction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Type; -import scalac.symtab.Symbol; - -/** This class represents an attributed function reference. */ -public class AFunction { - - //######################################################################## - // Public Cases - - public case Method(ACode object, Symbol method, AInvokeStyle style); - public case Primitive(APrimitive primitive); - public case NewArray(Type element); - - //######################################################################## - // Public Methods - - /** Returns a string representation of this function. */ - public String toString() { - return new ATreePrinter().printFunction(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AInvokeStyle.java b/sources/scalac/atree/AInvokeStyle.java deleted file mode 100644 index f833aad2f0..0000000000 --- a/sources/scalac/atree/AInvokeStyle.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a method invocation style. */ -public class AInvokeStyle { - - //######################################################################## - // Public Cases - - public case New; - public case Dynamic; - public case Static(boolean onInstance); - - //######################################################################## - // Public Constants - - public static final AInvokeStyle StaticClass = Static(false); - public static final AInvokeStyle StaticInstance = Static(true); - - //######################################################################## - // Public Methods - - /** Is this a new object creation? */ - public boolean isNew() { - switch (this) { - case New: - return true; - default: - return false; - } - } - - /** Is this a dynamic method call? */ - public boolean isDynamic() { - switch (this) { - case Dynamic: - return true; - default: - return false; - } - } - - /** Is this a static method call? */ - public boolean isStatic() { - switch (this) { - case Static(_): - return true; - default: - return false; - } - } - - /** Is this an instance method call? */ - public boolean hasInstance() { - switch (this) { - case Dynamic: - return true; - case Static(boolean onInstance): - return onInstance; - default: - return false; - } - } - - /** Returns a string representation of this style. */ - public String toString() { - switch (this) { - case New: - return "new"; - case Dynamic: - return "dynamic"; - case Static(false): - return "static-class"; - case Static(true): - return "static-instance"; - default: - throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ALocation.java b/sources/scalac/atree/ALocation.java deleted file mode 100644 index 0a9c440df2..0000000000 --- a/sources/scalac/atree/ALocation.java +++ /dev/null @@ -1,33 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; - -/** This class represents an attributed value location. */ -public class ALocation { - - //######################################################################## - // Public Cases - - public case Module(Symbol module); // !!! remove ? - public case Field(ACode object, Symbol field, boolean isStatic); - public case Local(Symbol local, boolean isArgument); - public case ArrayItem(ACode array, ACode index); - - //######################################################################## - // Public Methods - - /** Returns a string representation of this location. */ - public String toString() { - return new ATreePrinter().printLocation(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ALogicalOp.java b/sources/scalac/atree/ALogicalOp.java deleted file mode 100644 index 85010ae4f0..0000000000 --- a/sources/scalac/atree/ALogicalOp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a logical operation. */ -public class ALogicalOp { - - //######################################################################## - // Public Cases - - /** A bitwise AND operation */ - public case AND; - - /** A bitwise OR operation */ - public case OR; - - /** A bitwise XOR operation */ - public case XOR; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case AND: return "AND"; - case OR : return "OR"; - case XOR: return "XOR"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AMember.java b/sources/scalac/atree/AMember.java deleted file mode 100644 index 4275180a4d..0000000000 --- a/sources/scalac/atree/AMember.java +++ /dev/null @@ -1,87 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; - -/** This class represents an attributed class member. */ -public abstract class AMember { - - //######################################################################## - // Private Fields - - /** The member symbol */ - private final Symbol symbol; - - /** The static flag */ - private final boolean isStatic; - - /** The member code */ - private ACode code; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AMember(Symbol symbol, boolean isStatic) { - this.symbol = symbol; - this.isStatic = isStatic; - this.code = ACode.Void; - } - - //######################################################################## - // Public Methods - - /** Returns the symbol of this member. */ - public Symbol symbol() { - return symbol; - } - - /** Is this member public? */ - public boolean isPublic() { - return symbol().isPublic(); - } - - /** Is this member private? */ - public boolean isPrivate() { - return symbol().isPrivate(); - } - - /** Is this member protected? */ - public boolean isProtected() { - return symbol().isProtected(); - } - - /** Is this member static? */ - public boolean isStatic() { - return isStatic; - } - - /** Is this member deprecated? */ - public boolean isDeprecated() { - return false; // !!! - } - - /** Is this member synthetic? */ - public boolean isSynthetic() { - return symbol().isSynthetic(); - } - - /** Returns the member code. */ - public ACode code() { - return code; - } - - /** Sets the member code. */ - public void setCode(ACode code) { - this.code = code; - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AMethod.java b/sources/scalac/atree/AMethod.java deleted file mode 100644 index f904fa6b92..0000000000 --- a/sources/scalac/atree/AMethod.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class represents an attributed method. */ -public class AMethod extends AMember { - //######################################################################## - // Public Fields - - /** Contains the Intermediate code of this Method */ - public Object icode = null; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AMethod(Symbol symbol, boolean isStatic) { - super(symbol, isStatic); - } - - //######################################################################## - // Public Methods - - /** Is this method final? */ - public boolean isFinal() { - return symbol().isMethodFinal(); - } - - /** Is this method synchronized? */ - public boolean isSynchronized() { - return false; // !!! - } - - /** Is this method native? */ - public boolean isNative() { - return false; // !!! - } - - /** Is this method abstract? */ - public boolean isAbstract() { - return symbol().isDeferred(); - } - - /** Is this method FP-strict? */ - public boolean isStrictFP() { - return false; // !!! - } - - /** Returns the type parameters of this method. */ - public Symbol[] tparams() { - return symbol().type().typeParams(); - } - - /** Returns the value parameters of this method. */ - public Symbol[] vparams() { - return symbol().type().valueParams(); - } - - /** Returns the result type of this method. */ - public Type result() { - return symbol().type().resultType(); - } - - /** Returns a string representation of this method. */ - public String toString() { - return new ATreePrinter().printMethod(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/APrimitive.java b/sources/scalac/atree/APrimitive.java deleted file mode 100644 index 034a9f4d19..0000000000 --- a/sources/scalac/atree/APrimitive.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -/** This class represents a primitive operation. */ -public class APrimitive { - - //######################################################################## - // Public Cases - - // type : (type) => type - // range: type <- { BOOL, Ix, Ux, Rx } - // jvm : {i, l, f, d}neg - public case Negation(ATypeKind kind); - - // type : zero ? (type) => BOOL : (type,type) => BOOL - // range: type <- { BOOL, Ix, Ux, Rx, REF } - // jvm : if{eq, ne, lt, ge, le, gt}, if{null, nonnull} - // if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne} - public case Test(ATestOp op, ATypeKind kind, boolean zero); - - // type : (type,type) => I4 - // range: type <- { Ix, Ux, Rx } - // jvm : lcmp, {f, d}cmp{l, g} - public case Comparison(AComparisonOp op, ATypeKind kind); - - // type : (type,type) => type - // range: type <- { Ix, Ux, Rx } - // jvm : {i, l, f, d}{add, sub, mul, div, rem} - public case Arithmetic(AArithmeticOp op, ATypeKind kind); - - // type : (type,type) => type - // range: type <- { BOOL, Ix, Ux } - // jvm : {i, l}{and, or, xor} - public case Logical(ALogicalOp op, ATypeKind kind); - - // type : (type,I4) => type - // range: type <- { Ix, Ux } - // jvm : {i, l}{shl, ushl, shr} - public case Shift(AShiftOp op, ATypeKind kind); - - // type : (src) => dst - // range: src,dst <- { Ix, Ux, Rx } - // jvm : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s} - public case Conversion(ATypeKind src, ATypeKind dst); - - // type : (Array[REF]) => I4 - // range: type <- { BOOL, Ix, Ux, Rx, REF } - // jvm : arraylength - public case ArrayLength(ATypeKind kind); - - // type : (lf,rg) => STR - // range: lf,rg <- { BOOL, Ix, Ux, Rx, REF, STR } - // jvm : - - public case StringConcat(ATypeKind lf, ATypeKind rg); - - //######################################################################## - // Public Methods - - /** Returns a string representation of this primitive. */ - public String toString() { - return new ATreePrinter().printPrimitive(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ARepository.java b/sources/scalac/atree/ARepository.java deleted file mode 100644 index c1468a85a8..0000000000 --- a/sources/scalac/atree/ARepository.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import java.util.Map; -import java.util.LinkedHashMap; - -/** This class represents a repository of attributed classes. */ -public class ARepository { - - //######################################################################## - // Private Fields - - /** The symbol to class map */ - private final Map/*<Symbol,AClass>*/ classes; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ARepository() { - this.classes = new LinkedHashMap(); - } - - //######################################################################## - // Public Methods - - /** Adds the given class to this repository. */ - public void addClass(AClass clasz) { - assert !classes.containsKey(clasz.symbol()): clasz; - classes.put(clasz.symbol(), clasz); - } - - /** Returns the classes of this repository. */ - public AClass[] classes() { - return (AClass[])classes.values().toArray(new AClass[classes.size()]); - } - - /** Returns a string representation of this repository. */ - public String toString() { - return new ATreePrinter().printRepository(this).toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/AShiftOp.java b/sources/scalac/atree/AShiftOp.java deleted file mode 100644 index 791ce54328..0000000000 --- a/sources/scalac/atree/AShiftOp.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a shift operation. */ -public class AShiftOp { - - //######################################################################## - // Public Cases - - /** A logical shift to the left */ - public case LSL; - - /** An arithmetic shift to the right */ - public case ASR; - - /** A logical shift to the right */ - public case LSR; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case LSL: return "LSL"; - case ASR: return "ASR"; - case LSR: return "LSR"; - default: throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATestOp.java b/sources/scalac/atree/ATestOp.java deleted file mode 100644 index 1d90f5ba0e..0000000000 --- a/sources/scalac/atree/ATestOp.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a test operation. */ -public class ATestOp { - - //######################################################################## - // Public Cases - - /** An equality test */ - public case EQ; - - /** A non-equality test */ - public case NE; - - /** A less-than test */ - public case LT; - - /** A greater-than-or-equal test */ - public case GE; - - /** A less-than-or-equal test */ - public case LE; - - /** A greater-than test */ - public case GT; - - //######################################################################## - // Public Methods - - /** Returns the negation of this operation. */ - public ATestOp negate() { - switch (this) { - case EQ: return NE; - case NE: return EQ; - case LT: return GE; - case GE: return LT; - case LE: return GT; - case GT: return LE; - default: throw Debug.abort("unknown case", this); - } - } - - /** Returns a string representation of this operation. */ - public String toString() { - switch (this) { - case EQ: return "EQ"; - case NE: return "NE"; - case LT: return "LT"; - case GE: return "GE"; - case LE: return "LE"; - case GT: return "GT"; - default: throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreeFactory.java b/sources/scalac/atree/ATreeFactory.java deleted file mode 100644 index 0c09650a16..0000000000 --- a/sources/scalac/atree/ATreeFactory.java +++ /dev/null @@ -1,531 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.ast.Tree; -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** This class implements an attributed tree factory. */ -public class ATreeFactory { - - //######################################################################## - // Public Fields - - /** The unique Void node */ - public final ACode Void = ACode.Void; - - /** The unique UNIT constant */ - public final AConstant UNIT = AConstant.UNIT; - - /** The unique NULL constant */ - public final AConstant NULL = AConstant.NULL; - - /** The unique ZERO constant */ - public final AConstant ZERO = AConstant.ZERO; - - //######################################################################## - // Public Methods - Building code - - /** Builds a This node. */ - public ACode This(Tree t, Symbol clasz) { - ACode.This code = ACode.This(clasz); - code.pos = t.pos; - return code; - } - - /** Builds a Constant node. */ - public ACode Constant(Tree t, AConstant constant) { - ACode.Constant code = ACode.Constant(constant); - code.pos = t.pos; - return code; - } - - /** Builds a Load node. */ - public ACode Load(Tree t, ALocation location) { - ACode.Load code = ACode.Load(location); - code.pos = t.pos; - return code; - } - - /** Builds a Store node. */ - public ACode Store(Tree t, ALocation location, ACode value) { - ACode.Store code = ACode.Store(location, value); - code.pos = t.pos; - return code; - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function, Type[] ts, ACode[] vs) { - ACode.Apply code = ACode.Apply(function, ts, vs); - code.pos = t.pos; - return code; - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function, Type[] ts) { - return Apply(t, function, ts, ACode.EMPTY_ARRAY); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function, ACode[] vs) { - return Apply(t, function, Type.EMPTY_ARRAY, vs); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, AFunction function) { - return Apply(t, function, Type.EMPTY_ARRAY, ACode.EMPTY_ARRAY); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, APrimitive primitive, ACode v0) { - return Apply(t, AFunction.Primitive(primitive), new ACode[] {v0}); - } - - /** Builds an Apply node. */ - public ACode Apply(Tree t, APrimitive primitive, ACode v0, ACode v1) { - return Apply(t, AFunction.Primitive(primitive), new ACode[] {v0,v1}); - } - - /** Builds an IsAs node. */ - public ACode IsAs(Tree t, ACode value, Type type, boolean cast) { - ACode.IsAs code = ACode.IsAs(value, type, cast); - code.pos = t.pos; - return code; - } - - /** Builds an If node. */ - public ACode If(Tree t, ACode test, ACode success, ACode failure) { - ACode.If code = ACode.If(test, success, failure); - code.pos = t.pos; - return code; - } - - /** Builds a Switch node. */ - public ACode Switch(Tree t, ACode test, int[][] tags, ACode[] bodies) { - ACode.Switch code = ACode.Switch(test, tags, bodies); - code.pos = t.pos; - return code; - } - - /** Builds a Synchronized node. */ - public ACode Synchronized(Tree t, ACode lock, ACode value) { - ACode.Synchronized code = ACode.Synchronized(lock, value); - code.pos = t.pos; - return code; - } - - /** Builds a Block node. */ - public ACode Block(Tree t, Symbol[] locals,ACode[] statements,ACode value){ - ACode.Block code = ACode.Block(locals, statements, value); - code.pos = t.pos; - return code; - } - - /** Builds a Label node. */ - public ACode Label(Tree t, Symbol label, Symbol[] locals, ACode value) { - ACode.Label code = ACode.Label(label, locals, value); - code.pos = t.pos; - return code; - } - - /** Builds a Goto node. */ - public ACode Goto(Tree t, Symbol label, ACode[] vargs) { - ACode.Goto code = ACode.Goto(label, vargs); - code.pos = t.pos; - return code; - } - - /** Builds a Return node. */ - public ACode Return(Tree t, Symbol function, ACode value) { - ACode.Return code = ACode.Return(function, value); - code.pos = t.pos; - return code; - } - - /** Builds a Throw node. */ - public ACode Throw(Tree t, ACode value) { - ACode.Throw code = ACode.Throw(value); - code.pos = t.pos; - return code; - } - - /** Builds a Drop node. */ - public ACode Drop(Tree t, ACode value, Type type) { - ACode.Drop code = ACode.Drop(value, type); - code.pos = t.pos; - return code; - } - - //######################################################################## - // Public Methods - Building primitive operations - - /** Builds a negation operation */ - public ACode NOT(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, NOT(kind), v0); - } - - /** Builds an EQ operation */ - public ACode EQ(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, EQ(kind, true), v0); - } - - /** Builds a NE operation */ - public ACode NE(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, NE(kind, true), v0); - } - - /** Builds a LT operation */ - public ACode LT(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, LT(kind, true), v0); - } - - /** Builds a GE operation */ - public ACode GE(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, GE(kind, true), v0); - } - - /** Builds a LE operation */ - public ACode LE(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, LE(kind, true), v0); - } - - /** Builds a GT operation */ - public ACode GT(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, GT(kind, true), v0); - } - - /** Builds an EQ operation */ - public ACode EQ(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, EQ(kind, false), v0, v1); - } - - /** Builds a NE operation */ - public ACode NE(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, NE(kind, false), v0, v1); - } - - /** Builds a LT operation */ - public ACode LT(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LT(kind, false), v0, v1); - } - - /** Builds a GE operation */ - public ACode GE(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, GE(kind, false), v0, v1); - } - - /** Builds a LE operation */ - public ACode LE(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LE(kind, false), v0, v1); - } - - /** Builds a GT operation */ - public ACode GT(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, GT(kind, false), v0, v1); - } - - /** Builds a CMPL operation */ - public ACode CMPL(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, CMPL(kind), v0, v1); - } - - /** Builds a CMP operation */ - public ACode CMP(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, CMP(kind), v0, v1); - } - - /** Builds a CMPG operation */ - public ACode CMPG(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, CMPG(kind), v0, v1); - } - - /** Builds an ADD operation */ - public ACode ADD(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, ADD(kind), v0, v1); - } - - /** Builds a SUB operation */ - public ACode SUB(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, SUB(kind), v0, v1); - } - - /** Builds a MUL operation */ - public ACode MUL(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, MUL(kind), v0, v1); - } - - /** Builds a DIV operation */ - public ACode DIV(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, DIV(kind), v0, v1); - } - - /** Builds a REM operation */ - public ACode REM(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, REM(kind), v0, v1); - } - - /** Builds an AND operation. */ - public ACode AND(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, AND(kind), v0, v1); - } - - /** Builds an OR operation. */ - public ACode OR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, OR(kind), v0, v1); - } - - /** Builds an XOR operation. */ - public ACode XOR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, XOR(kind), v0, v1); - } - - /** Builds a LSL operation. */ - public ACode LSL(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LSL(kind), v0, v1); - } - - /** Builds a LSR operation. */ - public ACode LSR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, LSR(kind), v0, v1); - } - - /** Builds an ASR operation. */ - public ACode ASR(Tree t, ATypeKind kind, ACode v0, ACode v1) { - return Apply(t, ASR(kind), v0, v1); - } - - /** Builds a value conversion operation. */ - public ACode CONVERT(Tree t, ATypeKind src, ATypeKind dst, ACode v0) { - return Apply(t, CONVERT(src, dst), v0); - } - - /** Builds an array length operation. */ - public ACode LENGTH(Tree t, ATypeKind kind, ACode v0) { - return Apply(t, LENGTH(kind), v0); - } - - /** Builds a string concatenation operation. */ - public ACode CONCAT(Tree t, ATypeKind lf, ATypeKind rg, ACode v0,ACode v1){ - return Apply(t, CONCAT(lf, rg), v0, v1); - } - - //######################################################################## - // Public Methods - Building primitives - - /** Builds a negation primitive */ - public APrimitive NOT(ATypeKind kind) { - return APrimitive.Negation(kind); - } - - /** Builds an EQ primitive */ - public APrimitive EQ(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.EQ, kind, zero); - } - - /** Builds a NE primitive */ - public APrimitive NE(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.NE, kind, zero); - } - - /** Builds a LT primitive */ - public APrimitive LT(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.LT, kind, zero); - } - - /** Builds a GE primitive */ - public APrimitive GE(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.GE, kind, zero); - } - - /** Builds a LE primitive */ - public APrimitive LE(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.LE, kind, zero); - } - - /** Builds a GT primitive */ - public APrimitive GT(ATypeKind kind, boolean zero) { - return APrimitive.Test(ATestOp.GT, kind, zero); - } - - /** Builds a CMPL primitive */ - public APrimitive CMPL(ATypeKind kind) { - return APrimitive.Comparison(AComparisonOp.CMPL, kind); - } - - /** Builds a CMP primitive */ - public APrimitive CMP(ATypeKind kind) { - return APrimitive.Comparison(AComparisonOp.CMP, kind); - } - - /** Builds a CMPG primitive */ - public APrimitive CMPG(ATypeKind kind) { - return APrimitive.Comparison(AComparisonOp.CMPG, kind); - } - - /** Builds an ADD primitive */ - public APrimitive ADD(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.ADD, kind); - } - - /** Builds a SUB primitive */ - public APrimitive SUB(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.SUB, kind); - } - - /** Builds a MUL primitive */ - public APrimitive MUL(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.MUL, kind); - } - - /** Builds a DIV primitive */ - public APrimitive DIV(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.DIV, kind); - } - - /** Builds a REM primitive */ - public APrimitive REM(ATypeKind kind) { - return APrimitive.Arithmetic(AArithmeticOp.REM, kind); - } - - /** Builds an AND primitive. */ - public APrimitive AND(ATypeKind kind) { - return APrimitive.Logical(ALogicalOp.AND, kind); - } - - /** Builds an OR primitive. */ - public APrimitive OR(ATypeKind kind) { - return APrimitive.Logical(ALogicalOp.OR, kind); - } - - /** Builds an XOR primitive. */ - public APrimitive XOR(ATypeKind kind) { - return APrimitive.Logical(ALogicalOp.XOR, kind); - } - - /** Builds a LSL primitive. */ - public APrimitive LSL(ATypeKind kind) { - return APrimitive.Shift(AShiftOp.LSL, kind); - } - - /** Builds a LSR primitive. */ - public APrimitive LSR(ATypeKind kind) { - return APrimitive.Shift(AShiftOp.LSR, kind); - } - - /** Builds an ASR primitive. */ - public APrimitive ASR(ATypeKind kind) { - return APrimitive.Shift(AShiftOp.ASR, kind); - } - - /** Builds a value conversion primitive. */ - public APrimitive CONVERT(ATypeKind src, ATypeKind dst) { - return APrimitive.Conversion(src, dst); - } - - /** Builds an array length primitive. */ - public APrimitive LENGTH(ATypeKind kind) { - return APrimitive.ArrayLength(kind); - } - - /** Builds a string concatenation primitive. */ - public APrimitive CONCAT(ATypeKind lf, ATypeKind rg) { - return APrimitive.StringConcat(lf, rg); - } - - //######################################################################## - // Public Methods - Building constants - - /** Builds a BOOLEAN constant of given value. */ - public AConstant BOOLEAN(Boolean value) { - return BOOLEAN(value.booleanValue()); - } - - /** Builds a BOOLEAN constant of given value. */ - public AConstant BOOLEAN(boolean value) { - return AConstant.BOOLEAN(value); - } - - /** Builds a BYTE constant of given value. */ - public AConstant BYTE(Byte value) { - return BYTE(value.byteValue()); - } - - /** Builds a BYTE constant of given value. */ - public AConstant BYTE(byte value) { - return AConstant.BYTE(value); - } - - /** Builds a SHORT constant of given value. */ - public AConstant SHORT(Short value) { - return SHORT(value.shortValue()); - } - - /** Builds a SHORT constant of given value. */ - public AConstant SHORT(short value) { - return AConstant.SHORT(value); - } - - /** Builds a CHAR constant of given value. */ - public AConstant CHAR(Character value) { - return CHAR(value.charValue()); - } - - /** Builds a CHAR constant of given value. */ - public AConstant CHAR(char value) { - return AConstant.CHAR(value); - } - - /** Builds an INT constant of given value. */ - public AConstant INT(Integer value) { - return INT(value.intValue()); - } - - /** Builds an INT constant of given value. */ - public AConstant INT(int value) { - return AConstant.INT(value); - } - - /** Builds a LONG constant of given value. */ - public AConstant LONG(Long value) { - return LONG(value.longValue()); - } - - /** Builds a LONG constant of given value. */ - public AConstant LONG(long value) { - return AConstant.LONG(value); - } - - /** Builds a FLOAT constant of given value. */ - public AConstant FLOAT(Float value) { - return FLOAT(value.floatValue()); - } - - /** Builds a FLOAT constant of given value. */ - public AConstant FLOAT(float value) { - return AConstant.FLOAT(value); - } - - /** Builds a DOUBLE constant of given value. */ - public AConstant DOUBLE(Double value) { - return DOUBLE(value.doubleValue()); - } - - /** Builds a DOUBLE constant of given value. */ - public AConstant DOUBLE(double value) { - return AConstant.DOUBLE(value); - } - - /** Builds a STRING constant of given value. */ - public AConstant STRING(String value) { - return AConstant.STRING(value); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreeFromSTree.java b/sources/scalac/atree/ATreeFromSTree.java deleted file mode 100644 index 83e50eb7e1..0000000000 --- a/sources/scalac/atree/ATreeFromSTree.java +++ /dev/null @@ -1,553 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; - -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; - -/** This class translates syntax trees into attributed trees. */ -public class ATreeFromSTree { - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The attributed tree factory */ - private final ATreeFactory make; - - /** A mapping from primitive classes to initialization state */ - private final Map/*<Symbol,Boolean>*/ states; - - /** A mapping from primitive methods to generators */ - private final Map/*<Symbol,Generator>*/ generators; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ATreeFromSTree(Definitions definitions) { - this.definitions = definitions; - this.make = new ATreeFactory(); - this.states = new HashMap(); - this.generators = new HashMap(); - Symbol[] classes = { - definitions.ANY_CLASS, - definitions.OBJECT_CLASS, - definitions.STRING_CLASS, - definitions.THROWABLE_CLASS, - definitions.ARRAY_CLASS, - definitions.UNIT_CLASS, - definitions.BOOLEAN_CLASS, - definitions.BYTE_CLASS, - definitions.SHORT_CLASS, - definitions.CHAR_CLASS, - definitions.INT_CLASS, - definitions.LONG_CLASS, - definitions.FLOAT_CLASS, - definitions.DOUBLE_CLASS, - }; - for (int i = 0; i < classes.length; i++) - states.put(classes[i], Boolean.FALSE); - } - - //######################################################################## - // Public Methods - Translating units - - /** Translates the unit's body and stores the result in it. */ - public void translate(CompilationUnit unit) { - template(unit.repository = new ARepository(), unit.body); - } - - //######################################################################## - // Private Methods - Translating templates - - /** Translates the templates and adds them to the repository. */ - private void template(ARepository repository, Tree[] trees) { - for (int i = 0; i < trees.length; i++) template(repository, trees[i]); - } - - /** Translates the template and adds it to the repository. */ - private void template(ARepository repository, Tree tree) { - switch (tree) { - - case Empty: - return; - - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - AClass clasz = new AClass(tree.symbol()); - // !!! add static field to global modules - repository.addClass(clasz); - member(clasz, body); - return; - - case PackageDef(_, Template(_, Tree[] body)): - template(repository, body); - return; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Translating members - - /** Translates the members and adds them to the class. */ - private void member(AClass clasz, Tree[] trees) { - for (int i = 0; i < trees.length; i++) member(clasz, trees[i]); - } - - /** Translates the member and adds it to the class. */ - private void member(AClass clasz, Tree tree) { - switch (tree) { - - case Empty: - return; - - case ClassDef(_, _, _, _, _, _): - template(clasz, tree); - return; - - case ValDef(_, _, _, Tree rhs): - AField field = new AField(tree.symbol(), false); - clasz.addField(field); - return; - - case DefDef(_, _, _, _, _, Tree rhs): - AMethod method = new AMethod(tree.symbol(), false); - clasz.addMethod(method); - if (!method.isAbstract()) method.setCode(expression(rhs)); - return; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Translating statements - - /** Translates the statements. */ - private ACode[] statement(List locals, Tree[] trees) { - List codes = new ArrayList(); - for (int i = 0; i < trees.length; i++) { - ACode code = statement(locals, trees[i]); - if (code != ACode.Void) codes.add(code); - } - return (ACode[])codes.toArray(new ACode[codes.size()]); - } - - /** Translates the statement. */ - private ACode statement(List locals, Tree tree) { - switch (tree) { - - case Empty: - return make.Void; - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = tree.symbol(); - locals.add(symbol); - ALocation location = ALocation.Local(symbol, false); - return make.Store(tree, location, expression(rhs)); - - default: - return ACode.Drop(expression(tree), tree.type()); - } - } - - //######################################################################## - // Private Methods - Translating expressions - - /** Translates the expressions. */ - private ACode[] expression(Tree[] trees) { - ACode[] codes = new ACode[trees.length]; - for (int i = 0; i < codes.length; i++) codes[i] = expression(trees[i]); - return codes; - } - - /** Translates the expression. */ - private ACode expression(Tree tree) { - switch (tree) { - - case LabelDef(_, Ident[] idents, Tree rhs): - Symbol[] locals = Tree.symbolOf(idents); - return make.Label(tree, tree.symbol(), locals, expression(rhs)); - - case Block(Tree[] stats, Tree value): - List locals = new ArrayList(); - ACode[] codes = statement(locals, stats); - ACode code = expression(value); - if (locals.size() == 0 && codes.length == 0) return code; - Symbol[] symbols = - (Symbol[])locals.toArray(new Symbol[locals.size()]); - return make.Block(tree, symbols, codes, code); - - case Assign(Tree lhs, Tree rhs): - return make.Block(tree, Symbol.EMPTY_ARRAY, new ACode[] { - make.Store(tree, location(lhs), expression(rhs))}, - make.Void); - - case If(Tree cond, Tree thenp, Tree elsep): - ACode test = expression(cond); - return make.If(tree, test, expression(thenp), expression(elsep)); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - int[][] tagss = new int[tags.length][]; - for (int i = 0; i < tagss.length; i++) - tagss[i] = new int[] {tags[i]}; - ACode[] codes = new ACode[bodies.length + 1]; - for (int i = 0; i < bodies.length; i++) - codes[i] = expression(bodies[i]); - codes[tags.length] = expression(otherwise); - return make.Switch(tree, expression(test), tagss, codes); - - case Return(Tree value): - return make.Return(tree, tree.symbol(), expression(value)); - - case Throw(Tree value): - return make.Throw(tree, expression(value)); - - case New(Apply(Tree fun, Tree[] vargs)): - switch (fun) { - case Select(Create(_, Tree[] targs), _): - return apply(tree, fun, targs, vargs); - default: - throw Debug.abort("illegal case", tree); - } - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - return apply(tree, fun, targs, vargs); - case Apply(Tree fun, Tree[] vargs): - return apply(tree, fun, Tree.EMPTY_ARRAY, vargs); - - case Super(_, _): - case This(_): - return make.This(tree, tree.symbol()); - - case Select(_, _): - case Ident(_): - return make.Load(tree, location(tree)); - - case Literal(AConstant value): - return make.Constant(tree, value); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Translates the application. */ - private ACode apply(Tree tree, Tree fun, Tree[] targs, Tree[] vargs) { - Symbol symbol = fun.symbol(); - ACode[] codes = expression(vargs); - if (symbol.isLabel()) return make.Goto(tree, symbol, codes); - Type[] types = Tree.typeOf(targs); - AFunction function = function(fun); - switch (function) { - case Method(ACode object, Symbol method, AInvokeStyle style): - if (!style.isDynamic()) break; - Symbol clasz = method.owner(); - Object state = states.get(clasz); - if (state == null) break; - if (state != Boolean.TRUE) addGeneratorsOf(clasz); - Object generator = generators.get(method); - if (generator == null) break; - return generate((Generator)generator, tree, object, types, vargs); - } - return make.Apply(tree, function, types, codes); - } - - //######################################################################## - // Private Methods - Translating functions - - /** Translates the method. */ - private AFunction function(Tree tree) { - Symbol symbol = tree.symbol(); - switch (tree) { - - case Select(Create(_, _), _): - AInvokeStyle style = AInvokeStyle.New; - return AFunction.Method(make.Void, symbol, style); - - case Select(Tree qualifier, _): - AInvokeStyle style = invokeStyle(qualifier); - return AFunction.Method(expression(qualifier), symbol, style); - - case Ident(_): - AInvokeStyle style = AInvokeStyle.StaticClass; - return AFunction.Method(make.Void, symbol, style); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Returns the InvokeStyle to use for the qualifier. */ - private AInvokeStyle invokeStyle(Tree qualifier) { - switch (qualifier) { - case Super(_, _): - return AInvokeStyle.StaticInstance; - default: - return AInvokeStyle.Dynamic; - } - } - - //######################################################################## - // Private Methods - Translating locations - - /** Translates the location. */ - private ALocation location(Tree tree) { - Symbol symbol = tree.symbol(); - switch (tree) { - - case Select(Tree qualifier, _): - return ALocation.Field(expression(qualifier), symbol, false); - - case Ident(_): - if (symbol.isModule()) return ALocation.Module(symbol); - return symbol.owner().isClass() - ? ALocation.Field(make.Void, symbol, true) - : ALocation.Local(symbol, symbol.isParameter()); - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Translating constants - - /** Translates the constant. */ - private AConstant constant(Object value) { - if (value instanceof Boolean ) return make.BOOLEAN((Boolean )value); - if (value instanceof Byte ) return make.BYTE (((Byte )value)); - if (value instanceof Short ) return make.SHORT ((Short )value); - if (value instanceof Character) return make.CHAR ((Character)value); - if (value instanceof Integer ) return make.INT ((Integer )value); - if (value instanceof Long ) return make.LONG ((Long )value); - if (value instanceof Float ) return make.FLOAT ((Float )value); - if (value instanceof Double ) return make.DOUBLE ((Double )value); - if (value instanceof String ) return make.STRING ((String )value); - throw Debug.abort("illegal constant", value +" -- "+ value.getClass()); - } - - //######################################################################## - // Private Methods - Generating code for primitive methods - - /** Applies generator to given object and arguments. */ - private ACode generate(Generator generator, Tree tree, ACode object, - Type[] targs, Tree[] vargs) - { - switch (generator) { - - case ANYID: - assert targs.length == 0 && vargs.length == 1: tree; - return make.EQ(tree, ATypeKind.REF, object, expression(vargs[0])); - - case ANYNI: - assert targs.length == 0 && vargs.length == 1: tree; - return make.NE(tree, ATypeKind.REF, object, expression(vargs[0])); - - case ANYEQ: - Symbol lf = newLocal(tree, definitions.ANY_TYPE()); - Symbol rg = newLocal(tree, definitions.ANY_TYPE()); - return make.Block(tree, - new Symbol[] {lf, rg}, - new ACode[] { - store(tree, lf, object), - store(tree, rg, expression(vargs[0]))}, - make.If(tree, - make.EQ(tree, ATypeKind.REF, load(tree, lf)), - make.EQ(tree, ATypeKind.REF, load(tree, rg)), - make.Apply(tree, - AFunction.Method( - load(tree, lf), - definitions.ANY_EQUALS, - AInvokeStyle.Dynamic), - Type.EMPTY_ARRAY, - new ACode[] {load(tree, rg)}))); - - case ANYNE: - Symbol lf = newLocal(tree, definitions.ANY_TYPE()); - Symbol rg = newLocal(tree, definitions.ANY_TYPE()); - return make.Block(tree, - new Symbol[] {lf, rg}, - new ACode[] { - store(tree, lf, object), - store(tree, rg, expression(vargs[0]))}, - make.If(tree, - make.EQ(tree, ATypeKind.REF, load(tree, lf)), - make.NE(tree, ATypeKind.REF, load(tree, rg)), - make.NOT(tree, - ATypeKind.BOOL, - make.Apply(tree, - AFunction.Method( - load(tree, lf), - definitions.ANY_EQUALS, - AInvokeStyle.Dynamic), - Type.EMPTY_ARRAY, - new ACode[] {load(tree, rg)})))); - - case ISAS(boolean cast): - assert targs.length == 1 && vargs.length == 0: tree; - return make.IsAs(tree, object, targs[0], cast); - - case SYNCHRONIZED: - assert targs.length == 1 && vargs.length == 1: tree; - return make.Synchronized(tree, object, expression(vargs[0])); - - case THROW: - assert targs.length == 0 && vargs.length == 0: tree; - return make.Throw(tree, object); - - case CONCAT(ATypeKind prefix): - assert targs.length == 0 && vargs.length == 1: tree; - ATypeKind suffix = kind(vargs[0].type()); - ACode argument = expression(vargs[0]); - return make.CONCAT(tree, prefix, suffix, object, argument); - - default: - throw Debug.abort("unknown case", generator); - } - } - - /** Generates a load operation with given variable. */ - private ACode load(Tree tree, Symbol local) { - assert local.owner().isNone(): Debug.show(local); - return make.Load(tree, ALocation.Local(local, false)); - } - - /** Generates a store operation with given variable and value. */ - private ACode store(Tree tree, Symbol local, ACode value) { - assert local.owner().isNone(): Debug.show(local); - return make.Store(tree, ALocation.Local(local, false), value); - } - - /** Creates a variable with tree's position and given type. */ - private Symbol newLocal(Tree tree, Type type) { - Symbol owner = Symbol.NONE; // !!! - Name name = Name.fromString("local"); // !!! - return owner.newTerm(tree.pos, 0, name).setType(type); - } - - /** Returns the type kind of given type. */ - private ATypeKind kind(Type type) { - switch (type) { - case SingleType(_, _): - case ConstantType(_, _): - return kind(type.singleDeref()); - case TypeRef(_, Symbol clasz, _): - if (clasz == definitions.BOOLEAN_CLASS) return ATypeKind.BOOL; - if (clasz == definitions.BYTE_CLASS) return ATypeKind.I1; - if (clasz == definitions.SHORT_CLASS) return ATypeKind.I2; - if (clasz == definitions.CHAR_CLASS) return ATypeKind.U2; - if (clasz == definitions.INT_CLASS) return ATypeKind.I4; - if (clasz == definitions.LONG_CLASS) return ATypeKind.I8; - if (clasz == definitions.FLOAT_CLASS) return ATypeKind.R4; - if (clasz == definitions.DOUBLE_CLASS) return ATypeKind.R8; - if (clasz == definitions.STRING_CLASS) return ATypeKind.STR; - return ATypeKind.REF; - default: - return ATypeKind.REF; - } - } - - //######################################################################## - // Private Methods - Collecting primitive methods - - /** Associates generators to primitive methods of given class. */ - private void addGeneratorsOf(Symbol clasz) { - if (clasz == definitions.ANY_CLASS) { - addGenerator(definitions.ANY_EQEQ, Generator.ANYEQ); - addGenerator(definitions.ANY_BANGEQ, Generator.ANYNE); - addGenerator(definitions.ANY_IS_ERASED, Generator.ISAS(false)); - addGenerator(definitions.ANY_AS_ERASED, Generator.ISAS(true)); - } - if (clasz == definitions.OBJECT_CLASS) { - addGenerator(definitions.OBJECT_EQ, Generator.ANYID); - addGenerator(definitions.OBJECT_NE, Generator.ANYNI); - addGenerator(definitions.OBJECT_SYNCHRONIZED, Generator.SYNCHRONIZED); - } - if (clasz == definitions.STRING_CLASS) { - addGenerator(definitions.STRING_PLUS, Generator.CONCAT(ATypeKind.STR)); - } - if (clasz == definitions.THROWABLE_CLASS) { - addGenerator(definitions.THROWABLE_THROW, Generator.THROW); - } - if (clasz == definitions.ARRAY_CLASS) { - // !!! addAll(defs.ARRAY_CLASS, Names.length, Primitive.LENGTH, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.apply, Primitive.APPLY, 2); - // !!! addAll(defs.ARRAY_CLASS, Names.update, Primitive.UPDATE, 1); - } - if (clasz == definitions.UNIT_CLASS) { - // !!! - } - if (clasz == definitions.BOOLEAN_CLASS) { - // !!! - } - if (clasz == definitions.BYTE_CLASS) { - // !!! - } - if (clasz == definitions.SHORT_CLASS) { - // !!! - } - if (clasz == definitions.CHAR_CLASS) { - // !!! - } - if (clasz == definitions.INT_CLASS) { - // !!! - } - if (clasz == definitions.LONG_CLASS) { - // !!! - } - if (clasz == definitions.FLOAT_CLASS) { - // !!! - } - if (clasz == definitions.DOUBLE_CLASS) { - // !!! - } - states.put(clasz, Boolean.TRUE); - } - - /** Associates given generator to given primitive method. */ - private void addGenerator(Symbol method, Generator generator) { - generators.put(method, generator); - } - - //######################################################################## - // Private Class - Code generators - - /** Code generators for primitive methods. */ - private static class Generator { - case ANYID; - case ANYNI; - case ANYEQ; - case ANYNE; - case ISAS(boolean cast); - case SYNCHRONIZED; - case THROW; - case CONCAT(ATypeKind prefix); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreePrinter.java b/sources/scalac/atree/ATreePrinter.java deleted file mode 100644 index fb0a108a99..0000000000 --- a/sources/scalac/atree/ATreePrinter.java +++ /dev/null @@ -1,557 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolTablePrinter; -import scalac.util.Debug; -import scalac.util.SourceRepresentation; - -/** This class provides methods to print attributed trees. */ -public class ATreePrinter { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The underlying code printer */ - private final CodePrinter printer; - - /** The underlying symbol table printer */ - private final SymbolTablePrinter symtab; - - //######################################################################## - // Public Constructors - - /** Initalizes this instance */ - public ATreePrinter() { - this(new CodePrinter()); - } - - /** Initalizes this instance */ - public ATreePrinter(String step) { - this(Global.instance, new CodePrinter(step)); - } - - /** Initalizes this instance */ - public ATreePrinter(CodePrinter printer) { - this(Global.instance, printer); - } - - /** Initalizes this instance */ - public ATreePrinter(Global global, CodePrinter printer) { - this.global = global; - this.printer = printer; - this.symtab = new SymbolTablePrinter(global, printer); - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** Returns the underlying code printer. */ - public CodePrinter getCodePrinter() { - return printer; - } - - //######################################################################## - // Public Methods - Formatting - - /** Increases the indentation level by one. */ - public ATreePrinter indent() { - printer.indent(); - return this; - } - - /** Decreases the indentation level by one. */ - public ATreePrinter undent() { - printer.undent(); - return this; - } - - /** Inserts a new line. */ - public ATreePrinter line() { - printer.line(); - return this; - } - - /** Inserts a white space. */ - public ATreePrinter space() { - printer.space(); - return this; - } - - /** Prints an opening brace followed by a new line. */ - public ATreePrinter lbrace() { - return space().println('{').indent(); - } - - /** Prints a closing brace followed by a new line. */ - public ATreePrinter rbrace() { - return undent().space().println('}'); - } - - //######################################################################## - // Public Methods - Printing simple values - - /** Prints a new line. */ - public ATreePrinter println() { - printer.println(); - return this; - } - - /** Prints the boolean value followed by a new line. */ - public ATreePrinter println(boolean value) { - printer.println(value); - return this; - } - - /** Prints the byte value followed by a new line. */ - public ATreePrinter println(byte value) { - printer.println(value); - return this; - } - - /** Prints the short value followed by a new line. */ - public ATreePrinter println(short value) { - printer.println(value); - return this; - } - - /** Prints the char value followed by a new line. */ - public ATreePrinter println(char value) { - printer.println(value); - return this; - } - - /** Prints the int value followed by a new line. */ - public ATreePrinter println(int value) { - printer.println(value); - return this; - } - - /** Prints the long value followed by a new line. */ - public ATreePrinter println(long value) { - printer.println(value); - return this; - } - - /** Prints the float value followed by a new line. */ - public ATreePrinter println(float value) { - printer.println(value); - return this; - } - - /** Prints the double value followed by a new line. */ - public ATreePrinter println(double value) { - printer.println(value); - return this; - } - - /** Prints the string followed by a new line. */ - public ATreePrinter println(String value) { - printer.println(value); - return this; - } - - /** Prints the boolean value. */ - public ATreePrinter print(boolean value) { - printer.print(value); - return this; - } - - /** Prints the byte value. */ - public ATreePrinter print(byte value) { - printer.print(value); - return this; - } - - /** Prints the short value. */ - public ATreePrinter print(short value) { - printer.print(value); - return this; - } - - /** Prints the char value. */ - public ATreePrinter print(char value) { - printer.print(value); - return this; - } - - /** Prints the int value. */ - public ATreePrinter print(int value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public ATreePrinter print(long value) { - printer.print(value); - return this; - } - - /** Prints the float value. */ - public ATreePrinter print(float value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public ATreePrinter print(double value) { - printer.print(value); - return this; - } - - /** Prints the string. */ - public ATreePrinter print(String value) { - printer.print(value); - return this; - } - - //######################################################################## - // Public Methods - Printing types and symbols - - /** Prints the symbol. */ - public ATreePrinter printSymbol(Symbol symbol) { - symtab.printSymbolName(symbol); - return this; - } - - /** Prints the type. */ - public ATreePrinter printType(Type type) { - symtab.printType(type); - return this; - } - - //######################################################################## - // Public Methods - Printing trees - - /** Prints the units. */ - public ATreePrinter printUnits(CompilationUnit[] units) { - Phase phase = global.currentPhase; - println("[[attributed trees at "+phase+" (after "+phase.prev+")]]"); - for (int i = 0; i < units.length; i++) printUnit(units[i]); - return this; - } - - /** Prints the unit. */ - public ATreePrinter printUnit(CompilationUnit unit) { - println("// Scala source: " + unit.source); - return printRepository(unit.repository); - } - - /** Prints the repository. */ - public ATreePrinter printRepository(ARepository repository) { - AClass[] classes = repository.classes(); - for (int i = 0; i < classes.length; i++) printClass(classes[i]); - return this; - } - - /** Prints the class. */ - public ATreePrinter printClass(AClass clasz) { - printClassModifiers(clasz); - print(clasz.isInterface() ? "interface" : "class").space(); - printSymbol(clasz.symbol()); - Symbol[] tparams = clasz.tparams(); - if (tparams.length != 0) symtab.printTypeParams(tparams); - Symbol[] vparams = clasz.vparams(); - if (vparams.length != 0) symtab.printValueParams(vparams); - if (clasz.symbol().typeOfThis() != clasz.symbol().thisType()) - space().print(':').printType(clasz.symbol().typeOfThis()); - space().print("extends").space(); - symtab.printTypes(clasz.parents()," with "); - lbrace(); - printRepository(clasz); - AField[] fields = clasz.fields(); - for (int i = 0; i < fields.length; i++) printField(fields[i]); - AMethod[] methods = clasz.methods(); - for (int i = 0; i < methods.length; i++) printMethod(methods[i]); - return rbrace(); - } - - /** Prints the class modifiers. */ - public ATreePrinter printClassModifiers(AClass clasz) { - if (clasz.isDeprecated()) print("deprecated").space(); - if (clasz.isSynthetic()) print("synthetic").space(); - if (clasz.isPublic()) print("public").space(); - if (clasz.isPrivate()) print("private").space(); - if (clasz.isProtected()) print("protected").space(); - if (clasz.isFinal()) print("final").space(); - if (clasz.isAbstract()) print("abstract").space(); - return this; - } - - /** Prints the member modifiers. */ - public ATreePrinter printMemberModifiers(AMember member) { - if (member.isDeprecated()) print("deprecated").space(); - if (member.isSynthetic()) print("synthetic").space(); - if (member.isPublic()) print("public").space(); - if (member.isPrivate()) print("private").space(); - if (member.isProtected()) print("protected").space(); - if (member.isStatic()) print("static").space(); - return this; - } - - /** Prints the member code. */ - public ATreePrinter printMemberCode(AMember member) { - if (member.code() == ACode.Void) return this; - return print('=').space().printCode(member.code()); - } - - /** Prints the field. */ - public ATreePrinter printField(AField field) { - printFieldModifiers(field); - symtab.printSignature(field.symbol()).space(); - return printMemberCode(field).line(); - } - - /** Prints the field modifiers. */ - public ATreePrinter printFieldModifiers(AField field) { - printMemberModifiers(field); - if (field.isFinal()) print("final").space(); - if (field.isVolatile()) print("volatile").space(); - if (field.isTransient()) print("transient").space(); - return this; - } - - /** Prints the method. */ - public ATreePrinter printMethod(AMethod method) { - printMethodModifiers(method); - symtab.printSignature(method.symbol()).space(); - return printMemberCode(method).line(); - } - - /** Prints the method modifiers. */ - public ATreePrinter printMethodModifiers(AMethod method) { - printMemberModifiers(method); - if (method.isFinal()) print("final").space(); - if (method.isSynchronized()) print("synchronized").space(); - if (method.isNative()) print("native").space(); - if (method.isAbstract()) print("abstract").space(); - return this; - } - - /** Prints the code. */ - public ATreePrinter printCode(ACode code) { - switch (code) { - case Void: - return print("<void>"); - case This(Symbol clasz): - return printSymbol(clasz).print('.').print("this"); - case Constant(AConstant constant): - return printConstant(constant); - case Load(ALocation location): - return printLocation(location); - case Store(ALocation location, ACode value): - printLocation(location).space().print('=').space(); - return printCode(value); - case Apply(AFunction function, Type[] targs, ACode[] vargs): - printFunction(function); - if (targs.length > 0){ - print('['); - for (int i = 0; i < targs.length; i++) - (i == 0 ? this : print(',').space()).printType(targs[i]); - print(']'); - } - print('('); - for (int i = 0; i < vargs.length; i++) - (i == 0 ? this : print(',').space()).printCode(vargs[i]); - print(')'); - return this; - case IsAs(ACode value, Type type, boolean cast): - printCode(value).print('.').print(cast ? "as" : "is"); - return print('[').printType(type).print(']'); - case If(ACode test, ACode success, ACode failure): - print("if").space().print('(').printCode(test).print(')').lbrace(); - printCode(success).line(); - rbrace().space().print("else").space().lbrace(); - printCode(failure).line(); - return rbrace(); - case Switch(ACode test, int[][] tags, ACode[] bodies): - print("switch").space().print('(').printCode(test).print(')'); - lbrace(); - for (int i = 0; i < tags.length; i++) { - for (int j = 0; j < tags[i].length; j++) - print("case").space().print(tags[i][j]).print(':').line(); - indent().printCode(bodies[i]).undent().line(); - } - print("case").space().print('_').print(':').line(); - indent().printCode(bodies[tags.length]).undent(); - return rbrace(); - case Synchronized(ACode lock, ACode value): - print("synchronized").space(); - print('(').printCode(lock).print(')'); - return lbrace().printCode(value).rbrace(); - case Block(Symbol[] locals, ACode[] statements, ACode value): - lbrace(); - for (int i = 0; i < locals.length; i++) { - print("var").space().printSymbol(locals[i]); - print(":").space().printType(locals[i].type()); - println(";"); - } - for (int i = 0; i < statements.length; i++) - printCode(statements[i]).println(';'); - return printCode(value).line().rbrace(); - case Label(Symbol label, Symbol[] locals, ACode value): - print("label").space().printSymbol(label).print('('); - for (int i = 0; i < locals.length; i++) - (i == 0 ? this : print(',').space()).printSymbol(locals[i]); - print(')').space().print('=').lbrace(); - return printCode(value).rbrace(); - case Goto(Symbol label, ACode[] vargs): - print("goto").space().printSymbol(label).print('('); - for (int i = 0; i < vargs.length; i++) - (i == 0 ? this : print(',').space()).printCode(vargs[i]); - return print(')'); - case Return(Symbol function, ACode value): - print("return").symtab.printSymbolUniqueId(function).space(); - return printCode(value); - case Throw(ACode value): - return print("throw").space().printCode(value); - case Drop(ACode value, Type type): - print("drop").print('[').printType(type).print(']').space(); - return printCode(value); - default: - throw Debug.abort("unknown case", code); - } - } - - /** Prints the location. */ - public ATreePrinter printLocation(ALocation location) { - switch (location) { - case Module(Symbol module): - return printSymbol(module); - case Field(Void, Symbol field, true): - return printSymbol(field.owner()).print('.').printSymbol(field); - case Field(ACode object, Symbol field, boolean isStatic): - printCode(object).print('.'); - if (isStatic) print("<static>").space(); - return printSymbol(field); - case Local(Symbol local, _): - return printSymbol(local); - case ArrayItem(ACode array, ACode index): - return printCode(array).print('(').printCode(index).print(')'); - default: - throw Debug.abort("unknown case", location); - } - } - - /** Prints the function. */ - public ATreePrinter printFunction(AFunction function) { - switch (function) { - case Method(Void, Symbol method, AInvokeStyle.New): - return print("new").space().printSymbol(method); - case Method(Void, Symbol method, AInvokeStyle.Static(false)): - return printSymbol(method.owner()).print('.').printSymbol(method); - case Method(This(Symbol c), Symbol method, AInvokeStyle.Static(true)): - printSymbol(c).print('.').print("super").print('.'); - return printSymbol(method); - case Method(ACode object, Symbol method, AInvokeStyle style): - printCode(object).print('.'); - if (style != AInvokeStyle.Dynamic) print("<" +style+ ">").space(); - return printSymbol(method); - case Primitive(APrimitive primitive): - return printPrimitive(primitive); - case NewArray(Type element): - return print("new").space().printType(element).print("[]"); - default: - throw Debug.abort("unknown case", function); - } - } - - /** Prints the primitive. */ - public ATreePrinter printPrimitive(APrimitive primitive) { - switch (primitive) { - case Negation(ATypeKind kind): - return printPrimitiveOp("NEG", kind); - case Test(ATestOp op, ATypeKind kind, boolean zero): - return printPrimitiveOp(op.toString() + (zero ? "Z" : ""), kind); - case Comparison(AComparisonOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Arithmetic(AArithmeticOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Logical(ALogicalOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Shift(AShiftOp op, ATypeKind kind): - return printPrimitiveOp(op.toString(), kind); - case Conversion(ATypeKind src, ATypeKind dst): - return printPrimitiveOp("CONV", src, dst); - case ArrayLength(ATypeKind kind): - return printPrimitiveOp("LENGTH", kind); - case StringConcat(ATypeKind lf, ATypeKind rg): - return printPrimitiveOp("CONCAT", lf, rg); - default: - throw Debug.abort("unknown case", primitive); - } - } - - /** Prints the primitive operation of given type kind. */ - public ATreePrinter printPrimitiveOp(String op, ATypeKind kind) { - return printPrimitiveOp(op, kind, null); - } - - /** Prints the primitive operation of given types. */ - public ATreePrinter printPrimitiveOp(String op, ATypeKind k1,ATypeKind k2){ - print('<').print(op).print('>'); - if (k1 != null && global.uniqid) print('#').print(k1.toString()); - if (k2 != null && global.uniqid) print(',').print(k2.toString()); - return this; - } - - /** Prints the constant. */ - public ATreePrinter printConstant(AConstant constant) { - switch (constant) { - case UNIT: - return print("()"); - case BOOLEAN(boolean value): - return print(value); - case BYTE(byte value): - return print(value); - case SHORT(short value): - return print(value); - case CHAR(char value): - return print('\'').print(value).print('\''); - case INT(int value): - return print(value); - case LONG(long value): - return print(value); - case FLOAT(float value): - return print(value); - case DOUBLE(double value): - return print(value); - case STRING(String value): - return print('\"').print(SourceRepresentation.escape(value)).print('\"'); - case SYMBOL_NAME(Symbol value): - return print('\"').print(SourceRepresentation.escape(value.name.toString())).print('\"'); - case NULL: - return print("null"); - case ZERO: - return print("<zero>"); - default: - throw Debug.abort("unknown case", constant); - } - } - - //######################################################################## - // Public Methods - Converting - - /** Returns the string representation of this printer. */ - public String toString() { - return printer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATreeTyper.java b/sources/scalac/atree/ATreeTyper.java deleted file mode 100644 index 06133db15f..0000000000 --- a/sources/scalac/atree/ATreeTyper.java +++ /dev/null @@ -1,314 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.symtab.Definitions; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; - -/** This class implements an attributed tree typer. */ -public class ATreeTyper { - - //######################################################################## - // Private Fields - - /** The global environment */ - public final Global global; - - /** The global definitions */ - private final Definitions definitions; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ATreeTyper(Global global, Definitions definitions) { - this.global = global; - this.definitions = definitions; - } - - //######################################################################## - // Public Methods - Typing code - - /** Returns the types of the given codes. */ - public Type[] type(ACode[] codes) { - Type[] types = new Type[codes.length]; - for (int i = 0; i < types.length; i++) types[i] = type(codes[i]); - return types; - } - - /** Returns the type of the given code. */ - public Type type(ACode code) { - switch (code) { - case Void: - return definitions.void_TYPE(); - case This(Symbol clasz): - return clasz.thisType(); - case Constant(AConstant constant): - return type(constant); - case Load(ALocation location): - return type(location); - case Store(_, _): - return Type.NoType; - case Apply(AFunction function, Type[] targs, _): - return apply(type(function), targs).resultType(); - case IsAs(_, Type type, boolean cast): - return cast ? type : definitions.boolean_TYPE(); - case If(_, ACode success, ACode failure): - return Type.lub(new Type[]{type(success), type(failure)}); - case Switch(_, _, ACode[] bodies): - return Type.lub(type(bodies)); - case Synchronized(_, ACode value): - return type(value); - case Block(_, _, ACode value): - return type(value); - case Label(Symbol label, _, _): - return label.type().resultType(); - case Goto(_, _): - return Type.NoType; - case Return(_, _): - return Type.NoType; - case Throw(_): - return Type.NoType; - case Drop(_, _): - return Type.NoType; - default: - throw Debug.abort("unknown case", code); - } - } - - //######################################################################## - // Public Methods - Typing value locations - - /** Returns the type of the given value location. */ - public Type type(ALocation location) { - switch (location) { - case Module(Symbol module): - return module.thisType(); - case Field(Void, Symbol field, _): - return field.owner().thisType().memberStabilizedType(field); - case Field(ACode object, Symbol field, _): - return type(object).memberStabilizedType(field); - case Local(Symbol local, _): - return local.type(); - case ArrayItem(ACode array, _): - return getArrayElementType(type(array)); - default: - throw Debug.abort("unknown case", location); - } - } - - //######################################################################## - // Public Methods - Typing function references - - /** Returns the type of the given function reference. */ - public Type type(AFunction function) { - switch (function) { - case Method(Void, Symbol method, AInvokeStyle style): - Type type = method.owner().thisType().memberStabilizedType(method); - if (style == AInvokeStyle.New) { - assert method.isInitializer(): function; - Symbol[] tparams = method.owner().typeParams(); - if (tparams.length != 0) type = Type.PolyType(tparams, type); - } - return type; - case Method(ACode object, Symbol method, _): - return type(object).memberStabilizedType(method); - case Primitive(APrimitive primitive): - return type(primitive); - case NewArray(Type element): - return definitions.array_TYPE(element); - default: - throw Debug.abort("unknown case", function); - } - } - - //######################################################################## - // Public Methods - Typing primitives - - /** Returns the type of the given primitive. */ - public Type type(APrimitive primitive) { - switch (primitive) { - case Negation(ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type); - case Test(_, ATypeKind kind, true): - Type type = type(kind); - return getMethodType(type, type(ATypeKind.BOOL)); - case Test(_, ATypeKind kind, false): - Type type = type(kind); - return getMethodType(type, type, type(ATypeKind.BOOL)); - case Comparison(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type, type(ATypeKind.I4)); - case Arithmetic(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type, type); - case Logical(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type, type); - case Shift(_, ATypeKind kind): - Type type = type(kind); - return getMethodType(type, type(ATypeKind.I4), type); - case Conversion(ATypeKind src, ATypeKind dst): - return getMethodType(type(src), type(dst)); - case ArrayLength(ATypeKind kind): - Type type = definitions.array_TYPE(type(kind)); - return getMethodType(type, type(ATypeKind.I4)); - case StringConcat(ATypeKind lf, ATypeKind rg): - return getMethodType(type(lf), type(rg), type(ATypeKind.STR)); - default: - throw Debug.abort("unknown case", primitive); - } - } - - //######################################################################## - // Public Methods - Typing constants - - /** Returns the type of the given constant. */ - public Type type(AConstant constant) { - Type base = basetype(constant); - if (global.currentPhase.id > global.PHASE.ERASURE.id()) return base; - return Type.ConstantType(base, constant); - } - - /** Returns the base type of the given constant. */ - public Type basetype(AConstant constant) { - switch (constant) { - case UNIT : return definitions.void_TYPE(); // !!! -> UNIT_TYPE() - case BOOLEAN(_): return definitions.boolean_TYPE(); - case BYTE(_) : return definitions.byte_TYPE(); - case SHORT(_) : return definitions.short_TYPE(); - case CHAR(_) : return definitions.char_TYPE(); - case INT(_) : return definitions.int_TYPE(); - case LONG(_) : return definitions.long_TYPE(); - case FLOAT(_) : return definitions.float_TYPE(); - case DOUBLE(_) : return definitions.double_TYPE(); - case SYMBOL_NAME(_): - case STRING(_) : return definitions.STRING_TYPE(); - case NULL : return definitions.ALLREF_TYPE(); - case ZERO : return definitions.ALL_TYPE(); - default : throw Debug.abort("unknown case", constant); - } - } - - //######################################################################## - // Public Methods - Typing type kinds - - /** Returns the type of the given type kind. */ - public Type type(ATypeKind kind) { - switch (kind) { - case UNIT: return definitions.void_TYPE(); // !!! -> UNIT_TYPE() - case BOOL: return definitions.boolean_TYPE(); - // !!! case U1 : return ?; - case U2 : return definitions.char_TYPE(); - // !!! case U4 : return ?; - // !!! case U8 : return ?; - case I1 : return definitions.byte_TYPE(); - case I2 : return definitions.short_TYPE(); - case I4 : return definitions.int_TYPE(); - case I8 : return definitions.long_TYPE(); - case R4 : return definitions.float_TYPE(); - case R8 : return definitions.double_TYPE(); - case REF : return definitions.ANYREF_TYPE(); - case STR : return definitions.STRING_TYPE(); - case NULL: return definitions.ALLREF_TYPE(); - case ZERO: return definitions.ALL_TYPE(); - default : throw Debug.abort("unknown case", kind); - } - } - - //######################################################################## - // Public Methods - Aliases for scala - - public Type[] computeType(ACode[] codes) { - return type(codes); - } - - public Type computeType(ACode code) { - return type(code); - } - - public Type computeType(ALocation location) { - return type(location); - } - - public Type computeType(AFunction function) { - return type(function); - } - - public Type computeType(APrimitive primitive) { - return type(primitive); - } - - public Type computeType(AConstant constant) { - return type(constant); - } - - public Type computeType(ATypeKind kind) { - return type(kind); - } - - //######################################################################## - // Private Methods - - /** Returns the application of given arguments to given type. */ - private Type apply(Type type, Type[] targs) { - switch (type) { - case PolyType(Symbol[] tparams, Type result): - return result.subst(tparams, targs); - default: - assert targs.length == 0: type + " -- " + Debug.show(targs); - return type; - } - } - - /** Returns the element type of the given array type. */ - public Type getArrayElementType(Type type) { // !!! public / private - switch (type) { - case TypeRef(_, Symbol symbol, Type[] args): - assert symbol == definitions.ARRAY_CLASS && args.length == 1: type; - return args[0]; - case UnboxedArrayType(Type element): - return element; - default: - throw Debug.abort("non-array type", type); - } - } - - /** Returns a method type with given argument and result types. */ - private Type getMethodType(Type targ1, Type result) { - return getMethodType(new Type[]{targ1}, result); - } - - /** Returns a method type with given argument and result types. */ - private Type getMethodType(Type targ1, Type targ2, Type result) { - return getMethodType(new Type[]{targ1, targ2}, result); - } - - /** Returns a method type with given argument and result types. */ - private Type getMethodType(Type[] targs, Type result) { - Symbol[] tparams = new Symbol[targs.length]; - for (int i = 0; i < tparams.length; i++) { - Name name = Name.fromString("v" + i); - tparams[i] = Symbol.NONE.newTerm( // !!! should be newVParam - Position.NOPOS, Modifiers.PARAM, name); - tparams[i].setType(targs[i]); - } - return Type.MethodType(tparams, result); - } - - //######################################################################## -} diff --git a/sources/scalac/atree/ATypeKind.java b/sources/scalac/atree/ATypeKind.java deleted file mode 100644 index 1be2eb540d..0000000000 --- a/sources/scalac/atree/ATypeKind.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.atree; - -import scalac.util.Debug; - -/** This class represents a type kind. */ -public class ATypeKind { - - //######################################################################## - // Public Cases - - /** The unit value */ - public case UNIT; - - /** A boolean value */ - public case BOOL; - - /** A 1-byte unsigned integer */ - public case U1; - - /** A 2-byte unsigned integer */ - public case U2; - - /** A 4-byte unsigned integer */ - public case U4; - - /** An 8-byte unsigned integer */ - public case U8; - - /** A 1-byte signed integer */ - public case I1; - - /** A 2-byte signed integer */ - public case I2; - - /** A 4-byte signed integer */ - public case I4; - - /** An 8-byte signed integer */ - public case I8; - - /** A 4-byte floating point number */ - public case R4; - - /** An 8-byte floating point number */ - public case R8; - - /** An object reference */ - public case REF; - - /** A string reference */ - public case STR; - - /** The null reference */ - public case NULL; - - /** The zero value */ - public case ZERO; - - //######################################################################## - // Public Methods - - /** Returns a string representation of this type kind. */ - public String toString() { - switch (this) { - case UNIT: return "UNIT"; - case BOOL: return "BOOL"; - case U1 : return "U1"; - case U2 : return "U2"; - case U4 : return "U4"; - case U8 : return "U8"; - case I1 : return "I1"; - case I2 : return "I2"; - case I4 : return "I4"; - case I8 : return "I8"; - case R4 : return "R4"; - case R8 : return "R8"; - case REF : return "REF"; - case STR : return "STR"; - case NULL: return "NULL"; - case ZERO: return "ZERO"; - default : throw Debug.abort("unknown case", this); - } - } - - //######################################################################## -} diff --git a/sources/scalac/backend/Primitive.java b/sources/scalac/backend/Primitive.java deleted file mode 100644 index 2c55a68dc8..0000000000 --- a/sources/scalac/backend/Primitive.java +++ /dev/null @@ -1,205 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// Old$Id$ -// $Id$ - -package scalac.backend; - -import scalac.util.Debug; - -/** - * Primitive functions. - * - * @author Michel Schinz, Philippe Altherr - * @version 1.0 - */ - -public class Primitive { - - // Non-primitive operations - public case NOT_A_PRIMITIVE; // not a primitive - - // Arithmetic unary operations - public case POS; // +x - public case NEG; // -x - public case NOT; // ~x - - // Arithmetic binary operations - public case ADD; // x + y - public case SUB; // x - y - public case MUL; // x * y - public case DIV; // x / y - public case MOD; // x % y - - // Bitwise operations - public case OR; // x | y - public case XOR; // x ^ y - public case AND; // x & y - - // Shift operations - public case LSL; // x << y - public case LSR; // x >>> y - public case ASR; // x >> y - - // Comparison operations - public case ID; // x eq y - public case NI; // x ne y - public case EQ; // x == y - public case NE; // x != y - public case LT; // x < y - public case LE; // x <= y - public case GE; // x > y - public case GT; // x >= y - - // Boolean unary operations - public case ZNOT; // !x - - // Boolean binary operations - public case ZOR; // x || y - public case ZAND; // x && y - - // Array operations - public case LENGTH; // x.length - public case APPLY; // x(y) - public case UPDATE; // x(y) = z - - // Any operations - public case IS; // x.is[y] - public case AS; // x.as[y] - public case EQUALS; // x.equals(y) - public case HASHCODE; // x.hashcode() - public case TOSTRING; // x.toString() - - // AnyRef operations - public case SYNCHRONIZED; // x.synchronized(y) - - // String operations - public case CONCAT; // String.valueOf(x)+String.valueOf(y) - - // Throwable operations - public case THROW; // throw x - - // Value types conversions - public case COERCE; // x.coerce() - - // RunTime operations - public case BOX; // RunTime.box_<X>(x) - public case UNBOX; // RunTime.unbox_<X>(x) - public case NEW_ZARRAY; // RunTime.zarray(x) - public case NEW_BARRAY; // RunTime.barray(x) - public case NEW_SARRAY; // RunTime.sarray(x) - public case NEW_CARRAY; // RunTime.carray(x) - public case NEW_IARRAY; // RunTime.iarray(x) - public case NEW_LARRAY; // RunTime.larray(x) - public case NEW_FARRAY; // RunTime.farray(x) - public case NEW_DARRAY; // RunTime.darray(x) - public case NEW_OARRAY; // RunTime.oarray(x) - public case ZARRAY_LENGTH; // RunTime.zarray_length(x) - public case BARRAY_LENGTH; // RunTime.barray_length(x) - public case SARRAY_LENGTH; // RunTime.sarray_length(x) - public case CARRAY_LENGTH; // RunTime.carray_length(x) - public case IARRAY_LENGTH; // RunTime.iarray_length(x) - public case LARRAY_LENGTH; // RunTime.larray_length(x) - public case FARRAY_LENGTH; // RunTime.farray_length(x) - public case DARRAY_LENGTH; // RunTime.darray_length(x) - public case OARRAY_LENGTH; // RunTime.oarray_length(x) - public case ZARRAY_GET; // RunTime.zarray_get(x,y) - public case BARRAY_GET; // RunTime.barray_get(x,y) - public case SARRAY_GET; // RunTime.sarray_get(x,y) - public case CARRAY_GET; // RunTime.carray_get(x,y) - public case IARRAY_GET; // RunTime.iarray_get(x,y) - public case LARRAY_GET; // RunTime.larray_get(x,y) - public case FARRAY_GET; // RunTime.farray_get(x,y) - public case DARRAY_GET; // RunTime.darray_get(x,y) - public case OARRAY_GET; // RunTime.oarray_get(x,y) - public case ZARRAY_SET; // RunTime.zarray(x,y,z) - public case BARRAY_SET; // RunTime.barray(x,y,z) - public case SARRAY_SET; // RunTime.sarray(x,y,z) - public case CARRAY_SET; // RunTime.carray(x,y,z) - public case IARRAY_SET; // RunTime.iarray(x,y,z) - public case LARRAY_SET; // RunTime.larray(x,y,z) - public case FARRAY_SET; // RunTime.farray(x,y,z) - public case DARRAY_SET; // RunTime.darray(x,y,z) - public case OARRAY_SET; // RunTime.oarray(x,y,z) - - public case B2B; // RunTime.b2b(x) - public case B2S; // RunTime.b2s(x) - public case B2C; // RunTime.b2c(x) - public case B2I; // RunTime.b2i(x) - public case B2L; // RunTime.b2l(x) - public case B2F; // RunTime.b2f(x) - public case B2D; // RunTime.b2d(x) - public case S2B; // RunTime.s2b(x) - public case S2S; // RunTime.s2s(x) - public case S2C; // RunTime.s2c(x) - public case S2I; // RunTime.s2i(x) - public case S2L; // RunTime.s2l(x) - public case S2F; // RunTime.s2f(x) - public case S2D; // RunTime.s2d(x) - public case C2B; // RunTime.c2b(x) - public case C2S; // RunTime.c2s(x) - public case C2C; // RunTime.c2c(x) - public case C2I; // RunTime.c2i(x) - public case C2L; // RunTime.c2l(x) - public case C2F; // RunTime.c2f(x) - public case C2D; // RunTime.c2d(x) - public case I2B; // RunTime.i2b(x) - public case I2S; // RunTime.i2s(x) - public case I2C; // RunTime.i2c(x) - public case I2I; // RunTime.i2i(x) - public case I2L; // RunTime.i2l(x) - public case I2F; // RunTime.i2f(x) - public case I2D; // RunTime.i2d(x) - public case L2B; // RunTime.l2b(x) - public case L2S; // RunTime.l2s(x) - public case L2C; // RunTime.l2c(x) - public case L2I; // RunTime.l2i(x) - public case L2L; // RunTime.l2l(x) - public case L2F; // RunTime.l2f(x) - public case L2D; // RunTime.l2d(x) - public case F2B; // RunTime.f2b(x) - public case F2S; // RunTime.f2s(x) - public case F2C; // RunTime.f2c(x) - public case F2I; // RunTime.f2i(x) - public case F2L; // RunTime.f2l(x) - public case F2F; // RunTime.f2f(x) - public case F2D; // RunTime.f2d(x) - public case D2B; // RunTime.d2b(x) - public case D2S; // RunTime.d2s(x) - public case D2C; // RunTime.d2c(x) - public case D2I; // RunTime.d2i(x) - public case D2L; // RunTime.d2l(x) - public case D2F; // RunTime.d2f(x) - public case D2D; // RunTime.d2d(x) - - /** Return negated version of comparison primitive. */ - public Primitive negate() { - switch (this) { - case LT: return Primitive.GE; - case LE: return Primitive.GT; - case EQ: return Primitive.NE; - case NE: return Primitive.EQ; - case GE: return Primitive.LT; - case GT: return Primitive.LE; - default: throw Debug.abort("unknown primitive", this); - } - } - - /** Return primitive with arguments swapped (e.g. <= is turned - ** into =>). */ - public Primitive swap() { - switch (this) { - case LT: return Primitive.GT; - case LE: return Primitive.GE; - case EQ: return Primitive.EQ; - case NE: return Primitive.NE; - case GE: return Primitive.LE; - case GT: return Primitive.LT; - default: throw Debug.abort("unknown primitive", this); - } - } -} diff --git a/sources/scalac/backend/Primitives.java b/sources/scalac/backend/Primitives.java deleted file mode 100644 index fb2b49a3b0..0000000000 --- a/sources/scalac/backend/Primitives.java +++ /dev/null @@ -1,1304 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Primitives.java,v 1.12 2002/11/19 12:01:11 paltherr Exp $ -// $Id$ - -package scalac.backend; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.symtab.Definitions; -import scalac.symtab.TypeTags; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -/** - * Primitive functions. - * - * @author Michel Schinz, Philippe Altherr - * @version 1.0 - */ - -public class Primitives { - - //######################################################################## - // Primitives constants - - private static final Name RUNTIME_N = Name.fromString("RunTime"); - - private static final Name ZARRAY_N = Name.fromString("zarray"); - private static final Name BARRAY_N = Name.fromString("barray"); - private static final Name SARRAY_N = Name.fromString("sarray"); - private static final Name CARRAY_N = Name.fromString("carray"); - private static final Name IARRAY_N = Name.fromString("iarray"); - private static final Name LARRAY_N = Name.fromString("larray"); - private static final Name FARRAY_N = Name.fromString("farray"); - private static final Name DARRAY_N = Name.fromString("darray"); - private static final Name OARRAY_N = Name.fromString("oarray"); - - private static final Name ZARRAY_LENGTH_N=Name.fromString("zarray_length"); - private static final Name BARRAY_LENGTH_N=Name.fromString("barray_length"); - private static final Name SARRAY_LENGTH_N=Name.fromString("sarray_length"); - private static final Name CARRAY_LENGTH_N=Name.fromString("carray_length"); - private static final Name IARRAY_LENGTH_N=Name.fromString("iarray_length"); - private static final Name LARRAY_LENGTH_N=Name.fromString("larray_length"); - private static final Name FARRAY_LENGTH_N=Name.fromString("farray_length"); - private static final Name DARRAY_LENGTH_N=Name.fromString("darray_length"); - private static final Name OARRAY_LENGTH_N=Name.fromString("oarray_length"); - - private static final Name ZARRAY_GET_N = Name.fromString("zarray_get"); - private static final Name BARRAY_GET_N = Name.fromString("barray_get"); - private static final Name SARRAY_GET_N = Name.fromString("sarray_get"); - private static final Name CARRAY_GET_N = Name.fromString("carray_get"); - private static final Name IARRAY_GET_N = Name.fromString("iarray_get"); - private static final Name LARRAY_GET_N = Name.fromString("larray_get"); - private static final Name FARRAY_GET_N = Name.fromString("farray_get"); - private static final Name DARRAY_GET_N = Name.fromString("darray_get"); - private static final Name OARRAY_GET_N = Name.fromString("oarray_get"); - - private static final Name ZARRAY_SET_N = Name.fromString("zarray_set"); - private static final Name BARRAY_SET_N = Name.fromString("barray_set"); - private static final Name SARRAY_SET_N = Name.fromString("sarray_set"); - private static final Name CARRAY_SET_N = Name.fromString("carray_set"); - private static final Name IARRAY_SET_N = Name.fromString("iarray_set"); - private static final Name LARRAY_SET_N = Name.fromString("larray_set"); - private static final Name FARRAY_SET_N = Name.fromString("farray_set"); - private static final Name DARRAY_SET_N = Name.fromString("darray_set"); - private static final Name OARRAY_SET_N = Name.fromString("oarray_set"); - - private static final Name BOX_UVALUE_N = Name.fromString("box_uvalue"); - private static final Name BOX_ZVALUE_N = Name.fromString("box_zvalue"); - private static final Name BOX_BVALUE_N = Name.fromString("box_bvalue"); - private static final Name BOX_SVALUE_N = Name.fromString("box_svalue"); - private static final Name BOX_CVALUE_N = Name.fromString("box_cvalue"); - private static final Name BOX_IVALUE_N = Name.fromString("box_ivalue"); - private static final Name BOX_LVALUE_N = Name.fromString("box_lvalue"); - private static final Name BOX_FVALUE_N = Name.fromString("box_fvalue"); - private static final Name BOX_DVALUE_N = Name.fromString("box_dvalue"); - - private static final Name BOX_ZARRAY_N = Name.fromString("box_zarray"); - private static final Name BOX_BARRAY_N = Name.fromString("box_barray"); - private static final Name BOX_SARRAY_N = Name.fromString("box_sarray"); - private static final Name BOX_CARRAY_N = Name.fromString("box_carray"); - private static final Name BOX_IARRAY_N = Name.fromString("box_iarray"); - private static final Name BOX_LARRAY_N = Name.fromString("box_larray"); - private static final Name BOX_FARRAY_N = Name.fromString("box_farray"); - private static final Name BOX_DARRAY_N = Name.fromString("box_darray"); - private static final Name BOX_OARRAY_N = Name.fromString("box_oarray"); - private static final Name BOX__ARRAY_N = Name.fromString("box__array"); - - private static final Name UNBOX_UVALUE_N = Name.fromString("unbox_uvalue"); - private static final Name UNBOX_ZVALUE_N = Name.fromString("unbox_zvalue"); - private static final Name UNBOX_BVALUE_N = Name.fromString("unbox_bvalue"); - private static final Name UNBOX_SVALUE_N = Name.fromString("unbox_svalue"); - private static final Name UNBOX_CVALUE_N = Name.fromString("unbox_cvalue"); - private static final Name UNBOX_IVALUE_N = Name.fromString("unbox_ivalue"); - private static final Name UNBOX_LVALUE_N = Name.fromString("unbox_lvalue"); - private static final Name UNBOX_FVALUE_N = Name.fromString("unbox_fvalue"); - private static final Name UNBOX_DVALUE_N = Name.fromString("unbox_dvalue"); - - private static final Name UNBOX_ZARRAY_N = Name.fromString("unbox_zarray"); - private static final Name UNBOX_BARRAY_N = Name.fromString("unbox_barray"); - private static final Name UNBOX_SARRAY_N = Name.fromString("unbox_sarray"); - private static final Name UNBOX_CARRAY_N = Name.fromString("unbox_carray"); - private static final Name UNBOX_IARRAY_N = Name.fromString("unbox_iarray"); - private static final Name UNBOX_LARRAY_N = Name.fromString("unbox_larray"); - private static final Name UNBOX_FARRAY_N = Name.fromString("unbox_farray"); - private static final Name UNBOX_DARRAY_N = Name.fromString("unbox_darray"); - private static final Name UNBOX_OARRAY_N = Name.fromString("unbox_oarray"); - private static final Name UNBOX__ARRAY_N = Name.fromString("unbox__array"); - - private static final Name B2B_N = Name.fromString("b2b"); - private static final Name B2S_N = Name.fromString("b2s"); - private static final Name B2C_N = Name.fromString("b2c"); - private static final Name B2I_N = Name.fromString("b2i"); - private static final Name B2L_N = Name.fromString("b2l"); - private static final Name B2F_N = Name.fromString("b2f"); - private static final Name B2D_N = Name.fromString("b2d"); - private static final Name S2B_N = Name.fromString("s2b"); - private static final Name S2S_N = Name.fromString("s2s"); - private static final Name S2C_N = Name.fromString("s2c"); - private static final Name S2I_N = Name.fromString("s2i"); - private static final Name S2L_N = Name.fromString("s2l"); - private static final Name S2F_N = Name.fromString("s2f"); - private static final Name S2D_N = Name.fromString("s2d"); - private static final Name C2B_N = Name.fromString("c2b"); - private static final Name C2S_N = Name.fromString("c2s"); - private static final Name C2C_N = Name.fromString("c2c"); - private static final Name C2I_N = Name.fromString("c2i"); - private static final Name C2L_N = Name.fromString("c2l"); - private static final Name C2F_N = Name.fromString("c2f"); - private static final Name C2D_N = Name.fromString("c2d"); - private static final Name I2B_N = Name.fromString("i2b"); - private static final Name I2S_N = Name.fromString("i2s"); - private static final Name I2C_N = Name.fromString("i2c"); - private static final Name I2I_N = Name.fromString("i2i"); - private static final Name I2L_N = Name.fromString("i2l"); - private static final Name I2F_N = Name.fromString("i2f"); - private static final Name I2D_N = Name.fromString("i2d"); - private static final Name L2B_N = Name.fromString("l2b"); - private static final Name L2S_N = Name.fromString("l2s"); - private static final Name L2C_N = Name.fromString("l2c"); - private static final Name L2I_N = Name.fromString("l2i"); - private static final Name L2L_N = Name.fromString("l2l"); - private static final Name L2F_N = Name.fromString("l2f"); - private static final Name L2D_N = Name.fromString("l2d"); - private static final Name F2B_N = Name.fromString("f2b"); - private static final Name F2S_N = Name.fromString("f2s"); - private static final Name F2C_N = Name.fromString("f2c"); - private static final Name F2I_N = Name.fromString("f2i"); - private static final Name F2L_N = Name.fromString("f2l"); - private static final Name F2F_N = Name.fromString("f2f"); - private static final Name F2D_N = Name.fromString("f2d"); - private static final Name D2B_N = Name.fromString("d2b"); - private static final Name D2S_N = Name.fromString("d2s"); - private static final Name D2C_N = Name.fromString("d2c"); - private static final Name D2I_N = Name.fromString("d2i"); - private static final Name D2L_N = Name.fromString("d2l"); - private static final Name D2F_N = Name.fromString("d2f"); - private static final Name D2D_N = Name.fromString("d2d"); - - //######################################################################## - // Primitives state - - private final Global global; - private final Definitions definitions; - private final Map/*<Symbol,Primitive>*/ primitives; - private final SymbolNameWriter jreNameWriter; - private final SymbolNameWriter clrNameWriter; - - public final Symbol RUNTIME; - - public final Symbol NEW_ZARRAY; - public final Symbol NEW_BARRAY; - public final Symbol NEW_SARRAY; - public final Symbol NEW_CARRAY; - public final Symbol NEW_IARRAY; - public final Symbol NEW_LARRAY; - public final Symbol NEW_FARRAY; - public final Symbol NEW_DARRAY; - public final Symbol NEW_OARRAY; - - public final Symbol ZARRAY_LENGTH; - public final Symbol BARRAY_LENGTH; - public final Symbol SARRAY_LENGTH; - public final Symbol CARRAY_LENGTH; - public final Symbol IARRAY_LENGTH; - public final Symbol LARRAY_LENGTH; - public final Symbol FARRAY_LENGTH; - public final Symbol DARRAY_LENGTH; - public final Symbol OARRAY_LENGTH; - - public final Symbol ZARRAY_GET; - public final Symbol BARRAY_GET; - public final Symbol SARRAY_GET; - public final Symbol CARRAY_GET; - public final Symbol IARRAY_GET; - public final Symbol LARRAY_GET; - public final Symbol FARRAY_GET; - public final Symbol DARRAY_GET; - public final Symbol OARRAY_GET; - - public final Symbol ZARRAY_SET; - public final Symbol BARRAY_SET; - public final Symbol SARRAY_SET; - public final Symbol CARRAY_SET; - public final Symbol IARRAY_SET; - public final Symbol LARRAY_SET; - public final Symbol FARRAY_SET; - public final Symbol DARRAY_SET; - public final Symbol OARRAY_SET; - - public final Symbol BOX_UVALUE; - public final Symbol BOX_ZVALUE; - public final Symbol BOX_BVALUE; - public final Symbol BOX_SVALUE; - public final Symbol BOX_CVALUE; - public final Symbol BOX_IVALUE; - public final Symbol BOX_LVALUE; - public final Symbol BOX_FVALUE; - public final Symbol BOX_DVALUE; - - public final Symbol BOX_ZARRAY; - public final Symbol BOX_BARRAY; - public final Symbol BOX_SARRAY; - public final Symbol BOX_CARRAY; - public final Symbol BOX_IARRAY; - public final Symbol BOX_LARRAY; - public final Symbol BOX_FARRAY; - public final Symbol BOX_DARRAY; - public final Symbol BOX_OARRAY; - public final Symbol BOX__ARRAY; - - public final Symbol UNBOX_UVALUE; - public final Symbol UNBOX_ZVALUE; - public final Symbol UNBOX_BVALUE; - public final Symbol UNBOX_SVALUE; - public final Symbol UNBOX_CVALUE; - public final Symbol UNBOX_IVALUE; - public final Symbol UNBOX_LVALUE; - public final Symbol UNBOX_FVALUE; - public final Symbol UNBOX_DVALUE; - - public final Symbol UNBOX_ZARRAY; - public final Symbol UNBOX_BARRAY; - public final Symbol UNBOX_SARRAY; - public final Symbol UNBOX_CARRAY; - public final Symbol UNBOX_IARRAY; - public final Symbol UNBOX_LARRAY; - public final Symbol UNBOX_FARRAY; - public final Symbol UNBOX_DARRAY; - public final Symbol UNBOX_OARRAY; - public final Symbol UNBOX__ARRAY; - - public final Symbol B2B; - public final Symbol B2S; - public final Symbol B2C; - public final Symbol B2I; - public final Symbol B2L; - public final Symbol B2F; - public final Symbol B2D; - public final Symbol S2B; - public final Symbol S2S; - public final Symbol S2C; - public final Symbol S2I; - public final Symbol S2L; - public final Symbol S2F; - public final Symbol S2D; - public final Symbol C2B; - public final Symbol C2S; - public final Symbol C2C; - public final Symbol C2I; - public final Symbol C2L; - public final Symbol C2F; - public final Symbol C2D; - public final Symbol I2B; - public final Symbol I2S; - public final Symbol I2C; - public final Symbol I2I; - public final Symbol I2L; - public final Symbol I2F; - public final Symbol I2D; - public final Symbol L2B; - public final Symbol L2S; - public final Symbol L2C; - public final Symbol L2I; - public final Symbol L2L; - public final Symbol L2F; - public final Symbol L2D; - public final Symbol F2B; - public final Symbol F2S; - public final Symbol F2C; - public final Symbol F2I; - public final Symbol F2L; - public final Symbol F2F; - public final Symbol F2D; - public final Symbol D2B; - public final Symbol D2S; - public final Symbol D2C; - public final Symbol D2I; - public final Symbol D2L; - public final Symbol D2F; - public final Symbol D2D; - - //######################################################################## - // Primitives constructor - - public Primitives(Global global) { - this.global = global; - this.definitions = global.definitions; - this.primitives = new HashMap(); - this.jreNameWriter = new SymbolNameWriter().setClassSeparator('$'); - this.clrNameWriter = new SymbolNameWriter(); - this.RUNTIME = definitions.getModule("scala.runtime.RunTime"); - this.NEW_ZARRAY = getUniqueTerm(RUNTIME, ZARRAY_N); - this.NEW_BARRAY = getUniqueTerm(RUNTIME, BARRAY_N); - this.NEW_SARRAY = getUniqueTerm(RUNTIME, SARRAY_N); - this.NEW_CARRAY = getUniqueTerm(RUNTIME, CARRAY_N); - this.NEW_IARRAY = getUniqueTerm(RUNTIME, IARRAY_N); - this.NEW_LARRAY = getUniqueTerm(RUNTIME, LARRAY_N); - this.NEW_FARRAY = getUniqueTerm(RUNTIME, FARRAY_N); - this.NEW_DARRAY = getUniqueTerm(RUNTIME, DARRAY_N); - this.NEW_OARRAY = getUniqueTerm(RUNTIME, OARRAY_N); - this.ZARRAY_LENGTH = getUniqueTerm(RUNTIME, ZARRAY_LENGTH_N); - this.BARRAY_LENGTH = getUniqueTerm(RUNTIME, BARRAY_LENGTH_N); - this.SARRAY_LENGTH = getUniqueTerm(RUNTIME, SARRAY_LENGTH_N); - this.CARRAY_LENGTH = getUniqueTerm(RUNTIME, CARRAY_LENGTH_N); - this.IARRAY_LENGTH = getUniqueTerm(RUNTIME, IARRAY_LENGTH_N); - this.LARRAY_LENGTH = getUniqueTerm(RUNTIME, LARRAY_LENGTH_N); - this.FARRAY_LENGTH = getUniqueTerm(RUNTIME, FARRAY_LENGTH_N); - this.DARRAY_LENGTH = getUniqueTerm(RUNTIME, DARRAY_LENGTH_N); - this.OARRAY_LENGTH = getUniqueTerm(RUNTIME, OARRAY_LENGTH_N); - this.ZARRAY_GET = getUniqueTerm(RUNTIME, ZARRAY_GET_N); - this.BARRAY_GET = getUniqueTerm(RUNTIME, BARRAY_GET_N); - this.SARRAY_GET = getUniqueTerm(RUNTIME, SARRAY_GET_N); - this.CARRAY_GET = getUniqueTerm(RUNTIME, CARRAY_GET_N); - this.IARRAY_GET = getUniqueTerm(RUNTIME, IARRAY_GET_N); - this.LARRAY_GET = getUniqueTerm(RUNTIME, LARRAY_GET_N); - this.FARRAY_GET = getUniqueTerm(RUNTIME, FARRAY_GET_N); - this.DARRAY_GET = getUniqueTerm(RUNTIME, DARRAY_GET_N); - this.OARRAY_GET = getUniqueTerm(RUNTIME, OARRAY_GET_N); - this.ZARRAY_SET = getUniqueTerm(RUNTIME, ZARRAY_SET_N); - this.BARRAY_SET = getUniqueTerm(RUNTIME, BARRAY_SET_N); - this.SARRAY_SET = getUniqueTerm(RUNTIME, SARRAY_SET_N); - this.CARRAY_SET = getUniqueTerm(RUNTIME, CARRAY_SET_N); - this.IARRAY_SET = getUniqueTerm(RUNTIME, IARRAY_SET_N); - this.LARRAY_SET = getUniqueTerm(RUNTIME, LARRAY_SET_N); - this.FARRAY_SET = getUniqueTerm(RUNTIME, FARRAY_SET_N); - this.DARRAY_SET = getUniqueTerm(RUNTIME, DARRAY_SET_N); - this.OARRAY_SET = getUniqueTerm(RUNTIME, OARRAY_SET_N); - this.BOX_UVALUE = getUniqueTerm(RUNTIME, BOX_UVALUE_N); - this.BOX_ZVALUE = getUniqueTerm(RUNTIME, BOX_ZVALUE_N); - this.BOX_BVALUE = getUniqueTerm(RUNTIME, BOX_BVALUE_N); - this.BOX_SVALUE = getUniqueTerm(RUNTIME, BOX_SVALUE_N); - this.BOX_CVALUE = getUniqueTerm(RUNTIME, BOX_CVALUE_N); - this.BOX_IVALUE = getUniqueTerm(RUNTIME, BOX_IVALUE_N); - this.BOX_LVALUE = getUniqueTerm(RUNTIME, BOX_LVALUE_N); - this.BOX_FVALUE = getUniqueTerm(RUNTIME, BOX_FVALUE_N); - this.BOX_DVALUE = getUniqueTerm(RUNTIME, BOX_DVALUE_N); - this.BOX_ZARRAY = getUniqueTerm(RUNTIME, BOX_ZARRAY_N); - this.BOX_BARRAY = getUniqueTerm(RUNTIME, BOX_BARRAY_N); - this.BOX_SARRAY = getUniqueTerm(RUNTIME, BOX_SARRAY_N); - this.BOX_CARRAY = getUniqueTerm(RUNTIME, BOX_CARRAY_N); - this.BOX_IARRAY = getUniqueTerm(RUNTIME, BOX_IARRAY_N); - this.BOX_LARRAY = getUniqueTerm(RUNTIME, BOX_LARRAY_N); - this.BOX_FARRAY = getUniqueTerm(RUNTIME, BOX_FARRAY_N); - this.BOX_DARRAY = getUniqueTerm(RUNTIME, BOX_DARRAY_N); - this.BOX_OARRAY = getUniqueTerm(RUNTIME, BOX_OARRAY_N); - this.BOX__ARRAY = getUniqueTerm(RUNTIME, BOX__ARRAY_N); - this.UNBOX_UVALUE = getUniqueTerm(RUNTIME, UNBOX_UVALUE_N); - this.UNBOX_ZVALUE = getUniqueTerm(RUNTIME, UNBOX_ZVALUE_N); - this.UNBOX_BVALUE = getUniqueTerm(RUNTIME, UNBOX_BVALUE_N); - this.UNBOX_SVALUE = getUniqueTerm(RUNTIME, UNBOX_SVALUE_N); - this.UNBOX_CVALUE = getUniqueTerm(RUNTIME, UNBOX_CVALUE_N); - this.UNBOX_IVALUE = getUniqueTerm(RUNTIME, UNBOX_IVALUE_N); - this.UNBOX_LVALUE = getUniqueTerm(RUNTIME, UNBOX_LVALUE_N); - this.UNBOX_FVALUE = getUniqueTerm(RUNTIME, UNBOX_FVALUE_N); - this.UNBOX_DVALUE = getUniqueTerm(RUNTIME, UNBOX_DVALUE_N); - this.UNBOX_ZARRAY = getUniqueTerm(RUNTIME, UNBOX_ZARRAY_N); - this.UNBOX_BARRAY = getUniqueTerm(RUNTIME, UNBOX_BARRAY_N); - this.UNBOX_SARRAY = getUniqueTerm(RUNTIME, UNBOX_SARRAY_N); - this.UNBOX_CARRAY = getUniqueTerm(RUNTIME, UNBOX_CARRAY_N); - this.UNBOX_IARRAY = getUniqueTerm(RUNTIME, UNBOX_IARRAY_N); - this.UNBOX_LARRAY = getUniqueTerm(RUNTIME, UNBOX_LARRAY_N); - this.UNBOX_FARRAY = getUniqueTerm(RUNTIME, UNBOX_FARRAY_N); - this.UNBOX_DARRAY = getUniqueTerm(RUNTIME, UNBOX_DARRAY_N); - this.UNBOX_OARRAY = getUniqueTerm(RUNTIME, UNBOX_OARRAY_N); - this.UNBOX__ARRAY = getUniqueTerm(RUNTIME, UNBOX__ARRAY_N); - this.B2B = getUniqueTerm(RUNTIME, B2B_N); - this.B2S = getUniqueTerm(RUNTIME, B2S_N); - this.B2C = getUniqueTerm(RUNTIME, B2C_N); - this.B2I = getUniqueTerm(RUNTIME, B2I_N); - this.B2L = getUniqueTerm(RUNTIME, B2L_N); - this.B2F = getUniqueTerm(RUNTIME, B2F_N); - this.B2D = getUniqueTerm(RUNTIME, B2D_N); - this.S2B = getUniqueTerm(RUNTIME, S2B_N); - this.S2S = getUniqueTerm(RUNTIME, S2S_N); - this.S2C = getUniqueTerm(RUNTIME, S2C_N); - this.S2I = getUniqueTerm(RUNTIME, S2I_N); - this.S2L = getUniqueTerm(RUNTIME, S2L_N); - this.S2F = getUniqueTerm(RUNTIME, S2F_N); - this.S2D = getUniqueTerm(RUNTIME, S2D_N); - this.C2B = getUniqueTerm(RUNTIME, C2B_N); - this.C2S = getUniqueTerm(RUNTIME, C2S_N); - this.C2C = getUniqueTerm(RUNTIME, C2C_N); - this.C2I = getUniqueTerm(RUNTIME, C2I_N); - this.C2L = getUniqueTerm(RUNTIME, C2L_N); - this.C2F = getUniqueTerm(RUNTIME, C2F_N); - this.C2D = getUniqueTerm(RUNTIME, C2D_N); - this.I2B = getUniqueTerm(RUNTIME, I2B_N); - this.I2S = getUniqueTerm(RUNTIME, I2S_N); - this.I2C = getUniqueTerm(RUNTIME, I2C_N); - this.I2I = getUniqueTerm(RUNTIME, I2I_N); - this.I2L = getUniqueTerm(RUNTIME, I2L_N); - this.I2F = getUniqueTerm(RUNTIME, I2F_N); - this.I2D = getUniqueTerm(RUNTIME, I2D_N); - this.L2B = getUniqueTerm(RUNTIME, L2B_N); - this.L2S = getUniqueTerm(RUNTIME, L2S_N); - this.L2C = getUniqueTerm(RUNTIME, L2C_N); - this.L2I = getUniqueTerm(RUNTIME, L2I_N); - this.L2L = getUniqueTerm(RUNTIME, L2L_N); - this.L2F = getUniqueTerm(RUNTIME, L2F_N); - this.L2D = getUniqueTerm(RUNTIME, L2D_N); - this.F2B = getUniqueTerm(RUNTIME, F2B_N); - this.F2S = getUniqueTerm(RUNTIME, F2S_N); - this.F2C = getUniqueTerm(RUNTIME, F2C_N); - this.F2I = getUniqueTerm(RUNTIME, F2I_N); - this.F2L = getUniqueTerm(RUNTIME, F2L_N); - this.F2F = getUniqueTerm(RUNTIME, F2F_N); - this.F2D = getUniqueTerm(RUNTIME, F2D_N); - this.D2B = getUniqueTerm(RUNTIME, D2B_N); - this.D2S = getUniqueTerm(RUNTIME, D2S_N); - this.D2C = getUniqueTerm(RUNTIME, D2C_N); - this.D2I = getUniqueTerm(RUNTIME, D2I_N); - this.D2L = getUniqueTerm(RUNTIME, D2L_N); - this.D2F = getUniqueTerm(RUNTIME, D2F_N); - this.D2D = getUniqueTerm(RUNTIME, D2D_N); - initPrimitives(); - } - - //######################################################################## - // Private interface - - private Symbol getUniqueTerm(Symbol owner, Name name) { - Symbol symbol = getTerm(owner, name); - assert !symbol.isOverloaded() : - Debug.show(owner) + "." + name + " -> " + Debug.show(symbol); - return symbol; - } - - private Symbol getTerm(Symbol owner, Name name) { - Symbol symbol = owner.lookup(name); - assert symbol != Symbol.NONE : Debug.show(owner) + "." + name; - return symbol; - } - - private void initPrimitives() { - Definitions defs = definitions; - - // scala.Any - addPrimitive(defs.ANY_IS_ERASED, Primitive.IS); - addPrimitive(defs.ANY_AS_ERASED, Primitive.AS); - addPrimitive(defs.ANY_EQEQ, Primitive.EQ); - addPrimitive(defs.ANY_BANGEQ, Primitive.NE); - // !!! addPrimitive(defs.ANY_EQUALS, Primitive.EQUALS); - addPrimitive(defs.ANY_HASHCODE, Primitive.HASHCODE); - addPrimitive(defs.ANY_TOSTRING, Primitive.TOSTRING); - - // scala.Unit - addAll(defs.UNIT_CLASS, Names.EQ, Primitive.EQ, 1); - addAll(defs.UNIT_CLASS, Names.NE, Primitive.NE, 1); - addAll(defs.UNIT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.UNIT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.UNIT_CLASS, Names.toString, Primitive.TOSTRING, 1); - // !!! addAll(defs.UNIT_CLASS, Names.ADD, Primitive.CONCAT, 1); - - // scala.Boolean - //addAll(defs.BOOLEAN_CLASS, Names.EQ, Primitive.EQ, 2); - addAllPrimitive(defs.BOOLEAN_CLASS, Names.EQ, Primitive.EQ, 1); - //addAll(defs.BOOLEAN_CLASS, Names.NE, Primitive.NE, 2); - addAllPrimitive(defs.BOOLEAN_CLASS, Names.NE, Primitive.NE, 1); - addAll(defs.BOOLEAN_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.BOOLEAN_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.BOOLEAN_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.BOOLEAN_CLASS, Names.ZNOT, Primitive.ZNOT, 1); - addAll(defs.BOOLEAN_CLASS, Names.OR, Primitive.OR, 1); - addAll(defs.BOOLEAN_CLASS, Names.XOR, Primitive.XOR, 1); - addAll(defs.BOOLEAN_CLASS, Names.AND, Primitive.AND, 1); - addAll(defs.BOOLEAN_CLASS, Names.ZOR, Primitive.ZOR, 1); - addAll(defs.BOOLEAN_CLASS, Names.ZAND, Primitive.ZAND, 1); - // !!! addAll(defs.BOOLEAN_CLASS, Names.ADD, Primitive.CONCAT, 1); - - // scala.Byte - addAll(defs.BYTE_CLASS, Names.coerce, Primitive.COERCE, 5); - //addAll(defs.BYTE_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.BYTE_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.BYTE_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.BYTE_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.BYTE_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.BYTE_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.BYTE_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.BYTE_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.BYTE_CLASS, 7); - addSub(defs.BYTE_CLASS, 7); - addAll(defs.BYTE_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.BYTE_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.BYTE_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.BYTE_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.BYTE_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.BYTE_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.BYTE_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.BYTE_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.BYTE_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.BYTE_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.BYTE_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.BYTE_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.BYTE_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Short - addAll(defs.SHORT_CLASS, Names.coerce, Primitive.COERCE, 4); - //addAll(defs.SHORT_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.SHORT_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.SHORT_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.SHORT_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.SHORT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.SHORT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.SHORT_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.SHORT_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.SHORT_CLASS, 7); - addSub(defs.SHORT_CLASS, 7); - addAll(defs.SHORT_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.SHORT_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.SHORT_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.SHORT_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.SHORT_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.SHORT_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.SHORT_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.SHORT_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.SHORT_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.SHORT_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.SHORT_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.SHORT_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.SHORT_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Char - addAll(defs.CHAR_CLASS, Names.coerce, Primitive.COERCE, 4); - //addAll(defs.CHAR_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.CHAR_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.CHAR_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.CHAR_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.CHAR_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.CHAR_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.CHAR_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.CHAR_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.CHAR_CLASS, 7); - addSub(defs.CHAR_CLASS, 7); - addAll(defs.CHAR_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.CHAR_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.CHAR_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.CHAR_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.CHAR_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.CHAR_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.CHAR_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.CHAR_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.CHAR_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.CHAR_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.CHAR_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.CHAR_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.CHAR_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Int - addAll(defs.INT_CLASS, Names.coerce, Primitive.COERCE, 3); - //addAll(defs.INT_CLASS, Names.EQ, Primitive.EQ, 5); - addAllPrimitive(defs.INT_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.INT_CLASS, Names.NE, Primitive.NE, 5); - addAllPrimitive(defs.INT_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.INT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.INT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.INT_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.INT_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.INT_CLASS, 7); - addSub(defs.INT_CLASS, 7); - addAll(defs.INT_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.INT_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.INT_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.INT_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.INT_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.INT_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.INT_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.INT_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.INT_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.INT_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.INT_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.INT_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.INT_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Long - addAll(defs.LONG_CLASS, Names.coerce, Primitive.COERCE, 2); - //addAll(defs.LONG_CLASS, Names.EQ, Primitive.EQ, 4); - addAllPrimitive(defs.LONG_CLASS, Names.EQ, Primitive.EQ, 7); - //addAll(defs.LONG_CLASS, Names.NE, Primitive.NE, 4); - addAllPrimitive(defs.LONG_CLASS, Names.NE, Primitive.NE, 7); - //addAll(defs.LONG_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.LONG_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.LONG_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.LONG_CLASS, Names.NOT, Primitive.NOT, 1); - addAdd(defs.LONG_CLASS, 7); - addSub(defs.LONG_CLASS, 7); - addAll(defs.LONG_CLASS, Names.MUL, Primitive.MUL, 7); - addAll(defs.LONG_CLASS, Names.DIV, Primitive.DIV, 7); - addAll(defs.LONG_CLASS, Names.MOD, Primitive.MOD, 7); - addAll(defs.LONG_CLASS, Names.LT, Primitive.LT, 7); - addAll(defs.LONG_CLASS, Names.LE, Primitive.LE, 7); - addAll(defs.LONG_CLASS, Names.GT, Primitive.GT, 7); - addAll(defs.LONG_CLASS, Names.GE, Primitive.GE, 7); - addAll(defs.LONG_CLASS, Names.OR, Primitive.OR, 5); - addAll(defs.LONG_CLASS, Names.XOR, Primitive.XOR, 5); - addAll(defs.LONG_CLASS, Names.AND, Primitive.AND, 5); - addAll(defs.LONG_CLASS, Names.LSL, Primitive.LSL, 2); - addAll(defs.LONG_CLASS, Names.LSR, Primitive.LSR, 2); - addAll(defs.LONG_CLASS, Names.ASR, Primitive.ASR, 2); - - // scala.Float - addAll(defs.FLOAT_CLASS, Names.coerce, Primitive.COERCE, 1); - //addAll(defs.FLOAT_CLASS, Names.EQ, Primitive.EQ, 3); - addAllPrimitive(defs.FLOAT_CLASS, Names.EQ, Primitive.EQ, 2); - //addAll(defs.FLOAT_CLASS, Names.NE, Primitive.NE, 3); - addAllPrimitive(defs.FLOAT_CLASS, Names.NE, Primitive.NE, 2); - //addAll(defs.FLOAT_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.FLOAT_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.FLOAT_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAdd(defs.FLOAT_CLASS, 2); - addSub(defs.FLOAT_CLASS, 2); - addAll(defs.FLOAT_CLASS, Names.MUL, Primitive.MUL, 2); - addAll(defs.FLOAT_CLASS, Names.DIV, Primitive.DIV, 2); - addAll(defs.FLOAT_CLASS, Names.MOD, Primitive.MOD, 2); - addAll(defs.FLOAT_CLASS, Names.LT, Primitive.LT, 2); - addAll(defs.FLOAT_CLASS, Names.LE, Primitive.LE, 2); - addAll(defs.FLOAT_CLASS, Names.GT, Primitive.GT, 2); - addAll(defs.FLOAT_CLASS, Names.GE, Primitive.GE, 2); - - // scala.Double - //addAll(defs.DOUBLE_CLASS, Names.EQ, Primitive.EQ, 2); - addAllPrimitive(defs.DOUBLE_CLASS, Names.EQ, Primitive.EQ, 1); - //addAll(defs.DOUBLE_CLASS, Names.NE, Primitive.NE, 2); - addAllPrimitive(defs.DOUBLE_CLASS, Names.NE, Primitive.NE, 1); - //addAll(defs.DOUBLE_CLASS, Names.equals, Primitive.EQUALS, 1); - addAll(defs.DOUBLE_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - addAll(defs.DOUBLE_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAdd(defs.DOUBLE_CLASS, 1); - addSub(defs.DOUBLE_CLASS, 1); - addAll(defs.DOUBLE_CLASS, Names.MUL, Primitive.MUL, 1); - addAll(defs.DOUBLE_CLASS, Names.DIV, Primitive.DIV, 1); - addAll(defs.DOUBLE_CLASS, Names.MOD, Primitive.MOD, 1); - addAll(defs.DOUBLE_CLASS, Names.LT, Primitive.LT, 1); - addAll(defs.DOUBLE_CLASS, Names.LE, Primitive.LE, 1); - addAll(defs.DOUBLE_CLASS, Names.GT, Primitive.GT, 1); - addAll(defs.DOUBLE_CLASS, Names.GE, Primitive.GE, 1); - - // scala.Object - addPrimitive(defs.OBJECT_EQ, Primitive.ID); - addPrimitive(defs.OBJECT_NE, Primitive.NI); - addPrimitive(defs.OBJECT_SYNCHRONIZED, Primitive.SYNCHRONIZED); - - // scala.String - addPrimitive(defs.STRING_PLUS, Primitive.CONCAT); - - // scala.Throwable - addPrimitive(defs.THROWABLE_THROW, Primitive.THROW); - - // scala.Array - // !!! addAll(defs.ARRAY_CLASS, defs.EQEQ_N, Primitive.EQ, 1); - // !!! addAll(defs.ARRAY_CLASS, defs.BANGEQ_N, Primitive.NE, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.equals, Primitive.EQUALS, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.hashCode, Primitive.HASHCODE, 1); - // !!! addAll(defs.ARRAY_CLASS, Names.toString, Primitive.TOSTRING, 1); - addAll(defs.ARRAY_CLASS, Names.length, Primitive.LENGTH, 1); - addAll(defs.ARRAY_CLASS, Names.apply, Primitive.APPLY, 1); - addAll(defs.ARRAY_CLASS, Names.update, Primitive.UPDATE, 1); - - // scala.runtime.RunTime - addPrimitive(BOX_UVALUE, Primitive.BOX); - addPrimitive(BOX_ZVALUE, Primitive.BOX); - addPrimitive(BOX_BVALUE, Primitive.BOX); - addPrimitive(BOX_SVALUE, Primitive.BOX); - addPrimitive(BOX_CVALUE, Primitive.BOX); - addPrimitive(BOX_IVALUE, Primitive.BOX); - addPrimitive(BOX_LVALUE, Primitive.BOX); - addPrimitive(BOX_FVALUE, Primitive.BOX); - addPrimitive(BOX_DVALUE, Primitive.BOX); - addPrimitive(BOX_ZARRAY, Primitive.BOX); - addPrimitive(BOX_BARRAY, Primitive.BOX); - addPrimitive(BOX_SARRAY, Primitive.BOX); - addPrimitive(BOX_CARRAY, Primitive.BOX); - addPrimitive(BOX_IARRAY, Primitive.BOX); - addPrimitive(BOX_LARRAY, Primitive.BOX); - addPrimitive(BOX_FARRAY, Primitive.BOX); - addPrimitive(BOX_DARRAY, Primitive.BOX); - addPrimitive(BOX_OARRAY, Primitive.BOX); - addPrimitive(BOX__ARRAY, Primitive.BOX); - addPrimitive(UNBOX_UVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_ZVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_BVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_SVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_CVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_IVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_LVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_FVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_DVALUE, Primitive.UNBOX); - addPrimitive(UNBOX_ZARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_BARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_SARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_CARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_IARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_LARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_FARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_DARRAY, Primitive.UNBOX); - addPrimitive(UNBOX_OARRAY, Primitive.UNBOX); - addPrimitive(UNBOX__ARRAY, Primitive.UNBOX); - addPrimitive(B2B, Primitive.B2B); - addPrimitive(B2S, Primitive.B2S); - addPrimitive(B2C, Primitive.B2C); - addPrimitive(B2I, Primitive.B2I); - addPrimitive(B2L, Primitive.B2L); - addPrimitive(B2F, Primitive.B2F); - addPrimitive(B2D, Primitive.B2D); - addPrimitive(S2B, Primitive.S2B); - addPrimitive(S2S, Primitive.S2S); - addPrimitive(S2C, Primitive.S2C); - addPrimitive(S2I, Primitive.S2I); - addPrimitive(S2L, Primitive.S2L); - addPrimitive(S2F, Primitive.S2F); - addPrimitive(S2D, Primitive.S2D); - addPrimitive(C2B, Primitive.C2B); - addPrimitive(C2S, Primitive.C2S); - addPrimitive(C2C, Primitive.C2C); - addPrimitive(C2I, Primitive.C2I); - addPrimitive(C2L, Primitive.C2L); - addPrimitive(C2F, Primitive.C2F); - addPrimitive(C2D, Primitive.C2D); - addPrimitive(I2B, Primitive.I2B); - addPrimitive(I2S, Primitive.I2S); - addPrimitive(I2C, Primitive.I2C); - addPrimitive(I2I, Primitive.I2I); - addPrimitive(I2L, Primitive.I2L); - addPrimitive(I2F, Primitive.I2F); - addPrimitive(I2D, Primitive.I2D); - addPrimitive(L2B, Primitive.L2B); - addPrimitive(L2S, Primitive.L2S); - addPrimitive(L2C, Primitive.L2C); - addPrimitive(L2I, Primitive.L2I); - addPrimitive(L2L, Primitive.L2L); - addPrimitive(L2F, Primitive.L2F); - addPrimitive(L2D, Primitive.L2D); - addPrimitive(F2B, Primitive.F2B); - addPrimitive(F2S, Primitive.F2S); - addPrimitive(F2C, Primitive.F2C); - addPrimitive(F2I, Primitive.F2I); - addPrimitive(F2L, Primitive.F2L); - addPrimitive(F2F, Primitive.F2F); - addPrimitive(F2D, Primitive.F2D); - addPrimitive(D2B, Primitive.D2B); - addPrimitive(D2S, Primitive.D2S); - addPrimitive(D2C, Primitive.D2C); - addPrimitive(D2I, Primitive.D2I); - addPrimitive(D2L, Primitive.D2L); - addPrimitive(D2F, Primitive.D2F); - addPrimitive(D2D, Primitive.D2D); - addPrimitive(NEW_ZARRAY, Primitive.NEW_ZARRAY); - addPrimitive(NEW_BARRAY, Primitive.NEW_BARRAY); - addPrimitive(NEW_SARRAY, Primitive.NEW_SARRAY); - addPrimitive(NEW_CARRAY, Primitive.NEW_CARRAY); - addPrimitive(NEW_IARRAY, Primitive.NEW_IARRAY); - addPrimitive(NEW_LARRAY, Primitive.NEW_LARRAY); - addPrimitive(NEW_FARRAY, Primitive.NEW_FARRAY); - addPrimitive(NEW_DARRAY, Primitive.NEW_DARRAY); - addPrimitive(NEW_OARRAY, Primitive.NEW_OARRAY); - addPrimitive(ZARRAY_LENGTH, Primitive.ZARRAY_LENGTH); - addPrimitive(BARRAY_LENGTH, Primitive.BARRAY_LENGTH); - addPrimitive(SARRAY_LENGTH, Primitive.SARRAY_LENGTH); - addPrimitive(CARRAY_LENGTH, Primitive.CARRAY_LENGTH); - addPrimitive(IARRAY_LENGTH, Primitive.IARRAY_LENGTH); - addPrimitive(LARRAY_LENGTH, Primitive.LARRAY_LENGTH); - addPrimitive(FARRAY_LENGTH, Primitive.FARRAY_LENGTH); - addPrimitive(DARRAY_LENGTH, Primitive.DARRAY_LENGTH); - addPrimitive(OARRAY_LENGTH, Primitive.OARRAY_LENGTH); - addPrimitive(ZARRAY_GET, Primitive.ZARRAY_GET); - addPrimitive(BARRAY_GET, Primitive.BARRAY_GET); - addPrimitive(SARRAY_GET, Primitive.SARRAY_GET); - addPrimitive(CARRAY_GET, Primitive.CARRAY_GET); - addPrimitive(IARRAY_GET, Primitive.IARRAY_GET); - addPrimitive(LARRAY_GET, Primitive.LARRAY_GET); - addPrimitive(FARRAY_GET, Primitive.FARRAY_GET); - addPrimitive(DARRAY_GET, Primitive.DARRAY_GET); - addPrimitive(OARRAY_GET, Primitive.OARRAY_GET); - addPrimitive(ZARRAY_SET, Primitive.ZARRAY_SET); - addPrimitive(BARRAY_SET, Primitive.BARRAY_SET); - addPrimitive(SARRAY_SET, Primitive.SARRAY_SET); - addPrimitive(CARRAY_SET, Primitive.CARRAY_SET); - addPrimitive(IARRAY_SET, Primitive.IARRAY_SET); - addPrimitive(LARRAY_SET, Primitive.LARRAY_SET); - addPrimitive(FARRAY_SET, Primitive.FARRAY_SET); - addPrimitive(DARRAY_SET, Primitive.DARRAY_SET); - addPrimitive(OARRAY_SET, Primitive.OARRAY_SET); - } - - private void addAdd(Symbol clasz, int count) { - Name name = Names.ADD; - Symbol symbol = clasz.lookup(name); - assert !symbol.isNone(): Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - boolean unary = false; - boolean concat = false; - for (int i = 0; i < alts.length; i++) { - switch (alts[i].type()) { - case MethodType(Symbol[] vparams, _): - assert vparams.length == 1: alts[i].type(); - if (vparams[0].type().isSameAs(definitions.STRING_TYPE())) { - addPrimitive(alts[i], Primitive.CONCAT); - assert !concat; - concat = true; - } else { - addPrimitive(alts[i], Primitive.ADD); - count--; - } - break; - case PolyType(Symbol[] tparams, _): - addPrimitive(alts[i], Primitive.POS); - assert !unary; - unary = true; - break; - default: - throw Debug.abort("illegal case" , alts[i].type()); - } - } - assert count == 0 && unary && concat: count+" - "+unary+" - "+concat; - } - - private void addSub(Symbol clasz, int count) { - Name name = Names.SUB; - Symbol symbol = clasz.lookup(name); - assert !symbol.isNone(): Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - boolean unary = false; - for (int i = 0; i < alts.length; i++) { - switch (alts[i].type()) { - case MethodType(_, _): - addPrimitive(alts[i], Primitive.SUB); - count--; - break; - case PolyType(_, _): - addPrimitive(alts[i], Primitive.NEG); - assert !unary; - unary = true; - break; - default: - throw Debug.abort("illegal case" , alts[i].type()); - } - } - assert count == 0 && unary: count + " - " + unary; - } - - private void addAll(Symbol clasz,Name name,Primitive primitive,int count) { - Symbol symbol = clasz.lookup(name); - assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - assert count == alts.length : count + " != " + alts.length; - for (int i = 0; i < alts.length; i++) addPrimitive(alts[i], primitive); - } - - private void addAllPrimitive(Symbol clasz, Name name, Primitive primitive, int count) { - Symbol symbol = clasz.lookup(name); - assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternativeSymbols(); - int cnt = 0; - loop: - for (int i = 0; i < alts.length; i++) { - switch (alts[i].info()) { - case MethodType(Symbol[] vparams, _): - for (int j = 0; j < vparams.length; j++) { - if (!isValueType(vparams[j].info())) - continue loop; - } - addPrimitive(alts[i], primitive); - cnt++; - break; - } - } - assert cnt == count : "" + cnt + " != " + count; - } - - private boolean isValueType(Type t) { - return t.isSubType(definitions.ANYVAL_TYPE()); - } - - private void addPrimitive(Symbol symbol, Primitive primitive) { - assert !primitives.containsKey(symbol) : Debug.show(symbol); - primitives.put(symbol, primitive); - } - - //######################################################################## - // Primitives interface - general primitives - - /** Return true iff the given symbol refers to a primitive. */ - public boolean isPrimitive(Symbol symbol) { - return primitives.containsKey(symbol); - } - - /** Return primitive identified by the symbol. */ - public Primitive getPrimitive(Symbol symbol) { - Object value = primitives.get(symbol); - return value == null ? Primitive.NOT_A_PRIMITIVE : (Primitive)value; - } - - //######################################################################## - // Primitives interface - array creation primitives - - /** Return array creation method for elements of the given kind. */ - public Symbol getNewArraySymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return NEW_ZARRAY; - case TypeTags.BYTE : return NEW_BARRAY; - case TypeTags.SHORT : return NEW_SARRAY; - case TypeTags.CHAR : return NEW_CARRAY; - case TypeTags.INT : return NEW_IARRAY; - case TypeTags.LONG : return NEW_LARRAY; - case TypeTags.FLOAT : return NEW_FARRAY; - case TypeTags.DOUBLE : return NEW_DARRAY; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - boxing primitives - - /** Return box method for values of the given type. */ - public Symbol getBoxValueSymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getBoxValueSymbol(kind); - case UnboxedArrayType(Type elemtp): - return getBoxArraySymbol(elemtp); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return box method for values of the given kind. */ - public Symbol getBoxValueSymbol(int kind) { - switch (kind) { - case TypeTags.UNIT : return BOX_UVALUE; - case TypeTags.BOOLEAN: return BOX_ZVALUE; - case TypeTags.BYTE : return BOX_BVALUE; - case TypeTags.SHORT : return BOX_SVALUE; - case TypeTags.CHAR : return BOX_CVALUE; - case TypeTags.INT : return BOX_IVALUE; - case TypeTags.LONG : return BOX_LVALUE; - case TypeTags.FLOAT : return BOX_FVALUE; - case TypeTags.DOUBLE : return BOX_DVALUE; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return box method for arrays of elements of the given type. */ - public Symbol getBoxArraySymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getBoxArraySymbol(kind); - default: - return BOX_OARRAY; - } - } - - /** Return box method for arrays of elements of the given kind. */ - public Symbol getBoxArraySymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return BOX_ZARRAY; - case TypeTags.BYTE : return BOX_BARRAY; - case TypeTags.SHORT : return BOX_SARRAY; - case TypeTags.CHAR : return BOX_CARRAY; - case TypeTags.INT : return BOX_IARRAY; - case TypeTags.LONG : return BOX_LARRAY; - case TypeTags.FLOAT : return BOX_FARRAY; - case TypeTags.DOUBLE : return BOX_DARRAY; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - unboxing primitives - - /** Return unbox method returning values of the given type. */ - public Symbol getUnboxValueSymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getUnboxValueSymbol(kind); - case UnboxedArrayType(Type elemtp): - return getUnboxArraySymbol(elemtp); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return unbox method returning values of the given kind. */ - public Symbol getUnboxValueSymbol(int kind) { - switch (kind) { - case TypeTags.UNIT : return UNBOX_UVALUE; - case TypeTags.BOOLEAN: return UNBOX_ZVALUE; - case TypeTags.BYTE : return UNBOX_BVALUE; - case TypeTags.SHORT : return UNBOX_SVALUE; - case TypeTags.CHAR : return UNBOX_CVALUE; - case TypeTags.INT : return UNBOX_IVALUE; - case TypeTags.LONG : return UNBOX_LVALUE; - case TypeTags.FLOAT : return UNBOX_FVALUE; - case TypeTags.DOUBLE : return UNBOX_DVALUE; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return unbox method returning arrays of elements of the given type. */ - public Symbol getUnboxArraySymbol(Type type) { - switch (type) { - case UnboxedType(int kind): - return getUnboxArraySymbol(kind); - default: - return UNBOX_OARRAY; - } - } - - /** Return unbox method returning arrays of elements of the given kind. */ - public Symbol getUnboxArraySymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return UNBOX_ZARRAY; - case TypeTags.BYTE : return UNBOX_BARRAY; - case TypeTags.SHORT : return UNBOX_SARRAY; - case TypeTags.CHAR : return UNBOX_CARRAY; - case TypeTags.INT : return UNBOX_IARRAY; - case TypeTags.LONG : return UNBOX_LARRAY; - case TypeTags.FLOAT : return UNBOX_FARRAY; - case TypeTags.DOUBLE : return UNBOX_DARRAY; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - conversion primitives - - /** Return conversion method for given types. */ - public Symbol getConvertSymbol(Type from, Type to) { - switch (from) { - case UnboxedType(int kind): - return getConvertSymbol(kind, to); - default: - throw Debug.abort("illegal case", from); - } - } - - /** Return conversion method for given type and type kind. */ - public Symbol getConvertSymbol(Type from, int to) { - switch (from) { - case UnboxedType(int kind): - return getConvertSymbol(kind, to); - default: - throw Debug.abort("illegal case", from); - } - } - - /** Return conversion method for given type kind and type. */ - public Symbol getConvertSymbol(int from, Type to) { - switch (to) { - case UnboxedType(int kind): - return getConvertSymbol(from, kind); - default: - throw Debug.abort("illegal case", to); - } - } - - /** Return conversion method for given kind types. */ - public Symbol getConvertSymbol(int from, int to) { - switch (from) { - case TypeTags.BYTE : - switch (to) { - case TypeTags.BYTE : return B2B; - case TypeTags.SHORT : return B2S; - case TypeTags.CHAR : return B2C; - case TypeTags.INT : return B2I; - case TypeTags.LONG : return B2L; - case TypeTags.FLOAT : return B2F; - case TypeTags.DOUBLE : return B2D; - } break; - case TypeTags.SHORT : - switch (to) { - case TypeTags.BYTE : return S2B; - case TypeTags.SHORT : return S2S; - case TypeTags.CHAR : return S2C; - case TypeTags.INT : return S2I; - case TypeTags.LONG : return S2L; - case TypeTags.FLOAT : return S2F; - case TypeTags.DOUBLE : return S2D; - } break; - case TypeTags.CHAR : - switch (to) { - case TypeTags.BYTE : return C2B; - case TypeTags.SHORT : return C2S; - case TypeTags.CHAR : return C2C; - case TypeTags.INT : return C2I; - case TypeTags.LONG : return C2L; - case TypeTags.FLOAT : return C2F; - case TypeTags.DOUBLE : return C2D; - } break; - case TypeTags.INT : - switch (to) { - case TypeTags.BYTE : return I2B; - case TypeTags.SHORT : return I2S; - case TypeTags.CHAR : return I2C; - case TypeTags.INT : return I2I; - case TypeTags.LONG : return I2L; - case TypeTags.FLOAT : return I2F; - case TypeTags.DOUBLE : return I2D; - } break; - case TypeTags.LONG : - switch (to) { - case TypeTags.BYTE : return L2B; - case TypeTags.SHORT : return L2S; - case TypeTags.CHAR : return L2C; - case TypeTags.INT : return L2I; - case TypeTags.LONG : return L2L; - case TypeTags.FLOAT : return L2F; - case TypeTags.DOUBLE : return L2D; - } break; - case TypeTags.FLOAT : - switch (to) { - case TypeTags.BYTE : return F2B; - case TypeTags.SHORT : return F2S; - case TypeTags.CHAR : return F2C; - case TypeTags.INT : return F2I; - case TypeTags.LONG : return F2L; - case TypeTags.FLOAT : return F2F; - case TypeTags.DOUBLE : return F2D; - } break; - case TypeTags.DOUBLE : - switch (to) { - case TypeTags.BYTE : return D2B; - case TypeTags.SHORT : return D2S; - case TypeTags.CHAR : return D2C; - case TypeTags.INT : return D2I; - case TypeTags.LONG : return D2L; - case TypeTags.FLOAT : return D2F; - case TypeTags.DOUBLE : return D2D; - } break; - } - throw Debug.abort("illegal case: " + from + " -> " + to); - } - - //######################################################################## - // Primitives interface - array get and set primitives - - /** Return length method for arrays of the given type. */ - public Symbol getArrayLengthSymbol(Type type) { - switch (type) { - case UnboxedArrayType(UnboxedType(int kind)): - return getArrayLengthSymbol(kind); - case UnboxedArrayType(_): - return OARRAY_LENGTH; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return length method for arrays of elements of the given kind. */ - public Symbol getArrayLengthSymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return ZARRAY_LENGTH; - case TypeTags.BYTE : return BARRAY_LENGTH; - case TypeTags.SHORT : return SARRAY_LENGTH; - case TypeTags.CHAR : return CARRAY_LENGTH; - case TypeTags.INT : return IARRAY_LENGTH; - case TypeTags.LONG : return LARRAY_LENGTH; - case TypeTags.FLOAT : return FARRAY_LENGTH; - case TypeTags.DOUBLE : return DARRAY_LENGTH; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return get method for arrays of the given type. */ - public Symbol getArrayGetSymbol(Type type) { - switch (type) { - case UnboxedArrayType(UnboxedType(int kind)): - return getArrayGetSymbol(kind); - case UnboxedArrayType(_): - return OARRAY_GET; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return get method for arrays of elements of the given kind. */ - public Symbol getArrayGetSymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return ZARRAY_GET; - case TypeTags.BYTE : return BARRAY_GET; - case TypeTags.SHORT : return SARRAY_GET; - case TypeTags.CHAR : return CARRAY_GET; - case TypeTags.INT : return IARRAY_GET; - case TypeTags.LONG : return LARRAY_GET; - case TypeTags.FLOAT : return FARRAY_GET; - case TypeTags.DOUBLE : return DARRAY_GET; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return set method for arrays of the given type. */ - public Symbol getArraySetSymbol(Type type) { - switch (type) { - case UnboxedArrayType(UnboxedType(int kind)): - return getArraySetSymbol(kind); - case UnboxedArrayType(_): - return OARRAY_SET; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Return set method for arrays of elements of the given kind. */ - public Symbol getArraySetSymbol(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return ZARRAY_SET; - case TypeTags.BYTE : return BARRAY_SET; - case TypeTags.SHORT : return SARRAY_SET; - case TypeTags.CHAR : return CARRAY_SET; - case TypeTags.INT : return IARRAY_SET; - case TypeTags.LONG : return LARRAY_SET; - case TypeTags.FLOAT : return FARRAY_SET; - case TypeTags.DOUBLE : return DARRAY_SET; - default : throw Debug.abort("illegal kind " + kind); - } - } - - //######################################################################## - // Primitives interface - class names - - /* Return name to use in "Class.forName(<name>)" for the given type. */ - public String getNameForClassForName(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, _): - return getNameForClassForName(symbol); - case UnboxedType(int kind): - return getNameForClassForName(kind); - case UnboxedArrayType(TypeRef(_, Symbol symbol, _)): - return "[L" + getNameForClassForName(symbol) + ";"; - case UnboxedArrayType(Type elemtp): - return "[" + getNameForClassForName(elemtp); - default: - throw Debug.abort("illegal case", type); - } - } - - /* Return name to use in "Class.forName(<name>)" for the given symbol. */ - public String getNameForClassForName(Symbol symbol) { - return getJREClassName(symbol); - } - - /* Return name to use in "Class.forName(<name>)" for the given kind. */ - public String getNameForClassForName(int kind) { - switch (kind) { - case TypeTags.BOOLEAN: return "Z"; - case TypeTags.BYTE : return "B"; - case TypeTags.SHORT : return "S"; - case TypeTags.CHAR : return "C"; - case TypeTags.INT : return "I"; - case TypeTags.LONG : return "J"; - case TypeTags.FLOAT : return "F"; - case TypeTags.DOUBLE : return "D"; - default : throw Debug.abort("illegal kind " + kind); - } - } - - /** Return the JRE name of given class. */ - public String getJREClassName(Symbol clasz) { - assert clasz.isClassType(): Debug.show(clasz); - if (clasz == definitions.ANY_CLASS || - clasz == definitions.ANYREF_CLASS) - return getJREClassName(definitions.OBJECT_CLASS); - String suffix = clasz.isModuleClass() && !clasz.isJava() ? "$" : ""; - return jreNameWriter.toString(clasz, suffix); - } - - /** Return the CLR name of given class. */ - public String getCLRClassName(Symbol clasz) { - assert clasz.isClassType(): Debug.show(clasz); - return clrNameWriter.toString(clasz); - } - - //######################################################################## -} diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java deleted file mode 100644 index 3ea0cded19..0000000000 --- a/sources/scalac/backend/jvm/GenJVM.java +++ /dev/null @@ -1,1927 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.backend.jvm; - -import java.io.*; -import java.nio.ByteBuffer; -import java.util.*; - -import ch.epfl.lamp.fjbg.*; -import ch.epfl.lamp.util.Pair; - -import scala.tools.util.Position; - -import scalac.*; -import scalac.ast.Tree; -import scalac.atree.AConstant; -import scalac.backend.*; -import scalac.symtab.*; -import scalac.symtab.classfile.ClassfileConstants; -import scalac.symtab.classfile.Pickle; -import scalac.transformer.*; -import scalac.util.*; - - -/* Several things which are done here should in fact be done in - * previous phases, namely: - * - * - code linearisation (i.e. representation of code as a list of - * instructions), - * - * - removal of implicit "this" selection, - * - * - removal of implicit "unit" values, - * - * - removal of implicit conversion, - * - * - removal of "if"s without explicit "else" part, - * - * - expansion of "==", - * - * - introduction of a special primitive for string concatenation, - * - * - initialisation of module instance variable. - */ - -/** - * Backend generating JVM byte-codes. - * - * @version 2.0 - * @author Michel Schinz - */ - -public class GenJVM { - protected final static String JAVA_LANG_OBJECT = "java.lang.Object"; - protected final static String JAVA_LANG_STRING = "java.lang.String"; - protected final static String JAVA_LANG_STRINGBUFFER = - "java.lang.StringBuffer"; - protected final static String JAVA_RMI_REMOTE = "java.rmi.Remote"; - protected final static String JAVA_RMI_REMOTEEXCEPTION = - "java.rmi.RemoteException"; - - protected final static String SCALA_RUNTIME_RUNTIME = - "scala.runtime.RunTime"; - - protected final static String SCALA_ATTR = - ClassfileConstants.SCALA_N.toString(); - - protected final static String MODULE_INSTANCE_FIELD_NAME = "MODULE$"; - - protected final static String CONSTRUCTOR_STRING = - "<init>"; // TODO get it from FJBG - - protected final JObjectType JAVA_LANG_OBJECT_T = - new JObjectType(JAVA_LANG_OBJECT); - protected final JObjectType JAVA_LANG_STRING_T = - new JObjectType(JAVA_LANG_STRING); - protected final JObjectType JAVA_LANG_STRINGBUFFER_T = - new JObjectType (JAVA_LANG_STRINGBUFFER); - protected final JObjectType JAVA_LANG_THROWABLE_T = - new JObjectType("java.lang.Throwable"); - - protected final Symbol JAVA_RMI_REMOTE_CLASS; - protected final Symbol SCALA_SERIAL_VERSION_UID_CONSTR; - - protected final Global global; - protected final Definitions defs; - protected final Primitives prims; - - protected final Phase refCheckPhase; - protected final AddInterfacesPhase addInterfacesPhase; - - protected final FJBGContext fjbgContext; - - protected final ArrayList pickles = new ArrayList(); - - public GenJVM(Global global) { - this.global = global; - this.defs = global.definitions; - this.prims = global.primitives; - - this.refCheckPhase = global.PHASE.REFCHECK.phase(); - this.addInterfacesPhase = - (AddInterfacesPhase)global.PHASE.ADDINTERFACES.phase(); - - this.fjbgContext = new FJBGContext(); - - initTypeMap(); - initArithPrimMap(); - - JAVA_RMI_REMOTE_CLASS = defs.getClass(JAVA_RMI_REMOTE); - SCALA_SERIAL_VERSION_UID_CONSTR = - defs.getClass("scala.SerialVersionUID") .primaryConstructor(); - } - - /// Code generation - ////////////////////////////////////////////////////////////////////// - - /** Generate code for the given units. */ - public static void translate(Global global, CompilationUnit[] units) { - GenJVM translator = new GenJVM(global); - for (int i = 0; i < units.length; i++) translator.translate(units[i]); - } - - /** - * Generate code for the given unit. - */ - public void translate(CompilationUnit unit) { - try { - for (int i = 0; i < unit.body.length; ++i) - gen(Context.EMPTY.withSourceFileName(unit.source.getFile().getName()), - unit.body[i]); - } catch (JCode.OffsetTooBigException e) { - if (global.debug) e.printStackTrace(); - global.error(e.getMessage()); - } - // write .symbl files (must be generated after .class files) - for (int i = 0; i < pickles.size() / 2; i++) { - JClass clazz = (JClass)pickles.get(2 * i + 0); - Pickle pickle = (Pickle)pickles.get(2 * i + 1); - writeSymblFile(clazz, pickle); - } - pickles.clear(); - } - - /** - * Generate code to perform the side effects associated with the - * given tree (i.e. no value should remain on the stack - * afterwards). - */ - protected void gen(Context ctx, Tree tree) throws JCode.OffsetTooBigException { - startCodeForTree(ctx, tree); - - Symbol sym = tree.symbol(); - - switch (tree) { - case PackageDef(_, Tree.Template impl): - gen(ctx, impl); - break; - - case ClassDef(_, _, _, _, _, Tree.Template impl) : { - Tree.ClassDef classDef = (Tree.ClassDef)tree; - - Context ctx1 = enterClass(ctx, sym); - - addValueClassMembers(ctx1, classDef); - gen(ctx1, impl); - AConstant[] aargs = global.getAttrArguments - (sym, SCALA_SERIAL_VERSION_UID_CONSTR); - if (ctx1.isModuleClass || aargs != null) { - JMethod clinit = getClassConstructorMethod(ctx1); - if (clinit.getCode().getSize() == 0) { - Context ctx2 = - ctx1.withMethod(clinit, Collections.EMPTY_MAP, false); - completeClassConstructor(ctx2, sym); - ctx2.code.emitRETURN(); - genLocalVariableTable(ctx2); - } - } - - leaveClass(ctx1, sym); - } break; - - case Template(_, Tree[] body): - gen(ctx, body); - break; - - case ValDef(_, Name name, _, Tree rhs): { - if (ctx.method == null) - break; // ignore ValDefs in classes, handled elsewhere - - JType valType = typeStoJ(sym.info()); - JLocalVariable var = - ctx.method.addNewLocalVariable(valType, name.toString()); - ctx.locals.put(sym, new Integer(var.getIndex())); - - assert (rhs != Tree.Empty) : Debug.show(sym); - genLoad(ctx, rhs, valType); - ctx.code.emitSTORE(var); - } break; - - case DefDef(_, _, _, _, _, Tree rhs): { - Tree.DefDef defDef = (Tree.DefDef)tree; - boolean retry = false; - do { - Context ctx1 = enterMethod(ctx, defDef, retry); - try { - if (! Modifiers.Helper.isAbstract(sym.flags)) { - JType retType = ctx1.method.getReturnType(); - genLoad(ctx1, rhs, retType); - if (sym.name == Names.CLASS_CONSTRUCTOR) - completeClassConstructor(ctx1, sym.owner()); - ctx1.code.emitRETURN(retType); - ctx1.method.freeze(); - } - leaveMethod(ctx1); - break; - } catch (JCode.OffsetTooBigException e) { - ctx1.clazz.removeMethod(ctx1.method); - if (retry) - throw Debug.abort("method too big", sym, e); - retry = true; - } - } while (retry); - } break; - - case Return(Tree expr): { - JType retType = ctx.method.getReturnType(); - genLoad(ctx, expr, retType); - ctx.code.emitRETURN(retType); - } break; - - case Typed(Tree expr, _): - gen(ctx, expr); - break; - - case Empty: - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case TypeApply(_, _): - case FunType(_, _): - case CompoundType(_, _): - case AppliedType(_,_): - break; - - default: - genLoad(ctx, tree, JType.VOID); - } - - endCodeForTree(ctx, tree); - } - - protected void gen(Context ctx, Tree[] trees) - throws JCode.OffsetTooBigException { - for (int i = 0; i < trees.length; ++i) - gen(ctx, trees[i]); - } - - /** - * Generate code to load the value of the given tree on the - * stack, and make sure it is of the given expected type. - */ - protected JType genLoad(Context ctx, Tree tree, JType expectedType) - throws JCode.OffsetTooBigException { - startCodeForTree(ctx, tree); - - JType generatedType = null; - Symbol sym = tree.symbol(); - - switch (tree) { - case LabelDef(_, Tree.Ident[] params, Tree rhs): { - JCode.Label label = ctx.code.newLabel(); - label.anchorToNext(); - ctx.labels.put(sym, new Pair(label, params)); - generatedType = genLoad(ctx, rhs, expectedType); - ctx.labels.remove(sym); - } break; - - case Block(Tree[] stats, Tree value): { - int statsNum = stats.length; - for (int i = 0; i < stats.length; ++i) - gen(ctx, stats[i]); - genLoad(ctx, value, expectedType); - generatedType = expectedType; - } break; - - case Typed(Tree expr, _): - genLoad(ctx, expr, expectedType); - generatedType = expectedType; - break; - - case New(Tree init): - String className = javaName(tree.type.symbol()); - ctx.code.emitNEW(className); - ctx.code.emitDUP(); - gen(ctx, init); - generatedType = new JObjectType(className); - break; - - case Apply(TypeApply(Tree fun, Tree[] args), _): { - genLoadQualifier(ctx, fun); - - JType type = typeStoJ(args[0].type); - if (fun.symbol() == defs.ANY_IS_ERASED) { - ctx.code.emitINSTANCEOF((JReferenceType)type); - generatedType = JType.BOOLEAN; - } else if (fun.symbol() == defs.ANY_AS_ERASED) { - ctx.code.emitCHECKCAST((JReferenceType)type); - generatedType = type; - } else - throw Debug.abort("unexpected type application", tree); - } break; - - case Apply(Tree fun, Tree[] args): { - Symbol funSym = fun.symbol(); - - if (funSym.isLabel()) { - Pair/*<Label, Tree[]>*/ labelAndIdents = - (Pair)ctx.labels.get(funSym); - assert labelAndIdents != null : Debug.show(funSym); - JMethodType funType = (JMethodType)typeStoJ(funSym.info()); - - JCode.Label label = (JCode.Label)labelAndIdents.fst; - Tree[] idents = (Tree[])labelAndIdents.snd; - assert idents.length == args.length; - - for (int i = 0; i < args.length; ++i) - genLoad(ctx, args[i], typeStoJ(args[i].type)); - for (int i = idents.length; i > 0; --i) - genStoreEpilogue(ctx, idents[i-1]); - ctx.code.emitGOTO_maybe_W(label, ctx.useWideJumps); - generatedType = funType.getReturnType(); - } else if (isKnownPrimitive(funSym)) { - Primitive prim = prims.getPrimitive(funSym); - - switch (prim) { - case CONCAT: - genStringConcatenation(ctx, liftStringConcatenations(tree)); - generatedType = JAVA_LANG_STRING_T; - break; - - case POS: case NEG: - case ADD: case SUB: case MUL: case DIV: case MOD: - case NOT: case OR : case XOR: case AND: - case LSL: case LSR: case ASR: - Tree[] allArgs = extractPrimitiveArgs((Tree.Apply)tree); - allArgs[0] = unbox(allArgs[0]); - JType resType = typeStoJ(tree.type); - genArithPrim(ctx, prim, allArgs, resType, expectedType); - generatedType = resType; - break; - - case ID: case NI: - case EQ: case NE: case LT: case LE: case GE: case GT: - case ZNOT: case ZOR: case ZAND: - JCode.Label falseLabel = ctx.code.newLabel(); - JCode.Label afterLabel = ctx.code.newLabel(); - genCond(ctx, tree, falseLabel, false); - ctx.code.emitICONST_1(); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - falseLabel.anchorToNext(); - ctx.code.emitICONST_0(); - afterLabel.anchorToNext(); - generatedType = JType.BOOLEAN; - break; - - case THROW: - assert args.length == 0; - genThrow(ctx, ((Tree.Select)fun).qualifier); - // We pretend that we generated something of the - // expected type, to avoid trying to generate - // bogus conversions. - generatedType = expectedType; - break; - - case SYNCHRONIZED: { - assert args.length == 1; - Tree qual = ((Tree.Select)fun).qualifier; - genSynchronized(ctx, qual, args[0], expectedType); - generatedType = expectedType; - } break; - - case NEW_OARRAY: { - assert args.length == 2; - genRefArrayCreate(ctx, args[0], args[1]); - generatedType = expectedType; - } break; - - case NEW_ZARRAY : case NEW_BARRAY : case NEW_SARRAY : - case NEW_CARRAY : case NEW_IARRAY : case NEW_LARRAY : - case NEW_FARRAY : case NEW_DARRAY : - assert args.length == 1; - genArrayCreate(ctx, prim, args[0]); - generatedType = JAVA_LANG_OBJECT_T; // TODO refine - break; - - case ZARRAY_SET : case BARRAY_SET : case SARRAY_SET : - case CARRAY_SET : case IARRAY_SET : case LARRAY_SET : - case FARRAY_SET : case DARRAY_SET : case OARRAY_SET : - assert args.length == 3; - genArrayUpdate(ctx, args[0], args[1], args[2]); - generatedType = JType.VOID; - break; - - case ZARRAY_GET : case BARRAY_GET : case SARRAY_GET : - case CARRAY_GET : case IARRAY_GET : case LARRAY_GET : - case FARRAY_GET : case DARRAY_GET : case OARRAY_GET : - assert args.length == 2 : "get - " + args.length; - genArrayAccess(ctx, args[0], args[1]); - generatedType = getArrayElementType(args[0]); - break; - - case ZARRAY_LENGTH : case BARRAY_LENGTH : case SARRAY_LENGTH : - case CARRAY_LENGTH : case IARRAY_LENGTH : case LARRAY_LENGTH : - case FARRAY_LENGTH : case DARRAY_LENGTH : case OARRAY_LENGTH : - assert args.length == 1 : args.length; - genArrayLength(ctx, args[0]); - generatedType = JType.INT; - break; - - case B2B: case B2S: case B2C: case B2I: case B2L: case B2F: case B2D: - case S2B: case S2S: case S2C: case S2I: case S2L: case S2F: case S2D: - case C2B: case C2S: case C2C: case C2I: case C2L: case C2F: case C2D: - case I2B: case I2S: case I2C: case I2I: case I2L: case I2F: case I2D: - case L2B: case L2S: case L2C: case L2I: case L2L: case L2F: case L2D: - case F2B: case F2S: case F2C: case F2I: case F2L: case F2F: case F2D: - case D2B: case D2S: case D2C: case D2I: case D2L: case D2F: case D2D: - assert args.length == 1 : args.length; - JType fromType = typeStoJ(args[0].type); - genLoad(ctx, args[0], fromType); - ctx.code.emitT2T(fromType, expectedType); - generatedType = expectedType; - break; - - default: - throw Debug.abort("unknown primitive", prim); - } - } else { - JMethodType funType = (JMethodType)typeStoJ(funSym.info()); - JType[] argTypes = funType.getArgumentTypes(); - - boolean isConstrCall = funSym.isInitializer(); - boolean isSuperCall = false; - switch (fun) { - case Select(Super(_, _), _): isSuperCall = true; - } - - boolean isStatic = isStaticMember(funSym); - if (!isStatic) - genLoadQualifier(ctx, fun); - for (int i = 0; i < args.length; ++i) - genLoad(ctx, args[i], argTypes[i]); - - String clsName = isSuperCall - ? ctx.clazz.getSuperclassName() - : javaName(funSym.owner()); - String mthName = funSym.name.toString(); - - funSym.owner().info(); // [HACK] ensure that flags are - // transformed. - - if (funSym.owner().isInterface()) - ctx.code.emitINVOKEINTERFACE(clsName, mthName, funType); - else { - if (isConstrCall || isSuperCall) { - ctx.code.emitINVOKESPECIAL(clsName, mthName, funType); - if (isConstrCall && isSuperCall && ctx.isModuleClass) { - // Initialise module instance field ASAP - ctx.code.emitALOAD_0(); - ctx.code.emitPUTSTATIC(ctx.clazz.getName(), - MODULE_INSTANCE_FIELD_NAME, - ctx.clazz.getType()); - } - } else if (isStatic) - ctx.code.emitINVOKESTATIC(clsName, mthName, funType); - else - ctx.code.emitINVOKEVIRTUAL(clsName, mthName, funType); - } - generatedType = funType.getReturnType(); - } - } break; - - case Ident(_): - JType type = typeStoJ(sym.info()); - if (sym.isModule()) { - String javaSymName = javaName(sym.moduleClass()); - ctx.code.emitGETSTATIC(javaSymName, - MODULE_INSTANCE_FIELD_NAME, - type); - generatedType = type; - } else if (sym.isStatic()) { - JType fieldType = typeStoJ(sym.info()); - String className = javaName(sym.owner()); - String fieldName = sym.name.toString(); - ctx.code.emitGETSTATIC(className, fieldName, fieldType); - generatedType = type; - } else { - assert ctx.locals.containsKey(sym) - : Debug.show(sym) + " not in " + ctx.locals; - int index = ((Integer)(ctx.locals.get(sym))).intValue(); - ctx.code.emitLOAD(index, type); - generatedType = type; - } - break; - - case Select(Tree qualifier, _): - JType fieldType = typeStoJ(sym.info()); - String className = javaName(sym.owner()); - String fieldName = sym.name.toString(); - if (sym.isStatic()) { - ctx.code.emitGETSTATIC(className, fieldName, fieldType); - } else { - genLoadQualifier(ctx, tree); - ctx.code.emitGETFIELD(className, fieldName, fieldType); - } - generatedType = fieldType; - break; - - case Assign(Tree lhs, Tree rhs): { - genStorePrologue(ctx, lhs); - genLoad(ctx, rhs, typeStoJ(lhs.symbol().info())); - genStoreEpilogue(ctx, lhs); - generatedType = JType.VOID; - } break; - - case If(Tree cond, Tree thenp, Tree elsep): { - JType finalType = typeStoJ(tree.type); - - JCode.Label elseLabel = ctx.code.newLabel(); - genCond(ctx, cond, elseLabel, false); - genLoad(ctx, thenp, finalType); - JCode.Label afterLabel = ctx.code.newLabel(); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - elseLabel.anchorToNext(); - genLoad(ctx, elsep, finalType); - afterLabel.anchorToNext(); - generatedType = finalType; - } break; - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): { - JCode.Label[] labels = ctx.code.newLabels(bodies.length); - JCode.Label defaultLabel = ctx.code.newLabel(); - JCode.Label afterLabel = ctx.code.newLabel(); - - genLoad(ctx, test, JType.INT); - ctx.code.emitSWITCH(tags, labels, defaultLabel, 0.9); - for (int i = 0; i < bodies.length; ++i) { - labels[i].anchorToNext(); - genLoad(ctx, bodies[i], expectedType); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - } - defaultLabel.anchorToNext(); - genLoad(ctx, otherwise, expectedType); - afterLabel.anchorToNext(); - generatedType = expectedType; - } break; - - case This(_): - case Super(_, _): - ctx.code.emitALOAD_0(); - generatedType = JAVA_LANG_OBJECT_T; - break; - - case Literal(AConstant value): - generatedType = genLoadLiteral(ctx, value, expectedType); - break; - - case Empty: - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case TypeApply(_, _): - case FunType(_, _): - case CompoundType(_, _): - case AppliedType(_,_): - generatedType = JType.VOID; - break; - - case Sequence(_): - case ModuleDef(_,_,_,_): - case PatDef(_,_,_): - case Import(_, _): - case CaseDef(_, _, _): - case Visitor(_): - case Function(_, _): - throw Debug.abort("unexpected node", tree); - default: - throw Debug.abort("unknown node", tree); - } - - // Pop unneeded result from stack, or widen it if needed. - if (expectedType == JType.VOID && generatedType != JType.VOID) { - if (generatedType == JType.LONG || generatedType == JType.DOUBLE) - ctx.code.emitPOP2(); - else - ctx.code.emitPOP(); - } else if (! (expectedType == JType.VOID - || generatedType == expectedType - || generatedType.isReferenceType())) - ctx.code.emitT2T(generatedType, expectedType); - - endCodeForTree(ctx, tree); - return expectedType; - } - - /** - * Generate code to load the qualifier of the given tree, which - * can be implicitely "this". - */ - protected void genLoadQualifier(Context ctx, Tree tree) - throws JCode.OffsetTooBigException { - switch (tree) { - case Ident(_): - break; - case Select(Create(_, _), _): - break; - case Select(Tree qualifier, _): - genLoad(ctx, qualifier, JAVA_LANG_OBJECT_T); - break; - default: - throw Debug.abort("unknown qualifier", tree); - } - } - - protected JType genLoadLiteral(Context ctx, AConstant lit, JType type) { - switch (lit) { - case UNIT: - return JType.VOID; - case BOOLEAN(boolean value): - ctx.code.emitPUSH(value); - return JType.BOOLEAN; - case BYTE(byte value): - ctx.code.emitPUSH(value); - return JType.BYTE; - case SHORT(short value): - ctx.code.emitPUSH(value); - return JType.SHORT; - case CHAR(char value): - ctx.code.emitPUSH(value); - return JType.CHAR; - case INT(int value): - ctx.code.emitPUSH(value); - return JType.INT; - case LONG(long value): - ctx.code.emitPUSH(value); - return JType.LONG; - case FLOAT(float value): - ctx.code.emitPUSH(value); - return JType.FLOAT; - case DOUBLE(double value): - ctx.code.emitPUSH(value); - return JType.DOUBLE; - case STRING(String value): - ctx.code.emitPUSH(value); - return JAVA_LANG_STRING_T; - case SYMBOL_NAME(Symbol value): - ctx.code.emitPUSH(javaName(value)); - return JAVA_LANG_STRING_T; - case NULL: - if (type != JType.VOID) ctx.code.emitACONST_NULL(); - return type; - default: - throw Debug.abort("unknown literal", lit); - } - } - - /** - * Generate code to prepare the storage of a value in the location - * represented by the tree. - */ - protected void genStorePrologue(Context ctx, Tree tree) - throws JCode.OffsetTooBigException { - genLoadQualifier(ctx, tree); - } - - /** - * Generate code to perform the storage of the value on top of - * stack in the location represented by the tree. - */ - protected void genStoreEpilogue(Context ctx, Tree tree) { - Symbol sym = tree.symbol(); - if (sym.owner().isClass()) { - String ownerName = javaName(sym.owner()); - if (isStaticMember(sym)) - ctx.code.emitPUTSTATIC(ownerName, - sym.name.toString(), - typeStoJ(sym.info())); - else - ctx.code.emitPUTFIELD(ownerName, - sym.name.toString(), - typeStoJ(sym.info())); - } else { - assert ctx.locals.containsKey(sym) - : Debug.show(sym) + " not in " + ctx.locals; - int index = ((Integer)(ctx.locals.get(sym))).intValue(); - ctx.code.emitSTORE(index, typeStoJ(sym.info())); - } - } - - /** - * Generate code to evaluate the condition associated with the - * given tree and jump to the target when the condition is equal - * to the given value. - */ - protected void genCond(Context ctx, - Tree tree, - JCode.Label target, - boolean when) - throws JCode.OffsetTooBigException { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (isJumpingPrimitive(fun.symbol())) { - Primitive prim = prims.getPrimitive(fun.symbol()); - Tree[] allArgs = extractPrimitiveArgs((Tree.Apply)tree); - - switch (prim) { - case ID: case NI: case EQ: case NE: - assert allArgs.length == 2; - Tree unbox1 = unbox(allArgs[0]); - Tree unbox2 = unbox(allArgs[1]); - if (!getMaxType(unbox1, unbox2).isReferenceType()) { - allArgs[0] = unbox1; - allArgs[1] = unbox2; - genCompPrim(ctx, prim, allArgs, target, when); - } else { - genEqPrim(ctx, prim, allArgs, target, when); - } - return; - - case LT: case LE: case GE: case GT: - assert allArgs.length == 2; - allArgs[0] = unbox(allArgs[0]); - genCompPrim(ctx, prim, allArgs, target, when); - return; - - case ZNOT: - assert allArgs.length == 1; - genCond(ctx, unbox(allArgs[0]), target, !when); - return; - - case ZOR: - case ZAND: - if (when ^ (prim == Primitive.ZAND)) { - // x || y jump if true -or- x && y jump if false - genCond(ctx, unbox(allArgs[0]), target, when); - genCond(ctx, allArgs[1], target, when); - } else { - // x || y jump if false -or- x && y jump if true - JCode.Label afterLabel = ctx.code.newLabel(); - genCond(ctx, unbox(allArgs[0]), afterLabel, !when); - genCond(ctx, allArgs[1], target, when); - afterLabel.anchorToNext(); - } - return; - } - } - } - // Default case: the condition is not a comparison or logical - // primitive. - genLoad(ctx, tree, JType.BOOLEAN); - if (when) - ctx.code.emitIFNE(target); - else - ctx.code.emitIFEQ(target); - } - - protected Map/*<Primitive, Instruction>*/ arithPrimMap; - protected void addPrim(Primitive prim, - JOpcode z, - JOpcode i, - JOpcode l, - JOpcode f, - JOpcode d) { - arithPrimMap.put(prim, new JOpcode[] { z, i, l, f, d }); - } - - protected void initArithPrimMap() { - arithPrimMap = new HashMap(); - /* boolean, int & al., long, float, double */ - addPrim(Primitive.ADD, - null, JOpcode.IADD, JOpcode.LADD, JOpcode.FADD, JOpcode.DADD); - addPrim(Primitive.SUB, - null, JOpcode.ISUB, JOpcode.LSUB, JOpcode.FSUB, JOpcode.DSUB); - addPrim(Primitive.MUL, - null, JOpcode.IMUL, JOpcode.LMUL, JOpcode.FMUL, JOpcode.DMUL); - addPrim(Primitive.DIV, - null, JOpcode.IDIV, JOpcode.LDIV, JOpcode.FDIV, JOpcode.DDIV); - addPrim(Primitive.MOD, - null, JOpcode.IREM, JOpcode.LREM, JOpcode.FREM, JOpcode.DREM); - addPrim(Primitive.AND, - JOpcode.IAND, JOpcode.IAND, JOpcode.LAND, null, null); - addPrim(Primitive.OR, - JOpcode.IOR, JOpcode.IOR, JOpcode.LOR, null, null); - addPrim(Primitive.XOR, - JOpcode.IXOR, JOpcode.IXOR, JOpcode.LXOR, null, null); - addPrim(Primitive.LSL, - null, JOpcode.ISHL, JOpcode.LSHL, null, null); - addPrim(Primitive.LSR, - null, JOpcode.IUSHR, JOpcode.LUSHR, null, null); - addPrim(Primitive.ASR, - null, JOpcode.ISHR, JOpcode.LSHR, null, null); - addPrim(Primitive.POS, - null, null, null, null, null); - addPrim(Primitive.NEG, - null, JOpcode.INEG, JOpcode.LNEG, JOpcode.FNEG, JOpcode.DNEG); - } - - /** - * Generate code for the given arithmetic primitive, applied on - * the given arguments. - */ - protected void genArithPrim(Context ctx, - Primitive prim, - Tree[] args, - JType resType, - JType expectedType) - throws JCode.OffsetTooBigException { - int arity = args.length; - int resTypeIdx = getTypeIndex(resType); - - if ((prim == Primitive.LSL) - || (prim == Primitive.LSR) - || (prim == Primitive.ASR)) { - genLoad(ctx, args[0], resType); - genLoad(ctx, args[1], JType.INT); - } else { - for (int i = 0; i < arity; ++i) - genLoad(ctx, args[i], resType); - } - - if (prim == Primitive.NOT) { - if (resType == JType.LONG) { - ctx.code.emitPUSH(-1L); - ctx.code.emitLXOR(); - } else { - assert resType == JType.INT; - ctx.code.emitPUSH(-1); - ctx.code.emitIXOR(); - } - } else { - assert arithPrimMap.containsKey(prim); - JOpcode primInst = ((JOpcode[])arithPrimMap.get(prim))[resTypeIdx]; - if (primInst != null) - ctx.code.emit(primInst); - } - } - - /** Variable in which temporary objects are stored by the - * implementation of == */ - protected JLocalVariable eqEqTempVar; - - /** - * Generate code for the given equality primitive, applied on the - * given arguments. - */ - protected void genEqPrim(Context ctx, - Primitive prim, - Tree[] args, - JCode.Label target, - boolean when) - throws JCode.OffsetTooBigException { - JType maxType = getMaxType(args); - assert maxType.isReferenceType(): args[0]+" - "+args[1]+" : "+maxType; - // Generate code for all arguments - for (int i = 0; i < args.length; ++i) genLoad(ctx, args[i], maxType); - - if (prim == Primitive.ID) { - if (when) ctx.code.emitIF_ACMPEQ(target); - else ctx.code.emitIF_ACMPNE(target); - } else if (prim == Primitive.NI) { - if (!when) ctx.code.emitIF_ACMPEQ(target); - else ctx.code.emitIF_ACMPNE(target); - } else { - // Comparison between two references. We inline the code - // for the predefined (and final) "=="/"!=" operators, - // which check for null values and then forward the call - // to "equals". "==" could be defined as follows, if - // "null" was an object: - // final def ==(other: Any): boolean = - // if (this == null) other == null else this.equals(other) - assert prim == Primitive.EQ || prim == Primitive.NE; - - if (eqEqTempVar == null || eqEqTempVar.getOwner() != ctx.method) - eqEqTempVar = - ctx.method.addNewLocalVariable(JObjectType.JAVA_LANG_OBJECT, - "eqEqTemp$"); - - ctx.code.emitSTORE(eqEqTempVar); - ctx.code.emitDUP(); - JCode.Label ifNonNullLabel = ctx.code.newLabel(); - ctx.code.emitIFNONNULL(ifNonNullLabel); - ctx.code.emitPOP(); - ctx.code.emitLOAD(eqEqTempVar); - if (when ^ (prim != Primitive.EQ)) - ctx.code.emitIFNULL(target); - else - ctx.code.emitIFNONNULL(target); - JCode.Label afterLabel = ctx.code.newLabel(); - ctx.code.emitGOTO_maybe_W(afterLabel, ctx.useWideJumps); - ifNonNullLabel.anchorToNext(); - ctx.code.emitLOAD(eqEqTempVar); - JMethodType equalsType = - new JMethodType(JType.BOOLEAN, - new JType[] { JObjectType.JAVA_LANG_OBJECT }); - ctx.code.emitINVOKEVIRTUAL(JAVA_LANG_OBJECT, "equals", equalsType); - if (when ^ (prim != Primitive.EQ)) - ctx.code.emitIFNE(target); - else - ctx.code.emitIFEQ(target); - afterLabel.anchorToNext(); - } - } - - /** - * Generate code for the given comparison primitive, applied on - * the given arguments. - */ - protected void genCompPrim(Context ctx, - Primitive prim, - Tree[] args, - JCode.Label target, - boolean when) - throws JCode.OffsetTooBigException { - JType maxType = getMaxType(args); - assert !maxType.isReferenceType(): args[0]+" - "+args[1]+" : "+maxType; - int maxTypeIdx = getTypeIndex(maxType); - int intTypeIdx = getTypeIndex(JType.INT); - boolean intCompareWithZero = false; - // Generate code for all arguments, while detecting - // comparisons with 0, which can be optimised. - for (int i = 0; i < args.length; ++i) { - boolean isIntZero = false; - if (maxTypeIdx <= intTypeIdx) { - switch (args[i]) { - case Literal(AConstant constant): - int intVal; - switch (constant) { - case BOOLEAN(boolean value): - intVal = value ? 1 : 0; - break; - case BYTE(byte value): - intVal = value; - break; - case SHORT(short value): - intVal = value; - break; - case CHAR(char value): - intVal = value; - break; - case INT(int value): - intVal = value; - break; - default: - throw Debug.abort("unknown literal", constant); - } - if (intVal == 0) { - isIntZero = true; - if (i == 0) prim = prim.swap(); - } - } - } - if (intCompareWithZero || !isIntZero) - genLoad(ctx, args[i], maxType); - intCompareWithZero |= isIntZero; - } - - if (maxTypeIdx <= intTypeIdx && !intCompareWithZero) { - // Comparison between ints, no zeros involved - switch (maybeNegatedPrim(prim, !when)) { - case LT: ctx.code.emitIF_ICMPLT(target); break; - case LE: ctx.code.emitIF_ICMPLE(target); break; - case EQ: ctx.code.emitIF_ICMPEQ(target); break; - case NE: ctx.code.emitIF_ICMPNE(target); break; - case GE: ctx.code.emitIF_ICMPGE(target); break; - case GT: ctx.code.emitIF_ICMPGT(target); break; - default: throw Debug.abort("unknown primitive", prim); - } - } else { - // Comparison between longs, floats or double, or between - // one int and zero. - switch (maxType.getTag()) { - case JType.T_LONG: ctx.code.emitLCMP(); break; - case JType.T_FLOAT: ctx.code.emitFCMPG(); break; - case JType.T_DOUBLE: ctx.code.emitDCMPG(); break; - default: - ; // do nothing (int comparison with 0) - } - switch (maybeNegatedPrim(prim, !when)) { - case LT: ctx.code.emitIFLT(target); break; - case LE: ctx.code.emitIFLE(target); break; - case EQ: ctx.code.emitIFEQ(target); break; - case NE: ctx.code.emitIFNE(target); break; - case GE: ctx.code.emitIFGE(target); break; - case GT: ctx.code.emitIFGT(target); break; - default: throw Debug.abort("unknown primitive", prim); - } - } - } - - /** - * Generate code to throw the value returned by the argument. - */ - protected void genThrow(Context ctx, Tree arg) - throws JCode.OffsetTooBigException { - genLoad(ctx, arg, JAVA_LANG_OBJECT_T); - ctx.code.emitCHECKCAST(JAVA_LANG_THROWABLE_T); - ctx.code.emitATHROW(); - } - - /** - * Generate code to synchronise on the object and evaluate the - * code fragment. - */ - protected void genSynchronized(Context ctx, - Tree object, - Tree code, - JType expectedType) - throws JCode.OffsetTooBigException { - JLocalVariable monitorVar = - ctx.method.addNewLocalVariable(JAVA_LANG_OBJECT_T, "monitor"); - genLoad(ctx, object, JAVA_LANG_OBJECT_T); - ctx.code.emitSTORE(monitorVar); - ctx.code.emitLOAD(monitorVar); - ctx.code.emitMONITORENTER(); - int startPC = ctx.code.getPC(); - genLoad(ctx, code, expectedType); - int endPC = ctx.code.getPC(); - ctx.code.emitLOAD(monitorVar); - ctx.code.emitMONITOREXIT(); - - JCode.Label afterLabel = ctx.code.newLabel(); - ctx.code.emitGOTO(afterLabel); - int handlerPC = ctx.code.getPC(); - ctx.code.emitLOAD(monitorVar); - ctx.code.emitMONITOREXIT(); - ctx.code.emitATHROW(); - afterLabel.anchorToNext(); - - ctx.code.addFinallyHandler(startPC, endPC, handlerPC); - } - - /// Arrays - ////////////////////////////////////////////////////////////////////// - - /** - * Generate code to create an array of some basic type, whose size - * will be dynamically computed. - */ - protected void genArrayCreate(Context ctx, Primitive prim, Tree size) - throws JCode.OffsetTooBigException { - genLoad(ctx, size, JType.INT); - JType type; - switch (prim) { - case NEW_ZARRAY : type = JType.BOOLEAN; break; - case NEW_BARRAY : type = JType.BYTE; break; - case NEW_SARRAY : type = JType.SHORT; break; - case NEW_CARRAY : type = JType.CHAR; break; - case NEW_IARRAY : type = JType.INT; break; - case NEW_LARRAY : type = JType.LONG; break; - case NEW_FARRAY : type = JType.FLOAT; break; - case NEW_DARRAY : type = JType.DOUBLE; break; - default: throw Debug.abort("unexpected primitive", prim); - } - ctx.code.emitNEWARRAY(type); - } - - /** - * Generate code to create an array of references, whose size will - * be dynamically computed. - */ - protected void genRefArrayCreate(Context ctx, Tree size, Tree classNameLit) - throws JCode.OffsetTooBigException { - genLoad(ctx, size, JType.INT); - - String className; - switch (classNameLit) { - case Literal(STRING(String name)): className = name; break; - default: throw Debug.abort("invalid argument for oarray", classNameLit); - } - - JReferenceType elemType; - switch (className.charAt(0)) { - case '[': case 'L': - elemType = (JReferenceType)JType.parseSignature(className); break; - default: - elemType = new JObjectType(className); - } - ctx.code.emitANEWARRAY(elemType); - } - - /** - * Generate code to update an array. - */ - protected void genArrayUpdate(Context ctx, Tree array, Tree index, Tree value) - throws JCode.OffsetTooBigException { - genLoad(ctx, array, JAVA_LANG_OBJECT_T); - genLoad(ctx, index, JType.INT); - JType elemType = getArrayElementType(array); - if (elemType.isValueType()) - value = unbox(value); - genLoad(ctx, value, elemType); - ctx.code.emitASTORE(elemType); - } - - /** - * Generate code to load an element of an array. - */ - protected void genArrayAccess(Context ctx, Tree array, Tree index) - throws JCode.OffsetTooBigException { - genLoad(ctx, array, JAVA_LANG_OBJECT_T); - genLoad(ctx, index, JType.INT); - ctx.code.emitALOAD(getArrayElementType(array)); - } - - /** - * Generate code to load the length of an array. - */ - protected void genArrayLength(Context ctx, Tree array) - throws JCode.OffsetTooBigException { - genLoad(ctx, array, JAVA_LANG_OBJECT_T); - ctx.code.emitARRAYLENGTH(); - } - - /** - * Return the Java type of the elements of the array represented - * by the given tree. - */ - protected JType getArrayElementType(Tree array) { - JArrayType arrayType = (JArrayType)typeStoJ(array.type); - return arrayType.getElementType(); - } - - /// String concatenation - ////////////////////////////////////////////////////////////////////// - - protected Tree[] liftStringConcatenations(Tree tree) { - LinkedList accu = new LinkedList(); - liftStringConcatenations(tree, accu); - return (Tree[])accu.toArray(new Tree[accu.size()]); - } - - protected void liftStringConcatenations(Tree tree, LinkedList accu) { - switch (tree) { - case Apply(Select(Tree qualifier, Name selector), Tree[] args): { - Symbol funSym = ((Tree.Apply)tree).fun.symbol(); - if (prims.isPrimitive(funSym) - && prims.getPrimitive(funSym) == Primitive.CONCAT) { - liftStringConcatenations(qualifier, accu); - liftStringConcatenations(args[0], accu); - } else - accu.addLast(tree); - } break; - default: - accu.addLast(tree); - } - } - - /** - * Generate code to concatenate a list of expressions which return - * strings. - */ - protected void genStringConcatenation(Context ctx, Tree[] elements) - throws JCode.OffsetTooBigException { - // Create string buffer - ctx.code.emitNEW(JAVA_LANG_STRINGBUFFER); - ctx.code.emitDUP(); - ctx.code.emitINVOKESPECIAL(JAVA_LANG_STRINGBUFFER, - "<init>", - JMethodType.ARGLESS_VOID_FUNCTION); - - // Append all strings - for (int i = 0; i < elements.length; ++i) { - JType elemType = typeStoJ(elements[i].type); - if (!elemType.equals(JObjectType.JAVA_LANG_STRING) - && elemType.isReferenceType()) - elemType = JObjectType.JAVA_LANG_OBJECT; - genLoad(ctx, elements[i], elemType); - ctx.code.emitINVOKEVIRTUAL(JAVA_LANG_STRINGBUFFER, - "append", - new JMethodType(JAVA_LANG_STRINGBUFFER_T, - new JType[] { elemType })); - } - - // Get resulting string - ctx.code.emitINVOKEVIRTUAL(JAVA_LANG_STRINGBUFFER, - "toString", - new JMethodType(JObjectType.JAVA_LANG_STRING, - JType.EMPTY_ARRAY)); - } - - /// Primitives - ////////////////////////////////////////////////////////////////////// - - /** - * Return true iff the given symbol is a primitive, AND that - * primitive is recognized by this back-end, AND that primitive is - * a "jumping" one. - */ - protected boolean isJumpingPrimitive(Symbol sym) { - if (prims.isPrimitive(sym)) { - switch (prims.getPrimitive(sym)) { - case ID : case NI : case EQ : case NE : - case LT : case LE : case GE : case GT : - case ZNOT : case ZOR : case ZAND : - return true; - } - } - return false; - } - - /** - * Return true iff the given symbol is a primitive, AND that - * primitive is recognized by this back-end. - */ - protected boolean isKnownPrimitive(Symbol sym) { - if (isJumpingPrimitive(sym)) - return true; - - if (prims.isPrimitive(sym)) { - switch (prims.getPrimitive(sym)) { - case POS : case NEG : - case ADD : case SUB : case MUL : case DIV : case MOD : - case NOT : case OR : case XOR : case AND : - case LSL : case LSR : case ASR : - case NEW_ZARRAY : case NEW_BARRAY : case NEW_SARRAY : - case NEW_CARRAY : case NEW_IARRAY : case NEW_LARRAY : - case NEW_FARRAY : case NEW_DARRAY : case NEW_OARRAY : - case ZARRAY_GET : case BARRAY_GET : case SARRAY_GET : - case CARRAY_GET : case IARRAY_GET : case LARRAY_GET : - case FARRAY_GET : case DARRAY_GET : case OARRAY_GET : - case ZARRAY_SET : case BARRAY_SET : case SARRAY_SET : - case CARRAY_SET : case IARRAY_SET : case LARRAY_SET : - case FARRAY_SET : case DARRAY_SET : case OARRAY_SET : - case ZARRAY_LENGTH : case BARRAY_LENGTH : case SARRAY_LENGTH : - case CARRAY_LENGTH : case IARRAY_LENGTH : case LARRAY_LENGTH : - case FARRAY_LENGTH : case DARRAY_LENGTH : case OARRAY_LENGTH : - case IS : case AS : case ID : case NI : - case CONCAT : case THROW : case SYNCHRONIZED: - case B2B: case B2S: case B2C: case B2I: case B2L: case B2F: case B2D: - case S2B: case S2S: case S2C: case S2I: case S2L: case S2F: case S2D: - case C2B: case C2S: case C2C: case C2I: case C2L: case C2F: case C2D: - case I2B: case I2S: case I2C: case I2I: case I2L: case I2F: case I2D: - case L2B: case L2S: case L2C: case L2I: case L2L: case L2F: case L2D: - case F2B: case F2S: case F2C: case F2I: case F2L: case F2F: case F2D: - case D2B: case D2S: case D2C: case D2I: case D2L: case D2F: case D2D: - return true; - - case EQUALS : - case HASHCODE : - case TOSTRING : - case COERCE : - case BOX : - case UNBOX : - case APPLY : case UPDATE : case LENGTH : - return false; - default: - throw Debug.abort("unknown primitive", sym); - } - } else - return false; - } - - /** - * Negate the given primitive only if the second argument is - * true, otherwise return it as is. - */ - protected Primitive maybeNegatedPrim(Primitive prim, boolean negate) { - return negate ? prim.negate() : prim; - } - - /** - * Return all the arguments associated with the primitive - * represented by the given function call. - */ - protected Tree[] extractPrimitiveArgs(Tree.Apply call) { - Tree[] allArgs = Tree.cloneArray(1, call.args); - allArgs[0] = ((Tree.Select)(call.fun)).qualifier; - return allArgs; - } - - /** - * Return the unboxed version of the given tree. - */ - protected Tree unbox(Tree tree) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (prims.getPrimitive(fun.symbol()) == Primitive.BOX) { - assert args.length == 1; - return args[0]; - } else - return tree; - default: - return tree; - } - } - - /// Modules - ////////////////////////////////////////////////////////////////////// - - /** - * Add field containing module instance, and code to initialize - * it, to current class. - */ - protected void addModuleInstanceField(Context ctx) { - ctx.clazz.addNewField(JAccessFlags.ACC_PUBLIC - | JAccessFlags.ACC_FINAL - | JAccessFlags.ACC_STATIC, - MODULE_INSTANCE_FIELD_NAME, - ctx.clazz.getType()); - - ctx.code.emitNEW(ctx.clazz.getName()); - ctx.code.emitINVOKESPECIAL(ctx.clazz.getName(), - CONSTRUCTOR_STRING, - JMethodType.ARGLESS_VOID_FUNCTION); - // The field is initialised by the constructor, so we don't - // need to do it here, creating the instance is sufficient. - } - - protected JMethod addNewScalaMethod(JClass clazz, - Symbol method, - int addFlags) { - JMethodType methodType = (JMethodType)typeStoJ(method.type()); - - Symbol[] params = method.valueParams(); - String[] argNames = new String[params.length]; - - for (int i = 0; i < argNames.length; ++i) - argNames[i] = params[i].name.toString(); - - return clazz.addNewMethod(javaModifiers(method) | addFlags, - method.name.toString(), - methodType.getReturnType(), - methodType.getArgumentTypes(), - argNames); - } - - /** - * Create a class which mirrors all public methods of the given - * module class as static methods, to enable the use of the module - * from Java. - */ - protected void dumpModuleMirrorClass(Context ctx, Symbol cSym, Pickle pickle) { - String mainName = javaName(cSym); - String mirrorName = mainName.substring(0, mainName.length() - 1); - - JClass mirrorClass = fjbgContext.JClass(JAccessFlags.ACC_SUPER - | JAccessFlags.ACC_PUBLIC - | JAccessFlags.ACC_FINAL, - mirrorName, - JAVA_LANG_OBJECT, - JClass.NO_INTERFACES, - ctx.sourceFileName); - Scope.SymbolIterator memberIt = - cSym.members().iterator(); - while (memberIt.hasNext()) { - Symbol member = memberIt.next(); - if (!member.isMethod() - || member.isInitializer() - || member.isStatic()) - continue; - - JMethod mirrorMeth = - addNewScalaMethod(mirrorClass, member, JAccessFlags.ACC_STATIC); - JExtendedCode mirrorCode = (JExtendedCode)mirrorMeth.getCode(); - - mirrorCode.emitGETSTATIC(mainName, - MODULE_INSTANCE_FIELD_NAME, - new JObjectType(mainName)); - JType[] argTypes = mirrorMeth.getArgumentTypes(); - for (int index = 0, i = 0; i < argTypes.length; ++i) { - mirrorCode.emitLOAD(index, argTypes[i]); - index += argTypes[i].getSize(); - } - mirrorCode.emitINVOKEVIRTUAL(mainName, - mirrorMeth.getName(), - (JMethodType)mirrorMeth.getType()); - mirrorCode.emitRETURN(mirrorMeth.getReturnType()); - - mirrorCode.setLineNumber(0, - mirrorCode.getPC(), - Position.line(member.pos)); - } - addScalaAttr(mirrorClass, pickle); - - writeClassFile(mirrorClass); - } - - /** - * Add the "Scala" attribute to the given class, in which the - * symbol table is saved. - */ - protected void addScalaAttr(JClass cls, Pickle pickle) { - // change this to true to enable .symbl file generation - if (false) { - pickles.add(cls); - pickles.add(pickle); - } else { - JOtherAttribute scalaAttr = - fjbgContext.JOtherAttribute(cls, - cls, - SCALA_ATTR, - pickle.bytes, - pickle.size()); - cls.addAttribute(scalaAttr); - } - } - - /// Names - ////////////////////////////////////////////////////////////////////// - - protected HashMap nameMap/*<Symbol,String>*/ = new HashMap(); - - /** - * Return a Java-compatible version of the name of the given - * symbol. The returned name is mangled and includes the names of - * the owners. - */ - protected String javaName(Symbol sym) { - Object value = nameMap.get(sym); - if (value != null) return (String)value; - String name = prims.getJREClassName(sym); - nameMap.put(sym, name); - return name; - } - - /// Types - ////////////////////////////////////////////////////////////////////// - - /** - * Return the Java modifiers for the given Scala symbol. - */ - protected int javaModifiers(Symbol sym) { - int flags = sym.flags; - int jFlags = 0; - - if (Modifiers.Helper.isPrivate(flags)) - jFlags |= JAccessFlags.ACC_PRIVATE; - else - jFlags |= JAccessFlags.ACC_PUBLIC; - - if (Modifiers.Helper.isAbstract(flags)) - jFlags |= JAccessFlags.ACC_ABSTRACT; - if (Modifiers.Helper.isInterface(flags)) - jFlags |= JAccessFlags.ACC_INTERFACE; - - if (Modifiers.Helper.isFinal(flags) - && !(Modifiers.Helper.isAbstract(flags) - || Modifiers.Helper.isInterface(flags))) - jFlags |= JAccessFlags.ACC_FINAL; - - if (sym.isStatic()) - jFlags |= JAccessFlags.ACC_STATIC; - - return jFlags; - } - - protected HashMap typeMap/*<Symbol,Type>*/ = new HashMap(); - protected void initTypeMap() { - typeMap.put(defs.ANY_CLASS, JObjectType.JAVA_LANG_OBJECT); - typeMap.put(defs.ANYREF_CLASS, JObjectType.JAVA_LANG_OBJECT); - } - - /** - * Return the Java type corresponding to the given Scala type. - */ - protected JType typeStoJ(Type tp) { - switch (tp) { - case ConstantType(Type base, _): - return typeStoJ(base); - case TypeRef(_, Symbol sym, _): - Object value = typeMap.get(sym); - if (value != null) return (JType)value; - JType jTp = new JObjectType(javaName(sym)); - typeMap.put(sym, jTp); - return jTp; - case UnboxedType(TypeTags.BYTE): - return JType.BYTE; - case UnboxedType(TypeTags.CHAR): - return JType.CHAR; - case UnboxedType(TypeTags.SHORT): - return JType.SHORT; - case UnboxedType(TypeTags.INT): - return JType.INT; - case UnboxedType(TypeTags.LONG): - return JType.LONG; - case UnboxedType(TypeTags.FLOAT): - return JType.FLOAT; - case UnboxedType(TypeTags.DOUBLE): - return JType.DOUBLE; - case UnboxedType(TypeTags.BOOLEAN): - return JType.BOOLEAN; - case UnboxedType(TypeTags.UNIT): - return JType.VOID; - case UnboxedType(TypeTags.STRING): - return JObjectType.JAVA_LANG_STRING; - case UnboxedArrayType(Type elementType): - return new JArrayType(typeStoJ(elementType)); - case MethodType(Symbol[] vparams, Type result): - JType[] argTypes = new JType[vparams.length]; - for (int i = 0; i < vparams.length; ++i) - argTypes[i] = typeStoJ(vparams[i].info()); - return new JMethodType(typeStoJ(result), argTypes); - default: - throw Debug.abort("invalid type", tp); - } - } - - /** - * Return the "index" of the given type. This index encodes the - * level in the hierarchy of basic types, with arrays and objects - * on top of everything. - */ - protected int getTypeIndex(JType tp) { - return getTypeIndex(tp.getTag()); - } - - /** - * Return the "index" of the given type. - */ - protected int getTypeIndex(int tp) { - switch (tp) { - case JType.T_BOOLEAN: return 0; - case JType.T_BYTE: - case JType.T_CHAR: - case JType.T_SHORT: - case JType.T_INT: return 1; - case JType.T_LONG: return 2; - case JType.T_FLOAT: return 3; - case JType.T_DOUBLE: return 4; - case JType.T_ARRAY: - case JType.T_OBJECT: return 5; - default: return -1; - } - } - - /** - * Return the maximum of the types of all the given trees. All - * reference types are considered to be equivalent, and if several - * reference types are present in the trees, any one of them is - * returned. - */ - protected JType getMaxType(Tree[] trees) { - JType maxType = JType.BOOLEAN; - int maxTypeIdx = getTypeIndex(maxType); - - for (int i = 0; i < trees.length; ++i) { - JType argType = typeStoJ(trees[i].type); - if (getTypeIndex(argType) > maxTypeIdx) { - maxType = argType; - maxTypeIdx = getTypeIndex(maxType); - } - } - return maxType; - } - protected JType getMaxType(Tree tree1, Tree tree2) { - JType type1 = typeStoJ(tree1.type); - JType type2 = typeStoJ(tree2.type); - return getTypeIndex(type1) > getTypeIndex(type2) ? type1 : type2; - } - - /// Line numbers - ////////////////////////////////////////////////////////////////////// - - int[] pcStack = new int[32]; - int pcStackDepth = 0; - void startCodeForTree(Context ctx, Tree tree) { - if (pcStackDepth == pcStack.length) { - int[] newPCStack = new int[pcStack.length * 2]; - System.arraycopy(pcStack, 0, newPCStack, 0, pcStack.length); - pcStack = newPCStack; - } - pcStack[pcStackDepth++] = (ctx.code == null ? 0 : ctx.code.getPC()); - } - - void endCodeForTree(Context ctx, Tree tree) { - assert pcStackDepth > 0; - int startPC = pcStack[--pcStackDepth]; - if (ctx.code != null) - ctx.code.completeLineNumber(startPC, - ctx.code.getPC(), - Position.line(tree.pos)); - } - - protected void genLocalVariableTable(Context ctx) { - JLocalVariable[] vars = ctx.method.getLocalVariables(); - - if (!global.debuginfo || vars.length == 0) - return; - - JConstantPool pool = ctx.clazz.getConstantPool(); - int pc = ctx.code.getPC(); - int anonCounter = 1; - - ByteBuffer lvTab = ByteBuffer.allocate(2 + 10 * vars.length); - lvTab.putShort((short)vars.length); - for (int i = 0; i < vars.length; i++) { - JLocalVariable lv = vars[i]; - String name = (lv.getName() == null) - ? "<anon" + (anonCounter++) + ">" : lv.getName(); - lvTab.putShort((short)0); - lvTab.putShort((short)pc); - lvTab.putShort((short)pool.addUtf8(name)); - lvTab.putShort((short)pool.addUtf8(lv.getType().getSignature())); - lvTab.putShort((short)lv.getIndex()); - } - JAttribute attr = - fjbgContext.JOtherAttribute(ctx.clazz, - ctx.method, - "LocalVariableTable", - lvTab.array()); - ctx.code.addAttribute(attr); - } - - - /// Context - ////////////////////////////////////////////////////////////////////// - - /** - * Record the entry into a class, and return the appropriate - * context. - */ - protected Context enterClass(Context ctx, Symbol cSym) { - String javaName = javaName(cSym); - - boolean serializable = - global.getAttrArguments(cSym, defs.SCALA_SERIALIZABLE_CONSTR) != null; - - boolean cloneable = - global.getAttrArguments(cSym, defs.SCALA_CLONEABLE_CONSTR) != null; - - scalac.symtab.Type[] baseTps = cSym.info().parents(); - assert baseTps.length > 0 : Debug.show(cSym); - - int offset; - String superClassName; - if (cSym.isInterface()) { - offset = baseTps[0].symbol() == defs.ANY_CLASS ? 1 : 0; - superClassName = JAVA_LANG_OBJECT; - } else { - offset = 1; - superClassName = javaName(baseTps[0].symbol()); - } - String[] interfaceNames = new String[baseTps.length - offset - + (serializable ? 1 : 0) - + (cloneable ? 1 : 0)]; - for (int i = offset; i < baseTps.length; ++i) { - Symbol baseSym = baseTps[i].symbol(); - assert baseSym.isInterface() : cSym + " implements " + baseSym; - interfaceNames[i - offset] = javaName(baseSym); - } - if (serializable) - interfaceNames[interfaceNames.length - 1 - (cloneable ? 1 : 0)] = - "java.io.Serializable"; - if (cloneable) - interfaceNames[interfaceNames.length - 1] = "java.lang.Cloneable"; - - JClass cls = fjbgContext.JClass(javaModifiers(cSym) - & ~JAccessFlags.ACC_STATIC - | JAccessFlags.ACC_SUPER, - javaName, - superClassName, - interfaceNames, - ctx.sourceFileName); - - return ctx.withClass(cls, - cSym.isModuleClass() && ctx.clazz == null, - cSym.isSubClass(JAVA_RMI_REMOTE_CLASS)); - } - - protected void leaveClass(Context ctx, Symbol cSym) { - JClass clazz = ctx.clazz; - - Pickle pickle = (Pickle)global.symdata.get(cSym); - if (pickle != null) - if (ctx.isModuleClass) - dumpModuleMirrorClass(ctx, cSym, pickle); - else - addScalaAttr(clazz, pickle); - - writeClassFile(clazz); - } - - /** - * Record the entry into a method, and return the appropriate - * context. - */ - protected Context enterMethod(Context ctx, - Tree.DefDef mDef, - boolean useWideJumps) { - Symbol mSym = mDef.symbol(); - - global.log("entering method " + Debug.show(mSym) - + " (type: " + Debug.show(mSym.info()) + ")" - + " wide jumps? " + useWideJumps); - - JMethod method = addNewScalaMethod(ctx.clazz, mSym, 0); - - Map locals = new HashMap(); - Symbol[] args = mSym.valueParams(); - JType[] argTypes = method.getArgumentTypes(); - - int firstPos = mSym.isStatic() ? 0 : 1; - for (int i = 0, pos = firstPos; i < argTypes.length; ++i) { - locals.put(args[i], new Integer(pos)); - pos += argTypes[i].getSize(); - } - - if ((mSym.flags & Modifiers.BRIDGE) != 0) - method.addAttribute(fjbgContext.JOtherAttribute(ctx.clazz, - method, - "Bridge", - new byte[]{})); - - if (ctx.isRemote && mSym.isPublic()) { - // (see http://java.sun.com/docs/books/vmspec/html/ClassFile.doc.html#3129) - // Exceptions_attribute { - // .. - // u2 number_of_exceptions; - // u2 exception_index_table[number_of_exceptions]; - // } - JConstantPool cp = ctx.clazz.getConstantPool(); - int reInx = cp.addClass(JAVA_RMI_REMOTEEXCEPTION); - ByteBuffer contents = ByteBuffer.allocate(4); // u2 + u2[1] - contents.putShort((short)1); - contents.putShort((short)reInx); - global.log("adding 'Exceptions_attribute' " + contents.toString() - + " for remote method " + mSym.name.toString()); - method.addAttribute(fjbgContext.JOtherAttribute(ctx.clazz, - method, - "Exceptions", - contents.array())); - } - - return ctx.withMethod(method, locals, useWideJumps); - } - - protected void leaveMethod(Context ctx) { - genLocalVariableTable(ctx); - global.log("leaving method"); - } - - /// I/O - ////////////////////////////////////////////////////////////////////// - - /** Writes the given class to a file. */ - protected void writeClassFile(JClass clazz) { - File file = getFile(clazz, ".class"); - try { - clazz.writeTo(file); - global.operation("wrote " + file); - } catch (IOException exception) { - if (global.debug) exception.printStackTrace(); - global.error("could not write file " + file); - } - } - - /** Writes the given pickle for given class to a file. */ - protected void writeSymblFile(JClass clazz, Pickle pickle) { - File file = getFile(clazz, ".symbl"); - try { - pickle.writeTo(file); - global.operation("wrote " + file); - } catch (IOException exception) { - if (global.debug) exception.printStackTrace(); - global.error("could not write file " + file); - } - } - - /** Returns the file with the given suffix for the given class. */ - protected File getFile(JClass clazz, String suffix) { - String path = clazz.getName().replace('.', File.separatorChar); - return new File(global.outpath + File.separatorChar + path + suffix); - } - - /// Misc. - ////////////////////////////////////////////////////////////////////// - - /** - * Add value members (i.e. fields) to current class. - */ - protected void addValueClassMembers(Context ctx, Tree.ClassDef cDef) { - Symbol cSym = cDef.symbol(); - Scope.SymbolIterator memberIt = - cSym.members().iterator(); - while (memberIt.hasNext()) { - Symbol member = memberIt.next(); - if (member.isTerm() && !member.isMethod()) { - int flags = javaModifiers(member); - if (global.getAttrArguments(member,defs.SCALA_TRANSIENT_CONSTR) - != null) - flags |= JAccessFlags.ACC_TRANSIENT; - if (global.getAttrArguments(member,defs.SCALA_VOLATILE_CONSTR) - != null) - flags |= JAccessFlags.ACC_VOLATILE; - ctx.clazz.addNewField(flags, - member.name.toString(), - typeStoJ(member.info())); - } - } - } - - protected void completeClassConstructor(Context ctx, Symbol cSym) { - if (ctx.isModuleClass) - addModuleInstanceField(ctx); - AConstant[] aargs = - global.getAttrArguments(cSym, SCALA_SERIAL_VERSION_UID_CONSTR); - if (aargs == null) - return; - assert aargs.length == 1 : "Wrong attribute arguments: "; - String fieldName = "serialVersionUID"; - JField field = ctx.clazz.addNewField - (JAccessFlags.ACC_STATIC | JAccessFlags.ACC_PUBLIC, fieldName, - JType.LONG); - genLoadLiteral(ctx, aargs[0], JType.LONG); - ctx.code.emitPUTSTATIC(ctx.clazz.getName(), fieldName, JType.LONG); - } - - /** - * Return the class constructor method of the given class. - */ - private JMethod getClassConstructorMethod(Context ctx) { - JMethod[] methods = ctx.clazz.getMethods(); - JMethod clinit = null; - for (int i = 0; i < methods.length; ++i) { - if (methods[i].getName().equals("<clinit>")) { - clinit = methods[i]; - break; - } - } - return clinit != null - ? clinit - : ctx.clazz.addNewMethod(JAccessFlags.ACC_PUBLIC - | JAccessFlags.ACC_STATIC, - "<clinit>", - JType.VOID, - JType.EMPTY_ARRAY, - Strings.EMPTY_ARRAY); - } - - - /** - * Return true iff the given symbol is a static (in the Java - * sense) member of its owner. - */ - protected boolean isStaticMember(Symbol sym) { - return sym.isStatic(); - } -} - -/** - * A compilation context, which records information about the class - * and the method currently being generated. - */ -class Context { - public final String sourceFileName; - public final JClass clazz; - public final JMethod method; - public final JExtendedCode code; - public final Map/*<Symbol,JLocalVariable>*/ locals; - public final Map/*<Symbol,Pair<JCode.Label,Tree[]>>*/ labels; - public final boolean useWideJumps; - public final boolean isModuleClass; - public final boolean isRemote; - - public final static Context EMPTY = - new Context(null, null, null, null, null, false, false, false); - - private Context(String sourceFileName, - JClass clazz, - JMethod method, - Map locals, - Map labels, - boolean useWideJumps, - boolean isModuleClass, - boolean isRemote) { - this.sourceFileName = sourceFileName; - this.clazz = clazz; - this.method = method; - if (method == null || method.isAbstract()) - this.code = null; - else - this.code = (JExtendedCode)method.getCode(); - this.locals = locals; - this.labels = labels; - this.useWideJumps = useWideJumps; - this.isModuleClass = isModuleClass; - this.isRemote = isRemote; - } - - public Context withSourceFileName(String sourceFileName) { - return new Context(sourceFileName, - null, - null, - null, - null, - false, - false, - false); - } - - public Context withClass(JClass clazz, boolean isModuleClass, boolean isRemote) { - return new Context(this.sourceFileName, - clazz, - null, - null, - null, - false, - isModuleClass, - isRemote); - } - - public Context withMethod(JMethod method, Map locals, boolean useWideJumps) { - assert this.clazz == method.getOwner(); - return new Context(this.sourceFileName, - this.clazz, - method, - locals, - new HashMap(), - useWideJumps, - this.isModuleClass, - this.isRemote); - } -} diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java deleted file mode 100644 index 3850369356..0000000000 --- a/sources/scalac/backend/msil/GenMSIL.java +++ /dev/null @@ -1,2632 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.backend.msil; - -import scalac.Global; -import scalac.CompilationUnit; - -import scalac.util.Debug; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; -import scalac.util.SourceRepresentation; -import scalac.ast.Tree; -import scalac.ast.TreeList; -import scalac.atree.AConstant; -import Tree.*; -import scalac.symtab.Symbol; -import scalac.symtab.TypeTags; -import scalac.symtab.Modifiers; -import scalac.symtab.Definitions; -import scalac.symtab.classfile.Pickle; -import scalac.symtab.classfile.CLRTypes; - -import scalac.backend.Primitive; -import scalac.backend.Primitives; - -import scala.tools.util.Position; - -import ch.epfl.lamp.compiler.msil.*; -import ch.epfl.lamp.compiler.msil.emit.*; - -import Item.*; - -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; - -/** - * Generates MS IL code via Reflection.Emit-like API - * (ch.epfl.lamp.compiler.msil.emit package) - * - * @author Nikolay Mihaylov - */ -public final class GenMSIL { - - //################################################################ - - // The position of the paramater in the parameter list - private final Map/*<Symbol, Integer>*/ params = new HashMap(); - - // The LocalBuilder corresponding to the local variable symbol - private final Map/*<Symbol, LocalBuilder>*/ locals = new HashMap(); - - // mapping from LabelDef symbols to labels - private final Map/*<Symbol, Label>*/ sym2label = new HashMap(); - - // the code generator for the current method - private ILGenerator code; - - private final Global global; - private final TypeCreator tc; - private final Definitions defs; - private final Primitives primitives; - private final ItemFactory items; - - private static final Item TRUE_ITEM = Item.CondItem(Test.True, null, null); - private static final Item FALSE_ITEM = Item.CondItem(Test.False, null, null); - - /** The public entry point into the code generator. */ - public static void translate(Global global, CompilationUnit[] units) { - TypeCreator tc = new TypeCreator(global); - GenMSIL translator = new GenMSIL(global, tc); - tc.init(); - tc.collectSymbols(units); - tc.initAssembly(); - for (int i = 0; i < units.length; i++) translator.apply(units[i]); - tc.saveAssembly(); - } - - /** - * The private constructor of the code generator. - */ - private GenMSIL(Global global, TypeCreator tc) { - this.global = global; - this.defs = global.definitions; - this.primitives = global.primitives; - this.tc = tc; //new TypeCreator(global, this, phase); - this.items = new ItemFactory(this); - } - - - private String getSourceFilename() { - assert currUnit != null; - return SourceRepresentation.escape(currUnit.source.getFile().getPath()); - } - - // keeps track of the current compilation unit for better error reporting - private CompilationUnit currUnit; - - /** - * The main entry point into the code generator. Called from translate - * for every compilation unit. - */ - private void apply(CompilationUnit unit) { - currUnit = unit; - for (int i = 0; i < unit.body.length; i++) { - Tree tree = unit.body[i]; - Symbol sym = tree.symbol(); - try { - switch (tree) { - case Empty: break; - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - genClass(sym, body); - break; - case PackageDef(_, Template(_ , Tree[] body)): - genPackage(body); - break; - default: - throw Debug.abort - ("Illegal top-level definition: " + Debug.show(tree)); - } - } catch (Throwable e) { - currUnit.error(tree.pos, "Exception caught: " + e.getMessage()); - e.printStackTrace(); - tc.saveAssembly(); - System.exit(1); - } - } - } - - /** - * Generate the code for a Package definition. - */ - private void genPackage(Tree[] body) { - for (int i = 0; i < body.length; i++) { - Symbol sym = body[i].symbol(); - switch (body[i]) { - case Empty: - break; - - case ClassDef(_, _, _, _, _, Template(_, Tree[] classBody)): - Type type = tc.getType(sym); - assert type instanceof TypeBuilder - : Debug.show(sym) + " => [" + type.Assembly() + "]" + type; - if (type instanceof TypeBuilder) - genClass(sym, classBody); - break; - - case PackageDef(_, Template(_ , Tree[] body2)): - genPackage(body2); - break; - - default: - throw Debug.abort("Class definition expected", Debug.show(sym)); - } - } - } - - /** The symbol of the class that is currently being compiled. */ - private Symbol currentClass; - - /** The method that is currently being compiled. */ - private MethodBase currentMethod; - - - private static final byte[] NO_SYMTAB = new byte[] {1, 0, 0, 0}; - /* - * Emit the symbol table for the class given class as an MSIL attribute. - */ - private void emitSymtab(Symbol clazz) { - ConstructorInfo symtabConstr = tc.SYMTAB_DEFAULT_CONSTR; - byte[] symtab = null; - Pickle pickle = (Pickle)global.symdata.get(clazz); - if (pickle == null) { - symtab = NO_SYMTAB; - } else { - symtabConstr = tc.SYMTAB_CONSTR; - symtab = new byte[pickle.size() + 8]; - symtab[0] = 1; - for (int size = pickle.size(), i = 2; i < 6; i++) { - symtab[i] = (byte)(size & 0xff); - size >>= 8; - } - System.arraycopy(pickle.bytes, 0, symtab, 6, pickle.size()); - } - TypeBuilder type = (TypeBuilder) tc.getType(clazz); - if (clazz.isModuleClass()) { - TypeBuilder t = tc.getStaticType(clazz); - if (t != null) { - type.SetCustomAttribute(tc.SYMTAB_DEFAULT_CONSTR, NO_SYMTAB); - type = t; - if (global.args.debuginfo.value) - type.setPosition(Position.line(clazz.pos), getSourceFilename()); - } - } - type.SetCustomAttribute(symtabConstr, symtab); - } - - /* - * Generate the code for a class definition - */ - private void genClass(Symbol clazz, Tree[] body) { - Symbol outerClass = currentClass; - currentClass = clazz; - if (clazz.isModuleClass()) { - tc.getModuleField(clazz); - } - final TypeBuilder type = (TypeBuilder)tc.getType(clazz); - if (global.args.debuginfo.value) - type.setPosition(Position.line(clazz.pos), getSourceFilename()); - emitSymtab(clazz); - for (int i = 0; i < body.length; i++) { - Symbol sym = body[i].symbol(); - switch (body[i]) { - case Empty: - break; - - case ValDef(_, _, _, _): - // just to generate the field declaration - // the rhs should've been moved to the constructor body - tc.createField(sym); - break; - - case ClassDef(_, _, _, _, _, Template impl): - genClass(sym, impl.body); - break; - - case DefDef(_, _, _, ValDef[][] vparams, Tree tpe, Tree rhs): - if (!sym.isDeferred()) { - currentMethod = tc.getMethod(sym); - if (tc.isEntryPoint(sym) && tc.moreThanOneEntryPoint()) - currUnit.warning(body[i].pos, - "Program has more than one" - + " entry point defined"); - genDef(sym, vparams[0], rhs, msilType(tpe.type)); - } - break; - - default: - assert false : "Illegal class body definition: " - + Debug.show(body[i]); - } - } - if (tc.isCloneable(clazz)) { - Symbol cloneSym = clazz.lookup(Names.clone); - if (cloneSym.isNone()) { - short mods = MethodAttributes.Public - | MethodAttributes.Virtual - | MethodAttributes.HideBySig; - ILGenerator code = - type.DefineMethod("Clone", mods, tc.OBJECT, Type.EmptyTypes) - .GetILGenerator(); - code.Emit(OpCodes.Ldarg_0); - code.Emit(OpCodes.Call, tc.MEMBERWISE_CLONE); - code.Emit(OpCodes.Ret); - } - } - currentClass = outerClass; - } //genClass() - - - /* - * Specifies if the currently processed tree node is the last expression - * in a function so the generated code can be optimized: emitting ret - * instead of branch, emitting tailcalls, etc. - */ - private boolean lastExpr; - - private boolean enableTailCalls = false; - - private Label methodEnd = null; - - // set by backward jumps to show that the code ofter them is unreachable - private boolean unreachable = false; - - // used to push down the exit label of conditional expressions - private Label exitLabel; - - /* - * Generate code for constructors and methods. - */ - private void genDef(Symbol sym, ValDef[] parameters, Tree rhs, MSILType toType) { - MethodBase method = tc.getMethod(sym); - - params.clear(); - locals.clear(); - int argOffset = method.IsStatic() ? 0 : 1; - for (int i = 0; i < parameters.length; i++) { - params.put(parameters[i].symbol(), new Integer(i + argOffset)); - } - if (method.IsConstructor()) { - ConstructorInfo ctor = (ConstructorInfo) method; - code = ((ConstructorBuilder)ctor).GetILGenerator(); - methodEnd = code.DefineLabel(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(rhs.pos)); - if (sym.owner().isModuleClass() - && sym.owner().owner().isPackageClass()) { - Tree[] cstats = null; - switch (rhs) { - case Block(Tree[] stats, Tree value): - TreeList stms = new TreeList(); - for (int i = 0; i < stats.length; i++) { - switch (stats[i]) { - case Block(Tree[] stats2, Tree value2): - stms.append(stats2); - stms.append(value2); - break; - default: - stms.append(stats[i]); - } - } - switch (value) { - case Block(Tree[] stats2, Tree value2): - stms.append(stats2); - stms.append(value2); - break; - } - cstats = stms.toArray(); - break; - default: - cstats = new Tree[]{rhs}; - } - - // emit the call to the superconstructor - drop(gen(cstats[0], MSILType.VOID)); - closeMethod(methodEnd); - ConstructorBuilder cctor = ((TypeBuilder)(method.DeclaringType)). - DefineConstructor((short)(MethodAttributes.Static - | MethodAttributes.Public), - CallingConventions.Standard, - Type.EmptyTypes); - currentMethod = cctor; - code = cctor.GetILGenerator(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(sym.owner().pos)); - // initialize the static module reference - code.Emit(OpCodes.Newobj, ctor); - code.Emit(OpCodes.Stsfld, tc.getModuleField(currentClass)); - for (int i = 1; i < cstats.length; i++) { - drop(gen(cstats[i], MSILType.VOID)); - } - code.Emit(OpCodes.Ret); // conclude the static constructor - } else { - drop(gen(rhs, MSILType.VOID)); - closeMethod(methodEnd); - } - } else if (!method.IsAbstract()) { - lastExpr = true; - code = ((MethodBuilder)method).GetILGenerator(); - methodEnd = code.DefineLabel(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(rhs.pos)); - Item item = gen(rhs, toType); - if (returnsVoid(method)) - drop(item); - else - coerce(load(item), toType); // FIXME: coerce??? - closeMethod(methodEnd); - if (currentClass.isModuleClass()) { - MethodBuilder staticMethod = tc.getStaticObjectMethod(sym); - if (staticMethod != null) { - code = staticMethod.GetILGenerator(); - if (global.args.debuginfo.value) - code.setPosition(Position.line(sym.pos)); - code.Emit(OpCodes.Ldsfld, tc.getModuleField(currentClass)); - for (int i = 0; i < parameters.length; i++) - emitLdarg(i); - code.Emit(OpCodes.Call, (MethodInfo)method); - code.Emit(OpCodes.Ret); - } - } - } - - lastExpr = false; - code = null; - methodEnd = null; - } // genDef(); - - private void closeMethod(Label methodEnd) { - code.MarkLabel(methodEnd); - code.Emit(OpCodes.Ret); - } - - /* - * Check if the result type of a method is void - */ - private boolean returnsVoid(MethodBase method) { - return method.IsConstructor() || - (((MethodInfo)method).ReturnType == tc.VOID); - } - - private boolean returnsVoid(Symbol fun) { - switch (fun.type()) { - case MethodType(_, scalac.symtab.Type restype): - return restype.isSameAs(defs.UNIT_TYPE().unbox()); - default: - return false; - } - } - - /* - * Emit the code for this. - */ - private void emitThis() { - if (currentMethod.IsStatic()) { - if (currentMethod.IsConstructor()) { - code.Emit(OpCodes.Ldsfld, tc.getModuleField(currentClass)); - } else - throw Debug.abort ("Static methods don't have 'this' pointer"); - } else - code.Emit(OpCodes.Ldarg_0); - } - - - /* - * Sanity checks for items. - */ - private Item check(Item item) { - assert item != null && item.type != null : "" + item; - return item; - } - - /* - * - */ - private Item genLoad(Tree tree, MSILType toType) { - return load(gen(tree, toType)); - } - - /** the position of the treenode which is currently being processed. */ - private int pos; - - /* - * The main generator function. It keeps track of - * the current position in the tree for better error messages - */ - private Item gen(Tree tree, MSILType toType) { - unreachable = false; - if (global.args.debuginfo.value - && code != null && tree.pos != Position.NOPOS - && Position.line(tree.pos) != Position.line(pos)) - { - code.setPosition(Position.line(tree.pos)); - } - int tmpPos = pos; - pos = tree.pos; - Item item = null; - //i = gen0(tree, toType); - try { - item = gen0(tree, toType); - assert item.type.equals(toType) - || item.type.equals(unboxValueType(toType)) - : "" + item + " <> " + toType + "; tree = " + tree.getClass(); - } - catch (Throwable e) { - currUnit.error(tree.pos, "Exception caught: " + e.getMessage()); - e.printStackTrace(); - tc.saveAssembly(); - System.exit(1); -// + (global.debug ? "" : "; Use -debug to get a stack trace.")); -// //if (global.debug) -// e.printStackTrace(); -// //System.exit(1); - //throw Debug.abort(tree, e); - throw Debug.abort(e); - } - pos = tmpPos; - return check(item); - } - - /* - * Generate the code corresponding to the given tree node - */ - private Item gen0(Tree tree, MSILType toType) { - Symbol sym = tree.hasSymbol() ? tree.symbol() : null; - Item item = null; - switch (tree) { - case Empty: - return items.VoidItem(); - - case Block(Tree[] stats, Tree value): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - for (int i = 0; i < stats.length; i++) { - drop(gen(stats[i], MSILType.VOID)); - } - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return gen(value, toType); - - case ValDef(_, Name name, Tree tpe, Tree rhs): - LocalBuilder local = code.DeclareLocal(tc.getType(sym)); - local.SetLocalSymInfo(tree.symbol().name.toString()); - locals.put(sym, local); - if (rhs == Tree.Empty) - return items.VoidItem(); - MSILType type = msilType(tpe.type); - genLoad(rhs, type); - return check(store(items.LocalItem(local))); - - case Ident(_): - if (sym.isModule()) { - FieldInfo field = tc.getModuleField(sym); - // force the loading of the module - item = coerce(load(items.StaticItem(field)), toType); - } else { - MSILType type = msilType(sym.info()); - Integer slot = (Integer) params.get(sym); - if (slot != null) { - item = items.ArgItem(type, slot.intValue()); - } else { - LocalBuilder local = (LocalBuilder) locals.get(sym); - if (local != null) - item = items.LocalItem(local); - else { - assert sym.isStatic() : Debug.show(sym); - FieldInfo field = tc.getField(sym); - assert field != null : Debug.show(sym); - if (field.IsLiteral()) { - assert field.FieldType.IsEnum() - && field.getValue() != null - : field.toString(); - return coerce(mkLiteral(msilType(field.FieldType), - field.getValue()), - toType); - } - return coerce(items.StaticItem(field), toType); - } - } - } - return coerce(item, toType); - - case Select(Tree qualifier, _): - if (sym.isModule()) { - assert !sym.isJava() : "Cannot treat Java class '" + - Debug.show(sym) + "' as value."; - return coerce(load(items.StaticItem(tc.getModuleField(sym))), toType); - } - assert !sym.isStatic() :Debug.show(sym); - item = items.SelectItem(genLoad(qualifier, msilType(qualifier)), - tc.getField(sym)); - return coerce(item, toType); - - case Apply(Tree fun, Tree[] args): - Item i = check(genApply(fun, args, msilType(tree.type))); - return coerce(i, toType); - - case Assign(Tree lhs, Tree rhs): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - MSILType type = msilType(lhs.type); - Item var = gen(lhs, type); - genLoad(rhs, type); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return check(store(var)); - - case New(Tree init): - switch (init) { - case Apply(Tree fun, Tree[] args): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - ConstructorInfo ctor = (ConstructorInfo) tc.getMethod(fun.symbol()); - loadArgs(args, ctor.GetParameters()); - code.Emit(OpCodes.Newobj, ctor); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return coerce(items.StackItem(msilType(ctor.DeclaringType)), - toType); - default: - throw Debug.abort("Incorrect tree", init); - } - - case This(_): - return coerce(items.SelfItem(tc.getType(sym)), toType); - - case Super(_, _): - return coerce(items.SelfItem(tc.getType(sym)), toType); - - case Literal(AConstant value): - if (toType == MSILType.VOID) - return items.VoidItem(); - return coerce(items.LiteralItem(value), toType); - - case Return(Tree expr): - genLoad(expr, msilType(expr)); - code.Emit(OpCodes.Ret); - //code.Emit(OpCodes.Br, methodEnd); - return items.VoidItem(); - - case If(Tree cond, Tree thenp, Tree elsep): - item = genIf(cond, thenp, elsep, toType); - return check(item); - - case LabelDef(_, Ident[] params, Tree rhs): - Label l = code.DefineLabel(); - code.MarkLabel(l); - sym2label.put(sym, new LabelDescr(l, params)); - return gen(rhs, toType); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - boolean tmpLastExpr = lastExpr; lastExpr = false; - Item loc = gen(test, MSILType.I4); - switch (loc) { - case ArgItem(_): - case LocalItem(_): - case LiteralItem(_): - break; - default: - loc = items.LocalItem(code.DeclareLocal(tc.INT)); - store(loc); - } - lastExpr = tmpLastExpr; - Label tmpExitLabel = exitLabel; - if (exitLabel == null) - exitLabel = code.DefineLabel(); - - Label nextCase = code.DefineLabel(); - assert tags.length == bodies.length; - for (int i = 0; i < tags.length; i++) { - load(loc); - loadI4(tags[i]); - code.Emit(OpCodes.Bne_Un, nextCase); - genLoad(bodies[i], toType); -// if (lastExpr) -// code.Emit(OpCodes.Ret); -// else - if (!unreachable) - code.Emit(OpCodes.Br, exitLabel); - code.MarkLabel(nextCase); - nextCase = code.DefineLabel(); - } - Item i = genLoad(otherwise, toType); - if (tmpExitLabel == null) - resolve(exitLabel); - exitLabel = tmpExitLabel; - return i; - - default: - throw Debug.abort("Dunno what to do", tree); - } - } //gen() - - /* Generate code for conditional expressions. - */ - private Item genIf(Tree condp, Tree thenp, Tree elsep, MSILType toType) { - Item iThen = null; - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - Item.CondItem cond = mkCond(gen(condp, msilType(condp.type))); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - - if (elsep == Tree.Empty && toType == MSILType.VOID) { - if (cond.success == null) { - Chain success = new Chain(code.DefineLabel(), null); - branch(cond.test, success); - iThen = genLoad(thenp, toType); - resolve(success); - resolve(cond.failure); - } else { - Chain fail = (cond.failure != null) ? - cond.failure : new Chain(code.DefineLabel(), null); - branch(cond.test, fail); - resolve(cond.success); - iThen = genLoad(thenp, toType); - resolve(fail); - } - } else { - Chain fail = cond.failure != null ? - cond.failure : new Chain(code.DefineLabel(), null); - branch(cond.test, fail); - resolve(cond.success); - if (exitLabel == null) - exitLabel = code.DefineLabel(); - Item thenItem = gen(thenp, toType); - iThen = load(coerce(thenItem, toType)); -// if (lastExpr) -// code.Emit(OpCodes.Ret); -// else - if (!unreachable) - code.Emit(OpCodes.Br, exitLabel); - resolve(fail); - Item iElse = genLoad(elsep, toType); - if (tmpExitLabel == null) - resolve(exitLabel); - exitLabel = tmpExitLabel; - } - return iThen; - } //genIf - - /* Coerce the item to the specified type. */ - private Item coerce(Item item, MSILType toType) { - assert item != null && toType != null : "" + item + " => " + toType; - if (item.type.equals(toType)) - return item; - if (toType == MSILType.VOID) - return drop(item); - switch (item) { - case VoidItem(): - assert toType == MSILType.VOID : "" + toType; - return item; - case SelfItem(): - assert item.type.isSubtypeOf(toType); - item.type = toType; - return item; - case StackItem(): - MSILType utype = unboxValueType(toType); - if (item.type.isValueType() && utype != null) - toType = utype; - emitConvert(item.type, toType); - item.type = toType; - return item; - case LiteralItem(AConstant value): - switch (item.type) { - case REF(Type t): - if (item.type.isValueType()) { - assert t.IsEnum() || toType.equals(MSILType.OBJECT) - : item + " => "+ toType; - return coerce(load(item), toType); - } - assert (item.type.isValueType()) - || (item.type.isReferenceType() - && item.type.isSubtypeOf(toType)); - } - item.type = toType; - return item; - case ArgItem(_): - case LocalItem(_): - if (item.type.isSubtypeOf(toType)) { - item.type = toType; - return item; - } - break; - case CondItem(_, _, _): - if (item.type == MSILType.BOOL) - return item; - break; - } - return coerce(load(item), toType); - } - - /***/ - private void emitConvert(MSILType fromType, MSILType toType) { - switch (fromType) { - case REF(Type t): - if (t.IsValueType() && toType.isType(tc.OBJECT)) { - code.Emit(OpCodes.Box, t); - return; - } else if (t.IsEnum()) { - emitConvert(msilType(t.getUnderlyingType()), toType); - return; - } - } - if (fromType.isSubtypeOf(toType)) - return; - switch (toType) { - case BOOL: code.Emit(OpCodes.Conv_I4); return; // TODO: is this correct/best? - case I1: code.Emit(OpCodes.Conv_I1); return; - case I2: code.Emit(OpCodes.Conv_I2); return; - case I4: code.Emit(OpCodes.Conv_I4); return; - case I8: code.Emit(OpCodes.Conv_I8); return; - case R4: code.Emit(OpCodes.Conv_R4); return; - case R8: code.Emit(OpCodes.Conv_R8); return; - case CHAR: code.Emit(OpCodes.Conv_U2); return; - case REF(Type t): - if (t.IsEnum()) { - assert fromType.isType(t.getUnderlyingType()); - return; - } - break; - } - throw Debug.abort("emitConvert: " + fromType + " => " + toType - + "; fromType.isSubtypeOf(toType) = " - + fromType.isSubtypeOf(toType)); - } - - private static class LabelDescr { - final Label label; - final Ident[] params; - LabelDescr(Label label, Ident[] params) { - this.label = label; - this.params = params; - } - } - - private Item genApply(Tree fun, Tree[] args, MSILType resType) { - boolean tmpLastExpr = lastExpr; lastExpr = false; - Label tmpExitLabel = exitLabel; exitLabel = null; - Item item = genApply0(fun, args, resType); - lastExpr = tmpLastExpr; - exitLabel = tmpExitLabel; - return item; - } - /** Generate the code for an Apply node */ - private Item genApply0(Tree fun, Tree[] args, MSILType resType) { - Symbol sym = fun.symbol(); - switch (fun) { - case Ident(_): - LabelDescr ld = (LabelDescr)sym2label.get(sym); - if (ld != null) { - assert ld.params.length == args.length - : ld.params.length + " != " + args.length; - lastExpr = false; - for (int i = 0; i < args.length; i++) - genLoad(args[i], msilType(args[i].type)); - for (int i = args.length - 1; i >= 0; i--) { - Item ident = gen(ld.params[i], msilType(ld.params[i])); - store(ident); - } - code.Emit(OpCodes.Br, ld.label); - unreachable = true; - MSILType retType = msilType(sym.info().resultType()); - Item i = retType == MSILType.VOID ? items.VoidItem() - : items.StackItem(retType); - return coerce(i, resType); - } - assert sym.isStatic() : Debug.show(sym); - - Primitive p = primitives.getPrimitive(sym); - switch (p) { - case UNBOX: - assert args.length == 1; - MSILType t = msilType(args[0].type); - Item i = genLoad(args[0], t); - if (!i.type.isValueType()) { - MethodInfo method = (MethodInfo)tc.getMethod(sym); - code.Emit(OpCodes.Call, method); - i = returnsVoid(method) ? items.VoidItem() - : items.StackItem(msilType(method.ReturnType)); - return coerce(i, resType); - } - if (sym == primitives.UNBOX_UVALUE) { - return items.VoidItem(); - } - return i; - } - MSILType convTo = primitiveConvert(sym); - if (convTo != null) { - assert args.length == 1; - genLoad(args[0], convTo); - return items.StackItem(convTo); - } - // Generate delegate's reverse view - if (sym.name == Names.view && - CLRTypes.instance().isDelegateType(resType.toType())) - { - assert args.length == 1 : Debug.show(sym); - return createDelegateFromFunction(args[0], resType); - } - - return check(invokeMethod(sym, args, resType, true)); - - case Select(Tree qualifier, _): - // scala.Any.== - if (sym == defs.ANY_EQEQ) { - return genEq(qualifier, args[0]); - } - // scala.Any.!= - if (sym == defs.ANY_BANGEQ) { - return negate(genEq(qualifier, args[0])); - } - // java.lang.String.substring(int start, int end) needs conversion - // to System.String.Substring(int start, int length) - if (sym == tc.SYM_SUBSTRING_INT_INT) { - assert args.length == 2; - genLoad(qualifier, MSILType.STRING); - genLoad(args[0], MSILType.I4); - code.Emit(OpCodes.Dup); - code.Emit(OpCodes.Neg); - genLoad(args[1], MSILType.I4); - code.Emit(OpCodes.Add); - code.Emit(OpCodes.Call, tc.SUBSTRING_INT_INT); - return coerce(items.StackItem(MSILType.STRING), resType); - } - - if (sym == tc.SYM_COMPARE_TO_IGNORE_CASE) { - assert args.length == 1; - genLoad(qualifier, MSILType.STRING); - genLoad(args[0], MSILType.STRING); - code.Emit(OpCodes.Ldc_I4_1); - code.Emit(OpCodes.Call, tc.COMPARE_TO_IGNORE_CASE); - return coerce(items.StackItem(MSILType.STRING), resType); - } - - if (isPrimitiveArrayOp(sym)) { - Primitive prim = primitives.getPrimitive(sym); - loadArgs(args, tc.getMethod(sym).GetParameters()); - Type elemType = getArrayElemType(prim); - switch (prim) { - case ZARRAY_LENGTH: case BARRAY_LENGTH: case SARRAY_LENGTH: - case CARRAY_LENGTH: case IARRAY_LENGTH: case LARRAY_LENGTH: - case FARRAY_LENGTH: case DARRAY_LENGTH: case OARRAY_LENGTH: - code.Emit(OpCodes.Ldlen); - return items.StackItem(MSILType.I4); - case NEW_ZARRAY: - case NEW_BARRAY: - case NEW_SARRAY: - case NEW_CARRAY: - case NEW_IARRAY: - case NEW_LARRAY: - case NEW_FARRAY: - case NEW_DARRAY: - //case NEW_OARRAY: - code.Emit(OpCodes.Newarr, elemType); - return items.StackItem(MSILType.ARRAY(msilType(elemType))); - case ZARRAY_GET: case BARRAY_GET: case SARRAY_GET: - case CARRAY_GET: case IARRAY_GET: case LARRAY_GET: - case FARRAY_GET: case DARRAY_GET: case OARRAY_GET: - MSILType mType = MSILArrayElemType(elemType); - emitLdelem(mType); - return items.StackItem(mType); - case ZARRAY_SET: case BARRAY_SET: case SARRAY_SET: - case CARRAY_SET: case IARRAY_SET: case LARRAY_SET: - case FARRAY_SET: case DARRAY_SET: case OARRAY_SET: - emitStelem(MSILArrayElemType(elemType)); - return items.VoidItem(); - } - } - - if (isPrimitiveOp(sym)) { - assert args.length <= 1; - Tree right = args.length > 0 ? args[0] : Tree.Empty; - return primitiveOp(primitives.getPrimitive(sym), - qualifier, right, resType); - } - - Symbol owner = sym.owner(); - Type t = tc.getType(owner); - assert t != null; - if (t.IsEnum()) { - Primitive enumOp = null; - if (sym.name == Names.EQ) enumOp = Primitive.EQ; - else if (sym.name == Names.NE) enumOp = Primitive.NE; - else if (sym.name == Names.LT) enumOp = Primitive.LT; - else if (sym.name == Names.LE) enumOp = Primitive.LE; - else if (sym.name == Names.GT) enumOp = Primitive.GT; - else if (sym.name == Names.GE) enumOp = Primitive.GE; - else if (sym.name == Names.OR) enumOp = Primitive.OR; - else if (sym.name == Names.AND) enumOp = Primitive.AND; - else if (sym.name == Names.XOR) enumOp = Primitive.XOR; - if (enumOp != null) { - assert args.length == 1; - return primitiveOp(enumOp, qualifier, args[0], resType); - } - } - - switch (qualifier.type) { - case TypeRef(_, _, _): - case SingleType(_, _): - case ThisType(_): - MethodBase method = tc.getMethod(sym); - assert method != null : Debug.show(sym); - boolean virtualCall = false; - if (!method.IsStatic() || becomesStatic(sym)) { - // FIXME: after the Super attribution is correct - switch (qualifier) { - case Super(_, _): - load(items.SelfItem(tc.getType(currentClass))); - break; - default: - genAddr(qualifier, msilType(qualifier)); - virtualCall = !msilType(qualifier).isValueType(); - } - } - return check(invokeMethod(sym, args, resType, - virtualCall || method.IsAbstract())); - - default: - throw Debug.abort(Debug.show(fun)); - } // switch(qualifier.type) - - case TypeApply(Tree tfun, Tree[] targs): - final Symbol tsym = tfun.symbol(); - if (primitives.isPrimitive(tsym)) { - return primitiveOp(primitives.getPrimitive(tsym), - ((Select)tfun).qualifier, - targs[0], resType); - } - throw Debug.abort(Debug.show(fun)); - - default: - throw Debug.abort(Debug.show(fun)); - } // switch (fun) - } //genApply() - - - /** Generate code for scala's '==' */ - private Item genEq(Tree left, Tree right) { - LocalBuilder tmpLocal = (LocalBuilder)locals.get(defs.ANY_EQEQ); - if (tmpLocal == null) { - tmpLocal = code.DeclareLocal(tc.OBJECT); - locals.put(defs.ANY_EQEQ, tmpLocal); - } - Label l1 = code.DefineLabel(), l2 = code.DefineLabel(); - genLoad(left, MSILType.OBJECT); - genLoad(right, MSILType.OBJECT); - emitStloc(tmpLocal); - code.Emit(OpCodes.Dup); - code.Emit(OpCodes.Ldnull); - code.Emit(OpCodes.Bne_Un, l1); - emitLdloc(tmpLocal); - code.Emit(OpCodes.Ceq); - code.Emit(OpCodes.Br, l2); - code.MarkLabel(l1); - emitLdloc(tmpLocal); - code.Emit(OpCodes.Callvirt, tc.OBJECT_EQUALS); - code.MarkLabel(l2); - return items.StackItem(MSILType.BOOL); - } - - /** Is it a primitive (bot not an array) operation*/ - private boolean isPrimitiveOp(Symbol sym) { - switch (primitives.getPrimitive(sym)) { - case POS: case NEG: case NOT: - case ADD: case SUB: case MUL: case DIV: case MOD: - case OR: case XOR: case AND: - case LSL: case LSR: case ASR: - case ID: case NI: case EQ: case NE: case LT: case LE: case GT: case GE: - case ZNOT: case ZOR: case ZAND: - case IS: case AS: - case CONCAT: - case THROW: - case SYNCHRONIZED: - return true; - default: - return false; - } - } - - /* Is this a primitive Array operation. */ - private boolean isPrimitiveArrayOp(Symbol sym) { - switch (primitives.getPrimitive(sym)) { - case NEW_ZARRAY: case NEW_BARRAY: case NEW_SARRAY: - case NEW_CARRAY: case NEW_IARRAY: case NEW_LARRAY: - case NEW_FARRAY: case NEW_DARRAY: //case NEW_OARRAY: - case ZARRAY_LENGTH: case BARRAY_LENGTH: case SARRAY_LENGTH: - case CARRAY_LENGTH: case IARRAY_LENGTH: case LARRAY_LENGTH: - case FARRAY_LENGTH: case DARRAY_LENGTH: case OARRAY_LENGTH: - case ZARRAY_GET: case BARRAY_GET: case SARRAY_GET: - case CARRAY_GET: case IARRAY_GET: case LARRAY_GET: - case FARRAY_GET: case DARRAY_GET: case OARRAY_GET: - case ZARRAY_SET: case BARRAY_SET: case SARRAY_SET: - case CARRAY_SET: case IARRAY_SET: case LARRAY_SET: - case FARRAY_SET: case DARRAY_SET: case OARRAY_SET: - return true; - default: - return false; - } - } - - /* Is this a primitive conversion operation. */ - private MSILType primitiveConvert(Symbol sym) { - switch (primitives.getPrimitive(sym)) { - case B2B: case S2B: case C2B: case I2B: case L2B: case F2B: case D2B: - return MSILType.I1; - case B2S: case S2S: case C2S: case I2S: case L2S: case F2S: case D2S: - return MSILType.I2; - case B2C: case S2C: case C2C: case I2C: case L2C: case F2C: case D2C: - return MSILType.CHAR; - case B2I: case S2I: case C2I: case I2I: case L2I: case F2I: case D2I: - return MSILType.I4; - case B2L: case S2L: case C2L: case I2L: case L2L: case F2L: case D2L: - return MSILType.I8; - case B2F: case S2F: case C2F: case I2F: case L2F: case F2F: case D2F: - return MSILType.R4; - case B2D: case S2D: case C2D: case I2D: case L2D: case F2D: case D2D: - return MSILType.R8; - default: - return null; - } - } - - /* Generate code for primitive operations. */ - private Item primitiveOp(Primitive op, Tree left, Tree right, MSILType resType) - { - // treat some special cases - switch (op) { - - case CONCAT: - genLoad(left, MSILType.OBJECT); - genLoad(right, MSILType.OBJECT); - code.Emit(OpCodes.Call, tc.CONCAT_OBJECT_OBJECT); - return items.StackItem(MSILType.STRING); - - case ADD: - if (tc.getType(right.type) == tc.STRING) { - // TODO: check why this never gets printed - genLoad(left, MSILType.OBJECT); - genLoad(right, MSILType.OBJECT); - code.Emit(OpCodes.Call, tc.CONCAT_OBJECT_OBJECT); - return items.StackItem(MSILType.STRING); - } - break; - - case IS: - genLoad(left, MSILType.OBJECT); - final Type type = tc.getType(right.type); - code.Emit(OpCodes.Isinst, type); - return mkCond(items.StackItem(msilType(type))); - - case AS: - MSILType mltype = msilType(left); - Item item = genLoad(left, mltype); - final Type rtype = tc.getType(right.type); - final MSILType mrtype = msilType(rtype); - if (mltype.isEnum()) { - MSILType ptype = unboxValueType(mrtype); - if (ptype != null) { - MSILType uetype = msilType(mltype.getUnderlyingType()); - emitConvert(uetype, ptype); - return items.StackItem(ptype); - } - //} else if (!item.type.equals(mrtype) && !(rtype == tc.OBJECT)) { - } else if (!item.type.isSubtypeOf(mrtype) && !(rtype == tc.OBJECT)) { - if (rtype.IsValueType()) { - code.Emit(OpCodes.Unbox, rtype); - if (rtype.IsEnum()) - emitLdind(rtype.getUnderlyingType()); - else - code.Emit(OpCodes.Ldobj, rtype); - } else { - code.Emit(OpCodes.Castclass, rtype); - } - } - return items.StackItem(mrtype); - - case SYNCHRONIZED: - // TODO: reuse temporary local variable whenever possible - LocalBuilder tmp = code.DeclareLocal(tc.OBJECT); - genLoad(left, MSILType.OBJECT); - emitStloc(tmp); - emitLdloc(tmp); - code.Emit(OpCodes.Call, tc.MONITOR_ENTER); - genLoad(right, MSILType.OBJECT); - emitLdloc(tmp); - code.Emit(OpCodes.Call, tc.MONITOR_EXIT); - return items.StackItem(MSILType.OBJECT); - } - - Item iLeft = null; - MSILType tleft = msilType(left); - switch (left) { - case Apply(Tree fun , Tree[] args): - Primitive p = primitives.getPrimitive(fun.symbol()); - switch (p) { - case BOX: - assert args.length == 1; - iLeft = gen(args[0], msilType(args[0])); - break; - default: - iLeft = gen(left, tleft); - } - break; - default: - iLeft = gen(left, tleft); - } - - switch (op) { - case THROW: - load(iLeft); - code.Emit(OpCodes.Throw); -// code.Emit(OpCodes.Ldnull); -// return items.StackItem(MSILType.NULL); - //return coerce(loadNull(), resType); - return loadNull(); - - case POS: return load(coerce(iLeft, resType)); - case NEG: - iLeft = load(coerce(iLeft, resType)); - code.Emit(OpCodes.Neg); - return iLeft; - case NOT: - iLeft = load(coerce(iLeft, resType)); - code.Emit(OpCodes.Not); - return iLeft; - case ZNOT: - return negate(mkCond(iLeft)); - case ZOR: - Item.CondItem lcond = mkCond(iLeft), rcond = null; - Chain success = lcond.success, failure = lcond.failure; - switch (lcond.test) { - case True: - return lcond; - case False: - return mkCond(gen(right, MSILType.BOOL)); - case And(Test t): - success = (success != null) ? - success : new Chain(code.DefineLabel(), null); - branch(negate(lcond.test), success); - resolve(failure); - failure = null; - break; - default: - success = (success != null) ? - success : new Chain(code.DefineLabel(), null); - branch(negate(lcond.test), success); - } - rcond = mkCond((gen(right, MSILType.BOOL))); - rcond = items.CondItem(Test.Or(rcond.test), - merge(success, rcond.success), - merge(failure, rcond.failure)); - return rcond; - case ZAND: - Item.CondItem lcond = mkCond(iLeft), rcond = null; - Chain success = lcond.success, failure = lcond.failure; - switch (lcond.test) { - case False: - return lcond; - case True: - return mkCond(gen(right, MSILType.BOOL)); - case Or(Test t): - failure = (failure != null) ? - failure : new Chain(code.DefineLabel(), null); - branch(lcond.test, failure); - resolve(success); - success = null; - break; - default: - failure = (failure != null) ? - failure : new Chain(code.DefineLabel(), null); - branch(lcond.test, failure); - } - rcond = mkCond(gen(right, MSILType.BOOL)); - rcond = items.CondItem(Test.And(rcond.test), - merge(success, rcond.success), - merge(failure, rcond.failure)); - return rcond; - } - - MSILType toType = MSILType.arithmCoercion(iLeft.type.asPrimitive(), - primitiveType(right.type)); - load(coerce(iLeft, toType)); - genLoad(right, toType); - Item res = null; - switch (op) { - case ADD: code.Emit(OpCodes.Add); res = items.StackItem(toType); break; - case SUB: code.Emit(OpCodes.Sub); res = items.StackItem(toType); break; - case MUL: code.Emit(OpCodes.Mul); res = items.StackItem(toType); break; - case DIV: code.Emit(OpCodes.Div); res = items.StackItem(toType); break; - case MOD: code.Emit(OpCodes.Rem); res = items.StackItem(toType); break; - - case OR: code.Emit(OpCodes.Or); res = items.StackItem(toType); break; - case XOR: code.Emit(OpCodes.Xor); res = items.StackItem(toType); break; - case AND: code.Emit(OpCodes.And); res = items.StackItem(toType); break; - - case LSL: code.Emit(OpCodes.Shl); res = items.StackItem(toType); break; - case LSR: code.Emit(OpCodes.Shr); res = items.StackItem(toType); break; - case ASR: code.Emit(OpCodes.Shr_Un); res = items.StackItem(toType); break; - - case ID: case EQ: // FIXME?: should ID be treated as EQ? - res = items.CondItem(Test.Binary(Test.EQ, toType), null, null); - break; - case NI: case NE: // FIXME?: should NI be treated as NE? - res = items.CondItem(Test.Binary(Test.NE, toType), null, null); - break; - case LT: - res = items.CondItem(Test.Binary(Test.LT_IS, toType), null, null); - break; - case LE: - res = items.CondItem(Test.Binary(Test.LE_IS, toType), null, null); - break; - case GT: - res = items.CondItem(Test.Binary(Test.GT_IS, toType), null, null); - break; - case GE: - res = items.CondItem(Test.Binary(Test.GE_IS, toType), null, null); - break; - default: - throw Debug.abort(Debug.show(op)); - } - - return coerce(res, resType); - } - - /* - * Load function arguments on the stack. - */ - private void loadArgs(Tree[] args, ParameterInfo[] params) { - for (int i = 0; i < args.length; i++) { - MSILType toType = msilType(params[i].ParameterType); //msilType(args[i].type); - genLoad(args[i], toType); - } - } - - /* - * Tells if a non-static method is translated to a static one. - */ - private boolean becomesStatic(Symbol sym) { - MethodBase method = tc.getMethod(sym); - return !sym.isStatic() && method.IsStatic(); - } - - /* - * Generate code for method invocation - */ - private Item invokeMethod(Symbol fun, Tree[] args, MSILType resType, - boolean virtualCall) { - MethodBase method = tc.getMethod(fun); - assert method != null : "Coudn't resolve method: " + Debug.show(fun); - Item res = null; - if (method.IsStatic()) { - ParameterInfo[] params = method.GetParameters(); - if (becomesStatic(fun)) { - assert params.length == args.length + 1; - ParameterInfo[] newParams = new ParameterInfo[params.length - 1]; - for (int i = 0; i < newParams.length; i++) - newParams[i] = params[i + 1]; - params = newParams; - } - loadArgs(args, params); - code.Emit(OpCodes.Call, (MethodInfo)method); - res = returnsVoid(method) ? items.VoidItem() : - items.StackItem(resType); - } else if (method.IsConstructor()) { - // used only for calls to super constructor - //emitThis(); - loadArgs(args, method.GetParameters()); - code.Emit(OpCodes.Call, (ConstructorInfo)method); - res = items.VoidItem(); - } else { - loadArgs(args, method.GetParameters()); - if (enableTailCalls && lastExpr /*&& method == currentMethod*/) - code.Emit(OpCodes.Tailcall); - code.Emit(virtualCall ? OpCodes.Callvirt : OpCodes.Call, - (MethodInfo)method); - res = returnsVoid(method) ? items.VoidItem() : items.StackItem(resType); - } - CLRTypes clrt = CLRTypes.instance(); - if (returnsVoid(fun) && !returnsVoid(method) - && method != clrt.DELEGATE_COMBINE - && method != clrt.DELEGATE_REMOVE) - { - res = drop(res); - } - return res; - } - - private Item createDelegateFromFunction(Tree fun, MSILType type) { - Item ifun = genLoad(fun, msilType(fun.type)); - // Get the apply function of the delegate object - Symbol funSym = tc.getSymbol(ifun.type.toType()); - Symbol applySym = funSym.lookup(Names.apply); - MethodInfo apply = (MethodInfo) tc.getDelegateApplyMethod(applySym); - - // Get the (object, native int) constructor of the delegate type - Type delegateType = type.toType(); - ConstructorInfo delegCtor = delegateType.GetConstructor( - new Type[]{tc.OBJECT, Type.GetType("System.IntPtr")}); - - // Duplicate the object on the stack; we need its apply method - // and Ldvirtftn uses one element. - code.Emit(OpCodes.Dup); - code.Emit(OpCodes.Ldvirtftn, apply); - - // Create a new delegate; this uses up the element duplicated above. - code.Emit(OpCodes.Newobj, delegCtor); - - return items.StackItem(type); - } - - /* - * Returns the MSILType that corresponds to the given scala.symtab.Type - */ - private MSILType msilType(scalac.symtab.Type type) { - return type.symbol() == defs.ALLREF_CLASS ? MSILType.NULL - : msilType(tc.getType(type)); - } - - /* - * Also used from class ItemFactory. - */ - MSILType msilType(Type type) { - return MSILType.fromType(type); - } - - /* - * Returns the MSILType from the type atribute of a tree node - */ - private MSILType msilType(Tree t) { - return msilType(t.type); - } - - /* - * Treat the scala boxed types as a primitive type - */ - private MSILType primitiveType(scalac.symtab.Type type) { - MSILType mtype = msilType(type); - switch (mtype) { - case REF(Type t): - return unboxValueType(mtype).asPrimitive(); - //case NULL: - case ARRAY(_): - throw Debug.abort("cannot convert " + mtype); - default: - return mtype; - } - } - - private MSILType unboxValueType(MSILType type) { - switch (type) { - case REF(Type t): - if (t == tc.SCALA_BYTE) return MSILType.I1; - if (t == tc.SCALA_SHORT) return MSILType.I2; - if (t == tc.SCALA_INT) return MSILType.I4; - if (t == tc.SCALA_LONG) return MSILType.I8; - if (t == tc.SCALA_FLOAT) return MSILType.R4; - if (t == tc.SCALA_DOUBLE) return MSILType.R8; - if (t == tc.SCALA_CHAR) return MSILType.CHAR; - //if (t == tc.SCALA_UNIT) return MSILType.VOID; - if (t == tc.SCALA_BOOLEAN) return MSILType.BOOL; - } - return type; - } - - /* - * Provides a translation for some types when used as array elements. - */ - private MSILType MSILArrayElemType(Type type) { - MSILType mtype = msilType(type); - switch (mtype) { - case BOOL: return MSILType.I1; - case CHAR: return MSILType.I4; - default: return mtype; - } - } - - /* - * - */ - private Type getArrayElemType(Primitive p) { - switch (p) { - case NEW_ZARRAY: case ZARRAY_LENGTH: case ZARRAY_GET: case ZARRAY_SET: - return tc.BOOLEAN; - case NEW_BARRAY: case BARRAY_LENGTH: case BARRAY_GET: case BARRAY_SET: - return tc.BYTE; - case NEW_SARRAY: case SARRAY_LENGTH: case SARRAY_GET: case SARRAY_SET: - return tc.SHORT; - case NEW_CARRAY: case CARRAY_LENGTH: case CARRAY_GET: case CARRAY_SET: - return tc.CHAR; - case NEW_IARRAY: case IARRAY_LENGTH: case IARRAY_GET: case IARRAY_SET: - return tc.INT; - case NEW_LARRAY: case LARRAY_LENGTH: case LARRAY_GET: case LARRAY_SET: - return tc.LONG; - case NEW_FARRAY: case FARRAY_LENGTH: case FARRAY_GET: case FARRAY_SET: - return tc.FLOAT; - case NEW_DARRAY: case DARRAY_LENGTH: case DARRAY_GET: case DARRAY_SET: - return tc.DOUBLE; - case NEW_OARRAY: case OARRAY_LENGTH: case OARRAY_GET: case OARRAY_SET: - return tc.OBJECT; - } - throw Debug.abort("unknown primitive " + Debug.show(p)); - } - - /* - * Emit code to load an array elemnt of the given type on the stack. - */ - private Item emitLdelem(MSILType type) { - switch (type) { - case I1: code.Emit(OpCodes.Ldelem_I1); break; - case I2: code.Emit(OpCodes.Ldelem_I2); break; - case I4: code.Emit(OpCodes.Ldelem_I4); break; - case I8: code.Emit(OpCodes.Ldelem_I8); break; - case R4: code.Emit(OpCodes.Ldelem_R4); break; - case R8: code.Emit(OpCodes.Ldelem_R8); break; - case ARRAY(_): - case REF(_): - code.Emit(OpCodes.Ldelem_Ref); break; - } - return items.StackItem(type); - } - - /* - * Emit code to strore the value at the top of the stack from the given type - * to an array. - */ - private Item emitStelem(MSILType type) { - switch (type) { - case I1: code.Emit(OpCodes.Stelem_I1); break; - case I2: code.Emit(OpCodes.Stelem_I2); break; - case I4: code.Emit(OpCodes.Stelem_I4); break; - case I8: code.Emit(OpCodes.Stelem_I8); break; - case R4: code.Emit(OpCodes.Stelem_R4); break; - case R8: code.Emit(OpCodes.Stelem_R8); break; - case ARRAY(_): - case REF(_): - code.Emit(OpCodes.Stelem_Ref); break; - } - return items.StackItem(type); - } - - private Item.LiteralItem mkLiteral(MSILType type, Object value) { - LiteralItem item = null; - if (value instanceof Integer) - item = items.LiteralItem(AConstant.INT(((Number)value).intValue())); - else if (value instanceof Long) - item = items.LiteralItem(AConstant.LONG(((Number)value).longValue())); - else if (value instanceof Float) - item = items.LiteralItem(AConstant.FLOAT(((Number)value).floatValue())); - else if (value instanceof Double) - item = items.LiteralItem(AConstant.DOUBLE(((Number)value).doubleValue())); - else throw Debug.abort(); - item.type = type; - return item; - } - - private void emitLdarg(int slot) { - assert slot >= 0; - switch (slot) { - case 0: code.Emit(OpCodes.Ldarg_0); break; - case 1: code.Emit(OpCodes.Ldarg_1); break; - case 2: code.Emit(OpCodes.Ldarg_2); break; - case 3: code.Emit(OpCodes.Ldarg_3); break; - default: - code.Emit(slot < 256 ? OpCodes.Ldarg_S : OpCodes.Ldarg, slot); - } - } - - private void emitLdarga(int slot) { - code.Emit(slot < 256 ? OpCodes.Ldarga_S : OpCodes.Ldarga, slot); - } - - private void emitLdloc(LocalBuilder loc) { - switch (loc.slot) { - case 0: code.Emit(OpCodes.Ldloc_0); break; - case 1: code.Emit(OpCodes.Ldloc_1); break; - case 2: code.Emit(OpCodes.Ldloc_2); break; - case 3: code.Emit(OpCodes.Ldloc_3); break; - default: - code.Emit(loc.slot < 256 ? OpCodes.Ldloc_S : OpCodes.Ldloc, loc); - } - } - - private void emitLdloca(LocalBuilder loc) { - code.Emit(loc.slot < 256 ? OpCodes.Ldloca_S : OpCodes.Ldloca, loc); - } - - private void emitStloc(LocalBuilder loc) { - switch (loc.slot) { - case 0: code.Emit(OpCodes.Stloc_0); break; - case 1: code.Emit(OpCodes.Stloc_1); break; - case 2: code.Emit(OpCodes.Stloc_2); break; - case 3: code.Emit(OpCodes.Stloc_3); break; - default: - code.Emit(loc.slot < 256 ? OpCodes.Stloc_S : OpCodes.Stloc, loc); - } - } - - /* - * Load the value of an item on the stack. - */ - private Item load(Item that) { - switch (that) { - case VoidItem(): - return that; - - case StackItem(): - return (StackItem) that; - - case LiteralItem(AConstant value): - return loadLiteral(value, that.type); - - case SelfItem(): - emitThis(); - return items.StackItem(that.type); - - case ArgItem(int slot): - emitLdarg(slot); - return items.StackItem(that.type); - - case LocalItem(LocalBuilder local): - emitLdloc(local); - return items.StackItem(that.type); - - case StaticItem(FieldInfo field): - assert !field.IsLiteral() : field.toString(); - code.Emit(OpCodes.Ldsfld, field); - return items.StackItem(that.type); - - case SelectItem(Item qual, FieldInfo field): - Item i = load(qual); - code.Emit(OpCodes.Ldfld, field); - return items.StackItem(that.type); - - case CondItem(Test test, Chain success, Chain failure): - load(test); - switch (test) { - case Or(_): - case And(_): - Label exit = null; - /*if (lastExpr) - code.Emit(OpCodes.Ret); - else */ { - exit = code.DefineLabel(); - if (!unreachable) - code.Emit(OpCodes.Br, exit); - } - if (failure != null) { - resolve(failure); - load(FALSE_ITEM); - if (success != null) { - /*if (lastExpr) - code.Emit(OpCodes.Ret); - else*/ - if (!unreachable) - code.Emit(OpCodes.Br, exit); - } - } - if (success != null) { - resolve(success); - load(TRUE_ITEM); - } - resolve(exit); - break; - } - return items.StackItem(MSILType.BOOL); - - default: - throw Debug.abort("load item: " + that); - } - } - - - /* - * Load the value of a test on the stack. - */ - private void load(Test test) { - switch (test) { - case False: - code.Emit(OpCodes.Ldc_I4_0); - break; - case True: - code.Emit(OpCodes.Ldc_I4_1); - break; - case Bool(boolean value): - if (value) negate_load(); - break; - case Binary(int opcode, MSILType type): - code.Emit(load(opcode)); - if (negate_load(opcode)) negate_load(); - break; - case And(Test t): - load(t); - break; - case Or(Test t): - load(t); - break; - default: - throw Debug.abort(test.getClass().getName()); - } - } - - /* - * Load the value of an ALiteral on the stack. - */ - private Item.StackItem loadLiteral(AConstant constant) { - switch (constant) { - case UNIT: - return loadUnit(); - case BOOLEAN(boolean value): - return loadBool(value); - case BYTE(byte value): - return loadI4(value); - case SHORT(short value): - return loadI4(value); - case CHAR(char value): - loadI4(value); - return items.StackItem(MSILType.CHAR); - case INT(int value): - return loadI4(value); - case LONG(long value): - return loadI8(value); - case FLOAT(float value): - return loadR4(value); - case DOUBLE(double value): - return loadR8(value); - case STRING(String value): - return loadString(value); - case NULL: - return loadNull(); - default: - throw Debug.abort("illegal case", constant); - } - } - - /* - * Load the value of an ALiteral coerced to the given type. - */ - private Item loadLiteral(AConstant constant, MSILType ofType) { - switch (ofType) { - case I1: - case I2: - case I4: - loadI4(constant.intValue()); return items.StackItem(MSILType.I4); - case CHAR: - loadI4(constant.intValue()); return items.StackItem(MSILType.CHAR); - case I8: loadI8(constant.longValue()); return items.StackItem(ofType); - case R4: loadR4(constant.floatValue()); return items.StackItem(ofType); - case R8: loadR8(constant.doubleValue()); return items.StackItem(ofType); - case REF(Type t): - //assert t == tc.STRING || ofType.isValueType() : "" + ofType; - return coerce(loadLiteral(constant), ofType); - default: - return coerce(loadLiteral(constant), ofType); - } - } - - /* - * Load boxed scala.Unit on the stack. - */ - private Item.StackItem loadUnit() { - code.Emit(OpCodes.Call, tc.RUNTIME_BOX_UNIT); - return items.StackItem(msilType(tc.RUNTIME_BOX_UNIT.ReturnType)); - } - - /* - * Load a boolean value on the stack. - */ - private Item.StackItem loadBool(boolean value) { - code.Emit(value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); - return items.StackItem(MSILType.BOOL); - } - - /* - * Load a 32-bit integer literal on the stack. - */ - private Item.StackItem loadI4(int value) { - switch (value) { - case -1:code.Emit(OpCodes.Ldc_I4_M1); break; - case 0: code.Emit(OpCodes.Ldc_I4_0); break; - case 1: code.Emit(OpCodes.Ldc_I4_1); break; - case 2: code.Emit(OpCodes.Ldc_I4_2); break; - case 3: code.Emit(OpCodes.Ldc_I4_3); break; - case 4: code.Emit(OpCodes.Ldc_I4_4); break; - case 5: code.Emit(OpCodes.Ldc_I4_5); break; - case 6: code.Emit(OpCodes.Ldc_I4_6); break; - case 7: code.Emit(OpCodes.Ldc_I4_7); break; - case 8: code.Emit(OpCodes.Ldc_I4_8); break; - default: - if (value >= -128 && value <= 127) - code.Emit(OpCodes.Ldc_I4_S, value); - else - code.Emit(OpCodes.Ldc_I4, value); - } - return items.StackItem(MSILType.I4); - } - - /* - * Load a 64-bit integer value on the stack. - */ - private Item.StackItem loadI8(long value) { - code.Emit(OpCodes.Ldc_I8, value); - return items.StackItem(MSILType.I8); - } - - /* - * Load a single precision floating point value on the stack. - */ - private Item.StackItem loadR4(float value) { - code.Emit(OpCodes.Ldc_R4, value); - return items.StackItem(MSILType.R4); - } - - /* - * Load a double precision floating point value on the stack. - */ - private Item.StackItem loadR8(double value) { - code.Emit(OpCodes.Ldc_R8, value); - return items.StackItem(MSILType.R8); - } - - /* - * Load a string reference on the stack. - */ - private Item.StackItem loadString(String value) { - code.Emit(OpCodes.Ldstr, value); - return items.StackItem(MSILType.STRING); - } - - /* - * Load the 'null' reference on the stack. - */ - private Item.StackItem loadNull() { - code.Emit(OpCodes.Ldnull); - return items.StackItem(MSILType.NULL); - } - - private void emitLdind(Type type) { - if (type == tc.BYTE) - code.Emit(OpCodes.Ldind_I1); - else if (type == tc.SHORT) - code.Emit(OpCodes.Ldind_I2); - else if (type == tc.INT) - code.Emit(OpCodes.Ldind_I4); - else if (type == tc.LONG) - code.Emit(OpCodes.Ldind_I8); - else - throw Debug.abort("emitLdind failed", type); - } - - - /* - * Store the value on the stack to the location specified by the item. - */ - private Item store(Item that) { - switch (that) { - case ArgItem(int slot): - code.Emit(OpCodes.Starg, slot); - break; - - case LocalItem(LocalBuilder local): - emitStloc(local); - break; - - case StaticItem(FieldInfo field): - assert !field.IsLiteral(); - code.Emit(OpCodes.Stsfld, field); - break; - - case SelectItem(Item qual, FieldInfo field): - load(qual); - code.Emit(OpCodes.Stfld, field); - break; - - default: - throw Debug.abort("Cannot store item: " + that); - } - return items.VoidItem(); - } - - - /* - * Discard the item. - */ - private Item drop(Item that) { - switch (that) { - case VoidItem(): - case SelfItem(): - case LiteralItem(_): - case ArgItem(_): - case LocalItem(_): - case StaticItem(_): - break; - case StackItem(): - code.Emit(OpCodes.Pop); - break; - case SelectItem(Item qual, _): - drop(qual); - break; - case CondItem(Test test, _, _): - switch (test) { - case False: - case True: - break; - case Bool(_): - code.Emit(OpCodes.Pop); - break; - case And(_): - case Or(_): - drop(load(that)); - break; - case Binary(_, _): - code.Emit(OpCodes.Pop); - code.Emit(OpCodes.Pop); - break; - default : - throw Debug.abort(that.getClass().getName()); - } - break; - default: - drop(load(that)); - } - return items.VoidItem(); - } - - /* - * Generate a condition corresponding to the given item. - */ - private Item.CondItem mkCond(Item that) { - switch (that) { - case CondItem(_, _, _): return (Item.CondItem) that; - default: - load(that); - return items.CondItem(Test.Bool(false), null, null); - } - } - - // load the address of a value type item; - // for reference types load a reference - private Item genAddr(Tree tree, MSILType toType) { - Item item = gen(tree, toType); - if (!item.type.isValueType()) - return load(item); - switch (item) { - case ArgItem(int slot): - emitLdarga(slot); - break; - case LocalItem(LocalBuilder local): - emitLdloca(local); - break; - case StaticItem(FieldInfo field): - if (field.IsInitOnly()) { - load(item); - genLocalAddr(field.FieldType); - } else - code.Emit(OpCodes.Ldsflda, field); - break; - case SelectItem(Item qual, FieldInfo field): - if (field.IsInitOnly()) { - load(item); - genLocalAddr(field.FieldType); - } else { - load(qual); - code.Emit(OpCodes.Ldflda, field); - } - break; - case StackItem(): - genLocalAddr(item.type.toType()); - break; - default: - throw Debug.abort(item.toString()); - } - return items.StackItem(toType); - } - - private void genLocalAddr(Type localType) { - assert localType.IsValueType() : localType.toString(); - LocalBuilder tmpLocal = (LocalBuilder)locals.get(localType); - if (tmpLocal == null) { - tmpLocal = code.DeclareLocal(localType); - locals.put(localType, tmpLocal); - } - emitStloc(tmpLocal); - emitLdloca(tmpLocal); - } - - /* - * Negate a condition. - */ - private Item.CondItem negate(Item item) { - Item.CondItem cond = mkCond(item); - // swap the failure and success chains - //return items.CondItem(negate(cond.test), cond.success, cond.failure); - return items.CondItem(negate(cond.test), cond.failure, cond.success); - } - - /* - * Emit code to negate a boolean value on the stack. - */ - private void negate_load() { - code.Emit(OpCodes.Ldc_I4_1); - code.Emit(OpCodes.Xor); - } - - /* - * Negate a test. - */ - private Test negate(Test that) { - switch (that) { - - case False: - return Test.True; - - case True: - return Test.False; - - case Bool(boolean value): - return Test.Bool(!value); - - case And(Test test): - return Test.Or(negate(test)); - - case Or(Test test): - return Test.And(negate(test)); - - case Binary(int opcode, MSILType type): - return Test.Binary(negate(opcode), type); - - default: - throw Debug.abort(that.getClass().getName()); - } - } - - /* - * Emit code for the appropriate branch. - */ - private Label branch(Test test, Chain chain) { - assert chain != null; - Label label = chain.label; - switch (test) { - case False: - code.Emit(OpCodes.Br, label); - return label; - case True: - return null; - case Bool(boolean value): - code.Emit(value ? OpCodes.Brtrue : OpCodes.Brfalse, label); - return label; - case And(Test t): - return branch(t, chain); - case Or(Test t): - return branch(t, chain); - case Binary(int opcode, MSILType type): - code.Emit(branch(negate(opcode)), label); - return label; - default: - throw Debug.abort(); - } - } - - /* - * Merge two label chains. - */ - private static Chain merge(Chain c1, Chain c2) { - if (c1 == null) return c2; - if (c2 == null) return c1; - Chain c = c1; - for(; c.next != null; c = c.next) ; - c.next = c2; - return c1; - } - - /* - * Resolve all labels int the chain to the current position in the code. - */ - private void resolve(Chain c) { - for (; c != null; c = c.next) - code.MarkLabel(c.label); - } - - /* - * Resolve a label to the current position in the code. - */ - private void resolve(Label l) { - if (l != null) - code.MarkLabel(l); - } - - /* - * - */ - private static boolean negate_load(int opcode) { - switch (opcode) { - case Test.LT_IS: return false; - case Test.LE_IS: return true; - case Test.GT_IS: return false; - case Test.GE_IS: return true; - case Test.LT_IU: return false; - case Test.LE_IU: return true; - case Test.GT_IU: return false; - case Test.GE_IU: return true; - case Test.LT_RO: return false; - case Test.LE_RO: return true; - case Test.GT_RO: return false; - case Test.GE_RO: return true; - case Test.LT_RU: return false; - case Test.LE_RU: return true; - case Test.GT_RU: return false; - case Test.GE_RU: return true; - case Test.EQ : return false; - case Test.NE : return true; - default : throw Debug.abort("" + opcode); - } - } - - /* - * - */ - private static OpCode load(int opcode) { - switch (opcode) { - case Test.LT_IS: return OpCodes.Clt; - case Test.LE_IS: return OpCodes.Cgt; // negate - case Test.GT_IS: return OpCodes.Cgt; - case Test.GE_IS: return OpCodes.Clt; // negate - case Test.LT_IU: return OpCodes.Clt_Un; - case Test.LE_IU: return OpCodes.Cgt_Un; // negate - case Test.GT_IU: return OpCodes.Cgt_Un; - case Test.GE_IU: return OpCodes.Clt_Un; // negate - case Test.LT_RO: return OpCodes.Clt; - case Test.LE_RO: return OpCodes.Cgt_Un; // negate - case Test.GT_RO: return OpCodes.Cgt; - case Test.GE_RO: return OpCodes.Clt_Un; // negate - case Test.LT_RU: return OpCodes.Clt_Un; - case Test.LE_RU: return OpCodes.Cgt; // negate - case Test.GT_RU: return OpCodes.Cgt_Un; - case Test.GE_RU: return OpCodes.Clt; // negate - case Test.EQ : return OpCodes.Ceq; - case Test.NE : return OpCodes.Ceq; // negate - default : throw Debug.abort("" + opcode); - } - } - - /* - * - */ - private static int negate(int opcode) { - switch (opcode) { - case Test.LT_IS: return Test.GE_IS; - case Test.LE_IS: return Test.GT_IS; - case Test.GT_IS: return Test.LE_IS; - case Test.GE_IS: return Test.LT_IS; - case Test.LT_IU: return Test.GE_IU; - case Test.LE_IU: return Test.GT_IU; - case Test.GT_IU: return Test.LE_IU; - case Test.GE_IU: return Test.LT_IU; - case Test.LT_RO: return Test.GE_RU; - case Test.LE_RO: return Test.GT_RU; - case Test.GT_RO: return Test.LE_RU; - case Test.GE_RO: return Test.LT_RU; - case Test.LT_RU: return Test.GE_RO; - case Test.LE_RU: return Test.GT_RO; - case Test.GT_RU: return Test.LE_RO; - case Test.GE_RU: return Test.LT_RO; - case Test.EQ : return Test.NE; - case Test.NE : return Test.EQ; - default : throw Debug.abort("" + opcode); - } - } - - /* - * - */ - private static OpCode branch(int opcode) { - switch (opcode) { - case Test.LT_IS: - case Test.LT_RO: return OpCodes.Blt; - case Test.LE_IS: - case Test.LE_RO: return OpCodes.Ble; - case Test.GT_IS: - case Test.GT_RO: return OpCodes.Bgt; - case Test.GE_IS: - case Test.GE_RO: return OpCodes.Bge; - case Test.LT_IU: - case Test.LT_RU: return OpCodes.Blt_Un; - case Test.LE_IU: - case Test.LE_RU: return OpCodes.Ble_Un; - case Test.GT_IU: - case Test.GT_RU: return OpCodes.Bgt_Un; - case Test.GE_IU: - case Test.GE_RU: return OpCodes.Bge_Un; - case Test.EQ : return OpCodes.Beq; - case Test.NE : return OpCodes.Bne_Un; - default : throw Debug.abort("" + opcode); - } - } - - //########################################################################## -} // class GenMSIL - -/** - * Represents the supported types of the CLR. - */ -final class MSILType { - public case I1; - public case I2; - public case U2; - public case I4; - public case I8; - public case R4; - public case R8; - public case BOOL; - public case CHAR; - public case VOID; - public case NULL; - public case REF(Type t) { assert t != null && !t.IsArray(); } - public case ARRAY(MSILType t) { assert t != null; } - - private final static CLRTypes pp = CLRTypes.instance(); - - public static final MSILType OBJECT = REF(pp.OBJECT); - public static final MSILType STRING = REF(pp.STRING); - public static final MSILType UNIT = REF(pp.getType("scala.Unit")); - - //########################################################################## - // factory methods - -// public static MSILType fromKind(int kind) { -// switch (kind) { -// case TypeTags.BYTE: return I1; -// case TypeTags.CHAR: return CHAR; -// case TypeTags.SHORT: return I2; -// case TypeTags.INT: return I4; -// case TypeTags.LONG: return I8; -// case TypeTags.FLOAT: return R4; -// case TypeTags.DOUBLE: return R8; -// case TypeTags.BOOLEAN: return BOOL; -// case TypeTags.UNIT: return VOID; -// case TypeTags.STRING: return STRING; -// default: -// throw Debug.abort("Unknown kind: " + kind); - -// } -// } - - public static MSILType fromType(Type type) { - if (type == pp.BYTE) return I1; - if (type == pp.SHORT) return I2; - if (type == pp.INT) return I4; - if (type == pp.LONG) return I8; - if (type == pp.FLOAT) return R4; - if (type == pp.DOUBLE) return R8; - if (type == pp.CHAR) return CHAR; - if (type == pp.VOID) return VOID; - if (type == pp.BOOLEAN)return BOOL; - if (type == pp.STRING) return STRING; - if (type == pp.OBJECT) return OBJECT; - if (type.IsArray()) - return ARRAY(fromType(type.GetElementType())); - return REF(type); - - } - - public static MSILType fromAConstant(AConstant value) { - switch (value) { - case UNIT: - return UNIT; // was VOID; // FIXME - case BOOLEAN(_): - return BOOL; - case BYTE(_): - return I1; - case SHORT(_): - return I2; - case CHAR(_): - return CHAR; - case INT(_): - return I4; - case LONG(_): - return I8; - case FLOAT(_): - return R4; - case DOUBLE(_): - return R8; - case STRING(_): - return STRING; - case NULL: - return NULL; - case ZERO: - return I4; - default: - throw Debug.abort("unknown case", value); - } - } - - public Type toType() { - switch (this) { - case I1: return pp.BYTE; - case I2: return pp.SHORT; - //case U2: return ; - case I4: return pp.INT; - case I8: return pp.LONG; - case R4: return pp.FLOAT; - case R8: return pp.DOUBLE; - case BOOL: return pp.BOOLEAN; - case CHAR: return pp.CHAR; - case REF(Type t): return t; - case ARRAY(MSILType t): return pp.mkArrayType(t.toType()); - case VOID: return pp.VOID; - //case NULL: return "NULL"; - default: throw Debug.abort(getClass().toString()); - } - - } - - //########################################################################## - - public boolean equals(Object that) { - if (this == that) - return true; - if (that == null || !(that instanceof MSILType)) - return false; - MSILType thatType = (MSILType)that; - switch (this) { - case REF(Type t1): - switch (thatType) { - case REF(Type t2): - return t1.equals(t2); - default: - return false; - } - case ARRAY(MSILType t1): - switch (thatType) { - case ARRAY(MSILType t2): - return t1.equals(t2); - default: - return false; - } - default: - return false; - } - } - - public boolean isReferenceType() { - switch (this) { - case REF(Type t): - return !t.IsValueType(); - case NULL: - case ARRAY(_): - return true; - default: - return false; - } - } - - public boolean isValueType() { - return !isReferenceType(); - } - - public boolean isEnum() { - switch (this) { - case REF(Type t): - return t.IsEnum(); - default: - return false; - } - } - - /** Returns the underlying type of an enumeration; null otherwise */ - public Type getUnderlyingType() { - switch (this) { - case REF(Type t): - return t.getUnderlyingType(); - default: - return null; - } -} - - public boolean isType(Type type) { - return equals(fromType(type)); - } - - public MSILType asPrimitive() { - switch (this) { - case REF(Type t): - if (t.IsEnum()) return fromType(t.getUnderlyingType()); - else return this; - //case NULL: - case ARRAY(_): - throw Debug.abort(this); - default: return this; - } - } - - /** Is this type is a subtype of that. */ - public boolean isSubtypeOf(MSILType that) { - assert that != null; - if (this == that - || (this.isReferenceType() && that.isType(pp.OBJECT))) - return true; - if (this.isValueType() && that.isReferenceType()) - return false; - switch (this) { - case BOOL: return that == I4; - case REF(Type t1): - switch (that) { - case REF(Type t2): - return t1.isSubtypeOf(t2); - default: - return false; - } - case ARRAY(MSILType t1): - switch (that) { - case ARRAY(MSILType t2): - return t1.isSubtypeOf(t2); - default: - return false; - } - case NULL: - switch (that) { - case REF(_): - case ARRAY(_): - return true; - default: - return false; - } - default: - return false; - } - } - - - private static final MSILType [] ARITHM_PRECISION = - new MSILType[] {I1, I2, CHAR, I4, I8, R4, R8}; - - /** - * @param t1 - * @param t2 - * @return the arithmetic coercion type for types t1 and t2 - */ - public static MSILType arithmCoercion(MSILType t1, MSILType t2) { - if (t1 == t2) return t1; - int i, j, n = ARITHM_PRECISION.length; - for (i = 0; i < n; i++) - if (t1 == ARITHM_PRECISION[i]) - break; - for (j = 0; j < n; j++) - if (t2 == ARITHM_PRECISION[j]) - break; - int m = Math.max(i, j); - if (m < n) - return ARITHM_PRECISION[m]; - else if (t1.isSubtypeOf(t2)) return t2; - else if (t2.isSubtypeOf(t1)) return t1; - else throw Debug.abort("cannot find coercion " + t1 + " => " + t2); - } - - public String toString() { - switch (this) { - case I1: return "I1"; - case I2: return "I2"; - case U2: return "U2"; - case I4: return "I4"; - case I8: return "I8"; - case R4: return "R4"; - case R8: return "R8"; - case BOOL: return "BOOL"; - case CHAR: return "CHAR"; - case REF(Type t): return "REF(" + t + ")"; - case ARRAY(MSILType t): return "ARRAY(" + t + ")"; - case VOID: return "VOID"; - case NULL: return "NULL"; - default: return getClass().getName(); - } - } - - //########################################################################## -} - - -/** - * The items used for deferred code generation. - */ -class Item { - public MSILType type; - - public case VoidItem(); - public case StackItem(); - public case SelfItem(); - public case LiteralItem(AConstant value); - public case ArgItem(int slot); - public case LocalItem(LocalBuilder local); - public case StaticItem(FieldInfo field); - public case SelectItem(Item qual, FieldInfo field); - public case CondItem(Test test, Chain success, Chain failure); - - public String toString() { - switch (this) { - case VoidItem(): return "VoidItem: " + type; - case StackItem(): return "StackItem: " + type ; - case SelfItem(): return "this: " + type; - case LiteralItem(AConstant value): - return "LiteralItem(" + value + "): " + type; - case ArgItem( int slot): - return "ArgItem(" + slot + "): " + type; - case LocalItem( LocalBuilder local): - return "LocalItem(" + local + "): " + type; - case StaticItem( FieldInfo field): - return "StaticItem(" + field + "): " + type; - case SelectItem(_, FieldInfo field): - return "SelectItem(" + field + "): " +type; - case CondItem(Test test, Chain success, Chain failure): - return "CondItem(" + test + ", " + success - + ", " + failure + "): " + type; - } - return "??Item??"; - } -} - - -/** - * Class implementing a chain (list) of labels. - */ -class Chain { - Label label; - Chain next; - Chain(Label l, Chain n) { label = l; next = n; } -} - - -/** - * Factory class for items. - */ -class ItemFactory { - GenMSIL coder; - private static final Item.VoidItem VOID = Item.VoidItem(); - static { VOID.type = MSILType.VOID; } - - public ItemFactory(GenMSIL _coder) { - coder = _coder; - } - public Item.VoidItem VoidItem() { - return VOID; - } - public Item.StackItem StackItem(MSILType type) { - Item.StackItem item = Item.StackItem(); - item.type = type; - assert item.type != null; - return item; - } - public Item.SelfItem SelfItem(Type t) { - Item.SelfItem item = Item.SelfItem(); - item.type = coder.msilType(t); - assert item.type != null; - return item; - } - public Item.LiteralItem LiteralItem(AConstant value) { - Item.LiteralItem item = Item.LiteralItem(value); - item.type = MSILType.fromAConstant(value); - assert item.type != null; - return item; - } - public Item.ArgItem ArgItem(MSILType type, int slot) { - Item.ArgItem item = Item.ArgItem(slot); - item.type = type; - assert item.type != null; - return item; - } - public Item.LocalItem LocalItem(LocalBuilder local) { - Item.LocalItem item = Item.LocalItem(local); - item.type = coder.msilType(local.LocalType); - assert item.type != null; - return item; - } - public Item.StaticItem StaticItem(FieldInfo field) { - assert field.IsStatic(); - Item.StaticItem item = Item.StaticItem(field); - item.type = coder.msilType(field.FieldType); - assert item.type != null; - return item; - } - public Item.SelectItem SelectItem(Item qualifier, FieldInfo field) { - assert !field.IsStatic(); - Item.SelectItem item = Item.SelectItem(qualifier, field); - item.type = coder.msilType(field.FieldType); - assert item.type != null; - return item; - } - public Item.CondItem CondItem(Test test, Chain success, Chain failure) { - Item.CondItem item = Item.CondItem(test, success, failure); - item.type = MSILType.BOOL; - return item; - } -} - -/** - * Class representing the possible tests in conditional item - */ -class Test { - - public case False; - public case True; - public case Bool(boolean value); - public case Or(Test test); - public case And(Test test); - public case Binary(int opcode, MSILType type); - - public static final int LT_IS = 0x00; - public static final int LE_IS = 0x01; - public static final int GT_IS = 0x02; - public static final int GE_IS = 0x03; - - public static final int LT_IU = 0x04; - public static final int LE_IU = 0x05; - public static final int GT_IU = 0x06; - public static final int GE_IU = 0x07; - - public static final int LT_RO = 0x08; - public static final int LE_RO = 0x09; - public static final int GT_RO = 0x0A; - public static final int GE_RO = 0x0B; - - public static final int LT_RU = 0x0C; - public static final int LE_RU = 0x0D; - public static final int GT_RU = 0x0E; - public static final int GE_RU = 0x0F; - - public static final int EQ = 0x10; - public static final int NE = 0x11; - - public static String toString(int opcode) { - switch (opcode) { - case LT_IS: return "GE_IS"; - case LE_IS: return "GT_IS"; - case GT_IS: return "LE_IS"; - case GE_IS: return "LT_IS"; - case LT_IU: return "GE_IU"; - case LE_IU: return "GT_IU"; - case GT_IU: return "LE_IU"; - case GE_IU: return "LT_IU"; - case LT_RO: return "GE_RU"; - case LE_RO: return "GT_RU"; - case GT_RO: return "LE_RU"; - case GE_RO: return "LT_RU"; - case LT_RU: return "GE_RO"; - case LE_RU: return "GT_RO"; - case GT_RU: return "LE_RO"; - case GE_RU: return "LT_RO"; - case EQ : return "NE"; - case NE : return "EQ"; - default : throw Debug.abort("" + opcode); - } - } - - public String toString() { - switch (this) { - - case False: - return "False"; - case True: - return "True"; - case Bool(boolean value): - return "Test(" + value + ")"; - case Or(Test test): - return "Or(" + test + ")"; - case And(Test test): - return "And(" + test + ")"; - case Binary(int opcode, MSILType type): - return "Binary(" + toString(opcode) +"," + type + ")"; - - default: - throw Debug.abort(getClass().getName()); - } - } -} // class Test diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java deleted file mode 100644 index de0bd4a264..0000000000 --- a/sources/scalac/backend/msil/TypeCreator.java +++ /dev/null @@ -1,1449 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.backend.msil; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.ApplicationError; -import scalac.ast.Tree; -import scalac.ast.Traverser; -import scalac.atree.AConstant; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.SourceRepresentation; -import scalac.symtab.Kinds; -import scalac.symtab.TypeTags; -import scalac.symtab.Symbol; -import scalac.symtab.Scope; -import scalac.symtab.Modifiers; -import scalac.symtab.Definitions; -import scalac.symtab.AttributeInfo; -import scalac.symtab.classfile.CLRTypes; -import scala.tools.util.Position; -import scala.tools.util.SourceFile; - -import Tree.*; - -import ch.epfl.lamp.compiler.msil.*; -import ch.epfl.lamp.compiler.msil.emit.*; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; -import java.util.Map; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Set; -import java.util.HashSet; -import java.util.LinkedHashSet; - -/** - * Creates System.Reflection objects corresponding to - * Scala symbols - * - * @author Nikolay Mihaylov - * @version 1.1 - */ - -final class TypeCreator { - - //private final GenMSIL gen; - private final Global global; - private final Definitions defs; - - private final ArrayList typeBuilders = new ArrayList(); - - // for every method of an object give the corresponding static method - // of the accompanying class - private final Map/*<Symbol, MethodBuilder>*/ syms2staticMethods = new HashMap(); - - private final Map types2symbols = new HashMap(); - private final Map symbols2types = new HashMap(); - private final Map symbols2fields = new HashMap(); - private final Map symbols2methods = new HashMap(); - private final Map symbols2moduleFields = new HashMap(); - private final Set specialAttrs = new HashSet(); - - public static final String MODULE_S = "$MODULE"; - - public final Type BYTE; - public final Type CHAR; - public final Type SHORT; - public final Type INT; - public final Type LONG; - public final Type FLOAT; - public final Type DOUBLE; - public final Type BOOLEAN; - public final Type VOID; - public final Type ENUM; - - public final Type OBJECT; - public final Type STRING; - public final Type STRING_ARRAY; - public final Type ICLONEABLE; - - private final Type MONITOR; - - public final MethodInfo CONCAT_OBJECT_OBJECT; - public final MethodInfo OBJECT_EQUALS; - public final MethodInfo MONITOR_ENTER; - public final MethodInfo MONITOR_EXIT; - public final MethodInfo MEMBERWISE_CLONE; -// private final MethodInfo MONITOR_PULSE; -// private final MethodInfo MONITOR_PULSE_ALL; -// private final MethodInfo MONITOR_WAIT; -// private final MethodInfo MONITOR_WAIT_TIMEOUT; - - public final Type SCALA_BYTE; - public final Type SCALA_SHORT; - public final Type SCALA_INT; - public final Type SCALA_LONG; - public final Type SCALA_FLOAT; - public final Type SCALA_DOUBLE; - public final Type SCALA_CHAR; - public final Type SCALA_BOOLEAN; - public final Type SCALA_UNIT; - - public final MethodInfo RUNTIME_BOX_UNIT ; - - public Symbol SYM_SUBSTRING_INT_INT; - public MethodInfo SUBSTRING_INT_INT; - public Symbol SYM_COMPARE_TO_IGNORE_CASE; - public MethodInfo COMPARE_TO_IGNORE_CASE; - - public ConstructorInfo SYMTAB_CONSTR; - public ConstructorInfo SYMTAB_DEFAULT_CONSTR; - - private scalac.symtab.Type MAIN_METHOD_TYPE; - - private final Symbol SYSTEM_SERIALIZABLE_CONSTR; - private final Symbol SYSTEM_NONSERIALIZED_CONSTR; - - private final CLRTypes ti; - - private final Phase backPhase; - - //########################################################################## - - TypeCreator(Global global) { - this.global = global; - this.defs = global.definitions; - this.backPhase = global.PHASE.ADDINTERFACES.phase(); - - ti = CLRTypes.instance(); - - BYTE = ti.BYTE; - CHAR = ti.CHAR; - SHORT = ti.SHORT; - INT = ti.INT; - LONG = ti.LONG; - FLOAT = ti.FLOAT; - DOUBLE = ti.DOUBLE; - BOOLEAN = ti.BOOLEAN; - VOID = ti.VOID; - ENUM = ti.ENUM; - - OBJECT = ti.OBJECT; - STRING = ti.STRING; - STRING_ARRAY = Type.GetType("System.String[]"); - ICLONEABLE = Type.GetType("System.ICloneable"); - MONITOR = Type.GetType("System.Threading.Monitor"); - - final Type[] sObject1 = new Type[] {OBJECT}; - - //CONCAT_OBJECT = STRING.GetMethod("Concat", new Type[] {OBJECT}); - //CONCAT_STRING_STRING = STRING.GetMethod("Concat", new Type[] {STRING, STRING}); - CONCAT_OBJECT_OBJECT = - STRING.GetMethod("Concat", new Type[] {OBJECT, OBJECT}); - OBJECT_EQUALS = OBJECT.GetMethod("Equals", sObject1); -// MONITOR_PULSE = MONITOR.GetMethod("Pulse", sObject1); -// MONITOR_PULSE_ALL = MONITOR.GetMethod("PulseAll", sObject1); -// MONITOR_WAIT = MONITOR.GetMethod("Wait", sObject1); -// MONITOR_WAIT_TIMEOUT = MONITOR.GetMethod("Wait", new Type[] {OBJECT, INT}); - MONITOR_ENTER = MONITOR.GetMethod("Enter", sObject1); - MONITOR_EXIT = MONITOR.GetMethod("Exit", sObject1); - MEMBERWISE_CLONE = ti.MEMBERWISE_CLONE; - - SCALA_BYTE = getType("scala.Byte"); - SCALA_SHORT = getType("scala.Short"); - SCALA_INT = getType("scala.Int"); - SCALA_LONG = getType("scala.Long"); - SCALA_FLOAT = getType("scala.Float"); - SCALA_DOUBLE = getType("scala.Double"); - SCALA_CHAR = getType("scala.Char"); - SCALA_BOOLEAN = getType("scala.Boolean"); - SCALA_UNIT = getType("scala.Unit"); - - RUNTIME_BOX_UNIT = getType("scala.runtime.RunTime") - .GetMethod("box_uvalue", Type.EmptyTypes); - ti.map(defs.OBJECT_CLONE, MEMBERWISE_CLONE); - - SYSTEM_SERIALIZABLE_CONSTR = defs.getClass("System.SerializableAttribute") - .primaryConstructor(); - SYSTEM_NONSERIALIZED_CONSTR = defs.getClass("System.NonSerializedAttribute") - .primaryConstructor(); - - } - - private boolean initialized = false; - - /* - * Called from GenMSILPhase - */ - public void init() { - if (initialized) - return; - final Symbol JOBJECT = defs.OBJECT_CLASS; //defs.getClass("java.lang.Object"); - final Symbol JSTRING = defs.STRING_CLASS; - - // initialize type mappings - map(defs.ANY_CLASS, OBJECT); - map(defs.ANYREF_CLASS, OBJECT); - map(JOBJECT, OBJECT); - map(JSTRING, STRING); - - // constants useful for method mappings - final scalac.symtab.Type UNBOXED_LONG = - new scalac.symtab.Type.UnboxedType(TypeTags.LONG); - final scalac.symtab.Type UNBOXED_INT = - new scalac.symtab.Type.UnboxedType(TypeTags.INT); - final scalac.symtab.Type UNBOXED_CHAR = - new scalac.symtab.Type.UnboxedType(TypeTags.CHAR); - - final scalac.symtab.Type[] jEmpty = scalac.symtab.Type.EMPTY_ARRAY; - final scalac.symtab.Type[] jString1 = new scalac.symtab.Type[] - {defs.STRING_TYPE()}; - final scalac.symtab.Type[] jInt1 = new scalac.symtab.Type[] - {UNBOXED_INT}; - final scalac.symtab.Type[] jInt2 = new scalac.symtab.Type[] - {UNBOXED_INT, UNBOXED_INT}; - final scalac.symtab.Type[] jStringInt = new scalac.symtab.Type[] - {defs.STRING_TYPE(), UNBOXED_INT}; - final scalac.symtab.Type[] jChar2 = new scalac.symtab.Type[] - {UNBOXED_CHAR, UNBOXED_CHAR}; - - final Type[] sObject1 = new Type[] {OBJECT}; - final Type[] sString1 = new Type[] {STRING}; - final Type[] sString2 = new Type[] {STRING, STRING}; - final Type[] sChar1 = new Type[] {CHAR}; - final Type[] sCharInt2 = new Type[] {CHAR, INT}; - - final Type ObjectImpl = Type.GetType("com.ms.vjsharp.lang.ObjectImpl"); - - // map methods of java.lang.Object - translateMethod(JOBJECT, "equals", OBJECT, "Equals"); - translateMethod(JOBJECT, "hashCode", OBJECT, "GetHashCode"); - translateMethod(JOBJECT, "toString", OBJECT, "ToString"); - translateMethod(JOBJECT, "finalize", OBJECT, "Finalize"); - translateMethod(JOBJECT, "wait", jEmpty, MONITOR, "Wait", sObject1); - translateMethod(JOBJECT, "wait", new scalac.symtab. - Type[] {UNBOXED_LONG}, // defs.LONG_TYPE - MONITOR, "Wait", - new Type[] {OBJECT, INT}); - translateMethod(JOBJECT, "notify", jEmpty, MONITOR, "Pulse", sObject1); - translateMethod(JOBJECT, "notifyAll", jEmpty, MONITOR, "PulseAll", sObject1); - //translateMethod(JOBJECT, "getClass", jEmpty, ObjectImpl, "getClass", sObject1); - - // map methods of java.lang.String - //translateMethod(JSTRING, "equals", STRING, "Equals"); - //translateMethod(JSTRING, "toString", STRING, "ToString"); - translateMethod(JSTRING, "compareTo", STRING, "CompareTo"); - translateMethod(JSTRING, "length", STRING, "get_Length"); - translateMethod(JSTRING, "charAt", STRING, "get_Chars"); - translateMethod(JSTRING, "concat", jString1, STRING, "Concat", sString2); - translateMethod(JSTRING, "indexOf", jInt1, STRING, "IndexOf", sChar1); - translateMethod(JSTRING, "indexOf", jInt2, STRING, "IndexOf", sCharInt2); - translateMethod(JSTRING, "indexOf", jString1, STRING, "IndexOf"); - translateMethod(JSTRING, "indexOf", jStringInt, STRING, "IndexOf"); - translateMethod(JSTRING, "lastIndexOf", jInt1, STRING, "LastIndexOf", sChar1); - translateMethod(JSTRING, "lastIndexOf", jInt2, STRING, "LastIndexOf", sCharInt2); - translateMethod(JSTRING, "lastIndexOf", jString1, STRING, "LastIndexOf"); - translateMethod(JSTRING, "lastIndexOf", jStringInt, STRING, "LastIndexOf"); - translateMethod(JSTRING, "toLowerCase", jEmpty, STRING, "ToLower"); - translateMethod(JSTRING, "toUpperCase", jEmpty, STRING, "ToUpper"); - translateMethod(JSTRING, "startsWith", jString1, STRING, "StartsWith"); - translateMethod(JSTRING, "endsWith", jString1, STRING, "EndsWith"); - translateMethod(JSTRING, "substring", jInt1, STRING, "Substring"); - translateMethod(JSTRING, "intern", jEmpty, STRING, "Intern", sString1); - translateMethod(JSTRING, "replace", jChar2, STRING, "Replace"); - translateMethod(JSTRING, "toCharArray", STRING, "ToCharArray"); - -// translateMethod(defs.getModule("java.lang.Byte").moduleClass() -// , "parseByte", jString1, BYTE, "Parse"); -// translateMethod(defs.getModule("java.lang.Short").moduleClass() -// , "parseShort", jString1, SHORT, "Parse"); -// translateMethod(defs.getModule("java.lang.Integer").moduleClass() -// , "parseInt", jString1, INT, "Parse"); -// translateMethod(defs.getModule("java.lang.Long").moduleClass() -// , "parseLong", jString1, LONG, "Parse"); -// translateMethod(defs.getModule("java.lang.Float").moduleClass() -// , "parseFloat", jString1, FLOAT, "Parse"); -// translateMethod(defs.getModule("java.lang.Double").moduleClass() -// , "parseDouble", jString1, DOUBLE, "Parse"); - - SYM_SUBSTRING_INT_INT = lookupMethod(JSTRING, "substring", jInt2); - SUBSTRING_INT_INT = - STRING.GetMethod("Substring", new Type[]{INT,INT}); - SYM_COMPARE_TO_IGNORE_CASE = - lookupMethod(JSTRING, "compareToIgnoreCase", jString1); - COMPARE_TO_IGNORE_CASE = - STRING.GetMethod("Compare", new Type[]{STRING, STRING, BOOLEAN}); - initialized = true; - - SYMTAB_CONSTR = ti.SYMTAB_CONSTR; - SYMTAB_DEFAULT_CONSTR = ti.SYMTAB_DEFAULT_CONSTR; - - scalac.symtab.Type argument = defs.array_TYPE(defs.STRING_TYPE()); - scalac.symtab.Type result = defs.void_TYPE(); - Symbol formal = Symbol.NONE.newTerm // !!! should be newVParam - (Position.NOPOS, Modifiers.PARAM, Name.fromString("args")); - formal.setInfo(argument); - MAIN_METHOD_TYPE = - scalac.symtab.Type.MethodType(new Symbol[] {formal}, result); - - specialAttrs.add(defs.SCALA_SERIALIZABLE_CONSTR); - specialAttrs.add(defs.SCALA_TRANSIENT_CONSTR); - specialAttrs.add(SYSTEM_SERIALIZABLE_CONSTR); - specialAttrs.add(SYSTEM_NONSERIALIZED_CONSTR); - specialAttrs.add(defs.SCALA_CLONEABLE_CONSTR); - specialAttrs.add(defs.SCALA_VOLATILE_CONSTR); - specialAttrs.add(defs.getClass("scala.SerialVersionUID") - .primaryConstructor()); - specialAttrs.add(defs.getClass("scala._trait_") - .primaryConstructor()); - } // init() - - /* - * Looks up the method with the corresponding signature - */ - private Symbol lookupMethod(Symbol clazz, String name, - scalac.symtab.Type[] paramTypes) - { - Symbol[] methods = clazz.members(). - lookup(Name.fromString(name)).alternativeSymbols(); - search: - for (int i = 0; i < methods.length; i++) { - switch (methods[i].info()) { - case MethodType(Symbol[] vparams, _): - if (paramTypes.length != vparams.length) - continue; - for (int j = 0; j < vparams.length; j++) { - if (!paramTypes[j].isSameAs(vparams[j].info())) - continue search; - } - return methods[i]; - default: - continue; - } - } - return null; - } // Symbol lookupMethod(...) - - /* - * Format the signature of a method for better diagnostic printing. - */ - private static String methodSignature(Symbol sym) { - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - StringBuffer s = new StringBuffer(); - s.append(result); s.append(' '); - s.append(Debug.show(sym.owner())); s.append('.'); - s.append(sym.name.toString());s.append('('); - for (int i = 0; i < vparams.length; i++) { - if (i > 0) s.append(", "); - //s.append(Debug.show(vparams[i].info())); - s.append(vparams[i].info()); - } - s.append(")"); - return s.toString(); - default: - return "Symbol doesn't have a method type: " + Debug.show(sym); - } - } - - private static String methodSignature(Type[] params) { - StringBuffer s = new StringBuffer(); - s.append('('); - for (int i = 0; i < params.length; i++) { - if (i > 0) - s.append(", "); - s.append(params[i]); - } - s.append(')'); - return s.toString(); - } - - /** - * Create a mapping from method with symbol 'sym' - * to the method newClazz.newName(params) - */ - private void mapMethod(Symbol sym, Type newClazz, String name, Type[] params) { - MethodInfo method = newClazz.GetMethod(name, params); - assert method != null : "Cannot find translation for: " - + methodSignature(sym) + "->" + newClazz - + "::" + name + methodSignature(params); - symbols2methods.put(sym, method); - } - - /** - * Create mapping between the specified two methods only - */ - private void translateMethod(Symbol clazz, String name, - scalac.symtab.Type[] paramTypes, - Type newClazz, String newName, Type[] newParamTypes) - { - Symbol sym = lookupMethod(clazz, name, paramTypes); - assert sym != null : "Cannot find method: " + name + " in class " + - Debug.show(clazz) + "; scope = " + Debug.show(clazz.members()); - mapMethod(sym, newClazz, newName, newParamTypes); - } - - /** - * Lookup the method and create mapping for all overloaded alternatives - * to the corresponding methods in 'newClazz' - */ - private void translateMethod(Symbol clazz, String name, - Type newClazz, String newName) - { - Symbol sym = clazz.lookup(Name.fromString(name)); - assert sym != null : "Cannot find method: " + name; - translateMethod(sym, newClazz, newName); - } - - /** - * - */ - private void translateMethod(Symbol clazz, String name, - scalac.symtab.Type[] paramTypes, - Type newClazz, String newName) - { - Type[] newParamTypes = new Type[paramTypes.length]; - for (int i = 0; i < paramTypes.length; i++) - newParamTypes[i] = getType(paramTypes[i]); - translateMethod(clazz, name, paramTypes, - newClazz, newName, newParamTypes); - } - - /* - * Create a mapping for the two methods. - */ - private void translateMethod(Symbol sym, Type newClazz, String newName) { - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - mapMethod(sym, newClazz, newName, params); - break; - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - translateMethod(alts[i], newClazz, newName); - return; - default: - throw Debug.abort(Debug.show(sym, sym.info())); - } - } - - //########################################################################## - // tree treversal - - private static final Name MAIN_N = Name.fromString("main"); - - private final Set types2create = new LinkedHashSet(); - - private String assemName; - - private File outDir; - - private Symbol entryPoint; - - private boolean moreThanOneEntryPoint; - public boolean moreThanOneEntryPoint() { - return moreThanOneEntryPoint; - } - - private CompilationUnit entryPointUnit; - - private int entryPointPos; - - /** - collects the symbols of all classes defined in the program - * - collects all entry points - * - gives the name of the new assembly - */ - public void collectSymbols(CompilationUnit[] units) { - types2create.clear(); - entryPoint = null; - new CollectSymbols().traverse(units); - - // the assembly name supplied with the -o option (or null) - assemName = global.args.assemname.value; - - if (assemName == null) { - // assembly name not supplied with the -o option - if (entryPoint != null) { - // assume the name of the object defining the first entry point - assemName = entryPoint.owner().name.toString(); - } else { - // assume the name of the first source file - assemName = entryPointUnit.source.getFile().getName(); - assert assemName.endsWith(".scala") : assemName; - assemName = assemName.substring(0, assemName.length() - 6); - } - } else { - File f = new File(assemName); - outDir = f.getParentFile(); - assemName = f.getName(); - } - if (outDir == null) - outDir = new File("."); - } - - /** Determines if the given symbol is an entry point: - * - the name is "main" - * - belongs to a top-level class - * - the type is Array[String] => Unit - */ - public boolean isEntryPoint(Symbol main) { - return main.name == MAIN_N - && main.owner().isModuleClass() - && main.owner().owner().isPackageClass() - && MAIN_METHOD_TYPE.isSameAs(main.info()); - } - - /** A traverser that collects the symbols of all classes defined - * in the program and all entry points. - */ - private final class CollectSymbols extends Traverser { - private CompilationUnit currUnit; - public void traverse(CompilationUnit unit) { - currUnit = unit; - if (entryPointUnit == null) - entryPointUnit = unit; - super.traverse(unit); - } - public void traverse(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): - types2create.add(tree.symbol()); - traverse(impl); - return; - case DefDef(_, _, _, _, _, _): - Symbol sym = tree.symbol(); - if (isEntryPoint(sym)) { - if (entryPoint == null) { - entryPoint = sym; - entryPointUnit = currUnit; - entryPointPos = tree.pos; - } else - moreThanOneEntryPoint = true; - } - return; - case ValDef(_, _, _, _): - return; - default: - super.traverse(tree); - } - } - } - - //########################################################################## - - // the Assembly the program is compiled into. - private AssemblyBuilder msilAssembly; - - // the main module of the assembly - private ModuleBuilder msilModule; - - /** Create the output assembly - */ - void initAssembly() { - AssemblyName an = new AssemblyName(); - an.Name = assemName; - String moduleName = assemName + (entryPoint == null ? ".dll" : ".exe"); - msilAssembly = AssemblyBuilder.DefineDynamicAssembly(an); - msilModule = msilAssembly.DefineDynamicModule - (moduleName, new File(outDir, moduleName).getAbsolutePath()); - - for (Iterator classes = types2create.iterator(); classes.hasNext();) { - Symbol clazz = (Symbol)classes.next(); - createType(clazz); - } - } - - /** Finilize the code generation. Called from GenMSILPhase - * after processing all compilation units. - */ - public void saveAssembly() { - if (entryPoint != null) { - MethodInfo mainMethod = (MethodInfo)getMethod(entryPoint); - assert mainMethod != null : Debug.show(entryPoint); - FieldInfo moduleField = getModuleField(entryPoint.owner()); - assert moduleField != null : Debug.show(entryPoint.owner()); - MethodBuilder main = msilModule.DefineGlobalMethod - ("Main", MethodAttributes.Public | MethodAttributes.Static, - VOID, new Type[] {STRING_ARRAY} ); - main.DefineParameter(0, 0, "args"); - msilAssembly.SetEntryPoint(main); - ILGenerator code = main.GetILGenerator(); - if (global.args.debuginfo.value) { - String fname = SourceRepresentation - .escape(entryPointUnit.source.getFile().getPath()); - code.setPosition(Position.line(entryPointPos), fname); - } - - code.Emit(OpCodes.Ldsfld, moduleField); - code.Emit(OpCodes.Ldarg_0); - code.Emit(OpCodes.Callvirt, mainMethod); - code.Emit(OpCodes.Ret); - } - createTypes(); - File fassem = new File(outDir, assemName + ".il"); - String assemblyFilename = fassem.getPath(); - try { - msilAssembly.Save(assemblyFilename); - if (moreThanOneEntryPoint()) - global.warning("Setting " + Debug.show(entryPoint) + - " as an entry point"); - } catch (IOException e) { - global.error("Could not save " + assemblyFilename); - } - } - - /** - * Finalizes ('bakes') the newly created types - */ - private void createTypes() { - Iterator iter = typeBuilders.iterator(); - while (iter.hasNext()) - ((TypeBuilder)iter.next()).CreateType(); - } - - //########################################################################## - /** - * Creates bidirectional mapping from symbols to types. - */ - private Type map(Symbol sym, Type type) { - symbols2types.put(sym, type); - if (sym.isClass()) - types2symbols.put(type, sym); - return type; - } - - /** - * Return the System.Type object with the given name. - */ - private Type getType(String name) { - return ti.getType(name); - } - - /** - * Return the System.Type object corresponding to the type of the symbol - */ - public Type getType(Symbol sym) { - if (sym == null) return null; // FIXME: assert sym != null ? - if (sym == defs.ANY_CLASS || sym == defs.ANYREF_CLASS || sym == defs.OBJECT_CLASS) - return OBJECT; - if (sym == defs.STRING_CLASS) - return STRING; - - Type type = (Type) symbols2types.get(sym); - if (type != null) { - if (sym.isExternal()) { - assert !(type instanceof TypeBuilder) - : Debug.show(sym) + " -> " + type.toString(); - return type; - } else if (types2create.contains(sym) && type instanceof TypeBuilder) - return type; - } else if (types2create.contains(sym)) - type = createType(sym); - if (type != null) - return type; - - type = (Type)ti.getMember(sym); - if (type != null) - return map(sym, type); - - if (sym.isClass()) { - final Symbol owner = sym.owner(); - if (owner.isClass()) { - Type ownerType = getType(owner); - assert ownerType != null : Debug.show(owner); - type = ownerType.GetNestedType(sym.name.toString()); - } else { - String name = global.primitives.getCLRClassName(sym); - type = getType(sym.isModuleClass() && !sym.isJava() - ? name + "$" : name); - } - } else { - type = getType(sym.info()); - } - if (type != null) - return map(sym, type); - - throw Debug.abort("Type resolution failed for " + Debug.show(sym)); - } - - /** Retrieve the System.Type from the scala type. - */ - public Type getType(scalac.symtab.Type type) { - switch (type) { - case ThisType(Symbol s): - return getType(s); - case TypeRef(_, Symbol s, _): - return getType(s); - case CompoundType(_, _): - return getType(type.symbol()); - case UnboxedType(int kind): - return getTypeFromKind(kind); - case UnboxedArrayType(scalac.symtab.Type elemtp): - return ti.mkArrayType(getType(elemtp)); - case NoType: - return VOID; - default: - throw Debug.abort(Debug.show(type)); - } - } - - /** Retrieves the primitive datatypes given their kind - */ - private Type getTypeFromKind(int kind) { - switch (kind) { - case TypeTags.CHAR: return CHAR; - case TypeTags.BYTE: return BYTE; - case TypeTags.SHORT: return SHORT; - case TypeTags.INT: return INT; - case TypeTags.LONG: return LONG; - case TypeTags.FLOAT: return FLOAT; - case TypeTags.DOUBLE: return DOUBLE; - case TypeTags.BOOLEAN: return BOOLEAN; - case TypeTags.UNIT: return VOID; - case TypeTags.STRING: return STRING; - default: - throw new ApplicationError("Unknown kind: " + kind); - } - } - - public Symbol getSymbol(Type type) { - return (Symbol) types2symbols.get(type); - } - - public Type createType(Symbol clazz) { - try { return createType0(clazz); } - catch (Error e) { - throw Debug.abort(Debug.show(clazz), e); - } - } - - /** - * Creates the TypeBuilder for a class. - */ - public Type createType0(Symbol clazz) { - assert types2create.contains(clazz) : Debug.show(clazz); - Type type = (Type)symbols2types.get(clazz); - if (type != null && type instanceof TypeBuilder) - return type; - - TypeBuilder staticType = null; - final Symbol owner = clazz.owner(); - final String staticTypeName = owner.isClass() - ? clazz.nameString() - : global.primitives.getCLRClassName(clazz); - final String typeName = - staticTypeName + (clazz.isModuleClass() ? "$" : ""); - final scalac.symtab.Type classType = clazz.info(); - switch (classType) { - case CompoundType(scalac.symtab.Type[] baseTypes, _): - Type superType = null; - Type[] interfaces = null; - int inum = baseTypes.length; - if (clazz.isInterface()) { - int baseIndex = 0; - if (baseTypes[0].symbol() == defs.ANY_CLASS) { - --inum; - baseIndex = 1; - } - interfaces = new Type[inum]; - for (int i = 0; i < inum; i++) { - assert baseTypes[i + baseIndex].symbol().isInterface(); - interfaces[i] = getType(baseTypes[i + baseIndex].symbol()); - } - } else { - boolean cloneable = isCloneable(clazz); - superType = getType(baseTypes[0].symbol()); - assert inum > 0; - interfaces = new Type[inum - 1 + (cloneable ? 1 : 0)]; - for (int i = 1; i < inum; i++) - interfaces[i - 1] = getType(baseTypes[i].symbol()); - if (cloneable) - interfaces[inum - 1] = ICLONEABLE; - } - - type = (TypeBuilder) symbols2types.get(clazz); - if (type != null) - return type; - - if (owner.isPackageClass()) { // i.e. top level class - type = msilModule.DefineType - (typeName, translateTypeAttributes(clazz, false), - superType, interfaces); - if (clazz.isModuleClass()) { - Symbol module = owner.members().lookup(clazz.name.toTermName()); - Symbol linkedClass = module.linkedClass(); - - if (linkedClass == null || linkedClass.info().isError()) { - staticType = msilModule.DefineType - (staticTypeName, - translateTypeAttributes(clazz, false), - OBJECT, Type.EmptyTypes); - } - } - } else { - final Type outerType = (Type) getType(owner); - // check if the type have not been created by - // the (possible) creation of the outer type - type = (TypeBuilder) symbols2types.get(clazz); - if (type != null) - return type; - - assert outerType instanceof TypeBuilder : Debug.show(clazz); - type = ((TypeBuilder)outerType).DefineNestedType - (typeName, translateTypeAttributes(clazz, true), - superType, interfaces); - } - break; - - default: - throw Debug.abort("Symbol does not have a CompoundType", clazz); - } - typeBuilders.add(type); - map(clazz, type); - if (clazz.isModuleClass() && staticType != null) { - syms2staticTypes.put(clazz, staticType); - } - for (Scope.SymbolIterator syms = clazz.members().iterator(); - syms.hasNext(); ) - { - Symbol member = syms.next(); - if (member.isMethod()) { - MethodBase m = createMethod(member); - if (staticType != null && m.IsPublic() && !m.IsConstructor()) { - MethodBase sm = createMethod(staticType, member, true); - syms2staticMethods.put(member, sm); - } - } - else if (!member.isClass() && !member.isModule() - && !member.isType()) - createField(member); - } - - // adapted from Erasure; creates abstract method declarations - // for the interface methods for which the class doesn't provide - // implementation (requirement of the CLR) - if (clazz.isClass() && !clazz.isInterface()) { - Set ifaces = new HashSet(getInterfacesOf(clazz)); - Symbol svper = clazz.parents()[0].symbol(); - ifaces.removeAll(getInterfacesOf(svper)); - for (Iterator i = ifaces.iterator(); i.hasNext(); ) { - Symbol iface = (Symbol)i.next(); - for (Scope.SymbolIterator members = - iface.members().iterator(); - members.hasNext(); ) - { - Symbol method = members.next(); - if (!method.isTerm() || !method.isDeferred()) continue; - Symbol overriding = - method.overridingSymbol(clazz.info(), true); - if (overriding != method) continue; - Symbol overridden = method - .overriddenSymbol(clazz.parents()[0], clazz, true); - if (overridden.isNone()) { - Symbol newMethod = method.cloneSymbol(clazz); - newMethod.flags = (newMethod.flags & ~Modifiers.JAVA) - | Modifiers.SYNTHETIC | Modifiers.DEFERRED; - createMethod(newMethod); - } - } - } - } - setAttributes((TypeBuilder)type, global.getAttributes(clazz)); - return type; - } // createType() - - private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap(); - - /** Adapted from Erasure. Returns a set of the interfaces - * implemented by the class. - */ - private Set getInterfacesOf(Symbol clasz) { - assert clasz.isClass(): Debug.show(clasz); - Set set = (Set)interfaces.get(clasz); - if (set == null) { - set = new HashSet(); - interfaces.put(clasz, set); - scalac.symtab.Type parents[] = clasz.parents(); - for (int i = 0; i < parents.length; i++) - set.addAll(getInterfacesOf(parents[i].symbol())); - if (clasz.isInterface()) set.add(clasz); - } - return set; - } - - public boolean isCloneable(Symbol clazz) { - return global.getAttrArguments(clazz, defs.SCALA_CLONEABLE_CONSTR) - != null; - } - - //########################################################################## - // find/create methods - - public MethodBase getMethod(Symbol sym) { - MethodBase method = null; - try { - method = getMethod0(sym); - } catch (Throwable e) { - printMapping(sym, symbols2methods); - throw Debug.abort(Debug.show(sym), e); - } - return method; - } - - private static String dumpSymbol(Symbol sym) { - return Debug.show(sym) + " : " + Integer.toHexString(sym.flags); - } - private void printMapping(Symbol sym, Map map) { - System.out.println("For symbol " + dumpSymbol(sym)); - for (Iterator entries = map.entrySet().iterator(); - entries.hasNext(); ) - { - Map.Entry entry = (Map.Entry)entries.next(); - Symbol sentry = (Symbol)entry.getKey(); - if (sentry.owner() == sym.owner() - && sentry.name == sym.name) - { - System.out.println("Existing mapping " - + dumpSymbol(sentry) + " => " - + entry.getValue()); - } - } - System.out.println("Scope of owner: " + sym.owner().members()); - } - - /** - * Returns the MethodBase object corresponding to the symbol. - */ - public MethodBase getMethod0(Symbol sym) { - MethodBase method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return method; - MemberInfo m = ti.getMember(sym); - if (m != null && m instanceof MethodBase) { - method = (MethodBase) m; - } else { - // force the creation of the declaring type - Type owner = getType(sym.owner()); - assert owner != null : Debug.show(sym); - method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return method; - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - Type resType = getType(result); - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - if (sym.isInitializer()) { - // The owner of a constructor is the outer class - // so get the result type of the constructor - method = owner.GetConstructor(params); - assert method != null : "cannot find " + owner - + "::.ctor" + methodSignature(params); - } else { - method = owner instanceof TypeBuilder - ? findMethod(sym.owner(), sym) - : owner.GetMethod - (getMethodName(sym.name, params), params, resType); - } - break; - default: - throw Debug.abort("Symbol doesn't have a method type", sym); - } - assert method != null - : Debug.show(owner) + " => Cannot find method: " + methodSignature(sym); - } - symbols2methods.put(sym, method); - - return method; - } - - /** - * Returns all MethodBase objects corresponding to the symbol. - */ - private MethodBase[] getMethods(Symbol sym) { - MethodBase method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return new MethodBase[]{method}; - MemberInfo m = ti.getMember(sym); - if (m != null && m instanceof MethodBase) { - method = (MethodBase) m; - } else { - // force the creation of the declaring type - Type owner = getType(sym.owner()); - assert owner != null : Debug.show(sym); - method = (MethodBase) symbols2methods.get(sym); - if (method != null) - return new MethodBase[]{method}; - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - Type resType = getType(result); - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - if (sym.isInitializer()) { - // The owner of a constructor is the outer class - // so get the result type of the constructor - method = owner.GetConstructor(params); - assert method != null : "cannot find " + owner - + "::.ctor" + methodSignature(params); - } else { - method = owner instanceof TypeBuilder - ? findMethod(sym.owner(), sym) - : owner.GetMethod - (getMethodName(sym.name, params), params, resType); - } - break; - case OverloadedType(Symbol[] alts, scalac.symtab.Type[] alttypes): - MethodBase[] methods = new MethodBase[alts.length]; - for (int i = 0; i < alts.length; i++) - methods[i] = getMethod(alts[i]); - return methods; - - default: - throw Debug.abort("Symbol doesn't have a method type", sym); - } - assert method != null - : Debug.show(owner) + " => Cannot find method: " + methodSignature(sym); - } - symbols2methods.put(sym, method); - return new MethodBase[]{method}; - } - - /** - * Returns the exactest apply method. - * The exactest method is taken to be the first method that doesn't have - * an 'object' return type and all 'object' parameter types. - */ - public MethodBase getDelegateApplyMethod(Symbol sym) { - MethodBase methods[] = getMethods(sym); - if(methods.length > 1) { - assert methods.length == 2; - for (int i = 0; i < methods.length; i++) { - if(((MethodInfo)methods[i]).ReturnType != OBJECT) - return methods[i]; - ParameterInfo pi[] = methods[i].GetParameters(); - for (int j = 0; j < pi.length; j++) { - if(pi[j].ParameterType != OBJECT) - return methods[i]; - } - } - throw Debug.abort("Expected apply method not found", sym); - } else { - return methods[0]; - } - } - - private String getMethodName(Name name, Type[] params) { - if (name == Names.finalize && params.length == 0) - return "Finalize"; - if (name == Names.toString && params.length == 0) - return "ToString"; - if (name == Names.hashCode && params.length == 0) - return "GetHashCode"; - if (name == Names.equals && params.length == 1 && params[0] == OBJECT) - return "Equals"; - if (name == Names.clone && params.length == 0) - return "Clone"; - return name.toString(); - } - - private MethodBase findMethod(Symbol owner, Symbol member) { - Symbol[] ms = owner.lookup(member.name).alternativeSymbols(); - for (int i = 0; i < ms.length; i++) - if (member.info().isSameAs(ms[i].info())) { - MethodBase m = getMethod(ms[i]); - if (m != null) - return m; - } - throw Debug.abort("Couldn't find mapping for " + Debug.show(member)); - } - - private MethodBase createMethod(Symbol sym) { - MethodBase method = - createMethod((TypeBuilder)getType(sym.owner()), sym, false); - symbols2methods.put(sym, method); - setAttributes((ICustomAttributeSetter)method, global.getAttributes(sym)); - return method; - } - - - /** - * Create the method corresponding to the symbol. - - * @param isStatic - forces the created method to be static - */ - private MethodBase createMethod(TypeBuilder type, Symbol sym, boolean isStatic) - { - MethodBase method = null; - switch (sym.info()) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - short attr = translateMethodAttributes(sym); - if (isStatic) - attr = (short)((attr & ~MethodAttributes.Virtual - & ~MethodAttributes.Final) - | MethodAttributes.Static); - Phase bkpCurrent = global.currentPhase; - global.currentPhase = backPhase; - Name name = sym.name; String sname = name.toString(); - switch (sym.info()) { - case PolyType(Symbol[] tparams, _): - if (tparams.length == 0) { - name = Name.fromString("get_" + name); - } - break; - default: - if (sname.endsWith("_$eq")) { - name = Name.fromString("set_" + sname - .substring(0, sname.length() - 4)); - } - } - global.currentPhase = bkpCurrent; - - return createMethod(type, name, sym.info(), attr); - default: - throw Debug.abort("Symbol doesn't have a method type: " - + Debug.show(sym)); - } - } - - - /** - * Helper method to createMethod(Symbol) - */ - private MethodBase createMethod(TypeBuilder type, Name name, - scalac.symtab.Type symType, short attr) - { - MethodBase method = null; - switch (symType) { - case MethodType(Symbol[] vparams, scalac.symtab.Type result): - Type[] params = new Type[vparams.length]; - for (int i = 0; i < params.length; i++) - params[i] = getType(vparams[i]); - - if (name == Names.CONSTRUCTOR) { - ConstructorBuilder constructor = type.DefineConstructor - (attr, CallingConventions.Standard, params); - - for (int i = 0; i < vparams.length; i++) - constructor.DefineParameter - (i, ParameterAttributes.None, vparams[i].name.toString()); - return constructor; - } else { - final String sname = getMethodName(name, params); - MethodBuilder methodBuilder = type.DefineMethod - (sname, attr, getType(result), params); - - for (int i = 0; i < vparams.length; i++) - methodBuilder.DefineParameter - (i, 0/*ParameterAttributes.In*/, vparams[i].name.toString()); - return methodBuilder; - } - default: - throw Debug.abort("Method type expected: " + Debug.show(symType)); - } - } - - //########################################################################## - // find/create fields - - /** Returns the FieldInfo object corresponing to the symbol - */ - public FieldInfo getField(Symbol sym) { - FieldInfo field = (FieldInfo) symbols2fields.get(sym); - if (field != null) return field; - MemberInfo m = ti.getMember(sym); - if (m != null && m instanceof FieldInfo) { - field = (FieldInfo)m; - } else { - Type owner = getType(sym.owner()); - field = owner.GetField(sym.name.toString()); - if (field == null) { - System.out.println("Fields of class " + owner); - int bindingFlags = BindingFlags.DeclaredOnly - | BindingFlags.Instance | BindingFlags.Static - | BindingFlags.Public | BindingFlags.NonPublic; - FieldInfo[] fields = owner.GetFields(bindingFlags); - for (int i = 0; i < fields.length; i ++) - System.out.println("\t" + fields[i]); - } - } - assert field != null : "Cannot find field: " + Debug.show(sym); - symbols2fields.put(sym, field); - return field; - } - - /* - * - */ - public FieldInfo createField(Symbol sym) { - TypeBuilder owner = (TypeBuilder) getType(sym.owner()); - FieldInfo field = (FieldInfo) symbols2fields.get(sym); - if (field != null) { - assert field instanceof FieldBuilder; - return field; - } - field = owner.DefineField(sym.name.toString(), getType(sym.type()), - translateFieldAttributes(sym)); - Object o = symbols2fields.put(sym, field); - assert o == null : "Cannot re-define field: " + Debug.show(sym); - return field; - } - - /* - * - */ - private FieldInfo getModuleField(Type type) { - Symbol sym = (Symbol) types2symbols.get(type); - assert sym != null; - return getModuleField(sym); - } - - /** - * - */ - public MethodBuilder getStaticObjectMethod(Symbol sym) { - assert sym.owner().isModuleClass() : Debug.show(sym); - MethodBuilder method = (MethodBuilder)syms2staticMethods.get(sym); - assert sym != null : Debug.show(sym); - return method; - } - - private Map syms2staticTypes = new HashMap(); - - public TypeBuilder getStaticType(Symbol moduleClass) { - getType(moduleClass); // force the creation of the Type - TypeBuilder staticType = (TypeBuilder)syms2staticTypes.get(moduleClass); -// assert staticType != null : Debug.show(moduleClass) -// + " : " + syms2staticTypes; - return staticType; - } - - /* - * - */ - private Symbol getTypeSymbol(scalac.symtab.Type type) { - switch (type) { - case TypeRef(_, Symbol s, _): - return s; - default: - throw new ApplicationError("Cannot get symbol for: " - + Debug.show(type)); - } - } - - /** - * @return the field descriptor of the object instance - */ - public FieldInfo getModuleField(Symbol sym) { - assert sym.isModule() || sym.isModuleClass() : Debug.show(sym); - FieldInfo moduleField = (FieldInfo) symbols2moduleFields.get(sym); - if (moduleField == null) { - Symbol s = getTypeSymbol(sym.type()); - if (sym != s) { - moduleField = getModuleField(s); - } else { - Type type = getType(sym); - if (type instanceof TypeBuilder) { - TypeBuilder module = (TypeBuilder) type; - moduleField = module.DefineField - (MODULE_S, - module, - (short)(FieldAttributes.Public - | FieldAttributes.InitOnly - | FieldAttributes.Static)); - } else { - moduleField = type.GetField(MODULE_S); - assert moduleField != null; - } - } - symbols2moduleFields.put(sym, moduleField); - } - assert moduleField != null : Debug.show(sym); - return moduleField; - } - - //########################################################################## - // translate Scala modifiers into attributes - - /** Translates Scala modifiers into TypeAttributes - */ - private int translateTypeAttributes(Symbol clazz, boolean nested) { - int mods = clazz.flags; - int attr = TypeAttributes.AutoLayout | TypeAttributes.AnsiClass; - - if (Modifiers.Helper.isInterface(mods)) - attr |= TypeAttributes.Interface; - else - attr |= TypeAttributes.Class; - - if (Modifiers.Helper.isAbstract(mods)) - attr |= TypeAttributes.Abstract; - if (Modifiers.Helper.isFinal(mods)) - attr |= TypeAttributes.Sealed; - - if (nested) { - if (Modifiers.Helper.isPrivate(mods)) - //attr |= TypeAttributes.NestedPrivate; - // Inner classes end up in the interface of a Scala class - // and are not accessible from the implementation class. - // Giving them assembly visibility fixes the problem. - attr |= TypeAttributes.NestedAssembly; - else if (Modifiers.Helper.isProtected(mods)) - attr |= TypeAttributes.NestedFamORAssem; - else - attr |= TypeAttributes.NestedPublic; - } else { - if (Modifiers.Helper.isPrivate(mods)) - attr |= TypeAttributes.NotPublic; - else - attr |= TypeAttributes.Public; - } - boolean serializable = - global.getAttrArguments(clazz, defs.SCALA_SERIALIZABLE_CONSTR) != null - || global.getAttrArguments(clazz, SYSTEM_SERIALIZABLE_CONSTR) != null; - if (serializable) - attr |= TypeAttributes.Serializable; - return attr; - } - - /* - * Translates Scala modifiers into FieldAttributes - */ - private short translateFieldAttributes(Symbol field) { - int mods = field.flags; - int attr = 0; - - if (Modifiers.Helper.isFinal(mods)) - attr |= FieldAttributes.InitOnly; - if (Modifiers.Helper.isPrivate(mods)) - attr |= FieldAttributes.Private; - else if (Modifiers.Helper.isProtected(mods)) - attr |= FieldAttributes.FamORAssem; - else - attr |= FieldAttributes.Public; - - if (field.owner().isJava() && field.owner().isModuleClass()) - attr |= FieldAttributes.Static; - boolean tranzient = - global.getAttrArguments(field, defs.SCALA_TRANSIENT_CONSTR) != null - || global.getAttrArguments(field, SYSTEM_NONSERIALIZED_CONSTR) != null; - if (tranzient) - attr |= FieldAttributes.NotSerialized; - - return (short)attr; - } - - /* - * Translates Scala modifiers into MethodAttributes - */ - private static short translateMethodAttributes(Symbol method) - { - int mods = method.flags; - if (method.owner().isInterface()) - mods |= Modifiers.DEFERRED; - int attr = MethodAttributes.HideBySig; - if (!method.isInitializer()) { - attr |= MethodAttributes.Virtual; - if (Modifiers.Helper.isFinal(mods)) - attr |= MethodAttributes.Final; - if (Modifiers.Helper.isAbstract(mods)) - attr |= MethodAttributes.Abstract; - } - - if (Modifiers.Helper.isPrivate(mods)) - attr |= MethodAttributes.Private; - else if (Modifiers.Helper.isProtected(mods)) - attr |= MethodAttributes.Family; - else - attr |= MethodAttributes.Public; - - return (short)attr; - } - - //########################################################################## - - byte[] attributeArgs(AConstant[] args) { - ByteBuffer buf = ByteBuffer.allocate(1024); - buf.order(ByteOrder.LITTLE_ENDIAN); - buf.putShort((short)1); // write signature - for (int i = 0; i < args.length; i++) { - switch (args[i]) { - case BOOLEAN(boolean value): buf.put((byte)(value ? 1 : 0)); break; - case BYTE(byte value): buf.put(value); break; - case SHORT(short value): buf.putShort(value); break; - case CHAR(char value): buf.putChar(value); break; - case INT(int value): buf.putInt(value); break; - case LONG(long value): buf.putLong(value); break; - case FLOAT(float value): buf.putFloat(value); break; - case DOUBLE(double value): buf.putDouble(value); break; - case STRING(String value): - int length = value.length(); - if (length < 128) - buf.put((byte)length); - else if (length < 2<<14) { - buf.put((byte)((length >> 8) | 0x80)); - buf.put((byte)(length & 0xff)); - } else if (length < 2<<29) { - buf.put((byte)((length >> 24) | 0xc0)); - buf.put((byte)((length >> 16) & 0xff)); - buf.put((byte)((length >> 8) & 0xff)); - buf.put((byte)((length ) & 0xff)); - } else - throw Debug.abort("String too long: " + length); - try { - buf.put(value.getBytes("UTF-8")); - } catch (java.io.UnsupportedEncodingException e) { - throw Debug.abort(e); - } - break; - default: - throw Debug.abort("Cannot handle attribute argument " + args[i]); - } - } - buf.putShort((short)0); // count of named parameters == 0 - int length = buf.position(); - byte[] arr = new byte[length]; - System.arraycopy(buf.array(), 0, arr, 0, length); - return arr; - } - - private void setAttributes(ICustomAttributeSetter icas, AttributeInfo attr) { - for (; attr != null; attr = attr.next) { - if (!specialAttrs.contains(attr.constr)) { - ConstructorInfo constr = - (ConstructorInfo)getMethod(attr.constr); - byte[] args = attributeArgs(attr.args); - icas.SetCustomAttribute(constr, args); - } - } - } - -} // class TypeCreator diff --git a/sources/scalac/checkers/CheckTreeNodes.java.tmpl b/sources/scalac/checkers/CheckTreeNodes.java.tmpl deleted file mode 100644 index ca07b23cbd..0000000000 --- a/sources/scalac/checkers/CheckTreeNodes.java.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.checkers; - -import scalac.Global; -import scalac.CompilerPhases; -{#Imports#} - -/** Class to check tree nodes. */ -public class CheckTreeNodes { - - //######################################################################## - // Public Constants - - public static final CheckTreeNodes instance = new CheckTreeNodes(); - - //######################################################################## - // Private Fields - - private final Global global = Global.instance; - private final CompilerPhases phases = global.PHASE; - - //######################################################################## - // Public Methods - - public void check(Tree tree) { - {#TreeSwitch#} - } - - public boolean checkNode(Tree tree) { - check(tree); - return true; - } - - //######################################################################## -} diff --git a/sources/scalac/checkers/TreeChecker.java b/sources/scalac/checkers/TreeChecker.java deleted file mode 100644 index d5e7aac987..0000000000 --- a/sources/scalac/checkers/TreeChecker.java +++ /dev/null @@ -1,637 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.checkers; - -import java.util.Iterator; -import java.util.HashSet; -import java.util.Set; -import java.util.Stack; - -import scala.tools.util.Position; - -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.AbsTypeDef; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.ast.Tree.ValDef; -import scalac.ast.TreeInfo; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This checker checks that trees are well-formed. It checks both the - * shape and the attribution of the trees. WARNING: currently, the - * checks are valid only for trees generated by phase AddConstructors. - */ -public class TreeChecker { - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The stack of current units */ - private final Stack/*<CompilationUnit>*/ units = new Stack(); - - /** The stack of current classes */ - private final Stack/*<Symbol>*/ classes = new Stack(); - - /** The stack of current members */ - private final Stack/*<Symbol>*/ members = new Stack(); - - /** The stack of current owners */ - private final Stack/*<Symbol>*/ owners = new Stack(); - - /** The currently visible type variables */ - private final Set/*<Symbol>*/ tvars = new HashSet(); - - /** The currently visible value variables */ - private final Set/*<Symbol>*/ vvars = new HashSet(); - - /** The currently visible labels */ - private final Set/*<Symbol>*/ labels = new HashSet(); - - /** The currently defined symbols */ - private final Set/*<Symbol>*/ symbols = new HashSet(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public TreeChecker(Definitions definitions) { - this.definitions = definitions; - } - - //######################################################################## - // Public Methods - Checking units - - /** Checks the unit. Returns true. */ - public boolean check(CompilationUnit unit) { - pushUnit(unit); - template(unit.body); - popUnit(); - return true; - } - - //######################################################################## - // Private Methods - Checking templates - - /** Checks the templates. Returns true. */ - private boolean template(Tree[] trees) { - for (int i = 0; i < trees.length; i++) template(trees[i]); - return true; - } - - /** Checks the template. Returns true. */ - private boolean template(Tree tree) { - switch (tree) { - - case Empty: - return true; - - case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, _, Template(_, Tree[] body)): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isClass(): show(tree); - assert vparams.length == 1: show(tree); - containSymbols(tparams, symbol.typeParams()); - containSymbols(vparams[0],symbol.valueParams()); - registerSymbol(symbol); - scopeInsertParametersOf(symbol); - pushClass(symbol); - member(body); - popClass(); - scopeRemoveParametersOf(symbol); - return true; - - case PackageDef(Tree packaged, Template(Tree[] bases, Tree[] body)): - Symbol symbol = packaged.symbol(); - assert symbol != null && symbol.isPackage(): show(packaged); - assert bases.length == 0: show(tree); - pushOwner(symbol); - template(body); - popOwner(); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking members - - /** Checks the members. Returns true. */ - private boolean member(Tree[] trees) { - for (int i = 0; i < trees.length; i++) member(trees[i]); - return true; - } - - /** Checks the member. Returns true. */ - private boolean member(Tree tree) { - switch (tree) { - - case Empty: - return true; - - case ClassDef(_, _, _, _, _, _): - return template(tree); - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - assert rhs == Tree.Empty: show(tree); - registerSymbol(symbol); - pushMember(symbol); - popMember(); - return true; - - case DefDef(_, _, AbsTypeDef[]tparams, ValDef[][]vparams, _, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isMethod(): show(tree); - assert vparams.length == 1: show(tree); - containSymbols(tparams, symbol.typeParams()); - containSymbols(vparams[0],symbol.valueParams()); - assert symbol.isDeferred() == (rhs == Tree.Empty): show(tree); - registerSymbol(symbol); - scopeInsertParametersOf(symbol); - pushMember(symbol); - if (!symbol.isDeferred()) expression(rhs, symbol.resultType()); - popMember(); - scopeRemoveParametersOf(symbol); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking statements - - /** Checks the statement. Returns true. */ - private boolean statement(Set locals, Tree tree) { - switch (tree) { - - case Empty: - return true; - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - scopeInsertVVariable(symbol, false); - locals.add(symbol); - pushOwner(symbol); - expression(rhs, symbol.type()); - popOwner(); - return true; - - default: - return expression(tree, tree.type()); - } - } - - //######################################################################## - // Private Methods - Checking expressions - - /** Checks the expression of given expected type. Returns true. */ - private boolean expression(Tree tree, Type expected) { - // !!! conforms(tree, expected); - expected = tree.type(); - switch (tree) { - - case LabelDef(_, Ident[] idents, Tree rhs): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isLabel(): show(tree); - Symbol[] params = symbol.type().valueParams(); - assert params.length == idents.length: show(tree) - + format("params", Debug.show(params)); - for (int i = 0; i < idents.length; i++) { - location(idents[i]); - conforms(idents[i], definitions.ANY_TYPE(), params[i].type()); - Symbol local = idents[i].symbol(); - assert local != null && !local.isModule(): show(idents[i]); - } - conforms(tree, symbol.resultType()); - scopeInsertLabel(symbol); - expression(rhs, symbol.resultType()); - scopeRemoveLabel(symbol); - return true; - - case Block(Tree[] statements, Tree value): - Set locals = new HashSet(); - for (int i = 0; i < statements.length; i++) - statement(locals, statements[i]); - expression(value, expected); - for (Iterator i = locals.iterator(); i.hasNext(); ) - scopeRemoveVVariable((Symbol)i.next()); - return true; - - case Assign(Tree lhs, Tree rhs): - location(lhs); - expression(rhs, lhs.type().widen()); - return true; - - case If(Tree cond, Tree thenp, Tree elsep): - expression(cond, definitions.boolean_TYPE()); - expression(thenp, expected); - expression(elsep, expected); - return true; - - case Switch(Tree test, _, Tree[] bodies, Tree otherwise): - expression(test, definitions.int_TYPE()); - for (int i = 0; i < bodies.length; i++) - expression(bodies[i], expected); - expression(otherwise, expected); - return true; - - case Return(Tree value): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isMethod(): show(tree); - assert currentMember() == symbol: show(tree); - return expression(value, currentMember().resultType()); - - case Throw(Tree value): - return expression(value, definitions.THROWABLE_TYPE()); - - case New(Tree init): - switch (init) { - case Apply(Select(Create(_, Tree[] targs), _), Tree[] vargs): - return expression(init, definitions.void_TYPE()); - default: - throw Debug.abort("illegal case", show(tree)); - } - - case Create(Tree qualifier, Tree[] targs): - assert qualifier == Tree.Empty: show(tree); - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isClass(): show(tree); - return true; - - case Apply(Tree vfun, Tree[] vargs): - vapply(tree, vfun.type(), vargs); - switch (vfun) { - case TypeApply(Tree tfun, Tree[] targs): - Symbol symbol = tfun.symbol(); - assert symbol != null && !symbol.isLabel(): show(tree); - tapply(tree, tfun.type(), targs); - return function(tfun); - default: - return function(vfun); - } - - case Super(_, _): - case This(_): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isClass(): show(tree); - assert symbol == currentClass(): show(tree); - return true; - - case Select(_, _): - case Ident(_): - return location(tree); - - case Literal(_): - return true; - - default: - throw Debug.abort("illegal case", show(tree)); - } - } - - /** Checks the type application. Returns true. */ - private boolean tapply(Tree tree, Type function, Tree[] args) { - Symbol[] params = function.typeParams(); - assert params.length == args.length: show(tree) - + format("params", Debug.show(params)); - Type.Map subst = Type.getSubst(params, Tree.typeOf(args)); - for (int i = 0; i < args.length; i++) { - Type expected = subst.apply(params[i].info()); - Type loBound = subst.apply(params[i].loBound()); - conforms(args[i], expected, loBound); - } - conforms(tree, subst.apply(function.resultType())); - return true; - } - - /** Checks the value application. Returns true. */ - private boolean vapply(Tree tree, Type function, Tree[] args) { - Symbol[] params = function.valueParams(); - assert params.length == args.length: show(tree) - + format("params", Debug.show(params)); - for (int i = 0; i < args.length; i++) - expression(args[i], params[i].type()); - conforms(tree, function.resultType()); - return true; - } - - //######################################################################## - // Private Methods - Checking functions - - /** Checks the function. Returns true. */ - private boolean function(Tree tree) { - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - assert symbol.isMethod(): show(tree); - switch (tree) { - - case Select(Tree qualifier, _): - if (qualifier instanceof Tree.Create) - assert symbol.isInitializer(): show(tree); - return selection(tree); - - case Ident(_): - if (!symbol.isLabel() && symbol.isStatic()) return true; - assert labels.contains(symbol): show(tree); - assert symbol.owner() == currentMember(): show(tree); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Checks the location. Returns true. */ - private boolean location(Tree tree) { - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - assert !symbol.isMethod(): show(tree); - switch (tree) { - - case Select(_, _): - return selection(tree); - - case Ident(_): - if (symbol.isStatic()) return true; - assert vvars.contains(symbol): show(tree); - assert symbol.owner() == currentMember(): show(tree); - return true; - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking selection - - /** Checks the selection. Returns true. */ - private boolean selection(Tree tree) { - switch (tree) { - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - assert symbol != null && symbol.isTerm(): show(tree); - Symbol owner = symbol.owner(); - assert owner.isClass() && !owner.isStaticOwner(): show(tree); - assert qualifier.type().baseType(owner) != Type.NoType: - show(tree) + format("qual.type", qualifier.type()); - return expression(qualifier, qualifier.type()); - - default: - throw Debug.abort("illegal case", tree); - } - } - - //######################################################################## - // Private Methods - Checking helpers - - /** Do the trees contain the given symbols? */ - private void containSymbols(Tree[] trees, Symbol[] symbols) { - boolean ok = trees.length == symbols.length; - for (int i = 0; ok && i < trees.length; i++) - ok &= trees[i].symbol() == symbols[i]; - assert ok: show() + format("trees", trees) + format("symbols",symbols); - } - - /** Does the type conform to the expected type and lower bound? */ - private void conforms(Tree tree, Type expected, Type loBound) { - conforms(tree, expected); - if (false && !loBound.isSubType(tree.type())) { // !!! false && - Type.explainSwitch = true; - assert loBound.isSubType(tree.type()): show(tree) - + format("loBound", expected); - Type.explainSwitch = false; - } - } - - /** Does the type conform to the expected type? */ - private void conforms(Tree tree, Type expected) { - if (!tree.type().isSubType(expected)) { - Type.explainSwitch = true; - assert tree.type().isSubType(expected): show(tree) - + format("expected", expected); - Type.explainSwitch = false; - } - } - - //######################################################################## - // Private Methods - Declaring symbols - - /** Remove parameters of symbol from current scope. */ - private void scopeInsertParametersOf(Symbol symbol) { - Symbol[] tparams = symbol.typeParams(); - for (int i = 0; i < tparams.length; i++) - scopeInsertTVariable(tparams[i], true); - Symbol[] vparams = symbol.valueParams(); - for (int i = 0; i < vparams.length; i++) - scopeInsertVVariable(vparams[i], true); - } - - /** Adds the type variable to the current scope. */ - private void scopeInsertTVariable(Symbol symbol, boolean isParameter) { - assert !symbol.owner().isClass(): show(symbol); - assert symbol.isParameter() == isParameter: show(symbol); - registerSymbol(symbol); - tvars.add(symbol); - } - - /** Adds the value variable to the current scope. */ - private void scopeInsertVVariable(Symbol symbol, boolean isParameter) { - assert !symbol.owner().isClass(): show(symbol); - assert symbol.isParameter() == isParameter: show(symbol); - registerSymbol(symbol); - vvars.add(symbol); - } - - /** Adds the label to current scope. */ - private void scopeInsertLabel(Symbol symbol) { - assert !symbol.owner().isClass(): show(symbol); - registerSymbol(symbol); - labels.add(symbol); - } - - /** Remove parameters of symbol from current scope. */ - private void scopeRemoveParametersOf(Symbol symbol) { - Symbol[] tparams = symbol.typeParams(); - for (int i = 0; i < tparams.length; i++) - scopeRemoveTVariable(tparams[i]); - Symbol[] vparams = symbol.valueParams(); - for (int i = 0; i < vparams.length; i++) - scopeRemoveVVariable(vparams[i]); - } - - /** Removes the type variable from current scope. */ - private void scopeRemoveTVariable(Symbol symbol) { - boolean removed = tvars.remove(symbol); - assert removed: show(symbol); - } - - /** Removes the value variable from current scope. */ - private void scopeRemoveVVariable(Symbol symbol) { - boolean removed = vvars.remove(symbol); - assert removed: show(symbol); - } - - /** Removes the label symbol from current scope. */ - private void scopeRemoveLabel(Symbol symbol) { - boolean removed = labels.remove(symbol); - assert removed: show(symbol); - } - - /** Registers the symbol. */ - private void registerSymbol(Symbol symbol) { - boolean added = symbols.add(symbol); - assert added: show(symbol); - } - - //######################################################################## - // Private Methods - Managing current context - - /** Returns the current unit. */ - private CompilationUnit currentUnit() { - return units.size() > 0 ? (CompilationUnit)units.peek() : null; - } - - /** Returns the current class. */ - private Symbol currentClass() { - return classes.size() > 0 ? (Symbol)classes.peek() : null; - } - - /** Returns the current member. */ - private Symbol currentMember() { - return members.size() > 0 ? (Symbol)members.peek() : null; - } - - /** Returns the current owner. */ - private Symbol currentOwner() { - return owners.size() > 0 ? (Symbol)owners.peek() : null; - } - - /** Sets the current unit to the given one. */ - private void pushUnit(CompilationUnit unit) { - assert units.size() == 0: showPush(unit); - assert classes.size() == 0: showPush(unit); - assert members.size() == 0: showPush(unit); - units.push(unit); - } - - /** Sets the current class to the given one. */ - private void pushClass(Symbol clasz) { - assert clasz.isClass(): showPush(clasz); - assert members.size() == 0: showPush(clasz); - classes.push(clasz); - pushOwner(clasz); - } - - /** Sets the current member to the given one. */ - private void pushMember(Symbol member) { - assert member.isTerm(): showPush(member); - assert members.size() == 0: showPush(member); - assert member.owner() == currentClass(): showPush(member); - members.push(member); - pushOwner(member); - } - - /** Sets the current owner to the given one. */ - private void pushOwner(Symbol owner) { - owners.push(owner); - } - - /** Sets the current unit to the previous one. */ - private void popUnit() { - assert units.size() > 0: show(); - units.pop(); - } - - /** Sets the current class to the previous one. */ - private void popClass() { - assert members.size() == 0: show(); - assert classes.size() > 0: show(); - popOwner(); - classes.pop(); - } - - /** Sets the current member to the previous one. */ - private void popMember() { - assert members.size() > 0: show(); - popOwner(); - members.pop(); - } - - /** Sets the current owner to the previous one. */ - private void popOwner() { - assert owners.size() > 0: show(); - owners.pop(); - } - - //######################################################################## - // Private Methods - Showing errors - - /** Returns the current position. */ - private String show() { - return format("unit", currentUnit()) - + format("clasz", currentClass()) - + format("member", currentMember()) - + format("owner", currentOwner()); - } - - /** Returns the current position and given header and value. */ - private String show(String header, Object value) { - return show() + format(header, value); - } - - /** Returns the current position and given symbol. */ - private String show(Symbol symbol) { - return show("symbol", symbol) - + format("symbol.pos", Position.toString(symbol.pos)) - + format("symbol.info", symbol.info()); - } - - /** Returns the current position and given tree. */ - private String show(Tree tree) { - return show("tree", tree) - + format("tree.pos", Position.toString(tree.pos)) - + format("tree.symbol", tree.symbol()) - + format("tree.type", tree.type()); - } - - /** Returns the current position and given pushed value. */ - private String showPush(Object value) { - return show("pushing", value); - } - - /** Returns a string with the given header and value. */ - private String format(String header, Object value) { - while (header.length() < 12) header = header + ' '; - return "\n" + header + ": " + toString(value); - } - - /** Returns a string representation of the given value. */ - private String toString(Object value) { - if (value instanceof Symbol) return Debug.show(value); - if (value instanceof Object[]) return Debug.show(value); - return String.valueOf(value); - } - - //######################################################################## -} diff --git a/sources/scalac/framework/History.java b/sources/scalac/framework/History.java deleted file mode 100644 index ce0800358d..0000000000 --- a/sources/scalac/framework/History.java +++ /dev/null @@ -1,277 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.framework; - -import scalac.Global; -import scalac.Phase; -import scalac.util.Debug; - -/** - * This class implements a value history. It stores phase dependent - * values. - * - * Implementation: the value "values[n]" is valid from start of phase - * "starts[n]" to end of phase "(n == 0 ? limit : starts[n-1].prev)" - * and the promised value "next" is valid from start of phase - * "limit.next". - */ -public class History { - - //######################################################################## - // Private Constants - - /** An empty array of objects */ - private static final Object[] NO_VALUES = new Object[0]; - - /** An empty array of phases */ - private static final Phase[] NO_STARTS = new Phase[0]; - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The successive values of this history */ - private Object[] values; - - /** The start phases of the successive values */ - private Phase[] starts; - - /** The last known valid phase of the last value */ - private Phase limit; - - /** A promise of the next value (may be null) */ - private Promise next; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with current phase as first one. */ - public History() { - this(Global.instance); - } - - /** Initializes this instance with current phase as first one. */ - public History(Global global) { - this(global, global.currentPhase); - } - - /** Initializes this instance with given first phase. */ - public History(Phase first) { - this(first.global, first); - } - - /** Initializes this instance with given first phase. */ - public History(Global global, Phase first) { - this.global = global; - reset(first); - } - - //######################################################################## - // Public Methods - - /** Returns the first phase of this history. */ - public final Phase getFirstPhase() { - return starts.length > 0 ? starts[starts.length - 1] : limit.next; - } - - /** Returns the value at current phase. */ - public final Object getValue(Object owner) { - return getValueAt(owner, getPhase()); - } - - /** Returns the value at next phase. */ - public final Object getNextValue(Object owner) { - return getValueAt(owner, getNextPhase()); - } - - /** Returns the value at given phase. */ - public final Object getValueAt(Object owner, Phase phase) { - assert phase != null: show(owner, phase); - while (limit.id < phase.id) incrementLimit(owner); - for (int i = 0; i < starts.length; i++) - if (starts[i].id <= phase.id) return values[i]; - throw Debug.abort("prehistoric phase", show(owner, phase)); - } - - /** Sets the value at current phase. */ - public final History setValue(Object owner, Object value) { - return setValueAt(owner, getPhase(), value); - } - - /** Sets the value at next phase. */ - public final History setNextValue(Object owner, Object value) { - return setValueAt(owner, getNextPhase(), value); - } - - /** Sets the value at given phase. */ - public final History setValueAt(Object owner, Phase phase, Object value) { - assert phase != null: show(owner, phase); - assert phase == limit.next && next == null: show(owner, phase); - if (values.length == 0 || values[0] != value) { - this.values = append(value, values); - this.starts = append(phase, starts); - } - this.limit = phase; - return this; - } - - /** Sets a value promise at current phase. */ - public final History setPromise(Object owner, Promise promise) { - return setPromiseAt(owner, getPhase(), promise); - } - - /** Sets a value promise at next phase. */ - public final History setNextPromise(Object owner, Promise promise) { - return setPromiseAt(owner, getNextPhase(), promise); - } - - /** Sets a value promise at given phase. */ - public final History setPromiseAt(Object owner, Phase phase, - Promise promise) - { - assert phase != null: show(owner, phase); - assert phase == limit.next && next == null: show(owner, phase); - this.next = promise; - return this; - } - - /** Erases all values. */ - public final void reset() { - reset(getFirstPhase()); - } - - /** Erases all values and sets first phase to given one. */ - public final void reset(Phase first) { - assert first != null && first.prev != null: this + " - " + first; - this.values = NO_VALUES; - this.starts = NO_STARTS; - this.limit = first.prev; - this.next = null; - } - - /** Returns a string representation of this history. */ - public String toString() { - StringBuffer buffer = new StringBuffer("["); - for (int i = 0; i < values.length; i++) { - buffer.append(starts[i]).append(" -> "); - buffer.append(Debug.show(values[i])).append(", "); - } - buffer.append(limit); - if (next != null) buffer.append(" - ").append(next); - return buffer.append("]").toString(); - } - - //######################################################################## - // Protected Methods - - /** - * Computes the value at phase following given one by transforming - * the given value (which is the value at given phase). The - * default implementation changes the current phase to given one - * and then forwards the call to method "transformValue". - */ - protected Object transformValueAt(Object owner, Phase phase, Object value){ - Phase current = global.currentPhase; - global.currentPhase = phase; - Object result = transformValue(owner, value); - global.currentPhase = current; - return result; - } - - /** - * Computes the value at next phase by transforming the given - * value (which is the value at current phase). The default - * implementation forwards the call to method "computeValueAt". - */ - protected Object transformValue(Object owner, Object value) { - return computeValueAt(owner, global.currentPhase.next); - } - - /** - * Computes the value at given phase. The default implementation - * changes the current phase to given one and then forwards the - * call to method "computeValue". - */ - protected Object computeValueAt(Object owner, Phase phase) { - Phase current = global.currentPhase; - global.currentPhase = phase; - Object result = computeValue(owner); - global.currentPhase = current; - return result; - } - - /** - * Computes the value at current phase. The default implementation - * throws an exception. - */ - protected Object computeValue(Object owner) { - throw Debug.abort("undefined value", show(owner, getPhase())); - } - - //######################################################################## - // Private Methods - - /** Returns the current phase. */ - private Phase getPhase() { - return global.currentPhase; - } - - /** Returns the next phase. */ - private Phase getNextPhase() { - return getPhase().next; - } - - /** Increments the limit of this history. */ - private void incrementLimit(Object owner) { - Phase phase = limit; - Object value; - if (next != null) { - value = next.forceAt(owner, global, phase.next); - if (limit == phase) next = null; - } else if (values.length > 0) { - value = transformValueAt(owner, phase, values[0]); - } else { - value = computeValueAt(owner, phase.next); - } - if (limit == phase) setValueAt(owner, phase.next, value); - } - - /** Returns a string of this history and given owner. */ - private String show(Object owner) { - return this + " @ " + Debug.show(owner); - } - - /** Returns a string of this history and given owner and phase. */ - private String show(Object owner, Phase phase) { - return show(owner) + " - " + phase; - } - - //######################################################################## - // Private Functions - - /** Returns the concatenation of given values. */ - private static Object[] append(Object value, Object[] values) { - Object[] array = new Object[1 + values.length]; - array[0] = value; - for (int i = 1; i < array.length; i++) array[i] = values[i - 1]; - return array; - } - - /** Returns the concatenation of given phases. */ - private static Phase[] append(Phase phase, Phase[] phases) { - Phase[] array = new Phase[1 + phases.length]; - array[0] = phase; - for (int i = 1; i < array.length; i++) array[i] = phases[i - 1]; - return array; - } - - //######################################################################## -} diff --git a/sources/scalac/framework/Promise.java b/sources/scalac/framework/Promise.java deleted file mode 100644 index 7a1a521512..0000000000 --- a/sources/scalac/framework/Promise.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.framework; - -import scalac.Global; -import scalac.Phase; - -/** - * This abstract class represents a value promise (a lazy value). The - * promised value is obtained by invoking the method "force" which - * will detect any cyclic definition. Note that this class does not - * store evaluated values. Therefore, successive calls to "force" will - * trigger successive evaluations of the promise. - */ -public abstract class Promise { - - //######################################################################## - // Private Fields - - /** The current number of evaluation cycles */ - private int cycles; - - //######################################################################## - // Public Methods - - /** Forces this promise and returns its value. */ - public final Object force(Object owner) { - int cycles = this.cycles; - this.cycles++; - Object value = cycles > 0 - ? evaluate(owner) - : getCyclicValue(owner, cycles); - this.cycles--; - return value; - } - - /** Forces this promise at given phase and returns its value. */ - public final Object forceAt(Object owner, Global global, Phase phase) { - Phase current = global.currentPhase; - global.currentPhase = phase; - Object value = force(owner); - global.currentPhase = current; - return value; - } - - //######################################################################## - // Protected Methods - - /** - * Evaluates this promise. This method is invoked by non-cyclic - * calls to the method "force". - */ - protected abstract Object evaluate(Object owner); - - /** - * Returns the value to use in case of a cyclic definition. This - * method is invoked by cyclic calls to the method "force". The - * current (strictly positive) number of cycles is passed as an - * argument. - */ - protected abstract Object getCyclicValue(Object owner, int cycles); - - //######################################################################## -} diff --git a/sources/scalac/symtab/AttributeInfo.java b/sources/scalac/symtab/AttributeInfo.java deleted file mode 100644 index 00d7c22d5a..0000000000 --- a/sources/scalac/symtab/AttributeInfo.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import scalac.atree.AConstant; -import scalac.util.Debug; - -public class AttributeInfo { - - public final Symbol constr; - public final AConstant[] args; - public final AttributeInfo next; - - public AttributeInfo(Symbol constr, AConstant[] args, AttributeInfo next) { - this.constr = constr; - this.args = args; - this.next = next; - assert constr.isConstructor() : Debug.show(constr); - } - - public AConstant[] getAttrArguments(Symbol sym) { - for (AttributeInfo attr = this; attr != null; attr = attr.next) - if (attr.constr == sym) - return attr.args; - return null; - } - - public String toString() { - StringBuffer str = new StringBuffer("["); - for (AttributeInfo attr = this; attr != null; attr = attr.next) { - str.append(Debug.show(attr.constr.constructorClass())); - int n = attr.args.length; - if (n > 0) { - str.append('('); - for (int i = 0; i < n; i++) { - if (i > 0) str.append(", "); - str.append(attr.args[i]); - } - str.append(')'); - } - if (attr.next != null) { - str.append(", "); - } - } - str.append(']'); - return str.toString(); - } - -} diff --git a/sources/scalac/symtab/ClosureHistory.java b/sources/scalac/symtab/ClosureHistory.java deleted file mode 100644 index 0f5073cd89..0000000000 --- a/sources/scalac/symtab/ClosureHistory.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.Iterator; -import java.util.TreeMap; - -import scalac.Global; -import scalac.framework.History; -import scalac.util.Debug; -import scalac.util.ArrayApply; - -/** This class implements a closure history. */ -public class ClosureHistory extends History { - - //######################################################################## - // Protected Methods - - /** Transforms given closure into closure at next phase. */ - protected Object transformValue(Object owner, Object value){ - Type[] closure = (Type[])value; - for (int i = 0; i < closure.length; i++) { - Symbol symbol = closure[i].symbol(); - // !!! symbol.nextInfoHasChanged() would be better - if (symbol.info() != symbol.nextInfo()) - return super.transformValue(owner, closure); - } - return closure; - } - - /** Computes the closure at current phase. */ - protected Object computeValue(Object owner) { - Symbol clasz = (Symbol)owner; - TreeMap parents = new TreeMap(SymbolComparator.instance); - addParents(parents, clasz.info()); - Type[] closure = new Type[1 + parents.size()]; - Iterator types = parents.values().iterator(); - closure[0] = clasz.type(); - for (int i = 1; i < closure.length; i++) - closure[i] = (Type)types.next(); - //System.out.println("closure(" + owner + ") = " + ArrayApply.toString(closure));//DEBUG - return closure; - } - - //######################################################################## - // Private Functions - - /** Adds all parents of given type to given parent table. */ - private static void addParents(TreeMap/*<Symbol,Type>*/ table, Type type) { - switch (type) { - case ErrorType: case NoType: - return; - case TypeRef(_, Symbol symbol, _): - Type.Map map = Type.getThisTypeMap(symbol, type); - Type[] closure = symbol.closure(); - for (int i = 0; i < closure.length; i++) - table.put(closure[i].symbol(), map.apply(closure[i])); - return; - case CompoundType(Type[] parents, _): - for (int i = 0; i < parents.length; i++) - addParents(table, parents[i]); - return; - case SingleType(_, _): - case ThisType(_): - addParents(table, type.singleDeref()); - return; - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java deleted file mode 100644 index d100e911c8..0000000000 --- a/sources/scalac/symtab/Definitions.java +++ /dev/null @@ -1,1194 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -import scala.tools.util.Position; - -import scalac.Global; -import scalac.atree.ATreeTyper; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; - -public class Definitions { - - //######################################################################## - // Public Fields - Root module - - /** The attributed tree typer */ - public final ATreeTyper atyper; - - //######################################################################## - // Public Fields & Methods - Root class and some standard packages - - /** The root class */ - public final Symbol ROOT_CLASS; - - /** The java.lang package */ - public final Symbol JAVALANG; - - /** The scala package */ - public final Symbol SCALA; - - //######################################################################## - // Public Fields & Methods - Top and bottom classes - - /** The scala.Any class */ - public final Symbol ANY_CLASS; - public final Type ANY_TYPE() {return ANY_CLASS.staticType();} - - /** The scala.AnyVal class */ - public final Symbol ANYVAL_CLASS; - public final Type ANYVAL_TYPE() {return ANYVAL_CLASS.staticType();} - - /** The scala.AnyRef class */ - public final Symbol ANYREF_CLASS; - public final Type ANYREF_TYPE() {return ANYREF_CLASS.staticType();} - - /** The scala.AllRef class */ - public final Symbol ALLREF_CLASS; - public final Type ALLREF_TYPE() {return ALLREF_CLASS.staticType();} - - /** The scala.All class */ - public final Symbol ALL_CLASS; - public final Type ALL_TYPE() {return ALL_CLASS.staticType();} - - //######################################################################## - // Public Fields & Methods - Java classes - - /** The java.lang.Object class */ - public final Symbol OBJECT_CLASS; - public final Type OBJECT_TYPE() {return OBJECT_CLASS.staticType();} - - /** The java.lang.String class */ - public final Symbol STRING_CLASS; - public final Type STRING_TYPE() {return STRING_CLASS.staticType();} - - /** The java.lang.Throwable class */ - public final Symbol THROWABLE_CLASS; - public final Type THROWABLE_TYPE() {return THROWABLE_CLASS.staticType();} - - //######################################################################## - // Public Fields & Methods - Scala value classes - - /** The scala.Unit class */ - public final Symbol UNIT_CLASS; - public final Type UNIT_TYPE() {return UNIT_CLASS.staticType();} - - /** The scala.Boolean class */ - public final Symbol BOOLEAN_CLASS; - public final Type BOOLEAN_TYPE() {return BOOLEAN_CLASS.staticType();} - - /** The scala.Byte class */ - public final Symbol BYTE_CLASS; - public final Type BYTE_TYPE() {return BYTE_CLASS.staticType();} - - /** The scala.Short class */ - public final Symbol SHORT_CLASS; - public final Type SHORT_TYPE() {return SHORT_CLASS.staticType();} - - /** The scala.Char class */ - public final Symbol CHAR_CLASS; - public final Type CHAR_TYPE() {return CHAR_CLASS.staticType();} - - /** The scala.Int class */ - public final Symbol INT_CLASS; - public final Type INT_TYPE() {return INT_CLASS.staticType();} - - /** The scala.Long class */ - public final Symbol LONG_CLASS; - public final Type LONG_TYPE() {return LONG_CLASS.staticType();} - - /** The scala.Float class */ - public final Symbol FLOAT_CLASS; - public final Type FLOAT_TYPE() {return FLOAT_CLASS.staticType();} - - /** The scala.Double class */ - public final Symbol DOUBLE_CLASS; - public final Type DOUBLE_TYPE() {return DOUBLE_CLASS.staticType();} - - - //######################################################################## - // Public Fields & Methods - Scala reference classes - - /** The scala.ScalaObject class */ - public final Symbol SCALAOBJECT_CLASS; - public final Type SCALAOBJECT_TYPE() {return SCALAOBJECT_CLASS.staticType();} - - /** The scala.Attribute class */ - public final Symbol ATTRIBUTE_CLASS; - public final Type ATTRIBUTE_TYPE() {return ATTRIBUTE_CLASS.staticType();} - - /** The scala.Ref class */ - public final Symbol REF_CLASS; - public final Type REF_TYPE(Type element) { - return REF_CLASS.staticType(element); - } - - /** The scala.TupleX classes */ - public final int TUPLE_COUNT = 10; - public final Symbol[] TUPLE_CLASS = new Symbol[TUPLE_COUNT]; - public final Type TUPLE_TYPE(Type[] args) { - assert 0 < args.length && args.length < TUPLE_COUNT: args.length; - return TUPLE_CLASS[args.length].staticType(args); - } - - /** The scala.FunctionX classes */ - public final int FUNCTION_COUNT = 10; - public final Symbol[] FUNCTION_CLASS = new Symbol[FUNCTION_COUNT]; - public final Type FUNCTION_TYPE(Type[] args, Type result) { - assert 0 <= args.length; - if (args.length >= FUNCTION_COUNT) - throw new Type.Error("function has too many arguments; limit = " + (FUNCTION_COUNT-1)); - args = Type.cloneArray(args, 1); - args[args.length - 1] = result; - return FUNCTION_CLASS[args.length - 1].staticType(args); - } - - /** The scala.PartialFunction class */ - public final Symbol PARTIALFUNCTION_CLASS; - public final Type PARTIALFUNCTION_TYPE(Type argument, Type result) { - return PARTIALFUNCTION_CLASS.staticType(argument, result); - } - - /** The scala.Iterable class */ - public final Symbol ITERABLE_CLASS; - public final Type ITERABLE_TYPE(Type element) { - return ITERABLE_CLASS.staticType(element); - } - - /** The scala.Iterator class */ - public final Symbol ITERATOR_CLASS; - public final Type ITERATOR_TYPE(Type element) { - return ITERATOR_CLASS.staticType(element); - } - - /** The scala.Seq class */ - public final Symbol SEQ_CLASS; - public final Type SEQ_TYPE(Type element) { - return SEQ_CLASS.staticType(element); - } - - /** The scala.List class */ - public final Symbol LIST_CLASS; - public final Type LIST_TYPE(Type element) { - return LIST_CLASS.staticType(element); - } - - /** The scala.Nil module - * evaluated on demand to make bootstrap possible. - */ - public final Symbol NIL() { - return getModule("scala.Nil"); - } - - /** The scala.:: class - * evaluated on demand to make bootstrap possible. - */ - public final Symbol CONS_CLASS() { - return getClass("scala.$colon$colon"); - } - public final Type CONS_TYPE(Type element) { - return CONS_CLASS().staticType(element); - } - - /** The scala.Array class */ - public final Symbol ARRAY_CLASS; - public final Type ARRAY_TYPE(Type element) { - return ARRAY_CLASS.staticType(element); - } - - /** The scala.Type class & its subclasses */ - public final Symbol TYPE_CLASS; - public final Type TYPE_TYPE() { - return TYPE_CLASS.staticType(); - } - - public final Symbol CLASSTYPE_CLASS; - public final Type CLASSTYPE_TYPE() { - return CLASSTYPE_CLASS.staticType(); - } - - public final Symbol JAVACLASSTYPE_CLASS; - public final Symbol JAVAREFARRAYTYPE_CLASS; - - public final Symbol SCALACLASSTYPE_CLASS; - public final Type SCALACLASSTYPE_TYPE() { - return SCALACLASSTYPE_CLASS.staticType(); - } - - public final Symbol SINGLETYPE_CLASS; - - public final Symbol TYPECONSTRUCTOR_CLASS; - public final Type TYPECONSTRUCTOR_TYPE() { - return TYPECONSTRUCTOR_CLASS.staticType(); - } - - public final Symbol COMPOUNDTYPE_CLASS; - - public final Symbol LAZYPARENTS_CLASS; - public final Type LAZYPARENTS_TYPE() { - return LAZYPARENTS_CLASS.staticType(); - } - - /** The scala.Predef module */ - public final Symbol PREDEF; - - /** The scala.Console module */ - public final Symbol CONSOLE; - - /** The scala.MatchError module */ - public final Symbol MATCHERROR; - - //######################################################################## - // attributes - - public final Symbol SCALA_SERIALIZABLE_CONSTR; - public final Symbol SCALA_TRANSIENT_CONSTR; - public final Symbol SCALA_VOLATILE_CONSTR; - public final Symbol SCALA_CLONEABLE_CONSTR; - - //######################################################################## - // Public Fields & Methods - Scala primitive types - - /** Returns the primitive type void. */ - public final Type void_TYPE() { - return void_TYPE.type().resultType(); - } - - /** Returns the primitive type boolean. */ - public final Type boolean_TYPE() { - return boolean_TYPE.type().resultType(); - } - - /** Returns the primitive type byte. */ - public final Type byte_TYPE() { - return byte_TYPE.type().resultType(); - } - - /** Returns the primitive type short. */ - public final Type short_TYPE() { - return short_TYPE.type().resultType(); - } - - /** Returns the primitive type char. */ - public final Type char_TYPE() { - return char_TYPE.type().resultType(); - } - - /** Returns the primitive type int. */ - public final Type int_TYPE() { - return int_TYPE.type().resultType(); - } - - /** Returns the primitive type long. */ - public final Type long_TYPE() { - return long_TYPE.type().resultType(); - } - - /** Returns the primitive type float. */ - public final Type float_TYPE() { - return float_TYPE.type().resultType(); - } - - /** Returns the primitive type double. */ - public final Type double_TYPE() { - return double_TYPE.type().resultType(); - } - - /** Returns the primitive array type of given element type. */ - public final Type array_TYPE(Type element) { - Type type = array_TYPE.type().resultType(); - switch (type) { - case TypeRef(Type prefix, Symbol clasz, _): - return Type.typeRef(prefix, clasz, new Type[]{element}); - case UnboxedArrayType(_): - return Type.UnboxedArrayType(element); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## - // Public Fields & Methods - Top and bottom class methods - - /** Some scala.Any methods */ - public final Symbol ANY_EQEQ; - public final Symbol ANY_BANGEQ; - public final Symbol ANY_EQUALS; - public final Symbol ANY_HASHCODE; - public final Symbol ANY_TOSTRING; - //public final Symbol ANY_PLUS; - public final Symbol ANY_IS; - public final Symbol ANY_IS_ERASED; - public final Symbol ANY_AS; - public final Symbol ANY_AS_ERASED; - public final Symbol ANY_MATCH; - - //######################################################################## - // Public Fields & Methods - Java class methods - - /** Some java.lang.Object methods */ - public final Symbol OBJECT_EQ; - public final Symbol OBJECT_NE; - public final Symbol OBJECT_CLONE; - public final Symbol OBJECT_SYNCHRONIZED; - - /** Some java.lang.String methods */ - public final Symbol STRING_PLUS; - - /** Some java.lang.Throwable methods */ - public final Symbol THROWABLE_THROW; - - //######################################################################## - // Public Fields & Methods - Scala value class methods - - /** Some scala.Boolean methods */ - private Symbol BOOLEAN_OR; - private Symbol BOOLEAN_AND; - private Symbol BOOLEAN_NOT; - - public Symbol BOOLEAN_OR() { - if (BOOLEAN_OR == null) - BOOLEAN_OR = loadTerm(BOOLEAN_CLASS, Names.BARBAR); - return BOOLEAN_OR; - } - public Symbol BOOLEAN_AND() { - if (BOOLEAN_AND == null) - BOOLEAN_AND = loadTerm(BOOLEAN_CLASS, Names.AMPAMP); - return BOOLEAN_AND; - } - public Symbol BOOLEAN_NOT() { - if (BOOLEAN_NOT == null) - BOOLEAN_NOT = loadTerm(BOOLEAN_CLASS, Names.BANG); - return BOOLEAN_NOT; - } - - //######################################################################## - // Public Fields & Methods - Scala reference class methods - - /** Some scala.ScalaObject methods */ - private Symbol SCALAOBJECT_TAG; - - public Symbol SCALAOBJECT_TAG() { - if (SCALAOBJECT_TAG == null) - SCALAOBJECT_TAG = loadTerm(SCALAOBJECT_CLASS, Names.tag); - return SCALAOBJECT_TAG; - } - - private Symbol SCALAOBJECT_GETTYPE; - - public Symbol SCALAOBJECT_GETTYPE() { - if (SCALAOBJECT_GETTYPE == null) - SCALAOBJECT_GETTYPE = loadTerm(SCALAOBJECT_CLASS, Names.getScalaType); - return SCALAOBJECT_GETTYPE; - } - - /** Some scala.Ref methods */ - private Symbol REF_ELEM; - - public Symbol REF_ELEM() { - if (REF_ELEM == null) - REF_ELEM = loadTerm(REF_CLASS, Names.elem); - return REF_ELEM; - } - - /** Some scala.TupleX methods */ - private final Symbol[][] TUPLE_FIELD = new Symbol[TUPLE_COUNT][]; - - public Symbol TUPLE_FIELD(int arity, int index) { - assert 0 < arity && arity < TUPLE_COUNT: arity; - assert 0 < index && index <= arity: arity + " - " + index; - if (TUPLE_FIELD[arity][index - 1] == null) - TUPLE_FIELD[arity][index - 1] = loadTerm(TUPLE_CLASS[arity],Names.TUPLE_FIELD(index)); - return TUPLE_FIELD[arity][index - 1]; - } - - /** Some scala.FunctionX methods */ - private final Symbol[] FUNCTION_APPLY = new Symbol[FUNCTION_COUNT]; - - public Symbol FUNCTION_APPLY(int arity) { - assert 0 <= arity && arity < FUNCTION_COUNT: arity; - if (FUNCTION_APPLY[arity] == null) - FUNCTION_APPLY[arity] = loadTerm(FUNCTION_CLASS[arity],Names.apply); - return FUNCTION_APPLY[arity]; - } - - /** Some scala.PartialFunction methods */ - private Symbol PARTIALFUNCTION_ISDEFINEDAT; - - public Symbol PARTIALFUNCTION_ISDEFINEDAT() { - if (PARTIALFUNCTION_ISDEFINEDAT == null) - PARTIALFUNCTION_ISDEFINEDAT = loadTerm(PARTIALFUNCTION_CLASS, Names.isDefinedAt); - return PARTIALFUNCTION_ISDEFINEDAT; - } - - /** Some scala.Iterable methods */ - private Symbol ITERABLE_ELEMENTS; - - public Symbol ITERABLE_ELEMENTS() { - if (ITERABLE_ELEMENTS == null) - ITERABLE_ELEMENTS = loadTerm(ITERABLE_CLASS, Names.elements); - return ITERABLE_ELEMENTS; - } - - /** Some scala.Iterator methods */ - private Symbol ITERATOR_NEXT; - private Symbol ITERATOR_HASNEXT; - - public Symbol ITERATOR_NEXT() { - if (ITERATOR_NEXT == null) - ITERATOR_NEXT = loadTerm(ITERATOR_CLASS, Names.next); - return ITERATOR_NEXT; - } - public Symbol ITERATOR_HASNEXT() { - if (ITERATOR_HASNEXT == null) - ITERATOR_HASNEXT = loadTerm(ITERATOR_CLASS, Names.hasNext); - return ITERATOR_HASNEXT; - } - - /** Some scala.Seq methods */ - private Symbol SEQ_LENGTH; - - public Symbol SEQ_LENGTH() { - if (SEQ_LENGTH == null) - SEQ_LENGTH = loadTerm(SEQ_CLASS, Names.length); - return SEQ_LENGTH; - } - - /** Some scala.List methods */ - private Symbol LIST_ISEMPTY; - private Symbol LIST_HEAD; - private Symbol LIST_TAIL; - - public Symbol LIST_ISEMPTY() { - if (LIST_ISEMPTY == null) - LIST_ISEMPTY = loadTerm(LIST_CLASS, Names.isEmpty); - return LIST_ISEMPTY; - } - public Symbol LIST_HEAD() { - if (LIST_HEAD == null) - LIST_HEAD = loadTerm(LIST_CLASS, Names.head); - return LIST_HEAD; - } - public Symbol LIST_TAIL() { - if (LIST_TAIL == null) - LIST_TAIL = loadTerm(LIST_CLASS, Names.tail); - return LIST_TAIL; - } - - /** The scala.Array class */ - private Symbol ARRAY_LENGTH; - private Symbol ARRAY_GET; - private Symbol ARRAY_SET; - - public Symbol ARRAY_LENGTH() { - if (ARRAY_LENGTH == null) - ARRAY_LENGTH = loadTerm(ARRAY_CLASS, Names.length); - return ARRAY_LENGTH; - } - - public Symbol ARRAY_GET() { - if (ARRAY_GET == null) - ARRAY_GET = loadTerm(ARRAY_CLASS, Names.apply, new Type[]{int_TYPE()}); - return ARRAY_GET; - } - - public Symbol ARRAY_SET() { - if (ARRAY_SET == null) - ARRAY_SET = loadTerm(ARRAY_CLASS, Names.update); - return ARRAY_SET; - } - - /** Some scala.Predef methods */ - private Symbol PREDEF_ARRAY; - - public Symbol PREDEF_ARRAY() { - if (PREDEF_ARRAY == null) - PREDEF_ARRAY = PREDEF.lookup(Names.Array).firstAlternative(); - return PREDEF_ARRAY; - } - - /** Some scala.Console methods */ - private Symbol CONSOLE_PRINT; - - public Symbol CONSOLE_PRINT() { - if (CONSOLE_PRINT == null) - CONSOLE_PRINT = loadTerm(CONSOLE, Names.print); - return CONSOLE_PRINT; - } - - /** Some scala.MatchError methods */ - private Symbol MATCHERROR_FAIL; - - public Symbol MATCHERROR_FAIL() { - if (MATCHERROR_FAIL == null) - MATCHERROR_FAIL = loadTerm(MATCHERROR, Names.fail); - return MATCHERROR_FAIL; - } - - private Symbol MATCHERROR_REPORT; - - public Symbol MATCHERROR_REPORT() { - if (MATCHERROR_REPORT == null) - MATCHERROR_REPORT = loadTerm(MATCHERROR, Names.report); - return MATCHERROR_REPORT; - } - - /** The scala.Type class (and subclasses) */ - private Symbol TYPE_DEFAULTVALUE; - public Symbol TYPE_DEFAULTVALUE() { - if (TYPE_DEFAULTVALUE == null) - TYPE_DEFAULTVALUE = loadTerm(TYPE_CLASS, Names.defaultValue); - return TYPE_DEFAULTVALUE; - } - - private Symbol TYPE_NEWARRAY; - public Symbol TYPE_NEWARRAY() { - if (TYPE_NEWARRAY == null) - TYPE_NEWARRAY = loadTerm(TYPE_CLASS, Names.newArray); - return TYPE_NEWARRAY; - } - - private Symbol TYPE_ISINSTANCE; - public Symbol TYPE_ISINSTANCE() { - if (TYPE_ISINSTANCE == null) - TYPE_ISINSTANCE = loadTerm(TYPE_CLASS, Names.isInstance); - assert TYPE_ISINSTANCE != Symbol.NONE; - return TYPE_ISINSTANCE; - } - - private Symbol TYPE_CAST; - public Symbol TYPE_CAST() { - if (TYPE_CAST == null) - TYPE_CAST = loadTerm(TYPE_CLASS, Names.cast); - return TYPE_CAST; - } - - private Symbol RTT_DOUBLE; - public Symbol RTT_DOUBLE() { - if (RTT_DOUBLE == null) - RTT_DOUBLE = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Double); - return RTT_DOUBLE; - } - - private Symbol RTT_FLOAT; - public Symbol RTT_FLOAT() { - if (RTT_FLOAT == null) - RTT_FLOAT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Float); - return RTT_FLOAT; - } - - private Symbol RTT_LONG; - public Symbol RTT_LONG() { - if (RTT_LONG == null) - RTT_LONG = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Long); - return RTT_LONG; - } - - private Symbol RTT_INT; - public Symbol RTT_INT() { - if (RTT_INT == null) - RTT_INT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Int); - return RTT_INT; - } - - private Symbol RTT_SHORT; - public Symbol RTT_SHORT() { - if (RTT_SHORT == null) - RTT_SHORT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Short); - return RTT_SHORT; - } - - private Symbol RTT_CHAR; - public Symbol RTT_CHAR() { - if (RTT_CHAR == null) - RTT_CHAR = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Char); - return RTT_CHAR; - } - - private Symbol RTT_BYTE; - public Symbol RTT_BYTE() { - if (RTT_BYTE == null) - RTT_BYTE = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Byte); - return RTT_BYTE; - } - - private Symbol RTT_BOOLEAN; - public Symbol RTT_BOOLEAN() { - if (RTT_BOOLEAN == null) - RTT_BOOLEAN = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Boolean); - return RTT_BOOLEAN; - } - - private Symbol RTT_UNIT; - public Symbol RTT_UNIT() { - if (RTT_UNIT == null) - RTT_UNIT = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Unit); - return RTT_UNIT; - } - - private Symbol RTT_ANY; - public Symbol RTT_ANY() { - if (RTT_ANY == null) - RTT_ANY = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.Any); - return RTT_ANY; - } - - private Symbol RTT_ANYVAL; - public Symbol RTT_ANYVAL() { - if (RTT_ANYVAL == null) - RTT_ANYVAL = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.AnyVal); - return RTT_ANYVAL; - } - - private Symbol RTT_ALLREF; - public Symbol RTT_ALLREF() { - if (RTT_ALLREF == null) - RTT_ALLREF = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.AllRef); - return RTT_ALLREF; - } - - private Symbol RTT_ALL; - public Symbol RTT_ALL() { - if (RTT_ALL == null) - RTT_ALL = loadTerm(TYPE_CLASS.linkedModule().moduleClass(), Names.All); - return RTT_ALL; - } - - private Symbol TYPECONSTRUCTOR_GETINSTANTIATION; - public Symbol TYPECONSTRUCTOR_GETINSTANTIATION() { - if (TYPECONSTRUCTOR_GETINSTANTIATION == null) { - TYPECONSTRUCTOR_GETINSTANTIATION = - loadTerm(TYPECONSTRUCTOR_CLASS, Names.getInstantiation); - } - return TYPECONSTRUCTOR_GETINSTANTIATION; - } - - private Symbol TYPECONSTRUCTOR_INSTANTIATE; - public Symbol TYPECONSTRUCTOR_INSTANTIATE() { - if (TYPECONSTRUCTOR_INSTANTIATE == null) - TYPECONSTRUCTOR_INSTANTIATE = - loadTerm(TYPECONSTRUCTOR_CLASS, Names.instantiate); - return TYPECONSTRUCTOR_INSTANTIATE; - } - - private Symbol TYPECONSTRUCTOR_FUNCTIONOUTER; - public Symbol TYPECONSTRUCTOR_FUNCTIONOUTER() { - if (TYPECONSTRUCTOR_FUNCTIONOUTER == null) - TYPECONSTRUCTOR_FUNCTIONOUTER = - loadTerm(TYPECONSTRUCTOR_CLASS.linkedModule().moduleClass(), Names.functionOuter); - return TYPECONSTRUCTOR_FUNCTIONOUTER; - } - - private Symbol CLASSTYPE_ISNONTRIVIALINSTANCE; - public Symbol CLASSTYPE_ISNONTRIVIALINSTANCE() { - if (CLASSTYPE_ISNONTRIVIALINSTANCE == null) - CLASSTYPE_ISNONTRIVIALINSTANCE = - loadTerm(CLASSTYPE_CLASS, Names.isNonTrivialInstance); - return CLASSTYPE_ISNONTRIVIALINSTANCE; - } - - private Symbol SCALACLASSTYPE_SETPARENTS; - public Symbol SCALACLASSTYPE_SETPARENTS() { - if (SCALACLASSTYPE_SETPARENTS == null) - SCALACLASSTYPE_SETPARENTS = - loadTerm(SCALACLASSTYPE_CLASS, Names.setParents); - return SCALACLASSTYPE_SETPARENTS; - } - - private Symbol SCALACLASSTYPE_EMPTYARRAY; - public Symbol SCALACLASSTYPE_EMPTYARRAY() { - if (SCALACLASSTYPE_EMPTYARRAY == null) - SCALACLASSTYPE_EMPTYARRAY = - loadTerm(SCALACLASSTYPE_CLASS.linkedModule().moduleClass(), - Names.emptyArray); - return SCALACLASSTYPE_EMPTYARRAY; - } - - private Symbol JAVACLASSTYPE_JAVACLASSTYPE; - public Symbol JAVACLASSTYPE_JAVACLASSTYPE() { - if (JAVACLASSTYPE_JAVACLASSTYPE == null) - JAVACLASSTYPE_JAVACLASSTYPE = - loadTerm(JAVACLASSTYPE_CLASS.linkedModule().moduleClass(), - Names.javaClassType); - return JAVACLASSTYPE_JAVACLASSTYPE; - } - - private Symbol JAVACLASSTYPE_JAVAARRAYTYPE; - public Symbol JAVACLASSTYPE_JAVAARRAYTYPE() { - if (JAVACLASSTYPE_JAVAARRAYTYPE == null) - JAVACLASSTYPE_JAVAARRAYTYPE = - loadTerm(JAVACLASSTYPE_CLASS.linkedModule().moduleClass(), - Names.javaArrayType); - return JAVACLASSTYPE_JAVAARRAYTYPE; - } - - private Symbol JAVAREFARRAYTYPE_JAVAREFARRAYTYPE; - public Symbol JAVAREFARRAYTYPE_JAVAREFARRAYTYPE() { - if (JAVAREFARRAYTYPE_JAVAREFARRAYTYPE == null) - JAVAREFARRAYTYPE_JAVAREFARRAYTYPE = - loadTerm(JAVAREFARRAYTYPE_CLASS.linkedModule().moduleClass(), - Names.javaRefArrayType); - return JAVAREFARRAYTYPE_JAVAREFARRAYTYPE; - } - - // MSIL delegate types - public final Symbol DELEGATE_CLASS; - public final Type DELEGATE_TYPE() { - return DELEGATE_CLASS != null ? DELEGATE_CLASS.staticType() : null; - } - - //######################################################################## - // Public Fields - Global values - - /** The universal pattern */ - public final Symbol PATTERN_WILDCARD; - - //######################################################################## - // Private Fields - Symbol - - private final Symbol void_TYPE; - private final Symbol boolean_TYPE; - private final Symbol byte_TYPE; - private final Symbol short_TYPE; - private final Symbol char_TYPE; - private final Symbol int_TYPE; - private final Symbol long_TYPE; - private final Symbol float_TYPE; - private final Symbol double_TYPE; - private final Symbol array_TYPE; - - //######################################################################## - // Public Constructor - - /** Initializes this instance. */ - public Definitions(Global global) { - // make definitions accessible earlier to other components - global.definitions = this; - // create attributed tree typer - atyper = new ATreeTyper(global, this); - - final boolean forMSIL = global.target == Global.TARGET_MSIL; - - // the root class - ROOT_CLASS = ClassSymbol.newRootClass(global); - - // the java, java.lang and scala packages - JAVALANG = getModule(forMSIL ? "System" : "java.lang"); - SCALA = getModule("scala"); - - // the top and bottom classes - Symbol SCALA_CLASS = SCALA.moduleClass(); - ANY_CLASS = newClass(SCALA_CLASS, Names.Any, 0); - ANYVAL_CLASS = getClass("scala.AnyVal"); - ANYREF_CLASS = newAlias(SCALA_CLASS, Names.AnyRef, 0); - ALLREF_CLASS = newClass(SCALA_CLASS, Names.AllRef, Modifiers.ABSTRACT | Modifiers.FINAL); - ALL_CLASS = newClass(SCALA_CLASS, Names.All, Modifiers.ABSTRACT | Modifiers.FINAL); - - // the java classes - OBJECT_CLASS = getClass(forMSIL ? "System.Object" : "java.lang.Object"); - STRING_CLASS = getClass(forMSIL ? "System.String" : "java.lang.String"); - THROWABLE_CLASS = - getClass(forMSIL ? "System.Exception" : "java.lang.Throwable"); - // .NET delegate class - DELEGATE_CLASS = forMSIL ? getClass("System.MulticastDelegate") : null; - - // the scala value classes - UNIT_CLASS = getClass("scala.Unit"); - BOOLEAN_CLASS = getClass("scala.Boolean"); - BYTE_CLASS = getClass("scala.Byte"); - SHORT_CLASS = getClass("scala.Short"); - CHAR_CLASS = getClass("scala.Char"); - INT_CLASS = getClass("scala.Int"); - LONG_CLASS = getClass("scala.Long"); - FLOAT_CLASS = getClass("scala.Float"); - DOUBLE_CLASS = getClass("scala.Double"); - - // the scala reference classes - SCALAOBJECT_CLASS = getClass("scala.ScalaObject"); - ATTRIBUTE_CLASS = getClass("scala.Attribute"); - REF_CLASS = getClass("scala.Ref"); - for (int i = 1; i < TUPLE_COUNT; i++) { - TUPLE_CLASS[i] = getClass("scala.Tuple" + i); - TUPLE_FIELD[i] = new Symbol[i]; - } - for (int i = 0; i < FUNCTION_COUNT; i++) - FUNCTION_CLASS[i] = getClass("scala.Function" + i); - PARTIALFUNCTION_CLASS = getClass("scala.PartialFunction"); - ITERABLE_CLASS = getClass("scala.Iterable"); - ITERATOR_CLASS = getClass("scala.Iterator"); - SEQ_CLASS = getClass("scala.Seq"); - LIST_CLASS = getClass("scala.List"); - ARRAY_CLASS = getClass("scala.Array"); - TYPE_CLASS = getJVMClass("scala.Type"); - - CLASSTYPE_CLASS = getJVMClass("scala.runtime.types.ClassType"); - JAVACLASSTYPE_CLASS = getJVMClass("scala.runtime.types.JavaClassType"); - JAVAREFARRAYTYPE_CLASS = getJVMClass("scala.runtime.types.JavaRefArrayType"); - SCALACLASSTYPE_CLASS = getJVMClass("scala.runtime.types.ScalaClassType"); - SINGLETYPE_CLASS = getJVMClass("scala.runtime.types.SingleType"); - TYPECONSTRUCTOR_CLASS = getJVMClass("scala.runtime.types.TypeConstructor"); - COMPOUNDTYPE_CLASS = getJVMClass("scala.runtime.types.CompoundType"); - LAZYPARENTS_CLASS = getJVMClass("scala.runtime.types.LazyParents"); - - PREDEF = getModule("scala.Predef"); - CONSOLE = getModule("scala.Console"); - MATCHERROR = getModule("scala.MatchError"); - - SCALA_SERIALIZABLE_CONSTR = getClass("scala.serializable") - .primaryConstructor(); - SCALA_TRANSIENT_CONSTR = getClass("scala.transient") - .primaryConstructor(); - SCALA_VOLATILE_CONSTR = getClass("scala.volatile") - .primaryConstructor(); - SCALA_CLONEABLE_CONSTR = getClass("scala.cloneable") - .primaryConstructor(); - - // initialize generated classes and aliases - initClass(ANY_CLASS, Type.EMPTY_ARRAY); - initAlias(ANYREF_CLASS, OBJECT_TYPE()); - initClass(ALLREF_CLASS, new Type[]{ANYREF_TYPE()}); - initClass(ALL_CLASS, new Type[]{ANY_TYPE()}); - - // create type symbols - void_TYPE = newTypeMethod(Names.Unit ,UNIT_TYPE()); - boolean_TYPE = newTypeMethod(Names.Boolean,BOOLEAN_TYPE()); - byte_TYPE = newTypeMethod(Names.Byte ,BYTE_TYPE()); - short_TYPE = newTypeMethod(Names.Short ,SHORT_TYPE()); - char_TYPE = newTypeMethod(Names.Char ,CHAR_TYPE()); - int_TYPE = newTypeMethod(Names.Int ,INT_TYPE()); - long_TYPE = newTypeMethod(Names.Long ,LONG_TYPE()); - float_TYPE = newTypeMethod(Names.Float ,FLOAT_TYPE()); - double_TYPE = newTypeMethod(Names.Double ,DOUBLE_TYPE()); - array_TYPE = newTypeMethod(Names.Array ,ARRAY_TYPE(ANYREF_TYPE())); - - // add members to scala.Any - ANY_EQEQ = newMethod(ANY_CLASS,Names.EQEQ ,Modifiers.FINAL); - ANY_BANGEQ = newMethod(ANY_CLASS,Names.BANGEQ ,Modifiers.FINAL); - ANY_EQUALS = newMethod(ANY_CLASS,Names.equals ,0); - ANY_HASHCODE = newMethod(ANY_CLASS,Names.hashCode ,0); - ANY_TOSTRING = newMethod(ANY_CLASS,Names.toString ,0); - // ANY_PLUS = newMethod(ANY_CLASS,Names.PLUS ,Modifiers.FINAL); - ANY_IS = newMethod(ANY_CLASS,Names.isInstanceOf,Modifiers.FINAL); - ANY_IS_ERASED= newMethod(ANY_CLASS,Names.isInstanceOfE,Modifiers.FINAL); - ANY_AS = newMethod(ANY_CLASS,Names.asInstanceOf,Modifiers.FINAL); - ANY_AS_ERASED= newMethod(ANY_CLASS,Names.asInstanceOfE,Modifiers.FINAL); - ANY_MATCH = newMethod(ANY_CLASS,Names._match ,Modifiers.FINAL); - - initMethod(ANY_EQEQ , new Type[]{ANY_TYPE()} , boolean_TYPE()); - initMethod(ANY_BANGEQ , new Type[]{ANY_TYPE()} , boolean_TYPE()); - initMethod(ANY_EQUALS , new Type[]{ANY_TYPE()} , boolean_TYPE()); - initMethod(ANY_HASHCODE, new Type[]{} , int_TYPE()); - initMethod(ANY_TOSTRING, new Type[]{} , STRING_TYPE()); - // initMethod(ANY_PLUS , new Type[]{STRING_TYPE()}, STRING_TYPE()); - - Symbol[] ANY_IS_TPARAMS = {newTParam(ANY_IS, 0, ANY_TYPE())}; - ANY_IS.setInfo(Type.PolyType(ANY_IS_TPARAMS, boolean_TYPE())); - Symbol[] ANY_IS_ERASED_TPARAMS = - {newTParam(ANY_IS_ERASED, 0, ANY_TYPE())}; - ANY_IS_ERASED.setInfo(Type.PolyType(ANY_IS_ERASED_TPARAMS, - boolean_TYPE())); - - Symbol[] ANY_AS_TPARAMS = {newTParam(ANY_AS, 0, ANY_TYPE())}; - ANY_AS.setInfo(Type.PolyType(ANY_AS_TPARAMS,ANY_AS_TPARAMS[0].type())); - Symbol[] ANY_AS_ERASED_TPARAMS = - {newTParam(ANY_AS_ERASED, 0, ANY_TYPE())}; - ANY_AS_ERASED.setInfo(Type.PolyType(ANY_AS_ERASED_TPARAMS, - ANY_AS_ERASED_TPARAMS[0].type())); - - Symbol[] ANY_MATCH_TPARAMS = { - newTParam(ANY_MATCH, 0, ANY_TYPE()), - newTParam(ANY_MATCH, 1, ANY_TYPE())}; - Symbol[] ANY_MATCH_VPARAMS = { - newVParam(ANY_MATCH, 0, FUNCTION_TYPE( - new Type[]{ANY_MATCH_TPARAMS[0].type()}, - ANY_MATCH_TPARAMS[1].type()))}; - ANY_MATCH.setInfo( - Type.PolyType( - ANY_MATCH_TPARAMS, - Type.MethodType( - ANY_MATCH_VPARAMS, - ANY_MATCH_TPARAMS[1].type()))); - - // add members to java.lang.Object - OBJECT_EQ = - newMethod(OBJECT_CLASS, Names.eq, Modifiers.FINAL); - OBJECT_NE = - newMethod(OBJECT_CLASS, Names.ne, Modifiers.FINAL); - OBJECT_SYNCHRONIZED = - newMethod(OBJECT_CLASS, Names.synchronized_, Modifiers.FINAL); - - initMethod(OBJECT_EQ, new Type[]{ANYREF_TYPE()}, boolean_TYPE()); - initMethod(OBJECT_NE, new Type[]{ANYREF_TYPE()}, boolean_TYPE()); - Symbol OBJECT_SYNCHRONIZED_TPARAM = - newTParam(OBJECT_SYNCHRONIZED,0,ANY_TYPE()); - Symbol OBJECT_SYNCHRONIZED_VPARAM = - newVParam(OBJECT_SYNCHRONIZED,0,OBJECT_SYNCHRONIZED_TPARAM.type()); - OBJECT_SYNCHRONIZED.setInfo( - Type.PolyType( - new Symbol[] {OBJECT_SYNCHRONIZED_TPARAM}, - Type.MethodType( - new Symbol[] {OBJECT_SYNCHRONIZED_VPARAM}, - OBJECT_SYNCHRONIZED_TPARAM.type()))); - - if (forMSIL) { - OBJECT_CLONE = newMethod(OBJECT_CLASS, Names.clone, Modifiers.PROTECTED); - initMethod(OBJECT_CLONE, Type.EMPTY_ARRAY, ANYREF_TYPE()); - - Symbol WAIT0 = newMethod(OBJECT_CLASS, Names.wait, Modifiers.FINAL); - initMethod(WAIT0, Type.EMPTY_ARRAY, UNIT_TYPE()); - - Symbol WAIT1 = newMethod(OBJECT_CLASS, Names.wait, Modifiers.FINAL); - initMethod(WAIT1, new Type[]{LONG_TYPE()}, UNIT_TYPE()); - - Symbol WAIT2 = newMethod(OBJECT_CLASS, Names.wait, Modifiers.FINAL); - initMethod(WAIT2, new Type[]{LONG_TYPE(), INT_TYPE()}, UNIT_TYPE()); - - Symbol NOTIFY = - newMethod(OBJECT_CLASS, Names.notify, Modifiers.FINAL); - initMethod(NOTIFY, Type.EMPTY_ARRAY, UNIT_TYPE()); - - Symbol NOTIFY_ALL = - newMethod(OBJECT_CLASS, Names.notifyAll, Modifiers.FINAL); - initMethod(NOTIFY_ALL, Type.EMPTY_ARRAY, UNIT_TYPE()); - } else { - OBJECT_CLONE = null; - } - - // add members to java.lang.String - STRING_PLUS = newMethod(STRING_CLASS, Names.PLUS, Modifiers.FINAL); - initMethod(STRING_PLUS, new Type[]{ANY_TYPE()}, STRING_TYPE()); - - if (forMSIL) { - Symbol s = newMethod(STRING_CLASS, Name.fromString("length"), 0); - initMethod(s, Type.EMPTY_ARRAY, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("compareTo"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("charAt"), 0); - initMethod(s, new Type[] {INT_TYPE()}, CHAR_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("concat"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {INT_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("indexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {INT_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("lastIndexOf"), 0); - initMethod(s, new Type[] {STRING_TYPE(), INT_TYPE()}, INT_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("toLowerCase"), 0); - initMethod(s, Type.EMPTY_ARRAY, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("toUpperCase"), 0); - initMethod(s, Type.EMPTY_ARRAY, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("startsWith"), 0); - initMethod(s, new Type[]{STRING_TYPE()}, BOOLEAN_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("endsWith"), 0); - initMethod(s, new Type[]{STRING_TYPE()}, BOOLEAN_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("substring"), 0); - initMethod(s, new Type[]{INT_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("substring"), 0); - initMethod(s, new Type[]{INT_TYPE(), INT_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("intern"), 0); - initMethod(s, Type.EMPTY_ARRAY, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("replace"), 0); - initMethod(s, new Type[]{CHAR_TYPE(), CHAR_TYPE()}, STRING_TYPE()); - - s = newMethod(STRING_CLASS, Name.fromString("toCharArray"), 0); - initMethod(s, Type.EMPTY_ARRAY, array_TYPE(CHAR_TYPE())); - } - - // add members to java.lang.Throwable - THROWABLE_THROW = - newMethod(THROWABLE_CLASS, Names.throw_, Modifiers.FINAL); - THROWABLE_THROW.setInfo(Type.PolyType(Symbol.EMPTY_ARRAY, ALL_TYPE())); - - // create global values - PATTERN_WILDCARD = Symbol.NONE.newTerm( - Position.NOPOS, 0, Names.PATTERN_WILDCARD); - PATTERN_WILDCARD.setInfo(ALL_TYPE()); - - // initialize unboxed types in class Type - Type.initializeUnboxedTypes(this); - } - - //######################################################################## - // Public Methods - - /** Returns the symbol of the module with the given fullname. */ - public Symbol getModule(String fullname) { - Scope scope = ROOT_CLASS.members(); - int i = 0; - int j = fullname.indexOf('.', i); - while (j >= 0) { - Name name = Name.fromString(fullname.substring(i, j)); - scope = scope.lookup(name).members(); - i = j + 1; - j = fullname.indexOf('.', i); - } - Name name = Name.fromString(fullname.substring(i, fullname.length())); - Symbol sym = scope.lookup(name); - if (!sym.isModule()) { - switch (sym.type()) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int k = 0; k < alts.length; k++) - if ((sym = alts[k]).isModule()) break; - } - } - return sym; - } - - /** Returns the symbol of the class with the given fullname. */ - public Symbol getClass(String fullname) { - Scope scope = ROOT_CLASS.members(); - int i = 0; - int j = fullname.indexOf('.', i); - while (j >= 0) { - Name name = Name.fromString(fullname.substring(i, j)); - scope = scope.lookup(name).members(); - i = j + 1; - j = fullname.indexOf('.', i); - } - Name name = Name.fromString(fullname.substring(i, fullname.length())); - Symbol sym = scope.lookup(name.toTypeName()); - assert sym.kind != Kinds.NONE : "no class '" + fullname + "'"; - return sym; - } - - private Symbol getJVMClass(String fullname) { - return Global.instance.target == Global.TARGET_MSIL ? null : - getClass(fullname); - } - - //######################################################################## - // Private Methods - - /** Creates a new class */ - private Symbol newClass(Symbol owner, Name name, int flags) { - name = name.toTypeName(); - Symbol clasz = owner.newClass(Position.NOPOS, flags, name); - owner.members().enter(clasz); - return clasz; - } - - /** Creates a new type alias */ - private Symbol newAlias(Symbol owner, Name name, int flags) { - name = name.toTypeName(); - Symbol alias = owner.newTypeAlias(Position.NOPOS, flags, name); - owner.members().enter(alias); - return alias; - } - - /** Creates a new method */ - private Symbol newMethod(Symbol owner, Name name, int flags) { - assert owner.isClassType(): Debug.show(owner) + " -- " + name; - Symbol term = owner.newMethod(Position.NOPOS, flags, name); - owner.members().enterOrOverload(term); - return term; - } - - /** Creates a new type parameter */ - private Symbol newTParam(Symbol owner, int index, Type bound) { - Name name = Name.fromString("T" + index).toTypeName(); - return owner.newTParam(Position.NOPOS, 0, name, bound); - } - - /** Creates a new value parameter */ - private Symbol newVParam(Symbol owner, int index, Type type) { - Name name = Name.fromString("v" + index); - return owner.newVParam(Position.NOPOS, 0, name, type); - } - - /** Creates a new type method */ - private Symbol newTypeMethod(Name name, Type type) { - Symbol symbol = ANY_CLASS.newMethod(Position.NOPOS, 0, name); - initMethod(symbol, Type.EMPTY_ARRAY, type); - return symbol; - } - - /** Initializes the given class */ - private void initClass(Symbol clasz, Type[] parents) { - clasz.setInfo(Type.compoundType(parents, new Scope(), clasz)); - clasz.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor())); - } - - /** Initializes the given type alias */ - private void initAlias(Symbol alias, Type aliased) { - alias.setInfo(aliased); - alias.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, aliased)); - } - - /** Initializes the given method */ - private void initMethod(Symbol method, Type[] vargs, Type result) { - Symbol[] vparams = new Symbol[vargs.length]; - for (int i = 0; i < vargs.length; i++) - vparams[i] = newVParam(method, i, vargs[i]); - method.setInfo(Type.MethodType(vparams, result)); - } - - /** Returns the term member of given class with given name. */ - private Symbol loadTerm(Symbol clasz, Name name) { - Symbol sym = clasz.lookup(name); - assert sym.isTerm(): clasz+"."+name+" -> "+sym; - assert !sym.isOverloaded(): clasz+"."+name+" -> "+sym; - return sym; - } - - /** - * Returns the term member of given class with given name and - * value argument types. - */ - private Symbol loadTerm(Symbol clasz, Name name, Type[] vargs) { - Symbol sym = clasz.lookup(name); - assert sym.isTerm(): Debug.show(clasz, name, vargs, sym); - Symbol[] alts = sym.alternativeSymbols(); - for (int i = 0; i < alts.length; i++) { - switch (alts[i].type()) { - case PolyType(_, MethodType(Symbol[] vparams, _)): - if (Type.isSameAs(Symbol.type(vparams), vargs)) return alts[i]; - continue; - case MethodType(Symbol[] vparams, _): - if (Type.isSameAs(Symbol.type(vparams), vargs)) return alts[i]; - continue; - } - } - throw Debug.abort(Debug.show(clasz, name, vargs, alts)); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java deleted file mode 100644 index ca6f0bd294..0000000000 --- a/sources/scalac/symtab/EntryTags.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id: EntryTags.java - -package scalac.symtab; - -public interface EntryTags { - -/*************************************************** - * Symbol table attribute format: - * Symtab = nentries_Nat {Entry} - * Entry = 1 TERMNAME len_Nat NameInfo - * | 2 TYPENAME len_Nat NameInfo - * | 3 NUMBER lenNat NumInfo - * | 4 NONEsym len_Nat - * | 5 TYPEsym len_Nat SymbolInfo lobound_Ref - * | 6 ALIASsym len_Nat SymbolInfo constrsym_Ref - * | 7 CLASSsym len_Nat SymbolInfo [modulesym_Ref] - * thistype_Ref constrsym_Ref - * | 8 VALsym len_Nat SymbolInfo [classsym_Ref] - * | 9 EXTref len_Nat name_Ref [owner_Ref] - * | 10 EXTMODCLASSref len_Nat name_Ref [owner_Ref] - * | 11 NOtpe len_Nat - * | 12 THIStpe len_Nat sym_Ref - * | 13 SINGLEtpe len_Nat type_Ref sym_Ref - * | 14 CONSTANTtpe len_Nat type_Ref constant_Ref - * | 15 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} - * | 16 COMPOUNDtpe len_Nat - * iscompoundsym_Byte [owner_Ref] classsym_Ref {tpe_Ref} - * | 17 METHODtpe len_Nat tpe_Ref {tpe_Ref} - * | 18 POLYTtpe len_Nat tpe_Ref {sym_Ref} - * | 19 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref} - * | 22 FLAGGEDtpe len_Nat flags_Nat tpe_Ref - * | 24 LITERALunit len_Nat - * | 25 LITERALboolean len_Nat value_Byte - * | 26 LITERALbyte len_Nat value_Long - * | 27 LITERALshort len_Nat value_Long - * | 28 LITERALchar len_Nat value_Long - * | 29 LITERALint len_Nat value_Long - * | 30 LITERALlong len_Nat value_Long - * | 31 LITERALfloat len_Nat value_Long - * | 32 LITERALdouble len_Nat value_Long - * | 33 LITERALstring len_Nat name_Ref - * | 34 LITERALnull len_Nat - * | 35 LITERALzero len_Nat - * SymbolInfo = name_Ref owner_Ref flags_Nat info_Ref - * NameInfo = <character sequence of length len_Nat in Utf8 format> - * NumInfo = <len_Nat-byte signed number in big endian format> - * Ref = Nat - * - * len is remaining length after `len'. - */ - - int TERMname = 1, - TYPEname = 2, - NONEsym = 4, - TYPEsym = 5, - ALIASsym = 6, - CLASSsym = 7, - VALsym = 8, - EXTref = 9, - EXTMODCLASSref = 10, - NOtpe = 11, - THIStpe = 12, - SINGLEtpe = 13, - CONSTANTtpe = 14, - TYPEREFtpe = 15, - COMPOUNDtpe = 16, - METHODtpe = 17, - POLYtpe = 18, - OVERLOADEDtpe = 19, - UNBOXEDtpe = 20, - UNBOXEDARRAYtpe = 21, - FLAGGEDtpe = 22, - ERRORtpe = 23, - LITERALunit = 24, - LITERALboolean = 25, - LITERALbyte = 26, - LITERALshort = 27, - LITERALchar = 28, - LITERALint = 29, - LITERALlong = 30, - LITERALfloat = 31, - LITERALdouble = 32, - LITERALstring = 33, - LITERALnull = 34, - LITERALzero = 35, - NOpre = 36; - - int firstSymTag = NONEsym, lastSymTag = VALsym; - int firstTypeTag = NOtpe, lastTypeTag = FLAGGEDtpe; - -// flag encodings - - int REPEATEDflag = 4, DEFflag = 8; -} diff --git a/sources/scalac/symtab/Kinds.java b/sources/scalac/symtab/Kinds.java deleted file mode 100644 index b99c8fa8d0..0000000000 --- a/sources/scalac/symtab/Kinds.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - - -public interface Kinds { - - /** kind of non-existent symbol - */ - int NONE = 1; - - /** definition kinds - */ - int ALIAS = 2; - int CLASS = 3; - int TYPE = 4; - int VAL = 5; -} diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java deleted file mode 100644 index ab222e723f..0000000000 --- a/sources/scalac/symtab/Modifiers.java +++ /dev/null @@ -1,154 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -public interface Modifiers { - - // modifiers - int DEFERRED = 0x00000001; // was `abstract' for members - int FINAL = 0x00000002; - int PRIVATE = 0x00000004; - int PROTECTED = 0x00000008; - - int SEALED = 0x00000010; - int OVERRIDE = 0x00000020; - int CASE = 0x00000040; - int ABSTRACT = 0x00000080; // abstract class, or used in conjunction - // with abstract override. - // Note difference to DEFERRED! - - int DEF = 0x00000100; // a def parameter - int REPEATED = 0x00000200; // a repeated parameter - int SYNTHETIC = 0x00000400; - int DEPRECATED = 0x00000800; - - int JAVA = 0x00001000; // symbol was defined by a Java class - int MODUL = 0x00002000; // symbol is module or class implementing a module - int MUTABLE = 0x00004000; // symbol is a mutable variable. - int VIEWBOUND = 0x00004000; // type symbol has a <% bound. - int PARAM = 0x00008000; // symbol is a (type) parameter to a method - - int INITIALIZED = 0x00010000; // symbol's definition is complete - int LOCKED = 0x00020000; // temporary flag to catch cyclic dependencies - int ACCESSED = 0x00040000; // symbol was accessed at least once - int SELECTOR = 0x00080000; // symbol was used as selector in Select - - int PACKAGE = 0x00100000; // symbol is a java package. - int STABLE = 0x00800000; // functions that are assumed to be stable - // (typically, access methods for valdefs) - - int CAPTURED = 0x01000000; // variables is accessed from - // nested function. Set by LambdaLift - int INCONSTRUCTOR = 0x01000000; // transient flag for Analyzer - int PARAMACCESSOR = 0x02000000; // for methods: is an access method for a val parameter - // for parameters: is a val parameter - int CLOSURELOCK = PARAMACCESSOR; - // secondary meaning: a lock to test that closures of type - // symbols are non-cyclic. - - int ACCESSOR = 0x04000000; // function is an access function for a - // value or variable - int BRIDGE = 0x08000000; // function is a bridge method. - int LIFTED = BRIDGE; // transient flag for lambdalift - int ALTERNATIVE = BRIDGE; // transient flag for pickle/unpickle - int SNDTIME = BRIDGE; // debug - - int INTERFACE = 0x10000000; // symbol is a Java interface - int TRAIT = 0x20000000; // symbol is a Trait - - int COVARIANT = 0x40000000; // symbol is a covariant type variable - int CONTRAVARIANT = 0x80000000; // symbol is a contravariant type variable - - // masks - int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT | COVARIANT | CONTRAVARIANT; // these modifiers can be set in source programs. - int ACCESSFLAGS = PRIVATE | PROTECTED; - int VARIANCES = COVARIANT | CONTRAVARIANT; - int CONSTRFLAGS = CASE | JAVA; - /** Module flags inherited by their module-class */ - int MODULE2CLASSFLAGS = ACCESSFLAGS | DEPRECATED | SYNTHETIC | JAVA | PACKAGE | CASE; - - public static class Helper { - - public static boolean isAbstract(int flags) { - // todo: ABSTRACT and DEFERRED should be separated. - return (flags & DEFERRED) != 0 || - (flags & (ABSTRACT | OVERRIDE)) == ABSTRACT; - } - - public static boolean isFinal(int flags) { - return (flags & FINAL) != 0; - } - - public static boolean isPrivate(int flags) { - return (flags & PRIVATE) != 0; - } - - public static boolean isProtected(int flags) { - return (flags & PROTECTED) != 0; - } - - public static boolean isSealed(int flags) { - return (flags & SEALED) != 0; - } - - public static boolean isOverride(int flags) { - return (flags & OVERRIDE) != 0; - } - - public static boolean isCase(int flags) { - return (flags & CASE) != 0; - } - - public static boolean isCaseAccessor(int flags) { - return (flags & PARAMACCESSOR) != 0; - } - - public static boolean isInterface(int flags) { - return (flags & INTERFACE) != 0; - } - - public static boolean isDef(int flags) { - return (flags & DEF) != 0; - } - - public static boolean isModClass(int flags) { - return (flags & MODUL) != 0; - } - - public static boolean isJava(int flags) { - return (flags & JAVA) != 0; - } - - public static boolean isNoVal(int flags) { - return (flags & PACKAGE) != 0; - } - - public static String toString(int flags) { - StringBuffer buffer = new StringBuffer(); - toString(buffer, flags); - return buffer.toString(); - } - - public static void toString(StringBuffer buffer, int flags) { - //buffer.append(flags).append(": ");//debug - int marker = buffer.length(); - if (isPrivate(flags)) buffer.append("private "); - if (isProtected(flags)) buffer.append("protected "); - if (isAbstract(flags)) buffer.append("abstract "); - if (isFinal(flags)) buffer.append("final "); - if (isSealed(flags)) buffer.append("sealed "); - if (isInterface(flags)) buffer.append("interface "); - if (isCase(flags)) buffer.append("case "); - if (isDef(flags)) buffer.append("def "); - if (isOverride(flags)) buffer.append("override "); - int length = buffer.length(); - buffer.setLength(length - (length == marker ? 0 : 1)); - } - } -} diff --git a/sources/scalac/symtab/Scope.java b/sources/scalac/symtab/Scope.java deleted file mode 100644 index 7206a9ca02..0000000000 --- a/sources/scalac/symtab/Scope.java +++ /dev/null @@ -1,332 +0,0 @@ - /* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -import scalac.util.*; -import scalac.ApplicationError; - -public class Scope { - - public abstract static class SymbolIterator { - public abstract boolean hasNext(); - public abstract Symbol next(); - } - - public static class Entry { - - /** the absent entry - */ - public static final Entry NONE = new Entry(); - - /** the symbol of the entry (this is the symbol containing the name) - */ - public Symbol sym; - - /** the next entry in the hash bucket - */ - public Entry tail; - - /** the next entry in this scope - */ - private Entry next; - - /** The owner of the entry; - */ - public final Scope owner; - - public Entry(Symbol sym, Scope owner) { - this.sym = sym; - this.owner = owner; - this.next = owner.elems; - if (sym == null) throw new ApplicationError(); - owner.elems = this; - } - - private Entry() { - this.sym = Symbol.NONE; - this.owner = null; - } - - public Entry setSymbol(Symbol sym) { - this.sym = sym; - owner.elemsCache = null; - return this; - } - - public int hashCode() { - return sym.name.index; - } - - public String toString() { - return sym.toString(); - } - } - - /** all elements of this scope - */ - private Entry elems; - - /** the hash table - */ - private Entry[] hashtable; - - /** a cache for all elements, to be used by symbol iterator. - */ - private Symbol[] elemsCache = null; - - public Symbol[] getElemsCache() { - return elemsCache; - } - - /** size and mask of hash tables - * todo: make hashtables grow? - */ - private final int HASHSIZE = 0x80; - private final int HASHMASK = 0x7f; - - /** the threshold number of entries from which a hashtable is constructed. - */ - private final int MIN_HASH = 6; - - /** construct a new name space - */ - public Scope() { - this.elems = Entry.NONE; - } - - public Scope(Entry elems) { - this.elems = elems; - if (size() >= MIN_HASH) createHash(); - } - - public Scope(Scope base) { - this.elems = base.elems; - if (base.hashtable != null) { - this.hashtable = new Entry[HASHSIZE]; - for (int i = 0; i < HASHSIZE; i++) - hashtable[i] = base.hashtable[i]; - } - } - - public Scope(Symbol[] members) { - this(); - for (int i = 0; i < members.length; i++) - enter(members[i]); - } - - /** Returns a new scope with the same content as this one. */ - public Scope cloneScope() { - int size = 0; - Scope clone = new Scope(); - for (Entry e = elems; e != Entry.NONE; e = e.next, size++) - new Entry(e.sym, clone); - if (size >= MIN_HASH) clone.createHash(); - return clone; - } - - /** is the scope empty? - */ - public boolean isEmpty() { - return elems == Entry.NONE; - } - - /** the number of entries in this scope - */ - int size() { - int s = 0; - for (Entry e = elems; e != Entry.NONE; e = e.next) s++; - return s; - } - - public Scope enter(Entry e) { - assert this != Scope.EMPTY: Debug.show(e.sym); - elems = e; - elemsCache = null; - if (hashtable != null) { - int i = e.sym.name.index & HASHMASK; - elems.tail = hashtable[i]; - hashtable[i] = elems; - } else if (size() >= MIN_HASH) { - createHash(); - } - return this; - } - - /** enter a symbol - */ - public Scope enter(Symbol sym) { - // assert !sym.isConstructor(); - return enter(new Entry(sym, this)); - } - - public final Scope enterNoHide(Symbol sym) { - assert lookupEntry(sym.name) == Entry.NONE: - sym + " hides " + lookup(sym.name); - return enter(sym); - } - - public Scope enterOrOverload(Symbol sym) { - Entry e = lookupEntry(sym.name); - if (e.owner == this/* && (sym.flags & Modifiers.PRIVATE) == 0*/) { - e.setSymbol(e.sym.overloadWith(sym)); - return this; - } else { - return enter(sym); - } - } - - private void createHash() { - hashtable = new Entry[HASHSIZE]; - for (int i = 0; i < HASHSIZE; i++) - hashtable[i] = Entry.NONE; - enterInHash(elems); - } - - private void enterInHash(Entry e) { - if (e != Entry.NONE) { - enterInHash(e.next); - int i = e.sym.name.index & HASHMASK; - e.tail = hashtable[i]; - hashtable[i] = e; - } - } - - /** remove entry - */ - public void unlink(Entry e) { - if (elems == e) { - elems = e.next; - } else { - Entry e1 = elems; - while (e1.next != e) e1 = e1.next; - e1.next = e.next; - } - if (hashtable != null) { - Entry e1 = hashtable[e.sym.name.index & HASHMASK]; - if (e1 == e) { - hashtable[e.sym.name.index & HASHMASK] = e.tail; - } else { - while (e1.tail != e) e1 = e1.tail; - e1.tail = e.tail; - } - } - elemsCache = null; - } - - public boolean contains(Symbol sym) { - Entry e = lookupEntry(sym.name); - if (e.sym == sym) return true; - switch (e.sym.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i] == sym) return true; - } - return false; - } - - /** lookup a symbol - */ - public Symbol lookup(Name name) { - return lookupEntry(name).sym; - } - - /** lookup a symbol entry. - */ - public Entry lookupEntry(Name name) { - Entry e; - if (hashtable != null) { - e = hashtable[name.index & HASHMASK]; - while (e != Entry.NONE && e.sym.name != name) e = e.tail; - } else { - e = elems; - while (e != Entry.NONE && e.sym.name != name) e = e.next; - } - return e; - } - - /** return all symbols as an array, - * in the order they were entered in this scope. - */ - public Symbol[] elements() { - if (elemsCache == null) { - int s = size(); - elemsCache = new Symbol[s]; - for (Entry e = elems; e != Entry.NONE; e = e.next) - elemsCache[--s] = e.sym; - } - return elemsCache; - } - - class MySymbolIterator extends SymbolIterator { - private Symbol[] alternatives = Symbol.EMPTY_ARRAY; - private int altindex = 0; - private int elemindex = 0; - - public MySymbolIterator() { - elements(); - } - - public boolean hasNext() { - return altindex < alternatives.length || - elemindex < elemsCache.length; - } - - public Symbol next() { - if (altindex < alternatives.length) - return alternatives[altindex++]; - else { - Symbol sym = elemsCache[elemindex++]; - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): - alternatives = alts; - altindex = 0; - return next(); - default: - return sym; - } - } - } - } - - /** return all symbols as an iterator, - * in the order they were entered in this scope. - */ - public SymbolIterator iterator() { - return new MySymbolIterator(); - } - - - public String toString() { - return new SymbolTablePrinter().printScope(this).toString(); - } - - public static Scope EMPTY = new Scope(); -} - -public class ErrorScope extends Scope { - - private final Symbol owner; - - public ErrorScope(Symbol owner) { - this.owner = owner; - } - - public Entry lookupEntry(Name name) { - Entry entry = super.lookupEntry(name); - if (entry.sym.isNone()) { - Symbol symbol = name.isTermName() - ? owner.newErrorValue(name) - : owner.newErrorClass(name); - enter(symbol); - entry = super.lookupEntry(name); - } - return entry; - } - -} diff --git a/sources/scalac/symtab/SourceCompleter.java b/sources/scalac/symtab/SourceCompleter.java deleted file mode 100644 index 73596724bd..0000000000 --- a/sources/scalac/symtab/SourceCompleter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Symbol; - -/** This class implements a SymbolLoader that reads a source file. */ -public class SourceCompleter extends SymbolLoader { - - //######################################################################## - // Private Fields - - /** The source file to read */ - private final AbstractFile file; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with the specified source file. */ - public SourceCompleter(Global global, AbstractFile file) { - super(global); - this.file = file; - } - - //######################################################################## - // Protected Methods - - /** Completes the specified symbol by reading the source file. */ - protected String doComplete(Symbol root) throws IOException { - global.compileLate(global.getSourceFile(file), false); - return "source file '" + file + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymSet.java b/sources/scalac/symtab/SymSet.java deleted file mode 100644 index 0f91985386..0000000000 --- a/sources/scalac/symtab/SymSet.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -/** Sets of symbols, implemented as binary trees. - */ -public class SymSet { - private SymSet l, r; - private Symbol sym; - - public SymSet() {} - - private SymSet(Symbol sym, SymSet l, SymSet r) { - this.sym = sym; this.l = l; this.r = r; - } - - /** Union of this set and `{sym}'. - */ - public SymSet incl(Symbol sym) { - if (this == EMPTY) { - return new SymSet(sym, EMPTY, EMPTY); - } else if (sym == this.sym) { - return this; - } else if (less(sym, this.sym)) { - return new SymSet(this.sym, l.incl(sym), r); - } else { - assert less(this.sym, sym); - return new SymSet(this.sym, l, r.incl(sym)); - } - } - - /** Remove the element <code>sym</code> from the symbol set - */ - public SymSet excl(Symbol sym) { - if (sym == this.sym) { - if (l == EMPTY) return r; - if (r == EMPTY) return l; - SymSet m = r; - if (m.l != EMPTY) { - SymSet p; - do { - p = m; - m = m.l; - } while (m.l != EMPTY); - p.l = m.r; - m.r = r; - } - m.l = l; - return m; - } else if (less(sym, this.sym)) { - return new SymSet(this.sym, l.excl(sym), r); - } else { - assert less(this.sym, sym); - return new SymSet(this.sym, l, r.excl(sym)); - } - } - - /** Is `sym' an element of this set? - */ - public boolean contains(Symbol sym) { - if (this == EMPTY) { - return false; - } else if (sym == this.sym) { - return true; - } else if (less(sym, this.sym)) { - return l.contains(sym); - } else { - assert less(this.sym, sym); - return r.contains(sym); - } - } - - /** The number of elements in ths set. - */ - public int size() { - if (this == EMPTY) { - return 0; - } else { - return 1 + l.size() + r.size(); - } - } - - /** Copy elements of this set into `ss', starting at index `from'. - * Return index one past last element copied. - */ - public int copyToArray(Symbol[] ss, int from) { - if (this == EMPTY) { - return from; - } else { - from = l.copyToArray(ss, from); - ss[from] = sym; - return r.copyToArray(ss, from + 1); - } - } - - /** Return all elements of this set as an array. - */ - public Symbol[] toArray() { - int s = size(); - if (s == 0) return Symbol.EMPTY_ARRAY; - Symbol[] ss = new Symbol[s]; - copyToArray(ss, 0); - return ss; - } - - /** The empty set. - */ - public final static SymSet EMPTY = new SymSet(); - - private boolean less(Symbol s1, Symbol s2) { - return s1.isLess(s2); - } -} diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java deleted file mode 100644 index ad3710ff82..0000000000 --- a/sources/scalac/symtab/Symbol.java +++ /dev/null @@ -1,2573 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -//todo check significance of JAVA flag. - -package scalac.symtab; - -import scala.tools.util.AbstractFile; -import scala.tools.util.Position; - -import scalac.ApplicationError; -import scalac.CompilationUnit; -import scalac.Global; -import scalac.Phase; -import scalac.framework.History; -import scalac.util.ArrayApply; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.NameTransformer; - - -public abstract class Symbol implements Modifiers, Kinds { - - /** An empty symbol array */ - public static final Symbol[] EMPTY_ARRAY = new Symbol[0]; - - /** An empty array of symbol arrays */ - public static final Symbol[][] EMPTY_ARRAY_ARRAY = new Symbol[0][]; - - /** The absent symbol */ - public static final Symbol NONE = new NoSymbol(); - -// Attribues ------------------------------------------------------------- - - public static final int IS_ROOT = 0x00000001; - public static final int IS_ANONYMOUS = 0x00000002; - public static final int IS_LABEL = 0x00000010; - public static final int IS_CONSTRUCTOR = 0x00000020; - public static final int IS_ACCESSMETHOD = 0x00000100; - public static final int IS_STATIC = 0x00000200; - public static final int IS_ERROR = 0x10000000; - public static final int IS_THISTYPE = 0x20000000; - public static final int IS_LOCALDUMMY = 0x40000000; - public static final int IS_COMPOUND = 0x80000000; - -// Fields ------------------------------------------------------------- - - /** The unique identifier generator */ - private static int ids; - - /** The kind of the symbol */ - public int kind; - - /** The position of the symbol */ - public int pos; - - /** The name of the symbol */ - public Name name; - - /** The modifiers of the symbol */ - public int flags; - - /** The owner of the symbol */ - private Symbol owner; - - /** The infos of the symbol */ - private TypeIntervalList infos; - - /** The attributes of the symbol */ - private final int attrs; - - /** The unique identifier */ - public final int id; - - -// Constructors ----------------------------------------------------------- - - /** Generic symbol constructor */ - public Symbol(int kind, Symbol owner, int pos, int flags, Name name, int attrs) { - this.kind = kind; - this.pos = pos; - this.name = name; - this.owner = owner == null ? this : owner; - this.flags = flags & ~(INITIALIZED | LOCKED); // safety first - this.attrs = attrs; - this.id = ids++; - } - -// Factories -------------------------------------------------------------- - - /** Creates a new term owned by this symbol. */ - public final Symbol newTerm(int pos, int flags, Name name) { - return newTerm(pos, flags, name, 0); - } - - /** Creates a new constructor of this symbol. */ - public final Symbol newConstructor(int pos, int flags) { - assert isType(): Debug.show(this); - return new ConstructorSymbol(this, pos, flags); - } - - /** Creates a new method owned by this symbol. */ - public final Symbol newMethod(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new static method owned by this symbol. */ - public final Symbol newStaticMethod(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, IS_STATIC); - } - - /** Creates a new access method owned by this symbol. */ - public final Symbol newAccessMethod(int pos, Name name) { - assert isClass(): Debug.show(this); - int flags = PRIVATE | FINAL | SYNTHETIC; - return newTerm(pos, flags, name, IS_ACCESSMETHOD); - } - - /** Creates a new function owned by this symbol. */ - public final Symbol newFunction(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new method or function owned by this symbol. */ - public final Symbol newMethodOrFunction(int pos, int flags, Name name){ - assert isClass() || isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new label owned by this symbol. */ - public final Symbol newLabel(int pos, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, 0, name, IS_LABEL); - } - - /** Creates a new field owned by this symbol. */ - public final Symbol newField(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new static field owned by this symbol. */ - public final Symbol newStaticField(int pos, int flags, Name name) { - assert isClass(): Debug.show(this); - return newTerm(pos, flags, name, IS_STATIC); - } - - /** Creates a new variable owned by this symbol. */ - public final Symbol newVariable(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new variable owned by this symbol. */ - public final Symbol newFieldOrVariable(int pos, int flags, Name name) { - assert isClass() || isTerm(): Debug.show(this); - return newTerm(pos, flags, name, 0); - } - - /** Creates a new pattern variable owned by this symbol. */ - public final Symbol newPatternVariable(int pos, Name name) { - return newVariable(pos, 0, name); - } - - /** Creates a new value parameter owned by this symbol. */ - public final Symbol newVParam(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newTerm(pos, flags | PARAM, name); - } - - /** - * Creates a new value parameter owned by this symbol and - * initializes it with the type. - */ - public final Symbol newVParam(int pos, int flags, Name name, Type type) { - Symbol tparam = newVParam(pos, flags, name); - tparam.setInfo(type); - return tparam; - } - - /** - * Creates a new initialized dummy symbol for template of this - * class. - */ - public final Symbol newLocalDummy() { - assert isClass(): Debug.show(this); - Symbol local = newTerm(pos, 0, Names.LOCAL(this), IS_LOCALDUMMY); - local.setInfo(Type.NoType); - return local; - } - - /** Creates a new module owned by this symbol. */ - public final Symbol newModule(int pos, int flags, Name name) { - return new ModuleSymbol(this, pos, flags, name); - } - - /** - * Creates a new package owned by this symbol and initializes it - * with an empty scope. - */ - public final Symbol newPackage(int pos, Name name) { - return newPackage(pos, name, null); - } - - /** - * Creates a new package owned by this symbol, initializes it with - * the loader and enters it in the scope if it's non-null. - */ - public final Symbol newLoadedPackage(Name name, SymbolLoader loader, - Scope scope, SymbolOrigin origin) - { - assert loader != null: Debug.show(this) + " - " + name; - Symbol peckage = newPackage(Position.NOPOS, name, loader); - peckage.moduleClass().setOrigin(origin); - if (scope != null) scope.enterNoHide(peckage); - return peckage; - } - - /** - * Creates a new error value owned by this symbol and initializes - * it with an error type. - */ - public Symbol newErrorValue(Name name) { - Symbol symbol = newTerm(pos, SYNTHETIC, name, IS_ERROR); - symbol.setInfo(Type.ErrorType); - return symbol; - } - - /** Creates a new type alias owned by this symbol. */ - public final Symbol newTypeAlias(int pos, int flags, Name name) { - return new AliasTypeSymbol(this, pos, flags, name, 0); - } - - /** Creates a new abstract type owned by this symbol. */ - public final Symbol newAbstractType(int pos, int flags, Name name) { - return new AbsTypeSymbol(this, pos, flags, name, 0); - } - - /** Creates a new type parameter owned by this symbol. */ - public final Symbol newTParam(int pos, int flags, Name name) { - assert isTerm(): Debug.show(this); - return newAbstractType(pos, flags | PARAM, name); - } - - /** - * Creates a new type parameter owned by this symbol and - * initializes it with the type. - */ - public final Symbol newTParam(int pos, int flags, Name name, Type type) { - Symbol tparam = newTParam(pos, flags, name); - tparam.setInfo(type); - return tparam; - } - - /** - * Creates a new type alias owned by this symbol and initializes - * it with the info. - */ - public final Symbol newTypeAlias(int pos, int flags, Name name, Type info){ - Symbol alias = newTypeAlias(pos, flags, name); - alias.setInfo(info); - alias.allConstructors().setInfo(Type.MethodType(EMPTY_ARRAY, info)); - return alias; - } - - /** Creates a new class owned by this symbol. */ - public final ClassSymbol newClass(int pos, int flags, Name name) { - return newClass(pos, flags, name, 0); - } - - /** Creates a new anonymous class owned by this symbol. */ - public final ClassSymbol newAnonymousClass(int pos, Name name) { - assert isTerm(): Debug.show(this); - return newClass(pos, 0, name, IS_ANONYMOUS); - } - - /** - * Creates a new class with a linked module, both owned by this - * symbol, initializes them with the loader and enters the class - * and the module in the scope if it's non-null. - */ - public final ClassSymbol newLoadedClass(int flags, Name name, - SymbolLoader loader, Scope scope, SymbolOrigin origin) - { - assert loader != null: Debug.show(this) + " - " + name; - ClassSymbol clasz = new LinkedClassSymbol(this, flags, name); - clasz.setInfo(loader); - clasz.setOrigin(origin); - clasz.allConstructors().setInfo(loader); - clasz.linkedModule().setInfo(loader); - clasz.linkedModule().moduleClass().setInfo(loader); - clasz.linkedModule().moduleClass().setOrigin(origin); - if (scope != null) scope.enterNoHide(clasz); - if (scope != null) scope.enterNoHide(clasz.linkedModule()); - return clasz; - } - - /** - * Creates a new error class owned by this symbol and initializes - * it with an error type. - */ - public ClassSymbol newErrorClass(Name name) { - ClassSymbol symbol = newClass(pos, SYNTHETIC, name, IS_ERROR); - Scope scope = new ErrorScope(this); - symbol.setInfo(Type.compoundType(Type.EMPTY_ARRAY, scope, this)); - symbol.allConstructors().setInfo(Type.ErrorType); - return symbol; - } - - /** Creates a new term owned by this symbol. */ - final Symbol newTerm(int pos, int flags, Name name, int attrs) { - return new TermSymbol(this, pos, flags, name, attrs); - } - - /** Creates a new package owned by this symbol. */ - final Symbol newPackage(int pos, Name name, Type info) { - assert isPackageClass(): Debug.show(this); - Symbol peckage = newModule(pos, JAVA | PACKAGE, name); - if (info == null) info = Type.compoundType( - Type.EMPTY_ARRAY, new Scope(), peckage.moduleClass()); - peckage.moduleClass().setInfo(info); - return peckage; - } - - /** Creates a new class owned by this symbol. */ - final ClassSymbol newClass(int pos, int flags, Name name, int attrs) { - return new ClassSymbol(this, pos, flags, name, attrs); - } - - /** Creates a new compound class owned by this symbol. */ - final ClassSymbol newCompoundClass(Type info) { - int pos = Position.FIRSTPOS; - Name name = Names.COMPOUND_NAME.toTypeName(); - int flags = ABSTRACT | SYNTHETIC; - int attrs = IS_COMPOUND; - ClassSymbol clasz = newClass(pos, flags, name, attrs); - clasz.setInfo(info); - clasz.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor())); - return clasz; - } - -// Copying & cloning ------------------------------------------------------ - - /** Returns a fresh symbol with the same fields as this one. - */ - public final Symbol cloneSymbol() { - return cloneSymbol(owner); - } - - /** Returns a fresh symbol with the same fields as this one and the - * given owner. - */ - public final Symbol cloneSymbol(Symbol owner) { - Symbol clone = cloneSymbolImpl(owner, attrs); - clone.setInfo(info()); - return clone; - } - - protected abstract Symbol cloneSymbolImpl(Symbol owner, int attrs); - - /** Returns a shallow copy of the given array. */ - public static Symbol[] cloneArray(Symbol[] array) { - return cloneArray(0, array, 0); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items. - */ - public static Symbol[] cloneArray(int prefix, Symbol[] array) { - return cloneArray(prefix, array, 0); - } - - /** - * Returns a shallow copy of the given array suffixed by "suffix" - * null items. - */ - public static Symbol[] cloneArray(Symbol[] array, int suffix) { - return cloneArray(0, array, suffix); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items and suffixed by "suffix" null items. - */ - public static Symbol[] cloneArray(int prefix, Symbol[] array, int suffix) { - assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; - int size = prefix + array.length + suffix; - if (size == 0) return EMPTY_ARRAY; - Symbol[] clone = new Symbol[size]; - for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; - return clone; - } - - /** Returns the concatenation of the two arrays. */ - public static Symbol[] concat(Symbol[] array1, Symbol[] array2) { - if (array1.length == 0) return array2; - if (array2.length == 0) return array1; - Symbol[] clone = cloneArray(array1.length, array2); - for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; - return clone; - } - -// Setters --------------------------------------------------------------- - - /** Set owner */ - public Symbol setOwner(Symbol owner) { - assert !isConstructor() && !isNone() && !isError(): Debug.show(this); - setOwner0(owner); - return this; - } - protected void setOwner0(Symbol owner) { - this.owner = owner; - } - - /** Set type -- this is an alias for setInfo(Type info) */ - public final Symbol setType(Type info) { return setInfo(info); } - - /** - * Set initial information valid from start of current phase. This - * information is visible in the current phase and will be - * transformed by the current phase (except if current phase is - * the first one). - */ - public Symbol setInfo(Type info) { - return setInfoAt(info, Global.instance.currentPhase); - } - - /** - * Set initial information valid from start of given phase. This - * information is visible in the given phase and will be - * transformed by the given phase. - */ - private final Symbol setInfoAt(Type info, Phase phase) { - assert info != null: Debug.show(this); - assert phase != null: Debug.show(this); - assert !isConstructor() - || info instanceof Type.LazyType - || info == Type.NoType - || info == Type.ErrorType - || info instanceof Type.MethodType - || info instanceof Type.OverloadedType - || info instanceof Type.PolyType - : "illegal type for " + this + ": " + info; - infos = new TypeIntervalList(null, info, phase); - if (info instanceof Type.LazyType) flags &= ~INITIALIZED; - else flags |= INITIALIZED; - return this; - } - - /** - * Set new information valid from start of next phase. This - * information is only visible in next phase or through - * "nextInfo". It will not be transformed by the current phase. - */ - public final Symbol updateInfo(Type info) { - return updateInfoAt(info, Global.instance.currentPhase.next); - } - - /** - * Set new information valid from start of given phase. This - * information is only visible from the start of the given phase - * which is also the first phase that will transform this - * information. - */ - private final Symbol updateInfoAt(Type info, Phase phase) { - assert info != null: Debug.show(this); - assert phase != null: Debug.show(this); - assert infos != null: Debug.show(this); - assert !phase.precedes(infos.limit()) : - Debug.show(this) + " -- " + phase + " -- " + infos.limit(); - if (infos.limit() == phase) { - if (infos.start == phase) - infos = infos.prev; - else - infos.setLimit(infos.limit().prev); - } - infos = new TypeIntervalList(infos, info, phase); - return this; - } - - /** Set type of `this' in current class - */ - public Symbol setTypeOfThis(Type tp) { - throw new ApplicationError(this + ".setTypeOfThis"); - } - - /** Set the low bound of this type variable - */ - public Symbol setLoBound(Type lobound) { - throw new ApplicationError("setLoBound inapplicable for " + this); - } - - /** Set the view bound of this type variable - */ - public Symbol setVuBound(Type lobound) { - throw new ApplicationError("setVuBound inapplicable for " + this); - } - - /** Add an auxiliary constructor to class. - */ - public void addConstructor(Symbol constr) { - throw new ApplicationError("addConstructor inapplicable for " + this); - } - -// Symbol classification ---------------------------------------------------- - - /** Does this symbol denote an error symbol? */ - public final boolean isError() { - return (attrs & IS_ERROR) != 0; - } - - /** Does this symbol denote the none symbol? */ - public final boolean isNone() { - return kind == Kinds.NONE; - } - - /** Does this symbol denote a type? */ - public final boolean isType() { - return kind == TYPE || kind == CLASS || kind == ALIAS; - } - - /** Does this symbol denote a term? */ - public final boolean isTerm() { - return kind == VAL; - } - - /** Does this symbol denote a value? */ - public final boolean isValue() { - preInitialize(); - return kind == VAL && !(isModule() && isJava()) && !isPackage(); - } - - /** Does this symbol denote a stable value? */ - public final boolean isStable() { - return kind == VAL && - ((flags & DEF) == 0) && - ((flags & STABLE) != 0 || - (flags & MUTABLE) == 0 && type().isObjectType()); - } - - /** Does this symbol have the STABLE flag? */ - public final boolean hasStableFlag() { - return (flags & STABLE) != 0; - } - - /** Is this symbol captured? */ - public final boolean isCaptured() { - return (flags & CAPTURED) != 0; - } - - /** Is this symbol static (i.e. with no outer instance)? */ - public final boolean isStatic() { - return isRoot() || hasStaticAttribute() || owner.isStaticOwner(); - } - - public final boolean hasStaticAttribute() { - return (attrs & IS_STATIC) != 0; - } - - /** Does this symbol denote a class that defines static symbols? */ - public final boolean isStaticOwner() { - // !!! remove "isJava()"? translation does not work (yet?) - return isPackageClass() || (isJava() && isModuleClass() && isStatic()); - } - - /** Is this symbol final? - */ - public final boolean isFinal() { - return - (flags & (FINAL | PRIVATE)) != 0 || isLocal() || owner.isModuleClass(); - } - - /** Does this symbol denote a variable? */ - public final boolean isVariable() { - return kind == VAL && (flags & MUTABLE) != 0; - } - - /** Does this symbol denote a view bounded type variable? */ - public final boolean isViewBounded() { - Global global = Global.instance; - return kind == TYPE && (flags & VIEWBOUND) != 0 && - global.currentPhase.id <= global.PHASE.REFCHECK.id(); - } - - /** - * Does this symbol denote a final method? A final method is one - * that can't be overridden in a subclass. This method assumes - * that this symbol denotes a method. It doesn't test it. - */ - public final boolean isMethodFinal() { - return (flags & FINAL) != 0 || isPrivate() || isLifted(); - } - - /** Does this symbol denote a sealed class symbol? */ - public final boolean isSealed() { - return (flags & SEALED) != 0; - } - - /** Does this symbol denote a method? - */ - public final boolean isInitializedMethod() { - if (infos == null) return false; - switch (rawInfo()) { - case MethodType(_, _): - case PolyType(_, _): - return true; - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isMethod()) return true; - return false; - default: - return false; - } - } - - public final boolean isMethod() { - initialize(); - return isInitializedMethod(); - } - - public final boolean isCaseFactory() { - return isMethod() && !isConstructor() && (flags & CASE) != 0; - } - - public final boolean isAbstractClass() { - preInitialize(); - return kind == CLASS && (flags & ABSTRACT) != 0 && - this != Global.instance.definitions.ARRAY_CLASS; - } - - public final boolean isOverride() { - preInitialize(); - return (flags & OVERRIDE) != 0; - } - - public final boolean isAbstractOverride() { - preInitialize(); - return (flags & (ABSTRACT | OVERRIDE)) == (ABSTRACT | OVERRIDE); - } - - /* Does this symbol denote an anonymous class? */ - public final boolean isAnonymousClass() { - return isClass() && (attrs & IS_ANONYMOUS) != 0; - } - - /** Does this symbol denote the root class or root module? - */ - public final boolean isRoot() { - return (attrs & IS_ROOT) != 0; - } - - /** Does this symbol denote something loaded from a Java class? */ - public final boolean isJava() { - preInitialize(); - return (flags & JAVA) != 0; - } - - /** Does this symbol denote a Java package? */ - public final boolean isPackage() { - return kind == VAL && (flags & PACKAGE) != 0; - } - - /** Does this symbol denote a Java package class? */ - public final boolean isPackageClass() { - return kind == CLASS && (flags & PACKAGE) != 0; - } - - /** Does this symbol have the PACKAGE flag? */ - public final boolean hasPackageFlag() { - return (flags & PACKAGE) != 0; - } - - /** Does this symbol denote a module? */ - public final boolean isModule() { - return kind == VAL && (flags & MODUL) != 0; - } - - /** Does this symbol denote a module class? */ - public final boolean isModuleClass() { - return kind == CLASS && (flags & MODUL) != 0; - } - - /** Does this symbol denote a class? */ - public final boolean isClass() { - return kind == CLASS && (flags & PACKAGE) == 0; - } - - /** Does this symbol denote a case class? */ - public final boolean isCaseClass() { - preInitialize(); - return kind == CLASS && (flags & CASE) != 0; - } - - /** Does this symbol denote a case object? */ - public final boolean isCaseModuleClass() { - return isModuleClass() && isCaseClass(); - } - - /** Does this symbol denote a uniform (i.e. parameterless) class? */ - public final boolean isTrait() { - //preInitialize(); todo: enable, problem is that then we cannot print - // during unpickle - return kind == CLASS && (flags & TRAIT) != 0; - } - - /** Does this class symbol denote a compound type symbol? */ - public final boolean isCompoundSym() { - return (attrs & IS_COMPOUND) != 0; - } - - /** Does this symbol denote a this symbol? */ - public final boolean isThisSym() { - return (attrs & IS_THISTYPE) != 0; - } - - /** Does this symbol denote an interface? */ - public final boolean isInterface() { - info(); // force delayed transformInfos that may change this flag - return (flags & INTERFACE) != 0; - } - - /** Does this symbol denote a type alias? */ - public final boolean isTypeAlias() { - return kind == ALIAS; - } - - /** Does this symbol denote an abstract type? */ - public final boolean isAbstractType() { - return kind == TYPE; - } - - /** Does this symbol denote a class type? */ - public final boolean isClassType() { - return kind == CLASS; - } - - /** Does this symbol denote a public symbol? */ - public final boolean isPublic() { - return !isProtected() && !isPrivate(); - } - - /** Does this symbol denote a protected symbol? */ - public final boolean isProtected() { - preInitialize(); - return (flags & PROTECTED) != 0; - } - - /** Does this symbol denote a private symbol? */ - public final boolean isPrivate() { - preInitialize(); - return (flags & PRIVATE) != 0; - } - - /** Has this symbol been lifted? */ - public final boolean isLifted() { - preInitialize(); - return (flags & LIFTED) != 0; - } - - /** Does this symbol denote a deferred symbol? */ - public final boolean isDeferred() { - return (flags & DEFERRED) != 0; - } - - /** Does this symbol denote a synthetic symbol? */ - public final boolean isSynthetic() { - return (flags & SYNTHETIC) != 0; - } - - /** Does this symbol denote an accessor? */ - public final boolean isAccessor() { - return (flags & ACCESSOR) != 0; - } - - /** Has this symbol the PARAMACCESSOR flag? */ - public final boolean hasParamAccessorFlag() { - return (flags & PARAMACCESSOR) != 0; - } - - /** Does this symbol denote an access method? (a method to access - * private of protected members from inner classes) */ - public final boolean isAccessMethod() { - return (attrs & IS_ACCESSMETHOD) != 0; - } - - /** Is this symbol locally defined? I.e. not a member of a class or module */ - public final boolean isLocal() { - return owner.kind == VAL && - !((flags & PARAM) != 0 && owner.isPrimaryConstructor()); - } - - /** Is this symbol a parameter? Includes type parameters of methods. - */ - public final boolean isParameter() { - return (flags & PARAM) != 0; - } - - /** Is this symbol a type parameter? - */ - public final boolean isTypeParameter() { - return kind == TYPE && (flags & PARAM) != 0; - } - - /** Is this symbol a def parameter? - */ - public final boolean isDefParameter() { - return (flags & (PARAM | DEF)) == (PARAM | DEF); - } - - /** Is this class locally defined? - * A class is local, if - * - it is anonymous, or - * - its owner is a value - * - it is defined within a local class - */ - public final boolean isLocalClass() { - return isClass() && - (isAnonymousClass() || - owner.isValue() || - owner.isLocalClass()); - } - - /** Is this symbol an instance initializer? */ - public boolean isInitializer() { - return false; - } - - /** Is this symbol a constructor? */ - public final boolean isConstructor() { - return (attrs & IS_CONSTRUCTOR) != 0; - } - - /** Is this symbol the primary constructor of a type? */ - public final boolean isPrimaryConstructor() { - return isConstructor() && this == constructorClass().primaryConstructor(); - } - - /** Symbol was preloaded from package - */ - public final boolean isExternal() { - return pos == Position.NOPOS; - } - - /** Is this symbol an overloaded symbol? */ - public final boolean isOverloaded() { - Type tp = rawInfo(); - return - tp instanceof Type.OverloadedType || - tp instanceof LazyOverloadedType; - } - - /** Does this symbol denote a label? */ - public final boolean isLabel() { - return (attrs & IS_LABEL) != 0; - } - - /** Is this symbol accessed? */ - public final boolean isAccessed() { - return (flags & ACCESSED) != 0; - } - - /** The variance of this symbol as an integer - */ - public int variance() { - if ((flags & COVARIANT) != 0) return 1; - else if ((flags & CONTRAVARIANT) != 0) return -1; - else return 0; - } - -// Symbol names ---------------------------------------------------------------- - - /** Get the simple name of this Symbol (this is always a term name) - */ - public Name simpleName() { - if (isConstructor()) return constructorClass().name.toTermName(); - return name; - } - -// Symbol origin -------------------------------------------------------------- - - /** Returns the origin of this symbol. */ - public SymbolOrigin getOrigin() { - Symbol clasz = getMainClassOrNone(); - return (clasz != this ? clasz : owner()).getOrigin(); - } - - /** Sets the origin of this symbol. */ - public void setOrigin(SymbolOrigin origin) { - throw Debug.abort("not a class", this); - } - - /** - * Returns the main owner of this symbol. The main owner of a - * symbol is: - * - its module class for modules - * - its constructed class for constructors and factory methods - * - its owner for other symbols - * - * @see Symbol#getMainClassOrNone() - */ - public Symbol getMainOwner() { - if (isModule()) - return moduleClass(); - if (isConstructor()) - return constructorClass(); - if (isCaseFactory()) - return type().resultType().symbol(); - return owner(); - } - - /** - * Returns the main class of this symbol. The main class of a - * symbol is: - * - itself for non-compound classes and NONE - * - the main class of its main owner for other symbols - * - * This implies that the main class of a symbol is the first - * enclosing class of that symbol excepted for modules, - * constructors and factory methods. The main class of modules is - * their module class and the main class of constructors and - * factory methods is their constructed class. If a the symbol is - * not linked to a class through its owner, the method returns - * the symbol NONE. - * - * The main class of a symbol can be understood as the class that - * declared that symbol. - * - * @see Symbol@getMainOwner() - */ - public Symbol getMainClassOrNone() { - if (isNone() || (isClassType() && !isCompoundSym())) - return this; - return getMainOwner().getMainClassOrNone(); - } - - /** - * Determines the enclosing package of this symbol and returns the - * module class of that package. Note that the enclosing package - * of a package is itself. If a symbol has no enclosing package, - * the method returns the symbol NONE. - */ - public Symbol getEnclosingPackageClassOrNone() { - Symbol clasz = getMainClassOrNone(); - while (!clasz.isNone() && !clasz.isPackageClass()) - clasz = clasz.owner().getMainClassOrNone(); - return clasz; - } - - /** - * Returns the source directory of this symbol or "null" if it is - * unknown. The source directory of a symbol is the directory - * corresponding to the enclosing package of that symbol. - * - * @see Symbol@getEnclosingPackageClassOrNone() - */ - public final AbstractFile getSourceDirectoryOrNull() { - if (isNone()) return null; - if (!isPackageClass()) - return getEnclosingPackageClassOrNone().getSourceDirectoryOrNull(); - - switch (getOrigin()) { - case Directory(AbstractFile file): - return file; - default: - AbstractFile parent = owner().getSourceDirectoryOrNull(); - if (parent == null) return null; - return parent.lookupName(name.toString(), true); - } - } - - /** - * Returns the source file of this symbol or "null" if it is - * unknown. - */ - public final AbstractFile getSourceFileOrNull() { - switch (getOrigin()) { - case ClassFile(_, String sourcefile): - if (sourcefile == null) return null; - AbstractFile parent = getSourceDirectoryOrNull(); - if (parent == null) return null; - return parent.lookupName(sourcefile, false); - case ScalaFile(AbstractFile file): - return file; - case ScalaUnit(CompilationUnit unit): - return unit.source.getFile(); - default: - return null; - } - } - - /** - * Returns the compilation unit of this symbol or "null" if it is - * unknown or if the symbol has no associated compilation unit. - */ - public final CompilationUnit getUnitOrNull() { - switch (getOrigin()) { - case ScalaUnit(CompilationUnit unit): - return unit; - default: - return null; - } - } - -// Acess to related symbols ----------------------------------------------------- - - /** Get type parameters */ - public Symbol[] typeParams() { - return EMPTY_ARRAY; - } - - /** Get value parameters */ - public Symbol[] valueParams() { - return EMPTY_ARRAY; - } - - /** Get result type */ - public final Type resultType() { - return type().resultType(); - } - - /** Get type parameters at start of next phase */ - public final Symbol[] nextTypeParams() { - Global.instance.nextPhase(); - Symbol[] tparams = typeParams(); - Global.instance.prevPhase(); - return tparams; - } - - /** Get value parameters at start of next phase */ - public final Symbol[] nextValueParams() { - Global.instance.nextPhase(); - Symbol[] vparams = valueParams(); - Global.instance.prevPhase(); - return vparams; - } - - /** Get result type at start of next phase */ - public final Type nextResultType() { - return nextType().resultType(); - } - - /** Get all constructors of class */ - public Symbol allConstructors() { - return NONE; - } - - /** Get primary constructor of class */ - public Symbol primaryConstructor() { - return NONE; - } - - /** - * Returns the class linked to this module or null if there is no - * such class. The returned value remains the same for the whole - * life of the symbol. - * - * See method "linkedModule" to learn more about linked modules - * and classes. - */ - public ClassSymbol linkedClass() { - assert isModule(): "not a module: " + Debug.show(this); - return null; - } - - /** - * Returns the module linked to this class or null if there is no - * such module. The returned value remains the same for the whole - * life of the symbol. - * - * Linked modules and classes are intended to be used by the - * symbol table loader. They are needed because it is impossible - * to know from the name of a class or source file if it defines a - * class or a module. For that reason a class and a module (each - * linked to the other) are created for each of those files. Once - * the file is read the class, the module or both are initialized - * depending on what the file defines. - * - * It is guaranteed that if a class "c" has a linked module then - * "c.linkedModule().linkedClasss() == c" and that if a module "m" - * has a linked class then "m.linkedClasss().linkedModule() == m". - * - * The linked module of a Java class, is the module that contains - * the static members of that class. A Java class has always a - * linked module. - * - * The linked module of a Scala class, is the module with the same - * name declared in the same scope. A Scala class may or may not - * have a linked module. However, this does not depend on the - * presence or absence of a module with the same name but on how - * the class is created. Therefore a Scala class may have no - * linked module even though there exists a module with the same - * name in the same scope. A Scala class may also have a linked - * module even though there exists no module with the same name in - * the same scope. In the latter case, the linked would be - * initialized to NoType (which prevents accesses to it). - * - * There is a last catch about linked modules. It may happen that - * the symbol returned by "linkedModule" is not a module (and that - * method "linkedClass" works on a non-module symbol). At creation - * time, linked modules are always modules, but at initialization - * time, it may be discovered that the module is in fact a case - * class factory method. In that case, the module is downgraded to - * a non-module term. This implies that from then on calls to its - * method "moduleClass" will fail, but the links defined by the - * methods "linkedModule" and "linkedClass" remain unchanged. - */ - public ModuleSymbol linkedModule() { - assert isClassType(): "not a class: " + Debug.show(this); - return null; - } - - /** Get owner */ - public Symbol owner() { - return owner; - } - - /** Get owner, but if owner is primary constructor of a class, - * get class symbol instead. This is useful for type parameters - * and value parameters in classes which have the primary constructor - * as owner. - */ - public Symbol classOwner() { - Symbol owner = owner(); - Symbol clazz = owner.constructorClass(); - if (clazz.primaryConstructor() == owner) return clazz; - else return owner; - } - - /** The next enclosing class */ - public Symbol enclClass() { - return owner().enclClass(); - } - - /** The next enclosing method */ - public Symbol enclMethod() { - return isMethod() ? this : owner().enclMethod(); - } - - /** If this is a constructor, return the class it constructs. - * Otherwise return the symbol itself. - */ - public Symbol constructorClass() { - return this; - } - - /** - * Returns the class of this module. This method may be invoked - * only on module symbols. It returns always a non-null module - * class symbol whose identity never changes. - */ - public ModuleClassSymbol moduleClass() { - throw Debug.abort("not a module", this); - } - - /** - * Returns the source module of this module class. This method may - * be invoked only on module class symbols. It returns always a - * non-null module symbol whose identity never changes. - * - * This method should be used with great care. If possible, one - * should always use moduleClass instead. For example, one should - * write "m.moduleClass()==c" rather than "m==c.sourceModule()". - * - * This method is problematic because the module - module-class - * relation is not a one - one relation. There might be more than - * one module that share the same module class. In that case, the - * source module of the module class is the module that created - * the class. This implies that "m.moduleClass().sourceModule()" - * may be different of "m". However, its is guaranteed that - * "c.sourceModule().moduleClass()" always returns "c". - * - * Phases like "AddInterfaces" and "ExpandMixins" are two examples - * of phases that create additional modules referring the same - * module class. - * - * Even if a module class is related to only one module, the use - * of this method may still be dangerous. The problem is that - * modules and module classes are not always as related as one - * might expect. For example, modules declared in a function are - * lifted out of the function by phase "LambdaLift". During this - * process, the module value is transformed into a module method - * with a "Ref" argument. If the "sourceModule" method is used to - * replace references to module classes by references to their - * source modules and this is done it naively with the class of a - * lifted module, it will yield wrong code because the the "Ref" - * argument will be missing. - */ - public ModuleSymbol sourceModule() { - throw Debug.abort("not a module class", this); - } - - /** if type is a (possibly lazy) overloaded type, return its alternatves - * else return array consisting of symbol itself - */ - public Symbol[] alternativeSymbols() { - Symbol[] alts = type().alternativeSymbols(); - if (alts.length == 0) return new Symbol[]{this}; - else return alts; - } - - /** if type is a (possibly lazy) overloaded type, return its alternatves - * else return array consisting of type itself - */ - public Type[] alternativeTypes() { - return type().alternativeTypes(); - } - - /** if type is a overloaded type, return first stable alternative - * else return symbol itself - */ - public Symbol stableAlternative() { - switch (type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isStable()) return alts[i]; - } - return this; - } - - /** The symbol accessed by this accessor function. - */ - public Symbol accessed() { - assert (flags & ACCESSOR) != 0; - String name1 = name.toString(); - if (name1.endsWith(Names._EQ.toString())) - name1 = name1.substring(0, name1.length() - Names._EQ.length()); - return owner.lookup(Name.fromString(name1 + "$")); - } - - /** The members of this class or module symbol - */ - public Scope members() { - return info().members(); - } - - /** Lookup symbol with given name; return Symbol.NONE if not found. - */ - public Symbol lookup(Name name) { - return info().lookup(name); - } - -// Symbol types -------------------------------------------------------------- - - /** Was symbol's type updated during given phase? */ - public final boolean isUpdatedAt(Phase phase) { - Phase next = phase.next; - TypeIntervalList infos = this.infos; - while (infos != null) { - if (infos.start == next) return true; - if (infos.limit().precedes(next)) return false; - infos = infos.prev; - } - return false; - } - - /** Is this symbol locked? */ - public final boolean isLocked() { - return (flags & LOCKED) != 0; - } - - /** Is this symbol initialized? */ - public final boolean isInitialized() { - return (flags & INITIALIZED) != 0; - } - - /** Initialize the symbol */ - public final Symbol initialize() { - info(); - return this; - } - - /** Make sure symbol is entered - */ - public final void preInitialize() { - //todo: clean up - if (infos.info instanceof SymbolLoader) - infos.info.complete(this); - } - - /** Get info at start of current phase; This is: - * for a term symbol, its type - * for a type variable, its bound - * for a type alias, its right-hand side - * for a class symbol, the compound type consisting of - * its baseclasses and members. - */ - public final Type info() { - //if (isModule()) moduleClass().initialize(); - if ((flags & INITIALIZED) == 0) { - Global global = Global.instance; - Phase current = global.currentPhase; - global.currentPhase = rawFirstInfoStartPhase(); - Type info = rawFirstInfo(); - assert info != null : this; - if ((flags & LOCKED) != 0) { - setInfo(Type.ErrorType); - flags |= INITIALIZED; - throw new CyclicReference(this, info); - } - flags |= LOCKED; - //System.out.println("completing " + this);//DEBUG - info.complete(this); - flags = flags & ~LOCKED; - if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) { - flags |= SNDTIME; - Type tp = info(); - flags &= ~SNDTIME; - } else { - assert !(rawInfo() instanceof Type.LazyType) : this; - //flags |= INITIALIZED; - } - //System.out.println("done: " + this);//DEBUG - global.currentPhase = current; - } - return rawInfo(); - } - - /** Get info at start of next phase - */ - public final Type nextInfo() { - Global.instance.nextPhase(); - Type info = info(); - Global.instance.prevPhase(); - return info; - } - - /** Get info at start of given phase - */ - protected final Type infoAt(Phase phase) { - Global global = phase.global; - Phase current = global.currentPhase; - global.currentPhase = phase; - Type info = info(); - global.currentPhase = current; - return info; - } - - /** Get info at start of current phase, without forcing lazy types. - */ - public final Type rawInfo() { - return rawInfoAt(Global.instance.currentPhase); - } - - /** Get info at start of next phase, without forcing lazy types. - */ - public final Type rawNextInfo() { - Global.instance.nextPhase(); - Type info = rawInfo(); - Global.instance.prevPhase(); - return info; - } - - /** Get info at start of given phase, without forcing lazy types. - */ - private final Type rawInfoAt(Phase phase) { - //if (infos == null) return Type.NoType;//DEBUG - assert infos != null : this; - assert phase != null : this; - if (infos.limit().id <= phase.id) { - switch (infos.info) { - case LazyType(): - // don't force lazy types - return infos.info; - } - while (infos.limit() != phase) { - Phase limit = infos.limit(); - Type info = transformInfo(limit, infos.info); - assert info != null: Debug.show(this) + " -- " + limit; - if (info != infos.info) { - infos = new TypeIntervalList(infos, info, limit.next); - } else { - infos.setLimit(limit.next); - } - } - return infos.info; - } else { - TypeIntervalList infos = this.infos; - while (phase.id < infos.start.id && infos.prev != null) - infos = infos.prev; - return infos.info; - } - } - // where - private Type transformInfo(Phase phase, Type info) { - Global global = phase.global; - Phase current = global.currentPhase; - boolean keepInheritedOverloaded = current.id <= global.PHASE.UNCURRY.id(); - switch (info) { - case ErrorType: - case NoType: - return info; - case OverloadedType(Symbol[] alts, Type[] alttypes): - global.currentPhase = phase.next; - int n = 0; - boolean altChanged = false; - for (int i = 0; i < alts.length; i++) { - Type type = alts[i].info(); - if (keepInheritedOverloaded || - alts[i].owner() == owner()) n++; - if (alts[i].info() != alttypes[i]) altChanged = true; - } - Type result; - if (n < alts.length) { - Symbol[] symbols = new Symbol[n]; - Type[] types = new Type[n]; - int j = 0; - for (int i = 0; i < alts.length; i++) { - if (keepInheritedOverloaded || - alts[i].owner() == owner()) { - symbols[j] = alts[i]; - types[j] = alts[i].info(); - j++; - } else - if (Global.instance.debug) Global.instance.log("removing inherited alternatve " + alts[i] + ":" + alttypes[i]);//debug - } - result = Type.OverloadedType(symbols, types); - } else if (altChanged) { - Type[] types = new Type[alttypes.length]; - for (int i = 0; i < alts.length; i++) { - types[i] = alts[i].info(); - } - result = Type.OverloadedType(alts, types); - } else { - result = info; - } - global.currentPhase = current; - return result; - default: - global.currentPhase = phase; - info = phase.transformInfo(this, info); - global.currentPhase = current; - return info; - } - } - - /** Get first defined info, without forcing lazy types. - */ - public final Type rawFirstInfo() { - TypeIntervalList infos = this.infos; - assert infos != null : this; - while (infos.prev != null) infos = infos.prev; - return infos.info; - } - - /** Get phase that first defined an info, without forcing lazy types. - */ - public final Phase rawFirstInfoStartPhase() { - TypeIntervalList infos = this.infos; - assert infos != null : this; - while (infos.prev != null) infos = infos.prev; - return infos.start; - } - - /** Get type at start of current phase. The type of a symbol is: - * for a type symbol, the type corresponding to the symbol itself - * for a term symbol, its usual type - */ - public Type type() { - return info(); - } - public Type getType() { - return info(); - } - - /** Get type at start of next phase - */ - public final Type nextType() { - Global.instance.nextPhase(); - Type type = type(); - Global.instance.prevPhase(); - return type; - } - - /** The infos of these symbols as an array. - */ - static public Type[] info(Symbol[] syms) { - Type[] tps = new Type[syms.length]; - for (int i = 0; i < syms.length; i++) - tps[i] = syms[i].info(); - return tps; - } - - /** The types of these symbols as an array. - */ - static public Type[] type(Symbol[] syms) { - Type[] tps = new Type[syms.length]; - for (int i = 0; i < syms.length; i++) - tps[i] = syms[i].type(); - return tps; - } - static public Type[] getType(Symbol[] syms) { - return type(syms); - } - - /** Get static type. */ - public final Type staticType() { - return staticType(Type.EMPTY_ARRAY); - } - /** Get static type with given type argument. */ - public final Type staticType(Type arg0) { - return staticType(new Type[]{arg0}); - } - /** Get static type with given type arguments. */ - public final Type staticType(Type arg0, Type arg1) { - return staticType(new Type[]{arg0, arg1}); - } - /** Get static type with given type arguments. */ - public final Type staticType(Type[] args) { - Type prefix = owner.staticPrefix(); - if (isType()) return Type.typeRef(prefix, this, args); - assert args.length == 0: Debug.show(this, args); - return prefix.memberType(this); - } - - /** Get static prefix. */ - public final Type staticPrefix() { - assert isStaticOwner(): Debug.show(this) + " - " + isTerm() + " - " + isModuleClass() + " - " + owner().isStaticOwner() + " - " + isJava(); - Global global = Global.instance; - if (global.PHASE.EXPLICITOUTER.id() < global.currentPhase.id) - return Type.NoPrefix; - if (isRoot()) return thisType(); - assert sourceModule().owner() == owner(): Debug.show(this); - assert sourceModule().type().isObjectType(): Debug.show(this); - return Type.singleType(owner.staticPrefix(), sourceModule()); - } - - /** The type constructor of a symbol is: - * For a type symbol, the type corresponding to the symbol itself, excluding - * parameters. - * Not applicable for term symbols. - */ - public Type typeConstructor() { - throw new ApplicationError("typeConstructor inapplicable for " + this); - } - - /** The low bound of this type variable - */ - public Type loBound() { - return Global.instance.definitions.ALL_TYPE(); - } - - /** The view bound of this type variable - */ - public Type vuBound() { - return Global.instance.definitions.ANY_TYPE(); - } - - /** Get this.type corresponding to this symbol - */ - public Type thisType() { - return Type.NoPrefix; - } - - /** Get type of `this' in current class. - */ - public Type typeOfThis() { - return type(); - } - - /** Get this symbol of current class - */ - public Symbol thisSym() { return this; } - - - /** A total ordering between symbols that refines the class - * inheritance graph (i.e. subclass.isLess(superclass) always holds). - */ - public boolean isLess(Symbol that) { - if (this == that) return false; - int diff; - if (this.isType()) { - if (that.isType()) { - diff = this.closure().length - that.closure().length; - if (diff > 0) return true; - if (diff < 0) return false; - } else { - return true; - } - } else if (that.isType()) { - return false; - } - return this.id < that.id; - } - - /** Return the symbol's type itself followed by all its direct and indirect - * base types, sorted by isLess(). Overridden for class symbols. - */ - public Type[] closure() { - return info().closure(); - } - - /** Return position of `c' in the closure of this type; -1 if not there. - */ - public int closurePos(Symbol c) { - if (this == c) return 0; - if (c.isCompoundSym()) return -1; - Type[] closure = closure(); - int lo = 0; - int hi = closure.length - 1; - while (lo <= hi) { - int mid = (lo + hi) / 2; - Symbol clsym = closure[mid].symbol(); - if (c == clsym) return mid; - else if (c.isLess(clsym)) hi = mid - 1; - else if (clsym.isLess(c)) lo = mid + 1; - else throw new ApplicationError(); - } - return -1; - } - - public Type baseType(Symbol sym) { - int i = closurePos(sym); - if (i >= 0) return closure()[i]; - else return Type.NoType; - } - - /** Is this class a subclass of `c'? I.e. does it have a type instance - * of `c' as indirect base class? - */ - public boolean isSubClass(Symbol c) { - return this == c || - c.isError() || - closurePos(c) >= 0 || - this == Global.instance.definitions.ALL_CLASS || - (this == Global.instance.definitions.ALLREF_CLASS && - c != Global.instance.definitions.ALL_CLASS && - c.isSubClass(Global.instance.definitions.ANYREF_CLASS)); - } - - /** Get base types of this symbol */ - public Type[] parents() { - return info().parents(); - } - -// ToString ------------------------------------------------------------------- - - /** String representation of symbol's simple name. - * Translates expansions of operators back to operator symbol. E.g. - * $eq => =. - */ - public String nameString() { - return NameTransformer.decode(simpleName()); - } - - /** String representation, including symbol's kind - * e.g., "class Foo", "function Bar". - */ - public String toString() { - return new SymbolTablePrinter().printSymbolKindAndName(this).toString(); - } - - /** String representation of location. - */ - public String locationString() { - if (owner.kind == CLASS && - !owner.isAnonymousClass() && !owner.isCompoundSym() || - Global.instance.debug) - return " in " + - (owner.isModuleClass() ? owner.sourceModule() : owner); - else - return ""; - } - - /** String representation of definition. - */ - public String defString() { - return new SymbolTablePrinter().printSignature(this).toString(); - } - - public static String[] defString(Symbol[] defs) { - String[] strs = new String[defs.length]; - for (int i = 0; i < defs.length; i++) - strs[i] = defs[i].defString(); - return strs; - } - -// Overloading and Overriding ------------------------------------------- - - /** Return first alternative if this has a (possibly lazy) - * overloaded type, otherwise symbol itself. - * Needed in ClassSymbol.primaryConstructor() and in UnPickle. - */ - public Symbol firstAlternative() { - if (infos == null) - return this; - else if (infos.info instanceof Type.OverloadedType) { - Symbol result = infos.info.alternativeSymbols()[0]; - assert !result.isOverloaded(); - return result; - } else if (infos.info instanceof LazyOverloadedType) - return ((LazyOverloadedType) infos.info).sym1.firstAlternative(); - else - return this; - } - - /** Add another overloaded alternative to this symbol. - */ - public Symbol overloadWith(Symbol that) { - throw new ApplicationError("overloadWith inapplicable for " + this); - } - - /** A lazy type which, when forced computed the overloaded type - * of symbols `sym1' and `sym2'. It also checks that this type is well-formed. - */ - public static class LazyOverloadedType extends Type.LazyType { - Symbol sym1; - Symbol sym2; - LazyOverloadedType(Symbol sym1, Symbol sym2) { - this.sym1 = sym1; - this.sym2 = sym2; - } - - public Symbol[] alternativeSymbols() { - Symbol[] alts1 = sym1.alternativeSymbols(); - Symbol[] alts2 = sym2.alternativeSymbols(); - Symbol[] alts3 = new Symbol[alts1.length + alts2.length]; - System.arraycopy(alts1, 0, alts3, 0, alts1.length); - System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); - return alts3; - } - - public Type[] alternativeTypes() { - Type[] alts1 = sym1.alternativeTypes(); - Type[] alts2 = sym2.alternativeTypes(); - Type[] alts3 = new Type[alts1.length + alts2.length]; - System.arraycopy(alts1, 0, alts3, 0, alts1.length); - System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); - return alts3; - } - - public void complete(Symbol overloaded) { - overloaded.setInfo( - Type.OverloadedType( - alternativeSymbols(), alternativeTypes())); - } - - public String toString() { - return "LazyOverloadedType(" + sym1 + "," + sym2 + ")"; - } - } - - /** - * Returns the symbol in type "base" which is overridden by this - * symbol in class "this.owner()". Returns "NONE" if no such - * symbol exists. The type "base" must be a supertype of class - * "this.owner()". If "exact" is true, overriding is restricted to - * symbols that have the same type. The method may return this - * symbol only if "base.symbol()" is equal to "this.owner()". - */ - public final Symbol overriddenSymbol(Type base, boolean exact) { - return overriddenSymbol(base, owner(), exact); - } - public final Symbol overriddenSymbol(Type base) { - return overriddenSymbol(base, false); - } - - /** - * Returns the symbol in type "base" which is overridden by this - * symbol in "clasz". Returns "NONE" if no such symbol exists. The - * type "base" must be a supertype of "clasz" and "this.owner()" - * must be a superclass of "clasz". If "exact" is true, overriding - * is restricted to symbols that have the same type. The method - * may return this symbol if "base.symbol()" is a subclass of - * "this.owner()". - */ - public final Symbol overriddenSymbol(Type base, Symbol clasz, boolean exact) { - Type.Relation relation = exact - ? Type.Relation.SameType - : Type.Relation.SuperType; - return base.lookup(this, clasz.thisType(), relation); - } - public final Symbol overriddenSymbol(Type base, Symbol clasz) { - return overriddenSymbol(base, clasz, false); - } - - /** - * Returns the symbol in type "sub" which overrides this symbol in - * class "sub.symbol()". Returns this symbol if no such symbol - * exists. The class "sub.symbol()" must be a subclass of - * "this.owner()". If "exact" is true, overriding is restricted to - * symbols that have the same type. - */ - public final Symbol overridingSymbol(Type sub, boolean exact) { - Type.Relation relation = exact - ? Type.Relation.SameType - : Type.Relation.SubType; - return sub.lookup(this, sub, relation); - } - public final Symbol overridingSymbol(Type sub) { - return overridingSymbol(sub, false); - } - - /** Does this symbol override that symbol? - */ - public boolean overrides(Symbol that) { - return - ((this.flags | that.flags) & PRIVATE) == 0 && - this.name == that.name && - owner.thisType().memberType(this).derefDef().isSubType( - owner.thisType().memberType(that).derefDef()); - } - - /** Reset symbol to initial state - */ - public void reset(Type completer) { - this.flags &= SOURCEFLAGS; - this.pos = 0; - this.infos = null; - this.setInfo(completer); - } - - /** - * Returns the symbol to use in case of a rebinding due to a more - * precise type prefix. - */ - public Symbol rebindSym() { - return this; - } - - /** return a tag which (in the ideal case) uniquely identifies - * class symbols - */ - public int tag() { - return name.toString().hashCode(); - } - - public void addInheritedOverloaded(Type owntype) { - Symbol sym = Type.lookupNonPrivate(owner.parents(), name); - if (sym.kind == VAL) { - Type symtype = owner.thisType().memberType(sym); - switch (symtype) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) - addInheritedOverloaded(owntype, alts[i], alttypes[i]); - break; - default: - addInheritedOverloaded(owntype, sym, symtype); - } - } - } - - public void addInheritedOverloaded(Type owntype, Symbol sym, Type symtype) { - if (!owntype.overrides(symtype)) { - if (Global.instance.debug) Global.instance.log(owner() + " inherits overloaded: " + sym + ":" + symtype + sym.locationString());//debug - owner().members().lookupEntry(name).setSymbol(overloadWith(sym)); - //System.out.println("type is now: " + owner().members().lookup(name).type()); - } - } - - public Type removeInheritedOverloaded(Type owntype) { - switch (owntype) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - int n = 0; - for (int i = 0; i < alts.length; i++) - if (alts[i].owner() == owner()) n++; - if (n < alts.length) { - Symbol[] alts1 = new Symbol[n]; - Type[] alttypes1 = new Type[n]; - int j = 0; - for (int i = 0; i < alts.length; i++) { - if (alts[i].owner() == owner()) { - alts1[j] = alts[i]; - alttypes1[j] = alttypes[i]; - j++; - } else - if (Global.instance.debug) Global.instance.log("removing inherited alternatve " + alts[i] + ":" + alttypes[i]);//debug - } - return Type.OverloadedType(alts1, alttypes1); - } else { - return owntype; - } - default: - return owntype; - } - } -} - -/** A class for term symbols - */ -public // !!! for java -Xfuture -class TermSymbol extends Symbol { - - /** Constructor */ - TermSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(VAL, owner, pos, flags, name, attrs); - assert name.isTermName(): Debug.show(this); - } - - public boolean isInitializer() { - return name == Names.INITIALIZER; - } - - public Symbol[] typeParams() { - return type().typeParams(); - } - - public Symbol[] valueParams() { - return type().valueParams(); - } - - protected Symbol cloneSymbolImpl(Symbol owner, int attrs) { - return new TermSymbol(owner, pos, flags, name, attrs); - } - - /** Add another overloaded alternative to this symbol. - */ - public Symbol overloadWith(Symbol that) { - assert this.name == that.name : Debug.show(this) + " <> " + Debug.show(that); - //assert this.owner == that.owner : Debug.show(this) + " != " + Debug.show(that); - assert this.isConstructor() == that.isConstructor(); - - int overflags; - //if (this.owner == that.owner) - overflags = (this.flags & that.flags & - (JAVA | ACCESSFLAGS | DEFERRED | PARAM | SYNTHETIC)) | - ((this.flags | that.flags) & ACCESSOR); - // else // it's an inherited overloaded alternative - // overflags = this.flags & SOURCEFLAGS; - Symbol overloaded = (this.isConstructor()) - ? this.constructorClass().newConstructor(this.constructorClass().pos, overflags) - : owner().newTerm(pos, overflags, name, 0); - overloaded.setInfo(new LazyOverloadedType(this, that)); - return overloaded; - } -} - -/** A class for constructor symbols */ -final class ConstructorSymbol extends TermSymbol { - - /** The constructed class */ - private final Symbol clasz; - - /** Initializes this instance. */ - ConstructorSymbol(Symbol clasz, int pos, int flags) { - super(clasz.owner(), pos, flags, Names.CONSTRUCTOR, IS_CONSTRUCTOR); - this.clasz = clasz; - } - - public boolean isInitializer() { - return false; - } - - public Symbol constructorClass() { - return clasz; - } - - protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) { - throw Debug.abort("illegal clone of constructor", this); - } - -} - -/** A class for module symbols */ -public class ModuleSymbol extends TermSymbol { - - /** The module class */ - private final ModuleClassSymbol clasz; - - /** Initializes this instance. */ - private ModuleSymbol(Symbol owner, int pos, int flags, Name name, - int attrs, ModuleClassSymbol clasz) - { - super(owner, pos, flags | MODUL | FINAL | STABLE, name, attrs); - this.clasz = clasz != null ? clasz : new ModuleClassSymbol(this); - setType(Type.typeRef(owner().thisType(), this.clasz,Type.EMPTY_ARRAY)); - } - - /** Initializes this instance. */ - ModuleSymbol(Symbol owner, int pos, int flags, Name name) { - this(owner, pos, flags, name, 0, null); - } - - public ModuleClassSymbol moduleClass() { - // test may fail because loaded modules may be downgraded to - // case class factory methods (see Symbol#linkedModule()) - - assert isModule(): Debug.show(this); - return clasz; - } - - protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) { - return new ModuleSymbol(owner, pos, flags, name, attrs, clasz); - } - -} - -/** - * A class for linked module symbols - * - * @see Symbol#linkedModule() - */ -public // !!! for java -Xfuture -final class LinkedModuleSymbol extends ModuleSymbol { - - /** The linked class */ - private final LinkedClassSymbol clasz; - - /** Initializes this instance. */ - LinkedModuleSymbol(LinkedClassSymbol clasz) { - super(clasz.owner(), clasz.pos, clasz.flags & JAVA, - clasz.name.toTermName()); - this.clasz = clasz; - } - - public ClassSymbol linkedClass() { - return clasz; - } - -} - -/** A base class for all type symbols. - * It has AliasTypeSymbol, AbsTypeSymbol, ClassSymbol as subclasses. - */ -public // !!! for java -Xfuture -abstract class TypeSymbol extends Symbol { - - /** The history of closures of this symbol */ - private final History/*<Type[]>*/ closures; - - /** A cache for type constructors - */ - private Type tycon = null; - - /** The primary constructor of this type */ - private Symbol constructor; - - /** Constructor */ - public TypeSymbol(int kind, Symbol owner, int pos, int flags, Name name, int attrs) { - super(kind, owner, pos, flags, name, attrs); - this.closures = new ClosureHistory(); - assert name.isTypeName() : this; - this.constructor = newConstructor(pos, flags & CONSTRFLAGS); - } - - protected final void copyConstructorInfo(TypeSymbol other) { - { - Type info = primaryConstructor().info().cloneType( - primaryConstructor(), other.primaryConstructor()); - if (!isTypeAlias()) info = fixConstrType(info, other); - other.primaryConstructor().setInfo(info); - } - Symbol[] alts = allConstructors().alternativeSymbols(); - for (int i = 1; i < alts.length; i++) { - Symbol constr = other.newConstructor(alts[i].pos, alts[i].flags); - other.addConstructor(constr); - Type info = alts[i].info().cloneType(alts[i], constr); - if (!isTypeAlias()) info = fixConstrType(info, other); - constr.setInfo(info); - } - } - - private final Type fixConstrType(Type type, Symbol clone) { - switch (type) { - case MethodType(Symbol[] vparams, Type result): - result = fixConstrType(result, clone); - return new Type.MethodType(vparams, result); - case PolyType(Symbol[] tparams, Type result): - result = fixConstrType(result, clone); - return new Type.PolyType(tparams, result); - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym != this && isTypeAlias() && owner().isCompoundSym()) - return type; - assert sym == this: Debug.show(sym) + " != " + Debug.show(this); - return Type.typeRef(pre, clone, args); - case LazyType(): - return type; - default: - throw Debug.abort("unexpected constructor type:" + clone + ":" + type); - } - } - - /** add a constructor - */ - public final void addConstructor(Symbol constr) { - assert constr.isConstructor(): Debug.show(constr); - constructor = constructor.overloadWith(constr); - } - - /** Get primary constructor */ - public final Symbol primaryConstructor() { - return constructor.firstAlternative(); - } - - /** Get all constructors */ - public final Symbol allConstructors() { - return constructor; - } - - /** Get type parameters */ - public final Symbol[] typeParams() { - return primaryConstructor().info().typeParams(); - } - - /** Get value parameters */ - public final Symbol[] valueParams() { - return (kind == CLASS) ? primaryConstructor().info().valueParams() - : Symbol.EMPTY_ARRAY; - } - - /** Get type constructor */ - public final Type typeConstructor() { - if (tycon == null) - tycon = Type.typeRef(owner().thisType(), this, Type.EMPTY_ARRAY); - return tycon; - } - - public Symbol setOwner(Symbol owner) { - tycon = null; - constructor.setOwner0(owner); - switch (constructor.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) alts[i].setOwner0(owner); - } - return super.setOwner(owner); - } - - /** Get type */ - public final Type type() { - return primaryConstructor().type().resultType(); - } - public final Type getType() { - return primaryConstructor().type().resultType(); - } - - /** - * Get closure at start of current phase. The closure of a symbol - * is a list of types which contains the type of the symbol - * followed by all its direct and indirect base types, sorted by - * isLess(). - */ - public final Type[] closure() { - if (kind == ALIAS) return info().symbol().closure(); - if ((flags & CLOSURELOCK) != 0 && Global.instance.currentPhase.id <= Global.instance.PHASE.REFCHECK.id()) - throw new Type.Error("illegal cyclic reference involving " + this); - flags |= CLOSURELOCK; - Type[] result = (Type[])closures.getValue(this); - flags &= ~CLOSURELOCK; - return result; - } - - public void reset(Type completer) { - super.reset(completer); - closures.reset(); - tycon = null; - } - - - protected final Symbol cloneSymbolImpl(Symbol owner, int attrs) { - TypeSymbol clone = cloneTypeSymbolImpl(owner, attrs); - copyConstructorInfo(clone); - return clone; - } - - protected abstract TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs); -} - -public // !!! for java -Xfuture -final class AliasTypeSymbol extends TypeSymbol { - - /** Initializes this instance. */ - AliasTypeSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(ALIAS, owner, pos, flags, name, attrs); - } - - protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { - return new AliasTypeSymbol(owner, pos, flags, name, attrs); - } - -} - -final class AbsTypeSymbol extends TypeSymbol { - - private Type lobound = null; - private Type vubound = null; - - /** Initializes this instance. */ - AbsTypeSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(TYPE, owner, pos, flags, name, attrs); - allConstructors().setInfo(Type.MethodType(EMPTY_ARRAY, Type.typeRef(owner.thisType(), this, Type.EMPTY_ARRAY))); - } - - public Type loBound() { - initialize(); - return lobound == null ? Global.instance.definitions.ALL_TYPE() : lobound; - } - - public Type vuBound() { - initialize(); - return !isViewBounded() || vubound == null - ? Global.instance.definitions.ANY_TYPE() : vubound; - } - - public Symbol setLoBound(Type lobound) { - this.lobound = lobound; - return this; - } - - public Symbol setVuBound(Type vubound) { - this.vubound = vubound; - return this; - } - - protected TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { - TypeSymbol clone = new AbsTypeSymbol(owner, pos, flags, name, attrs); - clone.setLoBound(loBound()); - clone.setVuBound(vuBound()); - return clone; - } - -} - -/** A class for class symbols. */ -public class ClassSymbol extends TypeSymbol { - - /** The origin of this symbol */ - private SymbolOrigin origin; - - /** The given type of self, or NoType, if no explicit type was given. - */ - private Symbol thisSym = this; - - public Symbol thisSym() { return thisSym; } - - /** A cache for this.thisType() - */ - final private Type thistp = Type.ThisType(this); - - private final Symbol rebindSym; - - /** Initializes this instance. */ - ClassSymbol(Symbol owner, int pos, int flags, Name name, int attrs) { - super(CLASS, owner, pos, flags, name, attrs); - this.rebindSym = owner.newTypeAlias(pos, 0, Names.ALIAS(this)); - Type rebindType = new ClassAliasLazyType(); - this.rebindSym.setInfo(rebindType); - this.rebindSym.primaryConstructor().setInfo(rebindType); - } - - private class ClassAliasLazyType extends Type.LazyType { - public void complete(Symbol ignored) { - Symbol clasz = ClassSymbol.this; - Symbol alias = rebindSym; - Type prefix = clasz.owner().thisType(); - Type constrtype = clasz.type(); - constrtype = Type.MethodType(Symbol.EMPTY_ARRAY, constrtype); - constrtype = Type.PolyType(clasz.typeParams(), constrtype); - constrtype = constrtype.cloneType( - clasz.primaryConstructor(), alias.primaryConstructor()); - alias.primaryConstructor().setInfo(constrtype); - alias.setInfo(constrtype.resultType()); - } - } - - /** Creates the root class. */ - public static Symbol newRootClass(Global global) { - int pos = Position.NOPOS; - Name name = Names.ROOT.toTypeName(); - Symbol owner = Symbol.NONE; - int flags = JAVA | PACKAGE | FINAL; - int attrs = IS_ROOT; - Symbol clasz = new ClassSymbol(owner, pos, flags, name, attrs); - clasz.setInfo(global.getRootLoader()); - clasz.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, clasz.typeConstructor())); - // !!! Type.MethodType(Symbol.EMPTY_ARRAY, clasz.thisType())); - return clasz; - } - - /** Creates the this-type symbol associated to this class. */ - private final Symbol newThisType() { - return newTerm(pos, SYNTHETIC, Names.this_, IS_THISTYPE); - } - - /** Returns the origin of this symbol. */ - public SymbolOrigin getOrigin() { - return origin != null ? origin : super.getOrigin(); - } - - /** Sets the origin of this symbol. */ - public void setOrigin(SymbolOrigin origin) { - this.origin = origin; - } - - public Type thisType() { - Global global = Global.instance; - if (global.currentPhase.id > global.PHASE.ERASURE.id()) return type(); - return thistp; - } - - public Type typeOfThis() { - return thisSym.type(); - } - - public Symbol setTypeOfThis(Type tp) { - thisSym = newThisType(); - thisSym.setInfo(tp); - return this; - } - - /** Return the next enclosing class */ - public Symbol enclClass() { - return this; - } - - public Symbol caseFieldAccessor(int index) { - assert (flags & CASE) != 0 : this; - Scope.SymbolIterator it = info().members().iterator(); - Symbol sym = null; - if ((flags & JAVA) == 0) { - for (int i = 0; i <= index; i++) { - do { - sym = it.next(); - } while (sym != NONE && sym.kind != VAL || !sym.hasParamAccessorFlag() || !sym.isMethod()); - } - //System.out.println(this + ", case field[" + index + "] = " + sym);//DEBUG - } else { - sym = it.next(); - while (sym != NONE && (sym.flags & SYNTHETIC) == 0) { - //System.out.println("skipping " + sym); - sym = it.next(); - } - for (int i = 0; i < index; i++) - sym = it.next(); - //System.out.println("field accessor = " + sym);//DEBUG - } - assert sym != null : this; - return sym.stableAlternative(); - } - - public final Symbol rebindSym() { - return rebindSym; - } - - public void reset(Type completer) { - super.reset(completer); - thisSym = this; - } - - protected final TypeSymbol cloneTypeSymbolImpl(Symbol owner, int attrs) { - assert !isModuleClass(): Debug.show(this); - ClassSymbol clone = new ClassSymbol(owner, pos, flags, name, attrs); - if (thisSym != this) clone.setTypeOfThis(new ClonedThisSymLazyType()); - return clone; - } - - private final class ClonedThisSymLazyType extends Type.LazyType { - - public Type fix(Type type, Symbol clasz, Symbol clone, Type.Map map) { - switch (type) { - case ThisType(_): - return type; - case SingleType(_, _): - return map.apply(type); - case TypeRef(Type prefix, Symbol symbol, Type[] args): - if (symbol == clasz) type = Type.typeRef(prefix, clone, args); - return map.apply(type); - default: - throw Debug.abortIllegalCase(type); - } - } - - public Type getTypeFor(Symbol symbol) { - Symbol clasz = ClassSymbol.this; - Symbol clone = symbol.owner(); - Type.Map map = - Type.getSubst(clasz.typeParams(), clone.typeParams()); - Type self = clasz.type(); - Type type = clasz.typeOfThis(); - switch (type) { - case CompoundType(Type[] parents1, Scope members): - assert members.isEmpty(): Debug.show(clasz, type); - int length = parents1.length; - Type[] parents2 = new Type[parents1.length]; - boolean has_self = false; - for (int i = 0; i < parents2.length; i++) { - if (self.isSameAs(parents1[i])) { - assert !has_self: Debug.show(clasz, clone, type,""+i); - parents2[i] = clone.type(); - has_self = true; - } else { - parents2[i] = fix(parents1[i], clasz, clone, map); - } - } - if (!has_self) { - parents2 = Type.cloneArray(parents2, 1); - parents2[parents2.length - 1] = clone.type(); - } - return Type.compoundTypeWithOwner(clone, parents2, members); - default: - if (self.isSameAs(type)) return clone.type(); - Type[] parents = {fix(type, clasz, clone, map), clone.type()}; - return Type.compoundTypeWithOwner(clone, parents, new Scope()); - } - } - - public void complete(Symbol symbol) { - symbol.setInfo(getTypeFor(symbol)); - } - - } - -} - -/** - * A class for module class symbols - * - * @see Symbol#sourceModule() - */ -public final class ModuleClassSymbol extends ClassSymbol { - - /** The source module */ - private final ModuleSymbol module; - - /** Initializes this instance. */ - ModuleClassSymbol(ModuleSymbol module) { - super(module.owner(), module.pos, - (module.flags & MODULE2CLASSFLAGS) | MODUL | FINAL, - module.name.toTypeName(), 0); - primaryConstructor().flags |= PRIVATE; - primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, typeConstructor())); - this.module = module; - } - - public ModuleSymbol sourceModule() { - return module; - } - -} - -/** - * A class for linked class symbols - * - * @see Symbol#linkedModule() - */ -public // !!! for java -Xfuture -final class LinkedClassSymbol extends ClassSymbol { - - /** The linked module */ - private final LinkedModuleSymbol module; - - /** Initializes this instance. */ - LinkedClassSymbol(Symbol owner, int flags, Name name) { - super(owner, Position.NOPOS, flags, name, 0); - this.module = new LinkedModuleSymbol(this); - } - - public ModuleSymbol linkedModule() { - return module; - } - -} - -/** The class of Symbol.NONE - */ -public // !!! for java -Xfuture -final class NoSymbol extends Symbol { - - /** Constructor */ - public NoSymbol() { - super(Kinds.NONE, null, Position.NOPOS, 0, Names.NOSYMBOL, 0); - super.setInfo(Type.NoType); - } - - /** Returns the origin of this symbol. */ - public SymbolOrigin getOrigin() { - return SymbolOrigin.Unknown; - } - - /** Set type */ - public Symbol setInfo(Type info) { - assert info == Type.NoType : info; - return this; - } - - /** Return the next enclosing class */ - public Symbol enclClass() { - return this; - } - - /** Return the next enclosing method */ - public Symbol enclMethod() { - return this; - } - - public Symbol owner() { - throw new ApplicationError(); - } - - public Type thisType() { - return Type.NoPrefix; - } - - public void reset(Type completer) { - } - - protected Symbol cloneSymbolImpl(Symbol owner, int attrs) { - throw Debug.abort("illegal clone", this); - } - -} - -/** An exception for signalling cyclic references. - */ -public class CyclicReference extends Type.Error { - public Symbol sym; - public Type info; - public CyclicReference(Symbol sym, Type info) { - super("illegal cyclic reference involving " + sym); - this.sym = sym; - this.info = info; - } -} - -/** A base class for values indexed by phases. */ -public // !!! for java -Xfuture -abstract class IntervalList { - - /** Interval starts at start of phase "start" (inclusive) */ - public final Phase start; - /** Interval ends at start of phase "limit" (inclusive) */ - private Phase limit; - - public IntervalList(IntervalList prev, Phase start) { - this.start = start; - this.limit = start; - assert start != null && (prev == null || prev.limit.next == start) : - Global.instance.currentPhase + " - " + prev + " - " + start; - } - - public Phase limit() { - return limit; - } - - public void setLimit(Phase phase) { - assert phase != null && !phase.precedes(start) : start + " - " + phase; - limit = phase; - } - - public String toString() { - return "[" + start + "->" + limit + "]"; - } - -} - -/** A class for types indexed by phases. */ -public // !!! for java -Xfuture -class TypeIntervalList extends IntervalList { - - /** Previous interval */ - public final TypeIntervalList prev; - /** Info valid during this interval */ - public final Type info; - - public TypeIntervalList(TypeIntervalList prev, Type info, Phase start) { - super(prev, start); - this.prev = prev; - this.info = info; - assert info != null; - } - -} diff --git a/sources/scalac/symtab/SymbolCloner.java b/sources/scalac/symtab/SymbolCloner.java deleted file mode 100644 index d07717bdc7..0000000000 --- a/sources/scalac/symtab/SymbolCloner.java +++ /dev/null @@ -1,243 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.HashMap; -import java.util.Map; - -import scalac.util.Debug; - -/** - * This class implements a symbol cloner. It automatically determines - * the new owner of cloned symbols, clones their type and keeps track - * of all cloned symbols. Clone a type means clone all symbol declared - * in that type (for example parameters of a MethodType). - */ -public class SymbolCloner { - - //######################################################################## - // Public Fields - - /** A table that maps owners of symbols to owners of cloned symbols */ - public final Map/*<Symbol,Symbol*/ owners; - - /** A map<cloned,clone> into which cloned symbols are stored */ - public final Map/*<Symbol,Symbol*/ clones; - - //######################################################################## - // Public Constructor - - /** Initializes a new instance. */ - public SymbolCloner() { - this(new HashMap()); - } - - /** Initializes a new instance. */ - public SymbolCloner(Map owners) { - this(owners, new HashMap()); - } - - /** Initializes a new instance. */ - public SymbolCloner(Map owners, Map clones) { - this.owners = owners; - this.clones = clones; - } - - //######################################################################## - // Public Methods - Cloning symbols - - /** - * Returns the owner for the clone of the given symbol. The - * default implementation returns the clone of the symbol's owner - * if that owner has been cloned or else returns the owner - * associated to the symbol's owner in the owner table. - */ - public Symbol getOwnerFor(Symbol symbol) { - Symbol oldowner = symbol.owner(); - Object newowner = clones.get(oldowner); - if (newowner == null) newowner = owners.get(oldowner); - assert newowner != null : Debug.show(symbol); - return (Symbol)newowner; - } - - /** Clones the given symbol but not its type. */ - public Symbol cloneSymbolWithoutType(Symbol symbol) { - assert !symbol.isPrimaryConstructor(): Debug.show(symbol); - assert !symbol.isClassType() || symbol.isCompoundSym(): Debug.show(symbol); // !!! isCompoundSym() - assert !owners.containsKey(symbol): Debug.show(symbol); - assert !clones.containsKey(symbol): - Debug.show(symbol) + " -> " + Debug.show(clones.get(symbol)); - Symbol clone = symbol.cloneSymbol(getOwnerFor(symbol)); - clones.put(symbol, clone); - return clone; - } - - /** Clones the given symbols but not their types. */ - public Symbol[] cloneSymbolsWithoutTypes(Symbol[] symbols) { - if (symbols.length == 0) return Symbol.EMPTY_ARRAY; - Symbol[] clones = new Symbol[symbols.length]; - for (int i = 0; i < clones.length; i++) - clones[i] = cloneSymbolWithoutType(symbols[i]); - return clones; - } - - /** Clones the given scope but not the type of its members. */ - public Scope cloneScopeWithoutTypes(Scope scope) { - Scope clone = new Scope(); - for (Scope.SymbolIterator i = scope.iterator(); - i.hasNext(); ) { - clone.enterOrOverload(cloneSymbolWithoutType(i.next())); - } - return clone; - } - - /** Clones the given symbol and its type. */ - public Symbol cloneSymbol(Symbol symbol) { - Symbol clone = cloneSymbolWithoutType(symbol); - clone.setType(cloneType(symbol.info())); - return clone; - } - - /** Clones the given symbols and their types. */ - public Symbol[] cloneSymbols(Symbol[] symbols) { - Symbol[] clones = cloneSymbolsWithoutTypes(symbols); - for (int i = 0; i < clones.length; i++) - clones[i].setType(cloneType(symbols[i].info())); - return clones; - } - - /** Clones the given scope and the type of its members. */ - public Scope cloneScope(Scope scope) { - Scope clone = cloneScopeWithoutTypes(scope); - for (Scope.SymbolIterator i = scope.iterator(); - i.hasNext(); ) { - Symbol member = i.next(); - member.setType(cloneType(member.info())); - } - return clone; - } - - /** Clones the given type. */ - public Type cloneType(Type type) { - return cloner.apply(type); - } - - /** Clones the given types. */ - public Type[] cloneTypes(Type[] types) { - Type[] clones = new Type[types.length]; - for (int i = 0; i < types.length; i++) - clones[i] = cloner.apply(types[i]); - return clones; - } - - //######################################################################## - // Public Methods - Mapping symbols - - /** - * Returns the clone of the specified symbol if it has been cloned - * and the specified symbol otherwise. - */ - public Symbol mapSymbol(Symbol symbol) { - Object clone = clones.get(symbol); - return clone != null ? (Symbol)clone : symbol; - } - - /** Replaces all cloned symbols by clones in given type. */ - public Type mapType(Type type) { - return mapper.apply(type); - } - - /** Returns the type map built during symbol cloning. */ - // used in scalac/ast/TreeCloner.java - public Type.Map getTypeMap() { - return cloner; - } - - //######################################################################## - // Private Method - - private Symbol getCompoundClone(Symbol symbol) { - assert symbol.isCompoundSym(): Debug.show(symbol); - assert !owners.containsKey(symbol): Debug.show(symbol); - assert !clones.containsKey(symbol): - Debug.show(symbol) + " -> " + Debug.show(clones.get(symbol)); - Symbol owner = (Symbol)clones.get(symbol.owner()); - if (owner == null) owner = (Symbol)owners.get(symbol.owner()); - if (owner == null) owner = symbol.owner(); - Symbol clone = symbol.cloneSymbol(owner); - clones.put(symbol, clone); - return clone; - } - - //######################################################################## - // Private Class - Type mapper - - /** The type mapper Type.Map */ - private final Type.Map mapper = new TypeMapper(); - private class TypeMapper extends Type.Map { public Type apply(Type type) { - switch (type) { - case ErrorType: - case NoType: - case NoPrefix: - return type; - case ThisType(Symbol symbol): - Symbol clone = (Symbol)clones.get(symbol); - if (clone == null) return type; - return Type.ThisType(clone); - case SingleType(Type prefix, Symbol symbol): - Symbol clone = (Symbol)clones.get(symbol); - if (clone == null) return map(type); - return Type.singleType(apply(prefix), clone); - case ConstantType(_, _): - return map(type); - case TypeRef(Type prefix, Symbol symbol, Type[] args): - Symbol clone = (Symbol)clones.get(symbol); - if (clone == null) return map(type); - return Type.typeRef(apply(prefix), clone, map(args)); - case CompoundType(Type[] parts, Scope members): - Symbol clone = (Symbol)clones.get(type.symbol()); - // !!! if (clone == null) return map(type); - if (clone == null) clone = type.symbol(); - return Type.compoundType(map(parts), members, clone); - case MethodType(Symbol[] vparams, Type result): - return Type.MethodType(vparams, apply(result)); - case PolyType(Symbol[] tparams, Type result): - return Type.PolyType(tparams, apply(result)); - case UnboxedType(_): - return type; - case UnboxedArrayType(_): - return map(type); - default: - throw Debug.abort("illegal case", type); - } - }} - - //######################################################################## - // Private Class - Type cloner - - /** The type cloner Type.Map */ - private final Type.Map cloner = new TypeCloner(); - private class TypeCloner extends TypeMapper { public Type apply(Type type){ - switch (type) { - case CompoundType(Type[] parts, Scope members): - Symbol clone = /* !!! getCompoundClone */(type.symbol()); - return Type.compoundType(map(parts), /* !!! cloneScope */(members), clone); - case MethodType(Symbol[] vparams, Type result): - Symbol[] clones = cloneSymbols(vparams); - return Type.MethodType(clones, apply(result)); - case PolyType(Symbol[] tparams, Type result): - Symbol[] clones = cloneSymbols(tparams); - return Type.PolyType(clones, apply(result)); - default: - return super.apply(type); - } - }} - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolComparator.java b/sources/scalac/symtab/SymbolComparator.java deleted file mode 100644 index c703663bf4..0000000000 --- a/sources/scalac/symtab/SymbolComparator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.Comparator; - -/** This class implements a symbol comparator. */ -public class SymbolComparator implements Comparator { - - //######################################################################## - // Public Constants - - /** The unique instance of this class */ - public static final Comparator instance = new SymbolComparator(); - - //######################################################################## - // Private Constructors - - /** Initializes this instance. */ - private SymbolComparator() {} - - //######################################################################## - // Public Methods - - /** Compares the two arguments which must inherit from Symbol. */ - public int compare(Object lf, Object rg) { - return lf == rg ? 0 : ((Symbol)lf).isLess((Symbol)rg) ? -1 : 1; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolLoader.java b/sources/scalac/symtab/SymbolLoader.java deleted file mode 100644 index 2f656c92e0..0000000000 --- a/sources/scalac/symtab/SymbolLoader.java +++ /dev/null @@ -1,168 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.io.IOException; - -import scalac.Global; -import scalac.Phase; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This class implements common behaviors of lazy types used to load - * symbols from external sources (containing source or compiled code). - */ -public abstract class SymbolLoader extends Type.LazyType { - - //######################################################################## - // Public Fields - - /** The global environment */ - public final Global global; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public SymbolLoader(Global global) { - this.global = global; - } - - //######################################################################## - // Public Methods - - /** - * Completes the specified symbol. More precisely, it completes - * all symbols related to the root symbol of the specified - * symbol. It is guaranteed that after this method call all these - * symbols are initialized (or at least that their info does no - * longer contain this lazy type). - * - * The root symbol of a symbol is: - * - the root symbol of the constructed class, if it's a - * constructor, - * - the root symbol of the source module, if it's a module class, - * - the linked class, if it's a module with a linked class, - * - itself if it's a class or a module with no linked class, - * - undefined otherwise. - * - * The symbols related to a symbol include: - * - the symbol itself, - * - its constructor (allConstructors()), if it's a class, - * - the symbols related to its linked module, if there is one. - * - the symbols related to its module class, if it's a module, - */ - public final void complete(Symbol symbol) { - Symbol root = getRootSymbol(symbol); - try { - Phase phase = global.currentPhase; - global.currentPhase = global.PHASE.ANALYZER.phase(); - global.timer.start(); - String source = doComplete(root); - global.timer.stop("loaded " + source); - global.currentPhase = phase; - checkValidity(root, source); - } catch (IOException exception) { - global.timer.drop(); - if (global.debug) exception.printStackTrace(); - String error = "error while loading " + symbol; - String message = exception.getMessage(); - error = message != null ? error + ", " + message : "i/o " + error; - global.error(error); - } - initializeRoot(root); - } - - //######################################################################## - // Protected Methods - - /** - * Performs the actual loading and returns the name of the - * external source. It is guaranteed that the argument of this - * method is always a root symbol - * - * @see complete(Symbol) - */ - protected abstract String doComplete(Symbol root) throws IOException; - - //######################################################################## - // Private Methods - - /** - * Returns the root symbol of the specified symbol. - * - * @see complete(Symbol) - */ - private Symbol getRootSymbol(Symbol symbol) { - if (symbol.isConstructor()) - return getRootSymbol(symbol.constructorClass()); - if (symbol.isModuleClass()) - return getRootSymbol(symbol.sourceModule()); - if (symbol.isModule() && symbol.linkedClass() != null) - return symbol.linkedClass(); - assert symbol.isClassType() || symbol.isModule(): Debug.show(symbol); - return symbol; - } - - /** - * Checks that at least the specified root symbol or its linked - * module, if any, has been initialized and signals an error - * otherwise. - * - * @see complete(Symbol) - */ - private void checkValidity(Symbol root, String source) { - if (root.rawInfo() != this) return; - String what; - if (!root.isClassType() || root.linkedModule() == null) { - what = "does not define " + root; - } else { - if (root.linkedModule().moduleClass().rawInfo() != this) return; - what = "defines neither " + root + " nor " + root.linkedModule(); - } - global.error(source + " " + what); - } - - /** - * Initializes all symbols related to the specified root symbol - * and whose info is this instance. - * - * @see complete(Symbol) - */ - private void initializeRoot(Symbol root) { - if (root.isClassType()) { - initializeClass(root); - if (root.linkedModule() != null) - initializeRoot(root.linkedModule()); - } else { - initializeSymbol(root); - if (root.isModule()) initializeClass(root.moduleClass()); - } - } - - /** - * Initializes the specified class and its constructor if their - * info is this instance. - */ - private void initializeClass(Symbol clasz) { - initializeSymbol(clasz); - initializeSymbol(clasz.allConstructors()); - } - - /** Initializes the symbol if its info is this instance. */ - private void initializeSymbol(Symbol symbol) { - if (symbol.rawInfo() != this) return; - symbol.setInfo(symbol.isModule() ? Type.NoType : Type.ErrorType); - if (symbol.isConstructor()) symbol.flags |= Modifiers.PRIVATE; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolNameWriter.java b/sources/scalac/symtab/SymbolNameWriter.java deleted file mode 100644 index af57b23933..0000000000 --- a/sources/scalac/symtab/SymbolNameWriter.java +++ /dev/null @@ -1,306 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import scalac.Global; -import scalac.util.NameTransformer; - -/** - * This class provides methods to turn symbol names into strings. - * - * There are several kinds of owner/symbol relationships: - * - root/symbol - * - package/symbol - * - class/class - * - class/member - * - owner/parameter - * - none/symbol - * - error/symbol - * - other relationships - * - * The separator to use for each of these relationships are specified - * independently. When a separator is set to '\0' the corresponding - * owners are dropped from the resulting string. ROOT, NONE and ERROR - * owners are also dropped. The choice of the separator to use is done - * by the method "getOwnerSymbolSeparator(Symbol)" - * - * Symbol names are usually encoded. There is support to decode these - * names. - * - * Each symbol has an unique identifier. There is support to print - * these unique identifiers. - */ -public class SymbolNameWriter { - - //######################################################################## - // Private Fields - - /** The string buffer */ - private StringBuffer buffer; - - /** The root/symbol separator */ - private char root; - - /** The package/symbol separator */ - private char peckage; - - /** The class/class separator */ - private char clasz; - - /** The class/member separator */ - private char member; - - /** The owner/parameter separator */ - private char parameter; - - /** The none/symbol separator */ - private char none; - - /** The error/symbol separator */ - private char error; - - /** The other relationships separator */ - private char other; - - /** The name decoding status */ - private boolean decode; - - /** The symbol/unique-identifier separator */ - private char unique; - - /** The number of pending characters */ - private int pending; - - /** The prefix for the current operation (null if none) */ - private String prefix; - - //######################################################################## - // Public Constructors - - /** - * Initializes this instance with an empty string buffer. This is - * equivalent to calling "SymbolStringifier(null)". - */ - public SymbolNameWriter() { - this(null); - } - - /** - * Initializes this instance with given string buffer. All - * separators are set to '.' excepted the root/symbol separator - * which is set to '\0'. The symbol name decoding is disabled. The - * unique identifier printing is disabled. - */ - public SymbolNameWriter(StringBuffer buffer) { - setStringBuffer(buffer).setAllSeparators('.').setRootSeparator('\0'); - } - - //######################################################################## - // Public Method - Configuration operations - - /** Sets the string buffer. */ - public SymbolNameWriter setStringBuffer(StringBuffer buffer) { - this.buffer = buffer; - return this; - } - - /** Sets all separators. */ - public SymbolNameWriter setAllSeparators(char separator) { - setRootSeparator(separator); - setPackageSeparator(separator); - setClassSeparator(separator); - setMemberSeparator(separator); - setParameterSeparator(separator); - setNoneSeparator(separator); - setErrorSeparator(separator); - setOtherSeparator(separator); - return this; - } - - /** Sets the root/symbol separator. */ - public SymbolNameWriter setRootSeparator(char separator) { - this.root = separator; - return this; - } - - /** Sets the package/symbol separator. */ - public SymbolNameWriter setPackageSeparator(char separator) { - this.peckage = separator; - return this; - } - - /** Sets the class/class separator. */ - public SymbolNameWriter setClassSeparator(char separator) { - this.clasz = separator; - return this; - } - - /** Sets the class/member separator. */ - public SymbolNameWriter setMemberSeparator(char separator) { - this.member = separator; - return this; - } - - /** Sets the owner/parameter separator. */ - public SymbolNameWriter setParameterSeparator(char separator) { - this.parameter = separator; - return this; - } - - /** Sets the none/symbol separator. */ - public SymbolNameWriter setNoneSeparator(char separator) { - this.none = separator; - return this; - } - - /** Sets the error/symbol separator. */ - public SymbolNameWriter setErrorSeparator(char separator) { - this.error = separator; - return this; - } - - /** Sets the other relationships separator. */ - public SymbolNameWriter setOtherSeparator(char separator) { - this.other = separator; - return this; - } - - /** Sets the name decoding status. */ - public SymbolNameWriter setNameDecoding(boolean decode) { - this.decode = decode; - return this; - } - - /** Sets the symbol/unique-identifier separator. */ - public SymbolNameWriter setUniqueSeparator(char separator) { - this.unique = separator; - return this; - } - - //######################################################################## - // Public Method - To string operations - - /** Returns the string formed by the symbol. */ - public String toString(Symbol symbol) { - assert buffer == null; - String string = appendSymbol(symbol).toString(); - setStringBuffer(null); - return string; - } - - /** Returns the string formed by the prefix and symbol. */ - public String toString(String prefix, Symbol symbol) { - assert buffer == null; - String string = appendSymbol(prefix, symbol).toString(); - setStringBuffer(null); - return string; - } - - /** Returns the string formed by the symbol and suffix. */ - public String toString(Symbol symbol, String suffix) { - assert buffer == null; - String string = appendSymbol(symbol, suffix).toString(); - setStringBuffer(null); - return string; - } - - /** Returns the string formed by the prefix, symbol and suffix. */ - public String toString(String prefix, Symbol symbol, String suffix) { - assert buffer == null; - String string = appendSymbol(prefix, symbol, suffix).toString(); - setStringBuffer(null); - return string; - } - - //######################################################################## - // Public Method - Append operations - - /** Appends given symbol. */ - public StringBuffer appendSymbol(Symbol symbol) { - String name = getSymbolName(symbol); - this.pending += name.length(); - char separator = getSymbolSeparator(symbol); - return appendPrefix(symbol.owner(), separator).append(name);; - } - - /** Appends given prefix and symbol. */ - public StringBuffer appendSymbol(String prefix, Symbol symbol) { - assert this.prefix == null && prefix != null; - this.prefix = prefix; - return appendSymbol(symbol); - } - - /** Appends given symbol and suffix. */ - public StringBuffer appendSymbol(Symbol symbol, String suffix) { - this.pending += suffix.length(); - return appendSymbol(symbol).append(suffix); - } - - /** Appends given prefix, symbol and suffix. */ - public StringBuffer appendSymbol(String prefix, Symbol symbol, - String suffix) - { - assert this.prefix == null && prefix != null; - this.prefix = prefix; - this.pending += suffix.length(); - return appendSymbol(symbol).append(suffix); - } - - /** Appends prefix formed by given owner and separator. */ - public StringBuffer appendPrefix(Symbol owner, char separator) { - if (separator == 0) return getStringBuffer(); - this.pending += 1; - return appendSymbol(owner).append(separator); - } - - //######################################################################## - // Public Method - Query operations - - /** Returns the name to use for given symbol. */ - public String getSymbolName(Symbol symbol) { - String name = symbol.name.toString(); - if (decode) name = NameTransformer.decode(name); - if (unique != 0) name = name + unique + symbol.id; - return name; - } - - /** Returns the owner/symbol separator to use for given symbol. */ - public char getSymbolSeparator(Symbol symbol) { - if (symbol.isRoot() || symbol.isNone() || symbol.isError()) return 0; - if (symbol.isParameter()) return parameter; - Symbol owner = symbol.owner(); - if (owner.isRoot()) return root; - if (owner.isNone()) return none; - if (owner.isError()) return error; - if (owner.isPackageClass()) return peckage; - if (owner.isClass()) return symbol.isClass() ? clasz : member; - return other; - } - - /** Returns the string buffer. */ - public StringBuffer getStringBuffer() { - if (prefix != null) pending += prefix.length(); - if (buffer == null) { - this.buffer = new StringBuffer(pending); - } else { - buffer.ensureCapacity(buffer.length() + pending); - } - if (prefix != null) buffer.append(prefix); - this.pending = 0; - this.prefix = null; - return buffer; - } - - /** Returns the content of the string buffer. */ - public String toString() { - return buffer == null ? "" : buffer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolOrigin.java b/sources/scalac/symtab/SymbolOrigin.java deleted file mode 100644 index 29baa08a79..0000000000 --- a/sources/scalac/symtab/SymbolOrigin.java +++ /dev/null @@ -1,52 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import ch.epfl.lamp.compiler.msil.Assembly; -import scala.tools.util.AbstractFile; -import scalac.CompilationUnit; - -/** Instances of this class designate the origin of a symbol. */ -public class SymbolOrigin { - - //######################################################################## - // Public Cases - - /** Designates an unknown source */ - public case Unknown; - - /** Designates a directory */ - public case Directory(AbstractFile file); - - /** Designates a JVM class file (the source file may be null) */ - public case ClassFile(AbstractFile file, String sourcefile); - - /** Designates a Scala symbl file */ - public case SymblFile(AbstractFile file); - - /** Designates a Scala source file */ - public case ScalaFile(AbstractFile file); - - /** Designates a Scala compilation unit */ - public case ScalaUnit(CompilationUnit unit); - - /** Designates a CLR assembly */ - public case CLRAssembly(Assembly assembly); - - //######################################################################## - // Public Methods - - /** Records the source file attribute. */ - public void setSourceFileAttribute(String sourcefile) { - if (this instanceof SymbolOrigin.ClassFile) - ((SymbolOrigin.ClassFile)this).sourcefile = sourcefile; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolSubstTypeMap.java b/sources/scalac/symtab/SymbolSubstTypeMap.java deleted file mode 100644 index 144181faac..0000000000 --- a/sources/scalac/symtab/SymbolSubstTypeMap.java +++ /dev/null @@ -1,199 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; - -import ch.epfl.lamp.util.ForwardingMap; - -import scalac.util.Debug; - -/** A type map that substitues symbols and types for symbols. */ -public class SymbolSubstTypeMap extends Type.Map { - - //######################################################################## - // Private Fields - - /** A table containing the symbol to symbol substitutions */ - private Map/*<Symbol, Symbol>*/ symbols; - - /** A table containing the symbol to type substitutions */ - private Map/*<Symbol, Type>*/ types; - - //######################################################################## - // Public Constructors - - public SymbolSubstTypeMap() { - this.symbols = new HashMap(); - this.types = new HashMap(); - } - - public SymbolSubstTypeMap(Map symbols, Map types) { - this(); - insertSymbol(symbols); - insertType(types); - } - - public SymbolSubstTypeMap(SymbolSubstTypeMap other) { - this(); - insertSymbol(other.symbols); - insertType(other.types); - } - - //######################################################################## - // Public Methods - Inserting and removing symbol to symbol substitutions - - public void insertSymbol(Symbol[] keys, Symbol[] values) { - assert keys.length == values.length : keys.length+" != "+values.length; - for (int i = 0; i < keys.length; i++) insertSymbol(keys[i], values[i]); - } - - public void insertSymbol(Symbol key, Symbol value) { - assert !symbols.containsKey(key) : Debug.show(key); - assert !types.containsKey(key) : Debug.show(key); - symbols.put(key, value); - } - - public void insertSymbol(Map map) { - assert checkLeftContainsNoKeyFromRight(symbols, map); - assert checkLeftContainsNoKeyFromRight(types, map); - symbols.putAll(map); - } - - public void removeSymbol(Symbol[] keys) { - for (int i = 0; i < keys.length; i++) removeSymbol(keys[i]); - } - - public void removeSymbol(Symbol key) { - symbols.remove(key); - } - - public void removeSymbol(Set keys) { - symbols.keySet().removeAll(keys); - } - - public Symbol lookupSymbol(Symbol key) { - return (Symbol)symbols.get(key); - } - - public Map getSymbols() { - return new ForwardingMap(symbols) { - public Object put(Object key, Object value) { - insertSymbol((Symbol)key, (Symbol)value); - return null; - } - public void putAll(Map map) { - insertSymbol(map); - } - }; - } - - //######################################################################## - // Public Methods - Inserting and removing symbol to type substitutions - - public void insertType(Symbol[] keys, Type[] values) { - assert keys.length == values.length : keys.length+" != "+values.length; - for (int i = 0; i < keys.length; i++) insertType(keys[i], values[i]); - } - - public void insertType(Symbol key, Type value) { - assert !symbols.containsKey(key) : Debug.show(key); - assert !types.containsKey(key) : Debug.show(key); - types.put(key, value); - } - - public void insertType(Map map) { - assert checkLeftContainsNoKeyFromRight(symbols, map); - assert checkLeftContainsNoKeyFromRight(types, map); - types.putAll(map); - } - - public void removeType(Symbol[] keys) { - for (int i = 0; i < keys.length; i++) removeType(keys[i]); - } - - public void removeType(Symbol key) { - types.remove(key); - } - - public void removeType(Set keys) { - types.keySet().removeAll(keys); - } - - public Type lookupType(Symbol key) { - return (Type)types.get(key); - } - - public Map getTypes() { - return new ForwardingMap(types) { - public Object put(Object key, Object value) { - insertType((Symbol)key, (Type)value); - return null; - } - public void putAll(Map map) { - insertType(map); - } - }; - } - - //######################################################################## - // Public Methods - Applying the substitutions - - public Type apply(Type type) { - switch (type) { - - case TypeRef(NoPrefix, Symbol symbol, Type[] args): - Object value = types.get(symbol); - if (value != null) return (Type)value; - value = symbols.get(symbol); - if (value == null) return super.map(type); - Type prefix = ((Type.TypeRef)type).pre; - return Type.typeRef(apply(prefix), (Symbol)value, map(args)); - - case SingleType(NoPrefix, Symbol symbol): - Object value = types.get(symbol); - if (value != null) return (Type)value; - value = symbols.get(symbol); - if (value == null) return super.map(type); - Type prefix = ((Type.SingleType)type).pre; - return Type.singleType(apply(prefix), (Symbol)value); - - case ThisType(Symbol symbol): - Object value = symbols.get(symbol); - if (value == null) return super.map(type); - return Type.ThisType((Symbol)value); - - default: - return super.map(type); - } - } - - //######################################################################## - // Public Methods - Printing - - public String toString() { - return "{ symbols=" + symbols + " types=" + types + " }"; - } - - //######################################################################## - // Private Function - - private static boolean checkLeftContainsNoKeyFromRight(Map lf, Map rg) { - for (Iterator i = rg.keySet().iterator(); i.hasNext(); ) { - Object key = i.next(); - assert !lf.containsKey(key) : Debug.show(key); - } - return true; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/SymbolTablePrinter.java b/sources/scalac/symtab/SymbolTablePrinter.java deleted file mode 100644 index ad6fdbf1cd..0000000000 --- a/sources/scalac/symtab/SymbolTablePrinter.java +++ /dev/null @@ -1,602 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab; - -import java.io.StringWriter; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.atree.AConstant; -import scalac.symtab.Type.Constraint; -import scalac.symtab.Scope.SymbolIterator; -import scalac.util.Name; -import scalac.util.NameTransformer; -import scalac.util.Debug; - -/** This class provides methods to print symbols and types. */ -public class SymbolTablePrinter { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The underlying code printer */ - private final CodePrinter printer; - - //######################################################################## - // Public Constructors - - /** Creates a new instance */ - public SymbolTablePrinter() { - this((String)null); - } - - /** Creates a new instance */ - public SymbolTablePrinter(String step) { - this(Global.instance, new CodePrinter(step)); - } - - /** Creates a new instance */ - public SymbolTablePrinter(CodePrinter printer) { - this(Global.instance, printer); - } - - /** Creates a new instance */ - public SymbolTablePrinter(Global global, CodePrinter printer) { - this.global = global; - this.printer = printer; - } - - //######################################################################## - // Public Methods - Getting & Setting - - /** Returns the underlying code printer. */ - public CodePrinter getCodePrinter() { - return printer; - } - - //######################################################################## - // Public Methods - Formatting - - /** Increases the indentation level by one. */ - public SymbolTablePrinter indent() { - printer.indent(); - return this; - } - - /** Decreases the indentation level by one. */ - public SymbolTablePrinter undent() { - printer.undent(); - return this; - } - - /** Inserts a new line. */ - public SymbolTablePrinter line() { - printer.line(); - return this; - } - - /** Inserts a white space. */ - public SymbolTablePrinter space() { - printer.space(); - return this; - } - - //######################################################################## - // Public Methods - Printing simple values - - /** Prints a new line. */ - public SymbolTablePrinter println() { - printer.println(); - return this; - } - - /** Prints the boolean value followed by a new line. */ - public SymbolTablePrinter println(boolean value) { - printer.println(value); - return this; - } - - /** Prints the byte value followed by a new line. */ - public SymbolTablePrinter println(byte value) { - printer.println(value); - return this; - } - - /** Prints the short value followed by a new line. */ - public SymbolTablePrinter println(short value) { - printer.println(value); - return this; - } - - /** Prints the char value followed by a new line. */ - public SymbolTablePrinter println(char value) { - printer.println(value); - return this; - } - - /** Prints the int value followed by a new line. */ - public SymbolTablePrinter println(int value) { - printer.println(value); - return this; - } - - /** Prints the long value followed by a new line. */ - public SymbolTablePrinter println(long value) { - printer.println(value); - return this; - } - - /** Prints the float value followed by a new line. */ - public SymbolTablePrinter println(float value) { - printer.println(value); - return this; - } - - /** Prints the double value followed by a new line. */ - public SymbolTablePrinter println(double value) { - printer.println(value); - return this; - } - - /** Prints the string followed by a new line. */ - public SymbolTablePrinter println(String value) { - printer.println(value); - return this; - } - - /** Prints the boolean value. */ - public SymbolTablePrinter print(boolean value) { - printer.print(value); - return this; - } - - /** Prints the byte value. */ - public SymbolTablePrinter print(byte value) { - printer.print(value); - return this; - } - - /** Prints the short value. */ - public SymbolTablePrinter print(short value) { - printer.print(value); - return this; - } - - /** Prints the char value. */ - public SymbolTablePrinter print(char value) { - printer.print(value); - return this; - } - - /** Prints the int value. */ - public SymbolTablePrinter print(int value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public SymbolTablePrinter print(long value) { - printer.print(value); - return this; - } - - /** Prints the float value. */ - public SymbolTablePrinter print(float value) { - printer.print(value); - return this; - } - - /** Prints the long value. */ - public SymbolTablePrinter print(double value) { - printer.print(value); - return this; - } - - /** Prints the string. */ - public SymbolTablePrinter print(String value) { - printer.print(value); - return this; - } - - //######################################################################## - // Public Methods - Printing scopes - - /** Prints the members of the given scope. */ - public SymbolTablePrinter printScope(Scope scope) { - return printScope(scope, false); - } - - /** Prints the members of the given scope. */ - public SymbolTablePrinter printScope(Scope scope, boolean lazy) { - boolean first = true; - for (SymbolIterator i = scope.iterator(); i.hasNext(); ) { - Symbol member = i.next(); - if (!mustShowMember(member)) continue; - if (first) print("{").indent(); else print(", "); - first = false; - line().printSignature(member); - } - if (!first) line().undent().print("}"); else if (!lazy) print("{}"); - return this; - } - - /** - * Returns true iff the given member must be printed. The default - * implementation always returns true. - */ - public boolean mustShowMember(Symbol member) { - return true; - } - - //######################################################################## - // Public Methods - Printing symbols - - /** - * Returns the string representation of the kind of the given - * symbol or null if there is no such representation. - */ - public String getSymbolKind(Symbol symbol) { - switch (symbol.kind) { - case Kinds.NONE: - return null; - case Kinds.CLASS: - if (symbol.isPackageClass()) return "package class"; - if (symbol.isModuleClass()) return "object class"; - if (symbol.isTrait()) return "trait"; - return "class"; - case Kinds.TYPE: - case Kinds.ALIAS: - return "type"; - case Kinds.VAL: - if (symbol.isVariable()) return "variable"; - if (symbol.isPackage()) return "package"; - if (symbol.isModule()) return "object"; - if (symbol.isConstructor()) return "constructor"; - if (symbol.isInitializedMethod()) - if (global.debug || (symbol.flags & Modifiers.STABLE) == 0) - return "method"; - return "value"; - default: - throw Debug.abort("unknown kind " + symbol.kind); - } - } - - /** - * Returns the definition keyword associated to the given symbol - * or null if there is no such keyword. - */ - public String getSymbolKeyword(Symbol symbol) { - if (symbol.isParameter()) return null; - switch (symbol.kind) { - case Kinds.NONE: - return null; - case Kinds.CLASS: - if (symbol.isTrait()) return "trait"; - return "class"; - case Kinds.TYPE: - case Kinds.ALIAS: - return "type"; - case Kinds.VAL: - if (symbol.isVariable()) return "var"; - if (symbol.isPackage()) return "package"; - if (symbol.isModule()) return "object"; - if (symbol.isInitializedMethod()) return "def"; - return "val"; - default: - throw Debug.abort("unknown kind " + symbol.kind); - } - } - - /** Returns the name of the given symbol. */ - public String getSymbolName(Symbol symbol) { - String name = symbol.simpleName().toString(); - if (!global.debug) name = NameTransformer.decode(name); - return name; - } - - /** Returns the inner string of the given symbol. */ - public String getSymbolInnerString(Symbol symbol) { - switch (symbol.kind) { - case Kinds.NONE : return ": "; - case Kinds.ALIAS: return " = "; - case Kinds.CLASS: return " extends "; - case Kinds.TYPE : return " <: "; - case Kinds.VAL : return symbol.isModule() ? " extends " : - symbol.isDefParameter() ? ": => " : ": "; - default : throw Debug.abort("unknown kind " + symbol.kind); - } - } - - /** Prints the unique identifier of the given symbol */ - public SymbolTablePrinter printSymbolUniqueId(Symbol symbol) { - if (global.uniqid) print('#').print(symbol.id); - return this; - } - - /** Prints the name of the given symbol */ - public SymbolTablePrinter printSymbolName(Symbol symbol) { - print(getSymbolName(symbol)); - return printSymbolUniqueId(symbol); - } - - /** Prints the kind and the name of the given symbol. */ - public SymbolTablePrinter printSymbolKindAndName(Symbol symbol) { - if (symbol.isAnonymousClass()) { - print("<template>"); - return printSymbolUniqueId(symbol); - } else { - String kind = getSymbolKind(symbol); - if (kind != null) print(kind).space(); - return printSymbolName(symbol); - } - } - - /** Prints the type of the given symbol with the given inner string. */ - public SymbolTablePrinter printSymbolType(Symbol symbol, String inner) { - Type type = symbol.rawFirstInfo(); - if (!(type instanceof Type.LazyType)) type = symbol.info(); - boolean star = false; - if ((symbol.flags & Modifiers.REPEATED) != 0 && - type.symbol() == global.definitions.SEQ_CLASS && - type.typeArgs().length == 1) - { - type = type.typeArgs()[0]; - star = true; - } - printType(type, inner); - if (star) print("*"); - return this; - } - - /** Prints the signature of the given symbol. */ - public SymbolTablePrinter printSignature(Symbol symbol) { - String keyword = getSymbolKeyword(symbol); - if (keyword != null) print(keyword).space(); - String inner = getSymbolInnerString(symbol); - return printSymbolName(symbol) - .printType(symbol.loBound(), " >: ") - .printSymbolType(symbol, inner); - } - - - /** Prints the given type parameter section. */ - public SymbolTablePrinter printTypeParams(Symbol[] tparams) { - print('['); - for (int i = 0; i < tparams.length; i++) { - if (i > 0) print(","); - printSignature(tparams[i]); - } - return print(']'); - } - - /** Prints the given value parameter section. */ - public SymbolTablePrinter printValueParams(Symbol[] vparams) { - print('('); - for (int i = 0; i < vparams.length; i++) { - if (i > 0) print(","); - printSymbolType(vparams[i], - vparams[i].isDefParameter() ? "=> " : ""); - } - return print(')'); - } - - //######################################################################## - // Public Methods - Printing types - - /** Returns the type to print for the given type (transitive). */ - public Type getTypeToPrintForType(Type type) { - while (true) { - Type result = getTypeToPrintForType0(type); - if (result == type) return result; - type = result; - } - } - - /** Returns the type to print for the given type (non-transitive). */ - public Type getTypeToPrintForType0(Type type) { - switch (type) { - case ThisType(Symbol clasz): - if (global.debug || !clasz.isModuleClass()) return type; - Type prefix = getTypeToPrintForType(clasz.owner().thisType()); - Symbol module = clasz.sourceModule(); - if (module.owner() != clasz.owner()) return type; - if (!module.type().isObjectType()) return type; - return Type.singleType(prefix, module); - case SingleType(_, Symbol sym): - if (global.debug) return type; - if (sym.isSynthetic()) return type.widen(); - return type; - case CompoundType(Type[] parts, Scope members): - if (global.debug) return type; - if (type.isFunctionType()) return parts[1]; - return type; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != Type.NoType) return constr.inst; - return type; - default: - return type; - } - } - - /** Prints the given types separated by infix. */ - public SymbolTablePrinter printTypes(Type[] types, String infix) { - for (int i = 0; i < types.length; i++) { - if (i > 0) print(infix); - printType(types[i]); - } - return this; - } - - /** Prints the given type. */ - public SymbolTablePrinter printType(Type type) { - return printType0(getTypeToPrintForType(type)); - } - public SymbolTablePrinter printType0(Type type) { - printCommonPart(type); - switch (type) { - case ThisType(_): - case SingleType(_,_): - return print(".type"); - default: - return this; - } - } - - /** Prints the given type with the given inner string. */ - public SymbolTablePrinter printType(Type type, String inner) { - if (" <: ".equals(inner) && type.symbol() == global.definitions.ANY_CLASS || - " >: ".equals(inner) && type.symbol() == global.definitions.ALL_CLASS) - return this; - else - return printType0(getTypeToPrintForType(type), inner); - } - public SymbolTablePrinter printType0(Type type, String inner) { - switch (type) { - case PolyType(Symbol[] tparams, Type result): - if (tparams.length != 0 || global.debug) printTypeParams(tparams); - return printType(result, inner); - case MethodType(Symbol[] vparams, Type result): - return printValueParams(vparams).printType(result, inner); - default: - print(inner); - return printType0(type); - } - } - - /** Prints a function type with the given type arguments. */ - public SymbolTablePrinter printFunctionType(Type[] types) { - Type[] args = new Type[types.length - 1]; - for (int i = 0; i < args.length; i++) args[i] = types[i]; - print('(').printTypes(args, ",").print(") => "); - printType(types[types.length - 1]); - return this; - } - - /** Prints a template type with the given base types. */ - public SymbolTablePrinter printTemplateType(Type[] types) { - print("<template: ").printTypes(types, " with ").print(" {...}>"); - return this; - } - - /** Prints the type and prefix common part of the given type. */ - public SymbolTablePrinter printCommonPart(Type type) { - switch (type) { - case ErrorType: - return print("<error>"); - case AnyType: - return print("<any type>"); - case NoType: - return print("<notype>"); - case NoPrefix: - return print("<noprefix>"); - case ThisType(Symbol sym): - if ((sym.isAnonymousClass() || sym.isCompoundSym()) && !global.debug) - return print("this"); - return printSymbolName(sym).print(".this"); - case TypeRef(Type pre, Symbol sym, Type[] args): - if (!global.debug) { - if (type.isFunctionType()) - return printFunctionType(args); - if (sym.isAnonymousClass() || sym.isCompoundSym()) - return printTemplateType(pre.memberInfo(sym).parents()); - } - printPrefix(pre).printSymbolName(sym); - //print("{" + sym.owner() + "}");//DEBUG - if (args.length != 0) print('[').printTypes(args, ",").print(']'); - return this; - case SingleType(Type pre, Symbol sym): - return printPrefix(pre).printSymbolName(sym); - case ConstantType(Type base, AConstant value): - return printType(base).printConstantValue(value); - case CompoundType(Type[] parts, Scope members): - return printTypes(parts," with ").space() - .printScope(members,true) - .printSymbolUniqueId(type.symbol()); - case MethodType(_, _): - return printType0(type, "" /*null*/); - case PolyType(_, _): - return printType0(type, "" /*null*/); - case OverloadedType(Symbol[] alts, Type[] alttypes): - return printTypes(alttypes, " <and> "); - case TypeVar(Type origin, Constraint constr): - return printType(origin).print("?"); - case UnboxedType(int kind): - return print(type.unboxedName(kind).toString()); - case UnboxedArrayType(Type elemtp): - return printType(elemtp).print("[]"); - case LazyType(): - if (!global.debug) return print("?"); - String classname = type.getClass().getName(); - return print("<lazy type ").print(classname).print(">"); - default: - String classname = type.getClass().getName(); - return print("<unknown type ").print(classname).print(">"); - } - } - - //######################################################################## - // Public Methods - Printing prefixes - - /** Returns the type to print for the given prefix (transitive). */ - public Type getTypeToPrintForPrefix(Type prefix) { - while (true) { - Type result = getTypeToPrintForPrefix0(prefix); - if (result == prefix || result == null) return result; - prefix = result; - } - } - - /** Returns the type to print for the given prefix (non-transitive). */ - public Type getTypeToPrintForPrefix0(Type prefix) { - if (!global.debug) { - if (prefix.symbol().isNone()) return null; - if (prefix.symbol().isRoot()) return null; - } - return getTypeToPrintForType0(prefix); - } - - /** Prints the given type as a prefix. */ - public SymbolTablePrinter printPrefix(Type prefix) { - prefix = getTypeToPrintForPrefix(prefix); - return prefix == null ? this : printPrefix0(prefix); - } - public SymbolTablePrinter printPrefix0(Type prefix) { - printCommonPart(prefix); - switch (prefix) { - case NoPrefix: - case ThisType(_): - case SingleType(_,_): - return print("."); - default: - return print("#"); - } - } - - //######################################################################## - // Public Methods - Printing constants - - /** Prints the given constant value. */ - public SymbolTablePrinter printConstantValue(AConstant value) { - return print("(").print(value.toString()).print(")"); - } - - //######################################################################## - // Public Methods - Converting - - /** Returns the string representation of this printer. */ - public String toString() { - return printer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java deleted file mode 100644 index 0461525710..0000000000 --- a/sources/scalac/symtab/Type.java +++ /dev/null @@ -1,3736 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ -//todo: T {} == T - -package scalac.symtab; - -import java.util.HashMap; - -import scala.tools.util.Position; -import scalac.ApplicationError; -import scalac.atree.AConstant; -import scalac.util.*; -import scalac.Global; - -public class Type implements Modifiers, Kinds, TypeTags, EntryTags { - - public static boolean explainSwitch = false; - private static int indent = 0; - - public case ErrorType; // not used after analysis - public case AnyType; // not used after analysis - public case NoType; - public case NoPrefix; - - /** C.this.type - */ - public case ThisType(Symbol sym) { - assert sym.isClassType(): Debug.show(sym); - } - - /** pre.sym.type - * sym represents a valueS - */ - public case SingleType(Type pre, Symbol sym) { - assert this instanceof ExtSingleType; - } - - /** Type for a numeric or string constant. - */ - public case ConstantType(Type base, AConstant value); - - /** pre.sym[args] - * sym represents a type - * for example: scala.List[java.lang.String] is coded as - * - * TypeRef( - * SingleType(ThisType(definitions.ROOT_CLASS), definitions.SCALA), - * <List>, - * new Type[]{ - * TypeRef( - * SingleType( - * SingleType(ThisType(definitions.ROOT_CLASS), definitions.JAVA), - * definitions.LANG), - * definitions.STRING, - * new Type[]{})}). - * - */ - public case TypeRef(Type pre, Symbol sym, Type[] args) { - assert this instanceof ExtTypeRef: this; - } - - /** parts_1 with ... with parts_n { members } - */ - public case CompoundType(Type[] parts, Scope members) { - assert this instanceof ExtCompoundType; - } - - /** synthetic type of a method def ...(vparams): result = ... - */ - public case MethodType(Symbol[] vparams, Type result) { - for (int i = 0; i < vparams.length; i++) - assert vparams[i].isParameter() && vparams[i].isTerm(): this; - } - - /** synthetic type of a method def ...[tparams]result - * For instance, given def f[a](x: a): a - * f has type PolyType(new Symbol[]{<a>}, - * MethodType(new Symbol[]{<x>}, <a>.type())) - * - * if tparams is empty, this is the type of a parameterless method - * def ... = - * For instance, given def f = 1 - * f has type PolyType(new Symbol[]{}, <scala.Int>.type()) - */ - public case PolyType(Symbol[] tparams, Type result) { - for (int i = 0; i < tparams.length; i++) - assert tparams[i].isParameter()&&tparams[i].isAbstractType(): this; - } - - /** synthetic type of an overloaded value whose alternatives are - * alts_1, ..., alts_n, with respective types alttypes_1, ..., alttypes_n - * - * For instance, if there are two definitions of `f' - * def f: int - * def f: String - * then there are three symbols: - * ``f1'' corresponding to def f: int - * ``f2'' corresponding to def f: String - * ``f3'' corresponding to both - * f3 has type - * OverloadedType( - * new Symbol[]{<f1>, <f2>}, - * new Type[]{PolyType(new Symbol[]{}, <int>), - * PolyType(new Symbol[]{}, <String>), - * - */ - public case OverloadedType(Symbol[] alts, Type[] alttypes); - - /** Hidden case to implement delayed evaluation of types. - * No need to pattern match on this type; it will never come up. - */ - public case LazyType(); - - /** Hidden case to implement local type inference. - * Later phases do not need to match on this type. - */ - public case TypeVar(Type origin, Constraint constr); - - /** Hidden cases to implement type erasure. - * Earlier phases do not need to match on these types. - */ - public case UnboxedType(int tag); - public case UnboxedArrayType(Type elemtp); - - /** Force evaluation of a lazy type. No cycle - * check is needed; since this is done in Symbol. - * @see Symbol.info(). - */ - public void complete(Symbol p) {} - -// Creators --------------------------------------------------------------------- - - /** An empty Type array */ - public static final Type[] EMPTY_ARRAY = new Type[0]; - - public static SingleType singleType(Type pre, Symbol sym) { - assert sym.isTerm() && !sym.isNone(): pre + " -- " + Debug.show(sym); - rebind: - { - Symbol owner = sym.owner(); - if (!owner.isClass()) break rebind; - if (owner == pre.symbol()) break rebind; - // !!! add if (owner is sealed/final) break rebind ? - // !!! add if (owner is module class) break rebind ? - if (sym.isFinal() || sym.isPrivate()) break rebind; - Symbol rebind = pre.lookupNonPrivate(sym.name); - if (rebind.isNone()) break rebind; - if (rebind.isLocked()) throw new Type.Error( - "illegal cyclic reference involving " + rebind); - sym = rebind.rebindSym().stableAlternative(); - } - if (pre.isStable() || pre.isError()) { - return new ExtSingleType(pre, sym); - } else { - throw new Type.Malformed(pre, sym.nameString() + ".type"); - } - } - - public static Type constantType(AConstant value) { - return Global.instance.definitions.atyper.type(value); - } - - public static Type singleTypeMethod(Type pre, Symbol sym) { - Global global = Global.instance; - if (global.currentPhase.id <= global.PHASE.UNCURRY.id()) - return singleType(pre, sym); - else if (global.currentPhase.id <= global.PHASE.ERASURE.id()) - return sym.type().singleTypeMethod0(pre, sym); - else - return pre.memberType(sym); - } - - private Type singleTypeMethod0(Type pre, Symbol sym) { - switch (this) { - case PolyType(Symbol[] args, Type result): - return PolyType(args, result.singleTypeMethod0(pre, sym)); - case MethodType(Symbol[] args, Type result): - return MethodType(args, result.singleTypeMethod0(pre, sym)); - default: - return singleType(pre, sym); - } - } - - public static Type appliedType(Type tycon, Type[] args) { - switch (tycon) { - case TypeRef(Type pre, Symbol sym, Type[] args1): - if (args == args1) return tycon; - else return Type.typeRef(pre, sym, args); - default: - throw Debug.abort("illegal case", tycon); - } - } - - public static Type typeRef(Type pre, Symbol sym, Type[] args) { - rebind: - if (sym.isAbstractType()) { - Symbol owner = sym.owner(); - if (!owner.isClass()) break rebind; - if (owner == pre.symbol()) break rebind; - // !!! add if (owner is sealed/final) break rebind ? - // !!! add if (owner is module class) break rebind ? - if (sym.isFinal() || sym.isPrivate()) break rebind; - Symbol rebind = pre.lookupNonPrivate(sym.name); - if (rebind.isNone()) break rebind; - if (rebind.isLocked()) throw new Type.Error( - "illegal cyclic reference involving " + rebind); - sym = rebind.rebindSym(); - } - if (sym.isAbstractType() && !pre.isLegalPrefix() && !pre.isError()) - throw new Type.Malformed(pre, sym.nameString()); - if (sym.isTypeAlias()) { - Symbol[] params = sym.typeParams(); - if (args.length == params.length) { - if (sym.isLocked()) throw new Type.Error( - "illegal cyclic reference involving " + sym); - sym.flags |= LOCKED; - Type result = pre.memberInfo(sym).subst(params, args); - sym.flags &= ~LOCKED; - return result; - } - assert args.length == 0 || args.length == params.length: - Debug.show(pre, sym, args, params); - } - assert isLegalTypeRef(pre, sym, args): - Debug.show(pre, sym, args, sym.typeParams()); - return new ExtTypeRef(pre, sym, args); - } - private static boolean isLegalTypeRef(Type pre, Symbol sym, Type[] args) { - if (sym.kind == TYPE && !pre.isLegalPrefix() && !pre.isError()) return false; - if (!sym.isType() && !sym.isError()) return false; - // !!! return args.length == 0 || args.length == sym.typeParams().length; - return true; - } - - public static Type newTypeRefUnsafe(Type pre, Symbol sym, Type[] args) { - return new ExtTypeRef(pre, sym, args); - } - - public static CompoundType compoundType(Type[] parts, Scope members, - Symbol clazz) { - return new ExtCompoundType(parts, members, clazz); - } - - public static CompoundType compoundTypeWithOwner(Symbol owner, Type[] parts, Scope members) { - return new ExtCompoundType(owner, parts, members); - } - - static class ExtSingleType extends SingleType { - Type tp = null; - int definedId = -1; - ExtSingleType(Type pre, Symbol sym) { - super(pre, sym); - } - public Type singleDeref() { - if (definedId != Global.instance.currentPhase.id) { - definedId = Global.instance.currentPhase.id; - tp = pre.memberType(sym).resultType(); - } - return tp; - } - } - - static class ExtTypeRef extends TypeRef { - ExtTypeRef(Type pre, Symbol sym, Type[] args) { - super(pre, sym, args); - } - } - - private static final class ExtCompoundType extends CompoundType { - private final Symbol clasz; - public ExtCompoundType(Symbol owner, Type[] parts, Scope members) { - super(parts, members); - this.clasz = owner.newCompoundClass(this); - } - public ExtCompoundType(Type[] parts, Scope members, Symbol clasz) { - super(parts, members); - this.clasz = clasz; - } - public Symbol symbol() { - return clasz; - } - } - -// Access methods --------------------------------------------------------------- - - /** If this is a thistype, named type, applied type, singleton type, or compound type, - * its symbol, otherwise Symbol.NONE. - */ - public Symbol symbol() { - switch (this) { - case ThisType(Symbol sym): - return sym; - case TypeRef(_, Symbol sym, _): - return sym; - case SingleType(_, Symbol sym): - return sym; - case ConstantType(Type base, _): - return base.symbol(); - case TypeVar(Type origin, _): - return origin.symbol(); - case CompoundType(_, _): - // overridden in ExtCompoundType - throw new ApplicationError(); - default: - return Symbol.NONE; - } - } - - public static Symbol[] symbol(Type[] tps) { - Symbol[] syms = new Symbol[tps.length]; - for (int i = 0; i < syms.length; i++) - syms[i] = tps[i].symbol(); - return syms; - } - - /** If this is a reference to a type constructor, add its - * type parameters as arguments - */ - public Type withDefaultArgs() { - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (args.length == 0 && sym.typeParams().length != 0) - return Type.typeRef(pre, sym, Symbol.type(sym.typeParams())); - } - return this; - } - - /** The upper bound of this type. Returns always a TypeRef whose - * symbol is a class. - */ - public Type bound() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, _): - if (sym.kind == TYPE) return pre.memberInfo(sym).bound(); - assert sym.isClass() : Debug.show(sym) + " -- " + this; - return this; - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().bound(); - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.bound(); - else return this; - default: - throw Debug.abort("illegal case", this); - } - } - - /** If this type is a thistype or singleton type, its type, - * otherwise the type itself. - */ - public Type singleDeref() { - switch (this) { - case ThisType(Symbol sym): - return sym.typeOfThis(); - case SingleType(Type pre, Symbol sym): - // overridden in ExtSingleType - throw new ApplicationError(); - case ConstantType(Type base, _): - return base; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.singleDeref(); - else return this; - default: - return this; - } - } - - /** If this type is a thistype or singleton type, its underlying object type, - * otherwise the type itself. - */ - public Type widen() { - Type tp = singleDeref(); - switch (tp) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return tp.widen(); - default: - return tp; - } - } - - private static Map widenMap = new Map() { - public Type apply(Type t) { - return t.widen(); - } - }; - - public static Type[] widen(Type[] tps) { - return widenMap.map(tps); - } - - /** The thistype or singleton type corresponding to values of this type. - */ - public Type narrow() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == CLASS) return sym.thisType(); - else return ThisType(sym); - case CompoundType(_, _): - return symbol().thisType(); - default: - return this; - } - } - - /** If this type is a constant type, its underlying basetype; - * otherwise the type itself - */ - public Type deconst() { - switch (this) { - case ConstantType(Type base, _): - return base; - default: - return this; - } - } - - /** If this type is a parameterless method, its underlying resulttype; - * otherwise the type itself - */ - public Type derefDef() { - switch (this) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == 0) return restp; - } - return this; - } - - /** The lower approximation of this type (which must be a typeref) - */ - public Type loBound() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Type lb = Global.instance.definitions.ALL_TYPE(); - if (sym.kind == TYPE) { - lb = pre.memberLoBound(sym); - } - if (lb.symbol() == Global.instance.definitions.ALL_CLASS && - this.symbol() != Global.instance.definitions.ALL_CLASS && - this.isSubType(Global.instance.definitions.ANYREF_TYPE())) { - lb = Global.instance.definitions.ALLREF_TYPE(); - } - return lb; - default: - throw new ApplicationError(); - } - } - - /** If this is a this-type, named-type, applied type or single-type, its prefix, - * otherwise NoType. - */ - public Type prefix() { - switch (this) { - case ThisType(Symbol sym): return sym.owner().thisType(); - case TypeRef(Type pre, _, _): return pre; - case SingleType(Type pre, _): return pre; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.prefix(); - else return NoType; - default: return NoType; - } - } - - /** Get all type arguments of this type. - */ - public Type[] typeArgs() { - switch (unalias()) { - case TypeRef(_, _, Type[] args): - return args; - default: - return Type.EMPTY_ARRAY; - } - } - - /** Get type of `this' symbol corresponding to this type, extend - * homomorphically to function types and poly types. - */ - public Type instanceType() { - switch (unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym != sym.thisSym()) - return sym.typeOfThis() - .asSeenFrom(pre, sym.owner()) - .subst(sym.typeParams(), args); - break; - case MethodType(Symbol[] params, Type restp): - Type restp1 = restp.instanceType(); - if (restp1 != restp) - return MethodType(params, restp1); - break; - case PolyType(Symbol[] tparams, Type restp): - Type restp1 = restp.instanceType(); - if (restp1 != restp) - return PolyType(tparams, restp1); - break; - } - return this; - } - - /** Remove all aliases - */ - public Type unalias() { - Type result = unalias(0);//debug - //if (this != result) System.out.println(this + " ==> " + result);//DEBUG - return result; - } - - private Type unalias(int n) { - if (n == 100) - throw new Type.Error("alias chain too long (recursive type alias?): " + this); - switch (this) { - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.unalias(n + 1); - else return this; - } - return this; - } - - /** The (prefix/argument-adapted) parents of this type. - */ - public Type[] parents() { - switch (unalias()) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().parents(); - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == CLASS) { - assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug - return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()), - sym.typeParams(), args); - } else { - return new Type[]{sym.info().asSeenFrom(pre, sym.owner())}; - } - case CompoundType(Type[] parts, _): - return parts; - default: - return Type.EMPTY_ARRAY; - } - } - - /** Get type parameters of method type (a PolyType or MethodType) - * or EMPTY_ARRAY if method type is not polymorphic. - */ - public Symbol[] typeParams() { - switch (this) { - case PolyType(Symbol[] tparams, _): - return tparams; - case MethodType(Symbol[] vparams, _): - return Symbol.EMPTY_ARRAY; - case TypeRef(_, Symbol sym, Type[] args): - if (args.length == 0) return sym.typeParams(); - else return Symbol.EMPTY_ARRAY; - default: - return Symbol.EMPTY_ARRAY; - } - } - - /** Get value parameters of method type (a PolyType or MethodType) - * or EMPTY_ARRAY if method type has no value parameter section. - */ - public Symbol[] valueParams() { - return valueParams(false); - } - private Symbol[] valueParams(boolean ok) { - switch (this) { - case PolyType(_, Type result): - return result.valueParams(true); - case MethodType(Symbol[] vparams, _): - return vparams; - default: - if (ok) return Symbol.EMPTY_ARRAY; - throw Debug.abort("illegal case", this); - } - } - - /** If this type is a (possibly polymorphic) method type, its result type - * after applying all method argument sections, - * otherwise the type itself. - */ - public Type resultType() { - switch (this) { - case PolyType(_, Type tpe): - return tpe.resultType(); - case MethodType(_, Type tpe): - return tpe.resultType(); - default: - return this; - } - } - - /** The number of value parameter sections of this type. - */ - public int paramSectionCount() { - switch (this) { - case PolyType(_, Type restpe): - return restpe.paramSectionCount(); - case MethodType(_, Type restpe): - return restpe.paramSectionCount() + 1; - default: return 0; - } - } - - /** The first parameter section of this type. - */ - public Symbol[] firstParams() { - switch (this) { - case PolyType(_, Type restpe): - return restpe.firstParams(); - case MethodType(Symbol[] params, _): - return params; - default: return Symbol.EMPTY_ARRAY; - } - } - - /** If this type is overloaded, its alternative types, - * otherwise an array consisting of this type itself. - */ - public Type[] alternativeTypes() { - switch (this) { - case OverloadedType(_, Type[] alttypes): - return alttypes; - default: - return new Type[]{this}; - } - } - - /** If this type is overloaded, its alternative symbols, - * otherwise an empty array. - */ - public Symbol[] alternativeSymbols() { - switch (this) { - case OverloadedType(Symbol[] alts, _): - return alts; - default: - return Symbol.EMPTY_ARRAY; - } - } - -// Tests -------------------------------------------------------------------- - - /** Is this type a an error type? - */ - public boolean isError() { - switch (this) { - case ErrorType: - return true; - case ThisType(Symbol clasz): - return clasz.isError(); - case SingleType(_, Symbol symbol): - return symbol.isError(); - case TypeRef(_, Symbol symbol, _): - return symbol.isError(); - case CompoundType(Type[] parts, Scope members): - return symbol().isError(); - default: - return false; - } - } - - /** Is this type a this type or singleton type? - */ - public boolean isStable() { - switch (unalias()) { - case NoPrefix: - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return true; - case TypeRef(_, Symbol sym, _): - if (sym.isParameter() && sym.isSynthetic() && sym.hasStableFlag()) return true; - return false; - default: - return false; - } - } - - /** Is this type a legal prefix? - */ - public boolean isLegalPrefix() { - switch (unalias()) { - case NoPrefix: - case ThisType(_): - case SingleType(_, _): - return true; - case TypeRef(_, Symbol sym, _): - if (sym.isParameter() && sym.isSynthetic()) return true; - return false; - /* - return sym.kind == CLASS && - ((sym.flags & JAVA) != 0 || - (sym.flags & (TRAIT | ABSTRACT)) == 0); - */ - default: - return false; - } - } - - /** Is this type a s thistype or singletype? - */ - public boolean isSingletonType() { - switch (this) { - case ThisType(_): case SingleType(_, _): return true; - default: return false; - } - } - - /** Is this type a reference to an object type? - * todo: replace by this.isSubType(global.definitions.ANY_TYPE())? - */ - public boolean isObjectType() { - switch (unalias()) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - case CompoundType(_, _): - case TypeRef(_, _, _): - return true; - default: - return false; - } - } - - /** Is this type of the form scala.FunctionN[T_1, ..., T_n, +T] or - * scala.AnyRef with scala.FunctionN[T_1, ..., T_n, +T] or - * java.lang.Object with scala.FunctionN[T_1, ..., T_n, +T]? - */ - public boolean isFunctionType() { - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Definitions definitions = Global.instance.definitions; - return args.length > 0 - && args.length <= definitions.FUNCTION_COUNT - && sym == definitions.FUNCTION_CLASS[args.length - 1]; - case CompoundType(Type[] parents, Scope members): - Definitions definitions = Global.instance.definitions; - return members.isEmpty() && - parents.length == 2 && - (parents[0].symbol() == definitions.OBJECT_CLASS || - parents[0].symbol() == definitions.ANYREF_CLASS) && - parents[1].isFunctionType(); - } - return false; - } - - /** Is this a polymorphic method type? - */ - public boolean isPolymorphic() { - return typeParams().length > 0; - } - - /** Is this a parameterized or polymorphic method type? - */ - public boolean isParameterized() { - switch (this) { - case MethodType(_, _): return true; - default: return isPolymorphic(); - } - } - -// Members and Lookup ------------------------------------------------------- - - /** Get the scope containing the local members of this type. - * Symbols in this scope are not prefix-adapted! - */ - public Scope members() { - switch (this) { - case ErrorType: - return new Scope(); - case TypeRef(_, Symbol sym, _): - return sym.info().members(); - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().members(); - case CompoundType(Type[] basetypes, Scope members): - return members; - default: - return Scope.EMPTY; - } - } - - /** Lookup symbol with given name among all local and inherited members - * of this type; return Symbol.NONE if not found. - */ - public Symbol lookup(Name name) { - // The code below does the same as the following line but is - // slightly faster - // return lookup(new NameSearch(name, false)); - - switch (this) { - case ErrorType: - return new ErrorScope(Symbol.NONE).lookup(name); - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().lookup(name); - case TypeRef(_, Symbol sym, _): - return sym.info().lookup(name); - case CompoundType(Type[] parts, Scope members): - Symbol sym = members.lookup(name); - if (sym.kind != NONE) return sym; - else return lookupNonPrivate(name); - default: - return Symbol.NONE; - } - } - - /** Lookup non-private symbol with given name among all local and - * inherited members of this type; return Symbol.NONE if not found. - */ - public Symbol lookupNonPrivate(Name name) { - // The code below does the same as the following line but is - // slightly faster - // return lookup(new NameSearch(name, true)); - - switch (this) { - case ErrorType: - return new ErrorScope(Symbol.NONE).lookup(name); - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().lookupNonPrivate(name); - case TypeRef(_, Symbol sym, _): - return sym.info().lookupNonPrivate(name); - case CompoundType(Type[] parts, Scope members): - Symbol sym = members.lookup(name); - if (sym.kind != NONE && (sym.flags & PRIVATE) == 0) return sym; - else return lookupNonPrivate(parts, name); - default: - return Symbol.NONE; - } - } - - public static Symbol lookupNonPrivate(Type[] parts, Name name) { - // The code below does the same as the following line but is - // slightly faster - // return lookup(parts, new NameSearch(name, true)); - - // search base types in reverse; non-abstract members - // take precedence over abstract ones. - int i = parts.length; - Symbol sym = Symbol.NONE; - while (i > 0) { - i--; - Symbol sym1 = parts[i].lookupNonPrivate(name); - if (sym1.kind != NONE && - (sym.kind == NONE - || - (sym.flags & DEFERRED) != 0 && - (sym1.flags & DEFERRED) == 0 - || - (sym.flags & DEFERRED) == (sym1.flags & DEFERRED) && - sym1.owner().isSubClass(sym.owner()))) - sym = sym1; - } - return sym; - } - - /** - * Looks up in the current type a symbol with the same name as the - * given symbol and whose type (as seen from the given prefix) is - * in the given relation to the type (as seen from the given - * prefix) of the given symbol. If no such symbol is found, - * returns NONE. Note that in some cases, the returned symbol may - * be equal to the given one. The main purpose of this method is - * look up overridden and overriding symbols. - */ - public Symbol lookup(Symbol symbol, Type prefix, Relation relation) { - assert !symbol.isOverloaded(): Debug.show(symbol); - if (symbol.isPrivate() || symbol.isInitializer()) - return symbol().isSubClass(symbol.owner()) ? symbol : Symbol.NONE; - Symbol best = search(new SymbolSearch(symbol, prefix, relation)); - return best == null ? Symbol.NONE : best; - } - - /** - * Applies the given search to this type. Returns NONE on failure. - */ - public Symbol lookup(Search search) { - Symbol symbol = search(search); - return symbol == null ? Symbol.NONE : symbol; - } - - /** - * Applies the given search to the given types. Returns NONE on - * failure. - */ - public static Symbol lookup(Type[] parents, Search search) { - Symbol symbol = search(parents, search); - return symbol == null ? Symbol.NONE : symbol; - } - - /** - * Applies the given search to this type. Returns null on failure. - */ - public Symbol search(Search search) { - return search(this, search, null, false); - } - - /** - * Applies the given search to the given types. Returns null on - * failure. - */ - public static Symbol search(Type[] parents, Search search) { - Symbol best = null; - for (int i = parents.length - 1; 0 <= i; i--) - best = search(parents[i], search, best, true); - return best; - } - - /** - * Applies the given search to the given type. The symbol "best" - * is the best symbol found until now. It may be null. If no - * better symbol is found, the method returns this symbol. The - * flag "inherited" indicates whether the given type is the - * initial type (false) or is a type inherited by it (true). - */ - private static Symbol search(Type type, Search search, Symbol best, - boolean inherited) - { - while (true) { - switch (type) { - case ErrorType: - return best != null ? best : search.error(); - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - type = type.singleDeref(); - continue; - case TypeRef(_, Symbol symbol, _): - type = symbol.info(); - continue; - case CompoundType(Type[] parents, Scope members): - // The following code could be used to cut the search, but - // it is unclear whether it is faster - // if (best != null && !best.isDeferred()) - // if (!type.symbol().isSubClass(best.owner())) return best; - Symbol symbol = search.apply(members, inherited); - if (symbol != null) { - // !!! This assertion fails for "pos/clsrefine". - // There might be a bug in the analyzer. - // assert type.symbol().isSubClass(symbol.owner()): - // Debug.show(type, type.symbol(), symbol); - if ((best == null) - || - (best.isDeferred() && !symbol.isDeferred()) - || - ((best.isDeferred() == symbol.isDeferred()) && - symbol.owner().isSubClass(best.owner()))) - return symbol; - } - for (int i = parents.length - 1; 0 <= i; i--) - best = search(parents[i], search, best, true); - return best; - default: - return null; - } - } - } - - public static abstract class Search { - /** - * This method is applied to each encountered scope. The flag - * "inherited" indicates whether the scope is part of the - * initial type (false) or if it is inherited by it (true). - */ - public abstract Symbol apply(Scope members, boolean inherited); - /** This method is applied to each encountered error type. */ - public abstract Symbol error(); - } - - /** Seaches a symbol with the given name. */ - public static class NameSearch extends Search { - public final Name name; - public final boolean nonPrivate; - public NameSearch(Name name, boolean nonPrivate) { - this.name = name; - this.nonPrivate = nonPrivate; - } - public Symbol apply(Scope members, boolean inherited) { - Symbol symbol = members.lookup(name); - if (!symbol.isNone()) - if (!inherited || !nonPrivate || (symbol.flags & PRIVATE) == 0) - return symbol; - return null; - } - public Symbol error() { - return name.isTermName() - ? Symbol.NONE.newErrorValue(name) - : Symbol.NONE.newErrorClass(name); - } - } - - /** - * Searches a symbol with the same name as the given source symbol - * and whose type (as seen from the given prefix) is in the given - * relation to the type (as seen from the given prefix) of the - * source symbol. Note that in some cases, the returned symbol may - * be equal to the source one. This search is useful to find - * overridden and overriding symbols. - */ - public static class SymbolSearch extends Search { - - /** The type which the symbols are seen from */ - public final Type prefix; - /** The source symbol */ - public final Symbol srcsym; - /** The source symbol's type as seen from the prefix */ - public final Type srctype; - /** The java version of the previous type */ - public Type srcjavatype; - /** The type relation between returned and source symbols. */ - public final Relation relation; - - public SymbolSearch(Symbol srcsym, Type prefix, Relation relation) { - this.prefix = prefix; - this.srcsym = srcsym; - this.srctype = getSeenTypeOf(srcsym); - this.relation = relation; - assert !srcsym.isOverloaded(): Debug.show(srcsym); - } - - public Symbol apply(Scope members, boolean inherited) { - Symbol objsym = members.lookup(srcsym.name); - if (objsym.isNone()) return null; - switch (objsym.type()) { - case NoType: - case ErrorType: - return null; - case OverloadedType(Symbol[] alts, _): - for (int j = 0; j < alts.length; j++) - if (areRelated(alts[j], false)) return alts[j]; - return null; - default: - return areRelated(objsym, true) ? objsym : null; - } - } - - public Symbol error() { - return null; - } - - private Type getSeenTypeOf(Symbol symbol) { - return prefix.memberType(symbol).derefDef(); - } - - private Type getSrcTypeFor(Symbol objsym) { - if (!objsym.isJava()) return srctype; - if (srcjavatype == null) srcjavatype = srctype.objParamToAny(); - return srcjavatype; - } - - private boolean areRelated(Symbol objsym, boolean warn) { - if (objsym == srcsym) return true; - if (objsym.isPrivate() || objsym.isInitializer()) return false; - Type srctype = getSrcTypeFor(objsym); - Type objtype = getSeenTypeOf(objsym); -// System.out.println("" -// + "Is 'objsym' " + relation + " 'srcsym' in 'prefix' ?" -// + "\n srcsym : " + Debug.show(srcsym) -// + "\n objsym : " + Debug.show(objsym) -// + "\n srcsym.type: " + srcsym.type() -// + "\n objsym.type: " + objsym.type() -// + "\n prefix : " + prefix -// + "\n srctype : " + srctype -// + "\n objtype : " + objtype -// + "\n result : " + objtype.compareTo(srctype, relation) -// );//DEBUG - if (objtype.compareTo(srctype, relation)) return true; - if (warn && Global.instance.debug) System.out.println("" - + "'objsym' is not " + relation + " 'srcsym' in 'prefix'" - + "\n srcsym : " + Debug.show(srcsym) - + "\n objsym : " + Debug.show(objsym) - + "\n srcsym.type: " + srcsym.type() - + "\n objsym.type: " + objsym.type() - + "\n prefix : " + prefix - + "\nsince 'objtype' " + relation.toString(true) + " 'srctype'" - + "\n srctype : " + srctype - + "\n objtype : " + objtype - );//DEBUG - return false; - } - - } - //where - static private Map objToAnyMap = new Map() { - public Type apply(Type t) { - if (t.symbol() == Global.instance.definitions.OBJECT_CLASS) - return Global.instance.definitions.ANY_TYPE(); - else return t; - } - }; - - private Type objParamToAny() { - switch (this) { - case MethodType(Symbol[] params, Type restp): - Symbol[] params1 = objToAnyMap.map(params); - if (params1 == params) return this; - else return MethodType(params1, restp); - default: - return this; - } - } - -// Set Owner ------------------------------------------------------------------ - - public Type setOwner(Symbol owner) { - switch (this) { - case PolyType(Symbol[] tparams, Type restpe): - Type restpe1 = restpe.setOwner(owner); - if (restpe1 == restpe) return this; - else return Type.PolyType(tparams, restpe1); - case MethodType(Symbol[] params, Type restpe): - Symbol[] params1 = params; - if (params.length > 0 && - params[0].owner() != owner && params[0].owner() != Symbol.NONE) { - params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) - params1[i] = params[i].cloneSymbol(); - } - for (int i = 0; i < params.length; i++) - params1[i].setOwner(owner); - Type restpe1 = restpe.setOwner(owner); - if (params1 == params && restpe1 == restpe) return this; - else return Type.MethodType(params1, restpe1); - default: - return this; - } - } - -// Maps -------------------------------------------------------------------------- - - /** The type of type-to-type functions. - */ - public abstract static class Map { - - public abstract Type apply(Type t); - - /** - * This method assumes that all symbols in MethodTypes and - * PolyTypes have already been cloned. - */ - public Type applyParams(Type type) { - switch (type) { - - case MethodType(Symbol[] vparams, Type result): - map(vparams, true); - Type result1 = applyParams(result); - return result == result1 ? type : MethodType(vparams, result1); - - case PolyType(Symbol[] tparams, Type result): - map(tparams, true); - Type result1 = applyParams(result); - return result == result1 ? type : PolyType(tparams, result1); - - default: - return apply(type); - } - } - - /** Apply map to all top-level components of this type. - */ - public Type map(Type tp) { - switch (tp) { - case ErrorType: - case AnyType: - case NoType: - case NoPrefix: - case UnboxedType(_): - case TypeVar(_, _): - case ThisType(_): - return tp; - case TypeRef(Type pre, Symbol sym, Type[] args): - Type pre1 = apply(pre); - Type[] args1 = map(args); - if (pre1 == pre && args1 == args) return tp; - else return typeRef(pre1, sym, args1); - case SingleType(Type pre, Symbol sym): - Type pre1 = apply(pre); - if (pre1 == pre) return tp; - else return singleType(pre1, sym); - case ConstantType(Type base, AConstant value): - Type base1 = apply(base); - if (base1 == base) return tp; - else return new ConstantType(base1, value); - case CompoundType(Type[] parts, Scope members): - Type[] parts1 = map(parts); - Scope members1 = map(members); - if (parts1 == parts && members1 == members) { - return tp; - } else if (members1 == members && !tp.symbol().isCompoundSym()) { - return compoundType(parts1, members, tp.symbol()); - } else { - Scope members2 = new Scope(); - //Type tp1 = compoundType(parts1, members2); - Type tp1 = (tp.symbol().isCompoundSym()) ? compoundTypeWithOwner(tp.symbol().owner(), parts1, members2) - : compoundType(parts1, members2, tp.symbol()); - Symbol[] syms1 = members1.elements(); - Symbol[] syms2 = new Symbol[syms1.length]; - for (int i = 0; i < syms2.length; i++) { - syms2[i] = syms1[i].cloneSymbol(tp1.symbol()); - } - for (int i = 0; i < syms2.length; i++) { - syms2[i].setInfo(syms1[i].info().subst(syms1, syms2)); - if (syms2[i].kind == TYPE) { - syms2[i].setLoBound(syms1[i].loBound().subst(syms1, syms2)); - syms2[i].setVuBound(syms1[i].vuBound().subst(syms1, syms2)); - } - } - for (int i = 0; i < syms2.length; i++) { - members2.enter(syms2[i]); - } - return tp1; - } - - case MethodType(Symbol[] vparams, Type result): - Symbol[] vparams1 = map(vparams); - Type result1 = apply(result); - if (vparams1 == vparams && result1 == result) return tp; - else return MethodType(vparams1, result1); - case PolyType(Symbol[] tparams, Type result): - Symbol[] tparams1 = map(tparams); - Type result1 = apply(result); - if (tparams1 != tparams) result1 = result1.subst(tparams, tparams1); - if (tparams1 == tparams && result1 == result) return tp; - else return PolyType(tparams1, result1); - case OverloadedType(Symbol[] alts, Type[] alttypes): - Type[] alttypes1 = map(alttypes); - if (alttypes1 == alttypes) return tp; - else return OverloadedType(alts, alttypes1); - case UnboxedArrayType(Type elemtp): - Type elemtp1 = apply(elemtp); - if (elemtp1 == elemtp) return tp; - else return UnboxedArrayType(elemtp1); - default: - throw new ApplicationError(tp + " " + tp.symbol()); - } - } - - public final Symbol map(Symbol sym) { - return map(sym, false); - } - public Symbol map(Symbol sym, boolean dontClone) { - Type tp = sym.info(); - Type tp1 = apply(tp); - if (tp != tp1) { - if (!dontClone) sym = sym.cloneSymbol(); - sym.setInfo(tp1); - dontClone = true; - } - if (sym.kind == TYPE) { - Type lb = sym.loBound(); - Type lb1 = apply(lb); - if (lb != lb1) { - if (!dontClone) sym = sym.cloneSymbol(); - sym.setLoBound(lb1); - } - Type vb = sym.vuBound(); - Type vb1 = apply(vb); - if (vb != vb1) { - if (!dontClone) sym = sym.cloneSymbol(); - sym.setVuBound(vb1); - } - } - return sym; - } - - public Type[] map(Type[] tps) { - Type[] tps1 = tps; - for (int i = 0; i < tps.length; i++) { - Type tp = tps[i]; - Type tp1 = apply(tp); - if (tp1 != tp && tps1 == tps) { - tps1 = new Type[tps.length]; - System.arraycopy(tps, 0, tps1, 0, i); - } - tps1[i] = tp1; - } - return tps1; - } - - /** Apply map to all elements of this array of symbols, - * preserving recursive references to symbols in the array. - */ - public final Symbol[] map(Symbol[] syms) { - return map(syms, false); - } - public Symbol[] map(Symbol[] syms, boolean dontClone) { - Symbol[] syms1 = syms; - for (int i = 0; i < syms.length; i++) { - Symbol sym = syms[i]; - Symbol sym1 = map(sym, dontClone); - if (sym != sym1 && syms1 == syms) { - syms1 = new Symbol[syms.length]; - System.arraycopy(syms, 0, syms1, 0, i); - } - syms1[i] = sym1; - } - if (syms1 != syms) { - for (int i = 0; i < syms1.length; i++) { - if (syms1[i] == syms[i]) - syms1[i] = syms[i].cloneSymbol(); - } - new SubstSymMap(syms, syms1).map(syms1, true); - } - return syms1; - } - - /** Apply map to all elements of this array of this scope. - */ - public Scope map(Scope s) { - Symbol[] members = s.elements(); - Symbol[] members1 = map(members); - if (members == members1) return s; - else return new Scope(members1); - } - } - - public abstract static class MapOnlyTypes extends Map { - public Symbol map(Symbol sym, boolean dontClone) { return sym; } - public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; } - public Scope map(Scope s) { return s; } - } - - public static final Map IdMap = new Map() { - public Type apply(Type tp) { return tp; } - public Type applyParams(Type tp) { return tp; } - public Type map(Type tp) { return tp; } - public Symbol map(Symbol sym, boolean dontClone) { return sym; } - public Type[] map(Type[] tps) { return tps; } - public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; } - public Scope map(Scope scope) { return scope; } - }; - -// baseType and asSeenFrom -------------------------------------------------------- - - /** Return the base type of this type whose symbol is `clazz', or NoType, if - * such a type does not exist. - */ - public Type baseType(Symbol clazz) { - //System.out.println(this + ".baseType(" + clazz + ")");//DEBUG - switch (this) { - case ErrorType: - return ErrorType; - - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().baseType(clazz); - - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym == clazz) - return this; - else if (sym.kind == TYPE) - return sym.info() - .asSeenFrom(pre, sym.owner()).baseType(clazz); - else if (sym.kind == ALIAS) - return Type.NoType; - else if (clazz.isCompoundSym()) - return NoType; - else { - return sym.baseType(clazz) - .asSeenFrom(pre, sym.owner()) - .subst(sym.typeParams(), args); - } - - case CompoundType(Type[] parts, _): - for (int i = parts.length - 1; i >= 0; i--) { - Type result = parts[i].baseType(clazz); - if (result != NoType) return result; - } - break; - - case UnboxedArrayType(_): - if (clazz == Global.instance.definitions.ANY_CLASS || - clazz == Global.instance.definitions.ANYREF_CLASS) - return clazz.type(); - } - return NoType; - } - - /** A map to implement `asSeenFrom'. - */ - static class AsSeenFromMap extends Map { - - private final Type pre; - private final Symbol clazz; - - AsSeenFromMap(Type pre, Symbol clazz) { - this.pre = pre; - this.clazz = clazz; - } - - public Type apply(Type type) { - //System.out.println(type + " as seen from " + pre + "," + clazz);//DEBUG - if (pre == NoType || clazz.kind != CLASS) return type; - switch (type) { - case ThisType(Symbol sym): - return type.toPrefix(sym, pre, clazz); - case TypeRef(Type prefix, Symbol sym, Type[] args): - if (sym.owner().isPrimaryConstructor()) { - assert sym.kind == TYPE; - return type.toInstance(sym, pre, clazz); - } - return map(type); - - case SingleType(Type prefix, Symbol sym): - try { - return map(type); - } catch (Type.Malformed ex) {} - return apply(type.singleDeref()); - - default: - return map(type); - } - } - } - //where - Type toInstance(Symbol sym, Type pre, Symbol clazz) { - if (pre == NoType || clazz.kind != CLASS) - return this; - Symbol ownclass = sym.owner().constructorClass(); - if (ownclass == clazz && - pre.widen().symbol().isSubClass(ownclass)) { - switch (pre.baseType(ownclass)) { - case TypeRef(_, Symbol basesym, Type[] baseargs): - Symbol[] baseparams = basesym.typeParams(); - for (int i = 0; i < baseparams.length; i++) { - if (sym == baseparams[i]) return baseargs[i]; - } - //System.out.println(sym + " " + basesym + " " + ArrayApply.toString(baseparams));//DEBUG - break; - case ErrorType: - return ErrorType; - } - throw new ApplicationError( - this + " in " + ownclass + " cannot be instantiated from " + pre.widen() - ); - } else { - return toInstance(sym, pre.baseType(clazz).prefix(), clazz.owner()); - } - } - - Type toPrefix(Symbol sym, Type pre, Symbol clazz) { - //System.out.println(this + ".toPrefix(" + sym + "," + pre + "," + clazz + ")");//DEBUG - if (pre == NoType || clazz.kind != CLASS) - return this; - else if (sym.isSubClass(clazz) && - pre.widen().symbol().isSubClass(sym)) - return pre; - else - return toPrefix(sym, pre.baseType(clazz).prefix(), clazz.owner()); - } - - /** This type as seen from prefix `pre' and class `clazz'. This means: - * Replace all thistypes of `clazz' or one of its subclasses by `pre' - * and instantiate all parameters by arguments of `pre'. - * Proceed analogously for thistypes referring to outer classes. - */ - public Type asSeenFrom(Type pre, Symbol clazz) { - //System.out.println("computing asseenfrom of " + this + " with " + pre + "," + clazz);//DEBUG - return new AsSeenFromMap(pre, clazz).apply(this); - } - - /** Types `these' as seen from prefix `pre' and class `clazz'. - */ - public static Type[] asSeenFrom(Type[] these, Type pre, Symbol clazz) { - return new AsSeenFromMap(pre, clazz).map(these); - } - - /** The info of `sym', seen as a member of this type. - */ - public Type memberInfo(Symbol sym) { - return sym.info().asSeenFrom(this, sym.owner()); - } - - /** The type of `sym', seen as a member of this type. - */ - public Type memberType(Symbol sym) { - return sym.type().asSeenFrom(this, sym.owner()); - } - - /** The stabilized type of `sym', seen as a member of this type. - */ - public Type memberStabilizedType(Symbol sym) { - return sym.isStable() && this.isStable() - ? Type.singleTypeMethod(this, sym) - : this.memberType(sym); - } - - /** The low bound of `sym', seen as a member of this type. - */ - public Type memberLoBound(Symbol sym) { - return sym.loBound().asSeenFrom(this, sym.owner()); - } - - /** The view bound of `sym', seen as a member of this type. - */ - public Type memberVuBound(Symbol sym) { - return sym.vuBound().asSeenFrom(this, sym.owner()); - } - -// Substitutions --------------------------------------------------------------- - - /** A common map superclass for symbol/symbol and type/symbol substitutions. - */ - public static abstract class SubstMap extends Map { - private Symbol[] from; - - SubstMap(Symbol[] from) { - this.from = from; - } - - public boolean matches(Symbol sym1, Symbol sym2) { - return sym1 == sym2; - } - - /** Produce replacement type - * @param i The index in `from' of the symbol to be replaced. - * @param fromtp The type referring to this symbol. - */ - protected abstract Type replacement(int i, Type fromtp); - - /** Produce new substitution where some symbols are excluded. - * @param newfrom The new array of from symbols (without excluded syms) - * @param excluded The array of excluded sysmbols - */ - protected abstract SubstMap exclude(Symbol[] newfrom, Symbol[] excluded); - - public Type apply(Type t) { - switch (t) { - case TypeRef(NoPrefix, Symbol sym, Type[] args): - for (int i = 0; i < from.length; i++) { - if (matches(sym, from[i])) return replacement(i, t); - } - break; - case SingleType(NoPrefix, Symbol sym): - for (int i = 0; i < from.length; i++) { - if (matches(sym, from[i])) return replacement(i, t); - } - break; - case PolyType(Symbol[] tparams, Type result): - Symbol[] from1 = excludeSyms(from, tparams, from); - if (from1 != from) { - SubstMap f = exclude(from1, tparams); - Symbol[] tparams1 = f.map(tparams); - Type result1 = f.apply(result); - if (tparams1 != tparams) - result1 = result1.subst(tparams, tparams1); - if (tparams1 == tparams && result1 == result) return t; - else return PolyType(tparams1, result1); - } - } - return map(t); - } - //where - private boolean contains1(Symbol[] syms, Symbol sym) { - int i = 0; - while (i < syms.length && syms[i] != sym) i++; - return i < syms.length; - } - - private int nCommon(Symbol[] from, Symbol[] tparams) { - int cnt = 0; - for (int i = 0; i < from.length; i++) { - if (contains1(tparams, from[i])) cnt++; - } - return cnt; - } - - private Symbol[] excludeSyms(Symbol[] from, Symbol[] tparams, Symbol[] syms) { - int n = nCommon(from, tparams); - if (n == 0) { - return syms; - } else { - Symbol[] syms1 = new Symbol[syms.length - n]; - int j = 0; - for (int i = 0; i < from.length; i++) { - if (!contains1(tparams, from[i])) syms1[j++] = syms[i]; - } - return syms1; - } - } - - private Type[] excludeTypes(Symbol[] from, Symbol[] tparams, Type[] types) { - int n = nCommon(from, tparams); - if (n == 0) { - return types; - } else { - Type[] types1 = new Type[types.length - n]; - int j = 0; - for (int i = 0; i < from.length; i++) { - if (!contains1(tparams, from[i])) types1[j++] = types[i]; - } - return types1; - } - } - } - - /** A map for symbol/symbol substitutions - */ - public static class SubstSymMap extends SubstMap { - Symbol[] to; - protected SubstSymMap(Symbol[] from, Symbol[] to) { - super(from); - this.to = to; - } - protected Type replacement(int i, Type fromtp) { - switch (fromtp) { - case TypeRef(Type pre, Symbol sym, Type[] args): - return typeRef(pre, to[i], args); - case SingleType(Type pre, Symbol sym): - return singleType(pre, to[i]); - default: - throw new ApplicationError(); - } - } - protected SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) { - return new SubstSymMap(newfrom, excludeSyms(from, excluded, to)); - } - } - - /** A map for type/symbol substitutions - */ - public static class SubstTypeMap extends SubstMap { - Type[] to; - public SubstTypeMap(Symbol[] from, Type[] to) { - super(from); - this.to = to; - } - public Type replacement(int i, Type fromtp) { - return to[i]; - } - public SubstMap exclude(Symbol[] newfrom, Symbol[] excluded) { - return new SubstTypeMap(newfrom, excludeTypes(from, excluded, to)); - } - } - - - /** A map for symbol/symbol substitutions which, instead of - * cloning parameters, updates their symbol's types. - */ - public static class UpdateSubstSymMap extends SubstSymMap { - protected UpdateSubstSymMap(Symbol[] from, Symbol[] to) { - super(from, to); - } - public Type apply(Type t) { - switch (t) { - case PolyType(Symbol[] params, Type result): - // !!! Also update loBounds? How? loBound can only be set! - for (int i = 0; i < params.length; i++) { - Type tp = params[i].nextType(); - Type tp1 = apply(tp); - if (tp != tp1) params[i].updateInfo(tp1); - } - Type result1 = apply(result); - if (result1 == result) return t; - else return Type.PolyType(params, result1); - case MethodType(Symbol[] params, Type result): - for (int i = 0; i < params.length; i++) { - Type tp = params[i].nextType(); - Type tp1 = apply(tp); - if (tp != tp1) params[i].updateInfo(tp1); - } - Type result1 = apply(result); - if (result1 == result) return t; - else return Type.MethodType(params, result1); - default: - return super.apply(t); - } - } - public Symbol map(Symbol sym, boolean dontClone) { return sym; } - public Symbol[] map(Symbol[] syms, boolean dontClone) { return syms; } - public Scope map(Scope s) { return s; } - } - - /** Returns the given non-updating symbol/symbol substitution. */ - public static Map getSubst(Symbol[] from, Symbol[] to) { - return getSubst(from, to, false); - } - - /** Returns the given (updating?) symbol/symbol substitution. */ - public static Map getSubst(Symbol[] from, Symbol[] to, boolean update) { - if (from.length == 0 && to.length == 0) return IdMap; - if (update) return new UpdateSubstSymMap(from, to); - return new SubstSymMap(from, to); - } - - /** Returns the given non-updating symbol/type substitution. */ - public static Map getSubst(Symbol[] from, Type[] to) { - if (from.length == 0 && to.length == 0) return IdMap; - return new SubstTypeMap(from, to); - } - - /** Substitute symbols `to' for occurrences of symbols `from' in this type. - */ - public Type subst(Symbol[] from, Symbol[] to) { - if (to.length != 0 && from != to) {//!!! - assert from.length == to.length - : this + ": " + from.length + " != " + to.length; - return new SubstSymMap(from, to).apply(this); - } else return this; - } - - /** Substitute symbols `to' for occurrences of symbols `from' in these types. - */ - public static Type[] subst(Type[] these, Symbol[] from, Symbol[] to) { - if (these.length != 0 && to.length != 0 && from != to) { - assert from.length == to.length; - return new SubstSymMap(from, to).map(these); - } else return these; - } - - /** Substitute types `to' for occurrences of symbols `from' in this type. - */ - public Type subst(Symbol[] from, Type[] to) { - if (to.length != 0) { - assert from.length == to.length - : this + ": " + Debug.show(from) + " <> " + ArrayApply.toString(to); - return new SubstTypeMap(from, to).apply(this); - } else return this; - } - - /** Substitute types `to' for occurrences of symbols `from' in these types. - */ - public static Type[] subst(Type[] these, Symbol[] from, Type[] to) { - if (these.length != 0 && to.length != 0) { - assert from.length == to.length; - return new SubstTypeMap(from, to).map(these); - } else return these; - } - - /** - * A map that substitutes ThisTypes of a given class by a given - * type. All occurrences of the type parameters of the given class - * are replaced by the type arguments extracted from the given - * type. Furthermore, the prefixes of the given type are used to - * substitute, in the same way, the ThisTypes of the outer classes - * of the given class. - * - * object Foo { - * class C[D] { class I[J]; } - * val c: C[Int] = new C[Int]; - * class M[N] extends c.I[N]; - * } - * - * In the code above, a ThisTypeMap of class "I" and type - * "ThisType(M)", would do the following substitutions: - * - * - ThisType(I) -> ThisType(M) - * - TypeRef(_, J, _) -> TypeRef(_, N, -) - * - ThisType(C) -> SingleType(ThisType(Foo), c) - * - TypeRef(_, D, _) -> TypeRef(_, Int, _) - */ - private static class ThisTypeMap extends Map { - - private static Map create(Symbol clasz, Type type) { - HashMap subst = getSubst(clasz, type, 0); - return subst == null ? IdMap : new ThisTypeMap(subst); - } - - private static HashMap getSubst(Symbol clasz, Type type, int capacity){ - switch (type) { - case NoPrefix: - return getSubst(capacity); - case ThisType(Symbol symbol): - if (symbol == clasz) return getSubst(capacity); - } - Type base = type.baseType(clasz); - switch (base) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - capacity += 1 + args.length; - HashMap subst = getSubst(clasz.owner(), prefix, capacity); - subst.put(clasz, type); - Symbol[] params = clasz.typeParams(); - assert symbol == clasz && args.length == params.length: - type + " @ " + Debug.show(clasz) + " -> " + base; - for (int i = 0; i < params.length; i++) { - assert params[i].isParameter(): Debug.show(params[i]); - subst.put(params[i], args[i]); - } - return subst; - default: - throw Debug.abort("illegal case", - type + " @ " + Debug.show(clasz) + " -> " + base); - } - } - - private static HashMap getSubst(int capacity) { - return capacity == 0 ? null : new HashMap(capacity); - } - - private final HashMap/*<Symbol,Type>*/ subst; - - private ThisTypeMap(HashMap subst) { - this.subst = subst; - } - - public Type apply(Type type) { - switch (type) { - case ThisType(Symbol symbol): - Object lookup = subst.get(symbol); - if (lookup == null) break; - return (Type)lookup; - case TypeRef(NoPrefix, Symbol symbol, Type[] args): - if (!symbol.isParameter()) break; - assert args.length == 0: type; - Object lookup = subst.get(symbol); - if (lookup == null) break; - return (Type)lookup; - } - return map(type); - } - - public String toString() { - return subst.toString(); - } - - } - - /** Returns a ThisTypeMap of given class and type. */ - public static Map getThisTypeMap(Symbol clasz, Type type) { - return ThisTypeMap.create(clasz, type); - } - - /** A map for substitutions of thistypes. - */ - public static class SubstThisMap extends Map { - Symbol from; - Type to; - public SubstThisMap(Symbol from, Type to) { - this.from = from; - this.to = to; - } - public SubstThisMap(Symbol oldSym, Symbol newSym) { - this(oldSym, newSym.thisType()); - } - public Type apply(Type type) { - switch (type) { - case ThisType(Symbol sym): - return sym == from ? to : type; - default: - return map(type); - } - } - } - - public Type substThis(Symbol from, Type to) { - return new SubstThisMap(from, to).apply(this); - } - - public static Type[] substThis(Type[] these, Symbol from, Type to) { - return new SubstThisMap(from, to).map(these); - } - - static class ContainsMap extends Map { - boolean result = false; - Symbol sym; - ContainsMap(Symbol sym) { - this.sym = sym; - } - public Type apply(Type t) { - if (!result) { - switch (t) { - case TypeRef(Type pre, Symbol sym1, Type[] args): - if (sym == sym1) result = true; - else { map(pre); map(args); } - break; - case SingleType(Type pre, Symbol sym1): - map(pre); - if (sym == sym1) result = true; - break; - default: - map(t); - } - } - return t; - } - } - - /** Does this type contain symbol `sym'? - */ - public boolean contains(Symbol sym) { - ContainsMap f = new ContainsMap(sym); - f.apply(this); - return f.result; - } - - /** Does this type contain any of the symbols `syms'? - */ - public boolean containsSome(Symbol[] syms) { - for (int i = 0; i < syms.length; i++) - if (contains(syms[i])) return true; - return false; - } - -// Cloning --------------------------------------------------------------- - - /** Returns a shallow copy of the given array. */ - public static Type[] cloneArray(Type[] array) { - return cloneArray(0, array, 0); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items. - */ - public static Type[] cloneArray(int prefix, Type[] array) { - return cloneArray(prefix, array, 0); - } - - /** - * Returns a shallow copy of the given array suffixed by "suffix" - * null items. - */ - public static Type[] cloneArray(Type[] array, int suffix) { - return cloneArray(0, array, suffix); - } - - /** - * Returns a shallow copy of the given array prefixed by "prefix" - * null items and suffixed by "suffix" null items. - */ - public static Type[] cloneArray(int prefix, Type[] array, int suffix) { - assert prefix >= 0 && suffix >= 0: prefix + " - " + suffix; - int size = prefix + array.length + suffix; - if (size == 0) return EMPTY_ARRAY; - Type[] clone = new Type[size]; - for (int i = 0; i < array.length; i++) clone[prefix + i] = array[i]; - return clone; - } - - /** Returns the concatenation of the two arrays. */ - public static Type[] concat(Type[] array1, Type[] array2) { - if (array1.length == 0) return array2; - if (array2.length == 0) return array1; - Type[] clone = cloneArray(array1.length, array2); - for (int i = 0; i < array1.length; i++) clone[i] = array1[i]; - return clone; - } - - /** - * Clones a type i.e. returns a new type where all symbols in - * MethodTypes and PolyTypes and CompoundTypes have been cloned. - */ - public Type cloneType(Symbol oldOwner, Symbol newOwner) { - SymbolCloner cloner = new SymbolCloner(); - cloner.owners.put(oldOwner, newOwner); - return cloner.cloneType(this); - } - - /** - * Clones a type i.e. returns a new type where all symbols in - * MethodTypes and PolyTypes have been cloned. This method - * performs no substitution on the type of the cloned symbols. - * Typically, the type of those symbols will be fixed later by - * applying some Map.applyParams method to the returned type. - */ - public Type cloneTypeNoSubst(SymbolCloner cloner) { - switch (this) { - - case MethodType(Symbol[] vparams, Type result): - Symbol[] clones = cloner.cloneSymbols(vparams); - return Type.MethodType(clones, result.cloneTypeNoSubst(cloner)); - - case PolyType(Symbol[] tparams, Type result): - Symbol[] clones = cloner.cloneSymbols(tparams); - return Type.PolyType(clones, result.cloneTypeNoSubst(cloner)); - - default: - return this; - } - } - - -// Comparisons ------------------------------------------------------------------ - - /** Type relations */ - public static class Relation { - public case SubType; // this SubType that <=> this.isSubType(that) - public case SameType; // this SameType that <=> this.isSameAs(that) - public case SuperType; // this SuperType that <=> that.isSubType(this) - - public String toString() { - return toString(false); - } - public String toString(boolean negate) { - switch (this) { - case SubType : return negate ? "!<=" : "<="; - case SameType : return negate ? "!==" : "="; - case SuperType: return negate ? "!>=" : ">="; - default : throw Debug.abort("unknown relation", this); - } - } - } - - /** Is this type in given relation to that type? - */ - public boolean compareTo(Type that, Relation relation) { - switch (relation) { - case SubType : return this.isSubType(that); - case SameType : return this.isSameAs(that); - case SuperType: return that.isSubType(this); - default : throw Debug.abort("unknown relation", relation); - } - } - - /** Is this type a subtype of that type? - */ - public boolean isSubType(Type that) { - if (explainSwitch) { - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(this + " < " + that + "?"); - indent++; - } - boolean result = isSubType0(that); - if (explainSwitch) { - indent--; - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(result); - } - return result; - } - - public boolean isSubType0(Type that) { - if (this == that) return true; - - switch (this) { - case ErrorType: - case AnyType: - return true; - } - - switch (that) { - case ErrorType: - case AnyType: - return true; - - case NoType: - case NoPrefix: - return false; - - case ThisType(_): - case SingleType(_, _): - switch (this) { - case ThisType(_): - case SingleType(_, _): - return this.isSameAs(that); - default: - if (this.isSameAs(that)) return true; - } - break; - - case ConstantType(_, _): - switch (this) { - case ConstantType(Type base, _): - return this.isSameAs(that) || base.isSubType(that); - } - break; - - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym == sym1 && pre.isSubType(pre1) && - isSubArgs(args, args1, sym.typeParams()) - || - sym.kind == TYPE && pre.memberInfo(sym).isSubType(that)) - return true; - break; - } - if (sym1.kind == CLASS) { - Type base = this.baseType(sym1); - if (this != base && base.isSubType(that)) - return true; - } - break; - - case CompoundType(Type[] parts1, Scope members1): - int i = 0; - while (i < parts1.length && isSubType(parts1[i])) i++; - if (i == parts1.length && specializes(members1)) - return true; - break; - - case MethodType(Symbol[] ps1, Type res1): - switch (this) { - case MethodType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) { - Symbol p1 = ps1[i]; - Symbol p = ps[i]; - if (!p1.type().isSameAs(p.type()) || - (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED))) - return false; - } - return res.isSubType(res1); - } - break; - - case PolyType(Symbol[] ps1, Type res1): - switch (this) { - case PolyType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) - if (!ps1[i].info().subst(ps1, ps).isSubType(ps[i].info()) || - !ps[i].loBound().isSubType(ps1[i].loBound().subst(ps1, ps)) || - !ps1[i].vuBound().subst(ps1, ps).isSubType(ps[i].vuBound())) - return false; - return res.isSubType(res1.subst(ps1, ps)); - } - break; - - case OverloadedType(Symbol[] alts1, Type[] alttypes1): - for (int i = 0; i < alttypes1.length; i++) { - if (!isSubType(alttypes1[i])) - return false; - } - return true; - - case UnboxedType(int tag1): - switch (this) { - case UnboxedType(int tag): - return tag == tag1; - } - break; - - case UnboxedArrayType(Type elemtp1): - switch (this) { - case UnboxedArrayType(Type elemtp): - return elemtp.isSubType(elemtp1); - } - break; - - case TypeVar(Type origin, Constraint constr): - //todo: should we test for equality with origin? - if (constr.inst != NoType) { - return this.isSubType(constr.inst); - } else { - constr.lobounds = new List(this, constr.lobounds); - return true; - } - - default: - throw new ApplicationError(this + " <: " + that); - } - - switch (this) { - case NoType: - case NoPrefix: - return false; - case ThisType(_): - case SingleType(_, _): - if (this.isSameAs(that)) return true; - if (this.singleDeref().isSubType(that)) return true; - break; - case ConstantType(_, _): - if (this.singleDeref().isSubType(that)) return true; - break; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) { - return constr.inst.isSubType(that); - } else { - constr.hibounds = new List(that, constr.hibounds); - return true; - } - - case TypeRef(_, Symbol sym, _): - switch (that) { - case TypeRef(_, Symbol sym1, _): - if (sym1.kind == TYPE && this.isSubType(that.loBound())) - return true; - } - if (sym == Global.instance.definitions.ALL_CLASS) - return that.isSubType(Global.instance.definitions.ANY_TYPE()); - else if (sym == Global.instance.definitions.ALLREF_CLASS) - return - that.symbol() == Global.instance.definitions.ANY_CLASS || - (that.symbol() != Global.instance.definitions.ALL_CLASS && - that.isSubType(Global.instance.definitions.ANYREF_TYPE())); - break; - - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alttypes.length; i++) { - if (alttypes[i].isSubType(that)) return true; - } - break; - - case CompoundType(Type[] parts, Scope members): - int i = 0; - while (i < parts.length) { - if (parts[i].isSubType(that)) return true; - i++; - } - break; - - case UnboxedArrayType(_): - if (Global.instance.definitions.OBJECT_TYPE().isSubType(that)) - return true; - // !!! we should probably also test for Clonable, Serializable, ... - } - - return false; - } - - /** Are types `these' subtypes of corresponding types `those'? - */ - public static boolean isSubType(Type[] these, Type[] those) { - if (these.length != those.length) return false; - for (int i = 0; i < these.length; i++) { - if (!these[i].isSubType(those[i])) return false; - } - return true; - } - - /** Are types `these' arguments types conforming to corresponding types `those'? - */ - static boolean isSubArgs(Type[] these, Type[] those, Symbol[] tparams) { - if (these.length != those.length) return false; - for (int i = 0; i < these.length; i++) { - if ((tparams[i].flags & COVARIANT) != 0) { - if (!these[i].isSubType(those[i])) return false; - } else if ((tparams[i].flags & CONTRAVARIANT) != 0) { - //System.out.println("contra: " + these[i] + " " + those[i] + " " + those[i].isSubType(these[i]));//DEBUG - if (!those[i].isSubType(these[i])) return false; - } else { - if (!these[i].isSameAs(those[i])) return false; - } - } - return true; - } - - public static boolean isSubSet(Type[] alts, Type[] alts1) { - for (int i = 0; i < alts.length; i++) { - int j = 0; - while (j < alts1.length && !alts1[j].isSameAs(alts[i])) j++; - if (j == alts1.length) return false; - } - return true; - } - - /** Does this type implement all symbols in scope `s' with same or stronger types? - */ - public boolean specializes(Scope s) { - for (Scope.SymbolIterator it = s.iterator(); - it.hasNext();) { - if (!specializes(it.next())) return false; - } - return true; - } - - /** Does this type implement symbol `sym1' with same or stronger type? - */ - public boolean specializes(Symbol sym1) { - if (explainSwitch) { - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(this + " specializes " + sym1 + "?"); - indent++; - } - boolean result = specializes0(sym1); - if (explainSwitch) { - indent--; - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(result); - } - return result; - } - - private boolean specializes0(Symbol sym1) { - Type self = narrow(); - Symbol[] tparams = symbol().typeParams(); - Type[] targs = typeArgs(); - Symbol sym = lookup(sym1.name); - return - sym.kind != NONE && - (sym == sym1 - || - (sym.kind == sym1.kind || sym1.kind == TYPE) && - self.memberInfo(sym).subst(tparams, targs) - .isSubType(sym1.info().substThis(sym1.owner(), self)) && - sym1.loBound().substThis(sym1.owner(), self) - .isSubType(self.memberLoBound(sym).subst(tparams, targs)) && - self.memberVuBound(sym).subst(tparams, targs) - .isSubType(sym1.vuBound().substThis(sym1.owner(), self)) - || - (sym.kind == TYPE && sym1.kind == ALIAS && - sym1.info().unalias().isSameAs(sym.type()))); - } - - /** Is this type the same as that type? - */ - public boolean isSameAs(Type that) { - if (explainSwitch) { - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(this + " = " + that + "?"); - indent++; - } - boolean result = isSameAs0(that); - if (explainSwitch) { - indent--; - for (int i = 0; i < indent; i++) System.out.print(" "); - System.out.println(result); - } - return result; - } - - public boolean isSameAs0(Type that) { - if (this == that) return true; - - switch (this) { - case ErrorType: - case AnyType: - return true; - - case ThisType(Symbol sym): - switch (that) { - case ThisType(Symbol sym1): - return sym == sym1; - case SingleType(Type pre1, Symbol sym1): - return sym1.isModule() - && sym == sym1.moduleClass() - && sym.owner().thisType().isSameAs(pre1) - || - this.singleDeref().isSingletonType() && - this.singleDeref().isSameAs(that) - || - that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - deAlias(that) != that && - this.isSameAs(deAlias(that)); - default: - if (deAlias(this) != this) - return deAlias(this).isSameAs(that); - } - break; - - case SingleType(Type pre, Symbol sym): - switch (that) { - case SingleType(Type pre1, Symbol sym1): - return sym == sym1 && pre.isSameAs(pre1) - || - this.singleDeref().isSingletonType() && - this.singleDeref().isSameAs(that) - || - that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - (deAlias(this) != this || deAlias(that) != that) && - deAlias(this).isSameAs(deAlias(that)); - case ThisType(Symbol sym1): - return sym.isModule() - && sym.moduleClass() == sym1 - && pre.isSameAs(sym1.owner().thisType()) - || - this.singleDeref().isSingletonType() && - this.singleDeref().isSameAs(that) - || - that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - deAlias(this) != this && - deAlias(this).isSameAs(that); - default: - if (deAlias(this) != this) - return deAlias(this).isSameAs(that); - } - break; - - case ConstantType(Type base, AConstant value): - switch (that) { - case ConstantType(Type base1, AConstant value1): - return base.isSameAs(base1) && value.equals(value1); - } - break; - - case TypeRef(Type pre, Symbol sym, Type[] args): - switch (that) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - if (sym == sym1 && pre.isSameAs(pre1) && isSameAs(args, args1)) - return true; - } - break; - - case CompoundType(Type[] parts, Scope members): - switch (that) { - case CompoundType(Type[] parts1, Scope members1): - if (parts.length != parts1.length) return false; - for (int i = 0; i < parts.length; i++) - if (!parts[i].isSameAs(parts1[i])) return false; - return isSameAs(members, members1); - } - break; - - case MethodType(Symbol[] ps, Type res): - switch (that) { - case MethodType(Symbol[] ps1, Type res1): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) { - Symbol p1 = ps1[i]; - Symbol p = ps[i]; - if (!p1.type().isSameAs(p.type()) || - (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED))) - return false; - } - return res.isSameAs(res1); - } - break; - - case PolyType(Symbol[] ps, Type res): - switch (that) { - case PolyType(Symbol[] ps1, Type res1): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) - if (!ps1[i].info().subst(ps1, ps).isSameAs(ps[i].info()) || - !ps1[i].loBound().subst(ps1, ps).isSameAs(ps[i].loBound()) || - !ps1[i].vuBound().subst(ps1, ps).isSameAs(ps[i].vuBound())) - return false; - return res.isSameAs(res1.subst(ps1, ps)); - } - break; - - case OverloadedType(Symbol[] alts, Type[] alttypes): - switch (that) { - case OverloadedType(Symbol[] alts1, Type[] alttypes1): - return isSubSet(alttypes1, alttypes) - && isSubSet(alttypes, alttypes1); - } - break; - - case UnboxedType(int kind): - switch (that) { - case UnboxedType(int kind1): - return kind == kind1; - } - break; - - case UnboxedArrayType(Type elemtp): - switch (that) { - case UnboxedArrayType(Type elemtp1): - return elemtp.isSameAs(elemtp1); - } - break; - } - - switch (that) { - case ErrorType: - case AnyType: - return true; - case NoType: - case NoPrefix: - return false; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.isSameAs(this); - else return constr.instantiate(this.any2typevar()); - case ThisType(_): - case SingleType(_, _): - if (deAlias(that) != that) - return this.isSameAs(deAlias(that)); - } - - switch (this) { - case NoType: - case NoPrefix: - return false; - case TypeVar(Type origin, Constraint constr): - if (constr.inst != NoType) return constr.inst.isSameAs(that); - else return constr.instantiate(that.any2typevar()); - } - - return false; - } - //where - - static Type deAlias(Type tp) { - switch (tp) { - case ThisType(_): - case SingleType(_, _): - Type tp1 = tp.singleDeref(); - if (tp1.isStable()) return deAlias(tp1); - } - return tp; - } - - /** Are types `these' the same as corresponding types `those'? - */ - public static boolean isSameAs(Type[] these, Type[] those) { - if (these.length != those.length) return false; - for (int i = 0; i < these.length; i++) { - if (!these[i].isSameAs(those[i])) return false; - } - return true; - } - - /** Do scopes `s1' and `s2' define he same symbols with the same kinds and infos? - */ - public boolean isSameAs(Scope s1, Scope s2) { - return isSubScope(s1, s2) && isSubScope(s2, s1); - } - - /** Does scope `s1' define all symbols of scope `s2' with the same kinds and infos? - */ - private boolean isSubScope(Scope s1, Scope s2) { - for (Scope.SymbolIterator it = s2.iterator(); it.hasNext(); ) { - Symbol sym2 = it.next(); - // todo: handle overloaded - Symbol sym1 = s1.lookup(sym2.name); - if (sym1.kind != sym2.kind || - !sym1.info().isSameAs( - sym2.info().substThis( - sym2.owner(), sym1.owner().thisType())) || - !sym1.loBound().isSameAs( - sym2.loBound().substThis( - sym2.owner(), sym1.owner().thisType())) || - !sym1.vuBound().isSameAs( - sym2.vuBound().substThis( - sym2.owner(), sym1.owner().thisType()))) - return false; - } - return true; - } - - boolean isSameAsAll(Type[] tps) { - int i = 1; - while (i < tps.length && isSameAs(tps[i])) i++; - return i == tps.length; - } - - /** Map every occurrence of AnyType to a fresh type variable. - */ - public static Map any2typevarMap = new Map() { - public Type apply(Type t) { return t.any2typevar(); } - }; - - public Type any2typevar() { - switch (this) { - case AnyType: - return TypeVar(this, new Constraint()); - default: - return any2typevarMap.map(this); - } - } - - /** Does this type match type `tp', so that corresponding symbols with - * the two types would be taken to override each other? - */ - public boolean overrides(Type tp) { - switch (this) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alttypes.length; i++) { - if (alttypes[i].overrides(tp)) return true; - } - return false; - default: - switch (tp) { - case MethodType(Symbol[] ps1, Type res1): - switch (this) { - case MethodType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) { - Symbol p1 = ps1[i]; - Symbol p = ps[i]; - if (!p1.type().isSameAs(p.type()) || - (p1.flags & (DEF | REPEATED)) != (p.flags & (DEF | REPEATED))) - return false; - } - return res.overrides(res1); - } - return false; - - case PolyType(Symbol[] ps1, Type res1): - switch (this) { - case PolyType(Symbol[] ps, Type res): - if (ps.length != ps1.length) return false; - for (int i = 0; i < ps.length; i++) - if (!ps1[i].info().subst(ps1, ps).isSubType(ps[i].info()) || - !ps[i].loBound().isSubType(ps1[i].loBound().subst(ps1, ps)) || - !ps1[i].vuBound().subst(ps1, ps).isSubType(ps[i].vuBound())) - return false; - return res.overrides(res1.subst(ps1, ps)); - } - return false; - - case OverloadedType(_, _): - throw new ApplicationError("overrides inapplicable for " + tp); - - default: - switch (this) { - case MethodType(_, _): case PolyType(_, _): return false; - default: return true; - } - } - } - } - -// Closures and Least Upper Bounds --------------------------------------------------- - - /** The closure of this type, i.e. the widened type itself followed by all - * its direct and indirect (pre-) base types, sorted by Symbol.isLess(). - */ - public Type[] closure() { - switch (this.widen().unalias()) { - case TypeRef(Type pre, Symbol sym, Type[] args): - return subst( - asSeenFrom(sym.closure(), pre, sym.owner()), - sym.typeParams(), args); - - case CompoundType(Type[] parts, Scope members): -/* - if (symbol().isCompoundSym()) { - Type[][] closures = new Type[parts.length][]; - for (int i = 0; i < parts.length; i++) - closures[i] = parts[i].closure(); - return union(closures); - } else { -*/ - return symbol().closure(); - - default: - return new Type[]{this}; - } - } - - /** return union of array of closures. It is assumed that - * for any two base types with the same class symbols the later one - * is a subtype of the former. - */ - static private Type[] union(Type[][] closures) { - if (closures.length == 1) return closures[0]; // fast special case - int[] index = new int[closures.length]; - int totalsize = 0; - for (int i = 0; i < index.length; i++) { - index[i] = 0; - totalsize = totalsize + closures[i].length; - } - Type[] res = new Type[totalsize]; - int j = 0; - - while (true) { - // find minimal element - Type min = null; - for (int i = 0; i < index.length; i++) { - if (index[i] < closures[i].length) { - Type cltype = closures[i][index[i]]; - if (min == null || - cltype.symbol().isLess(min.symbol()) || - cltype.symbol() == min.symbol()) { - min = cltype; - } - } - } - if (min == null) break; - - res[j] = min; - j = j + 1; - - // bump all indices that start with minimal element - for (int i = 0; i < index.length; i++) { - if (index[i] < closures[i].length && - closures[i][index[i]].symbol() == min.symbol()) - index[i] = index[i] + 1; - } - } - Type[] result = new Type[j]; - System.arraycopy(res, 0, result, 0, j); - return result; - } - - /** return intersection of non-empty array of closures - */ - static private Type[] intersection(Type[][] closures) { - if (closures.length == 1) return closures[0]; // fast special case - int[] index = new int[closures.length]; - Type[] mintypes = new Type[closures.length]; - int minsize = Integer.MAX_VALUE; - for (int i = 0; i < index.length; i++) { - index[i] = 0; - if (closures[i].length < minsize) minsize = closures[i].length; - } - Type[] res = new Type[minsize]; - int j = 0; - - L: - while (true) { - // find minimal element - Symbol minsym = null; - for (int i = 0; i < index.length; i++) { - if (index[i] == closures[i].length) break L; - Symbol clsym = closures[i][index[i]].symbol(); - if (minsym == null || clsym.isLess(minsym)) minsym = clsym; - } - - boolean agree = true; - // bump all indices that start with minimal element - for (int i = 0; i < index.length; i++) { - Type cltype = closures[i][index[i]]; - if (cltype.symbol() == minsym) { - mintypes[i] = cltype; - index[i] = index[i] + 1; - } else { - agree = false; - } - } - if (agree) { - Type mintype = argLub(mintypes); - if (mintype.symbol().kind == CLASS) { - res[j] = mintype; - j = j + 1; - } - } - } - Type[] result = new Type[j]; - System.arraycopy(res, 0, result, 0, j); - return result; - } - - /** same as lub, but all types are instances of the same class, - * possibly with different prefixes and arguments. - */ - //todo: catch lubs not within bounds. - static Type argLub(Type[] tps) { - tps = elimRedundant(tps, true); - if (tps.length == 1) return tps[0]; - - Type pre = tps[0].prefix(); - Symbol sym = tps[0].symbol(); - Symbol[] tparams = sym.typeParams(); - Type[] args = new Type[tparams.length]; - Type[][] argss = new Type[args.length][tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - assert sym == sym1; - assert args1.length == args.length; - if (!pre.isSameAs(pre1)) return NoType; - for (int j = 0; j < args1.length; j++) - argss[j][i] = args1[j]; - break; - case ErrorType: - return ErrorType; - default: - assert false : tps[i]; - } - } - for (int j = 0; j < args.length; j++) { - if ((tparams[j].flags & COVARIANT) != 0) - args[j] = lub(argss[j]); - else if ((tparams[j].flags & CONTRAVARIANT) != 0) - args[j] = glb(argss[j]); - else return NoType; - } - return typeRef(pre, sym, args); - } - - /** The frontier of a closure C is the minimal set of types such that - * the union of the closures of these types equals C. - */ - static private Type[] frontier(Type[] closure) { - Type[] front = new Type[closure.length]; - int j = 0; - for (int i = 0; i < closure.length; i++) { - int k = 0; - Type tp = closure[i]; - while (k < j && !front[k].symbol().isSubClass(tp.symbol())) - k++; - if (k == j) { - front[j] = tp; - j++; - } - } - Type[] result = new Type[j]; - System.arraycopy(front, 0, result, 0, j); - return result; - } - - /** remove types that are subtypes of some other type. - */ - static private Type[] elimRedundant(Type[] tps, boolean elimLower) { - Type.List tl = Type.List.EMPTY; - int nredundant = 0; - boolean[] redundant = new boolean[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case ErrorType: - return new Type[]{ErrorType}; - case MethodType(_, _): - case PolyType(_, _): - case OverloadedType(_, _): - return new Type[]{NoType}; - default: - assert tps[i].isObjectType(): tps[i]; - for (int j = 0; j < i && !redundant[i]; j++) { - if (!redundant[j]) { - if (tps[i].isSubType(tps[j])) { - redundant[elimLower ? i : j] = true; - nredundant++; - } else if (tps[j].isSubType(tps[i])) { - redundant[elimLower ? j : i] = true; - nredundant++; - } - } - } - } - } - - if (nredundant != 0) { - Type[] tps1 = new Type[tps.length - nredundant]; - int n = 0; - for (int i = 0; i < tps.length; i++) { - if (!redundant[i]) tps1[n++] = tps[i]; - } - return tps1; - } else { - return tps; - } - } - - static int recCount = 0; - static boolean giveUp = false; - static int recLimit = 10; - - public static Type lub(Type[] tps) { - if (recCount == recLimit) { - giveUp = true; - return Global.instance.definitions.ANY_TYPE(); - } else { - recCount++; - Type result = lub0(tps); - recCount--; - if (recCount == 0) { - if (giveUp) { - giveUp = false; - throw new Error("failure to compute least upper bound of types " + - ArrayApply.toString(tps, "", " and ", ";\n") + - "an approximation is: " + result + ";\n" + - "additional type annotations are needed"); - } else { - giveUp = false; - } - } - return result; - } - } - - /** Return the least upper bound of non-empty array of types `tps'. - */ - public static Type lub0(Type[] tps) { - //for (int i = 0; i < recCount; i++) System.out.print(" "); System.out.println("lub" + ArrayApply.toString(tps));//debug - - if (tps.length == 0) return Global.instance.definitions.ALL_TYPE(); - - //If all types are method types with same parameters, - //compute lub of their result types. - switch (tps[0]) { - case PolyType(Symbol[] tparams, _): - return polyLub(tps, tparams); - case MethodType(Symbol[] vparams, _): - return methodLub(tps, vparams); - } - - // remove types that are subtypes of some other type. - tps = elimRedundant(tps, true); - if (tps.length == 1) return tps[0]; - - // singleDeref singletypes and try again - Type[] tps1 = tps; - for (int i = 0; i < tps.length; i++) { - Type tp1 = tps[i].singleDeref(); - if (tp1 != tps[i] && tps1 == tps) { - tps1 = new Type[tps.length]; - System.arraycopy(tps, 0, tps1, 0, i); - } - tps1[i] = tp1; - } - if (tps1 != tps) return lub0(tps1); - - // intersect closures and build frontier. - Type[][] closures = new Type[tps.length][]; - for (int i = 0; i < tps.length; i++) { - closures[i] = tps[i].closure(); - } - Type[] allBaseTypes = intersection(closures); - Type[] leastBaseTypes = frontier(allBaseTypes); - assert leastBaseTypes.length > 0 : ArrayApply.toString(tps); - - // add refinements where necessary - Scope members = new Scope(); - Type lubType = compoundTypeWithOwner(Symbol.NONE, leastBaseTypes, members); // !!! NONE - /* - Type lubThisType = lubType.narrow(); - //System.out.println("lubtype = " + lubType);//DEBUG - - Symbol[] rsyms = new Symbol[tps.length]; - Type[] rtps = new Type[tps.length]; - Type[] rlbs = new Type[tps.length]; - for (int i = 0; i < allBaseTypes.length; i++) { - for (Scope.SymbolIterator it = allBaseTypes[i].members().iterator(); - it.hasNext(); ) { - Symbol sym = it.next(); - Name name = sym.name; - if ((sym.flags & PRIVATE) == 0 && lubType.lookup(name) == sym) { - Type symType = memberTp(lubThisType, sym); - Type symLoBound = lubThisType.memberLoBound(sym); - int j = 0; - while (j < tps.length) { - rsyms[j] = tps[j].lookupNonPrivate(name); - if (rsyms[j] == sym) break; - rtps[j] = memberTp(tps[j], rsyms[j]) - .substThis(tps[j].symbol(), lubThisType); - rlbs[j] = tps[j].memberLoBound(rsyms[j]) - .substThis(tps[j].symbol(), lubThisType); - if (rtps[j].isSameAs(symType) && - rlbs[j].isSameAs(symLoBound)) break; - j++; - } - if (j == tps.length) { - if (Global.instance.debug) - System.out.println("refinement lub for " + - ArrayApply.toString(rsyms) + ":" + ArrayApply.toString(rtps));//debug - Symbol lubSym = lub(rsyms, rtps, rlbs, lubType.symbol()); - if (lubSym.kind != NONE && - !(lubSym.kind == sym.kind && - lubSym.info().isSameAs(symType) && - lubSym.loBound().isSameAs(symType))) - members.enter(lubSym); - } - } - } - } - //System.out.print("lub "); System.out.print(ArrayApply.toString(tps)); System.out.println(" = " + lubType);//DEBUG - */ - if (leastBaseTypes.length == 1 && members.isEmpty()) - return leastBaseTypes[0]; - else return lubType; - } - //where - private static Type memberTp(Type base, Symbol sym) { - return sym.kind == CLASS ? base.memberType(sym) : base.memberInfo(sym); - } - - private static Type polyLub(Type[] tps, Symbol[] tparams0) { - Type[][] hiboundss = new Type[tparams0.length][tps.length]; - Type[][] loboundss = new Type[tparams0.length][tps.length]; - Type[][] vuboundss = new Type[tparams0.length][tps.length]; - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == tparams0.length) { - for (int j = 0; j < tparams0.length; j++) { - hiboundss[j][i] = tparams[j].info() - .subst(tparams, tparams0); - loboundss[j][i] = tparams[j].loBound() - .subst(tparams, tparams0); - vuboundss[j][i] = tparams[j].vuBound() - .subst(tparams, tparams0); - } - restps[i] = restp.subst(tparams, tparams0); - } else { - return Type.NoType; - } - break; - default: - return Type.NoType; - } - } - Type[] hibounds = new Type[tparams0.length]; - Type[] lobounds = new Type[tparams0.length]; - Type[] vubounds = new Type[tparams0.length]; - for (int j = 0; j < tparams0.length; j++) { - hibounds[j] = glb(hiboundss[j]); - lobounds[j] = lub(loboundss[j]); - vubounds[j] = glb(vuboundss[j]); - } - Symbol[] tparams = new Symbol[tparams0.length]; - for (int j = 0; j < tparams.length; j++) { - tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE) - .setInfo(hibounds[j].subst(tparams0, tparams)) - .setLoBound(lobounds[j].subst(tparams0, tparams)) - .setVuBound(vubounds[j].subst(tparams0, tparams)); - } - return Type.PolyType(tparams, lub(restps).subst(tparams0, tparams)); - } - - private static Type methodLub(Type[] tps, Symbol[] vparams0) { - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case MethodType(Symbol[] vparams, Type restp): - if (vparams.length != vparams0.length) - return Type.NoType; - for (int j = 0; j < vparams.length; j++) - if (!vparams[j].type().isSameAs(vparams0[j].type()) || - (vparams[j].flags & (DEF | REPEATED)) != - (vparams0[j].flags & (DEF | REPEATED))) - return Type.NoType; - restps[i] = restp; - } - } - Symbol[] vparams = new Symbol[vparams0.length]; - for (int j = 0; j < vparams.length; j++) { - vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE); - } - return Type.MethodType(vparams, lub(restps)); - } - - private static Symbol lub(Symbol[] syms, Type[] tps, Type[] lbs, Symbol owner) { - //System.out.println("lub" + ArrayApply.toString(syms));//DEBUG - int lubKind = syms[0].kind; - for (int i = 1; i < syms.length; i++) { - Symbol sym = syms[i]; - if (sym.isError()) return Symbol.NONE; - if (sym.isType() && sym.kind != lubKind) lubKind = TYPE; - } - if (lubKind == syms[0].kind && tps[0].isSameAsAll(tps)) { - return syms[0].cloneSymbol(); - } - - Type lubType = lub(tps); - if (lubType == Type.NoType) return Symbol.NONE; - Symbol lubSym; - switch (lubKind) { - case VAL: - lubSym = owner.newTerm(syms[0].pos, 0, syms[0].name); - break; - case TYPE: case ALIAS: case CLASS: - lubSym = owner.newAbstractType(syms[0].pos, 0, syms[0].name); - lubSym.setLoBound(glb(lbs)); - break; - default: - throw new ApplicationError(); - } - lubSym.setInfo(lubType.setOwner(lubSym)); - return lubSym; - } - - public static Type glb(Type[] tps) { - if (recCount == recLimit) { - giveUp = true; - return Global.instance.definitions.ALL_TYPE(); - } else { - recCount++; - Type result = glb0(tps); - recCount--; - if (recCount == 0) { - if (giveUp) { - giveUp = false; - throw new Error("failure to compute greatest lower bound of types " + - ArrayApply.toString(tps, "", " and ", ";\n") + - "an approximation is: " + result + ";\n" + - "additional type annotations are needed"); - } else { - giveUp = false; - } - } - return result; - } - } - - public static Type glb0(Type[] tps) { - if (tps.length == 0) return Global.instance.definitions.ANY_TYPE(); - - // step one: eliminate redunandant types; return if one one is left - tps = elimRedundant(tps, false); - if (tps.length == 1) return tps[0]; - - // step two: build arrays of all typerefs and all refinements - Type.List treftl = Type.List.EMPTY; - Type.List comptl = Type.List.EMPTY; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case TypeRef(_, _, _): - treftl = new Type.List(tps[i], treftl); - break; - case CompoundType(Type[] parents, Scope members): - if (!members.isEmpty()) - comptl = new Type.List(tps[i], comptl); - for (int j = 0; j < parents.length; j++) - treftl = new Type.List(parents[j], treftl); - break; - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return Global.instance.definitions.ALL_TYPE(); - } - } - - CompoundType glbType = compoundTypeWithOwner(Symbol.NONE, Type.EMPTY_ARRAY, new Scope()); // !!! NONE - Type glbThisType = glbType.narrow(); - - // step 3: compute glb of all refinements. - Scope members = Scope.EMPTY; - if (comptl != List.EMPTY) { - Type[] comptypes = comptl.toArrayReverse(); - Scope[] refinements = new Scope[comptypes.length]; - for (int i = 0; i < comptypes.length; i++) - refinements[i] = comptypes[i].members(); - if (!setGlb(glbType.members, refinements, glbThisType)) { - // refinements don't have lower bound, so approximate - // by AllRef - glbType.members = Scope.EMPTY; - treftl = new Type.List( - Global.instance.definitions.ALLREF_TYPE(), treftl); - } - } - - // eliminate redudant typerefs - Type[] treftypes = elimRedundant(treftl.toArrayReverse(), false); - if (treftypes.length != 1 || !glbType.members.isEmpty()) { - // step 4: replace all abstract types by their lower bounds. - boolean hasAbstract = false; - for (int i = 0; i < treftypes.length; i++) { - if (treftypes[i].unalias().symbol().kind == TYPE) - hasAbstract = true; - } - if (hasAbstract) { - treftl = Type.List.EMPTY; - for (int i = 0; i < treftypes.length; i++) { - if (treftypes[i].unalias().symbol().kind == TYPE) - treftl = new Type.List(treftypes[i].loBound(), treftl); - else - treftl = new Type.List(treftypes[i], treftl); - } - treftypes = elimRedundant(treftl.toArrayReverse(), false); - } - } - - if (treftypes.length != 1) { - // step 5: if there are conflicting instantiations of same - // class, replace them by lub/glb of arguments or lower bound. - Type lb = NoType; - for (int i = 0; - i < treftypes.length && - lb.symbol() != Global.instance.definitions.ALL_CLASS; - i++) { - for (int j = 0; j < i; j++) { - if (treftypes[j].symbol() == treftypes[i].symbol()) - lb = argGlb(treftypes[j], treftypes[i]); - } - } - if (lb != NoType) return lb; - } - - if (treftypes.length == 1 && glbType.members.isEmpty()) { - return treftypes[0]; - } else { - glbType.parts = treftypes; - return glbType; - } - } - - private static Type argGlb(Type tp1, Type tp2) { - switch (tp1) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - switch (tp2) { - case TypeRef(Type pre2, Symbol sym2, Type[] args2): - assert sym1 == sym2; - if (pre1.isSameAs(pre2)) { - Symbol[] tparams = sym1.typeParams(); - Type[] args = new Type[tparams.length]; - for (int i = 0; i < tparams.length; i++) { - if (args1[i].isSameAs(args2[i])) - args[i] = args1[i]; - else if ((tparams[i].flags & COVARIANT) != 0) - args[i]= lub(new Type[]{args1[i], args2[i]}); - else if ((tparams[i].flags & CONTRAVARIANT) != 0) - args[i]= glb(new Type[]{args1[i], args2[i]}); - else - return glb(new Type[]{tp1.loBound(), tp2.loBound()}); - } - return typeRef(pre1, sym1, args); - } - } - } - return glb(new Type[]{tp1.loBound(), tp2.loBound()}); - } - - /** Set scope `result' to glb of scopes `ss'. Return true iff succeeded. - */ - private static boolean setGlb(Scope result, Scope[] ss, Type glbThisType) { - for (int i = 0; i < ss.length; i++) - for (Scope.SymbolIterator it = ss[i].iterator(); it.hasNext(); ) - if (!addMember(result, it.next(), glbThisType)) return false; - return true; - } - - /** Add member `sym' to scope `s'. If`s' has already a member with same name, - * overwrite its info/low bound to form glb of both symbols. - */ - private static boolean addMember(Scope s, Symbol sym, Type glbThisType) { - Type syminfo = sym.info().substThis(sym.owner(), glbThisType); - Type symlb = sym.loBound().substThis(sym.owner(), glbThisType); - Type symvb = sym.vuBound().substThis(sym.owner(), glbThisType); - Scope.Entry e = s.lookupEntry(sym.name); - if (e == Scope.Entry.NONE) { - Symbol sym1 = sym.cloneSymbol(glbThisType.symbol()); - sym1.setInfo(syminfo); - if (sym1.kind == TYPE) { - sym1.setLoBound(symlb); - sym1.setVuBound(symvb); - } - s.enter(sym1); - } else { - Type einfo = e.sym.info(); - if (einfo.isSameAs(syminfo)) { - } else if (einfo.isSubType(syminfo) && sym.kind != ALIAS) { - } else if (syminfo.isSubType(einfo) && e.sym.kind != ALIAS) { - e.sym.setInfo(syminfo); - } else if (sym.kind == VAL && e.sym.kind == VAL || - sym.kind == TYPE && e.sym.kind == TYPE) { - e.sym.setInfo(glb(new Type[]{einfo, syminfo}).setOwner(e.sym)); - } else { - return false; - } - if (e.sym.kind == TYPE && sym.kind == TYPE) { - Type elb = e.sym.loBound(); - if (elb.isSameAs(symlb)) { - } else if (symlb.isSubType(elb)) { - } else if (elb.isSubType(symlb)) { - e.sym.setLoBound(symlb); - } else { - e.sym.setLoBound(lub(new Type[]{elb, symlb})); - } - Type evb = e.sym.vuBound(); - if (evb.isSameAs(symvb)) { - } else if (evb.isSubType(symvb)) { - } else if (symvb.isSubType(evb)) { - e.sym.setVuBound(symvb); - } else { - e.sym.setVuBound(glb(new Type[]{evb, symvb})); - } - } - } - return true; - } - - private static Type polyGlb(Type[] tps, Symbol[] tparams0) { - Type[][] hiboundss = new Type[tparams0.length][tps.length]; - Type[][] loboundss = new Type[tparams0.length][tps.length]; - Type[][] vuboundss = new Type[tparams0.length][tps.length]; - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case PolyType(Symbol[] tparams, Type restp): - if (tparams.length == tparams0.length) { - for (int j = 0; j < tparams0.length; j++) { - hiboundss[j][i] = tparams[j].info() - .subst(tparams, tparams0); - loboundss[j][i] = tparams[j].loBound() - .subst(tparams, tparams0); - vuboundss[j][i] = tparams[j].vuBound() - .subst(tparams, tparams0); - } - restps[i] = restp.subst(tparams, tparams0); - } else { - return Type.NoType; - } - break; - default: - return Type.NoType; - } - } - Type[] hibounds = new Type[tparams0.length]; - Type[] lobounds = new Type[tparams0.length]; - Type[] vubounds = new Type[tparams0.length]; - for (int j = 0; j < tparams0.length; j++) { - hibounds[j] = lub(hiboundss[j]); - lobounds[j] = glb(loboundss[j]); - vubounds[j] = lub(vuboundss[j]); - } - Symbol[] tparams = new Symbol[tparams0.length]; - for (int j = 0; j < tparams.length; j++) { - tparams[j] = tparams0[j].cloneSymbol(Symbol.NONE) - .setInfo(hibounds[j].subst(tparams0, tparams)) - .setLoBound(lobounds[j].subst(tparams0, tparams)) - .setVuBound(vubounds[j].subst(tparams0, tparams)); - } - return Type.PolyType(tparams, glb(restps).subst(tparams0, tparams)); - } - - private static Type methodGlb(Type[] tps, Symbol[] vparams0) { - Type[] restps = new Type[tps.length]; - for (int i = 0; i < tps.length; i++) { - switch (tps[i]) { - case MethodType(Symbol[] vparams, Type restp): - if (vparams.length != vparams0.length) - return Type.NoType; - for (int j = 0; j < vparams.length; j++) - if (!vparams[i].type().isSameAs(vparams0[i].type()) || - (vparams[i].flags & (DEF | REPEATED)) != - (vparams0[i].flags & (DEF | REPEATED))) - return Type.NoType; - restps[i] = restp; - } - } - Symbol[] vparams = new Symbol[vparams0.length]; - for (int j = 0; j < vparams.length; j++) { - vparams[j] = vparams0[j].cloneSymbol(Symbol.NONE); - } - return Type.MethodType(vparams, glb(restps)); - } - -// Erasure -------------------------------------------------------------------------- - - public static Map erasureMap = new MapOnlyTypes() { - public Type apply(Type t) { return t.erasure(); } - }; - - private static final Type[] unboxedType = - new Type[LastUnboxedTag + 1 - FirstUnboxedTag]; - private static final Name[] unboxedName = - new Name[LastUnboxedTag + 1 - FirstUnboxedTag]; - private static final Symbol[] boxedSymbol = - new Symbol[LastUnboxedTag + 1 - FirstUnboxedTag]; - - private static void mkStdClassType(int kind, String unboxedstr, Symbol boxedsym) { - unboxedType[kind - FirstUnboxedTag] = UnboxedType(kind); - unboxedName[kind - FirstUnboxedTag] = Name.fromString(unboxedstr); - boxedSymbol[kind - FirstUnboxedTag] = boxedsym; - } - - static void initializeUnboxedTypes(Definitions definitions) { - mkStdClassType(BYTE, "byte", definitions.BYTE_CLASS); - mkStdClassType(SHORT, "short", definitions.SHORT_CLASS); - mkStdClassType(CHAR, "char", definitions.CHAR_CLASS); - mkStdClassType(INT, "int", definitions.INT_CLASS); - mkStdClassType(LONG, "long", definitions.LONG_CLASS); - mkStdClassType(FLOAT, "float", definitions.FLOAT_CLASS); - mkStdClassType(DOUBLE, "double", definitions.DOUBLE_CLASS); - mkStdClassType(BOOLEAN, "boolean", definitions.BOOLEAN_CLASS); - mkStdClassType(UNIT, "void", definitions.UNIT_CLASS); - } - - /** Return unboxed type of given kind. - */ - public static Type unboxedType(int kind) { - return unboxedType[kind - FirstUnboxedTag]; - } - - /** Return the name of unboxed type of given kind. - */ - public static Name unboxedName(int kind) { - return unboxedName[kind - FirstUnboxedTag]; - } - - /** If type is boxed, return its unboxed equivalent; otherwise return the type - * itself. - */ - public Type unbox() { - switch (this) { - case TypeRef(_, Symbol clasz, Type[] args): - if (args.length == 0) { - for (int i = 0; i < boxedSymbol.length; i++) - if (boxedSymbol[i] == clasz) return unboxedType[i]; - } else if (args.length == 1) { - Definitions definitions = Global.instance.definitions; - if (clasz == definitions.ARRAY_CLASS) { - Type item = args[0]; - Type bound = item.upperBound(); - // todo: check with Philippe if this is what we want. - if (item.symbol().isClass() || - (bound.symbol() != definitions.ANY_CLASS && - bound.symbol() != definitions.ANYVAL_CLASS)) - { - return UnboxedArrayType(args[0].erasure()); - } - } - } - } - return this; - } - //where - private Type upperBound() { - switch (this) { - case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == TYPE) - return pre.memberInfo(sym).upperBound(); - } - return this; - } - - /** Return the erasure of this type. - */ - public Type erasure() { - switch (this) { - case ThisType(_): - case SingleType(_, _): - case ConstantType(_, _): - return singleDeref().erasure(); - case TypeRef(Type pre, Symbol sym, Type[] args): - switch (sym.kind) { - case ALIAS: case TYPE: - return sym.info().asSeenFrom(pre, sym.owner()).erasure(); - - case CLASS: - Definitions definitions = Global.instance.definitions; - if (sym == definitions.UNIT_CLASS) return this; - if (sym == definitions.OBJECT_CLASS || - sym == definitions.ALL_CLASS || - sym == definitions.ALLREF_CLASS) - return Type.typeRef(NoPrefix, definitions.ANY_CLASS, EMPTY_ARRAY); - else { - Type this1 = unbox(); - if (this1 != this) return this1; - else return Type.typeRef(NoPrefix, sym, EMPTY_ARRAY); - } - - default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind); - } - case CompoundType(Type[] parents, _): - if (parents.length > 0) return parents[0].erasure(); - else return this; - case MethodType(Symbol[] params, Type tp): - Symbol[] params1 = erasureMap.map(params); - Type tp1 = tp.fullErasure(); - switch (tp1) { - case MethodType(Symbol[] params2, Type tp2): - Symbol[] newparams = new Symbol[params1.length + params2.length]; - System.arraycopy(params1, 0, newparams, 0, params1.length); - System.arraycopy(params2, 0, newparams, params1.length, params2.length); - return MethodType(newparams, tp2); - default: - if (params1 == params && tp1 == tp) return this; - else return MethodType(params1, tp1); - } - case PolyType(_, Type result): - return result.erasure(); - default: - return erasureMap.map(this); - } - } - - /** Return the full erasure of the type. Full erasure is the same - * as "normal" erasure, except that the "Unit" type is erased to - * the "void" type. - */ - public Type fullErasure() { - Type erasure = erasure(); - if (Global.instance.definitions.UNIT_CLASS == erasure.symbol()) - erasure = erasure.unbox(); - return erasure; - } - -// Object Interface ----------------------------------------------------------------- - - public String toString() { - return new SymbolTablePrinter().printType(this).toString(); - } - - public String toLongString() { - String str = toString(); - if (str.endsWith(".type")) return str + " (with underlying type " + widen() + ")"; - else return str; - } - - public int hashCode() { - switch (this) { - case ErrorType: - return ERRORtpe; - case NoType: - return NOtpe; - case NoPrefix: - return NOpre; - case ThisType(Symbol sym): - return THIStpe - ^ (sym.hashCode() * 41); - case TypeRef(Type pre, Symbol sym, Type[] args): - return TYPEREFtpe - ^ (pre.hashCode() * 41) - ^ (sym.hashCode() * (41*41)) - ^ (hashCode(args) * (41*41*41)); - case SingleType(Type pre, Symbol sym): - return SINGLEtpe - ^ (pre.hashCode() * 41) - ^ (sym.hashCode() * (41*41)); - case ConstantType(Type base, AConstant value): - return CONSTANTtpe - ^ (base.hashCode() * 41) - ^ (value.hashCode() * (41*41)); - case CompoundType(Type[] parts, Scope members): - return symbol().hashCode(); - //return COMPOUNDtpe - // ^ (hashCode(parts) * 41) - // ^ (members.hashCode() * (41 * 41)); - case MethodType(Symbol[] vparams, Type result): - int h = METHODtpe; - for (int i = 0; i < vparams.length; i++) - h = (h << 4) ^ (vparams[i].flags & SOURCEFLAGS); - return h - ^ (hashCode(Symbol.type(vparams)) * 41) - ^ (result.hashCode() * (41 * 41)); - case PolyType(Symbol[] tparams, Type result): - return POLYtpe - ^ (hashCode(tparams) * 41) - ^ (result.hashCode() * (41 * 41)); - case OverloadedType(Symbol[] alts, Type[] alttypes): - return OVERLOADEDtpe - ^ (hashCode(alts) * 41) - ^ (hashCode(alttypes) * (41 * 41)); - case UnboxedType(int kind): - return UNBOXEDtpe - ^ (kind * 41); - case UnboxedArrayType(Type elemtp): - return UNBOXEDARRAYtpe - ^ (elemtp.hashCode() * 41); - default: - throw new ApplicationError("bad type for hashCode: " + this); - } - } - - public static int hashCode(Object[] elems) { - int h = 0; - for (int i = 0; i < elems.length; i++) - h = h * 41 + elems[i].hashCode(); - return h; - } - - // todo: change in relation to needs. - - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof Type) { - Type that = (Type) other; - switch (this) { - case ErrorType: - return that == ErrorType; - case NoType: - return that == NoType; - case NoPrefix: - return that == NoPrefix; - case ThisType(Symbol sym): - switch (that) { - case ThisType(Symbol sym1): - return sym == sym1; - default: return false; - } - case TypeRef(Type pre, Symbol sym, Type[] args): - switch (that) { - case TypeRef(Type pre1, Symbol sym1, Type[] args1): - return pre.equals(pre1) && sym == sym1 && equals(args, args1); - default: return false; - } - case SingleType(Type pre, Symbol sym): - switch (that) { - case SingleType(Type pre1, Symbol sym1): - return pre.equals(pre1) && sym == sym1; - default: return false; - } - case ConstantType(Type base, AConstant value): - switch (that) { - case ConstantType(Type base1, AConstant value1): - return base.equals(base1) && value.equals(value1); - default: return false; - } - case CompoundType(Type[] parts, Scope members): - switch (that) { - case CompoundType(Type[] parts1, Scope members1): - return this.symbol() == that.symbol(); - //return parts.equals(parts1) && members.equals(members1); - default: return false; - } - case MethodType(Symbol[] vparams, Type result): - switch (that) { - case MethodType(Symbol[] vparams1, Type result1): - if (vparams.length != vparams1.length) - return false; - for (int i = 0; i < vparams.length; i++) - if ((vparams[i].flags & SOURCEFLAGS) != - (vparams1[i].flags & SOURCEFLAGS)) - return false; - return - equals(Symbol.type(vparams), Symbol.type(vparams1)) && - result.equals(result1); - default: return false; - } - case PolyType(Symbol[] tparams, Type result): - switch (that) { - case PolyType(Symbol[] tparams1, Type result1): - return equals(tparams, tparams1) && result.equals(result1); - default: return false; - } - case OverloadedType(Symbol[] alts, Type[] alttypes): - switch (that) { - case OverloadedType(Symbol[] alts1, Type[] alttypes1): - return equals(alts, alts1) && equals(alttypes, alttypes1); - default: return false; - } - case UnboxedType(int kind): - switch (that) { - case UnboxedType(int kind1): - return kind == kind1; - default: return false; - } - case UnboxedArrayType(Type elemtp): - switch (that) { - case UnboxedArrayType(Type elemtp1): - return elemtp.equals(elemtp1); - default: return false; - } - default: - } - } - return false; - } - - public static boolean equals(Object[] elems1, Object[] elems2) { - if (elems1.length != elems2.length) return false; - for (int i = 0; i < elems1.length; i++) { - if (!elems1[i].equals(elems2[i])) return false; - } - return true; - } - -// Type.List class ----------------------------------------------------------------- - - /** A class for lists of types. - */ - public static class List { - public Type head; - public List tail; - public List(Type head, List tail) { - this.head = head; this.tail = tail; - } - public int length() { - return (this == EMPTY) ? 0 : 1 + tail.length(); - } - public Type[] toArray() { - Type[] ts = new Type[length()]; - copyToArray(ts, 0, 1); - return ts; - } - public void copyToArray(Type[] ts, int start, int delta) { - if (this != EMPTY) { - ts[start] = head; - tail.copyToArray(ts, start+delta, delta); - } - } - public Type[] toArrayReverse() { - Type[] ts = new Type[length()]; - copyToArray(ts, ts.length - 1, -1); - return ts; - } - - public String toString() { - if (this == EMPTY) return "List()"; - else return head + "::" + tail; - } - - public static List EMPTY = new List(null, null); - - public static List append(List l, Type tp) { - return (l == EMPTY) ? new List(tp, EMPTY) - : new List(l.head, append(l.tail, tp)); - } - } - -// Type.Constraint class ------------------------------------------------------- - - /** A class for keeping sub/supertype constraints and instantiations - * of type variables. - */ - public static class Constraint { - public List lobounds = List.EMPTY; - public List hibounds = List.EMPTY; - public Type inst = NoType; - - public boolean instantiate(Type tp) { - for (List l = lobounds; l != List.EMPTY; l = l.tail) { - if (!l.head.isSubType(tp)) return false; - } - for (List l = hibounds; l != List.EMPTY; l = l.tail) { - if (!tp.isSubType(l.head)) return false; - } - inst = tp; - return true; - } - } - -// Type.Error class -------------------------------------------------------------- - - /** A class for throwing type errors - */ - public static class Error extends java.lang.Error { - public String msg; - public Error(String msg) { - super(msg); - this.msg = msg; - } - } - - public static class Malformed extends Error { - public Malformed(Type pre, String tp) { - super("malformed type: " + pre + "#" + tp); - } - } - - /** A class for throwing type errors - */ - public static class VarianceError extends Error { - public VarianceError(String msg) { - super(msg); - } - } - - public static void explainTypes(Type found, Type required) { - if (Global.instance.explaintypes) { - boolean s = explainSwitch; - explainSwitch = true; - found.isSubType(required); - explainSwitch = s; - } - } -} - -/* A standard pattern match: - - case ErrorType: - case AnyType: - case NoType: - case ThisType(Symbol sym): - case TypeRef(Type pre, Symbol sym, Type[] args): - case SingleType(Type pre, Symbol sym): - case ConstantType(Type base, Object value): - case CompoundType(Type[] parts, Scope members): - case MethodType(Symbol[] vparams, Type result): - case PolyType(Symbol[] tparams, Type result): - case OverloadedType(Symbol[] alts, Type[] alttypes): -*/ - diff --git a/sources/scalac/symtab/TypeTags.java b/sources/scalac/symtab/TypeTags.java deleted file mode 100644 index 0a0d25cfb6..0000000000 --- a/sources/scalac/symtab/TypeTags.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab; - -public interface TypeTags { - - /** unboxed type tags - */ - int BYTE = 10; - int CHAR = 11; - int SHORT = 12; - int INT = 13; - int LONG = 14; - int FLOAT = 15; - int DOUBLE = 16; - int BOOLEAN = 17; - int UNIT = 18; - int STRING = 19; - - int FirstUnboxedTag = BYTE; - int LastUnboxedTag = UNIT; -} diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java deleted file mode 100644 index 7f04a3d147..0000000000 --- a/sources/scalac/symtab/classfile/AttributeParser.java +++ /dev/null @@ -1,216 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scala.tools.util.AbstractFileReader; -import scalac.*; -import scalac.atree.AConstant; -import scalac.symtab.*; -import scalac.util.*; -import java.util.*; - -public class AttributeParser implements ClassfileConstants { - - /** the classfile input buffer - */ - protected AbstractFileReader in; - - /** the constant pool - */ - protected ConstantPool pool; - - protected ClassfileParser parser; - - /** constructor - */ - public AttributeParser(AbstractFileReader in, - ConstantPool pool, - ClassfileParser parser) - { - this.in = in; - this.pool = pool; - this.parser = parser; - } - - /** convert an attribute name into an attribute id - */ - public int nameToId(Name name) { - if (name == SOURCEFILE_N) - return SOURCEFILE_ATTR; - if (name == SYNTHETIC_N) - return SYNTHETIC_ATTR; - if (name == DEPRECATED_N) - return DEPRECATED_ATTR; - if (name == CODE_N) - return CODE_ATTR; - if (name == EXCEPTIONS_N) - return EXCEPTIONS_ATTR; - if (name == CONSTANT_VALUE_N) - return CONSTANT_VALUE_ATTR; - if (name == LINE_NUM_TABLE_N) - return LINE_NUM_TABLE_ATTR; - if (name == LOCAL_VAR_TABLE_N) - return LOCAL_VAR_TABLE_ATTR; - if (name == INNERCLASSES_N) - return INNERCLASSES_ATTR; - if (name == META_N) - return META_ATTR; - if (name == SCALA_N) - return SCALA_ATTR; - if (name == JACO_N) - return JACO_ATTR; - if (name == BRIDGE_N) - return BRIDGE_ATTR; - if (name == SIG_N) - return SIG_ATTR; - return BAD_ATTR; - } - - /** skip all attributes. - */ - public void skipAttributes() { - char nattr = in.nextChar(); - for (int i = 0; i < nattr; i++) { - in.skip(2); - in.skip(in.nextInt()); - } - } - - /** read all attributes associated with symbol 'sym' which are - * contained in 'attrs'. - */ - public Symbol readAttributes(Symbol def, Type type, int attrs) { - char nattr = in.nextChar(); - for (int i = 0; i < nattr; i++) { - Name attrName = pool.getName(in.nextChar()); - int attr = nameToId(attrName); - int attrLen = in.nextInt(); - if ((attrs & attr) == 0) { - //System.out.println("# skipping " + attrName + " of " + def); - in.skip(attrLen); - } else { - //System.out.println("# reading " + attrName + " of " + def); - readAttribute(def, type, attr, attrLen); - } - } - return def; - } - - /** read a single attribute 'attr' for symbol 'sym' with type 'type'. - */ - public void readAttribute(Symbol sym, Type type, int attr, int attrLen) { - switch (attr) { - // class attributes - case SCALA_ATTR: - try { - UnPickle.parse(parser.global, in.nextBytes(attrLen), sym); - return; - } catch (UnPickle.BadSignature exception) { - throw new RuntimeException(exception); - } - case INNERCLASSES_ATTR: - int n = in.nextChar(); - //System.out.println(sym + " has " + n + " innerclass entries"); - for (int i = 0; i < n; i++) { - int inner = in.nextChar(); - if (inner == 0) { in.skip(6); continue; } - int outer = in.nextChar(); - if (outer == 0) { in.skip(4); continue; } - int name = in.nextChar(); - if (name == 0) { in.skip(2); continue; } - int flags = in.nextChar(); - if ((flags & JAVA_ACC_STATIC) == 0) continue; - if ((flags & (JAVA_ACC_PUBLIC | JAVA_ACC_PROTECTED)) == 0) - continue; - if (pool.getClass(outer) != sym) continue; - Symbol alias = sym.linkedModule().moduleClass() - .newTypeAlias(Position.NOPOS, 0, - pool.getName(name).toTypeName(), - parser.make.classType(pool.getClass(inner))); - parser.statics.enterNoHide(alias); - } - //in.skip(attrLen); - return; - // method attributes - case CODE_ATTR: - in.skip(attrLen); - return; - case EXCEPTIONS_ATTR: - //int nexceptions = in.nextChar(); - //Type[] thrown = new Type[nexceptions]; - //for (int j = 0; j < nexceptions; j++) - // thrown[j] = make.classType(reader.readClassName(in.nextChar())); - //((MethodType)def.type).thrown = thrown; - in.skip(attrLen); - return; - case LINE_NUM_TABLE_ATTR: - in.skip(attrLen); - return; - case LOCAL_VAR_TABLE_ATTR: - in.skip(attrLen); - return; - // general attributes - case SYNTHETIC_ATTR: - sym.flags |= Modifiers.SYNTHETIC; - return; - case BRIDGE_ATTR: - sym.flags |= Modifiers.BRIDGE; - return; - case DEPRECATED_ATTR: - sym.flags |= Modifiers.DEPRECATED; - return; - case CONSTANT_VALUE_ATTR: - AConstant constant = pool.getConstantValue(in.nextChar()); - switch (constant) { - case INT(int value): - Definitions definitions = parser.global.definitions; - Symbol base = sym.getType().symbol(); - if (base == definitions.INT_CLASS) break; - if (base == definitions.CHAR_CLASS) - constant = AConstant.CHAR((char)value); - else if (base == definitions.SHORT_CLASS) - constant = AConstant.SHORT((short)value); - else if (base == definitions.BYTE_CLASS) - constant = AConstant.BYTE((byte)value); - else - constant = AConstant.BOOLEAN(value != 0); - } - sym.setInfo(parser.make.constantType(constant)); - return; - case META_ATTR: - //System.out.println("parsing meta data for " + sym); - String meta = pool.getString(in.nextChar()).trim(); - MetaParser mp = new MetaParser - (meta, tvars, sym, type, parser.c, parser.ctype, parser.make); - sym.setInfo(mp.parse()); - return; - case JACO_ATTR: - // this attribute is present in all PiCo generated classfiles - int mods = in.nextChar(); - mods |= (in.nextChar() << 16); - boolean algebraicClass = (mods & 0x00100000) != 0; - boolean caseClass = (mods & 0x00200000) != 0; - if (caseClass) - sym.flags |= Modifiers.CASE | Modifiers.JAVA; - in.skip(attrLen - 4); - return; - case SOURCEFILE_ATTR: - String name = pool.getString(in.nextChar()); - parser.c.getOrigin().setSourceFileAttribute(name); - parser.m.moduleClass().getOrigin().setSourceFileAttribute(name); - return; - default: - in.skip(attrLen); - return; - } - } - - Scope tvars = new Scope(); -} diff --git a/sources/scalac/symtab/classfile/CLRClassParser.java b/sources/scalac/symtab/classfile/CLRClassParser.java deleted file mode 100644 index 498237edbe..0000000000 --- a/sources/scalac/symtab/classfile/CLRClassParser.java +++ /dev/null @@ -1,538 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2003, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scalac.Global; -import scalac.atree.AConstant; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.symtab.SymbolOrigin; -import scalac.symtab.Scope; -import scalac.symtab.Modifiers; -import scalac.symtab.Type.*; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -import scala.tools.util.Position; -import ch.epfl.lamp.compiler.msil.*; - -import java.util.Set; -import java.util.HashSet; -import java.util.Arrays; -import java.util.Iterator; - -public class CLRClassParser extends SymbolLoader { - - //########################################################################## - - private static Name[] ENUM_CMP_NAMES = new Name[] - { Names.EQ, Names.NE, Names.LT, Names.LE, Names.GT, Names.GE }; - - private static Name[] ENUM_BIT_LOG_NAMES = new Name[] - { Names.OR, Names.AND, Names.XOR }; - - private static JavaTypeFactory make; - - private static final CLRTypes clrTypes = CLRTypes.instance(); - - private final Type type; - - public CLRClassParser(Global global, Type type) { - super(global); - this.type = type; - } - - private Symbol clazz; - private Scope members; - private Symbol staticsClass; - private Scope statics; - scalac.symtab.Type clazzType; - - private final Scope tvars = new Scope(); - - protected String doComplete(Symbol root) { - clazz = root; - clazz.owner().initialize(); //??? - - if (make == null) - make = new JavaTypeCreator(global.definitions); - - clazz.flags = translateAttributes(type); - Type[] ifaces = type.getInterfaces(); - scalac.symtab.Type[] baseTypes = new scalac.symtab.Type[ifaces.length+1]; - baseTypes[0] = type.BaseType() != null ? getCLRType(type.BaseType()) - : (type.IsInterface() ? make.objectType() : make.anyType()); - for (int i = 0; i < ifaces.length; i++) - baseTypes[i + 1] = getCLRType(ifaces[i]); - members = new Scope(); - statics = new Scope(); - scalac.symtab.Type clazzInfo = - scalac.symtab.Type.compoundType(baseTypes, members, clazz); - clazz.setInfo(clazzInfo); - Symbol staticsModule = clazz.linkedModule(); - staticsClass = staticsModule.moduleClass(); - assert staticsClass.isModuleClass(): Debug.show(staticsClass); - scalac.symtab.Type staticsInfo = scalac.symtab.Type.compoundType - (scalac.symtab.Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo); - staticsModule.setInfo(make.classType(staticsClass)); - clazzType = make.classType(clazz); - - // import nested types - Type[] nestedTypes = type.getNestedTypes(); - for (int i = 0; i < nestedTypes.length; i++) { - Type ntype = nestedTypes[i]; - if (ntype.IsNestedPrivate() || ntype.IsNestedAssembly() - || ntype.IsNestedFamANDAssem()) - continue; - Name classname = Name.fromString(ntype.Name).toTypeName(); - CLRClassParser loader = new CLRClassParser(global, ntype); - SymbolOrigin origin = SymbolOrigin.CLRAssembly(ntype.Assembly()); - Symbol nclazz = staticsClass.newLoadedClass - (JAVA, classname, loader, statics, origin); - clrTypes.map(nclazz, ntype); - } - - FieldInfo[] fields = type.getFields(); - for (int i = 0; i < fields.length; i++) { - if (fields[i].IsPrivate() || fields[i].IsAssembly() - || fields[i].IsFamilyAndAssembly()) - continue; - int mods = translateAttributes(fields[i]); - Name name = Name.fromString(fields[i].Name); - scalac.symtab.Type fieldType = getCLRType(fields[i].FieldType); - if (fields[i].IsLiteral() && !fields[i].FieldType.IsEnum()) - fieldType = make.constantType( - getConstant(fieldType.symbol(), fields[i].getValue())); - Symbol owner = fields[i].IsStatic() ? staticsClass : clazz; - Symbol field = owner.newField(Position.NOPOS, mods, name); - parseMeta(field, fields[i], fieldType); - (fields[i].IsStatic() ? statics : members).enterOrOverload(field); - clrTypes.map(field, fields[i]); - } - - Set methodsSet = new HashSet(Arrays.asList(type.getMethods())); - - PropertyInfo[] props = type.getProperties(); - for (int i = 0; i < props.length; i++) { - scalac.symtab.Type proptype = getCLSType(props[i].PropertyType); - if (proptype == null) - continue; - - MethodInfo getter = props[i].GetGetMethod(true); - MethodInfo setter = props[i].GetSetMethod(true); - if (getter == null || getter.IsPrivate() || - getter.IsAssembly() || getter.IsFamilyAndAssembly()) - continue; - assert props[i].PropertyType == getter.ReturnType; - Name n; - scalac.symtab.Type mtype; - - ParameterInfo[] gparams = getter.GetParameters(); - if (gparams.length == 0) { - n = Name.fromString(props[i].Name); - mtype = - scalac.symtab.Type.PolyType(Symbol.EMPTY_ARRAY, proptype); - } else { - n = Names.apply; - mtype = methodType(getter, getter.ReturnType); - } - int mods = translateAttributes(getter); - createMethod(n, mods, mtype, getter, getter.IsStatic()); - assert methodsSet.contains(getter) : "" + getter; - methodsSet.remove(getter); - - if (setter == null || setter.IsPrivate() || - setter.IsAssembly() || setter.IsFamilyAndAssembly()) - continue; - ParameterInfo[] sparams = setter.GetParameters(); - assert getter.IsStatic() == setter.IsStatic(); - assert setter.ReturnType == clrTypes.VOID; - assert sparams.length == gparams.length + 1 : "" + getter + "; " + setter; - - if (gparams.length == 0) - n = Name.fromString(n.toString() + Names._EQ); - else n = Names.update; - - mods = translateAttributes(setter); - mtype = methodType(setter, global.definitions.UNIT_TYPE()); - createMethod(n, mods, mtype, setter, setter.IsStatic()); - assert methodsSet.contains(setter) : "" + setter; - methodsSet.remove(setter); - } - - for (Iterator i = methodsSet.iterator(); i.hasNext(); ) { - MethodInfo method = (MethodInfo)i.next(); - if ((clrTypes.getSymbol(method) != null) || method.IsPrivate() - || method.IsAssembly() || method.IsFamilyAndAssembly()) - continue; - createMethod(method); - } - - // Create symbols related to delegate types - if(clrTypes.isDelegateType(type)) { - createDelegateView(); - createDelegateChainers(); - } - - // for enumerations introduce comparison and bitwise logical operations; - // the backend should recognize and replace them with comparison or - // bitwise logical operations on the primitive underlying type - if (type.IsEnum()) { - scalac.symtab.Type[] argTypes = new scalac.symtab.Type[] {clazzType}; - int mods = Modifiers.JAVA | Modifiers.FINAL; - for (int i = 0; i < ENUM_CMP_NAMES.length; i++) { - scalac.symtab.Type enumCmpType = - make.methodType(argTypes, - global.definitions.boolean_TYPE(), - scalac.symtab.Type.EMPTY_ARRAY); - createMethod(ENUM_CMP_NAMES[i], mods, enumCmpType, null, false); - } - for (int i = 0; i < ENUM_BIT_LOG_NAMES.length; i++) { - scalac.symtab.Type enumBitLogType = make.methodType - (argTypes, clazzType, scalac.symtab.Type.EMPTY_ARRAY); - createMethod - (ENUM_BIT_LOG_NAMES[i], mods, enumBitLogType, null, false); - } - } - - ConstructorInfo[] constrs = type.getConstructors(); - for (int i = 0; i < constrs.length; i++) { - if (constrs[i].IsStatic() || constrs[i].IsPrivate() - || constrs[i].IsAssembly() || constrs[i].IsFamilyAndAssembly()) - continue; - createConstructor(constrs[i]); - } - - Symbol constr = clazz.primaryConstructor(); - if (!constr.isInitialized()) { - constr.setInfo(scalac.symtab.Type.MethodType - (Symbol.EMPTY_ARRAY, clazzType)); - if ((clazz.flags & Modifiers.INTERFACE) == 0) - constr.flags |= Modifiers.PRIVATE; - } - - parseMeta(clazz, type, clazzInfo); - - return type + " from assembly " + type.Assembly(); - } - - private scalac.symtab.Type parseMeta(Symbol sym, - ICustomAttributeProvider member, - scalac.symtab.Type defaultType) - { - if (member !=null && member.IsDefined(clrTypes.PICO_META_ATTR, false)) { - Object[] attrs = - member.GetCustomAttributes(clrTypes.PICO_META_ATTR, false); - assert attrs.length == 1 : "attrs.length = " + attrs.length; - String meta = - (String)((Attribute)attrs[0]).getConstructorArguments()[0]; - defaultType = new MetaParser - (meta, tvars, sym, defaultType, clazz, clazzType, make).parse(); - } - sym.setInfo(defaultType); - return defaultType; - } - - private void createConstructor(ConstructorInfo constr) { - scalac.symtab.Type mtype = methodType(constr, clazzType); - if (mtype == null) - return; - Symbol constrSym = clazz.primaryConstructor(); - int mods = translateAttributes(constr); - if (constrSym.isInitialized()) { - constrSym = clazz.newConstructor(Position.NOPOS, mods); - clazz.addConstructor(constrSym); - } else { - constrSym.flags = mods; - } - setParamOwners(mtype, constrSym); - parseMeta(constrSym, constr, mtype); - clrTypes.map(constrSym, constr); - } - - private void createMethod(MethodInfo method) { - scalac.symtab.Type mtype = - methodType(method, method.ReturnType); - if (mtype == null) - return; - int mods = translateAttributes(method); - createMethod(getName(method), mods, mtype, method, method.IsStatic()); - } - - // Create static view methods within the delegate and the function type - // with the following signatures: - // def MyDelegate.view(MyDelegate): FunctionX[InvokeArgs..., InvokeRet]; - // def FunctionX.view(FunctionX[InvokeArgs..., InvokeRet]): MyDelegate; - private void createDelegateView() { - // Extract the parameter and return types of the Invoke method - MethodInfo invoke = (MethodInfo)type.GetMember("Invoke")[0]; - scalac.symtab.Type invokeRetType = getCLRType(invoke.ReturnType); - scalac.symtab.Type invokeParamTypes[] = - new scalac.symtab.Type[invoke.GetParameters().length]; - for(int j = 0; j < invoke.GetParameters().length; j++) - invokeParamTypes[j] = - getCLRType(invoke.GetParameters()[j].ParameterType); - scalac.symtab.Type funType = - global.definitions.FUNCTION_TYPE(invokeParamTypes, invokeRetType); - - // FORWARD MAPPING (Delegate => Function) - scalac.symtab.Type viewParamTypes[] = { getCLRType(type) }; - scalac.symtab.Type viewRetType = funType; - scalac.symtab.Type viewMethodType = make.methodType( - viewParamTypes, - viewRetType, - scalac.symtab.Type.EMPTY_ARRAY); - - createMethod(Names.view, Modifiers.JAVA, viewMethodType, null, true); - - // REVERSE MAPPING (Function => Delegate) - viewParamTypes = new scalac.symtab.Type[]{ funType }; - viewRetType = getCLRType(type); - viewMethodType = make.methodType( - viewParamTypes, - viewRetType, - scalac.symtab.Type.EMPTY_ARRAY); - - createMethod(Names.view, Modifiers.JAVA, viewMethodType, null, true); - } - - private void createDelegateChainers() { - int mods = Modifiers.JAVA | Modifiers.FINAL; - Type[] args = new Type[]{type}; - - createMethod(Names.PLUSEQ, mods, args, clrTypes.VOID, - clrTypes.DELEGATE_COMBINE, false); - createMethod(Names.MINUSEQ, mods, args, clrTypes.VOID, - clrTypes.DELEGATE_REMOVE, false); - createMethod - (Names.PLUS, mods, args, type, clrTypes.DELEGATE_COMBINE, false); - createMethod - (Names.MINUS, mods, args, type, clrTypes.DELEGATE_REMOVE, false); - } - - private Symbol createMethod(Name name, int mods, Type[] args, - Type retType, MethodInfo method, boolean statik) - { - return createMethod(name, mods, args, getCLSType(retType), method, statik); - } - private Symbol createMethod(Name name, int mods, Type[] args, - scalac.symtab.Type retType, - MethodInfo method, - boolean statik) - { - scalac.symtab.Type mtype = methodType(args, retType); - assert mtype != null : name; - return createMethod(name, mods, mtype, method, statik); - } - private Symbol createMethod(Name name, int mods, scalac.symtab.Type mtype, - MethodInfo method, boolean statik) - { - Symbol methodSym = (statik ? staticsClass: clazz) - .newMethod(Position.NOPOS, mods, name); - setParamOwners(mtype, methodSym); - parseMeta(methodSym, method, mtype); // sets the type to mtype if no meta - (statik ? statics : members).enterOrOverload(methodSym); - if (method != null) - clrTypes.map(methodSym, method); - return methodSym; - } - - private Name getName(MethodInfo method) { - final String name = method.Name; - if (method.IsStatic()) return Name.fromString(name); - final ParameterInfo[] params = method.GetParameters(); - if (name.equals("GetHashCode") && params.length == 0) - return Names.hashCode; - if (name.equals("ToString") && params.length == 0) - return Names.toString; - if (name.equals("Finalize") && params.length == 0) - return Names.finalize; - if (name.equals("Equals") && params.length == 1 - && params[0].ParameterType == clrTypes.OBJECT) - return Names.equals; - // TODO: check if the type implements ICloneable? - if (name.equals("Clone") && params.length == 0) - return Names.clone; - // Pretend that delegates have a 'apply' method instead of the 'Invoke' - // method. This is harmless because the latter one can't be called - // directly anyway. - if (name.equals("Invoke") - && clrTypes.isDelegateType(method.DeclaringType)) - return Names.apply; - return Name.fromString(name); - } - - //########################################################################## - - private Type[] getParamTypes(MethodBase method) { - ParameterInfo[] params = method.GetParameters(); - Type[] paramTypes = new Type[params.length]; - for (int i = 0; i < params.length; i++) - paramTypes[i] = params[i].ParameterType; - return paramTypes; - } - - private scalac.symtab.Type methodType(MethodBase method, Type rettype) { - scalac.symtab.Type rtype = getCLSType(rettype); - return rtype == null ? null : methodType(method, rtype); - } - - /** Return a method type for the given method. */ - private scalac.symtab.Type methodType(MethodBase method, - scalac.symtab.Type rettype) - { - return methodType(getParamTypes(method), rettype); - } - - /** Return a method type for the provided argument types and return type. */ - private scalac.symtab.Type methodType(Type[] argtypes, - scalac.symtab.Type rettype) - { - scalac.symtab.Type[] ptypes = new scalac.symtab.Type[argtypes.length]; - for (int i = 0; i < argtypes.length; i++) { - ptypes[i] = getCLSType(argtypes[i]); - if (ptypes[i] == null) - return null; - } - return make.methodType(ptypes, rettype, scalac.symtab.Type.EMPTY_ARRAY); - } - - private void setParamOwners(scalac.symtab.Type type, Symbol owner) { - switch (type) { - case PolyType(Symbol[] params, scalac.symtab.Type restype): - for (int i = 0; i < params.length; i++) params[i].setOwner(owner); - setParamOwners(restype, owner); - return; - case MethodType(Symbol[] params, scalac.symtab.Type restype): - for (int i = 0; i < params.length; i++) params[i].setOwner(owner); - setParamOwners(restype, owner); - return; - } - } - - //########################################################################## - - private scalac.symtab.Type getClassType(Type type) { - assert type != null; - scalac.symtab.Type res = - make.classType(type.FullName.replace('+', '.')); - if (res.isError()) - global.error("unknown class reference " + type.FullName); - return res; - } - - private scalac.symtab.Type getCLSType(Type type) { - if (/*type == clrTypes.BYTE ||*/ type == clrTypes.USHORT - || type == clrTypes.UINT || type == clrTypes.ULONG - || type.IsNotPublic() || type.IsNestedPrivate() - || type.IsNestedAssembly() || type.IsNestedFamANDAssem() - || type.IsPointer() - || (type.IsArray() && getCLSType(type.GetElementType()) == null)) - return null; - //Symbol s = clrTypes.getSymbol(type); - //scalac.symtab.Type t = s != null ? make.classType(s) : getCLRType(type); - return getCLRType(type); - } - - private scalac.symtab.Type getCLRType(Type type) { - if (type == clrTypes.OBJECT) - return make.objectType(); - if (type == clrTypes.STRING) - return make.stringType(); - if (type == clrTypes.VOID) - return make.voidType(); - if (type == clrTypes.BOOLEAN) - return make.booleanType(); - if (type == clrTypes.CHAR) - return make.charType(); - if (type == clrTypes.BYTE || type == clrTypes.UBYTE) - return make.byteType(); - if (type == clrTypes.SHORT || type == clrTypes.USHORT) - return make.shortType(); - if (type == clrTypes.INT || type == clrTypes.UINT) - return make.intType(); - if (type == clrTypes.LONG || type == clrTypes.ULONG) - return make.longType(); - if (type == clrTypes.FLOAT) - return make.floatType(); - if (type == clrTypes.DOUBLE) - return make.doubleType(); - if (type.IsArray()) - return make.arrayType(getCLRType(type.GetElementType())); - Symbol s = clrTypes.getSymbol(type); - return s != null ? make.classType(s) : getClassType(type); - } - - public AConstant getConstant(Symbol base, Object value) { - if (base == global.definitions.BOOLEAN_CLASS) - return AConstant.BOOLEAN(((Number)value).intValue() != 0); - if (base == global.definitions.BYTE_CLASS) - return AConstant.BYTE(((Number)value).byteValue()); - if (base == global.definitions.SHORT_CLASS) - return AConstant.SHORT(((Number)value).shortValue()); - if (base == global.definitions.CHAR_CLASS) - return AConstant.CHAR(((Character)value).charValue()); - if (base == global.definitions.INT_CLASS) - return AConstant.INT(((Number)value).intValue()); - if (base == global.definitions.LONG_CLASS) - return AConstant.LONG(((Number)value).longValue()); - if (base == global.definitions.FLOAT_CLASS) - return AConstant.FLOAT(((Number)value).floatValue()); - if (base == global.definitions.DOUBLE_CLASS) - return AConstant.DOUBLE(((Number)value).doubleValue()); - if (base == global.definitions.STRING_CLASS) - return AConstant.STRING((String)value); - throw Debug.abort("illegal value", Debug.show(value, base)); - } - - private static int translateAttributes(Type type) { - int mods = Modifiers.JAVA; - if (type.IsNotPublic() || type.IsNestedPrivate() - || type.IsNestedAssembly() || type.IsNestedFamANDAssem()) - mods |= Modifiers.PRIVATE; - else if (type.IsNestedFamily() || type.IsNestedFamORAssem()) - mods |= Modifiers.PROTECTED; - if (type.IsAbstract()) - mods |= Modifiers.ABSTRACT; - if (type.IsSealed()) - mods |= Modifiers.FINAL; - if (type.IsInterface()) - mods |= Modifiers.INTERFACE | Modifiers.TRAIT | Modifiers.ABSTRACT; - - return mods; - } - - private static int translateAttributes(FieldInfo field) { - int mods = Modifiers.JAVA; - if (field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly()) - mods |= Modifiers.PRIVATE; - else if (field.IsFamily() || field.IsFamilyOrAssembly()) - mods |= Modifiers.PROTECTED; - if (field.IsInitOnly()) - mods |= Modifiers.FINAL; - else - mods |= Modifiers.MUTABLE; - - return mods; - } - - private static int translateAttributes(MethodBase method) { - int mods = Modifiers.JAVA; - if (method.IsPrivate() || method.IsAssembly() || method.IsFamilyAndAssembly()) - mods |= Modifiers.PRIVATE; - else if (method.IsFamily() || method.IsFamilyOrAssembly()) - mods |= Modifiers.PROTECTED; - if (method.IsAbstract()) - mods |= Modifiers.DEFERRED; - - return mods; - } -} diff --git a/sources/scalac/symtab/classfile/CLRPackageParser.java b/sources/scalac/symtab/classfile/CLRPackageParser.java deleted file mode 100644 index c7e5296e17..0000000000 --- a/sources/scalac/symtab/classfile/CLRPackageParser.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.Iterator; -import java.util.HashMap; -import java.util.HashSet; - -import scala.tools.util.AbstractFile; -import scala.tools.util.ByteArrayFile; -import scala.tools.util.VirtualDirectory; - -import scalac.Global; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.symtab.SymbolOrigin; - -import ch.epfl.lamp.compiler.msil.Type; -import ch.epfl.lamp.compiler.msil.Attribute; - -/** - * Package/namespace member loader for the CLR. - */ -public final class CLRPackageParser extends PackageParser { - - //######################################################################## - // Private Constants - - /** An empty directory */ - private static final AbstractFile EMPTY = new VirtualDirectory("<empty>"); - - //######################################################################## - // Protected Fields - - /** A table to collect types */ - protected final HashMap types = new HashMap(); - - //######################################################################## - // Public Constructors - - public CLRPackageParser(Global global, AbstractFile directory) { - super(global, directory); - } - - //######################################################################## - // Protected Methods - - protected PackageParser newPackageParser(AbstractFile directory) { - return new CLRPackageParser(global, directory); - } - - protected void collectAllMembers(Symbol clasz) { - super.collectAllMembers(clasz); - HashSet namespaces = new HashSet(); - CLRTypes.instance().collectMembers(clasz, types, namespaces); - for (Iterator i = namespaces.iterator(); i.hasNext(); ) { - String namespace = (String)i.next(); - if (!packages.containsKey(namespace)) - packages.put(namespace, EMPTY); - } - } - - protected void removeHiddenMembers(Symbol clasz) { - // Ignore all ".symbl" and ".class" files. - symbols.clear(); - classes.clear(); - super.removeHiddenMembers(clasz); - // Classes/Objects in the root package are hidden. - if (clasz.isRoot()) { types.clear(); } - // Source versions hide compiled versions except if separate - // compilation is enabled and the compiled version is more - // recent. In that case the compiled version hides the source - // version. - boolean separate = global.separate; - for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) { - if (types.isEmpty()) break; - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile sfile = (AbstractFile)entry.getValue(); - Type type = (Type)types.get(name); - boolean hidden = false; - if (type != null) - if (separate /* !!! && type.Assembly().getFile().lastModified() > sfile.lastModified() */) - hidden = true; - else - types.remove(name); - if (hidden) i.remove(); - } - // Packages are hidden by classes/objects with the same name. - packages.keySet().removeAll(types.keySet()); - } - - protected Scope createMemberSymbols(Symbol clasz) { - CLRTypes clrTypes = CLRTypes.instance(); - String namespace = clrTypes.getNameSpaceOf(clasz); - Scope members = super.createMemberSymbols(clasz); - - // import the CLR types contained in the package (namespace) - for (Iterator i = types.values().iterator(); i.hasNext(); ) { - Type type = (Type)i.next(); - - assert namespace.equals(type.Namespace) - : Debug.show(clasz, namespace) + " << " + type.FullName; - AbstractFile symfile = null; - if (type.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) { - Object[] attrs = type.GetCustomAttributes - (clrTypes.SCALA_SYMTAB_ATTR, false); - assert attrs.length == 1 : attrs.length; - Attribute a = (Attribute)attrs[0]; - assert a.GetType() == clrTypes.SCALA_SYMTAB_ATTR : a.toString(); - if (a.getConstructor() == clrTypes.SYMTAB_DEFAULT_CONSTR) - continue; - byte[] symtab = (byte[])a.getConstructorArguments()[0]; - symfile = new ByteArrayFile - (type.FullName, "[" + type.Assembly().GetName() + "]", - symtab); - } - SymbolLoader loader = symfile != null - ? new SymblParser(Global.instance, symfile) - : new CLRClassParser(Global.instance, type); - - Name classname = Name.fromString(type.Name).toTypeName(); - SymbolOrigin origin = SymbolOrigin.CLRAssembly(type.Assembly()); - Symbol clazz = clasz.newLoadedClass - (JAVA, classname, loader, members, origin); - clrTypes.map(clazz, type); - //Type moduleType = getType(type.FullName + "$"); - //map(clazz, moduleType != null ? moduleType : type); - } - - return members; - } - - protected String doComplete(Symbol root) { - String base = super.doComplete(root); - base = directory == EMPTY ? "" : base + " and "; - String namespace = CLRTypes.instance().getNameSpaceOf(root); - return base + "namespace '" + namespace + "'"; - } - - //######################################################################## -} // CLRPackageParser diff --git a/sources/scalac/symtab/classfile/CLRTypes.java b/sources/scalac/symtab/classfile/CLRTypes.java deleted file mode 100644 index f7a5af508c..0000000000 --- a/sources/scalac/symtab/classfile/CLRTypes.java +++ /dev/null @@ -1,330 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.List; -import java.util.LinkedList; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.LinkedHashSet; -import java.util.Arrays; -import java.util.Iterator; -import java.util.Comparator; - -import java.io.File; - -import scalac.Global; -import scalac.CompilerCommand; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; - -import ch.epfl.lamp.compiler.msil.*; - -/** - * Collects all types from all reference assemblies. - */ -public final class CLRTypes { - - //########################################################################## - - private static CLRTypes instance; - - /** Return the unique instance of the CLRTypes class */ - public static CLRTypes instance() { - assert instance != null; - return instance; - } - - /** Initialize the CLRTypes */ - public static void init(CompilerCommand args) { - instance = new CLRTypes(args); - } - - //########################################################################## - - public final Type BYTE; - public final Type UBYTE; - public final Type CHAR; - public final Type SHORT; - public final Type USHORT; - public final Type INT; - public final Type UINT; - public final Type LONG; - public final Type ULONG; - public final Type FLOAT; - public final Type DOUBLE; - public final Type BOOLEAN; - public final Type VOID; - public final Type ENUM; - public final Type DELEGATE; - - public final Type OBJECT; - public final Type STRING; - public final Type STRING_ARRAY; - - public final MethodInfo MEMBERWISE_CLONE; - - public final Type PICO_META_ATTR; - - public final Type SCALA_SYMTAB_ATTR; - public final ConstructorInfo SYMTAB_CONSTR; - public final ConstructorInfo SYMTAB_DEFAULT_CONSTR; - - public final MethodInfo DELEGATE_COMBINE; - public final MethodInfo DELEGATE_REMOVE; - - private final SymbolNameWriter snw = new SymbolNameWriter(); - - private Type[] types; - - private final CompilerCommand args; - - private CLRTypes(CompilerCommand args) { - this.args = args; - scala.tools.util.ClassPath.addFilesInPath( - assemrefs, args.assemrefs.value); - Assembly mscorlib = findAssembly("mscorlib.dll", true); - Type.initMSCORLIB(mscorlib); - findAllAssemblies(); - - if (getType("scala.Int") == null) { - findAssembly("scala.dll", true); - } - - BYTE = getType("System.SByte"); - UBYTE = getType("System.Byte"); - CHAR = getType("System.Char"); - SHORT = getType("System.Int16"); - USHORT = getType("System.UInt16"); - INT = getType("System.Int32"); - UINT = getType("System.UInt32"); - LONG = getType("System.Int64"); - ULONG = getType("System.UInt64"); - FLOAT = getType("System.Single"); - DOUBLE = getType("System.Double"); - BOOLEAN = getType("System.Boolean"); - VOID = getType("System.Void"); - ENUM = getType("System.Enum"); - DELEGATE = getType("System.MulticastDelegate"); - - OBJECT = getType("System.Object"); - STRING = getType("System.String"); - STRING_ARRAY = getType("System.String[]"); - - MEMBERWISE_CLONE = OBJECT.GetMethod("MemberwiseClone", Type.EmptyTypes); - - PICO_META_ATTR = Type.GetType("scala.runtime.MetaAttribute"); - SCALA_SYMTAB_ATTR = Type.GetType("scala.runtime.SymtabAttribute"); - final Type[] bytearray = new Type[]{ Type.GetType("System.Byte[]") }; - SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray); - SYMTAB_DEFAULT_CONSTR = - SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes); - - Type delegate = Type.GetType("System.Delegate"); - Type[] dargs = new Type[]{delegate, delegate}; - DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs); - DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs); - - assert PICO_META_ATTR != null; - assert SCALA_SYMTAB_ATTR != null; - assert DELEGATE_COMBINE != null; - assert DELEGATE_REMOVE != null; - - Type[] types = Type.EmptyTypes; - Iterator as = assemblies.iterator(); - while (as.hasNext()) { - Type[] atypes = ((Assembly)as.next()).GetTypes(); - int j = 0; - for (int i = 0; i < atypes.length; i++) - // skip nested types - if (atypes[i].DeclaringType == null) - atypes[j++] = atypes[i]; - Type[] btypes = new Type[types.length + j]; - System.arraycopy(types, 0, btypes, 0, types.length); - System.arraycopy(atypes, 0, btypes, types.length, j); - types = btypes; - } - - Comparator typeNameComparator = - new Comparator() { - public int compare(Object o1, Object o2) { - Type t1 = (Type)o1; - Type t2 = (Type)o2; - return t1.FullName.compareTo(t2.FullName); - } - }; - - Arrays.sort(types, typeNameComparator); - this.types = types; - } - - //########################################################################## - // type mapping and lookup - - private final Map syms2members = new HashMap(); - private final Map members2syms = new HashMap(); - - public void map(Symbol sym, MemberInfo m) { - syms2members.put(sym, m); - members2syms.put(m, sym); - } - - public MemberInfo getMember(Symbol sym) { - return (MemberInfo)syms2members.get(sym); - } - - public Symbol getSymbol(MemberInfo m) { - return (Symbol)members2syms.get(m); - } - - public Type getType(String name) { - Type t = Type.GetType(name); - //assert t != null : name; - return t; - } - - public Type mkArrayType(Type elemType) { - return getType(elemType.FullName + "[]"); - } - - // Returns true if the given type is a delegate type. - public boolean isDelegateType(Type t) { - return t.BaseType() == DELEGATE; - } - - //########################################################################## - // assembly loading methods - - // a list of all loaded assemblies - private final List assemblies = new LinkedList(); - - // a set of all directories and assembly files - private final Set/*<File>*/ assemrefs = new LinkedHashSet(); - - /** Load the assembly with the given name - */ - private Assembly findAssembly(String name, boolean required) { - // see if the assembly is referenced directly - for (Iterator assems = assemrefs.iterator(); assems.hasNext();) { - File file = (File)assems.next(); - if (!file.getName().equals(name)) - continue; - Assembly assem = Assembly.LoadFrom(file.getPath()); - if (assem != null) { - assems.remove(); - assemblies.add(assem); - return assem; - } - } - // look in directories specified with the '-r' option - for (Iterator assems = assemrefs.iterator(); assems.hasNext();) { - File d = (File)assems.next(); - if (!d.isDirectory()) - continue; - File file = new File(d, name); - if (file.exists()) { - Assembly assem = Assembly.LoadFrom(file.getPath()); - if (assem != null) { - assemblies.add(assem); - return assem; - } - } - } - // try in the current directory - File file = new File(".", name); - if (file.exists()) { - Assembly assem = Assembly.LoadFrom(file.getPath()); - if (assem != null) { - assemblies.add(assem); - return assem; - } - } - - if (required) - abort(name); - - return null; - } - - /** Load the rest of the assemblies specified with the '-r' option - */ - private void findAllAssemblies() { - for (Iterator assems = assemrefs.iterator(); assems.hasNext();) { - File f = (File)assems.next(); - if (f.isFile()) { - Assembly assem = Assembly.LoadFrom(f.getPath()); - if (assem != null) { - assemblies.add(assem); - assems.remove(); - } - } - } - } - - private void abort(String name) { - //the Global instance is not yet constructed; use the Reporter from args - args.reporter().error(null, "cannot find assembly " + name + - "; use the -r option to specify its location"); - throw Debug.abort(); - } - - //########################################################################## - // collect the members contained in a given namespace - - /** Find the position of the first type whose name starts with - * the given prefix; return the length of the types array if no match - * is found so the result can be used to terminate loop conditions - */ - private int findFirst(String prefix) { - int m = 0, n = types.length - 1; - while (m < n) { - int l = (m + n) / 2; - int res = types[l].FullName.compareTo(prefix); - if (res < 0) m = l + 1; - else n = l; - } - return types[m].FullName.startsWith(prefix) ? m : types.length; - } - - /** Collects the members contained in the given Scala package (namespace) - */ - void collectMembers(Symbol pakage, Map/*<String,Type>*/ typesMap, - Set/*<String>*/ namespacesSet) - { - String namespace = pakage.isRoot() ? "" : snw.toString(pakage) + "."; - int nl = namespace.length(); - for (int i = findFirst(namespace); - i < types.length && types[i].FullName.startsWith(namespace); - i++) - { - Type type = types[i]; - if (type.FullName.equals("java.lang.Object") - || type.FullName.equals("java.lang.String")) { - continue; - } - int k = type.FullName.indexOf(".", nl); - if (k < 0) { - typesMap.put(type.Name, type); - } else { - namespacesSet.add(type.Namespace.substring(nl, k)); - } - } - } - - /** Returns the namespace of the given package */ - String getNameSpaceOf(Symbol pakage) { - assert pakage.hasPackageFlag() || pakage.isRoot(): Debug.show(pakage); - return pakage.isRoot() ? "" : snw.toString(pakage); - } - - //########################################################################## -} // CLRTypes diff --git a/sources/scalac/symtab/classfile/ClassParser.java b/sources/scalac/symtab/classfile/ClassParser.java deleted file mode 100644 index 5284d9cfed..0000000000 --- a/sources/scalac/symtab/classfile/ClassParser.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.util.Debug; - -/** This class implements a SymbolLoader that reads a class file. */ -public class ClassParser extends SymbolLoader { - - //######################################################################## - // Private Fields - - /** The class file to read */ - private final AbstractFile file; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with the specified class file. */ - public ClassParser(Global global, AbstractFile file) { - super(global); - this.file = file; - } - - //######################################################################## - // Protected Methods - - /** Completes the specified symbol by reading the class file. */ - protected String doComplete(Symbol root) throws IOException { - assert root.isClassType(): Debug.show(root); - ClassfileParser.parse(global, file, root); - return "class file '" + file + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/ClassfileConstants.java b/sources/scalac/symtab/classfile/ClassfileConstants.java deleted file mode 100644 index 02c07eea4b..0000000000 --- a/sources/scalac/symtab/classfile/ClassfileConstants.java +++ /dev/null @@ -1,79 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scalac.util.Name; - -public interface ClassfileConstants { - - int JAVA_MAGIC = 0xCAFEBABE; - int JAVA_MAJOR_VERSION = 45; - int JAVA_MINOR_VERSION = 3; - - int JAVA_ACC_PUBLIC = 0x0001; - int JAVA_ACC_PRIVATE = 0x0002; - int JAVA_ACC_PROTECTED = 0x0004; - int JAVA_ACC_STATIC = 0x0008; - int JAVA_ACC_FINAL = 0x0010; - int JAVA_ACC_SUPER = 0x0020; - int JAVA_ACC_SYNCHRONIZED = 0x0020; - int JAVA_ACC_VOLATILE = 0x0040; - int JAVA_ACC_BRIDGE = 0x0040; - int JAVA_ACC_TRANSIENT = 0x0080; - int JAVA_ACC_NATIVE = 0x0100; - int JAVA_ACC_INTERFACE = 0x0200; - int JAVA_ACC_ABSTRACT = 0x0400; - int JAVA_ACC_STRICT = 0x0800; - int JAVA_ACC_SYNTHETIC = 0x1000; - - int CONSTANT_UTF8 = 1; - int CONSTANT_UNICODE = 2; - int CONSTANT_INTEGER = 3; - int CONSTANT_FLOAT = 4; - int CONSTANT_LONG = 5; - int CONSTANT_DOUBLE = 6; - int CONSTANT_CLASS = 7; - int CONSTANT_STRING = 8; - int CONSTANT_FIELDREF = 9; - int CONSTANT_METHODREF = 10; - int CONSTANT_INTFMETHODREF = 11; - int CONSTANT_NAMEANDTYPE = 12; - - int BAD_ATTR = 0x00000; - int SOURCEFILE_ATTR = 0x00001; - int SYNTHETIC_ATTR = 0x00002; - int DEPRECATED_ATTR = 0x00004; - int CODE_ATTR = 0x00008; - int EXCEPTIONS_ATTR = 0x00010; - int CONSTANT_VALUE_ATTR = 0x00020; - int LINE_NUM_TABLE_ATTR = 0x00040; - int LOCAL_VAR_TABLE_ATTR = 0x00080; - int INNERCLASSES_ATTR = 0x08000; - int META_ATTR = 0x10000; - int SCALA_ATTR = 0x20000; - int JACO_ATTR = 0x40000; - int BRIDGE_ATTR = 0x80000; - int SIG_ATTR = 0x100000; - - Name SOURCEFILE_N = Name.fromString("SourceFile"); - Name SYNTHETIC_N = Name.fromString("Synthetic"); - Name BRIDGE_N = Name.fromString("Bridge"); - Name DEPRECATED_N = Name.fromString("Deprecated"); - Name CODE_N = Name.fromString("Code"); - Name EXCEPTIONS_N = Name.fromString("Exceptions"); - Name CONSTANT_VALUE_N = Name.fromString("ConstantValue"); - Name LINE_NUM_TABLE_N = Name.fromString("LineNumberTable"); - Name LOCAL_VAR_TABLE_N = Name.fromString("LocalVariableTable"); - Name INNERCLASSES_N = Name.fromString("InnerClasses"); - Name META_N = Name.fromString("JacoMeta"); - Name SCALA_N = Name.fromString("ScalaSignature"); - Name JACO_N = Name.fromString("JacoInterface"); - Name SIG_N = Name.fromString("Signature"); - Name CONSTR_N = Name.fromString("<init>"); -} diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java deleted file mode 100644 index 235e350903..0000000000 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ /dev/null @@ -1,323 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.AbstractFile; -import scala.tools.util.AbstractFileReader; -import scala.tools.util.Position; -import scalac.*; -import scalac.util.*; -import scalac.symtab.*; -import scalac.symtab.Scope.SymbolIterator; -import java.io.*; -import java.util.*; - -//todo: don't keep statics module in scope. - -public class ClassfileParser implements ClassfileConstants { - - static final int CLASS_ATTR = SOURCEFILE_ATTR - | INNERCLASSES_ATTR - | SYNTHETIC_ATTR - | DEPRECATED_ATTR - | META_ATTR - | SCALA_ATTR - | JACO_ATTR - | SIG_ATTR; - static final int METH_ATTR = CODE_ATTR - | EXCEPTIONS_ATTR - | SYNTHETIC_ATTR - | DEPRECATED_ATTR - | META_ATTR - | SIG_ATTR - | BRIDGE_ATTR; - static final int FIELD_ATTR = CONSTANT_VALUE_ATTR - | SYNTHETIC_ATTR - | DEPRECATED_ATTR - | META_ATTR - | SIG_ATTR; - - protected final Global global; - protected final AbstractFileReader in; - protected final Symbol c; - protected final Symbol m; - protected final Type ctype; - protected final JavaTypeFactory make; - protected final ConstantPool pool; - protected final AttributeParser attrib; - protected final Scope locals; - protected final Scope statics; - - - private ClassfileParser(Global global, AbstractFileReader in, Symbol c, JavaTypeFactory make, ConstantPool pool) { - this.global = global; - this.in = in; - this.c = c; - this.m = c.linkedModule(); - this.ctype = make.classType(c); - this.make = make; - this.pool = pool; - this.attrib = new AttributeParser(in, pool, this); - this.locals = new Scope(); - this.statics = new Scope(); - } - - - /** parse the classfile and throw IO exception if there is an - * error in the classfile structure - */ - public static void parse(Global global, AbstractFile file, Symbol c) throws IOException { - AbstractFileReader in = new AbstractFileReader(file); - try { - int magic = in.nextInt(); - if (magic != JAVA_MAGIC) - throw new IOException("class file '" + in.file + "' " - + "has wrong magic number 0x" + Integer.toHexString(magic) - + ", should be 0x" + Integer.toHexString(JAVA_MAGIC)); - int minorVersion = in.nextChar(); - int majorVersion = in.nextChar(); - if ((majorVersion < JAVA_MAJOR_VERSION) || - ((majorVersion == JAVA_MAJOR_VERSION) && - (minorVersion < JAVA_MINOR_VERSION))) - throw new IOException("class file '" + in.file + "' " - + "has unknown version " - + majorVersion + "." + minorVersion - + ", should be less than " - + JAVA_MAJOR_VERSION + "." + JAVA_MINOR_VERSION); - JavaTypeFactory make = new JavaTypeCreator(global.definitions); - Signatures sigs = new Signatures(global, make, in); - ConstantPool pool = new ConstantPool(in, sigs); - int flags = in.nextChar(); - Symbol clasz = pool.getClass(in.nextChar()); - if (c != clasz) - throw new IOException("class file '" + in.file + "' " - + "contains wrong class " + clasz.staticType()); - new ClassfileParser(global, in, c, make, pool).parse(flags); - } catch (RuntimeException e) { - if (global.debug) e.printStackTrace(); - throw new IOException("class file '" + in.file + "' is broken"); - } - } - - protected void parse(int flags) { - { - // todo: correct flag transition - c.flags = transFlags(flags); - if ((c.flags & Modifiers.DEFERRED) != 0) - c.flags = c.flags & ~Modifiers.DEFERRED | Modifiers.ABSTRACT; - Type supertpe = readClassType(in.nextChar()); - Type[] basetpes = new Type[in.nextChar() + 1]; - // set info of class - Type classInfo = Type.compoundType(basetpes, locals, c); - c.setInfo(classInfo); - // set info of statics class - Symbol staticsClass = m.moduleClass(); - assert staticsClass.isModuleClass(): Debug.show(staticsClass); - Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo); - m.setInfo(make.classType(staticsClass)); - basetpes[0] = supertpe; - for (int i = 1; i < basetpes.length; i++) - basetpes[i] = readClassType(in.nextChar()); - int fieldCount = in.nextChar(); - for (int i = 0; i < fieldCount; i++) - parseField(); - int methodCount = in.nextChar(); - for (int i = 0; i < methodCount; i++) - parseMethod(); - - Symbol constr = c.primaryConstructor(); - if (!constr.isInitialized()) { - constr.setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, ctype)); - if ((c.flags & Modifiers.INTERFACE) == 0) - constr.flags |= Modifiers.PRIVATE; - } - attrib.readAttributes(c, classInfo, CLASS_ATTR); - //System.out.println("dynamic class: " + c); - //System.out.println("statics class: " + staticsClass); - //System.out.println("module: " + m); - //System.out.println("modules class: " + m.type().symbol()); - - int savedFlags = c.flags; - c.flags |= Modifiers.INITIALIZED; - // hack to make memberType in addInheritedOverloaded work - if (global.currentPhase.id <= global.PHASE.REFCHECK.id() && - !c.name.toString().endsWith("$class")) - addInheritedOverloaded(); - - //if (global.debug) { - // Symbol[] elems = c.members().elements(); - // global.log(c + " defines: "); - // for (int i = 0; i < elems.length; i++) { - // global.log(elems[i] + ":" + elems[i].type()); - // } - //} - - c.flags = savedFlags; - - // Add static members of superclass - // todo: remove - Symbol superclass = supertpe.symbol(); - if (m.isJava() && superclass.isJava()) { - Symbol mclass = m.moduleClass(); - SymbolIterator i = superclass.linkedModule().moduleClass() - .members().iterator(); - outer: - while (i.hasNext()) { - Symbol member = i.next(); - Symbol current = statics.lookup(member.name); - if (!current.isNone()) { - if (!member.isTerm()) continue outer; - Type info = member.info(); - Symbol[] currents = current.alternativeSymbols(); - inner: - for (int j = 0; j < currents.length; j++) { - if (currents[j].owner() != mclass) - continue inner; - if (currents[j].info().isSubType(info)) - continue outer; - } - } - statics.enterOrOverload(member); - } - } - } - } - - private void addInheritedOverloaded() { - Symbol[] elems = c.members().elements(); - for (int i = 0; i < elems.length; i++) { - addInheritedOverloaded(elems[i]); - } - } - - private void addInheritedOverloaded(Symbol sym) { - if (sym.isMethod() && !sym.isConstructor()) { - sym.addInheritedOverloaded(sym.type()); - } - } - - /** convert Java modifiers into Scala flags - */ - public int transFlags(int flags) { - int res = 0; - if ((flags & JAVA_ACC_PRIVATE) != 0) - res |= Modifiers.PRIVATE; - else if ((flags & JAVA_ACC_PROTECTED) != 0) - res |= Modifiers.PROTECTED; - else if ((flags & JAVA_ACC_PUBLIC) == 0) - res |= Modifiers.PRIVATE; - if ((flags & JAVA_ACC_ABSTRACT) != 0) - res |= Modifiers.DEFERRED; - if ((flags & JAVA_ACC_FINAL) != 0) - res |= Modifiers.FINAL; - if ((flags & JAVA_ACC_INTERFACE) != 0) - res |= Modifiers.INTERFACE | Modifiers.TRAIT | Modifiers.ABSTRACT; - if ((flags & JAVA_ACC_SYNTHETIC) != 0) - res |= Modifiers.SYNTHETIC; - return res | Modifiers.JAVA; - } - - /** read a class name and return the corresponding class type - */ - protected Type readClassType(int i) { - return i == 0 ? make.anyType() : make.classType(pool.getClass(i)); - } - - /** read a field - */ - protected void parseField() { - int jflags = in.nextChar(); - int sflags = transFlags(jflags); - if ((jflags & JAVA_ACC_FINAL) == 0) sflags |= Modifiers.MUTABLE; - if ((sflags & Modifiers.PRIVATE) != 0) { - in.skip(4); - attrib.skipAttributes(); - } else { - Name name = pool.getName(in.nextChar()); - Symbol owner = getOwner(jflags); - Symbol symbol = owner.newTerm(Position.NOPOS, sflags, name); - Type type = pool.getFieldType(in.nextChar()); - symbol.setInfo(type); - attrib.readAttributes(symbol, type, FIELD_ATTR); - getScope(jflags).enterOrOverload(symbol); - } - } - - /** read a method - */ - protected void parseMethod() { - int jflags = in.nextChar(); - int sflags = transFlags(jflags); - if ((jflags & JAVA_ACC_BRIDGE) != 0) sflags |= Modifiers.PRIVATE; - if ((sflags & Modifiers.PRIVATE) != 0) { - in.skip(4); - attrib.skipAttributes(); - } else { - Name name = pool.getName(in.nextChar()); - Type type = pool.getMethodType(in.nextChar()); - Symbol owner = getOwner(jflags); - Symbol symbol; - boolean newConstructor = false; - if (name == CONSTR_N) { - switch (type) { - case MethodType(Symbol[] vparams, _): - type = Type.MethodType(vparams, ctype); - break; - default: - throw Debug.abort("illegal case", type); - } - symbol = owner.primaryConstructor(); - if (symbol.isInitialized()) { - symbol = owner.newConstructor(Position.NOPOS, sflags); - newConstructor = true; - } else { - symbol.flags = sflags; - } - } else { - symbol = owner.newTerm(Position.NOPOS, sflags, name); - } - setParamOwners(type, symbol); - symbol.setInfo(type); - attrib.readAttributes(symbol, type, METH_ATTR); - if (name != CONSTR_N) { - if ((symbol.flags & Modifiers.BRIDGE) == 0) - getScope(jflags).enterOrOverload(symbol); - } else if (newConstructor) - owner.addConstructor(symbol); - } - } - - /** return the owner of a member with given java flags - */ - private Symbol getOwner(int jflags) { - return (jflags & JAVA_ACC_STATIC) != 0 ? m.moduleClass() : c; - } - - /** return the scope of a member with given java flags - */ - private Scope getScope(int jflags) { - return (jflags & JAVA_ACC_STATIC) != 0 ? statics : locals; - } - - private void setParamOwners(Type type, Symbol owner) { - switch (type) { - case PolyType(Symbol[] params, Type result): - for (int i = 0; i < params.length; i++) - params[i].setOwner(owner); - setParamOwners(result, owner); - break; - case MethodType(Symbol[] params, Type result): - for (int i = 0; i < params.length; i++) params[i].setOwner(owner); - setParamOwners(result, owner); - break; - } - } -} diff --git a/sources/scalac/symtab/classfile/ConstantPool.java b/sources/scalac/symtab/classfile/ConstantPool.java deleted file mode 100644 index 0a042ae3f0..0000000000 --- a/sources/scalac/symtab/classfile/ConstantPool.java +++ /dev/null @@ -1,217 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scalac.atree.AConstant; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scala.tools.util.AbstractFileReader; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.SourceRepresentation; - -/** This class implements the parsing of class file constant pools. */ -public class ConstantPool implements ClassfileConstants { - - //######################################################################## - // Private Fields - - /** The input file */ - private final AbstractFileReader in; - - /** The signature parser */ - private final Signatures parser; - - /** The start addresses of all constants */ - private final int[] starts; - - /** The values of the constants (or null if not yet read) */ - private final Object[] values; - - //######################################################################## - // Public Constructors - - /** Initializes this instance by reading constant pool in file. */ - public ConstantPool(AbstractFileReader in, Signatures parser) { - this.in = in; - this.parser = parser; - this.starts = new int[in.nextChar()]; - this.values = new Object[starts.length]; - for (int index = 1; index < starts.length; ) { - starts[index++] = in.bp; - switch (in.nextByte()) { - case CONSTANT_UTF8: - case CONSTANT_UNICODE: - in.skip(in.nextChar()); - continue; - case CONSTANT_CLASS: - case CONSTANT_STRING: - in.skip(2); - continue; - case CONSTANT_FIELDREF: - case CONSTANT_METHODREF: - case CONSTANT_INTFMETHODREF: - case CONSTANT_NAMEANDTYPE: - case CONSTANT_INTEGER: - case CONSTANT_FLOAT: - in.skip(4); - continue; - case CONSTANT_LONG: - case CONSTANT_DOUBLE: - in.skip(8); - index++; - continue; - default: - throw errorBadTag(in.bp - 1); - } - } - } - - //######################################################################## - // Public Methods - - /** Returns the string at given index. */ - public String getString(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof String) return (String)values[index]; - if (values[index] instanceof Name) return values[index].toString(); - String value = readString(starts[index]); - values[index] = value; - return value; - } - - /** Returns the name at given index. */ - public Name getName(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Name) return (Name)values[index]; - Name value = readName(starts[index]); - values[index] = value; - return value; - } - - /** Returns the class at given index. */ - public Symbol getClass(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Symbol) return (Symbol)values[index]; - Symbol value = readClass(starts[index]); - values[index] = value; - return value; - } - - /** Returns the field type at given index. */ - public Type getFieldType(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Type) return (Type)values[index]; - Type value = readFieldType(starts[index]); - values[index] = value; - return value; - } - - /** Returns the method type at given index. */ - public Type getMethodType(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] instanceof Type) return clone((Type)values[index]); - Type value = readMethodType(starts[index]); - values[index] = value; - return value; - } - - /** Returns the constant value at given index. */ - public AConstant getConstantValue(int index) { - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - if (values[index] != null) return (AConstant)values[index]; - AConstant value = readConstantValue(starts[index]); - values[index] = value; - return value; - } - - //######################################################################## - // Private Fields - - /** Reads the string at given address. */ - private String readString(int address) { - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).getSignature(); - } - - /** Reads the name at given address. */ - private Name readName(int address) { - return Name.fromString(readString(address)); - } - - /** Reads the class at given address. */ - private Symbol readClass(int address) { - if (in.byteAt(address) != CONSTANT_CLASS) throw errorBadTag(address); - int index = in.getChar(address + 1); - if (index <= 0 || starts.length <= index) throw errorBadIndex(index); - address = starts[index]; - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).readClassName(); - } - - /** Reads the field type at given address. */ - private Type readFieldType(int address) { - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).readValueType(); - } - - /** Reads the method type at given address. */ - private Type readMethodType(int address) { - if (in.byteAt(address) != CONSTANT_UTF8) throw errorBadTag(address); - return parser.at(address).readMethodType(); - } - - /** Reads the constant value at given address. */ - private AConstant readConstantValue(int address) { - switch (in.byteAt(address)) { - case CONSTANT_STRING: - return AConstant.STRING(getString(in.getChar(address + 1))); - case CONSTANT_INTEGER: - return AConstant.INT(in.getInt(address + 1)); - case CONSTANT_FLOAT: - return AConstant.FLOAT(in.getFloat(address + 1)); - case CONSTANT_LONG: - return AConstant.LONG(in.getLong(address + 1)); - case CONSTANT_DOUBLE: - return AConstant.DOUBLE(in.getDouble(address + 1)); - default: - throw errorBadTag(address); - } - } - - /** Returns the type with all its parameters symbols cloned. */ - private Type clone(Type type) { - switch (type) { - case MethodType(Symbol[] params, Type result): - Symbol[] clones = new Symbol[params.length]; - for (int i = 0; i < clones.length; i++) - clones[i] = params[i].cloneSymbol(Symbol.NONE); - return Type.MethodType(clones, result); - case ErrorType: - return type; - default: - throw Debug.abort("illegal case", type); - } - } - - /** Throws an exception signaling a bad constant index. */ - private RuntimeException errorBadIndex(int index) { - String error = "bad constant pool index: " + index; - throw new RuntimeException(error); - } - - /** Throws an exception signaling a bad tag at given address. */ - private RuntimeException errorBadTag(int address) { - int tag = in.byteAt(address); - String error = "bad constant pool tag " + tag + " at byte " + address; - throw new RuntimeException(error); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/JavaTypeCreator.java b/sources/scalac/symtab/classfile/JavaTypeCreator.java deleted file mode 100644 index d01f1923e2..0000000000 --- a/sources/scalac/symtab/classfile/JavaTypeCreator.java +++ /dev/null @@ -1,162 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scalac.atree.AConstant; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.symtab.*; -import Type.*; - - -public class JavaTypeCreator implements JavaTypeFactory { - - protected final Definitions definitions; - - protected final Type ANY_TYPE; - protected final Type DOUBLE_TYPE; - protected final Type FLOAT_TYPE; - protected final Type LONG_TYPE; - protected final Type INT_TYPE; - protected final Type CHAR_TYPE; - protected final Type SHORT_TYPE; - protected final Type BYTE_TYPE; - protected final Type BOOLEAN_TYPE; - protected final Type UNIT_TYPE; - protected final Type OBJECT_TYPE; - protected final Type STRING_TYPE; - protected final Type ARRAY_TYPE; - - public JavaTypeCreator(Definitions definitions) { - this.definitions = definitions; - this.ANY_TYPE = classType(definitions.ANY_CLASS); - this.DOUBLE_TYPE = classType(definitions.DOUBLE_CLASS); - this.FLOAT_TYPE = classType(definitions.FLOAT_CLASS); - this.LONG_TYPE = classType(definitions.LONG_CLASS); - this.INT_TYPE = classType(definitions.INT_CLASS); - this.CHAR_TYPE = classType(definitions.CHAR_CLASS); - this.SHORT_TYPE = classType(definitions.SHORT_CLASS); - this.BYTE_TYPE = classType(definitions.BYTE_CLASS); - this.BOOLEAN_TYPE = classType(definitions.BOOLEAN_CLASS); - this.UNIT_TYPE = classType(definitions.UNIT_CLASS); - this.OBJECT_TYPE = classType(definitions.OBJECT_CLASS); - this.STRING_TYPE = classType(definitions.STRING_CLASS); - this.ARRAY_TYPE = classType(definitions.ARRAY_CLASS); - } - - public Type anyType() { - return ANY_TYPE; - } - - public Type byteType() { - return BYTE_TYPE; - } - - public Type shortType() { - return SHORT_TYPE; - } - - public Type charType() { - return CHAR_TYPE; - } - - public Type intType() { - return INT_TYPE; - } - - public Type longType() { - return LONG_TYPE; - } - - public Type floatType() { - return FLOAT_TYPE; - } - - public Type doubleType() { - return DOUBLE_TYPE; - } - - public Type booleanType() { - return BOOLEAN_TYPE; - } - - public Type voidType() { - return UNIT_TYPE; - } - - public Type objectType() { - return OBJECT_TYPE; - } - - public Type stringType() { - return STRING_TYPE; - } - - public Type classType(String classname) { - if (classname.equals("java.lang.Object")) - return objectType(); - if (classname.equals("java.lang.String")) - return stringType(); - return classType(definitions.getClass(classname)); - } - - public Type classType(Symbol clasz) { - return clasz.staticType(); - } - - public Type arrayType(Type elemtpe) { - return Type.appliedType(ARRAY_TYPE, new Type[]{elemtpe}); - } - - public Type methodType(Type[] argtpes, Type restpe, Type[] thrown) { - Symbol[] args = new Symbol[argtpes.length]; - for (int i = 0; i < args.length; i++) { - args[i] = Symbol.NONE.newTerm( // !!! should be newVParam - Position.NOPOS, Modifiers.PARAM, Name.fromString("x" + i)); - args[i].setInfo(objToAny(argtpes[i])); - } - return new MethodType(args, restpe); - } - private Type objToAny(Type tp) { - return tp.isSameAs(OBJECT_TYPE) ? ANY_TYPE : tp; - } - - public Type packageType(Name packagename) { - return null; - } - - /** return the constant type for the given constant. - */ - public Type constantType(AConstant value) { - return Type.constantType(value); - } - - /** return the type of a given constant. - */ - public Type typeOfValue(Object value) { - if (value instanceof Character) - return charType(); - else if (value instanceof Integer) - return intType(); - else if (value instanceof Long) - return longType(); - else if (value instanceof Float) - return floatType(); - else if (value instanceof Double) - return doubleType(); - else if (value instanceof String) - return stringType(); - else if (value instanceof Boolean) - return booleanType(); - else - throw Debug.abort("unknown constant type", value.getClass()); - } - -} diff --git a/sources/scalac/symtab/classfile/JavaTypeFactory.java b/sources/scalac/symtab/classfile/JavaTypeFactory.java deleted file mode 100644 index af89fce22b..0000000000 --- a/sources/scalac/symtab/classfile/JavaTypeFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scalac.atree.AConstant; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; - -public interface JavaTypeFactory { - Type anyType(); - Type byteType(); - Type shortType(); - Type charType(); - Type intType(); - Type longType(); - Type floatType(); - Type doubleType(); - Type booleanType(); - Type voidType(); - Type objectType(); - Type stringType(); - Type classType(String classname); - Type classType(Symbol clasz); - Type arrayType(Type elemtpe); - Type methodType(Type[] argtpes, Type restpe, Type[] thrown); - Type packageType(Name packagename); - Type constantType(AConstant value); -} diff --git a/sources/scalac/symtab/classfile/MetaParser.java b/sources/scalac/symtab/classfile/MetaParser.java deleted file mode 100644 index afc5f525e1..0000000000 --- a/sources/scalac/symtab/classfile/MetaParser.java +++ /dev/null @@ -1,287 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, 2003, 2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scalac.util.Name; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Scope; -import scalac.symtab.Type; -import scalac.ApplicationError; -import scalac.util.Debug; - -import java.util.Vector; -import java.util.StringTokenizer; -import java.util.NoSuchElementException; - -/** a parser class for parsing meta type information in classfiles - * generated by pico. - */ -class MetaParser { - private final Symbol owner; - private final StringTokenizer scanner; - private final Type defaultType; - private String token; - private final Scope tvars; - private Scope locals; - private final Symbol clazz; - private final Type ctype; - private final JavaTypeFactory make; - - MetaParser(String meta, Scope tvars, Symbol owner, Type defaultType, - Symbol clazz, Type ctype, JavaTypeFactory make) { - this.scanner = new StringTokenizer(meta, "()[], \t<;", true); - this.defaultType = defaultType; - this.owner = owner; - this.tvars = tvars; - this.clazz = clazz; - this.ctype = ctype; - this.make = make; - } - - private static Name getTypeName(String name) { - return Name.fromString(name).toTypeName(); - } - - private Symbol getTVar(String name) { - return getTVar(name, clazz.primaryConstructor()); - } - - private Symbol getTVar(String name, Symbol owner) { - if (name.startsWith("?")) { - Symbol s = (locals != null ? locals : tvars) - .lookup(getTypeName(name)); - if (s != Symbol.NONE) - return s; - else if (locals != null) { - s = tvars.lookup(getTypeName(name)); - if (s != Symbol.NONE) - return s; - } - s = owner.newTParam - (Position.NOPOS, 0, getTypeName(token), make.anyType()); - tvars.enter(s); - return s; - } else - return Symbol.NONE; - } - - private String nextToken() { - do { - token = scanner.nextToken().trim(); - } while (token.length() == 0); - return token; - } - - protected Type parse() { - if (scanner.hasMoreTokens()) { - nextToken(); - if (!scanner.hasMoreTokens()) - return defaultType; - if ("class".equals(token)) - return parseMetaClass(); - if ("method".equals(token)) - return parseMetaMethod(); - if ("field".equals(token)) - return parseMetaField(); - if ("constr".equals(token)) - return parseConstrField(); - } - return defaultType; - } - - protected Type parseMetaClass() { - nextToken(); - //System.out.println("parse meta class " + token);//DEBUG - if ("[".equals(token)) { - try { - Vector syms = new Vector(); - do { - nextToken(); - int vflag = 0; - if (token.equals("+")) { - nextToken(); - vflag = Modifiers.COVARIANT; - } else if (token.equals("-")) { - nextToken(); - vflag = Modifiers.CONTRAVARIANT; - } - assert token.startsWith("?"); - Symbol s = getTVar(token); - if (s == Symbol.NONE) - return defaultType; - s.flags |= vflag; - nextToken(); - //System.out.println("new var " + s + ", " + token);//DEBUG - if (token.equals("<")) { - nextToken(); - s.setInfo(parseType()); - } - syms.add(s); - } while (token.equals(",")); - assert "]".equals(token); - nextToken(); - Symbol[] smbls = (Symbol[])syms.toArray(new Symbol[syms.size()]); - //System.out.println("*** " + syms);//DEBUG - Type clazztype = Type.appliedType(ctype, Symbol.type(smbls)); - Symbol constr = clazz.primaryConstructor(); - switch (constr.rawInfo()) { - case MethodType(Symbol[] vparams, _): - constr.setInfo(Type.PolyType - (smbls, Type.MethodType(vparams, clazztype))); - break; - default: - throw new ApplicationError(constr.rawInfo()); - } - } catch (NoSuchElementException e) { - } - } - Type res = defaultType; - if ("extends".equals(token)) { - Vector basetpes = new Vector(); - do { - nextToken(); - basetpes.add(parseType()); - } while (token.equals("with")); - switch (defaultType) { - case CompoundType(_, Scope scope): - Type[] ts = (Type[])basetpes.toArray(new Type[basetpes.size()]); - res = Type.compoundType(ts, scope, defaultType.symbol()); - } - } - assert ";".equals(token); - return res; - } - - protected Type parseType() { - String name = token; - Symbol s = getTVar(name); - nextToken(); - if (s != Symbol.NONE) - return s.type(); - Type clazztype = make.classType(name).unalias(); - if (token.equals("[")) { - Vector types = new Vector(); - do { - nextToken(); - types.add(parseType()); - } while (token.equals(",")); - assert "]".equals(token); - nextToken(); - Type[] args = new Type[types.size()]; - types.toArray(args); - return Type.appliedType(clazztype, args); - } else { - return clazztype; - } - } - - protected Type parseMetaMethod() { - locals = new Scope(); - try { - nextToken(); - Symbol[] smbls = null; - //System.out.println("parse meta method " + token); - if ("[".equals(token)) { - Vector syms = new Vector(); - do { - nextToken(); - if ("]".equals(token)) - break; - assert token.startsWith("?"); - Symbol s = owner.newTParam - (Position.NOPOS, 0, getTypeName(token), make.anyType()); - locals.enter(s); - nextToken(); - if (token.equals("<")) { - nextToken(); - s.setInfo(parseType()); - } - syms.add(s); - } while (token.equals(",")); - assert "]".equals(token); - nextToken(); - smbls = (Symbol[])syms.toArray(new Symbol[syms.size()]); - } - if ("(".equals(token)) { - int i = 0; - Vector params = new Vector(); - do { - nextToken(); - if (")".equals(token)) - break; - int flags = 0; - if ("def".equals(token)) { - nextToken(); - flags |= Modifiers.DEF; - } - Symbol vp = owner.newVParam - (Position.NOPOS, flags, Name.fromString("x" + (i++))); - params.add(vp.setInfo(parseType())); - //System.out.println(" + " + token); - } while (token.equals(",")); - assert ")".equals(token); - nextToken(); - //System.out.println("+++ method " + token); - Type restpe = parseType(); - assert ";".equals(token); - Type mtype = Type.MethodType - ((Symbol[])params.toArray(new Symbol[params.size()]), - restpe); - return smbls == null ? mtype : Type.PolyType(smbls, mtype); - } else { - Type res = parseType(); - assert ";".equals(token); - return Type.PolyType - (smbls == null ? Symbol.EMPTY_ARRAY : smbls, res); - } - } catch (NoSuchElementException e) { - e.printStackTrace(); - return defaultType; - } finally { - locals = null; - } - } - - protected Type parseMetaField() { - nextToken(); - return parseType(); - } - - protected Type parseConstrField() { - try { - nextToken(); - //System.out.println("+++ constr " + token); - if ("(".equals(token)) { - int i = 0; - Vector params = new Vector(); - do { - nextToken(); - if (")".equals(token)) - break; - Symbol vp = owner.newVParam - (Position.NOPOS, 0, Name.fromString("x" + (i++))); - params.add(vp.setInfo(parseType())); - //System.out.println(" + " + token); - } while (token.equals(",")); - assert ")".equals(token); - nextToken(); - assert ";".equals(token); - return Type.MethodType((Symbol[])params.toArray(new Symbol[params.size()]), - ctype); - } else { - assert ";".equals(token); - return Type.PolyType(Symbol.EMPTY_ARRAY, ctype); - } - } catch (NoSuchElementException e) { - return defaultType; - } - } -} diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java deleted file mode 100644 index fdbc796916..0000000000 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ /dev/null @@ -1,232 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.Iterator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map.Entry; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Scope; -import scalac.symtab.SourceCompleter; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; -import scalac.symtab.SymbolOrigin; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - -/** - * This class implements a package member loader. It can be used to - * complete package class symbols. - */ -public class PackageParser extends SymbolLoader { - - //######################################################################## - // Protected Fields - - /** The directory to read */ - protected final AbstractFile directory; - - /** A table to collect .scala files */ - protected final HashMap/*<String,AbstractFile>*/ sources = new HashMap(); - /** A table to collect .symbl files */ - protected final HashMap/*<String,AbstractFile>*/ symbols = new HashMap(); - /** A table to collect .class files */ - protected final HashMap/*<String,AbstractFile>*/ classes = new HashMap(); - /** A table to collect subdirectories */ - protected final HashMap/*<String,AbstractFile>*/ packages = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public PackageParser(Global global, AbstractFile directory) { - super(global); - this.directory = directory; - assert directory != null; - } - - //######################################################################## - // Protected Methods - - /** Is the given name a valid input file base name? */ - protected boolean isValidName(String name) { - return name.length() > 0 - &&!name.endsWith("$class") - && name.indexOf("$$anon") == -1; - } - - /** Returns a new package parser for the given directory. */ - protected PackageParser newPackageParser(AbstractFile directory) { - return new PackageParser(global, directory); - } - - /** - * Collects all members of the package. This method is invoked by - * method "doComplete". It should not be invoked otherwise. - */ - protected void collectAllMembers(Symbol clasz) { - for (Iterator i = directory.list(); i.hasNext(); ) { - AbstractFile file = (AbstractFile)i.next(); - String filename = file.getName(); - if (file.isDirectory()) { - if (filename.equals("META-INF")) continue; - packages.put(filename, file); - continue; - } - if (filename.endsWith(".class")) { - String name = filename.substring(0, filename.length() - 6); - if (!isValidName(name)) continue; - if (!classes.containsKey(name)) classes.put(name, file); - continue; - } - if (filename.endsWith(".symbl")) { - String name = filename.substring(0, filename.length() - 6); - if (!isValidName(name)) continue; - if (!symbols.containsKey(name)) symbols.put(name, file); - continue; - } - if (filename.endsWith(".scala")) { - String name = filename.substring(0, filename.length() - 6); - if (!isValidName(name)) continue; - if (!sources.containsKey(name)) sources.put(name, file); - continue; - } - } - } - - /** - * Removes from the members collected by "collectAllMembers" all - * those that are hidden. This method is invoked by method - * "doComplete". It should not be invoked otherwise. - */ - protected void removeHiddenMembers(Symbol clasz) { - // Classes/Objects in the root package are hidden. - if (clasz.isRoot()) sources.clear(); - if (clasz.isRoot()) symbols.clear(); - if (clasz.isRoot()) classes.clear(); - // For all files "<N>.class" find the longest M such that - // there is a file "<M>.symbl" and M equals N or "<M>$" is a - // prefix of N. If the file "<N>.class" is less recent than - // the file "<M>.symbl" ignore the ".class" file. Otherwise, - // if M equals N, ignore the ".symbl" file. - for (Iterator i = classes.entrySet().iterator(); i.hasNext(); ) { - if (symbols.isEmpty()) break; - Entry entry = (Entry)i.next(); - String cname = (String)entry.getKey(); - AbstractFile cfile = (AbstractFile)entry.getValue(); - for (String zname = cname; true; ) { - AbstractFile zfile = (AbstractFile)symbols.get(zname); - if (zfile != null) { - if (cfile.lastModified() <= zfile.lastModified()) { - i.remove(); - } else if (zname == cname) { - symbols.remove(zname); - } - break; - } - int index = zname.lastIndexOf('$'); - if (index < 0) break; - zname = zname.substring(0, index); - } - } - // Source versions hide compiled versions except if separate - // compilation is enabled and the compiled version is more - // recent. In that case the compiled version hides the source - // version. - boolean separate = global.separate; - for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) { - if (symbols.isEmpty() && classes.isEmpty()) break; - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile sfile = (AbstractFile)entry.getValue(); - AbstractFile zfile = (AbstractFile)symbols.get(name); - AbstractFile cfile = (AbstractFile)classes.get(name); - boolean hidden = false; - if (zfile != null) - if (separate && zfile.lastModified() > sfile.lastModified()) - hidden = true; - else - symbols.remove(name); - if (cfile != null) - if (separate && cfile.lastModified() > sfile.lastModified()) - hidden = true; - else - classes.remove(name); - if (hidden) i.remove(); - } - // Packages are hidden by classes/objects with the same name. - packages.keySet().removeAll(sources.keySet()); - packages.keySet().removeAll(symbols.keySet()); - packages.keySet().removeAll(classes.keySet()); - } - - /** - * Creates symbols for all members left by method - * "removeHiddenMembers". This method is invoked by method - * "doComplete". It should not be invoked otherwise. - */ - protected Scope createMemberSymbols(Symbol clasz) { - Scope members = new Scope(); - for (Iterator i = sources.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile sfile = (AbstractFile)entry.getValue(); - Name classname = Name.fromString(name).toTypeName(); - SymbolLoader loader = new SourceCompleter(global, sfile); - SymbolOrigin origin = SymbolOrigin.ScalaFile(sfile); - clasz.newLoadedClass(0, classname, loader, members, origin); - } - for (Iterator i = symbols.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile zfile = (AbstractFile)entry.getValue(); - Name classname = Name.fromString(name).toTypeName(); - SymbolLoader loader = new SymblParser(global, zfile); - SymbolOrigin origin = SymbolOrigin.SymblFile(zfile); - clasz.newLoadedClass(0, classname, loader, members, origin); - } - for (Iterator i = classes.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile cfile = (AbstractFile)entry.getValue(); - Name classname = Name.fromString(name).toTypeName(); - SymbolLoader loader = new ClassParser(global, cfile); - SymbolOrigin origin = SymbolOrigin.ClassFile(cfile, null); - clasz.newLoadedClass(JAVA, classname, loader, members, origin); - } - for (Iterator i = packages.entrySet().iterator(); i.hasNext(); ) { - HashMap.Entry entry = (HashMap.Entry)i.next(); - String name = (String)entry.getKey(); - AbstractFile dfile = (AbstractFile)entry.getValue(); - Name packagename = Name.fromString(name); - SymbolLoader loader = newPackageParser(dfile); - SymbolOrigin origin = SymbolOrigin.Directory(dfile); - clasz.newLoadedPackage(packagename, loader, members, origin); - } - return members; - } - - /** Completes the package symbol by loading all its members. */ - protected String doComplete(Symbol root) { - assert root.isRoot() || root.isPackage(): Debug.show(root); - Symbol clasz = root.isRoot() ? root : root.moduleClass(); - collectAllMembers(clasz); - removeHiddenMembers(clasz); - Scope members = createMemberSymbols(clasz); - clasz.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, clasz)); - return "directory path '" + directory + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java deleted file mode 100644 index 22699b33a3..0000000000 --- a/sources/scalac/symtab/classfile/Pickle.java +++ /dev/null @@ -1,616 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import java.util.HashMap; -import java.io.*; -import scalac.Global; -import scalac.ApplicationError; -import scalac.atree.AConstant; -import scalac.util.*; -import scalac.symtab.*; -import Symbol.*; -import Type.*; - -public class Pickle implements Kinds, Modifiers, EntryTags { - - final static boolean debug = false; - -/*************************************************** - * Symbol table attribute format: see EntryTags.java - */ - public byte[] bytes; - private int bp; - - private Name rootname; - private Symbol rootowner; - private HashMap index; - private Object[] entries; - private int ep; - - /** Write symbol table info for root. - * root must be either a module or a class. - */ - public Pickle() { - index = new HashMap(); - entries = new Object[256]; - ep = 0; - } - - /** Pickle all symbols descending from `root'. - */ - public void add(Symbol root) { - if (!root.isExternal()) { - if (Global.instance.debug) System.out.println("pickling " + root); - if (index.get(root) == null) { - this.rootname = root.name.toTermName(); - this.rootowner = root.owner(); - putSymbol(root); - } - } - } - - /** Finalize pickler with given fullname. - */ - public void pickle() { - bytes = new byte[4096]; - bp = 0; - writeAttr(); - this.index = null; - this.entries = null; - } - - /** The number of elements defined in `bytes'. - */ - public int size() { - return bp; - } - - public void writeTo(File file) throws IOException { - OutputStream stream = new FileOutputStream(file); - stream.write(bytes, 0, size()); - stream.close(); - } - -/* ************************************************** - * Phase 1: Build entry table - ************************************************* */ - - /** Is root in symbol.owner*? - */ - private boolean isLocal(Symbol sym) { - return - sym.name.toTermName() == rootname && sym.owner() == rootowner - || - sym.isConstructor() && isLocal(sym.constructorClass()) - || - (sym.kind != NONE && isLocal(sym.owner())); - } - - /** Store entry `e' in index at next available position unless it it - * already there. Return true iff entry is new. - */ - private boolean putEntry(Object e) { - Integer n = (Integer) index.get(e); - if (n == null) { - //System.out.println("entry " + e);//DEBUG - if (ep == entries.length) { - Object[] entries1 = new Object[ep * 2]; - System.arraycopy(entries, 0, entries1, 0, ep); - entries = entries1; - } - entries[ep] = e; - index.put(e, new Integer(ep)); - ep++; - return true; - } else { - return false; - } - } - - /** Store symbol in index. If symbol is local, also store - * everything it refers to. - */ - private void putSymbol(Symbol sym) { - if (putEntry(sym)) { - if (debug) System.out.println("put " + sym); - if (isLocal(sym)) { - putEntry(sym.name); - putSymbol(sym.isConstructor() ? sym.constructorClass() : sym.owner()); - switch (sym.kind) { - case TYPE: - if (sym.isViewBounded()) putType(sym.vuBound()); - else putType(sym.info()); - putType(sym.loBound()); - break; - case ALIAS: - putType(sym.info()); - putSymbol(sym.allConstructors()); - break; - case CLASS: - putType(sym.info()); - if (sym.isModuleClass()) putSymbol(sym.sourceModule()); - putType(sym.typeOfThis()); - putSymbol(sym.allConstructors()); - Symbol[] elems = sym.members().elements(); - for (int i = 0; i < elems.length; i++) - putSymbol(elems[i]); - - break; - case VAL: - putType(sym.removeInheritedOverloaded(sym.info())); - if (sym.isConstructor() && - sym == sym.constructorClass().allConstructors()) - putSymbol(sym.constructorClass()); - else if (sym.isModule()) - putSymbol(sym.moduleClass()); - break; - default: - throw new ApplicationError(); - } - } else if (sym.kind != NONE) { - putEntry(sym.isModuleClass() || sym.isRoot() ? sym.name.toTermName() : sym.name); - if (!sym.owner().isRoot()) - putSymbol(sym.owner()); - } - } - } - - private void putSymbols(Symbol[] syms) { - for (int i = 0; i < syms.length; i++) - putSymbol(syms[i]); - } - - /** Store type and everythig it refers to in index. - */ - private void putType(Type tp) { - if (putEntry(tp)) { - switch (tp) { - case NoType: - break; - case NoPrefix: - putSymbol(Symbol.NONE); - // !!! code above is usefull for compatibility - // !!! nothing would be better line - break; - case ThisType(Symbol sym): - putSymbol(sym); - break; - case SingleType(Type pre, Symbol sym): - putType(pre); - putSymbol(sym); - break; - case ConstantType(Type base, AConstant value): - putType(base); - putConstant(value); - break; - case TypeRef(Type pre, Symbol sym, Type[] args): - putType(pre); - putSymbol(sym); - putTypes(args); - break; - case CompoundType(Type[] parents, Scope members): - Symbol clazz = tp.symbol(); - if (clazz.isCompoundSym()) putSymbol(clazz.owner()); - putSymbol(clazz); - putTypes(parents); - break; - case MethodType(Symbol[] vparams, Type result): - putType(result); - for (int i = 0; i < vparams.length; i++) { - Type ptype = vparams[i].type(); - putType(ptype); - int pflags = vparams[i].flags; - if ((pflags & (REPEATED | DEF)) != 0) - putEntry(new FlagsAndType(encodeFlags(pflags), ptype)); - } - break; - case PolyType(Symbol[] tparams, Type result): - putType(result); - putSymbols(tparams); - break; - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) alts[i].flags |= ALTERNATIVE; - putSymbols(alts); - putTypes(alttypes); - break; - default: - throw new ApplicationError(); - } - } - } - - private void putTypes(Type[] tps) { - for (int i = 0; i < tps.length; i++) - putType(tps[i]); - } - - private void putConstant(AConstant constant) { - if (putEntry(constant)) { - switch (constant) { - case STRING(String value): - putEntry(Name.fromString(value)); - return; - } - } - } - -/* ************************************************** - * Phase 2: Write byte array - ************************************************* */ - - private void resizeTo(int size) { - byte[] bytes1 = new byte[size]; - System.arraycopy(bytes, 0, bytes1, 0, bp); - bytes = bytes1; - } - - /** Write a byte of data - */ - private void writeByte(int b) { - if (bp == bytes.length) resizeTo(bytes.length * 2); - bytes[bp++] = (byte)b; - if (debug) System.out.print(b + " "); - } - - /** Write a natural number in big endian format, base 128. - * All but the last digits have bit 0x80 set. - */ - private void writeNat(int x) { - int y = x >>> 7; - if (y != 0) writeNatPrefix(y); - writeByte(x & 0x7f); - } - - private void writeNatPrefix(int x) { - int y = x >>> 7; - if (y != 0) writeNatPrefix(y); - writeByte((x & 0x7f) | 0x80); - } - - /** Write a natural number at `pos' - * If number is more than one byte, shift rest of array to make space. - */ - private void patchNat(int pos, int x) { - bytes[pos] = (byte) (x & 0x7f); - int y = x >>> 7; - if (y != 0) patchNatPrefix(pos, y); - } - - private void patchNatPrefix(int pos, int x) { - writeByte(0); - System.arraycopy(bytes, pos, bytes, pos+1, bp - (pos+1)); - bytes[pos] = (byte) ((x & 0x7f) | 0x80); - int y = x >>> 7; - if (y != 0) patchNatPrefix(pos, y); - } - - /** Write a long number in signed big endian format, base 256. - */ - private void writeLong(long x) { - long y = x >> 8; - long z = x & 0xff; - if (-y != z >> 7) writeLong(y); - writeByte((int) z); - } - - /** Write a reference to object, i.e., the object's number in the index. - */ - private void writeRef(Object ref) { - Integer i = (Integer) index.get(ref); - assert i != null : ref + " " + ref.getClass(); - writeNat(i.intValue()); - } - - private void writeRefs(Object[] es) { - for (int i = 0; i < es.length; i++) writeRef(es[i]); - } - - /** Write a name entry. Names are stored in Utf8 format. - */ - private void writeName(Name name) { - writeByte(name.isTermName() ? TERMname : TYPEname); - writeByte(0); // space for length - byte[] ascii = name.toAsciiUnsafe(); - while (bp + ascii.length > bytes.length) resizeTo(bytes.length * 2); - System.arraycopy(ascii, 0, bytes, bp, ascii.length); - if (debug) System.out.print(name); - bp = bp + ascii.length; - } - - /** Write a symbol entry. - */ - private void writeSymbol(Symbol sym) { - if (debug) System.out.println("write " + sym); - if (isLocal(sym)) { - switch (sym.kind) { - case TYPE: - writeByte(TYPEsym); - break; - case ALIAS: - writeByte(ALIASsym); - break; - case CLASS: - writeByte(CLASSsym); - break; - case VAL: - writeByte(VALsym); - break; - default: - throw new ApplicationError(); - } - writeByte(0); // space for length - writeRef(sym.name); - writeRef(sym.isConstructor() ? sym.constructorClass() : sym.owner()); - writeNat(sym.flags); - switch (sym.kind) { - case TYPE: - if (sym.isViewBounded()) writeRef(sym.vuBound()); - else writeRef(sym.info()); - writeRef(sym.loBound()); - break; - case ALIAS: - writeRef(sym.info()); - writeRef(sym.allConstructors()); - break; - case CLASS: - writeRef(sym.info()); - if (sym.isModuleClass()) writeRef(sym.sourceModule()); - writeRef(sym.typeOfThis()); - writeRef(sym.allConstructors()); - break; - case VAL: - writeRef(sym.removeInheritedOverloaded(sym.info())); - if (sym.isConstructor() && - sym == sym.constructorClass().allConstructors()) - writeRef(sym.constructorClass()); - else if (sym.isModule()) - writeRef(sym.moduleClass()); - break; - default: - throw new ApplicationError(); - } - } else if (sym.kind == NONE) { - writeByte(NONEsym); - writeByte(0); // space for length - } else { - if (sym.isModuleClass() || sym.isRoot()) { - writeByte(EXTMODCLASSref); - writeByte(0); // space for length - writeRef(sym.name.toTermName()); - } else { - writeByte(EXTref); - writeByte(0); // space for length - assert !sym.isConstructor() : sym; - writeRef(sym.name); - } - if (!sym.owner().isRoot()) - writeRef(sym.owner()); - } - sym.flags &= ~ALTERNATIVE; - } - - /** Write a type entry. - */ - private void writeType(Type tp) { - switch (tp) { - case NoType: - writeByte(NOtpe); - writeByte(0); // space for length - break; - case NoPrefix: - writeByte(THIStpe); - writeByte(0); // space for length - writeRef(Symbol.NONE); - // !!! code above is usefull for compatibility - // !!! following code would be better line: - // !!! writeByte(NOpre); - // !!! writeByte(0); // space for length - break; - case ThisType(Symbol sym): - writeByte(THIStpe); - writeByte(0); // space for length - writeRef(sym); - break; - - case SingleType(Type pre, Symbol sym): - writeByte(SINGLEtpe); - writeByte(0); // space for length - writeRef(pre); - writeRef(sym); - break; - - case ConstantType(Type base, AConstant value): - writeByte(CONSTANTtpe); - writeByte(0); // space for length - writeRef(base); - writeRef(value); - break; - - case TypeRef(Type pre, Symbol sym, Type[] args): - writeByte(TYPEREFtpe); - writeByte(0); // space for length - writeRef(pre); - writeRef(sym); - writeRefs(args); - break; - - case CompoundType(Type[] parents, Scope members): - writeByte(COMPOUNDtpe); - writeByte(0); // space for length - Symbol clazz = tp.symbol(); - writeByte(clazz.isCompoundSym() ? 1 : 0); - if (clazz.isCompoundSym()) writeRef(clazz.owner()); - writeRef(clazz); - writeRefs(parents); - break; - - case MethodType(Symbol[] vparams, Type result): - writeByte(METHODtpe); - writeByte(0); // space for length - writeRef(result); - for (int i = 0; i < vparams.length; i++) { - Type ptype = vparams[i].type(); - int pflags = vparams[i].flags; - if ((pflags & (REPEATED | DEF)) != 0) - writeRef(new FlagsAndType(encodeFlags(pflags), ptype)); - else - writeRef(ptype); - } - break; - - case PolyType(Symbol[] tparams, Type result): - writeByte(POLYtpe); - writeByte(0); // space for length - writeRef(result); - writeRefs(tparams); - break; - - case OverloadedType(Symbol[] alts, Type[] alttypes): - writeByte(OVERLOADEDtpe); - writeByte(0); // space for length - writeRefs(alts); - writeRefs(alttypes); - break; - - default: - throw new ApplicationError(); - } - } - - private void writeFlagsAndType(FlagsAndType ft) { - writeByte(FLAGGEDtpe); - writeByte(0); // space for length - writeNat(ft.flags); - writeRef(ft.type); - } - - /** Write a constant entry. - */ - private void writeConstant(AConstant constant) { - switch (constant) { - case UNIT: - writeByte(LITERALunit); - writeByte(0); // space for length - return; - case BOOLEAN(boolean value): - writeByte(LITERALboolean); - writeByte(0); // space for length - writeByte(value ? 1 : 0); - return; - case BYTE(byte value): - writeByte(LITERALbyte); - writeByte(0); // space for length - writeLong(value); - return; - case SHORT(short value): - writeByte(LITERALshort); - writeByte(0); // space for length - writeLong(value); - return; - case CHAR(char value): - writeByte(LITERALchar); - writeByte(0); // space for length - writeLong(value); - return; - case INT(int value): - writeByte(LITERALint); - writeByte(0); // space for length - writeLong(value); - return; - case LONG(long value): - writeByte(LITERALlong); - writeByte(0); // space for length - writeLong(value); - return; - case FLOAT(float value): - writeByte(LITERALfloat); - writeByte(0); // space for length - writeLong(Float.floatToIntBits(value)); - return; - case DOUBLE(double value): - writeByte(LITERALdouble); - writeByte(0); // space for length - writeLong(Double.doubleToLongBits(value)); - return; - case STRING(String value): - writeByte(LITERALstring); - writeByte(0); // space for length - writeRef(Name.fromString(value)); - return; - case NULL: - writeByte(LITERALnull); - writeByte(0); // space for length - return; - case ZERO: - writeByte(LITERALzero); - writeByte(0); // space for length - return; - default: - throw Debug.abort("unknown case", constant); - } - } - - private void writeEntry(Object e) { - int startpos = bp; - if (e instanceof Symbol) - writeSymbol((Symbol) e); - else if (e instanceof Type) - writeType((Type) e); - else if (e instanceof Name) - writeName((Name) e); - else if (e instanceof FlagsAndType) - writeFlagsAndType((FlagsAndType) e); - else if (e instanceof AConstant) - writeConstant((AConstant)e); - else - throw new ApplicationError(e); - patchNat(startpos + 1, bp - (startpos + 2)); - } - - private void writeAttr() { - writeNat(ep); - for (int i = 0; i < ep; i++) { - if (debug) System.out.print(i + "," + bp + ": "); - writeEntry(entries[i]); - if (debug) System.out.print("(" + entries[i] + ")"); - if (debug) System.out.println(); - } - } - - private static int encodeFlags(int flags) { - int n = 0; - if ((flags & REPEATED) != 0) n |= REPEATEDflag; - if ((flags & DEF) != 0) n |= DEFflag; - return n; - } - - static class FlagsAndType { - int flags; - Type type; - FlagsAndType(int flags, Type type) { - this.flags = flags; - this.type = type; - } - public boolean equals(Object other) { - if (other instanceof FlagsAndType) { - FlagsAndType that = (FlagsAndType) other; - return this.type.equals(that.type) && - this.flags == that.flags; - } else { - return false; - } - } - public int hashCode() { - return 37 + ((flags * 41) ^ type.hashCode()); - } - } -} - diff --git a/sources/scalac/symtab/classfile/Signatures.java b/sources/scalac/symtab/classfile/Signatures.java deleted file mode 100644 index 102bce1a64..0000000000 --- a/sources/scalac/symtab/classfile/Signatures.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import scala.tools.util.Position; -import scala.tools.util.AbstractFileReader; -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.SourceRepresentation; -import scalac.util.Debug; - -/** This class implements the parsing of class file signatures. */ -public class Signatures { - - //######################################################################## - // Private Fields - - /** The global environment */ - private final Global global; - - /** The Java type factory */ - private final JavaTypeFactory make; - - /** The input file */ - private final AbstractFileReader in; - - /** The address of the first byte of the current signature */ - private int first; - - /** The address of the last byte of the current signature */ - private int last; - - /** The current address (first <= current <= last) */ - private int current; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Signatures(Global global, JavaTypeFactory make, - AbstractFileReader in) - { - this.global = global; - this.make = make; - this.in = in; - } - - //######################################################################## - // Public Methods - - /** - * Sets the address of the next signature to read. The address - * must point to the first byte of a CONSTANT_Utf8_info. - */ - public Signatures at(int address) { - first = address + 3; - last = first + in.getChar(address + 1) - 1; - current = first; - return this; - } - - /** Returns the current signature. */ - public String getSignature() { - return SourceRepresentation.ascii2string(in.buf, first, last-first+1); - } - - /** Reads the class signature at current address. */ - public Symbol readClassName() { - Symbol owner = global.definitions.ROOT_CLASS; - int start = current; - for (; current <= last; current++) { - int b = in.byteAt(current); - if (b == ';') break; - if (b != '/') continue; - Name name = Name.fromAscii(in.buf, start, current - start); - Symbol module = owner.members().lookup(name); - if (!module.isModule()) { - Symbol symbol = owner.newModule(Position.NOPOS, 0, name); - symbol.moduleClass().setInfo(Type.ErrorType); - error("could not find module " + symbol.staticType()); - if (module.isNone()) owner.members().enterNoHide(symbol); - module = symbol; - } - owner = module.moduleClass(); - start = current + 1; - } - - Symbol clasz = null; - Name name = Name.fromAscii(in.buf, start, current-start); - if (owner == global.definitions.JAVALANG.moduleClass()) { - if (name == Names.String) - clasz = global.definitions.STRING_CLASS; - else if (name == Names.Object) - clasz = global.definitions.OBJECT_CLASS; - } - if (clasz == null) { - name = name.toTypeName(); - clasz = owner.members().lookup(name); - } - - if (!clasz.isClass()) { - Symbol symbol = owner.newErrorClass(name); - error("could not find class " + symbol.staticType()); - if (clasz.isNone()) owner.members().enterNoHide(symbol); - clasz = symbol; - } - current++; - return clasz; - } - - /** Reads the value type signature at current address. */ - public Type readValueType() { - switch (in.byteAt(current++)) { - case 'V': return make.voidType(); - case 'Z': return make.booleanType(); - case 'B': return make.byteType(); - case 'S': return make.shortType(); - case 'C': return make.charType(); - case 'I': return make.intType(); - case 'J': return make.longType(); - case 'F': return make.floatType(); - case 'D': return make.doubleType(); - case 'L': return make.classType(readClassName()); - case '[': return make.arrayType(readValueType()); - default : return errorBadTypeTag(current - 1); - } - } - - /** Reads the method type signature at current address. */ - public Type readMethodType() { - if (in.byteAt(current++) != '(') return errorBadTypeTag(current - 1); - Type[] parameters = readParamterTypes(0); - Type result = readValueType(); - return make.methodType(parameters, result, Type.EMPTY_ARRAY); - } - - //######################################################################## - // Private Methods - - /** Reads the parameter types at current address. */ - private Type[] readParamterTypes(int i) { - if (in.byteAt(current) == ')') { - current++; - return new Type[i]; - } else { - Type type = readValueType(); - Type[] types = readParamterTypes(i + 1); - types[i] = type; - return types; - } - } - - /** Signals a bad tag at given address. Return ErrorType. */ - private Type errorBadTypeTag(int address) { - char tag = (char)in.byteAt(address); - error("bad tag '" + tag + "' in signature '" + getSignature() + "'"); - return Type.ErrorType; - } - - /** Signals the given error. */ - private void error(String error) { - global.error("class file '" + in.file + "': " + error); - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/SymblParser.java b/sources/scalac/symtab/classfile/SymblParser.java deleted file mode 100644 index 5c948d9176..0000000000 --- a/sources/scalac/symtab/classfile/SymblParser.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -import scalac.Global; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolLoader; - -/** This class implements a SymbolLoader that reads a symbol file. */ -public class SymblParser extends SymbolLoader { - - //######################################################################## - // Private Fields - - /** The symbol file to read */ - private final AbstractFile file; - - //######################################################################## - // Public Constructors - - /** Initializes this instance with the specified symbol file. */ - public SymblParser(Global global, AbstractFile file) { - super(global); - this.file = file; - } - - //######################################################################## - // Protected Methods - - /** Completes the specified symbol by reading the symbol file. */ - public String doComplete(Symbol root) throws IOException { - UnPickle.parse(global, file, root); - return "symbol file '" + file + "'"; - } - - //######################################################################## -} diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java deleted file mode 100644 index f3a715b480..0000000000 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ /dev/null @@ -1,643 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.symtab.classfile; - -import java.util.HashMap; -import java.io.IOException; -import java.io.PrintStream; -import scala.tools.util.AbstractFile; -import scala.tools.util.Position; -import scalac.*; -import scalac.atree.AConstant; -import scalac.util.*; -import scalac.symtab.*; -import Symbol.*; -import Type.*; - -public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags { - -/*************************************************** - * Symbol table attribute format: see EntryTags.java - */ - static final boolean debug = true; - - public static void parse(Global global, AbstractFile file, Symbol root) - throws IOException - { - try { - parse(global, file.read(), root); - } catch (BadSignature exception) { - throw new IOException("symbol file '" + file.getPath() + "' " - + "could not be loaded; " + exception.getMessage()); - } - } - - /** - * The root symbol must be either a module or a non-module - * class. The unpickler initializes it. If it has a linked module - * or class, it will also be initialized. - */ - public static void parse(Global global, byte[] data, Symbol root) - throws BadSignature - { - new UnPickle(global, data, root); - } - - Symbol classroot; - Symbol moduleroot; - byte[] bytes; - int bp; - int[] index; - Object[] entries; - int paramFlags; - final Global global; - - private UnPickle(Global global, byte[] data, Symbol root) { - this.global = global; - this.classroot = root.isModule() ? root.linkedClass() : root; - this.moduleroot = root.isClassType() ? root.linkedModule() : root; - assert classroot == null || classroot.isClassType(): Debug.show(root); - assert moduleroot == null || moduleroot.isModule(): Debug.show(root); - if (root != moduleroot && moduleroot != null) { - moduleroot.moduleClass().setInfo(Type.NoType); - } - if (global.debug) global.log( - "unpickle " + root + " " + classroot + " " + moduleroot - + (moduleroot != null ? " " + moduleroot.moduleClass() : "")); - this.bytes = data; - this.bp = 0; - index = new int[readNat()]; - for (int i = 0; i < index.length; i++) { - index[i] = bp; - bp++; - bp = readNat() + bp; - } - entries = new Object[index.length]; - - if (global.debug) print(System.out); - - for (int i = 0; i < index.length; i++) { - if (isSymbolEntry(i)) getSymbol(i); - } - if (global.debug) global.log("unpickled " + root + ":" + root.rawInfo());//debug - if (!classroot.isInitialized() && !moduleroot.isInitialized()) - throw new BadSignature(this, "it does not define " + root); - // the isModule test is needed because moduleroot may become - // the case class factory method of classroot - if (moduleroot != null && moduleroot.isModule() && moduleroot.moduleClass().type() == Type.NoType) { - moduleroot.setInfo(Type.NoType); - } - } - - int readByte() { - return bytes[bp++]; - } - - int readNat() { - int b; - int x = 0; - do { - b = readByte(); - x = (x << 7) + (b & 0x7f); - } while ((b & 0x80) != 0); - return x; - } - - long readLong(int n) { - long x = 0; - for (int i = 0; i < n; i++) { - x = (x << 8) + (readByte() & 0xff); - } - int leading = 64 - (n * 8); - return x << leading >> leading; - } - - boolean isTypeEntry(int i) { - int tag = bytes[index[i]]; - return (firstTypeTag <= tag && tag <= lastTypeTag) || tag == NOpre; - } - - boolean isSymbolEntry(int i) { - int tag = bytes[index[i]]; - return (firstSymTag <= tag && tag <= lastSymTag); - } - - Name getName(int n) { - if (entries[n] == null) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int len = readNat(); - Name name = Name.fromAscii(bytes, bp, len); - switch (tag) { - case TERMname : entries[n] = name; break; - case TYPEname : entries[n] = name.toTypeName(); break; - default: throw new BadSignature(this); - } - bp = savedBp; - } - return (Name) entries[n]; - } - - Name readNameRef() { - return getName(readNat()); - } - - String decode(Name name) { - if (name.isTypeName()) return "type " + NameTransformer.decode(name); - else return "value " + NameTransformer.decode(name); - } - - /* - void enterSymbol(Symbol sym) { - Symbol owner = sym.owner(); - if (owner.kind == CLASS && - !sym.isConstructor() && !sym.isModuleClass()) { - Scope scope = owner.info().members(); - scope.enterOrOverload(sym); - } - } - */ - - void enterSymbol(Symbol sym) { - /* - if (global.debug) { - global.log("entering " + sym + ":" + sym.type() + " in " + sym.owner());//debug - if (sym.kind == CLASS) - global.log("primconstr = " + sym.primaryConstructor()); - } - */ - if ((sym.flags & ALTERNATIVE) != 0) { - sym.flags &= ~ALTERNATIVE; - } else { - Symbol owner = sym.owner(); - if (owner.kind == CLASS && - !sym.isConstructor() && !sym.isModuleClass()) { - Scope scope = owner.info().members(); - Symbol other = scope.lookup(sym.name); - if (other == Symbol.NONE) { - scope.enter(sym); - } else { - assert sym == other - : "double enter: " + other + ":" + other.rawFirstInfo() + "," + sym + ":" + sym.rawFirstInfo(); - } - } - } - } - - Symbol getSymbol(int n) { - if (entries[n] == null) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int end = readNat() + bp; - Symbol sym; - Symbol owner; - switch (tag) { - case NONEsym: - entries[n] = sym = Symbol.NONE; - break; - case EXTref: - case EXTMODCLASSref: - Name name = readNameRef(); - if (bp == end) { - owner = global.definitions.ROOT_CLASS; - } else { - assert bp < end; - owner = readSymbolRef(); - } - if (name == Names.ROOT && owner == Symbol.NONE) { - sym = global.definitions.ROOT_CLASS; - if (tag == EXTref) sym = sym; - // !!! line above is usefull for the transition - // !!! after some time, replace it by the following line: - // !!! assert tag != EXTref; - } else { - sym = owner.info().lookup(name); - if (tag == EXTMODCLASSref) { - /* - if (sym.kind == VAL) - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isModule()) sym = alts[i]; - } - */ - assert sym.isModule(); - sym = sym.moduleClass(); - } - } - entries[n] = sym; - if (sym.kind == NONE) { - if (global.debug) - global.log(owner.info().members().toString()); - throw new BadSignature(this, - "reference " + decode(name) + " of " + owner + - " refers to nonexisting symbol."); - } - break; - default: - assert isSymbolEntry(n) : n; - Name name = readNameRef(); - if (global.debug) - global.log("reading " + name + " at " + n); - owner = readSymbolRef(); - if (entries[n] == null) { - int flags = readNat(); - int inforef = readNat(); - switch (tag) { - case TYPEsym: - entries[n] = sym = owner.newAbstractType( - Position.NOPOS, flags, name); - if ((flags & VIEWBOUND) != 0) { - sym.setInfo(global.definitions.ANY_TYPE()); - sym.setVuBound(getType(inforef, sym)); - } else { - sym.setInfo(getType(inforef, sym)); - } - sym.setLoBound(readTypeRef(sym)); - break; - - case ALIASsym: - entries[n] = sym = owner.newTypeAlias( - Position.NOPOS, flags, name); - sym.setInfo(getType(inforef, sym)); - Symbol constr = readSymbolRef(); - break; - - case CLASSsym: - if ((flags & MODUL) != 0) { - Symbol modulesym = readSymbolRef(); - entries[n] = sym = modulesym.moduleClass(); - sym.flags = flags; - } else if (classroot != null && name == classroot.name && owner == classroot.owner()) { - if (global.debug) - global.log("overwriting " + classroot); - entries[n] = sym = classroot; - sym.flags = flags; - } else { - entries[n] = sym = owner.newClass( - Position.NOPOS, flags, name); - } - sym.setInfo(getType(inforef, sym)); - sym.setTypeOfThis(readTypeRef(sym)); - Symbol constr = readSymbolRef(); - assert constr == sym.allConstructors(); - break; - - case VALsym: - if (moduleroot != null && name == moduleroot.name && owner == moduleroot.owner()) { - if (global.debug) - global.log("overwriting " + moduleroot); - entries[n] = sym = moduleroot; - sym.flags = flags; - } else if ((flags & MODUL) != 0) { - entries[n] = sym = owner.newModule( - Position.NOPOS, flags, name); - } else if (name == Names.CONSTRUCTOR) { - Symbol tsym = bp < end ? readSymbolRef() : null; - if (tsym == null) { - entries[n] = sym = owner.newConstructor( - Position.NOPOS, flags); - } else { - entries[n] = sym = tsym.allConstructors(); - sym.flags = flags; - } - } else { - entries[n] = sym = owner.newTerm( - Position.NOPOS, flags, name); - } - if (sym.isModule()) { - Symbol clasz = readSymbolRef(); - assert clasz == sym.moduleClass(): Debug.show(sym); - } - Type owntype = getType(inforef, sym); - sym.setInfo(owntype); - break; - - default: - throw new BadSignature(this); - } - - enterSymbol(sym); - } - } - bp = savedBp; - } - return (Symbol) entries[n]; - } - - Symbol readSymbolRef() { - return getSymbol(readNat()); - } - - Symbol[] readSymbolRefs(int end) { - return readSymbolRefs(0, end); - } - - Symbol[] readSymbolRefs(int nread, int end) { - if (bp == end) { - return new Symbol[nread]; - } else { - assert bp < end; - int bp0 = bp; - int ref = readNat(); - if (isSymbolEntry(ref)) { - Symbol s = getSymbol(ref); - Symbol[] ss = readSymbolRefs(nread+1, end); - ss[nread] = s; - return ss; - } else { - bp = bp0; - return new Symbol[nread]; - } - } - } - - Type getType(int n, Symbol owner) { - Type tpe = (Type)entries[n]; - if (tpe == null) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int end = readNat() + bp; - switch (tag) { - case NOtpe: - tpe = Type.NoType; - break; - case NOpre: - tpe = Type.NoPrefix; - break; - case THIStpe: - Symbol sym = readSymbolRef(); - tpe = (sym.kind == NONE) ? Type.NoPrefix : Type.ThisType(sym); - // !!! code above is usefull for the transition - // !!! after some time, replace it by the following line: - // !!! tpe = Type.ThisType(readSymbolRef()); - break; - case SINGLEtpe: - Type prefix = readTypeRef(owner); - Symbol symbol = readSymbolRef(); - tpe = symbol.isRoot() ? symbol.thisType() : Type.singleType(prefix, symbol); - // !!! code above is usefull for the transition - // !!! after some time, replace it by the following line: - // !!! tpe = Type.singleType(readTypeRef(), readSymbolRef()); - break; - case CONSTANTtpe: - Type base = readTypeRef(owner); - AConstant value = readConstantRef(); - tpe = new Type.ConstantType(base, value); - break; - case TYPEREFtpe: - tpe = Type.newTypeRefUnsafe( // !!! - readTypeRef(owner), readSymbolRef(), readTypeRefs(end, owner)); - break; - case COMPOUNDtpe: - boolean isCompoundSym = readByte() != 0; - Symbol ctOwner = isCompoundSym - ? readSymbolRef() - : null; - int ctClassRef = readNat(); - Symbol ctClass = isCompoundSym - ? (Symbol)entries[ctClassRef] - : getSymbol(ctClassRef); - Type[] parents = readTypeRefs(end, owner); - if (ctClass == null) { - tpe = Type.compoundTypeWithOwner(ctOwner, parents, new Scope()); - entries[ctClassRef] = tpe.symbol(); - } else { - tpe = Type.compoundType(parents, new Scope(), ctClass); - } - break; - case METHODtpe: - Type restype = readTypeRef(owner); - int bp1 = bp; - Type[] argtypes = readTypeRefs(end, owner); - int[] flags = new int[argtypes.length]; - bp = bp1; - readFlags(flags); - Symbol[] params = new Symbol[argtypes.length]; - for (int i = 0; i < argtypes.length; i++) { - Name name = Name.fromString("$" + i); - params[i] = owner.newVParam( - Position.NOPOS, flags[i], name, argtypes[i]); - } - tpe = Type.MethodType(params, restype); - break; - case POLYtpe: - Type restype = readTypeRef(owner); - tpe = Type.PolyType(readSymbolRefs(end), restype); - break; - case OVERLOADEDtpe: - int bp0 = bp; - Symbol[] alts = readSymbolRefs(end); - int bp1 = bp; - Type[] alttypes = readTypeRefs(end, alts); - assert alts.length == alttypes.length - : alts.length + "!=" + alttypes.length + - " at " + bp0 + "/" + bp1 + "/" + bp; - tpe = Type.OverloadedType(alts, alttypes); - break; - case FLAGGEDtpe: - readNat(); // skip flags - tpe = readTypeRef(owner); - break; - default: - throw new BadSignature(this); - } - if (tag != METHODtpe) entries[n] = tpe; - bp = savedBp; - } - return tpe; - } - - Type readTypeRef(Symbol owner) { - return getType(readNat(), owner); - } - - Type[] readTypeRefs(int end, Symbol owner) { - return readTypeRefs(0, end, owner, null); - } - - Type[] readTypeRefs(int end, Symbol[] owners) { - return readTypeRefs(0, end, null, owners); - } - - Type[] readTypeRefs(int nread, int end, Symbol owner, Symbol[] owners) { - assert (owner != null) ^ (owners != null); - if (bp == end) { - return new Type[nread]; - } else { - assert bp < end : bp + ">" + end; - int bp0 = bp; - int ref = readNat(); - if (isTypeEntry(ref)) { - Type t = getType(ref, owner != null ? owner : owners[nread]); - Type[] ts = readTypeRefs(nread + 1, end, owner, owners); - ts[nread] = t; - return ts; - } else { - bp = bp0; - return new Type[nread]; - } - } - } - - void readFlags(int[] flags) { - for (int i = 0; i < flags.length; i++) - flags[i] = getFlags(readNat()); - } - - int getFlags(int n) { - int savedBp = bp; - bp = index[n]; - int tag = bytes[bp++]; - int end = readNat() + bp; - int flags = (tag == FLAGGEDtpe) ? decodeFlags(readNat()) : 0; - bp = savedBp; - return flags; - } - - private static int decodeFlags(int n) { - int flags = 0; - if ((n & REPEATEDflag) != 0) flags |= REPEATED; - if ((n & DEFflag) != 0) flags |= DEF; - return flags; - } - - AConstant readConstant() { - int tag = bytes[bp++]; - int len = readNat(); - switch (tag) { - case LITERALunit: - return AConstant.UNIT; - case LITERALboolean: - return AConstant.BOOLEAN(readByte() == 0 ? false : true); - case LITERALbyte: - return AConstant.BYTE((byte)readLong(len)); - case LITERALshort: - return AConstant.SHORT((short)readLong(len)); - case LITERALchar: - return AConstant.CHAR((char)readLong(len)); - case LITERALint: - return AConstant.INT((int)readLong(len)); - case LITERALlong: - return AConstant.LONG(readLong(len)); - case LITERALfloat: - return AConstant.FLOAT(Float.intBitsToFloat((int)readLong(len))); - case LITERALdouble: - return AConstant.DOUBLE(Double.longBitsToDouble(readLong(len))); - case LITERALstring: - return AConstant.STRING(readNameRef().toString()); - case LITERALnull: - return AConstant.NULL; - case LITERALzero: - return AConstant.ZERO; - default: - throw Debug.abort("illegal tag: " + tag); - } - } - - AConstant readConstantRef() { - int n = readNat(); - int savedBp = bp; - bp = index[n]; - AConstant constant = readConstant(); - bp = savedBp; - return constant; - } - - public static class BadSignature extends java.lang.Error { - public BadSignature(UnPickle outer, String msg) { - super(msg); - } - public BadSignature(UnPickle outer) { - this(outer, "malformed signature at " + outer.bp); - } - } - -// --- print symbl files ------------------------------------------------- - - private static String tag2string(int tag) { - switch (tag) { - case TERMname: return "TERMname"; - case TYPEname: return "TYPEname"; - case NONEsym: return "NONEsym"; - case TYPEsym: return "TYPEsym"; - case ALIASsym: return "ALIASsym"; - case CLASSsym: return "CLASSsym"; - case VALsym: return "VALsym"; - case EXTref: return "EXTref"; - case EXTMODCLASSref: return "EXTMODCLASSref"; - case NOtpe: return "NOtpe"; - case THIStpe: return "THIStpe"; - case SINGLEtpe: return "SINGLEtpe"; - case TYPEREFtpe: return "TYPEREFtpe"; - case CONSTANTtpe: return "CONSTANTtpe"; - case COMPOUNDtpe: return "COMPOUNDtpe"; - case METHODtpe: return "METHODtpe"; - case POLYtpe: return "POLYtpe"; - case OVERLOADEDtpe: return "OVERLOADEDtpe"; - case UNBOXEDtpe: return "UNBOXEDtpe"; - case UNBOXEDARRAYtpe: return "UNBOXEDARRAYtpe"; - case FLAGGEDtpe: return "FLAGGEDtpe"; - case ERRORtpe: return "ERRORtpe"; - case LITERALunit: return "LITERALunit"; - case LITERALboolean: return "LITERALboolean"; - case LITERALbyte: return "LITERALbyte"; - case LITERALshort: return "LITERALshort"; - case LITERALchar: return "LITERALchar"; - case LITERALint: return "LITERALint"; - case LITERALlong: return "LITERALlong"; - case LITERALfloat: return "LITERALfloat"; - case LITERALdouble: return "LITERALdouble"; - case LITERALstring: return "LITERALstring"; - case LITERALnull: return "LITERALnull"; - case LITERALzero: return "LITERALzero"; - default: return "***BAD TAG***(" + tag + ")"; - } - } - - private void print(PrintStream out) { - out.println("symbl attribute for " + classroot + ":"); - for (int i = 0; i < index.length; i++) { - out.print(i + "," + index[i] + ": "); - bp = index[i]; - int tag = readByte(); - out.print(tag2string(tag)); - int len = readNat(); - int end = len + bp; - out.print(" " + len); - switch (tag) { - case TERMname: - case TYPEname: - String name = SourceRepresentation.ascii2string(bytes, bp, len); - out.print(" " + SourceRepresentation.escape(name)); - bp = end; - break; - case NONEsym: - break; - case TYPEsym: - case ALIASsym: - case CLASSsym: - case VALsym: - out.print(" " + readNat()); //name - out.print(" " + readNat()); //owner - out.print(" " + Integer.toHexString(readNat())); //flags - out.print(" " + readNat()); //type - break; - case FLAGGEDtpe: - out.print(" " + Integer.toHexString(readNat())); //flags - } - while (bp < end) out.print(" " + readNat()); - out.println(); - } - } -} - diff --git a/sources/scalac/transformer/AddAccessorsPhase.java b/sources/scalac/transformer/AddAccessorsPhase.java deleted file mode 100644 index 2f684e1acb..0000000000 --- a/sources/scalac/transformer/AddAccessorsPhase.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: AddAccessorsPhase.java,v 1.1 2002/10/17 12:27:11 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeList; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - - -/** - * This phase adds private accessor fields and methods for all class - * constructor arguments which are accessed from within the class' - * methods, or nested classes. - */ -public class AddAccessorsPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AddAccessorsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - //######################################################################## - // Private Class - Tree transformer - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - /** The parameter to accessor method map */ - private final Map/*<Symbol,Symbol>*/ methods = new HashMap(); - - /** The current method */ - private Symbol method; - - /** Creates an accessor field symbol for given parameter. */ - private Symbol createAccessorField(Symbol param) { - int flags = Modifiers.PRIVATE | Modifiers.STABLE; - Name name = Name.fromString(param.name + "$"); - Symbol owner = param.owner().constructorClass(); - Symbol field = owner.newField(param.pos, flags, name); - field.setType(param.type()); - owner.members().enterOrOverload(field); - return field; - } - - /** Creates an accessor method symbol for given parameter. */ - private Symbol createAccessorMethod(Symbol param) { - int flags = Modifiers.PRIVATE | Modifiers.STABLE | Modifiers.ACCESSOR; - Name name = param.name; - Symbol owner = param.owner().constructorClass(); - Symbol method = owner.newMethod(param.pos, flags, name); - method.setType(Type.MethodType(Symbol.EMPTY_ARRAY, param.type())); - owner.members().enterOrOverload(method); - methods.put(param, method); - return method; - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): { - Symbol clasz = tree.symbol(); - // transform parents and body - Symbol backup = this.method; - this.method = clasz.primaryConstructor(); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - this.method = backup; - // create accessor field & method trees - TreeList accessors = new TreeList(); - Symbol[] params = clasz.valueParams(); - for (int i = 0; i < params.length; ++i) { - Symbol param = params[i]; - Symbol method = (Symbol)methods.remove(param); - if (method == null) continue; - Symbol field = createAccessorField(param); - accessors.append( - gen.ValDef( - field, - gen.Ident(param.pos, param))); - accessors.append( - gen.DefDef( - method, - gen.Select(gen.This(param.pos, clasz), field))); - } - body = Tree.concat(accessors.toArray(), body); - impl = gen.Template(clasz.pos, impl.symbol(), parents, body); - return gen.ClassDef(clasz, impl); - } - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - return Tree.Empty; // eliminate - case Typed(Tree expr, _): - return transform(expr); // eliminate - case DefDef(_, _, _, _, _, _): - Symbol backup = this.method; - this.method = tree.symbol(); - tree = super.transform(tree); - this.method = backup; - return tree; - case Ident(_): - Symbol symbol = tree.symbol(); - if (!symbol.owner().isPrimaryConstructor()) break; - if (symbol.owner() == this.method) break; - Symbol method = (Symbol)methods.get(symbol); - if (method == null) method = createAccessorMethod(symbol); - Tree qualifier = gen.This(tree.pos, method.owner()); - return gen.Apply(gen.Select(tree.pos, qualifier, method)); - } - return super.transform(tree); - } - - }; - - //######################################################################## -} diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java deleted file mode 100644 index 5440c68ebf..0000000000 --- a/sources/scalac/transformer/AddConstructors.java +++ /dev/null @@ -1,295 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.util.ArrayList; -import java.util.HashMap; - -import scalac.Global; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This phase adds to all classes one initializer method per - * constructor. Initializers have the same value parameters as their - * corresponding constructor but no type parameters. - * - * An initializer may be used in the body of another initializer - * either to invoke another initializer of the same class or to invoke - * an initailizer of the superclass. In that case, the initializer - * must appear in a Select node whose qualifier is either a This node - * or a Super node. The type of such a Select node is the type of the - * initializer. - * - * An initializer may also be used in a new operation. In that case, - * the initializer must appear in an Ident node. The type of such an - * Ident node is a PolyType whose arguments are the type arguments of - * the initializer's class and whose result type is the initializer's - * type. - * - * This phase does the following in the tree: - * - * - replaces all non-primary constructors definitions by initializer - * definitions with the same body, - * - * - for each non-interface class creates an primary initializer - * method corresponding to the primary constructor, - * - * - moves the call to the super constructor into the primary - * initializer, - * - * - moves all class fields initialization code (rhs of ValDefs) into - * the primary initializer, - * - * - moves all class-level expressions into the primary initializer, - * - * - replaces all constructor invocations by initializer invocations, - * except in the parents field of class templates. - * - * @author Nikolay Mihaylov - * @version 1.2 - */ -public class AddConstructors extends GenTransformer { - - /** A constructor to initializer map */ - private final HashMap/*<Symbol,Symbol>*/ initializers; - - /** A constructor to initializer parameter substitution */ - private final SymbolSubstTypeMap subst; - - /** The current primary initializer or null */ - private Symbol primaryInitializer; - - /** - * ... - * - * @param global - * @param initializers - */ - public AddConstructors(Global global, HashMap initializers) { - super(global); - this.initializers = initializers; - this.subst = new SymbolSubstTypeMap(); - } - - /** - * Returns the initializer corresponding to the given constructor. - * - * @param constructor - * @return - */ - private Symbol getInitializer(Symbol constructor) { - assert constructor.isConstructor(): Debug.show(constructor); - Symbol initializer = (Symbol)initializers.get(constructor); - if (initializer == null) { - assert !constructor.constructorClass().isInterface(): - "found interface constructor " + Debug.show(constructor); - int flags = constructor.isPrivate() - ? (constructor.flags & ~Modifiers.PRIVATE) | Modifiers.PROTECTED - : constructor.flags; - initializer = constructor.constructorClass().newMethod( - constructor.pos, - flags & Modifiers.ACCESSFLAGS, - constructor.name); - initializer.setInfo( - Type.MethodType( - constructor.valueParams(), - global.definitions.void_TYPE()) - .cloneType(constructor, initializer)); - initializer.owner().members().enterOrOverload(initializer); - initializers.put(constructor, initializer); - } - return initializer; - } - - /** - * Process the tree. - */ - public Tree transform(Tree tree) { - return transform(tree, false); - } - - /** - * ... - * - * @param tree - * @param inNew - * @return - */ - private Tree transform(Tree tree, boolean inNew) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): - Symbol clasz = tree.symbol(); - - if (clasz.isInterface()) - return gen.ClassDef(clasz, transform(impl.body)); - - // expressions that go before the call to the super constructor - final ArrayList constrBody = new ArrayList(); - - // expressions that go after the call to the super constructor - final ArrayList constrBody2 = new ArrayList(); - - // the body of the class after the transformation - final ArrayList classBody = new ArrayList(); - - Symbol local = impl.symbol(); - for (int i = 0; i < impl.body.length; i++) { - Tree member = impl.body[i]; - if (member.definesSymbol() && member.symbol().owner()!=local) { - switch (member) { - case ValDef(_, _, _, Tree rhs): - // move initialization code into initializer - Symbol field = member.symbol(); - if (rhs == Tree.Empty) break; - member = gen.ValDef(field, Tree.Empty); - Tree assign = gen.Assign( - gen.Select(gen.This(member.pos, clasz),field),rhs); - if (rhs.hasSymbol() && rhs.symbol().isParameter()) { - constrBody.add(assign); - } else { - constrBody2.add(assign); - } - } - classBody.add(member); - } else { - // move class-level code into initializer - constrBody2.add(member); - } - } - - // inline the call to the super constructor - for (int i = 0; i < impl.parents.length; i++) { - switch (impl.parents[i]) { - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] args): - assert fun.symbol().isConstructor(): impl.parents[i]; - if (fun.symbol().constructorClass().isInterface()) continue; - int pos = impl.parents[i].pos; - Tree superConstr = gen.Select - (gen.Super(pos, clasz), getInitializer(fun.symbol())); - constrBody.add(gen.mkApply_V(superConstr, args)); - break; - case Apply(Tree fun, Tree[] args): - assert fun.symbol().isConstructor(): impl.parents[i]; - if (fun.symbol().constructorClass().isInterface()) continue; - int pos = impl.parents[i].pos; - Tree superConstr = gen.Select - (gen.Super(pos, clasz), getInitializer(fun.symbol())); - constrBody.add(gen.mkApply_V(superConstr, args)); - break; - default: - throw Debug.abort("illegal case", impl.parents[i]); - } - } - - // add valdefs and class-level expression to the constructor body - constrBody.addAll(constrBody2); - - Tree constrTree = gen.mkUnitBlock( - clasz.primaryConstructor().pos, - (Tree[])constrBody.toArray(new Tree[constrBody.size()])); - - classBody.add(gen.DefDef(clasz.primaryConstructor(), constrTree)); - - Tree[] newBody = (Tree[]) classBody.toArray(Tree.EMPTY_ARRAY); - - // transform the bodies of all members in order to substitute - // the constructor references with the new ones - return gen.ClassDef(clasz, transform(newBody)); - - case DefDef(_, _, _, _, _, Tree rhs): - if (!tree.symbol().isConstructor()) return super.transform(tree); - // replace constructor by initializer - Symbol constructor = tree.symbol(); - Symbol initializer = getInitializer(constructor); - subst.insertSymbol( - constructor.typeParams(), - constructor.constructorClass().typeParams()); - subst.insertSymbol( - constructor.valueParams(), - initializer.valueParams()); - if (constructor.isPrimaryConstructor()) - primaryInitializer = initializer; - rhs = transform(rhs); - primaryInitializer = null; - subst.removeSymbol(constructor.valueParams()); - subst.removeSymbol(constructor.typeParams()); - // add consistent result expression - rhs = gen.mkUnitBlock(rhs); - return gen.DefDef(initializer, rhs); - - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol symbol = tree.symbol(); - if (symbol.owner().isConstructor()) { - // update symbols like x in these examples - // ex 1: class C { { val x = ...; ... } } - // ex 2: class C { def this(i: Int) { val x = i; ... } } - symbol.setOwner(getInitializer(symbol.owner())); - symbol.updateInfo(subst.apply(symbol.info())); - } - return super.transform(tree); - - case New(Tree init): - return gen.New(transform(init, true)); - - case TypeApply(Tree fun, Tree[] args): - if (!fun.symbol().isConstructor()) return super.transform(tree); - if (!inNew) return transform(fun); - assert fun instanceof Tree.Ident: tree; - return transform(tree, fun.symbol(), transform(args)); - - case Apply(Tree fun, Tree[] args): - return gen.Apply(transform(fun, inNew), transform(args)); - - case Ident(_): - Symbol symbol = tree.symbol(); - if (inNew) return transform(tree, symbol, Tree.EMPTY_ARRAY); - if (symbol.isConstructor()) { - symbol = getInitializer(symbol); - Symbol clasz = symbol.owner(); - return gen.Select(gen.This(tree.pos, clasz), symbol); - } - else if (symbol.owner().isConstructor()) { - symbol = subst.lookupSymbol(symbol); - } - return gen.Ident(tree.pos, symbol); - - case TypeTerm(): - return gen.TypeTerm(tree.pos, subst.apply(tree.getType())); - - default: - return super.transform(tree); - } // switch(tree) - - } // transform() - - /** - * Transforms the new instance creation. - * - * @param tree - * @param constructor - * @param targs - * @return - */ - private Tree transform(Tree tree, Symbol constructor, Tree[] targs) { - assert constructor.isConstructor(): tree; - Symbol initializer = getInitializer(constructor); - Symbol clasz = initializer.owner(); - Tree instance = gen.Create(tree.pos, Tree.Empty, clasz, targs); - return gen.Select(tree.pos, instance, initializer); - } - -} // class AddConstructors diff --git a/sources/scalac/transformer/AddConstructorsPhase.java b/sources/scalac/transformer/AddConstructorsPhase.java deleted file mode 100644 index 1dfb10e344..0000000000 --- a/sources/scalac/transformer/AddConstructorsPhase.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -//package scala.compiler.backend; -package scalac.transformer; - -import java.util.HashMap; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -public class AddConstructorsPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from old constructor symbols to new ones */ - private final HashMap/*<Symbol,Symbol>*/ constructors = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AddConstructorsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - if (symbol.isConstructor()) { - switch (type) { - case PolyType(Symbol[] tparams, MethodType(_, Type result)): - result = Type.MethodType(Symbol.EMPTY_ARRAY, result); - return Type.PolyType(tparams, result); - case MethodType(_, Type result): - return Type.MethodType(Symbol.EMPTY_ARRAY, result); - default: - throw Debug.abort("illegal case", type); - } - } - return type; - } - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - new AddConstructors(global, constructors).apply(unit); - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java deleted file mode 100644 index 1e922a8165..0000000000 --- a/sources/scalac/transformer/AddInterfaces.java +++ /dev/null @@ -1,304 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// TODO find a good way to change symbol flags (PRIVATE, DEFERRED, -// INTERFACE). In particular find how to make sure that the -// modifications are not made too early, for example before the symbol -// is cloned. - -package scalac.transformer; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeGen; -import scalac.ast.TreeList; -import scalac.symtab.Type; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.util.Debug; - -/** - * Add, for each class, an interface with the same name, to be used - * later by mixin expansion. More specifically: - * - * - at the end of the name of every class, the string "$class" is - * added, - * - * - an interface with the original name of the class is created, and - * contains all directly bound members of the class (as abstract - * members), - * - * - the interface is added to the mixin base classes of the class. - * - * @author Michel Schinz - * @version 1.0 - */ -public class AddInterfaces extends GenTransformer { - - //######################################################################### - // Private Fields - - /** The AddInterface phase */ - private final AddInterfacesPhase phase; - - /** The current class (null is none) */ - private Symbol clasz; - - /** The current member (null is none) */ - private Symbol member; - - /** The current class substitution (null is none) */ - private Type.Map classSubst; - - /** The current parameter substitution (null is none) */ - private SymbolSubstTypeMap paramSubst; - - //######################################################################### - // Public Constructors - - /** Initializes this instance. */ - public AddInterfaces(Global global, AddInterfacesPhase phase) { - super(global); - this.phase = phase; - } - - //######################################################################### - // Public Methods - - /** Transforms the given symbol. - * - * @param tree - * @return - */ - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case Create(_, _): - return phase.getClassSymbol(tree.symbol()); - case Return(_): - return member; - case This(_): - case Super(_, _): - return clasz; - case Select(Super(_, _), _): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - return getClassMember(symbol, true); - case Select(_, _): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - return symbol; - case Ident(_): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - if (symbol.isParameter() && !symbol.owner().isStatic()) - return getClassVParam(symbol); - return symbol; - default: - return tree.symbol(); - } - } - - /** Transforms the given type. */ - public Type transform(Type type) { - if (classSubst != null) type = classSubst.apply(type); - if (paramSubst != null) type = paramSubst.apply(type); - return type; - } - - /** Transforms the given trees. */ - public Tree[] transform(Tree[] trees) { - if (member != null) return super.transform(trees); - TreeList list = new TreeList(); - for (int i = 0; i < trees.length; i++) template(list, trees[i]); - return list.toArray(); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol symbol = tree.symbol(); - if (symbol.owner() != member) { - symbol.updateInfo(transform(symbol.info())); - symbol.setOwner(member); - } - return super.transform(tree); - case Select(Tree qualifier, _): - Type prefix = qualifier.type(); - qualifier = transform(qualifier); - Symbol symbol = getSymbolFor(tree); - if (symbol.isJava() && !symbol.owner().isInterface()) { - if (qualifier.type().widen().symbol().isInterface()) { - Type baseType = prefix.baseType(symbol.owner()); - assert baseType != Type.NoType: tree; - qualifier = gen.mkAsInstanceOf(qualifier, baseType); - } - } - return gen.Select(tree.pos, qualifier, symbol); - default: - return super.transform(tree); - } - } - - //######################################################################### - // Private Methods - - /** Transforms the given template and adds it to given list. - * - * @param trees - * @param tree - */ - private void template(TreeList trees, Tree tree) { - switch (tree) { - case Empty: - return; - case PackageDef(_, _): - trees.append(super.transform(tree)); - return; - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - TreeList list = new TreeList(transform(body)); - this.clasz = tree.symbol(); - Map methods = new HashMap(); - if (phase.needInterface(clasz)) { - Symbol clone = phase.getClassSymbol(clasz); - trees.append(getClassTree(clasz, list, methods)); - list = new TreeList(); - this.classSubst = new Type.SubstThisMap(clasz, clone); - this.paramSubst = phase.getClassSubst(clone); - this.clasz = clone; - } - for (int i = 0; i < body.length; i++) member(methods, body[i]); - trees.append(getClassTree(clasz, list, methods)); - assert methods.isEmpty(): Debug.show(methods.keySet().toArray()); - this.paramSubst = null; - this.classSubst = null; - this.clasz = null; - return; - case DefDef(_, _, _, _, _, _): - case ValDef(_, _, _, _): - return; - default: - throw Debug.abort("illegal tree", tree); - } - } - - /** - * Transforms the given class member. Methods with a non-empty - * body are added to the given method map. All other members are - * dropped. - * - * @param methods - * @param tree - */ - private void member(Map methods, Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - return; - case DefDef(_, _, _, _, _, Tree rhs): - if (rhs == Tree.Empty) return; - Symbol symbol = tree.symbol(); - this.member = getClassMember(symbol); - if (member != symbol) { - paramSubst.insertSymbol( - symbol.typeParams(), member.nextTypeParams()); - paramSubst.insertSymbol( - symbol.valueParams(), member.nextValueParams()); - } - methods.put(member, gen.DefDef(member, transform(rhs))); - if (member != symbol) { - paramSubst.removeSymbol(symbol.valueParams()); - paramSubst.removeSymbol(symbol.typeParams()); - } - this.member = null; - return; - case ValDef(_, _, _, Tree rhs): - assert rhs == Tree.Empty: tree; - return; - default: - throw Debug.abort("illegal tree", tree); - } - } - - /** - * Returns the tree of the given class. Its body is built by - * adding its members to the provided body. Non-abstract methods - * are removed from the provided method map. All other members are - * generated from their symbol. - * - * @param clasz - * @param body - * @param methods - * @return - */ - private Tree getClassTree(Symbol clasz, TreeList body, Map methods) { - Scope members = clasz.nextInfo().members(); - for (Scope.SymbolIterator i = members.iterator(); i.hasNext(); ) { - Symbol member = i.next(); - if (!member.isTerm()) continue; - body.append(getMemberTree(clasz, member, methods)); - } - Tree[] array = body.toArray(); - if (!clasz.isInterface()) phase.classToBody.put(clasz, array); - return gen.ClassDef(clasz, array); - } - - /** - * Returns the tree of the given member. Non-abstract methods are - * removed from the given method map. All other members are - * generated from their symbol. - * - * @param clasz - * @param member - * @param methods - * @return - */ - private Tree getMemberTree(Symbol clasz, Symbol member, Map methods) { - if (!member.isMethod()) return gen.ValDef(member, Tree.Empty); - if (member.isDeferred()) return gen.DefDef(member, Tree.Empty); - Tree method = (Tree)methods.remove(member); - assert method != null: Debug.show(clasz + "." + member + ":" + member.info() + member.locationString()); - return method; - } - - /** Returns the symbol of given parameter in current class. - * - * @param vparam - * @return - */ - private Symbol getClassVParam(Symbol vparam) { - if (paramSubst == null) return vparam; - Symbol clone = (Symbol)paramSubst.lookupSymbol(vparam); - assert clone != null: Debug.show(vparam, clasz, member); - return clone; - } - - /** Returns the symbol of given member in current class. */ - private Symbol getClassMember(Symbol member) { - return getClassMember(member, false); - } - // !!! Try to remove version with lazy argument. It is currently - // needed for super calls to abstract method (possible in mixins). - private Symbol getClassMember(Symbol member, boolean lazy) { - Symbol owner = member.owner(); - assert owner.isClass(): Debug.show(member); - if (!phase.needInterface(owner)) return member; - Symbol clasz = phase.getClassSymbol(owner); - Symbol clone = (Symbol)phase.getClassMemberMap(clasz).get(member); - assert clone != null || lazy: Debug.show(member, " not in ", clasz); - return clone != null ? clone : member; - } - - //######################################################################### -} diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java deleted file mode 100644 index 026ac5feda..0000000000 --- a/sources/scalac/transformer/AddInterfacesPhase.java +++ /dev/null @@ -1,313 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// TODO try to use setInfo instead of updateInfo for cloned symbols, -// to avoid the need to use nextPhase/nextInfo. - -package scalac.transformer; - -import java.util.HashMap; -import java.util.Map; - -import scalac.*; -import scalac.symtab.*; -import scalac.util.Debug; -import scalac.util.Name; - -public class AddInterfacesPhase extends Phase { - - /** Initializes this instance. */ - public AddInterfacesPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - new AddInterfaces(global, this).apply(unit); - } - - public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor() || sym.owner().isConstructor()) { - return tp; - } else if (sym.isClass() && !sym.isJava()) { - Definitions definitions = global.definitions; - if (sym == definitions.ANY_CLASS) return tp; - Type[] oldParents = tp.parents(); - assert oldParents.length > 0 : Debug.show(sym); - for (int i = 1; i < oldParents.length; ++i) { - Symbol oldSym = oldParents[i].symbol(); - assert !oldSym.isJava() || oldSym.isInterface() : - Debug.show(sym) + " <: " + Debug.show(oldSym); - } - - boolean ifaceReqrd = needInterface(sym); - Type[] newParents; - Scope newMembers = new Scope(); - - Scope.SymbolIterator oldMembersIt = - tp.members().iterator(); - while (oldMembersIt.hasNext()) { - Symbol member = oldMembersIt.next(); - - if (ifaceReqrd - && (member.isInitializer() || !memberGoesInInterface(member))) - continue; - - if (member.isPrivate() && !member.isClass()) { - member.name = uniqueName(member); - member.flags ^= Modifiers.PRIVATE; - } else if (member.isProtected()) - member.flags ^= Modifiers.PROTECTED; - - newMembers.enterOrOverload(member); - } - - if (ifaceReqrd) { - // Before this phase, the symbol is a class, but after - // it will be an interface. Its type has to be changed - // so that: - // - // 1. Java classes are removed from its parents, - // - // 2. only members which will end up in the - // interface are kept, and private ones are made - // public and renamed. - sym.flags |= Modifiers.INTERFACE; - newParents = oldParents; - } else { - // The symbol is the one of a class which doesn't need - // an interface. We need to fix its parents to use - // class symbols instead of interface symbols. - newParents = new Type[oldParents.length]; - for (int i = 0; i < oldParents.length; ++i) { - switch (oldParents[i]) { - case TypeRef(Type pre, Symbol oldSym, Type[] args): - newParents[i] = !needInterface(oldSym) - ? oldParents[i] - : Type.typeRef(pre, getClassSymbol(oldSym), args); - break; - default: - throw Debug.abort("illegal case", oldParents[i]); - } - } - } - - return Type.compoundType(newParents, newMembers, sym); - } else if (sym.owner().isClass() || sym.isParameter()) { - getClassSymbol(sym.enclClass()); - return sym.info(); - } else - return tp; - } - - protected boolean memberGoesInInterface(Symbol member) { - return !member.isStatic() && (member.isType() || member.isMethod()); - } - - protected final SymbolNameWriter uniqueNameWriter = new SymbolNameWriter() - .setAllSeparators('$') - .setRootSeparator('\0'); - protected Name uniqueName(Symbol sym) { - Name name = Name.fromString(uniqueNameWriter.toString(sym)); - return sym.name.isTypeName() ? name.toTypeName() : name; - } - - // Terminology: in the following code, the symbol which was used - // until this phase for the class, and will now be used for the - // interface is called the "interface symbol". The symbol created - // by this phase for the class is called the "class symbol". - - /** True iff the given class symbol needs an interface. */ - protected boolean needInterface(Symbol classSym) { - assert classSym.isClass() - : Debug.show(classSym) + " is not a class (kind " + classSym.kind + ")"; - return !(classSym.isJava() - || classSym.isModuleClass() - || classSym.isAnonymousClass() - || hasInterfaceSymbol(classSym) - || classSym == global.definitions.ANY_CLASS - || classSym == global.definitions.ANYREF_CLASS - || classSym == global.definitions.ALL_CLASS - || classSym == global.definitions.ALLREF_CLASS); - } - - protected final static String CLASS_SUFFIX = "$class"; - protected Name className(Name ifaceName) { - Name className = Name.fromString(ifaceName.toString() + CLASS_SUFFIX); - if (ifaceName.isTypeName()) return className.toTypeName(); - else return className; - } - - protected final HashMap/*<Symbol,Symbol>*/ ifaceToClass = new HashMap(); - protected final HashMap/*<Symbol,Symbol>*/ classToIFace = new HashMap(); - protected final HashMap/*<Symbol,Tree[]>*/ classToBody = new HashMap(); - - /** Return the class symbol corresponding to the given interface - * symbol. If the class does not need an interface, return the - * given symbol. - * - * @param ifaceSym - * @return - */ - protected Symbol getClassSymbol(Symbol ifaceSym) { - assert ifaceSym.isClass(): Debug.show(ifaceSym); - if (!needInterface(ifaceSym)) - return ifaceSym; - - Symbol classSym = (Symbol)ifaceToClass.get(ifaceSym); - if (classSym == null) { - classSym = ifaceSym.cloneSymbol(ifaceSym.owner()); - classSym.name = className(ifaceSym.name); - ifaceSym.flags &= ~Modifiers.FINAL; - classSym.flags &= ~Modifiers.INTERFACE; - - Scope ifaceOwnerMembers = ifaceSym.owner().members(); - ifaceOwnerMembers.enter(classSym); - - Type.SubstThisMap thisTypeMap = - new Type.SubstThisMap(ifaceSym, classSym); - - // Create class substitution map. - SymbolSubstTypeMap classSubst = newClassSubst(classSym); - Map classMemberMap = newClassMemberMap(classSym); - - Symbol[] ifaceTParams = ifaceSym.typeParams(); - Symbol[] classTParams = classSym.typeParams(); - classSubst.insertSymbol(ifaceTParams, classTParams); - - // Clone all members, entering them in the class scope. - Scope classMembers = new Scope(); - Scope.SymbolIterator ifaceMembersIt = - ifaceSym.members().iterator(); - while (ifaceMembersIt.hasNext()) { - Symbol ifaceMemberSym = ifaceMembersIt.next(); - - if (ifaceMemberSym.isType() - || ifaceMemberSym.isDeferred()) - continue; - - Symbol classMemberSym; - if (memberGoesInInterface(ifaceMemberSym)) { - if (ifaceMemberSym.isPrivate()) { - ifaceMemberSym.name = uniqueName(ifaceMemberSym); - ifaceMemberSym.flags |= Modifiers.FINAL; - ifaceMemberSym.flags ^= Modifiers.PRIVATE; - } else if (ifaceMemberSym.isProtected()) - ifaceMemberSym.flags ^= Modifiers.PROTECTED; - - classMemberSym = ifaceMemberSym.cloneSymbol(classSym); - ifaceMemberSym.flags &= ~Modifiers.FINAL; - classMemberSym.setInfo( - thisTypeMap.applyParams( - classSubst.applyParams( - classMemberSym.info().cloneType( - ifaceMemberSym, classMemberSym)))); - - ifaceMemberSym.flags |= Modifiers.DEFERRED; - } else { - // Member doesn't go in interface, we just make it - // owned by the class. - classMemberSym = ifaceMemberSym; - - // [HACK] the following forces the evaluation of - // the type of all value parameters, which might - // otherwise become invalid once the owner is - // changed. - classMemberSym.info(); - if (classMemberSym.isMethod()) { - Symbol[] vp = classMemberSym.valueParams(); - for (int i = 0; i < vp.length; ++i) - vp[i].info(); - } - - classMemberSym.setOwner(classSym); - classMemberSym.updateInfo( - thisTypeMap.apply( - classSubst.apply( - classMemberSym.info()))); - } - - classMemberMap.put(ifaceMemberSym, classMemberSym); - classMembers.enterOrOverload(classMemberSym); - } - - // Give correct type to the class symbol by using class - // symbols for its parents, and by adding the interface - // among them. - Type[] oldClassParents = classSym.parents(); - int oldParentsCount = oldClassParents.length; - Type[] newClassParents = new Type[oldParentsCount + 1]; - for (int i = 0; i < oldParentsCount; ++i) { - switch (oldClassParents[i]) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Type newTp = Type.typeRef(pre, getClassSymbol(sym), args); - newClassParents[i] = classSubst.apply(newTp); - break; - default: - throw Debug.abort("unexpected type for parent", oldClassParents[i]); - } - } - newClassParents[oldParentsCount] = classSubst.apply(ifaceSym.type()); - // TODO setInfo cannot be used here because the type then - // goes through transformInfo. Maybe setInfo should behave - // like updateInfo. - classSym.updateInfo(Type.compoundType(newClassParents, - classMembers, - classSym)); - ifaceToClass.put(ifaceSym, classSym); - classToIFace.put(classSym, ifaceSym); - - // move attributes to the implementing class - AttributeInfo attr = global.removeAttributes(ifaceSym); - if (attr != null) { - global.setAttribute(classSym, attr); - } - } - return classSym; - } - - public boolean hasInterfaceSymbol(Symbol classSym) { - return classToIFace.containsKey(classSym); - } - - public Symbol getInterfaceSymbol(Symbol classSym) { - return (Symbol)classToIFace.get(classSym); - } - - HashMap/*<Symbol,SymbolSubstTypeMap>*/ classSubstitutions = new HashMap(); - protected SymbolSubstTypeMap newClassSubst(Symbol classSym) { - SymbolSubstTypeMap subst = new SymbolSubstTypeMap(); - classSubstitutions.put(classSym, subst); - return subst; - } - - /** Return symbol substitution for the class (a mapping from the - * interface's type and value parameters to the class' equivalent) - */ - public SymbolSubstTypeMap getClassSubst(Symbol classSym) { - SymbolSubstTypeMap classSubst = - (SymbolSubstTypeMap)classSubstitutions.get(classSym); - assert classSubst != null; - return classSubst; - } - - HashMap/*<Symbol, HashMap>*/ classMemberMaps = new HashMap(); - protected HashMap newClassMemberMap(Symbol classSym) { - HashMap map = new HashMap(); - classMemberMaps.put(classSym, map); - return map; - } - - /** Return symbol substitution for the class (a mapping from the - * interface's type and value parameters to the class' equivalent) - */ - public Map getClassMemberMap(Symbol classSym) { - return (Map)classMemberMaps.get(classSym); - } - -} diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java deleted file mode 100644 index 67a462b1f4..0000000000 --- a/sources/scalac/transformer/Erasure.java +++ /dev/null @@ -1,759 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Erasure.java,v 1.48 2003/01/16 14:21:19 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.ast.Tree.AbsTypeDef; -import scalac.ast.Tree.AliasTypeDef; -import scalac.ast.Tree.ValDef; -import scalac.ast.TreeList; -import scalac.ast.GenTransformer; -import scalac.atree.AConstant; -import scalac.symtab.Definitions; -import scalac.symtab.Kinds; -import scalac.symtab.Type; -import scalac.symtab.TypeTags; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.SymSet; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolTablePrinter; -import scalac.backend.Primitive; -import scalac.backend.Primitives; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -/** A transformer for type erasure and bridge building - * - * @author Martin Odersky - * @version 1.0 - * - * What it does: - * (1) Map every type to its erasure. - * (2) If method A overrides a method B, and the erased type ETA of A is - * different from the erased type ETB of B seen as a member of A's class, - * add a bridge method with the same name as A,B, with signature ETB - * which calls A after casting parameters. - */ -public class Erasure extends GenTransformer implements Modifiers { - - //######################################################################## - // Private Constants - - /** The unboxed types */ - private static final Type - UNBOXED_UNIT = Type.unboxedType(TypeTags.UNIT), - UNBOXED_BOOLEAN = Type.unboxedType(TypeTags.BOOLEAN), - UNBOXED_BYTE = Type.unboxedType(TypeTags.BYTE), - UNBOXED_SHORT = Type.unboxedType(TypeTags.SHORT), - UNBOXED_CHAR = Type.unboxedType(TypeTags.CHAR), - UNBOXED_INT = Type.unboxedType(TypeTags.INT), - UNBOXED_LONG = Type.unboxedType(TypeTags.LONG), - UNBOXED_FLOAT = Type.unboxedType(TypeTags.FLOAT), - UNBOXED_DOUBLE = Type.unboxedType(TypeTags.DOUBLE); - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The global primitives */ - private final Primitives primitives; - - /** The current unit */ - private CompilationUnit unit; - - private final boolean forMSIL; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Erasure(Global global) { - super(global); - this.definitions = global.definitions; - this.primitives = global.primitives; - this.forMSIL = global.target == global.TARGET_MSIL; - } - - //######################################################################## - // Public Methods - - /** Transforms the given unit. */ - public void apply(CompilationUnit unit) { - this.unit = unit; - super.apply(unit); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - Symbol clasz = tree.symbol(); - TreeList members = new TreeList(transform(body)); - addBridges(clasz, members); - return gen.ClassDef(clasz, members.toArray()); - - case ValDef(_, _, _, Tree rhs): - Symbol field = tree.symbol(); - if (rhs != Tree.Empty) rhs = transform(rhs, field.nextType()); - return gen.ValDef(field, rhs); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol method = tree.symbol(); - if (rhs != Tree.Empty) - rhs = transform(rhs, method.nextType().resultType()); - return gen.DefDef(method, rhs); - - case LabelDef(_, Ident[] params, Tree body): - Symbol label = tree.symbol(); - body = transform(body, label.nextType().resultType()); - return gen.LabelDef(label, Tree.symbolOf(params), body); - - case Assign(Tree lhs, Tree rhs): - lhs = transform(lhs); - rhs = transform(rhs, lhs.type); - return gen.Assign(tree.pos, lhs, rhs); - - case Return(Tree expr): - Symbol method = tree.symbol(); - Type type = method.nextType().resultType(); - return gen.Return(tree.pos, method, transform(expr, type)); - - case New(Tree init): - if (tree.getType().symbol() == definitions.ARRAY_CLASS) { - switch (init) { - case Apply(_, Tree[] args): - assert args.length == 1: tree; - Type element = getArrayElementType(tree.getType()).erasure(); - Tree size = transform(args[0]); - return genNewUnboxedArray(tree.pos, element, size); - default: - throw Debug.abort("illegal case", tree); - } - } - return gen.New(tree.pos, transform(init)); - - case Create(_, _): - return gen.Create(tree.pos, Tree.Empty, tree.symbol()); - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - fun = transform(fun); - vargs = transform(vargs); - Symbol symbol = fun.symbol(); - if (symbol == definitions.ANY_AS_ERASED) { - assert targs.length == 1 && vargs.length == 0: tree; - return coerce(getQualifier(fun), targs[0].getType().erasure()); - } - if (symbol == definitions.ANY_IS_ERASED) { - assert targs.length == 1 && vargs.length == 0: tree; - Type type = targs[0].type.erasure(); - if (isUnboxedSimpleType(type)) type = targs[0].type; - return gen.mkIsInstanceOf(tree.pos, getQualifier(fun), type); - } - return genApply(tree.pos, fun, vargs); - - case Apply(Tree fun, Tree[] vargs): - fun = transform(fun); - vargs = transform(vargs); - switch (fun) { - case Select(Apply(Tree bfun, Tree[] bargs), _): - Symbol bsym = bfun.symbol(); - if (primitives.getPrimitive(bsym) != Primitive.BOX) break; - assert bargs.length == 1: fun; - switch (primitives.getPrimitive(fun.symbol())) { - case COERCE: - assert vargs.length == 0: tree; - Tree value = bargs[0]; - return coerce(value, fun.type().resultType()); - case LENGTH: - assert vargs.length == 0: tree; - Tree array = bargs[0]; - return genUnboxedArrayLength(tree.pos, array); - case APPLY: - assert vargs.length == 1: tree; - Tree array = bargs[0]; - Tree index = vargs[0]; - return genUnboxedArrayGet(tree.pos, array, index); - case UPDATE: - assert vargs.length == 2: tree; - Tree array = bargs[0]; - Tree index = vargs[0]; - Tree value = vargs[1]; - return genUnboxedArraySet(tree.pos, array, index, value); - } - } - return genApply(tree.pos, fun, vargs); - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - Type prefix = qualifier.type().baseType(symbol.owner()).erasure(); - assert prefix != Type.NoType: tree + " -- " + Debug.show(symbol); - qualifier = transform(qualifier); - qualifier = coerce(qualifier, prefix); - - // Might end up with "box(unbox(...))". That's needed by backend. - if (isUnboxedType(prefix)) qualifier = box(qualifier, true); - return gen.Select(tree.pos, qualifier, symbol); - - case Literal(AConstant.ZERO): - return gen.mkNullLit(tree.pos); - - case Block(_, _): - case If(_, _, _): - case Switch(_, _, _, _): - return transform(tree, tree.getType().fullErasure()); - - default: - return super.transform(tree); - } - } - - //######################################################################## - // Private Methods - Tree transformation - - /** Transforms the given trees with given prototype. */ - private Tree[] transform(Tree[] trees, Type pt) { - for (int i = 0; i < trees.length; i++) { - Tree tree = transform(trees[i], pt); - if (tree == trees[i]) continue; - Tree[] array = new Tree[trees.length]; - for (int j = 0; j < i ; j++) array[j] = trees[j]; - array[i] = tree; - while (++i < trees.length) array[i] = transform(trees[i], pt); - return array; - } - return trees; - } - - /** Transforms the given tree with given prototype. */ - private Tree transform(Tree tree, Type pt) { - switch (tree) { - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, transform(stats), transform(value, pt)); - - case If(Tree cond, Tree thenp, Tree elsep): - cond = transform(cond, UNBOXED_BOOLEAN); - thenp = transform(thenp, pt); - elsep = transform(elsep, pt); - return gen.If(tree.pos, cond, thenp, elsep, pt); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - test = transform(test, UNBOXED_INT); - bodies = transform(bodies, pt); - otherwise = transform(otherwise, pt); - return gen.Switch(tree.pos, test, tags, bodies, otherwise, pt); - - case Return(_): - // !!! why do we build a block here? - Tree value = transform(gen.mkDefaultValue(tree.pos, pt), pt); - return gen.mkBlock(transform(tree), value); - - case LabelDef(_, _, _): - case Assign(_, _): - case New(_): - case Apply(_, _): - case Super(_, _): - case This(_): - case Select(_, _): - case Ident(_): - case Literal(_): - return coerce(transform(tree), pt); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Transforms Unit literal with given prototype. */ - private Tree transformUnit(int pos, Type pt) { - Tree unit = pt.isSameAs(UNBOXED_UNIT) - ? gen.mkUnitLit(pos) - : gen.mkApply__(gen.mkGlobalRef(pos, primitives.BOX_UVALUE)); - return coerce(unit, pt); - } - - /** Coerces the given tree to the given type. */ - private Tree coerce(Tree tree, Type pt) { - if (isSubType(tree.type(), pt)) { - if (tree.type().symbol() == definitions.ARRAY_CLASS) { - if (pt.symbol() != definitions.ARRAY_CLASS) { - Symbol symbol = primitives.UNBOX__ARRAY; - Tree unboxtree = gen.mkGlobalRef(tree.pos, symbol); - tree = gen.mkApply_V(unboxtree, new Tree[] {tree}); - return coerce(tree, pt); - } - } - return tree; - } - if (isUnboxedSimpleType(tree.type())) { - if (isUnboxedSimpleType(pt)) return convert(tree, pt); - Type to = pt.erasure(); - if (!isUnboxedSimpleType(to) || isSameAs(to, tree.type())) - return box(tree); - else - return coerce(convert(tree, to), pt); - } else if (isUnboxedArrayType(tree.type())) { - if (!isUnboxedArrayType(pt)) return check(box(tree), pt); - } else if (isUnboxedSimpleType(pt)) { - Type from = tree.type().erasure(); - if (isUnboxedSimpleType(from)) - return convert(unbox(tree, from), pt); - else - return unbox(coerce(tree, boxUnboxedType(pt)), pt); - } else if (isUnboxedArrayType(pt)) { - if (tree.type.symbol() == definitions.ARRAY_CLASS) - return coerce(unbox(tree, pt), pt); - } else if (pt.symbol() == definitions.ARRAY_CLASS) { - Tree boxtree = gen.mkGlobalRef(tree.pos, primitives.BOX__ARRAY); - return gen.mkApply_V(boxtree, new Tree[]{tree}); - } - return gen.mkAsInstanceOf(tree, pt); - } - - /** Checks that the given tree is of the given type. */ - private Tree check(Tree tree, Type pt) { - assert isSubType(tree.type(), pt): tree +" - "+ tree.type() +" - "+pt; - return tree; - } - - - /** Boxes the given tree. */ - private Tree box(Tree tree) { - return box(tree, false); - } - - /** Boxes the given tree. */ - private Tree box(Tree tree, boolean force) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (primitives.getPrimitive(fun.symbol()) == Primitive.UNBOX) { - assert args.length == 1: tree; - if (!force) return args[0]; - } - } - Symbol symbol = primitives.getBoxValueSymbol(tree.getType()); - Tree boxtree = gen.mkGlobalRef(tree.pos, symbol); - return tree.getType().equals(UNBOXED_UNIT) - ? gen.mkBlock(tree, gen.mkApply__(boxtree)) - : gen.mkApply_V(boxtree, new Tree[]{tree}); - } - - /** Unboxes the given tree to the given type. */ - private Tree unbox(Tree tree, Type pt) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (primitives.getPrimitive(fun.symbol()) == Primitive.BOX) { - assert args.length == 1: tree; - return args[0]; - } - } - Symbol symbol = primitives.getUnboxValueSymbol(pt); - return gen.mkApply_V( - gen.mkGlobalRef(tree.pos, symbol), new Tree[]{tree}); - } - - /** Converts the given tree to the given type. */ - private Tree convert(Tree tree, Type to) { - Symbol symbol = primitives.getConvertSymbol(tree.type(), to); - return gen.mkApply_V( - gen.mkGlobalRef(tree.pos, symbol), new Tree[]{tree}); - } - - //######################################################################## - // Private Methods - Tree generation - - /** Generates given bridge method forwarding to given method. */ - private Tree genBridgeMethod(Symbol bridge, Symbol method) { - Type type = bridge.nextType(); - Tree body = genApply(bridge.pos, - gen.Select(gen.This(bridge.pos, bridge.owner()), method), - gen.mkLocalRefs(bridge.pos, type.valueParams())); - return gen.DefDef(bridge, coerce(body, type.resultType())); - } - - /** Generates an application with given function and arguments. */ - private Tree genApply(int pos, Tree fun, Tree[] args) { - switch (fun.getType()) { - case MethodType(Symbol[] params, Type result): - Tree[] args1 = args; - for (int i = 0; i < args.length; i++) { - Tree arg = args[i]; - Tree arg1 = coerce(arg, params[i].nextType()); - if (arg1 != arg && args1 == args) { - args1 = new Tree[args.length]; - for (int j = 0; j < i; j++) args1[j] = args[j]; - } - args1[i] = arg1; - } - return gen.mkApply_V(pos, fun, args1); - default: - throw Debug.abort("illegal type " + fun.getType() + " for " + fun); - } - } - - /** - * Generates a new unboxed array of given size and with elements - * of given type. - */ - private Tree genNewUnboxedArray(int pos, Type element, Tree size) { - if (global.target == global.TARGET_INT) { - Tree[] targs = {gen.mkType(pos, element)}; - Tree[] vargs = {coerce(size, UNBOXED_INT)}; - Tree fun = gen.mkGlobalRef(pos, primitives.NEW_OARRAY); - return gen.mkApplyTV(fun, targs, vargs); - } - switch (element) { - case UnboxedType(int kind): return genNewUnboxedArray(pos, kind, size); - } - String name = primitives.getNameForClassForName(element); - Tree[] args = { coerce(size, UNBOXED_INT), gen.mkStringLit(pos,name) }; - Tree array = - gen.mkApply_V(gen.mkGlobalRef(pos,primitives.NEW_OARRAY), args); - return gen.mkAsInstanceOf(array, Type.UnboxedArrayType(element)); - } - - /** - * Generates a new unboxed array of given size and with elements - * of given unboxed type kind. - */ - private Tree genNewUnboxedArray(int pos, int kind, Tree size) { - Symbol symbol = primitives.getNewArraySymbol(kind); - Tree[] args = { coerce(size, UNBOXED_INT) }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array length operation. */ - private Tree genUnboxedArrayLength(int pos, Tree array) { - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArrayLengthSymbol(array.getType()); - Tree[] args = { array }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array get operation. */ - private Tree genUnboxedArrayGet(int pos, Tree array, Tree index) { - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArrayGetSymbol(array.getType()); - index = coerce(index, UNBOXED_INT); - Tree[] args = { array, index }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array set operation. */ - private Tree genUnboxedArraySet(int pos, Tree array,Tree index,Tree value){ - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArraySetSymbol(array.getType()); - index = coerce(index, UNBOXED_INT); - value = coerce(value, getArrayElementType(array.getType())); - Tree[] args = { array, index, value }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - //######################################################################## - // Private Methods - Queries - - /** Returns the qualifier of the given tree. */ - private Tree getQualifier(Tree tree) { - switch (tree) { - case Select(Tree qualifier, _): - return qualifier; - default: - throw Debug.abort("no qualifier for tree", tree); - } - } - - /** Are the given erased types in a subtyping relation? */ - private boolean isSubType(Type tp1, Type tp2) { - global.nextPhase(); - boolean result = tp1.isSubType(tp2); - global.prevPhase(); - return result; - } - - /** Are the given erased types in an equality relation? */ - private boolean isSameAs(Type tp1, Type tp2) { - global.nextPhase(); - boolean result = tp1.isSameAs(tp2); - global.prevPhase(); - return result; - } - - /** Is the given type an unboxed type? */ - private boolean isUnboxedType(Type type) { - switch (type) { - case UnboxedType(_) : return true; - case UnboxedArrayType(_): return true; - default : return false; - } - } - - /** Is the given type an unboxed simple type? */ - private boolean isUnboxedSimpleType(Type type) { - switch (type) { - case UnboxedType(_) : return true; - default : return false; - } - } - - /** Is the given type an unboxed array type? */ - private boolean isUnboxedArrayType(Type type) { - switch (type) { - case UnboxedArrayType(_): return true; - default : return false; - } - } - - /** Returns the boxed version of the given unboxed type. */ - private Type boxUnboxedType(Type type) { - switch (type) { - case UnboxedType(TypeTags.UNIT): - return definitions.UNIT_CLASS.type(); - case UnboxedType(TypeTags.BOOLEAN): - return definitions.BOOLEAN_CLASS.type(); - case UnboxedType(TypeTags.BYTE): - return definitions.BYTE_CLASS.type(); - case UnboxedType(TypeTags.SHORT): - return definitions.SHORT_CLASS.type(); - case UnboxedType(TypeTags.CHAR): - return definitions.CHAR_CLASS.type(); - case UnboxedType(TypeTags.INT): - return definitions.INT_CLASS.type(); - case UnboxedType(TypeTags.LONG): - return definitions.LONG_CLASS.type(); - case UnboxedType(TypeTags.FLOAT): - return definitions.FLOAT_CLASS.type(); - case UnboxedType(TypeTags.DOUBLE): - return definitions.DOUBLE_CLASS.type(); - case UnboxedArrayType(Type element): - return Type.appliedType( - definitions.ARRAY_CLASS.type(), new Type[] {element}); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Returns the element type of the given array type. */ - private Type getArrayElementType(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, Type[] args): - if (symbol != definitions.ARRAY_CLASS) break; - assert args.length == 1: type; - return args[0]; - case UnboxedArrayType(Type element): - return element; - } - throw Debug.abort("non-array type", type); - } - -////////////////////////////////////////////////////////////////////////////////// -// Bridge Building -///////////////////////////////////////////////////////////////////////////////// - - private TreeList bridges; - private HashMap bridgeSyms; - - /** Add bridge which Java-overrides `sym1' and which forwards to `sym' - */ - public void addBridge(Symbol owner, Symbol sym, Symbol sym1) { - Type bridgeType = sym1.nextType(); - - // create bridge symbol and add to bridgeSyms(sym) - // or return if bridge with required type already exists for sym. - SymSet bridgesOfSym = (SymSet) bridgeSyms.get(sym); - if (bridgesOfSym == null) bridgesOfSym = SymSet.EMPTY; - Symbol[] brs = bridgesOfSym.toArray(); - for (int i = 0; i < brs.length; i++) { - if (isSameAs(brs[i].type(), bridgeType)) return; - } - Symbol bridgeSym = sym.cloneSymbol(); - bridgeSym.flags |= (SYNTHETIC | BRIDGE); - bridgeSym.flags &= ~(JAVA | DEFERRED); - bridgesOfSym = bridgesOfSym.incl(bridgeSym); - bridgeSyms.put(sym, bridgesOfSym); - bridgeSym.setOwner(owner); - - // check that there is no overloaded symbol with same erasure as bridge - // todo: why only check for overloaded? - Symbol overSym = owner.members().lookup(sym.name); - switch (overSym.nextType()) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) { - if (sym != alts[i] && isSameAs(bridgeType, alttypes[i])) { - unit.error(sym.pos, "overlapping overloaded alternatives; " + - "overridden " + sym1 + sym1.locationString() + - " has same erasure as " + alts[i] + - alttypes[i] + alts[i].locationString()); - } - } - } - - switch (bridgeType) { - case MethodType(Symbol[] params, Type restp): - // assign to bridge symbol its bridge type - // where owner of all parameters is bridge symbol itself. - Symbol[] params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) { - params1[i] = params[i].cloneSymbol(bridgeSym); - } - bridgeSym.setType(Type.MethodType(params1, restp)); - - bridges.append(genBridgeMethod(bridgeSym, sym)); - } - - } - - /** Add an "empty bridge" (abstract method declaration) to satisfy - * CLR's requirement that classes should provide declaration - * for all methods of the interfaces they implement - */ - /* - public void addEmptyBridge(Symbol owner, Symbol method) { - Type bridgeType = method.nextType(); - Symbol bridgeSym = method.cloneSymbol(owner); - bridgeSym.flags = bridgeSym.flags & ~JAVA | SYNTHETIC | DEFERRED; - //bridgeSym.setOwner(owner); - switch (bridgeType) { - case MethodType(Symbol[] params, Type restp): - // assign to bridge symbol its bridge type - // where owner of all parameters is bridge symbol itself. - Symbol[] params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) { - params1[i] = params[i].cloneSymbol(bridgeSym); - } - bridgeSym.setType(Type.MethodType(params1, restp)); - Tree bridge = gen.DefDef(bridgeSym, Tree.Empty); - bridges.append(bridge); - } - } - */ - - private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap(); - - private Set getInterfacesOf(Symbol clasz) { - assert clasz.isClass(): Debug.show(clasz); - Set set = (Set)interfaces.get(clasz); - if (set == null) { - set = new HashSet(); - interfaces.put(clasz, set); - Type parents[] = clasz.parents(); - for (int i = 0; i < parents.length; i++) - set.addAll(getInterfacesOf(parents[i].symbol())); - if (clasz.isInterface()) set.add(clasz); - } - return set; - } - - private void addInterfaceBridges_(Symbol clasz) { - assert clasz.isClass() && !clasz.isInterface(): Debug.show(clasz); - assert clasz.parents().length > 0: Debug.show(clasz)+": "+clasz.info(); - Symbol svper = clasz.parents()[0].symbol(); - assert svper.isClass() && !svper.isInterface(): Debug.show(clasz); - Set interfaces = new HashSet(getInterfacesOf(clasz)); - interfaces.removeAll(getInterfacesOf(svper)); - for (Iterator i = interfaces.iterator(); i.hasNext(); ) { - Symbol inter = (Symbol)i.next(); - addInterfaceBridgesAux(clasz, inter.members()); - } - } - - private void addInterfaceBridgesAux(Symbol owner, Scope symbols) { - for (Scope.SymbolIterator i = symbols.iterator(); - i.hasNext();) { - Symbol member = i.next(); - if (!member.isTerm() || !member.isDeferred()) continue; - addInterfaceBridges(owner, member); - } - } - - - private Symbol getOverriddenMethod(Symbol method) { - Type[] parents = method.owner().parents(); - if (parents.length == 0) return Symbol.NONE; - return method.overriddenSymbol(parents[0]); - } - - public void addBridgeMethodsTo(Symbol method) { - assert method.owner().isClass() && !method.owner().isInterface(); - Symbol overridden = getOverriddenMethod(method); - if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType())) - addBridge(method.owner(), method, overridden); - } - - public void addInterfaceBridges(Symbol owner, Symbol method) { - assert owner.isClass() && !owner.isInterface(): Debug.show(owner); - Symbol overriding = method.overridingSymbol(owner.thisType()); - if (overriding == method) { - Symbol overridden = method.overriddenSymbol(owner.thisType().parents()[0], owner); - if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType())) - addBridge(owner, method, overridden); - // moved this into the TypeCreator class of the MSIL backend - //if (forMSIL && (overridden.isNone() || overridden.owner() != owner)) - // addEmptyBridge(owner, method); - } else if (!overriding.isNone() && !isSameAs(overriding.nextType(), method.nextType())) - addBridge(owner, overriding, method); - } - - private void addBridges(Symbol clasz, TreeList members) { - TreeList savedBridges = bridges; - HashMap savedBridgeSyms = bridgeSyms; - bridges = new TreeList(); - bridgeSyms = new HashMap(); - - int length = members.length(); - if (!clasz.isInterface()) { - for (int i = 0; i < length; i++) { - switch (members.get(i)) { - case DefDef(_, _, _, _, _, Tree rhs): - addBridgeMethodsTo(members.get(i).symbol()); - } - } - addInterfaceBridges_(clasz); - } - - members.append(bridges); - if (bridges.length() > 0) { - Type info = clasz.nextInfo(); - switch (info) { - case CompoundType(Type[] parts, Scope members_): - members_ = members_.cloneScope(); - for (int i = 0; i < bridges.length(); i++) { - Tree bridge = (Tree)bridges.get(i); - members_.enterOrOverload(bridge.symbol()); - } - clasz.updateInfo(Type.compoundType(parts, members_, info.symbol())); - break; - default: - throw Debug.abort("class = " + Debug.show(clasz) + ", " + - "info = " + Debug.show(info)); - } - } - bridgeSyms = savedBridgeSyms; - bridges = savedBridges; - } - - -} diff --git a/sources/scalac/transformer/ErasurePhase.java b/sources/scalac/transformer/ErasurePhase.java deleted file mode 100644 index c0669e22f2..0000000000 --- a/sources/scalac/transformer/ErasurePhase.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ErasurePhase.java,v 1.13 2002/11/14 15:58:22 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.backend.Primitive; -import scalac.backend.Primitives; -import scalac.symtab.Definitions; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - -public class ErasurePhase extends Phase { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final Primitives primitives; - private final Erasure erasure; - - //######################################################################## - // Public Constructors - - public ErasurePhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - this.definitions = global.definitions; - this.primitives = global.primitives; - this.erasure = new Erasure(global); - } - - //######################################################################## - // Public Methods - - public void apply(CompilationUnit unit) { - erasure.apply(unit); - } - - public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor() && sym.constructorClass().isSubClass(definitions.ANYVAL_CLASS)) return tp; - if (sym.isClass()) { - if (sym == definitions.ANY_CLASS) return tp; - if (sym.isJava() && sym.isModuleClass()) return tp; - if (sym.isSubClass(definitions.ANYVAL_CLASS)) - if (sym != definitions.ANYVAL_CLASS) return tp; - switch (tp) { - case CompoundType(Type[] parents, Scope members): - assert parents.length != 0: Debug.show(sym) + " -- " + tp; - if (sym.isInterface()) { - Symbol superclass = parents[0].symbol(); - if (superclass.isJava() && !superclass.isInterface()) { - parents = Type.cloneArray(parents); - parents[0] = definitions.ANYREF_TYPE(); - tp = Type.compoundType(parents, members, sym); - } - } - return Type.erasureMap.map(tp); - default: - throw Debug.abort("illegal case", tp); - } - } - if (sym.isTerm() && sym.isParameter()) { - if (primitives.getPrimitive(sym.owner()) == Primitive.BOX) - return eraseUnboxMethodType(tp); - if (primitives.getPrimitive(sym.owner()) == Primitive.UNBOX) - return eraseBoxMethodType(tp); - } - if (sym.isType()) return tp; - if (sym.isThisSym()) return sym.owner().nextType(); - // if (sym == definitions.NULL) return tp.resultType().erasure(); - if (global.target == global.TARGET_INT && sym ==primitives.NEW_OARRAY){ - // !!! hack for interpreter - Name name = Name.fromString("element").toTypeName(); - Symbol tparam = sym.newTParam(sym.pos, 0, name, definitions.ANY_TYPE()); - return Type.PolyType(new Symbol[]{tparam}, tp); - } - switch (primitives.getPrimitive(sym)) { - case Primitive.IS : return Type.PolyType(tp.typeParams(), Type.MethodType(tp.valueParams(), tp.resultType().erasure())); - case Primitive.AS : return tp; - case Primitive.BOX: return eraseBoxMethodType(tp); - case Primitive.UNBOX: return eraseUnboxMethodType(tp); - default : return tp.erasure(); - } - } - - //######################################################################## - // Private Methods - - private Type eraseBoxMethodType(Type type) { - switch (type) { - case PolyType(_, Type result): - return eraseBoxMethodType(result); - case MethodType(Symbol[] params, Type result): - return Type.MethodType(params, eraseBoxMethodType(result)); - case TypeRef(Type prefix, Symbol clasz, Type[] args): - return Type.typeRef(prefix, clasz, Type.EMPTY_ARRAY); - default: - throw Debug.abort("illegal case", type); - } - } - - private Type eraseUnboxMethodType(Type type) { - switch (type) { - case PolyType(_, Type result): - return eraseUnboxMethodType(result); - case MethodType(Symbol[] params, Type result): - return Type.MethodType(params, eraseUnboxMethodType(result)); - case TypeRef(_, Symbol clasz, Type[] args): - if (clasz == definitions.ARRAY_CLASS) { - Symbol element = args[0].symbol(); - if (element.isAbstractType()) - if (element.info().symbol() == definitions.ANY_CLASS) - return definitions.ANYREF_CLASS.nextType(); - } - return type.fullErasure(); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ExpandMixinsPhase.java b/sources/scalac/transformer/ExpandMixinsPhase.java deleted file mode 100644 index 969080039a..0000000000 --- a/sources/scalac/transformer/ExpandMixinsPhase.java +++ /dev/null @@ -1,473 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ExpandMixinsPhase.java,v 1.8 2002/05/02 10:59:35 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; -import java.util.LinkedList; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeGen; -import scalac.ast.TreeInfo; -import scalac.ast.TreeList; -import scalac.ast.Traverser; -import scalac.ast.Transformer; -import scalac.ast.GenTransformer; -import scalac.ast.GenTreeCloner; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.SymbolCloner; -import scalac.symtab.SymbolSubstTypeMap; - -// TODO do not copy hidden members which are not accessible via -// "super". - -/** - * A phase to expand mixins using code copying. We assume that links - * to outer classes have been made explicit by a previous phase. - */ -// !!! needs to be cleaned -public class ExpandMixinsPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from classes to their interface */ - private final Map/*<Symbol,Symbol>*/ interfaces; - - /** A map from classes to their type transformer */ - private final Map/*<Symbol,TypeTransformer>*/ transformers; - - /** A map from classes to their expanded body */ - private final Map/*<Symbol,Tree[]>*/ expansions; - - /** A map from classes to their original (unexpanded) body */ - private final Map/*<Symbol,Tree[]>*/ bodies; - - /** A map from members to their original member */ - private final Map/*<Symbol,Symbol>*/ origins; - - - /** A transformer that expands classes that have mixins */ - private final GenTransformer expander; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ExpandMixinsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - Phase addinterfaces = global.PHASE.ADDINTERFACES.phase(); - this.interfaces = ((AddInterfacesPhase)addinterfaces).classToIFace; - this.transformers = new HashMap(); - this.expansions = new HashMap(); - this.bodies = ((AddInterfacesPhase)addinterfaces).classToBody; - this.origins = new HashMap(); - this.expander = new TreeExpander(global); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - expander.apply(unit); - } - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - while (true) { - if (symbol.isJava()) return type; - if (symbol.isInterface()) return type; - if (symbol.isCompoundSym()) return type; // !!! check - if (symbol.isClass()) { - return getTypeExpander(symbol).apply(type); - } - symbol = symbol.isConstructor() - ? symbol.constructorClass() - : symbol.owner(); - } - } - - //######################################################################## - // Private Methods - - //######################################################################## - // Private Class - Tree expander - - /** - * A tree transformer that expands class definitions and removes - * compiled units. - */ - private class TreeExpander extends GenTransformer { - public TreeExpander(Global global) { - super(global); - } - public void apply(CompilationUnit unit) { - if (unit.mixinOnly) { - assert Debug.log("removing unit " + unit); - unit.body = Tree.EMPTY_ARRAY; - } else { - super.apply(unit); - } - } - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - Symbol clasz = tree.symbol(); - if (clasz.isInterface()) return super.transform(tree); - return gen.ClassDef(clasz, getExpandedBody(clasz)); - default: - return super.transform(tree); - } - } - } - - //######################################################################## - // Private Class - Tree inliner - - /** - * A Tree cloner that clones mixin bodies. It assumes that these - * bodies have already been expanded. References to mixin value - * parameters are replaced by references to newly-created inlined - * fields. The symbol of Super and This nodes is replaced by the - * symbol of the generated class. The symbol of super members is - * rebound if required. Note that as the input tree has already - * been expanded, it contains only super member to the first - * supertype of the mixin, all other super members have been - * removed during the expansion of the input tree. - */ - private static class TreeInliner extends GenTreeCloner { - private final Symbol clasz; - private final Type supertype; - private boolean initializer; - public TreeInliner(Global global, TypeTransformer transformer) { - super(global, transformer, transformer.cloner); - // !!! global.nextPhase(); - this.clasz = transformer.clasz; - // !!! global.prevPhase(); - this.supertype = clasz.nextInfo().parents()[0]; - } - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case Select(Super(_, _), _): - if (tree.symbol().isInitializer()) return tree.symbol(); // !!! - assert supertype.symbol().isSubClass(tree.symbol().owner()): - tree + " -- " + Debug.show(clasz); - global.nextPhase(); - Symbol symbol = tree.symbol().overriddenSymbol(supertype); - assert !symbol.isNone(): Debug.show(tree, clasz, supertype); - global.prevPhase(); - return symbol; - case Super(_, _): - case This(_): - return clasz; - default: - return super.getSymbolFor(tree); - } - } - public Tree transform(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - if (tree.symbol().hasStaticAttribute()) - return Tree.Empty; - break; - case DefDef(_, _, _, _, _, _): - Symbol symbol = getSymbolFor(tree); - if (symbol.owner() != clasz || symbol.hasStaticAttribute()) - return Tree.Empty; - if (symbol.isInitializer()) initializer = true; - tree = super.transform(tree); - initializer = false; - return tree; - case Apply(Select(Super(_, _), _), _): - if (TreeInfo.methSymbol(tree).isInitializer() && !initializer) - return Tree.Empty; - break; - } - if (tree.hasSymbol() && tree.symbol().isParameter()) { - Symbol symbol = getSymbolFor(tree); - if (!symbol.isParameter()) { - assert tree instanceof Tree.Ident: tree; - return gen.Select(gen.This(tree.pos, clasz), symbol); - } - } - return super.transform(tree); - } - } - - //######################################################################## - // Private Class - Class tree expander - - /** - * A tree transformer that expands a class definitions. Super - * members are rebound and/or rewritten into normal members. - */ - private class ClassTreeExpander extends TreeExpander { - private final Symbol clasz; - private final Type[] parents; - private final Map clones; - public ClassTreeExpander(Global global, TypeTransformer transformer) { - super(global); - this.clasz = transformer.clasz; - this.parents = clasz.parents(); - this.clones = transformer.cloner.clones; - } - private Symbol getSuperMember(Symbol member) { - for (int i = 0; i < parents.length; i++) { - global.nextPhase(); - if (!parents[i].symbol().isSubClass(member.owner())) { - global.prevPhase(); // !!! - continue; - } - Symbol override = member.overridingSymbol(parents[i]); - global.prevPhase(); - assert !override.isNone(): - Debug.show(member, clasz, parents[i]); - if (i == 0) return override; - Symbol clone = (Symbol)clones.get(override); - assert clone != null: Debug.show(member, override, clasz); - return clone; - } - // !!! double loop - for (int i = 0; i < parents.length; i++) { - if (!parents[i].symbol().isSubClass(member.owner())) continue; - //global.nextPhase(); - Symbol override = member.overridingSymbol(parents[i]); - //global.prevPhase(); - assert !override.isNone(): - Debug.show(member, clasz, parents[i]); - if (i == 0) return override; - Symbol clone = (Symbol)clones.get(override); - assert clone != null: Debug.show(member, override, clasz); - return clone; - } - throw Debug.abort(Debug.show(member, clasz)); - } - public Tree transform(Tree tree) { - switch (tree) { - case Select(Super(_, _), _): - Symbol symbol = getSuperMember(tree.symbol()); - Tree qualifier = symbol.owner() == clasz - ? gen.This(tree.pos, clasz) - : gen.Super(tree.pos, clasz); - return gen.Select(tree.pos, qualifier, symbol); - default: - return super.transform(tree); - } - } - } - - - - - - - - - - - - - - - - /** Returns the type transformer to use for the given class. */ - private TypeTransformer getTypeExpander(Symbol clasz) { // !!! - assert clasz.isClass() && !clasz.isInterface(): Debug.show(clasz); - TypeTransformer transformer =(TypeTransformer)transformers.get(clasz); - if (transformer == null) { - transformer = new TypeTransformer(clasz); - transformers.put(clasz, transformer); - } - return transformer; - } - - /** Returns the expanded body of the given clasz. */ - private Tree[] getExpandedBody(Symbol clasz) { - Tree[] body = (Tree[])expansions.get(clasz); - if (body == null) { - body = (Tree[])bodies.remove(clasz); - assert body != null: Debug.show(clasz); - TypeTransformer transformer = getTypeExpander(clasz); - TreeList list = new TreeList(); - assert Debug.log("expanding tree ", clasz); - Type[] parents = clasz.parents(); - TreeInliner inliner = new TreeInliner(global, transformer); - for (int i = 1; i < parents.length; i++) { - Symbol mixin = parents[i].symbol(); - if (mixin.isInterface()) continue; - assert Debug.log("expanding tree ", clasz, ": inlining ", mixin); - list.append(inliner.transform(getExpandedBody(mixin))); - } - ClassTreeExpander expander = new ClassTreeExpander(global, transformer); - list.append(expander.transform(body)); - body = list.toArray(); - expansions.put(clasz, body); - } - return body; - } - - //######################################################################## - // Private Class - Collector - - private class TypeTransformer extends Type.MapOnlyTypes { - - public final Symbol clasz; - public final Type[] parents; - public final SymbolCloner cloner; - public final Map/*<Symbol,Type>*/ inlines; - - public TypeTransformer(Symbol clasz) { - this.clasz = clasz; - this.parents = clasz.parents(); - this.cloner = new SymbolCloner(); - this.inlines = new HashMap(); - initialize(); - } - - private void initialize() { - Type[] parents = clasz.parents(); - // !!! parents.length > 0 - if (parents.length > 0) parents[0].symbol().nextInfo(); // force - assert Debug.log("expanding type ", clasz); - for (int i = parents.length - 1; 0 < i; i--) { - switch (parents[i]) { - case TypeRef(Type prefix, Symbol mixin, Type[] args): - if (mixin.isInterface()) continue; - mixin.nextInfo(); // force - assert Debug.log("expanding type ", clasz, ": inlining ", mixin); - cloner.owners.put(mixin, clasz); - cloner.owners.put(mixin.primaryConstructor(), clasz); - // map mixin type parameters to mixin type arguments - Symbol[] tparams = mixin.typeParams(); - for (int j = 0; j < tparams.length; j++) - inlines.put(tparams[j], args[j]); - - createMixedInMemberSymbols(mixin.nextInfo().members()); - } - } - Set clones = new HashSet(cloner.clones.keySet()); -// cloner.clones.putAll(getTypeTransformerFor(parents[0].symbol()).cloner.clones); // !!! build closure - - // !!! remove ? - for (Iterator i = cloner.clones.values().iterator(); i.hasNext();){ - // !!! for (Iterator i = clones.iterator(); i.hasNext();){ - Symbol clone = (Symbol)i.next(); - clone.setInfo(apply(clone.info())); - } - } - - private Symbol getMemberOrigin(Symbol member) { - Object origin = origins.get(member); - return origin == null ? member : (Symbol)origin; - } - - private void createMixedInMemberSymbols(Scope symbols) { - Scope scope = clasz.members(); - for (SymbolIterator i = symbols.iterator(); i.hasNext();) { - Symbol member = i.next(); - boolean shadowed = member.isPrivate() || member.isInitializer() - || member.overridingSymbol(clasz.thisType()) != member; - Symbol origin = getMemberOrigin(member); - if (!shadowed && origin != null) { - Symbol overridden = member.overriddenSymbol(parents[0]); - if (origin == getMemberOrigin(overridden)) { - cloner.clones.put(member, overridden); - continue; - } - } - // !!! when the symbol is shadowed, inlining could be - // avoided if the original definition is accessible - // through super - assert Debug.log("expanding type ", clasz, ": cloning ", member); - Symbol clone = cloner.cloneSymbol(member); - if (shadowed) clone.name = Names.MIXIN(member); - if (shadowed) clone.flags &= ~Modifiers.OVERRIDE; - if (shadowed) clone.flags &= ~Modifiers.ACCESSFLAGS; - if (shadowed) clone.flags |= Modifiers.PRIVATE; - scope.enterOrOverload(clone); - origins.put(clone, origin != null ? origin : member); - } - } - - - public Type apply(Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - Type inline = (Type)inlines.get(symbol); - if (inline != null) return inline; - if (symbol.isParameter()) { - Symbol clone = (Symbol)cloner.clones.get(symbol); - if (clone != null) { - assert prefix == Type.NoPrefix && args.length == 0: - type; - return Type.typeRef(prefix, clone, args); - } - } - return map(type); - case SingleType(Type prefix, Symbol symbol): - Symbol clone = (Symbol)cloner.clones.get(symbol); - prefix = apply(prefix); - return Type.singleType(prefix, clone != null ? clone : symbol); - case ThisType(_): - return clasz.thisType(); - case CompoundType(Type[] parents, Scope members): - if (type.symbol() != clasz) return map(type); - if (parents.length <= 1) return type; - Symbol iface = (Symbol)interfaces.get(clasz); - if (iface == null) { - int i = 1; - while (i < parents.length && parents[i].symbol().isInterface()) i++; - if (i == parents.length) return type; - parents = Type.cloneArray(parents); - while (i < parents.length) { - if (!parents[i].symbol().isInterface()) - parents[i] = Type.typeRef(parents[i].prefix(), (Symbol)interfaces.get(parents[i].symbol()), parents[i].typeArgs()); - i++; - } - return Type.compoundType(parents, members, clasz); - } - assert parents[parents.length - 1].symbol() == iface: type; - if (parents.length == 2) return type; - for (int i = 1; i < parents.length - 1; i++) { - Symbol mixin = parents[i].symbol(); - Symbol imix = mixin.isInterface() - ? mixin - : (Symbol)interfaces.get(mixin); - assert iface.isSubClass(imix): type+" - "+i; - } - parents = new Type[] {parents[0], parents[parents.length - 1]}; - return Type.compoundType(parents, members, clasz); - default: - return map(type); - } - } - - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java deleted file mode 100644 index b1b05832a1..0000000000 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ /dev/null @@ -1,558 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.util.Collections; -import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; -import scalac.util.Name; -import scalac.util.Names; - -/** - * This phase does the following: - * - * - In every nested class, adds to each of its constructor a new - * value parameter that contains a link to the outer class. - * - * - In every nested type, adds to each of its constructor a new type - * parameter for every type parameter appearing in outer types. - * - * - In every class, adds a forwarding "super" method for every method - * that is accessed via "super" in a nested class. - * - * - Replaces all prefixes of TypeRefs by localThisTypes. - * - * - Adds all missing qualifiers. - */ -// !!! needs to be cleaned -public class ExplicitOuterClassesPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from constructor symbols to type transformers */ - private final Map/*<Symbol,TypeTransformer>*/ transformers = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ExplicitOuterClassesPhase(Global global,PhaseDescriptor descriptor){ - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - if (symbol.isConstructor()) { - Symbol clasz = symbol.constructorClass(); - if (clasz.isClass() && !clasz.isCompoundSym()) - return transformInfo(clasz, symbol, type); - } - return getTypeTransformerFor(symbol).apply(type); - } - - //######################################################################## - // Private Methods - - /** - * Computes and returns the new type of the constructor. As a side - * effect, creates and stores the type transformer corresponding - * to this constructor. - */ - private Type transformInfo(Symbol clasz, Symbol constructor, Type type) { - Symbol[] tparams = type.typeParams(); - Symbol[] vparams = type.valueParams(); - int depth = getClassDepth(clasz); - - Map/*<Symbol,Type>*/ table = new HashMap(); - table.put(clasz, clasz.thisType()); - for (int i = 0; i < tparams.length; i++) - table.put(tparams[i], tparams[i].type()); - - Symbol[] owners = new Symbol[depth]; - Symbol[][] tparamss = new Symbol[depth][]; - - Symbol vlink = null; - if (depth > 0) { - int count = depth; - Symbol owner = clasz.owner(); - for (int i = depth - 1; i >= 0; i--) { - owners[i] = owner; - tparamss[i] = owner.typeParams(); - count += tparamss[i].length; - owner = owner.owner(); - } - - // create outer value link - vparams = Symbol.cloneArray(1, vparams); - int vflags = Modifiers.SYNTHETIC; - Name vname = Names.OUTER(constructor); - vlink = constructor.newVParam(constructor.pos, vflags, vname); - vlink.setInfo(clasz.owner().thisType()); - vparams[0] = vlink; - - int o = 0; - tparams = Symbol.cloneArray(count, tparams); - for (int i = 0; i < depth; i++) { - // create new type parameters - for (int j = 0; j < tparamss[i].length; j++) { - Symbol oldtparam = tparamss[i][j]; - Symbol newtparam = oldtparam.cloneSymbol(constructor); - newtparam.name = Names.OUTER(constructor, oldtparam); - table.put(oldtparam, newtparam.type()); - tparams[o++] = newtparam; - } - // create outer type links - int tflags = Modifiers.PARAM | Modifiers.COVARIANT | Modifiers.SYNTHETIC | Modifiers.STABLE; - Name tname = Names.OUTER(constructor, owners[i]); - Symbol tlink = constructor.newTParam( - constructor.pos, tflags, tname, owners[i].typeOfThis()); - table.put(owners[i], tlink.type()); - tparams[o++] = tlink; - } - - } - - transformers.put(constructor, new TypeTransformer(table)); - type = Type.typeRef(Type.NoPrefix, clasz, Symbol.type(tparams)); - type = Type.MethodType(vparams, type); - if (tparams.length > 0) type = Type.PolyType(tparams, type); - return type; - } - - /** Returns the type transformer for the given symbol. */ - private TypeTransformer getTypeTransformerFor(Symbol symbol) { - while (true) { - Symbol test = symbol; - if (test.isConstructor()) test = test.constructorClass(); - // !!! isClassType -> isClass ? - if (test.isClassType() && !test.isCompoundSym()) break; - symbol = symbol.owner(); - } -// !!! -// while (!symbol.isClassType() && !(symbol.isConstructor() && symbol.constructorClass().isClassType())) // !!! isClassType -> isClass ? -// symbol = symbol.owner(); - if (symbol.isClassType()) - symbol = symbol.primaryConstructor(); - if (symbol.constructorClass().isPackageClass()) - return topLevelTypeTransformer; - TypeTransformer context = (TypeTransformer)transformers.get(symbol); - if (context == null) { - symbol.nextInfo(); - context = (TypeTransformer)transformers.get(symbol); - assert context != null: Debug.show(symbol); - } - return context; - } - - //######################################################################## - // Private Functions - - /** - * Returns the depth of the specified class. The depth of a class - * is: - * - -1 for a package class - * - 0 for a top-level class - * - the depth of the enclosing class plus 1 for an inner class - */ - private static int getClassDepth(Symbol clasz) { - assert clasz.isClass() || clasz.isPackageClass(): Debug.show(clasz); - int depth = -1; - while (!clasz.isPackageClass()) { clasz = clasz.owner(); depth++; } - return depth; - } - - /** - * Returns the type arguments of the flattened version of the - * specified type reference. This functions takes and returns - * non-transformed types. - */ - private static Type[] getFlatArgs(Type prefix, Symbol clasz, Type[] args) { - int depth = getClassDepth(clasz); - if (depth <= 0) return args; - Type[] prefixes = new Type[depth]; - Type[][] argss = new Type[depth][]; - int count = collect(prefix, clasz, prefixes, argss); - args = Type.cloneArray(count, args); - for (int i = 0, o = 0; i < depth; i++) { - for (int j = 0; j < argss[i].length; j++) - args[o++] = argss[i][j]; - args[o++] = prefixes[i]; - } - return args; - } - // where - private static int collect(Type prefix, Symbol clasz, Type[] prefixes, - Type[][] argss) - { - int count = prefixes.length; - for (int i = prefixes.length - 1; i >= 0; i--) { - prefixes[i] = prefix; - Symbol owner = clasz.owner(); - Type base = prefix.baseType(owner); - switch (base) { - case TypeRef(Type type, Symbol symbol, Type[] args): - assert symbol == owner: Debug.show(base); - count += args.length; - argss[i] = args; - prefix = type; - clasz = owner; - continue; - default: - throw Debug.abortIllegalCase(base); - } - } - return count; - } - - //######################################################################## - // Private Class - Type transformer - - /** The type transformer for top-level types */ - private static final TypeTransformer topLevelTypeTransformer = - new TypeTransformer(Collections.EMPTY_MAP); - - /** The type transformer */ - private static final class TypeTransformer extends Type.MapOnlyTypes { - - private final Map/*<Symbol,Type>*/ tparams; - - public TypeTransformer(Map tparams) { - this.tparams = tparams; - } - - public Type apply(Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - if (symbol.isParameter() && symbol.owner().isConstructor()) { - assert prefix == Type.NoPrefix: type; - assert args.length == 0: type; - Object value = tparams.get(symbol); - return value != null ? (Type)value : type; - } - if (symbol.isClass() && !symbol.isCompoundSym()) { - args = map(getFlatArgs(prefix, symbol, args)); - prefix = Type.NoPrefix; - return Type.typeRef(prefix, symbol, args); - } - if (symbol.isPackageClass()) { - args = Type.EMPTY_ARRAY; - prefix = Type.NoPrefix; - return Type.typeRef(prefix, symbol, args); - } - return Type.typeRef(apply(prefix), symbol, map(args)); - case SingleType(Type prefix, Symbol symbol): - if (symbol.owner().isPackageClass()) - return Type.singleType(Type.NoPrefix, symbol); - return Type.singleType(apply(prefix), symbol); - case ThisType(Symbol clasz): - Object value = tparams.get(clasz); - if (value != null) return (Type)value; - assert clasz.isCompoundSym() || clasz.isPackageClass(): - Debug.show(clasz); - return type; - case CompoundType(Type[] parents, Scope members): - // !!! this case should not be needed - return Type.compoundType(map(parents), members, type.symbol()); - default: - return map(type); - } - } - - } - - //######################################################################## - // Private Class - Tree transformer - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - /** The current context */ - private Context context; - - /** The current method */ - private Symbol method; - - /** Transforms the given type. */ - public Type transform(Type type) { - return context.transformer.apply(type); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - if (global.debug) global.log("transforming " + tree);//debug - switch (tree) { - - case ClassDef(_, _, _, _, _, Template impl): - Symbol clasz = tree.symbol(); - context = new Context(context, clasz, new HashMap(), new HashMap()); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - body = Tree.concat(body, genAccessMethods(false)); - body = Tree.concat(body, genAccessMethods(true)); - if (context.vfield != null) { - body = Tree.cloneArray(1, body); - body[0] = gen.ValDef( - context.vfield, - gen.Ident(context.vfield.pos, context.vparam)); - } - context = context.outer; - return gen.ClassDef(clasz, parents, impl.symbol(), body); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol method = tree.symbol(); - Context backup = context; - if (method.isConstructor()) - context = context.getConstructorContext(method); - this.method = method; - rhs = transform(rhs); - this.method = null; - context = backup; - return gen.DefDef(method, rhs); - - case Apply(Tree vfun, Tree[] vargs): - switch (vfun) { - case TypeApply(Tree tfun, Tree[] targs): - if (!tfun.symbol().isConstructor()) break; - return transform(tree, vargs, vfun, targs, tfun); - default: - if (!vfun.symbol().isConstructor()) break; - return transform(tree, vargs, vfun, Tree.EMPTY_ARRAY,vfun); - } - return super.transform(tree); - - case This(_): - return genOuterRef(tree.pos, tree.symbol()); - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - if (symbol.owner().isStaticOwner()) // !!! qualifier ignored - return gen.mkGlobalRef(tree.pos, symbol); - Symbol access; - switch (qualifier) { - case Super(_, _): - Symbol clasz = qualifier.symbol(); - if (clasz == context.clasz) { - access = symbol; - qualifier = gen.Super(tree.pos, qualifier.symbol()); - } else { - access = getAccessSymbol(symbol, clasz); - qualifier = genOuterRef(qualifier.pos, clasz); - } - break; - default: - access = getAccessSymbol(symbol, null); - qualifier = transform(qualifier); - break; - } - tree = gen.Select(tree.pos, qualifier, access); - if (access != symbol && !symbol.isMethod()) - tree = gen.mkApply__(tree); - return tree; - - default: - return super.transform(tree); - } - } - - /* Add outer type and value arguments to constructor calls. */ - private Tree transform(Tree vapply, Tree[] vargs, Tree tapply, - Tree[] targs, Tree tree) - { - switch (tree) { - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - Symbol clasz = symbol.constructorClass(); - if (getClassDepth(clasz) > 0) { - Type[] types = Tree.typeOf(targs); - types = getFlatArgs(qualifier.type(), clasz, types); - targs = gen.mkTypes(tapply.pos, types); - vargs = Tree.cloneArray(1, vargs); - vargs[0] = qualifier; - } else { - assert !containsValue(qualifier): tree; - } - tree = gen.Ident(tree.pos, symbol); - if (targs.length != 0) - tree = gen.TypeApply(tapply.pos, tree, transform(targs)); - return gen.Apply(vapply.pos, tree, transform(vargs)); - default: - throw Debug.abortIllegalCase(tree); - } - } - - /** - * Returns the symbol to access the specified member from the - * current context. If "svper" is non null, the member is - * selected from the superclass of the specified class. The - * returned symbol may be the same as the given one. - */ - private Symbol getAccessSymbol(Symbol member, Symbol svper) { - if (member.isPublic() && svper == null) return member; - Context context = this.context; - for (; context != null; context = context.outer) - if (svper != null - ? context.clasz == svper - : member.isPrivate() - ? context.clasz == member.owner() - // !!! This is incorrect without static access methods - : context.clasz.isSubClass(member.owner())) break; - assert context != null: Debug.show(this.context, member); - if (context == this.context) return member; - Map table = svper != null ? context.supers : context.selfs; - Symbol access = (Symbol)table.get(member); - if (access == null) { - // !!! generate static access methods ? - Name name = Names.ACCESS(member, svper != null); - access = context.clasz.newAccessMethod(context.clasz.pos,name); - global.nextPhase(); - Type info = member.isMethod() - ? member.info().cloneType(member, access) - : Type.MethodType(Symbol.EMPTY_ARRAY, member.info()); - access.setInfo(info); - global.prevPhase(); - table.put(member, access); - context.clasz.nextInfo().members().enter(access); - assert Debug.log("created access method: ", access); - } - return access; - } - - /** Generates the trees of the access methods. */ - private Tree[] genAccessMethods(boolean withSuper) { - Map table = withSuper ? context.supers : context.selfs; - if (table.size() == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[table.size()]; - Iterator entries = table.entrySet().iterator(); - for (int i = 0; i < trees.length; i++) { - Map.Entry entry = (Map.Entry)entries.next(); - Symbol member = (Symbol)entry.getKey(); - Symbol access = (Symbol)entry.getValue(); - int pos = access.pos; - Tree qualifier = withSuper - ? gen.Super(pos, context.clasz) - : gen.This(pos, context.clasz); - Tree select = gen.Select(qualifier, member); - Tree[] targs = gen.mkTypeRefs(pos, access.nextTypeParams()); - Tree[] vargs = gen.mkLocalRefs(pos, access.nextValueParams()); - Tree body = member.isMethod() - ? gen.mkApplyTV(select, targs, vargs) - : select; - trees[i] = gen.DefDef(access, body); - } - return trees; - } - - /** Returns a tree referencing the given outer class. */ - private Tree genOuterRef(int pos, Symbol clasz) { - if (context.clasz == clasz) return gen.This(pos, clasz); - Tree tree = method == null || method.isConstructor() - ? gen.Ident(pos, context.vparam) - : gen.Select(gen.This(pos, context.clasz),context.getVField()); - for (Context c = context.outer;; c = c.outer) { - assert c != null: Debug.show(clasz, context.clasz); - if (c.clasz == clasz) return tree; - Symbol access = getAccessSymbol(c.getVField(), null); - tree = gen.Apply(gen.Select(tree, access)); - } - } - - /** Tests whether the tree contains some value computation. */ - private boolean containsValue(Tree tree) { - switch (tree) { - case This(_): - return !tree.symbol().isPackageClass(); - case Select(Tree qualifier, _): - return containsValue(qualifier) || tree.symbol().isValue(); - default: - return false; - } - } - - }; - - //######################################################################## - // Private Class - Tree transformer context - - /** This class represents the tree transformation context. */ - private class Context { - - /** The outer context */ - public final Context outer; - /** The context class */ - public final Symbol clasz; - /** The context type transformer */ - public final TypeTransformer transformer; - /** The self access methods (maps members to accessors) */ - public final Map/*<Symbol,Symbol>*/ selfs; - /** The super access methods (maps members to accessors) */ - public final Map/*<Symbol,Symbol>*/ supers; - /** The context outer paramater (null if none) */ - public final Symbol vparam; - /** The context outer field (null if none or not yet used) */ - private Symbol vfield; - - /** Initializes this instance. */ - public Context(Context outer, Symbol symbol, Map selfs, Map supers) { - this.outer = outer; - this.clasz = symbol.constructorClass(); - this.transformer = getTypeTransformerFor(symbol); - this.selfs = selfs; - this.supers = supers; - this.vparam = outer != null ? symbol.nextValueParams()[0] : null; - } - - /** Returns a context for the given constructor. */ - public Context getConstructorContext(Symbol constructor) { - assert constructor.constructorClass() == clasz; - return new Context(outer, constructor, selfs, supers); - } - - /** - * Returns the outer value field. The field is created on the - * fly if it does not yet exist. - */ - private Symbol getVField() { - assert outer != null: Debug.show(clasz); - if (vfield == null) { - int flags = - Modifiers.SYNTHETIC | Modifiers.PRIVATE | Modifiers.STABLE; - vfield = clasz.newField(clasz.pos, flags, Names.OUTER(clasz)); - vfield.setInfo(outer.clasz.thisType()); - clasz.members().enterNoHide(vfield); - } - return vfield; - } - - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ICodePhase.java b/sources/scalac/transformer/ICodePhase.java deleted file mode 100644 index 3274897641..0000000000 --- a/sources/scalac/transformer/ICodePhase.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -/** - * This class represents the ICode phase for the java version - * of the compiler. It doesn't do anything but permit to make - * a bridge between the java implementation of Socos et the - * scala one. See scala.tools.scalac.icode.ICodePhase for - * implementation - */ -public abstract class ICodePhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ICodePhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Prints the given compilation units. */ - public abstract void print(CompilationUnit[] units, CodePrinter printer); - - //######################################################################## -} diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java deleted file mode 100644 index fdf14e8d9b..0000000000 --- a/sources/scalac/transformer/LambdaLift.java +++ /dev/null @@ -1,763 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.io.*; -import java.util.HashMap; - -import scalac.*; -import scalac.ast.*; -import scalac.symtab.*; -import scalac.util.*; -import Tree.*; - - -/** A lambda lifting transformer - * - * @author Martin Odersky - * @version 1.0 - * - * What it does: - * Lift every class and function that's contained in another function - * out to be a member to the next enclosing class. - * Pass free variables and type variables as parameters to class constructors. - * Variables and values that are free in some function or class - * are given new unique names. - * Free mutable variables are converted to reference cells. - * All types are updated so that proxies are passed for additional free - * type variables. - */ -public class LambdaLift extends OwnerTransformer - implements Modifiers, Kinds { - - final Global global; - final Definitions definitions; - final FreeVars free; - final LambdaLiftPhase descr; - private CompilationUnit unit; - - public LambdaLift(Global global, LambdaLiftPhase descr) { - super(global); - this.global = global; - this.definitions = global.definitions; - this.free = new FreeVars(global); - this.descr = descr; - } - - public void apply(CompilationUnit unit) { - this.unit = unit; - global.log(unit.source.toString()); - free.initialize(unit); - currentOwner = global.definitions.ROOT_CLASS; - unit.body = transformTemplateStats(unit.body, currentOwner); - } - - /** If `sym' is a class, return its primary constructor; - * otherwise current symbol itself - * - * @param sym - * @return - */ - static Symbol asFunction(Symbol sym) { - return sym.kind == CLASS ? sym.primaryConstructor() : sym; - } - - /** Is symbol local relative to owner? - * Primary constructor parameters are local iff owner (contained in) - * the primary constructor. - * - * @param sym - * @param owner - * @return <code>true</code> if the symbol <code>sym</code> - * is local relative to <code>owner</code> - */ - static boolean isLocal(Symbol sym, Symbol owner) { - if (sym.isParameter() && - sym.owner().isPrimaryConstructor() && - sym.owner().constructorClass().kind == CLASS && - !(owner.isParameter() && owner.owner() == sym)) { - Symbol encl = sym.owner().owner(); - Symbol clazz = sym.owner().constructorClass(); - //System.out.println("isLocal " + sym + " " + encl + " " + clazz + " " + owner);//DEBUG - while (owner != encl && - owner.kind != NONE && - owner != clazz) { - owner = owner.owner(); - //System.out.println(":" + owner);//DEBUG - } - return owner != clazz; - } - return sym.isLocal(); - } - - /** Propagate free variables from all called functions. - * `asFunction' applied to the next enclosing function or class owner. - * - * @param owner - * @return - */ - static Symbol enclFun(Symbol owner) { - Symbol sym = owner; - while (!asFunction(sym).isMethod()) sym = sym.owner(); - return asFunction(sym); - } - - /** Return SymSet from a hashmap. - * - * @param f - * @param sym - * @return - */ - private static SymSet get(HashMap f, Symbol sym) { - SymSet ss = (SymSet) f.get(sym); - return ss == null ? SymSet.EMPTY : ss; - } - - /** Compute free variables map `fvs'. - * Also assign unique names to all - * value/variable/let symbols that are free in some function or class, and to - * all class/function symbols that are owned by some function. - */ - static class FreeVars extends OwnerTransformer { - - private CompilationUnit unit; - - public FreeVars(Global global) { - super(global); - } - - /** A hashtable storing free variables of functions and class constructors. - */ - private HashMap/*<Symbol,SymSet>*/ fvs; - - /** A hashtable storing free type variables of functions and class constructors. - */ - private HashMap/*<Symbol,SymSet>*/ ftvs; - - /** A hashtable storing calls between functions and class constructors - */ - private HashMap/*<Symbol,SymSet>*/ called; - - /** The set of symbols that need to be renamed. - */ - private SymSet renamable; - - /** The set of symbols that bound by polytypes - * and therefore are not free type variables. - */ - private SymSet excluded; - - /** A flag to indicate whether new free variables have been found - */ - private boolean changedFreeVars; - - /** A flag to indicate whether we are in propagation phase - * (used in assertion). - */ - private boolean propagatePhase; - - /** Insert `sym' into the set of free variables of `owner' - * - * @param owner - * @param sym - */ - private void putFree(Symbol owner, Symbol sym) { - assert owner.isLocal(); - HashMap f = sym.isType() ? ftvs : fvs; - SymSet ss = get(f, owner); - if (!ss.contains(sym)) { - f.put(owner, ss.incl(sym)); - changedFreeVars = true; - if (global.debug) global.log(sym + " is free in " + owner); - } - } - - /** Insert `to' into the set of functions called by `from' - * - * @param from - * @param to - */ - private void putCall(Symbol from, Symbol to) { - SymSet ss = get(called, from); - if (!ss.contains(to)) { - called.put(from, ss.incl(to)); - } - } - - /** Mark symbol `sym' as being free in `owner', unless `sym' - * is defined in `owner' or there is a class between `owner's owner - * and the owner of `sym'. - * Return `true' if there is no class between `owner' and - * the owner of sym. - * - * @param sym - * @param owner - * @return - */ - private boolean markFree(Symbol sym, Symbol owner) { - if (global.debug) - global.log("mark " + sym + " of " + sym.owner() + - " free in " + owner);//debug - if (owner.kind == NONE) { - assert propagatePhase : sym + " in " + sym.owner(); - return false; - } else if (sym.owner() == owner) { - return true; - } else if (markFree(sym, owner.owner())) { - Symbol fowner = asFunction(owner); - if (fowner.isMethod()) { - putFree(fowner, sym); - renamable = renamable.incl(sym); - if (sym.isVariable()) sym.flags |= CAPTURED; - } - return owner.kind != CLASS; - } else { - return false; - } - } - - /** Assign unique name to symbol. - * If symbol is a class assign same name to its primary constructor. - */ - private void makeUnique(Symbol sym) { - sym.name = unit.fresh.newName(sym.name); - } - - private Type.Map traverseTypeMap = new Type.Map() { - public Type apply(Type tp) { - if (global.debug) global.log("traverse " + tp);//debug - switch (tp) { - case TypeRef(NoPrefix, Symbol sym, Type[] targs): - if (isLocal(sym, currentOwner) && - sym.kind == TYPE && - !excluded.contains(sym)) - markFree(sym, currentOwner); - break; - case SingleType(NoPrefix, Symbol sym): - if (isLocal(sym, currentOwner)) - markFree(sym, currentOwner); - break; - case PolyType(Symbol[] tparams, Type restp): - for (int i = 0; i < tparams.length; i++) - excluded = excluded.incl(tparams[i]); - Type tp1 = super.map(tp); - for (int i = 0; i < tparams.length; i++) - excluded = excluded.excl(tparams[i]); - return tp1; - } - return map(tp); - } - }; - - public Tree transform(Tree tree) { - if (global.debug) global.log("free " + tree);//debug - assert tree.type != null : tree; - traverseTypeMap.apply(tree.type.widen()); - Symbol sym = tree.symbol(); - switch(tree) { - case ClassDef(_, _, _, _, _, _): - case DefDef(_, _, _, _, _, _): - if (sym.isLocal()) { - renamable = renamable.incl(sym); - } - return super.transform(tree); - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AbsTypeDef( - tree, sym, - transform(rhs, currentOwner), - transform(lobound, currentOwner)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AliasTypeDef( - tree, sym, - transform(tparams, currentOwner), - transform(rhs, currentOwner)); - - case Ident(_): - if (isLocal(sym, currentOwner)) { - if (sym.isMethod()) { - Symbol f = enclFun(currentOwner); - if (f.name.length() > 0) // it is not a template function { - putCall(f, sym); - } else if (sym.kind == VAL || sym.kind == TYPE) { - markFree(sym, currentOwner); - } - } - return tree; - - default: - return super.transform(tree); - } - } - - /** Propagate free fariables from all called functions. - * - * @param fvs - */ - void propagateFvs(HashMap fvs) { - Object[] fs = called.keySet().toArray(); - for (int i = 0; i < fs.length; i++) { - Symbol f = (Symbol) fs[i]; - Symbol[] calledFromF = get(called, f).toArray(); - for (int j = 0; j < calledFromF.length; j++) { - //System.out.println(f + " calls " + calledFromF[j]);//DEBUG - Symbol[] newFvs = get(fvs, calledFromF[j]).toArray(); - for (int k = 0; k < newFvs.length; k++) { - markFree(newFvs[k], f); - } - } - } - } - - /** This method re-enters all free variables into their free variable - * sets. This is necessary because the names of these variables (and - * therefore their `isLess' order have changed. - * - * @param fvs - */ - private void restoreFvs(HashMap fvs) { - Object[] fs = fvs.keySet().toArray(); - for (int i = 0; i < fs.length; i++) { - Symbol f = (Symbol) fs[i]; - Symbol[] elems = get(fvs, f).toArray(); - SymSet elems1 = SymSet.EMPTY; - for (int j = 0; j < elems.length; j++) - elems1 = elems1.incl(elems[j]); - fvs.put(f, elems1); - } - } - - /** Compute a mapping from symbols to their free variables - * in hashtable `fvs'. Also rename all variables that need it. - * - * @param unit - */ - public void initialize(CompilationUnit unit) { - this.unit = unit; - fvs = new HashMap(); - ftvs = new HashMap(); - called = new HashMap(); - renamable = SymSet.EMPTY; - excluded = SymSet.EMPTY; - apply(unit); - - propagatePhase = true; - do { - changedFreeVars = false; - propagateFvs(fvs); - propagateFvs(ftvs); - } while (changedFreeVars); - - Symbol[] ss = renamable.toArray(); - for (int i = 0; i < ss.length; i++) { - makeUnique(ss[i]); - } - - restoreFvs(fvs); - restoreFvs(ftvs); - } - } - - private TreeList liftedDefs; - - /** Transform template and add lifted definitions to it. - * - * @param stats - * @param tsym - * @return - */ - public Tree[] transformTemplateStats(Tree[] stats, Symbol tsym) { - TreeList prevLiftedDefs = liftedDefs; - liftedDefs = new TreeList(); - TreeList stats1 = new TreeList(super.transformTemplateStats(stats, tsym)); - stats1.append(liftedDefs); - liftedDefs = prevLiftedDefs; - return stats1.toArray(); - } - - /** ... - * - * @param tree - */ - public Tree transform(Tree tree) { - //global.debugPrinter.print("lifting ").print(tree).println().end();//DEBUG - //System.out.print(tree.type + " --> ");//DEBUG - tree.type = descr.transform(tree.type, currentOwner); - //System.out.println(tree.type);//DEBUG - switch (tree) { - case Block(Tree[] stats, Tree value): - for (int i = 0; i < stats.length; i++) - liftSymbol(stats[i]); - return copy.Block(tree, transform(stats), transform(value)); - - case ClassDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): - Symbol sym = tree.symbol(); - if ((mods & LIFTED) != 0) { - ((ClassDef) tree).mods &= ~LIFTED; - Tree tree1 = copy.ClassDef( - tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym.primaryConstructor())), - new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym.primaryConstructor()))}, - transform(tpe, sym), - transform(impl, sym)); - liftedDefs.append(tree1); - return Tree.Empty; - } else { - assert !sym.isLocal() : sym; - return copy.ClassDef( - tree, sym, - transform(tparams, sym), - transform(vparams, sym), - transform(tpe, sym), - transform(impl, sym)); - } - - case DefDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Symbol sym = tree.symbol(); - if ((mods & LIFTED) != 0) { - ((DefDef) tree).mods &= ~LIFTED; - Tree tree1 = copy.DefDef( - tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym)), - new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym))}, - transform(tpe, sym), - transform(rhs, sym)); - liftedDefs.append(tree1); - return Tree.Empty; - } else { - assert !sym.isLocal() : sym; - return copy.DefDef( - tree, sym, - transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), - transform(rhs, sym)); - } - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AbsTypeDef( - tree, tree.symbol(), - transform(rhs, currentOwner), - transform(lobound, currentOwner)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AliasTypeDef( - tree, tree.symbol(), - transform(tparams, currentOwner), - transform(rhs, currentOwner)); - - case ValDef(_, _, _, Tree rhs): - Symbol sym = tree.symbol(); - rhs = transform(rhs, sym); - if (sym.isCaptured()) { - assert sym.isLocal(); - switch (sym.nextType()) { - case TypeRef(_, Symbol clasz, Type[] args): - Tree constr = gen.mkPrimaryConstructorGlobalRef(rhs.pos, clasz); - rhs = gen.New(gen.mkApplyTV(constr, args, new Tree[]{rhs})); - break; - default: - throw Debug.abort("illegal case", sym.nextType()); - } - } - return gen.ValDef(sym, rhs); - - case Sequence(Tree[] args): - throw new ApplicationError("this should not happen"); - /* // moved this to Uncurry - Tree tree1 = gen.mkNewList(tree.pos, tree.type.typeArgs()[0], transform(args)); - //System.out.println("TUPLE: " + tree + "\n ==> \n" + tree1);//DEBUG - return tree1; - */ - - case Return(Block(Tree[] stats, Tree value)): - return transform( - gen.Block(stats, gen.Return(tree.pos, tree.symbol(), value))); - - case Return(Tree expr): - if (tree.symbol() != currentOwner.enclMethod()) { - unit.error(tree.pos, "non-local return not yet implemented"); - } - return super.transform(tree); - - case Apply(Tree fn, Tree[] args): - Symbol fsym = TreeInfo.methSymbol(fn); - Tree fn1 = transform(fn); - switch (fn1) { - case TypeApply(Tree fn2, Tree[] targs): - //if (args.length == 1 && fn2.symbol() == definitions.PREDEF_ARRAY()) { - // throw new ApplicationError("this should not happen"); - /* // this moved to UnCurry - switch (args[0]) { - case Sequence(Tree[] items): - assert targs.length == 1: tree; - Tree array = gen.mkNewArray( - args[0].pos, - targs[0].type(), - transform(items), - currentOwner); - // fn2 may be like "{ println("hello"); Predef}.Array" - switch (fn2) { - case Select(Tree qualifier, _): - return gen.mkBlock(args[0].pos, qualifier, array); - default: - throw Debug.abort("illegal case", fn2); - } - } - */ - //} - fn1 = copy.TypeApply( - fn1, fn2, addFreeArgs(tree.pos, get(free.ftvs, fsym), targs, true)); - break; - default: - Tree[] targs = addFreeArgs( - tree.pos, get(free.ftvs, fsym), Tree.EMPTY_ARRAY, true); - if (targs.length > 0) - fn1 = gen.TypeApply(fn1, targs); - } - Tree[] args1 = transform(args); - return copy.Apply( - tree, fn1, addFreeArgs(tree.pos, get(free.fvs, fsym), args1, false)); - - case Ident(_): - Symbol sym = tree.symbol(); - if (isLocal(sym, currentOwner) && - (sym.kind == TYPE || (sym.kind == VAL && !sym.isMethod()))) { - sym = descr.proxy(sym, currentOwner); - } - Tree tree1 = gen.mkLocalRef(tree.pos, sym); - if (sym.isCaptured()) - return gen.Select(tree1, definitions.REF_ELEM()); - else - return tree1; - - default: - return super.transform(tree); - } - } - - private Symbol[] ftvsParams(Symbol owner) { - Symbol[] freevars = get(free.ftvs, owner).toArray(); - Symbol[] params = new Symbol[freevars.length]; - for (int i = 0; i < params.length; i++) { - params[i] = freevars[i].cloneSymbol(owner); - params[i].pos = owner.pos; - params[i].flags = PARAM | SYNTHETIC; - } - for (int i = 0; i < params.length; i++) - params[i].setInfo(freevars[i].info().subst(freevars, params)); - return params; - } - - private Symbol[] fvsParams(Symbol owner) { - Symbol[] freevars = get(free.fvs, owner).toArray(); - Symbol[] params = new Symbol[freevars.length]; - for (int i = 0; i < params.length; i++) { - params[i] = freevars[i].cloneSymbol(owner); - params[i].pos = owner.pos; - params[i].flags &= CAPTURED; - params[i].flags |= PARAM | SYNTHETIC; - params[i].setInfo(freevars[i].type()); - } - return params; - } - - private Symbol[] newtparams(Symbol owner) { - Symbol[] tparams = owner.nextType().typeParams(); - int nfree = get(free.ftvs, owner).size(); - assert nfree == tparams.length - owner.type().typeParams().length - : owner + " " + nfree + " " + tparams.length + " " + owner.type().firstParams().length; - Symbol[] newtparams = new Symbol[nfree]; - System.arraycopy(tparams, tparams.length - nfree, newtparams, 0, nfree); - return newtparams; - } - - private Symbol[] newparams(Symbol owner) { - Symbol[] params = owner.nextType().firstParams(); - int nfree = get(free.fvs, owner).size(); - assert nfree == params.length - owner.type().firstParams().length; - Symbol[] newparams = new Symbol[nfree]; - System.arraycopy(params, params.length - nfree, newparams, 0, nfree); - return newparams; - } - - /** For members: - * change symbol of tree so that - * owner = currentClass - * newparams are added - * enter symbol in scope of currentClass - * For non-members: - * change symbol of tree so that - * owner = currentMember - */ - private void liftSymbol(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - ((ClassDef) tree).mods |= LIFTED; - Symbol sym = tree.symbol(); - sym.flags |= LIFTED; - assert sym.isLocal() : sym; - Symbol constr = sym.primaryConstructor(); - liftSymbol( - sym, get(free.ftvs, constr).toArray(), - ftvsParams(constr), fvsParams(constr)); - break; - - case DefDef(_, _, _, _, _, _): - ((DefDef) tree).mods |= LIFTED; - Symbol sym = tree.symbol(); - sym.flags |= LIFTED | PRIVATE; - assert sym.isLocal() : sym; - liftSymbol( - sym, get(free.ftvs, sym).toArray(), - ftvsParams(sym), fvsParams(sym)); - break; - - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol sym = tree.symbol(); - assert sym.isLocal() : sym; - // This is to fix the owner of y from x to f in this example: - // class C { def f = { val x = { val y = ...; y } } } - if (!isClassMember(sym.owner())) { - assert isClassMember(sym.owner().owner()): Debug.show(tree, sym); - sym.setOwner(sym.owner().owner()); - } - break; - - } - } - // where - private boolean isClassMember(Symbol sym) { - return sym.isConstructor() || sym.owner().isClass(); - } - - private void liftSymbol(Symbol sym, Symbol[] oldtparams, - Symbol[] newtparams, Symbol[] newparams) { - Symbol enclClass = sym.owner(); - while (!enclClass.isClassType()) { - enclClass = enclClass.isConstructor() && !enclClass.isPrimaryConstructor() - ? enclClass.constructorClass() - : enclClass.owner(); - } - if (!sym.isConstructor()) sym.setOwner(enclClass); - if (!sym.isConstructor()) enclClass.members().enter(sym); - if (sym.isMethod()) { - if (newtparams.length != 0 || newparams.length != 0) { - sym.updateInfo( - addParams( - addTypeParams( - sym.nextInfo(), oldtparams, newtparams), - newparams)); - if (global.debug) - global.log(sym + " has now type " + sym.nextType()); - } - } else if (sym.kind == CLASS) { - Symbol constr = sym.primaryConstructor(); - liftSymbol(constr, oldtparams, newtparams, newparams); - // fix result type of constructor - constr.updateInfo(descr.transform(constr.nextInfo(), constr)); - } else { - throw new ApplicationError(); - } - } - - private Type addTypeParams(Type tp, Symbol[] oldtparams, Symbol[] newtparams) { - if (newtparams.length == 0) return tp; - switch (tp) { - case MethodType(_, _): - return Type.PolyType( - newtparams, - Type.getSubst(oldtparams, newtparams, true).apply(tp)); - case PolyType(Symbol[] tparams, Type restpe): - Symbol[] tparams1 = new Symbol[tparams.length + newtparams.length]; - System.arraycopy(tparams, 0, tparams1, 0, tparams.length); - System.arraycopy(newtparams, 0, tparams1, tparams.length, newtparams.length); - return Type.PolyType( - tparams1, - Type.getSubst(oldtparams, newtparams, true).apply(restpe)); - default: - throw new ApplicationError("illegal type: " + tp); - } - } - - private Type addParams(Type tp, Symbol[] newparams) { - if (newparams.length == 0) return tp; - switch (tp) { - case MethodType(Symbol[] params, Type restpe): - Symbol[] params1 = new Symbol[params.length + newparams.length]; - System.arraycopy(params, 0, params1, 0, params.length); - System.arraycopy(newparams, 0, params1, params.length, newparams.length); - return Type.MethodType(params1, restpe); - case PolyType(Symbol[] tparams, Type restpe): - return Type.PolyType(tparams, addParams(restpe, newparams)); - default: - throw new ApplicationError("illegal type: " + tp); - } - } - - private AbsTypeDef[] addTypeParams(AbsTypeDef[] tparams, Symbol[] newtparams) { - if (newtparams.length == 0) return tparams; - AbsTypeDef[] tparams1 = new AbsTypeDef[tparams.length + newtparams.length]; - System.arraycopy(tparams, 0, tparams1, 0, tparams.length); - for (int i = 0; i < newtparams.length; i++) { - tparams1[tparams.length + i] = gen.mkTypeParam(newtparams[i]); - } - return tparams1; - } - - private ValDef[] addParams(ValDef[] params, Symbol[] newparams) { - if (newparams.length == 0) return params; - ValDef[] params1 = new ValDef[params.length + newparams.length]; - System.arraycopy(params, 0, params1, 0, params.length); - for (int i = 0; i < newparams.length; i++) { - params1[params.length + i] = gen.mkParam(newparams[i]); - } - return params1; - } - - /** For all variables or type variables in `fvs', - * append proxies to argument array `args'. - * - * @param pos - * @param fvs - * @param args - * @param types - * @return - */ - private Tree[] addFreeArgs(int pos, SymSet fvs, Tree[] args, boolean types) { - if (fvs != SymSet.EMPTY) { - Symbol[] fparams = fvs.toArray(); - Tree[] args1 = new Tree[args.length + fparams.length]; - System.arraycopy(args, 0, args1, 0, args.length); - for (int i = 0; i < fparams.length; i++) { - Symbol farg = descr.proxy(fparams[i], currentOwner); - args1[args.length + i] = - types ? gen.mkTypeRef(pos, farg) : gen.Ident(pos, farg); - } - return args1; - } else { - return args; - } - } - -} diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java deleted file mode 100644 index 06c1984249..0000000000 --- a/sources/scalac/transformer/LambdaLiftPhase.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -//import java.util.ArrayList; - -import scalac.*; -import scalac.parser.*; -import scalac.symtab.*; -import scalac.util.ArrayApply; - - -public class LambdaLiftPhase extends Phase implements Kinds, Modifiers { - - /** Initializes this instance. */ - public LambdaLiftPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - /** Applies this phase to the given compilation unit. - * - * @param unit - */ - public void apply(CompilationUnit unit) { - new LambdaLift(global, this).apply(unit); - } - - /** ... - * - * @param sym - * @param tp - * @return - */ - public Type transformInfo(Symbol sym, Type tp) { - /* - if (global.debug) - global.log("transform info for " + sym + ":" + tp + sym.locationString()); - */ - Type tp1 = tp; - if (sym != Symbol.NONE) { - switch (tp) { - case MethodType(_, _): - case PolyType(_, _): - tp1 = transform(tp, sym); - break; - default: - if (sym.kind == CLASS) - tp1 = transform(tp, sym); - else - tp1 = transform(tp, sym.owner()); - } - } - if (sym.isCaptured()) - return global.definitions.REF_TYPE(tp1); - else return tp1; - } - - /** Add proxies as type arguments for propagated type parameters. - * - * @param tp - * @param owner - * @return - */ - Type transform(Type tp, Symbol owner) { - return transformTypeMap.setOwner(owner).apply(tp); - } - - /** MapOnlyTypes => All symbols are mapped to themselves. - */ - private class TransformTypeMap extends Type.MapOnlyTypes { - Symbol owner; -// ArrayList/*<Symbol>*/ excluded = new ArrayList(); - Type.Map setOwner(Symbol owner) { this.owner = owner; return this; } - - public Type apply(Type tp) { - switch (tp) { - case TypeRef(Type pre, Symbol sym, Type[] targs): - if (sym.kind == CLASS) { - switch (pre) { - case NoPrefix: - pre = sym.owner().enclClass().thisType(); - tp = Type.typeRef(pre, sym, targs); - } - } - switch (pre) { - case NoPrefix: - if (LambdaLift.isLocal(sym, owner)) { - assert targs.length == 0; - return proxy(sym, owner).type(); - } - break; - case ThisType(_): - if (sym.kind == CLASS && - sym.primaryConstructor().isUpdatedAt(LambdaLiftPhase.this)) { - Symbol[] tparams = sym.primaryConstructor().nextInfo().typeParams(); - int i = tparams.length; - while (i > 0 && tparams[i-1].isSynthetic()) - i--; - if (i < tparams.length) { - if (global.debug) - global.log("adding proxies for " + sym + - ": " + ArrayApply.toString(tparams)); - - Type[] targs1 = new Type[tparams.length]; - System.arraycopy(map(targs), 0, targs1, 0, targs.length); - while (i < tparams.length) { - targs1[i] = proxy(tparams[i], owner).type(); - i++; - } - return Type.typeRef(pre, sym, targs1); - } - } - } - break; -/* - case PolyType(Symbol[] tparams, _): - if (tparams.length != 0) { - int len = excluded.size(); - for (int i = 0; i < tparams.length; i++) - excluded.add(tparams[i]); - Type tp1 = map(tp); - for (int i = 0; i < tparams.length; i++) - excluded.remove(excluded.size() - 1); - return tp1; - } -*/ - } - return map(tp); - } - } - - private TransformTypeMap transformTypeMap = new TransformTypeMap(); - - /** Return closest enclosing (type)parameter that has same name as `fv', - * or `fv' itself if this is the closest definition. - * - * @param fv - * @param owner - * @return - */ - Symbol proxy(Symbol fv, Symbol owner) { - if (global.debug) - global.log("proxy " + fv + " of " + fv.owner() + - " in " + LambdaLift.enclFun(owner)); - Symbol o = owner; - while (o.kind != NONE) { - if (global.debug) - global.log("looking in " + LambdaLift.enclFun(o) + " " + - ArrayApply.toString(o.typeParams())); - Symbol fowner = LambdaLift.enclFun(o); - if (fowner.isMethod()) { - if (LambdaLift.enclFun(fv.owner()) == fowner) return fv; - Type ft = (fowner.isUpdatedAt(this)) ? fowner.nextType() - : fowner.type(); - Symbol[] ownerparams = fv.isType() ? ft.typeParams() - : ft.firstParams(); - for (int i = 0; i < ownerparams.length; i++) { - if (ownerparams[i].name == fv.name) - return ownerparams[i]; - } - } - assert o.owner() != o; - o = o.owner(); - } - return fv; - //throw new ApplicationError("proxy " + fv + " in " + owner); - } - -} diff --git a/sources/scalac/transformer/MakeBoxingExplicitPhase.java b/sources/scalac/transformer/MakeBoxingExplicitPhase.java deleted file mode 100644 index 435886b1dc..0000000000 --- a/sources/scalac/transformer/MakeBoxingExplicitPhase.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.checkers.TreeChecker; -import scalac.symtab.Definitions; - -/** - * This phase makes boxing and unboxing of primitive values and arrays - * explicit. - */ -public class MakeBoxingExplicitPhase extends Phase { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final TreeChecker checker; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public MakeBoxingExplicitPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - this.definitions = global.definitions; - this.checker = new TreeChecker(definitions); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - assert checker.check(unit); - new scalac.atree.ATreeFromSTree(definitions).translate(unit); // !!! - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/OwnerTransformer.java b/sources/scalac/transformer/OwnerTransformer.java deleted file mode 100644 index 55ee93dadd..0000000000 --- a/sources/scalac/transformer/OwnerTransformer.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.*; -import scalac.ast.*; -import scalac.symtab.Kinds; -import scalac.symtab.Symbol; -import scalac.util.Name; -import Tree.*; - - -/** A default transformer class which also maintains owner information - * - * @author Martin Odersky - * @version 1.0 - */ -public class OwnerTransformer extends Transformer { - - protected Symbol currentOwner; - - public OwnerTransformer(Global global) { - super(global); - } - - public void apply(CompilationUnit unit) { - currentOwner = global.definitions.ROOT_CLASS; - unit.body = transform(unit.body); - } - - /** .. - * - * @param tree - * @param owner - * @return - */ - public Tree transform(Tree tree, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - Tree tree1 = transform(tree); - currentOwner = prevOwner; - return tree1; - } - - /** .. - * - * @param params - * @param owner - * @return - */ - public AbsTypeDef[] transform(AbsTypeDef[] params, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - AbsTypeDef[] res = transform(params); - currentOwner = prevOwner; - return res; - } - - /** .. - * - * @param params - * @param owner - * @return - */ - public ValDef[][] transform(ValDef[][] params, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - ValDef[][] res = transform(params); - currentOwner = prevOwner; - return res; - } - - /** .. - * - * @param templ - * @param owner - * @return - */ - public Template transform(Template templ, Symbol owner) { - Symbol prevOwner = currentOwner; - if (owner.kind == Kinds.CLASS) - currentOwner = owner.primaryConstructor(); - Tree[] parents1 = transform(templ.parents); - currentOwner = owner; - Tree[] body1 = transformTemplateStats(templ.body, templ.symbol()); - currentOwner = prevOwner; - return copy.Template(templ, parents1, body1); - } - - /** .. - * - * @param ts - * @param tsym - * @return - */ - public Tree[] transformTemplateStats(Tree[] ts, Symbol tsym) { - Tree[] ts1 = ts; - for (int i = 0; i < ts.length; i++) { - Tree t = transformTemplateStat(ts[i], tsym); - if (t != ts[i] && ts1 == ts) { - ts1 = new Tree[ts.length]; - System.arraycopy(ts, 0, ts1, 0, i); - } - ts1[i] = t; - } - return ts1; - } - - /** .. - * - * @param stat - * @param tsym - * @return - */ - public Tree transformTemplateStat(Tree stat, Symbol tsym) { - return transform(stat, tsym); - } - - /** .. - * - * @param tree - * @return - */ - public Tree transform(Tree tree) { - switch(tree) { - case PackageDef(Tree packaged, Template impl): - return copy.PackageDef( - tree, - transform(packaged), - transform(impl, packaged.symbol())); - - case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): - Symbol symbol = tree.symbol(); - return copy.ClassDef( - tree, symbol, - transform(tparams, symbol.primaryConstructor()), - transform(vparams, symbol.primaryConstructor()), - transform(tpe, symbol), - transform(impl, symbol)); - - case ModuleDef(_, _, Tree tpe, Template impl): - Symbol symbol = tree.symbol(); - return copy.ModuleDef( - tree, symbol, - transform(tpe, symbol), - transform(impl, symbol.moduleClass())); - - case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.DefDef( - tree, symbol, - transform(tparams, symbol), - transform(vparams, symbol), - transform(tpe, symbol), - transform(rhs, symbol)); - - case ValDef(_, _, Tree tpe, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.ValDef( - tree, symbol, - transform(tpe), - transform(rhs, symbol)); - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - Symbol symbol = tree.symbol(); - return copy.AbsTypeDef( - tree, symbol, - transform(rhs, symbol), - transform(lobound, symbol)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.AliasTypeDef( - tree, symbol, - transform(tparams, symbol), - transform(rhs, symbol)); - - default: - return super.transform(tree); - } - } - -} diff --git a/sources/scalac/transformer/TailCallPhase.java b/sources/scalac/transformer/TailCallPhase.java deleted file mode 100644 index 4798e22c1a..0000000000 --- a/sources/scalac/transformer/TailCallPhase.java +++ /dev/null @@ -1,296 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.GenTransformer; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * A Tail Call Transformer - * - * @author Erik Stenman - * @version 1.0 - * - * What it does: - * - * Finds method calls in tail-position and replaces them with jumps. - * A call is in a tail-position if it is the last instruction to be - * executed in the body of a method. This is done by recursing over - * the trees that may contain calls in tail-position (trees that can't - * contain such calls are not transformed). However, they are not that - * many. - * - * Self-recursive calls in tail-position are replaced by jumps to a - * label at the beginning of the method. As the JVM provides no way to - * jump from a method to another one, non-recursive calls in - * tail-position are not optimized. - * - * A method call is self-recursive if it calls the current method on - * the current instance and the method is final (otherwise, it could - * be a call to an overridden method in a subclass). Furthermore, If - * the method has type parameters, the call must contain these - * parameters as type arguments. - * - * Nested functions can be tail recursive (if this phase runs before - * lambda lift) and they are transformed as well. - * - * If a method contains self-recursive calls, a label is added to at - * the beginning of its body and the calls are replaced by jumps to - * that label. - */ -public class TailCallPhase extends Phase { - - private static class Context { - /** The current method */ - public Symbol method = Symbol.NONE; - - /** The current tail-call label */ - public Symbol label = Symbol.NONE; - - /** The expected type arguments of self-recursive calls */ - public Type[] types; - - /** Tells whether we are in a tail position. */ - public boolean tailPosition; - - public Context() { - this.tailPosition = false; - } - - /** - * The Context of this transformation. It contains the current enclosing method, - * the label and the type parameters of the enclosing method, together with a - * flag which says whether our position in the tree allows tail calls. This is - * modified only in <code>Block</code>, where stats cannot possibly contain tail - * calls, but the value can. - */ - public Context(Symbol method, Symbol label, Type[] types, boolean tailPosition) { - this.method = method; - this.label = label; - this.types = types; - this.tailPosition = tailPosition; - } - } - - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public TailCallPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - //######################################################################## - // Private Classes - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - - /** The context of this call */ - private Context ctx = new Context(); - - /** Transform the given tree, which is (or not) in tail position */ - public Tree transform(Tree tree, boolean tailPos) { - boolean oldTP = ctx.tailPosition; - ctx.tailPosition = tailPos; - tree = transform(tree); - ctx.tailPosition = oldTP; - return tree; - } - - public Tree[] transform(Tree[] trees, boolean tailPos) { - boolean oldTP = ctx.tailPosition; - ctx.tailPosition = tailPos; - trees = transform(trees); - ctx.tailPosition = oldTP; - return trees; - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - case DefDef(_, _, _, _, _, Tree rhs): - Context oldCtx = ctx; - - ctx = new Context(); - - //assert method == null: Debug.show(method) + " -- " + tree; - ctx.method = tree.symbol(); - ctx.tailPosition = true; - - if (ctx.method.isMethodFinal() || ctx.method.owner().isMethod()) { - ctx.label = ctx.method.newLabel(ctx.method.pos, ctx.method.name); - ctx.types = Type.EMPTY_ARRAY; - Type type = ctx.method.type(); - switch (type) { - case PolyType(Symbol[] tparams, Type result): - ctx.types = Symbol.type(tparams); - type = result; - } - ctx.label.setInfo(type.cloneType(ctx.method, ctx.label)); - rhs = transform(rhs); - if (ctx.label.isAccessed()) { - global.log("Rewriting def " + ctx.method.simpleName()); - rhs = gen.LabelDef(ctx.label, ctx.method.valueParams(), rhs); - } - tree = gen.DefDef(ctx.method, rhs); - } else { - assert !ctx.method.isMethodFinal() - : "Final method: " + ctx.method.simpleName(); - // non-final method - ctx.tailPosition = false; - tree = gen.DefDef(tree.symbol(), transform(rhs)); - } - ctx = oldCtx; - return tree; - - case Block(Tree[] stats, Tree value): - boolean oldPosition = ctx.tailPosition; - ctx.tailPosition = false; stats = transform(stats); - ctx.tailPosition = oldPosition; - return gen.Block(tree.pos, stats, transform(value)); - - - case If(Tree cond, Tree thenp, Tree elsep): - Type type = tree.type(); - thenp = transform(thenp); - elsep = transform(elsep); - return gen.If(tree.pos, cond, thenp, elsep); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - Type type = tree.type(); - bodies = transform(bodies); - otherwise = transform(otherwise); - return gen.Switch(tree.pos, test, tags, bodies,otherwise,type); - - // handle pattern matches explicitly - case Apply(Select(_, scalac.util.Names._match), Tree[] args): - Tree newTree = global.make.Apply(tree.pos, ((Tree.Apply)tree).fun, transform(args)); - newTree.setType(tree.getType()); - return newTree; - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - if (ctx.method != Symbol.NONE && ctx.tailPosition) { - assert targs != null : "Null type arguments " + tree; - assert ctx.types != null : "Null types " + tree; - - if (!Type.isSameAs(Tree.typeOf(targs), ctx.types) | - !ctx.tailPosition) - return tree; - return transform(tree, fun, transform(vargs, false)); - } else - return tree; - - case Apply(Tree fun, Tree[] vargs): - if (ctx.tailPosition) - return transform(tree, fun, transform(vargs, false)); - else - return gen.mkApply_V(fun, transform(vargs, false)); - - case Visitor(Tree.CaseDef[] cases): - Tree newTree = global.make.Visitor(tree.pos, super.transform(cases)); - newTree.setType(tree.getType()); - return newTree; - - case CaseDef(Tree pattern, Tree guard, Tree body): - return gen.CaseDef(pattern, guard, transform(body)); - - case Typed(Tree expr, Tree type): - return gen.Typed(transform(expr), type); - - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol impl_symbol = getSymbolFor(impl); - Tree[] body = transform(impl.body); - return gen.ClassDef(getSymbolFor(tree), impl.parents, impl_symbol, body); - - case PackageDef(_, _): - case LabelDef(_, _, _): - case Return(_): - return super.transform(tree); - - - case Empty: - case ValDef(_, _, _, _): - case Assign(_, _): - case New(_): - case Super(_, _): - case This(_): - case Select(_, _): - case Ident(_): - case Literal(_): - case TypeTerm(): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - case Function(_, _): - return tree; - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Transforms the given function call. */ - private Tree transform(Tree tree, Tree fun, Tree[] vargs) { - if (fun.symbol() != ctx.method) - return tree; - switch (fun) { - case Select(Tree qual, _): - if (!isReferenceToThis(qual, ctx.method.owner())) - return tree; - global.log("Applying tail call recursion elimination for " + - ctx.method.enclClass().simpleName() + "." + ctx.method.simpleName()); - return gen.Apply(tree.pos, gen.Ident(qual.pos, ctx.label), vargs); - - case Ident(_): - global.log("Applying tail call recursion elimination for function " + - ctx.method.enclClass().simpleName() + "." + ctx.method.simpleName()); - return gen.Apply(tree.pos, gen.Ident(fun.pos, ctx.label), vargs); - - default: - throw Debug.abort("illegal case", fun); - } - } - - /** - * Returns true if the tree represents the current instance of - * given class. - */ - private boolean isReferenceToThis(Tree tree, Symbol clasz) { - switch (tree) { - case This(_): - assert tree.symbol() == clasz: tree +" -- "+ Debug.show(clasz); - return true; - default: - return false; - } - } - - }; - - //######################################################################## -} diff --git a/sources/scalac/transformer/TypesAsValuesPhase.java b/sources/scalac/transformer/TypesAsValuesPhase.java deleted file mode 100644 index 394373bd94..0000000000 --- a/sources/scalac/transformer/TypesAsValuesPhase.java +++ /dev/null @@ -1,1415 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.symtab.Definitions; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Modifiers; -import scalac.atree.AConstant; -import scalac.ast.Transformer; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.TreeGen; -import scalac.ast.TreeList; -import scalac.backend.Primitives; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -import java.util.Map; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Arrays; -import java.util.Collections; - -/** - * Turn types into values by applying the following transformations: - * - * - For all type member T of all classes, add an accessor method - * T$type returnining the type as a value (the accessor is abstract - * if the type member is abstract). - * - * - For all polymorphic methods/constructors, add a value parameter - * for each type parameter. - * - * - Add a method getScalaType to every class, to obtain its type as a - * value. - * - * - Transform all type expressions into value expressions: type - * application is turned into value application, type selection into - * value selection, and so on. - * - * @author Michel Schinz - * @version 1.0 - */ - -// TODO use a constant instead of generating empty arrays all the -// time. - -public class TypesAsValuesPhase extends Phase { - private final GenTransformer transformer; - - /** - * The list of members to add to a given class (either type - * accessors or instantiation methods). - */ - private final HashMap/*<Symbol,Symbol[]>*/ membersToAdd = - new HashMap(); - - /** The list of parameters to add to a given method. */ - private final HashMap/*<Symbol,List<Symbol>>*/ paramsToAdd = - new HashMap(); - - /** The accessor method corresponding to a given type (or class) member. */ - private final HashMap/*<Symbol, Symbol>*/ typeAccessor = - new HashMap(); - - /** The instanciation method corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ instantiator = - new HashMap(); - - /** The lazy parent class corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ lazyParentsClass = - new HashMap(); - - /** The class constructor corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ classInitialiser = - new HashMap(); - - private final HashMap/*<Symbol,Symbol>*/ tConstructor = - new HashMap(); - - private final HashMap/*<Symbol, HashSet<Symbol>>*/ constructorNeed = - new HashMap(); - - private final Definitions defs = global.definitions; - private final Primitives prims = global.primitives; - - private final Type.MethodType typeAccessorType, lazyForceType; - - private final Symbol ARRAY_CONSTRUCTOR = - defs.ARRAY_CLASS.primaryConstructor(); - - private final TEnv EENV = new TEnv(); - - private final Map/*<Symbol, Symbol>*/ predefTypes; - private final Map/*<Type, String>*/ basicTypes; - - private HashMap/*<Symbol, Ancestor[][]>*/ ancestorCache = new HashMap(); - - public TypesAsValuesPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - // If RTT are disabled, use a minimal transformer which simply - // replaces [ia]sInstanceOf with their erased counterpart. - if (global.runTimeTypes && global.target != Global.TARGET_MSIL) { - transformer = new TV_Transformer(global); - typeAccessorType = - new Type.MethodType(new Symbol[]{}, defs.TYPE_TYPE()); - lazyForceType = - new Type.MethodType(Symbol.EMPTY_ARRAY, - defs.ARRAY_TYPE(defs.SCALACLASSTYPE_TYPE())); - predefTypes = new HashMap(); - predefTypes.put(defs.DOUBLE_CLASS, defs.RTT_DOUBLE()); - predefTypes.put(defs.FLOAT_CLASS, defs.RTT_FLOAT()); - predefTypes.put(defs.LONG_CLASS, defs.RTT_LONG()); - predefTypes.put(defs.INT_CLASS, defs.RTT_INT()); - predefTypes.put(defs.SHORT_CLASS, defs.RTT_SHORT()); - predefTypes.put(defs.CHAR_CLASS, defs.RTT_CHAR()); - predefTypes.put(defs.BYTE_CLASS, defs.RTT_BYTE()); - predefTypes.put(defs.BOOLEAN_CLASS, defs.RTT_BOOLEAN()); - predefTypes.put(defs.UNIT_CLASS, defs.RTT_UNIT()); - - predefTypes.put(defs.ANY_CLASS, defs.RTT_ANY()); - predefTypes.put(defs.ANYVAL_CLASS, defs.RTT_ANYVAL()); - predefTypes.put(defs.ALLREF_CLASS, defs.RTT_ALLREF()); - predefTypes.put(defs.ALL_CLASS, defs.RTT_ALL()); - - basicTypes = new HashMap(); - basicTypes.put(defs.BOOLEAN_TYPE(), "Z"); - basicTypes.put(defs.BYTE_TYPE(), "B"); - basicTypes.put(defs.CHAR_TYPE(), "C"); - basicTypes.put(defs.DOUBLE_TYPE(), "D"); - basicTypes.put(defs.FLOAT_TYPE(), "F"); - basicTypes.put(defs.INT_TYPE(), "I"); - basicTypes.put(defs.LONG_TYPE(), "J"); - basicTypes.put(defs.SHORT_TYPE(), "S"); - - membersToAdd.put(defs.ARRAY_CLASS, new Symbol[0]); - paramsToAdd.put(ARRAY_CONSTRUCTOR, new Symbol[0]); - - ancestorCache.put(defs.OBJECT_CLASS, new Ancestor[0][]); - } else { - transformer = new TV_MiniTransformer(global); - typeAccessorType = lazyForceType = null; - predefTypes = basicTypes = null; - } - } - - /** - * Return the symbol of the accessor for the given type symbol. - */ - private Symbol getAccessorSym(Symbol typeSym) { - assert typeSym.isType(); - Symbol accessorSym = (Symbol)typeAccessor.get(typeSym); - if (accessorSym == null) { - accessorSym = typeSym.owner().newVariable(typeSym.pos, - typeSym.flags, - Names.TYPE(typeSym)); - accessorSym.setInfo(defs.TYPE_TYPE()); - typeAccessor.put(typeSym, accessorSym); - } - return accessorSym; - } - - private Symbol getInstMethSym(Symbol classSym) { - Symbol imSym = (Symbol)instantiator.get(classSym); - if (imSym == null) { - int pos = classSym.pos; - boolean isStatic = !isNestedClass(classSym); - Name imName = Names.INSTANTIATE(classSym, isStatic); - - int flags = classSym.isAbstractType() ? Modifiers.DEFERRED : 0; - - imSym = isStatic - ? classSym.newStaticMethod(pos, 0, imName) - : classSym.owner().newMethodOrFunction(pos, flags, imName); - - Symbol[] argTypes; - Symbol typesP = imSym.newVParam(pos, 0, Name.fromString("types")); - typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE())); - argTypes = new Symbol[]{ typesP }; - - imSym.setInfo(new Type.MethodType(argTypes, - isStatic - ? defs.SCALACLASSTYPE_TYPE() - : defs.TYPE_TYPE())); - - instantiator.put(classSym, imSym); - } - return imSym; - } - - private Symbol getLazyParentClassSym(Symbol classSym) { - Symbol lpcSym = (Symbol)lazyParentsClass.get(classSym); - if (lpcSym == null) { - int pos = classSym.pos; - Name lpcName = Names.LAZYPARENTS(classSym); - lpcSym = classSym.owner().newClass(pos, 0, lpcName); - - Type lpcInfo = - Type.compoundType(new Type[] { defs.LAZYPARENTS_TYPE() }, - new Scope(), - lpcSym); - lpcSym.setInfo(lpcInfo); - - Symbol lpcConstrSym = lpcSym.primaryConstructor(); - Symbol typesP = - lpcConstrSym.newVParam(pos, 0, Name.fromString("types")); - typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE())); - - lpcConstrSym.setInfo(new Type.MethodType(new Symbol[]{ typesP }, - defs.UNIT_TYPE())); - - lazyParentsClass.put(classSym, lpcSym); - } - return lpcSym; - } - - private Symbol getTConstructorSym(Symbol classSym) { - Symbol tcSym = (Symbol)tConstructor.get(classSym); - if (tcSym == null) { - int pos = classSym.pos; - boolean isStatic = !isNestedClass(classSym); - Name tcName = Names.TYPECONSTRUCTOR(classSym, isStatic); - - tcSym = isStatic - ? classSym.newStaticField(pos, 0, tcName) - : classSym.owner().newFieldOrVariable(pos, 0, tcName); - tcSym.setInfo(defs.TYPECONSTRUCTOR_TYPE()); - - tConstructor.put(classSym, tcSym); - } - return tcSym; - } - - private Symbol getClassInitSym(Symbol classSym) { - Symbol ciSym = (Symbol)classInitialiser.get(classSym); - if (ciSym == null) { - int pos = classSym.pos; - - ciSym = classSym.newStaticMethod(pos, 0, Names.CLASS_CONSTRUCTOR); - ciSym.setInfo(new Type.MethodType(Symbol.EMPTY_ARRAY, - defs.UNIT_TYPE())); - - classInitialiser.put(classSym, ciSym); - } - return ciSym; - } - - private Symbol[] membersToAdd(Symbol classSym) { - Symbol[] toAdd = (Symbol[])membersToAdd.get(classSym); - if (toAdd == null) { - HashSet seenMembers = new HashSet(); // [HACK] - ArrayList toAddL = new ArrayList(); - Scope.SymbolIterator membersIt = classSym.members().iterator(); - while (membersIt.hasNext()) { - Symbol member = membersIt.next(); - // [HACK] work around a bug in the analyzer, which - // doesn't add the module class to its owner's members - if (member.isModule()) - member = member.moduleClass(); - if (!seenMembers.add(member)) - continue; - if (member.isClass()) { - toAddL.add(getTConstructorSym(member)); - toAddL.add(getInstMethSym(member)); - } else if (member.isType()) - toAddL.add(getInstMethSym(member)); - } - - if (needsInstantiationMethod(classSym)) { - toAddL.add(getTConstructorSym(classSym)); - toAddL.add(getClassInitSym(classSym)); - toAddL.add(getInstMethSym(classSym)); - } - - toAdd = (Symbol[])toAddL.toArray(new Symbol[toAddL.size()]); - membersToAdd.put(classSym, toAdd); - } - return toAdd; - } - - private Symbol[] paramsToAdd(Symbol methSym) { - Symbol[] toAdd = (Symbol[])paramsToAdd.get(methSym); - if (toAdd == null) { - Symbol[] tparams = methSym.typeParams(); - - ArrayList toAddL = new ArrayList(); - for (int i = 0; i < tparams.length; ++i) - toAddL.add(getAccessorSym(tparams[i])); - - toAdd = (Symbol[])toAddL.toArray(new Symbol[toAddL.size()]); - paramsToAdd.put(methSym, toAdd); - } - - return toAdd; - } - - /** - * Return true iff the given symbol is not a polymorphic - * primitive, which shouldn't get type parameters as value - * parameters. - */ - private boolean monoPrimitive(Symbol sym) { - return sym.isJava() - || sym == ARRAY_CONSTRUCTOR - || sym == defs.OBJECT_SYNCHRONIZED - || sym == defs.ANY_IS - || sym == defs.ANY_IS_ERASED - || sym == defs.ANY_AS - || sym == defs.ANY_AS_ERASED; - } - - public Type transformInfo(Symbol symbol, Type type) { - if (!global.runTimeTypes) return type; - - if (symbol.isClass()) { - Symbol[] toAdd = membersToAdd(symbol); - - if (toAdd.length == 0) - return type; - else { - Scope newMembers = new Scope(symbol.members()); - - for (int i = 0; i < toAdd.length; ++i) - newMembers.enterOrOverload(toAdd[i]); - - return Type.compoundType(type.parents(), newMembers, symbol); - } - } else if (type.typeParams().length > 0 && !monoPrimitive(symbol)) { - // Polymorphic method/constructor: - // - add a value parameter for every type parameter. - switch (type) { - case PolyType(Symbol[] tparams, // : - Type.MethodType(Symbol[] vparams, Type result)): - List newVParams = - new LinkedList(Arrays.asList(paramsToAdd(symbol))); - newVParams.addAll(Arrays.asList(vparams)); - Symbol[] newVParamsA = (Symbol[]) - newVParams.toArray(new Symbol[newVParams.size()]); - - return new Type.PolyType(tparams, - new Type.MethodType(newVParamsA, - result)); - - default: - throw Debug.abort("unexpected type: ", type); - } - } else - return type; - } - - /** - * Return true iff the given type is trivial, that is if it - * has neither a prefix, nor type parameters. - */ - private boolean isTrivial(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, Type[] args): - if (sym == defs.ARRAY_CLASS) - return isTrivial(args[0]); - else - return sym.isStatic() && args.length == 0; - case SingleType(_, _): - case ThisType(_): - case CompoundType(_, _): - return false; - default: - throw Debug.abort("unexpected type", tp); - } - } - - /** - * Return true iff the given type is strongly trivial, that is - * if it and all its ancestors are trivial. - */ - private boolean isStronglyTrivial(Type tp) { - if (isTrivial(tp)) { - Type[] parents = tp.parents(); - for (int i = 0; i < parents.length; ++i) { - if (!isStronglyTrivial(parents[i])) - return false; - } - return true; - } else - return false; - } - - private boolean isNestedClass(Symbol classSym) { - return !classSym.owner().isPackageClass(); - } - - private boolean needsInstantiationMethod(Symbol classSym) { - return !(isNestedClass(classSym) || isStronglyTrivial(classSym.type())); - } - - public void apply(CompilationUnit unit) { - transformer.apply(unit); - } - - private class TV_Transformer extends TV_MiniTransformer { - private Symbol currentOwner; - private TreeList additionalTopLevelClasses; - - public TV_Transformer(Global global) { - super(global); - } - - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - additionalTopLevelClasses = new TreeList(); - TreeList newUnitBody = new TreeList(transform(unit.body)); - newUnitBody.append(additionalTopLevelClasses); - additionalTopLevelClasses = null; - unit.body = newUnitBody.toArray(); - } - - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol clsSym = tree.symbol(); - - TreeList newBody = new TreeList(); - if (needsInstantiationMethod(clsSym)) { - boolean lazy = isCyclic(clsSym); - - Symbol tcSym = getTConstructorSym(clsSym); - newBody.append(tConstructorVal(clsSym, tcSym)); - Symbol ciSym = getClassInitSym(clsSym); - newBody.append(classInitialiser(clsSym, ciSym, tcSym)); - Symbol imSym = getInstMethSym(clsSym); - newBody.append(instantiatorBody(clsSym, imSym, lazy)); - - if (lazy) { - Symbol lpcSym = getLazyParentClassSym(clsSym); - Tree lpc = lazyParentsClass(clsSym, lpcSym); - additionalTopLevelClasses.append(lpc); - } - } - newBody.append(transformStatements(impl.body, impl.symbol())); - - return gen.ClassDef(clsSym, - transform(impl.parents, - clsSym.primaryConstructor()), - impl.symbol(), - newBody.toArray()); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - - if (symbol.name == Names.getScalaType && symbol.isSynthetic()) { - // Correct the body of the getScalaType method - // which, until now, was a placeholder (introduced - // by RefCheck). - return gen.DefDef(symbol, - scalaClassType(symbol.pos, - symbol.owner().type(), - symbol, - EENV)); - } else - return gen.DefDef(symbol, transform(rhs, symbol)); - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, - transformStatements(stats), - transform(value)); - - case ValDef(_, _, Tree tpe, Literal(AConstant.ZERO)): - // transform default values: - // val x: T = _ - // becomes - // val x: T = asValue(T).defaultValue() - Symbol symbol = getSymbolFor(tree); - Tree defaultValue = - gen.mkRef(tree.pos, - typeAsValue(tree.pos, - tpe.type, - currentOwner, - EENV), - defs.TYPE_DEFAULTVALUE()); - Tree rhs = gen.mkApply__(tree.pos, defaultValue); - return gen.ValDef(symbol, rhs); - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.ValDef(symbol, transform(rhs, symbol)); - - case New(Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs)): - if (fun.symbol() == ARRAY_CONSTRUCTOR - && targs[0].type().symbol().isParameter()) { - // Transform array creations: - // new Array[T](size) - // becomes - // asValue(T).newArray[T](size) - assert targs.length == 1; - assert vargs.length == 1; - Tree newArrayfun = gen.mkRef(tree.pos, - typeAsValue(targs[0].pos, - targs[0].type(), - currentOwner, - EENV), - defs.TYPE_NEWARRAY()); - return gen.mkApplyTV(newArrayfun, targs, vargs); - } else - return super.transform(tree); - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - Symbol funSym = fun.symbol(); - - if (funSym == defs.ANY_IS) { - assert targs.length == 1 && vargs.length == 0; - Type type = targs[0].type; - Tree expr = transform(qualifierOf(fun)); - return (isTrivial(type) && !isSpecial(type)) - ? super.transform(tree) - : genInstanceTest(tree.pos, expr, type); - } else if (funSym == defs.ANY_AS) { - // Transform instance tests: - // e.asInstanceOf[T] - // becomes: - // asValue(T).cast(e).asInstanceOf[T] - // unless T is a trivial type for which a Java - // instance test is sufficient, in which case the - // erased version of asInstanceOf is used. - assert targs.length == 1 && vargs.length == 0; - Type type = targs[0].type; - Tree expr = transform(qualifierOf(fun)); - return (isTrivial(type) && !isSpecial(type)) - ? super.transform(tree) - : genTypeCast(tree.pos, expr, type); - } else if (!monoPrimitive(funSym)) { - // Transform applications to pass types as values: - // f[T1, ...](v1, ...) - // becomes - // f[T1, ...](asValue(T1), ..., v1, ...) - Tree[] newVArgs = transform(vargs); - Tree[] finalVArgs = - new Tree[newVArgs.length + targs.length]; - for (int i = 0; i < targs.length; ++i) - finalVArgs[i] = typeAsValue(targs[i].pos, - targs[i].type, - currentOwner, - EENV); - System.arraycopy(newVArgs, 0, - finalVArgs, targs.length, - newVArgs.length); - return gen.mkApplyTV(tree.pos, - transform(fun), - targs, - finalVArgs); - } else - return super.transform(tree); - - default: - return super.transform(tree); - } - } - - private Tree[] transformStatements(Tree[] stats) { - ArrayList newStats = new ArrayList(); - int beginIdx = 0; - for (int i = 0; i < stats.length; ++i) { - Tree stat = stats[i]; - switch (stat) { - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol clsSym = stat.symbol(); - boolean lazy = isCyclic(clsSym); - Symbol tcSym = getTConstructorSym(clsSym); - newStats.add(beginIdx++, tConstructorVal(clsSym, tcSym)); - Symbol insSym = getInstMethSym(clsSym); - newStats.add(instantiatorBody(clsSym, insSym, lazy)); - if (lazy) { - Symbol lpcSym = getLazyParentClassSym(clsSym); - newStats.add(lazyParentsClass(clsSym, lpcSym)); - } - break; - - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - Symbol tpSym = stat.symbol(); - Symbol insSym = getInstMethSym(tpSym); - newStats.add(typeAccessorBody(tpSym, insSym)); - break; - } - newStats.add(transform(stat)); - } - return (Tree[])newStats.toArray(new Tree[newStats.size()]); - } - - private Tree[] transformStatements(Tree[] stats, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree[] newStats = transformStatements(stats); - this.currentOwner = bkpOwner; - return newStats; - } - - private Tree transform(Tree tree, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree newTree = transform(tree); - this.currentOwner = bkpOwner; - return newTree; - } - - private Tree[] transform(Tree[] trees, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree[] newTrees = transform(trees); - this.currentOwner = bkpOwner; - return newTrees; - } - - private int level(Symbol sym) { - Symbol superClass = sym.parents()[0].symbol(); - assert superClass != Symbol.NONE : sym; - if (superClass == defs.ANY_CLASS) - return 0; - else - return 1 + level(superClass); - } - - /** - * Return a method giving access to the given type, as a - * value. - */ - private Tree.DefDef typeAccessorBody(Symbol typSym, Symbol accSym) { - Tree rhs; - if (typSym.isAbstractType()) - rhs = Tree.Empty; - else if (typSym.isClass()) - rhs = scalaClassType(typSym.pos, typSym.type(), accSym, EENV); - else { - final Symbol[] vparams = accSym.valueParams(); - final int pos = accSym.pos; - - final HashMap varMap = new HashMap(); - Symbol[] tparams = typSym.typeParams(); - for (int i = 0; i < tparams.length; ++i) - varMap.put(tparams[i], new Integer(i)); - - TEnv tEnv = new TEnv() { - public boolean definesVar(Symbol sym) { - return varMap.containsKey(sym); - } - - public Tree treeForVar(Symbol sym) { - int idx = ((Integer)varMap.get(sym)).intValue(); - Tree array = gen.mkLocalRef(pos, vparams[0]); - return gen.mkArrayGet(pos, array, idx); - } - }; - - rhs = typeAsValue(typSym.pos, typSym.type(), accSym, tEnv); - } - return gen.DefDef(accSym, rhs); - } - - private Tree tConstructorVal(Symbol clsSym, Symbol tcSym) { - return gen.ValDef(tcSym, - tcSym.isStatic() - ? Tree.Empty - : tConstructorRHS(tcSym.pos, clsSym, tcSym)); - } - - private Tree classInitialiser(Symbol clsSym, - Symbol ciSym, - Symbol tcSym) { - if (tcSym.isStatic()) { - int pos = tcSym.pos; - Tree rhs = tConstructorRHS(pos, clsSym, ciSym); - Tree assign = gen.Assign(pos, gen.Ident(pos, tcSym), rhs); - - return gen.DefDef(ciSym, assign); - } else - return Tree.Empty; - } - - private Tree tConstructorRHS(int pos, Symbol clsSym, Symbol owner) { - int zCount = 0, mCount = 0, pCount = 0; - Symbol[] tparams = clsSym.typeParams(); - - for (int i = 0; i < tparams.length; ++i) { - if ((tparams[i].flags & Modifiers.COVARIANT) != 0) - ++pCount; - else if ((tparams[i].flags & Modifiers.CONTRAVARIANT) != 0) - ++mCount; - else - ++zCount; - } - - Ancestor[][] ancestors = computeAncestors(clsSym); - int[] ancestorCode = getAncestorCode(ancestors); - - Tree outer = isNestedClass(clsSym) - ? (clsSym.owner().isClass() - ? gen.This(pos, clsSym.owner()) - : gen.mkGlobalRef(pos, defs.TYPECONSTRUCTOR_FUNCTIONOUTER())) - : gen.mkNullLit(pos); - - Tree[] tcArgs = new Tree[] { - gen.mkIntLit(pos, level(clsSym)), - gen.mkSymbolNameLit(pos, clsSym), - outer, - gen.mkIntLit(pos, zCount), - gen.mkIntLit(pos, mCount), - gen.mkIntLit(pos, pCount), - gen.mkIntLit(pos, ancestors.length), - ancestorCode.length == 0 - ? gen.mkNullLit(pos) - : mkNewIntLitArray(pos, getAncestorCode(ancestors), owner) - }; - - Symbol tcConst = defs.TYPECONSTRUCTOR_CLASS.primaryConstructor(); - Tree tcCall = - gen.mkApply_V(pos, gen.mkGlobalRef(pos, tcConst), tcArgs); - return gen.New(pos, tcCall); - } - - private Tree mkNewIntLitArray(int pos, int[] values, Symbol owner) { - Tree[] intLits = new Tree[values.length]; - for (int i = 0; i < values.length; ++i) - intLits[i] = gen.mkIntLit(pos, values[i]); - return gen.mkNewArray(pos, defs.INT_TYPE(), intLits, owner); - } - - private Tree lazyParentsClass(Symbol clsSym, Symbol lazyClsSym) { - int pos = clsSym.pos; - - Symbol typesSym = lazyClsSym.primaryConstructor().valueParams()[0]; - - Symbol forceSym = lazyClsSym.newMethod(pos, 0, Names.force); - forceSym.setInfo(lazyForceType); - lazyClsSym.members().enter(forceSym); - Tree.DefDef forceDef = - gen.DefDef(forceSym, - parentsArray(pos, clsSym, typesSym, forceSym)); - - return gen.ClassDef(lazyClsSym, new Tree[] { forceDef }); - } - - /** - * Return a method to instantiate the given type. - */ - private Tree.DefDef instantiatorBody(Symbol clsSym, - Symbol insSym, - boolean lazy) { - // TODO fix flags for all symbols below - final int pos = clsSym.pos; - final Symbol typesArr = insSym.valueParams()[0]; - - Tree[] body = new Tree[2]; - - // Generate call to "getInstantiation" method of - // constructor. - Tree getInstFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_GETINSTANTIATION()); - - Tree[] getInstArgs = new Tree[]{ gen.mkLocalRef(pos, typesArr) }; - - Symbol instVal = - insSym.newVariable(pos, 0, Name.fromString("inst")); - instVal.setInfo(defs.SCALACLASSTYPE_TYPE()); - - Tree instValDef = - gen.ValDef(instVal, - gen.mkApply_V(pos, getInstFun, getInstArgs)); - - // Generate test to see if a call to "instantiate" is - // necessary. - Tree cond = - gen.mkApply_V(pos, - gen.Select(pos, - gen.mkLocalRef(pos, instVal), - defs.ANY_BANGEQ), - new Tree[] { gen.mkNullLit(pos) }); - Tree thenP = gen.mkLocalRef(pos, instVal); - Tree elseP = lazy - ? lazyInstantiateCall(pos, clsSym, typesArr) - : strictInstantiateCall(pos, clsSym, typesArr, insSym); - Tree ifExpr = - gen.If(pos, cond, thenP, elseP, defs.SCALACLASSTYPE_TYPE()); - - return gen.DefDef(insSym, gen.mkBlock(pos, instValDef, ifExpr)); - } - - private Tree strictInstantiateCall(int pos, - Symbol clsSym, - Symbol tpArraySym, - Symbol owner) { - Tree instFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_INSTANTIATE()); - Tree[] instArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym), - parentsArray(pos, clsSym, tpArraySym, owner) - }; - return gen.mkApply_V(pos, instFun, instArgs); - } - - private Tree lazyInstantiateCall(int pos, - Symbol clsSym, - Symbol tpArraySym) { - Tree instFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_INSTANTIATE()); - Symbol lpcSym = getLazyParentClassSym(clsSym); - Tree lazyConstr = - gen.mkPrimaryConstructorLocalRef(pos, lpcSym); - Tree[] lazyConstrArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym) - }; - Tree[] instArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym), - gen.New(pos, gen.mkApply_V(lazyConstr, lazyConstrArgs)) - }; - return gen.mkApply_V(pos, instFun, instArgs); - } - - private Tree parentsArray(final int pos, - final Symbol clsSym, - final Symbol tpArraySym, - final Symbol owner) { - final HashMap varMap = new HashMap(); - final Symbol[] tparams = clsSym.typeParams(); - for (int i = 0; i < tparams.length; ++i) - varMap.put(tparams[i], new Integer(i)); - - // Type environment mapping the type parameters of the - // class to their corresponding element in the "types" - // array passed to this instantiator. - TEnv tEnv = new TEnv() { - public boolean definesVar(Symbol sym) { - return varMap.containsKey(sym); - } - public Tree treeForVar(Symbol sym) { - int idx = ((Integer)varMap.get(sym)).intValue(); - Tree array = gen.mkLocalRef(pos, tpArraySym); - return gen.mkArrayGet(pos, array, idx); - } - public boolean definesVarArray(Symbol[] syms) { - if (syms.length == tparams.length) { - for (int i = 0; i < syms.length; ++i) { - if (syms[i] != tparams[i]) - return false; - } - return true; - } else - return false; - } - public Tree treeForVarArray(Symbol[] syms) { - assert definesVarArray(syms); - return gen.mkLocalRef(pos, tpArraySym); - } - }; - - Type[] parents = clsSym.parents(); - TreeList parentTypes = new TreeList(); - for (int i = 0; i < parents.length; ++i) { - Type parent = parents[i]; - if (!isStronglyTrivial(parent)) - parentTypes.append(typeAsValue(pos, parent, owner, tEnv)); - } - boolean emptyParents = (parentTypes.length() == 0); - return emptyParents - ? gen.mkGlobalRef(pos, defs.SCALACLASSTYPE_EMPTYARRAY()) - : gen.mkNewArray(pos, - defs.SCALACLASSTYPE_TYPE(), - parentTypes.toArray(), - owner); - } - - /** - * Generate code to test if the given expression is an - * instance of the given type. - */ - private Tree genInstanceTest(int pos, Tree expr, Type tp) { - Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - - if (isKnowClassType(tp)) { - Symbol val = - currentOwner.newVariable(pos, - Modifiers.SYNTHETIC, - Names.LOCAL(currentOwner)); - val.setType(expr.type); - - Tree valDef = gen.ValDef(val, expr); - - Tree cheapTest = - gen.mkIsInstanceOf(pos, gen.mkLocalRef(pos, val), tp, true); - Symbol isNonTrivialInst = defs.CLASSTYPE_ISNONTRIVIALINSTANCE(); - Tree scalaTpVal = gen.mkAsInstanceOf(pos, - tpVal, - defs.CLASSTYPE_TYPE(), - true); - Tree expensiveTest = - gen.mkApply_V(pos, - gen.Select(pos, scalaTpVal, isNonTrivialInst), - new Tree[] { gen.mkLocalRef(pos, val) }); - - Tree bothTests = - gen.mkApply_V(pos, - gen.Select(pos, - cheapTest, - defs.BOOLEAN_AND()), - new Tree[] { expensiveTest }); - - return gen.mkBlock(pos, valDef, bothTests); - } else { - Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); - return gen.mkApply_V(pos, fun, new Tree[] { expr }); - } - } - - /** - * Generate code to cast the given value to the given type. - */ - private Tree genTypeCast(int pos, Tree expr, Type tp) { - Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - Tree fun = gen.Select(pos, tpVal, defs.TYPE_CAST()); - Tree castCall = gen.mkApply_V(pos, fun, new Tree[] { expr }); - return gen.mkAsInstanceOf(pos, castCall, tp); - } - - private boolean isSpecial(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, _): - return (sym == defs.ANY_CLASS) - || (sym == defs.ANYVAL_CLASS) - || (sym == defs.ALLREF_CLASS) - || (sym == defs.ALL_CLASS); - default: - return false; - } - } - - private boolean isKnowClassType(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, _): - return (sym != defs.ARRAY_CLASS) && !sym.isParameter(); - default: - return false; - } - } - - private void addConstructorsNeededBy(HashSet roots, - Type tp, - HashSet set){ - switch (tp) { - case TypeRef(_, Symbol pSym, Type[] args): - if (!pSym.isParameter()) { - set.add(pSym); - set.addAll(constructorsNeededBy(roots, pSym)); - for (int i = 0; i < args.length; ++i) - addConstructorsNeededBy(roots, args[i], set); - } - break; - case CompoundType(Type[] parts, _): - for (int i = 0; i < parts.length; ++i) - addConstructorsNeededBy(roots, parts[i], set); - default: - ; // nothing to do - } - } - - private HashSet constructorsNeededBy(HashSet roots, Symbol sym) { - HashSet constr = new HashSet(); - if (roots.add(sym)) { - Type[] parents = sym.parents(); - for (int i = 0; i < parents.length; ++i) - addConstructorsNeededBy(roots, parents[i], constr); - } - return constr; - } - - private HashSet constructorsNeededBy(Symbol sym) { - HashSet constr = (HashSet)constructorNeed.get(sym); - if (constr == null) { - constr = constructorsNeededBy(new HashSet(), sym); - constructorNeed.put(sym, constr); - } - return constr; - } - - private boolean isCyclic(Symbol sym) { - HashSet constrs = constructorsNeededBy(sym); - if (constrs.contains(sym)) - return true; - Iterator constrsIt = constrs.iterator(); - while (constrsIt.hasNext()) { - Symbol constr = (Symbol)constrsIt.next(); - if (constr.isAbstractType()) - return true; - } - return false; - } - - /** - * Transform a type into a tree representing it. - */ - private Tree typeAsValue(int pos, Type tp, Symbol owner, TEnv env) { - switch (tp) { - case ConstantType(Type base, _): - return typeAsValue(pos, base, owner, env); - - case TypeRef(Type pre, Symbol sym, Type[] args): - if (env.definesVar(sym)) { - assert args.length == 0; - return env.treeForVar(sym); - } else if (sym == defs.ARRAY_CLASS) { - assert args.length == 1; - return arrayType(pos, args[0], owner, env); - } else if (predefTypes.containsKey(sym)) { - return gen.mkGlobalRef(pos, (Symbol)predefTypes.get(sym)); - } else if (sym.isJava()) { - assert args.length <= 1 - : Debug.show(sym) + " " + args.length; - return javaClassType(pos, sym); - } else if (!sym.isParameter()) { - // Reference to a "global" type. - return scalaClassType(pos, tp, owner, env); - } else { - assert !isValuePrefix(pre) : tp; - return gen.mkLocalRef(pos, getAccessorSym(sym)); - } - - case SingleType(Type pre, Symbol sym): - return singleType(pos, (Type.SingleType)tp); - - case ThisType(Symbol sym): - return thisType(pos, sym); - - case CompoundType(Type[] parts, Scope members): - return compoundType(pos, parts, members, owner, env); - - default: - throw Debug.abortIllegalCase(tp); - } - } - - private Tree arrayType(int pos, - Type elemType, - Symbol owner, - TEnv env) { - Type realElemType = elemType; - int dimensions = 1; - while (realElemType.symbol() == defs.ARRAY_CLASS) { - realElemType = realElemType.typeArgs()[0]; - ++dimensions; - } - - if (isTrivial(elemType)) { - Tree nameLit; - if (basicTypes.containsKey(elemType)) - nameLit = - gen.mkStringLit(pos, (String)basicTypes.get(elemType)); - else - nameLit = gen.mkSymbolNameLit(pos, realElemType.symbol()); - - Tree constr = - gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVAARRAYTYPE()); - Tree[] args = new Tree[]{ - nameLit, - gen.mkIntLit(pos, dimensions) - }; - return gen.mkApply_V(constr, args); - } else { - Tree constr = - gen.mkGlobalRef(pos, - defs.JAVAREFARRAYTYPE_JAVAREFARRAYTYPE()); - Tree[] args = new Tree[]{ - typeAsValue(pos, elemType, owner, env), - gen.mkIntLit(pos, dimensions) - }; - return gen.mkApply_V(constr, args); - } - } - - private Tree javaClassType(int pos, Symbol sym) { - Tree constr = - gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVACLASSTYPE()); - Tree nameLit = gen.mkSymbolNameLit(pos, sym); - Tree[] args = new Tree[] { nameLit }; - return gen.mkApply_V(constr, args); - } - - private Tree thisType(int pos, Symbol sym) { - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, defs.SINGLETYPE_CLASS); - Tree[] args = new Tree[] { gen.This(pos, sym) }; - return gen.New(pos, gen.mkApply_V(constr, args)); - } - - private Tree singleType(int pos, Type.SingleType tp) { - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, defs.SINGLETYPE_CLASS); - Tree[] args = new Tree[] { gen.mkQualifier(pos, tp) }; - return gen.New(pos, gen.mkApply_V(constr, args)); - } - - private Tree compoundType(int pos, - Type[] parts, - Scope members, - Symbol owner, - TEnv env) { - Tree[] partsT = new Tree[parts.length]; - for (int i = 0; i < parts.length; ++i) - partsT[i] = typeAsValue(pos, parts[i], owner, env); - - Tree[] constrArgs = new Tree[] { - gen.mkNewArray(pos, defs.CLASSTYPE_TYPE(), partsT, owner), - gen.mkBooleanLit(pos, members.isEmpty()) - }; - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, - defs.COMPOUNDTYPE_CLASS); - return gen.New(pos, gen.mkApply_V(constr, constrArgs)); - } - - private Tree scalaClassType(int pos, Type tp, Symbol owner, TEnv env) { - if (isStronglyTrivial(tp)) - return javaClassType(pos, tp.symbol()); - - switch (tp) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Symbol insSym = getInstMethSym(sym); - Tree preFun = (isNestedClass(sym) && sym.owner().isClass()) - ? gen.Select(pos, gen.mkQualifier(pos, pre), insSym) - : gen.Ident(pos, insSym); - - Tree insArg; - int[] perm = typeParamsPermutation(sym.typeParams()); - Symbol[] permArgs = new Symbol[args.length]; - for (int i = 0; i < args.length; ++i) - permArgs[i] = args[perm[i]].symbol(); - - if (env.definesVarArray(permArgs)) - insArg = env.treeForVarArray(permArgs); - else { - Tree[] tps = new Tree[args.length]; - for (int i = 0; i < args.length; ++i) - tps[i] = typeAsValue(pos, args[perm[i]], owner, env); - insArg = gen.mkNewArray(pos, defs.TYPE_TYPE(), tps, owner); - } - - return gen.mkApply_V(pos, preFun, new Tree[] { insArg }); - - default: - throw Debug.abort("unexpected type: ", tp); - } - } - - private final int VARIANT = - Modifiers.COVARIANT | Modifiers.CONTRAVARIANT; - - /** - * Compute the (unique) permutation which puts all invariant - * type parameters first, followed by the contravariant ones, - * then the covariants, preserving the relative ordering of - * arguments with same variance. - */ - private int[] typeParamsPermutation(Symbol[] params) { - int[] tparamsPerm = new int[params.length]; - int permIdx = 0; - - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & VARIANT) == 0) - tparamsPerm[permIdx++] = i; - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & Modifiers.CONTRAVARIANT) != 0) - tparamsPerm[permIdx++] = i; - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & Modifiers.COVARIANT) != 0) - tparamsPerm[permIdx++] = i; - assert permIdx == tparamsPerm.length; - - return tparamsPerm; - } - - private boolean isValuePrefix(Type pre) { - switch (pre) { - case ThisType(Symbol clazz): - return !(clazz.isPackage() || clazz.isNone()); - case NoPrefix: - return false; - default: - return true; - } - } - - private Ancestor[][] computeAncestors0(Symbol classSym) { - Symbol[] nstParents = notStronglyTrivialParents(classSym); - int level = level(classSym); - ArrayList/*<Ancestor>*/[] ancestor = new ArrayList[level + 1]; - - for (int l = 0; l < ancestor.length; ++l) - ancestor[l] = new ArrayList(); - - if (!isTrivial(classSym.type())) - ancestor[level].add(new Ancestor(classSym, -1, -1)); - - // Go over parents from left to right and add missing - // ancestors to the set, remembering where they come from. - for (int p = 0; p < nstParents.length; ++p) { - Symbol parentSymbol = nstParents[p]; - Ancestor[][] parentAncestors = computeAncestors(parentSymbol); - assert parentAncestors.length <= ancestor.length; - - for (int l = 0; l < parentAncestors.length; ++l) { - ArrayList/*<Ancestor>*/ myRow = ancestor[l]; - Ancestor[] parentRow = parentAncestors[l]; - parentRowLoop: - for (int i = 0; i < parentRow.length; ++i) { - Symbol sym = parentRow[i].symbol; - assert !isTrivial(sym.type()) : sym; - - Iterator myRowIt = myRow.iterator(); - while (myRowIt.hasNext()) { - Ancestor myAncestor = (Ancestor)myRowIt.next(); - if (myAncestor.symbol == sym) - continue parentRowLoop; - } - myRow.add(new Ancestor(sym, p, i)); - } - } - } - - int ancestorsLen = ancestor.length; - while (ancestorsLen > 0 && ancestor[ancestorsLen - 1].isEmpty()) - --ancestorsLen; - - Ancestor[][] finalAncestor = new Ancestor[ancestorsLen][]; - for (int i = 0; i < finalAncestor.length; ++i) { - finalAncestor[i] = (Ancestor[]) - ancestor[i].toArray(new Ancestor[ancestor[i].size()]); - } - - return finalAncestor; - } - - /** Return the non-trivial ancestors of the class */ - private Ancestor[][] computeAncestors(Symbol classSym) { - Ancestor[][] ancestor = (Ancestor[][])ancestorCache.get(classSym); - if (ancestor == null) { - ancestor = computeAncestors0(classSym); - ancestorCache.put(classSym, ancestor); -// debugPrintAncestor(classSym, ancestor); - } - return ancestor; - } - - /** Return the parents which are not strongly trivial. */ - private Symbol[] notStronglyTrivialParents(Symbol classSym) { - Type[] parentTypes = classSym.parents(); - ArrayList nstParents = new ArrayList(parentTypes.length); - for (int i = 0; i < parentTypes.length; ++i) { - if (!isStronglyTrivial(parentTypes[i])) - nstParents.add(parentTypes[i].symbol()); - } - return (Symbol[]) - nstParents.toArray(new Symbol[nstParents.size()]); - } - - private int[] getAncestorCode(Ancestor[][] ancestor) { - ArrayList/*<Ancestor>*/[] prunedRows = - new ArrayList[ancestor.length]; - - int totalSize = 0; - for (int l = 0; l < ancestor.length; ++l) { - Ancestor[] row = ancestor[l]; - ArrayList/*<Ancestor>*/ prunedRow = new ArrayList(row.length); - for (int i = 0; i < row.length; ++i) { - if (row[i].parentIndex > 0) - prunedRow.add(row[i]); - } - prunedRows[l] = prunedRow; - if (!prunedRow.isEmpty()) - totalSize += 2 + 2 * prunedRow.size(); - } - - int[] res = new int[totalSize]; - int i = 0; - for (int l = 0; l < prunedRows.length; ++l) { - ArrayList row = prunedRows[l]; - if (!row.isEmpty()) { - res[i++] = l; - res[i++] = row.size(); - Iterator ancIt = row.iterator(); - while (ancIt.hasNext()) { - Ancestor anc = (Ancestor)ancIt.next(); - res[i++] = anc.parentIndex; - res[i++] = anc.position; - } - } - } - assert i == totalSize; - return res; - } - } - - /** - * Minimalistic transformer, which simply transforms calls to - * isInstanceOf/asInstanceOf by calls to their erased - * counterparts. Used when full run time types are disabled. - */ - private class TV_MiniTransformer extends GenTransformer { - private final Definitions defs; - - public TV_MiniTransformer(Global global) { - super(global); - defs = global.definitions; - } - - public Tree transform(Tree tree) { - switch (tree) { - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - Symbol funSym = fun.symbol(); - if (funSym == defs.ANY_IS || funSym == defs.ANY_AS) { - assert vargs.length == 0; - Symbol erasedSym = (funSym == defs.ANY_AS) - ? defs.ANY_AS_ERASED - : defs.ANY_IS_ERASED; - return gen.mkApplyTV(tree.pos, - gen.Select(fun.pos, - transform(qualifierOf(fun)), - erasedSym), - targs, - vargs); - } else - return super.transform(tree); - - default: - return super.transform(tree); - } - } - } - - /** - * Extract qualifier from a tree, which must be a Select node. - */ - private Tree qualifierOf(Tree tree) { - switch (tree) { - case Select(Tree qualifier, _): return qualifier; - default: throw Debug.abort("cannot extract qualifier from ", tree); - } - } - - // Debugging function - private void debugPrintAncestor(Symbol sym, Ancestor[][] ancestor) { - System.out.println("ancestor for " + Debug.show(sym)); - for (int l = 0; l < ancestor.length; ++l) { - System.out.print(" [" + l + "] "); - for (int i = 0; i < ancestor[l].length; ++i) { - if (i > 0) - System.out.print(" "); - System.out.println(" " + Debug.show(ancestor[l][i].symbol) - + "/par" + ancestor[l][i].parentIndex - + "/pos" + ancestor[l][i].position); - } - if (ancestor[l].length == 0) - System.out.println("<empty>"); - } - } - - ////////////////////////////////////////////////////////////////////// - - private static class TEnv { - public boolean definesVar(Symbol sym) { - return false; - } - public Tree treeForVar(Symbol sym) { - throw Debug.abort("no tree for variable " + sym); - } - public boolean definesVarArray(Symbol[] syms) { - return false; - } - public Tree treeForVarArray(Symbol[] syms) { - throw Debug.abort("no tree for variable array " + syms); - } - } - - private static class Ancestor { - public static final Ancestor[] EMPTY_ARRAY = new Ancestor[0]; - - public final Symbol symbol; - public final int parentIndex; - public final int position; - - public Ancestor(Symbol symbol, int parentIndex, int position) { - this.symbol = symbol; - this.parentIndex = parentIndex; - this.position = position; - } - } -} diff --git a/sources/scalac/transformer/WholeProgPhase.java b/sources/scalac/transformer/WholeProgPhase.java deleted file mode 100644 index 7591352c21..0000000000 --- a/sources/scalac/transformer/WholeProgPhase.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; - -/** - * This class represents the wholeprog phase for the java version of - * the compiler. It doesn't do anything but permit to make a bridge - * between the java implementation of Socos and the scala one. See - * scala.tools.scalac.wholeprog.WholeProgPhase for implementation. - */ -public abstract class WholeProgPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public WholeProgPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## -} diff --git a/sources/scalac/typechecker/AnalyzerPhase.java b/sources/scalac/typechecker/AnalyzerPhase.java deleted file mode 100644 index 517d4713dc..0000000000 --- a/sources/scalac/typechecker/AnalyzerPhase.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.typechecker; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.ast.TreeGen; -import scalac.symtab.Definitions; -import scalac.symtab.Symbol; - - -public abstract class AnalyzerPhase extends Phase { - - public final TreeGen gen; - - /** Initializes this instance. */ - public AnalyzerPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - global.definitions = new Definitions(global); - this.gen = new TreeGen(global, global.make); - } - - public abstract void addConsoleImport(Symbol module); - -} diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java deleted file mode 100644 index 528ca7b47d..0000000000 --- a/sources/scalac/typechecker/Infer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.typechecker; - -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -public abstract class Infer { - - /** throw a type error if arguments not within bounds. - */ - public abstract void checkBounds(Symbol[] tparams, Type[] targs, String prefix); - - - public abstract Type skipViewParams(Symbol[] tparams, Type tp); - -} diff --git a/sources/scalac/util/AbstractFileReader.java b/sources/scalac/util/AbstractFileReader.java deleted file mode 100644 index bf3d6f437d..0000000000 --- a/sources/scalac/util/AbstractFileReader.java +++ /dev/null @@ -1,113 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.util; - -import java.io.IOException; - -import scala.tools.util.AbstractFile; - -public class AbstractFileReader { - - /** the buffer containing the file - */ - public byte[] buf; - - /** the current input pointer - */ - public int bp; - - /** the file path name - */ - public final String path; - - /** constructor - */ - public AbstractFileReader(AbstractFile f) throws IOException { - buf = f.read(); - bp = 0; - path = f.getPath(); - } - - /** return byte at offset 'pos' - */ - public byte byteAt(int pos) { - return buf[pos]; - } - - /** read a byte - */ - public byte nextByte() { - return buf[bp++]; - } - - /** read some bytes - */ - public byte[] nextBytes(int len) { - byte[] res = new byte[len]; - System.arraycopy(buf, bp, res, 0, len); - bp += len; - return res; - } - - /** read a character - */ - public char nextChar() { - return - (char)(((buf[bp++] & 0xff) << 8) + - (buf[bp++] & 0xff)); - } - - /** read an integer - */ - public int nextInt() { - return ((buf[bp++] & 0xff) << 24) + - ((buf[bp++] & 0xff) << 16) + - ((buf[bp++] & 0xff) << 8) + - (buf[bp++] & 0xff); - } - - /** extract a character at position bp from buf - */ - public char getChar(int mybp) { - return (char)(((buf[mybp] & 0xff) << 8) + (buf[mybp+1] & 0xff)); - } - - /** extract an integer at position bp from buf - */ - public int getInt(int mybp) { - return ((buf[mybp ] & 0xff) << 24) + - ((buf[mybp+1] & 0xff) << 16) + - ((buf[mybp+2] & 0xff) << 8) + - (buf[mybp+3] & 0xff); - } - - /** extract a long integer at position bp from buf - */ - public long getLong(int mybp) { - return ((long)(getInt(mybp)) << 32) + (getInt(mybp + 4) & 0xffffffffL); - } - - /** extract a float at position bp from buf - */ - public strictfp float getFloat(int mybp) { - return Float.intBitsToFloat(getInt(mybp)); - } - - /** extract a double at position bp from buf - */ - public strictfp double getDouble(int mybp) { - return Double.longBitsToDouble(getLong(mybp)); - } - - /** skip next 'n' bytes - */ - public void skip(int n) { - bp += n; - } -} diff --git a/sources/scalac/util/ArrayApply.java b/sources/scalac/util/ArrayApply.java deleted file mode 100644 index 087278af5b..0000000000 --- a/sources/scalac/util/ArrayApply.java +++ /dev/null @@ -1,54 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -public abstract class ArrayApply { - - //######################################################################## - // Arrays interface - Object - - public static String toString(Object[] src) { - return append(new StringBuffer(), src).toString(); - } - - public static String toString(Object[] src, String infix) { - return append(new StringBuffer(), src, infix).toString(); - } - - public static String toString(Object[] src, String prefix, String infix, - String suffix) - { - return append(new StringBuffer(), src, prefix,infix,suffix).toString(); - } - - //######################################################################## - // Arrays interface - StringBuffer - - public static StringBuffer append(StringBuffer buffer, Object[] src) { - return append(buffer, src, "[", ",", "]"); - } - - public static StringBuffer append(StringBuffer buffer, Object[] src, - String infix) - { - return append(buffer, src, "", infix, ""); - } - - public static StringBuffer append(StringBuffer buffer, Object[] src, - String prefix, String infix, String suffix) - { - buffer.append(prefix); - for (int i = 0; i < src.length; i++) { - if (i > 0) buffer.append(infix); - buffer.append(src[i]); - } - buffer.append(suffix); - return buffer; - } -} diff --git a/sources/scalac/util/Debug.java b/sources/scalac/util/Debug.java deleted file mode 100644 index 3e889beb62..0000000000 --- a/sources/scalac/util/Debug.java +++ /dev/null @@ -1,503 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import scala.tools.util.debug.Debugger; -import scala.tools.util.debug.ToStringDebugger; - -import scalac.Global; -import scalac.ast.Tree; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; - -/** - * Debugging class, used e.g. to obtain string representations of - * compiler data structures that are not "pretty-printed" and thus - * easier to relate to the source code. - * - * All methods are static to be easily useable in any context. - * - * @author Michel Schinz - * @version 1.0 - */ -public class Debug extends scala.tools.util.debug.Debug { - - //######################################################################## - // Private Initialization - - /** - * Forces the initialization of this class. Returns the boolean - * value true so that it can be invoked from an assert statement. - */ - public static boolean initialize() { - // nothing to do, everything is done in the static initializer - return true; - } - - static { - addDebugger(new ToStringDebugger(Tree.class)); - addDebugger(new ToStringDebugger(Type.class)); - addDebugger(SymbolDebugger.object); - addDebugger(ScopeDebugger.object); - } - - //######################################################################## - // Public Methods - Logging - - public static boolean log(Object a) { - return logAll(new Object[] {a}); - } - - public static boolean log(Object a, Object b) { - return logAll(new Object[] {a, b}); - } - - public static boolean log(Object a, Object b, Object c) { - return logAll(new Object[] {a, b, c}); - } - - public static boolean log(Object a, Object b, Object c, Object d) { - return logAll(new Object[] {a, b, c, d}); - } - - public static boolean logAll(Object[] args) { - return Global.instance.log(showAll(args, null)); - } - - //######################################################################## - // showTree - - private static void append(StringBuffer buf, Name[] names) { - for (int i = 0; i < names.length; i++) { - if (i > 0) buf.append(","); - append(buf, names[i]); - } - } - - private static void append(StringBuffer buf, Name name) { - buf.append("\"" + name + '"'); - } - - private static void append(StringBuffer buf, String str) { - buf.append("\"" + str + '"'); - } - - private static void append(StringBuffer buf, Tree[] trees, boolean showType) { - buf.append('['); - for (int i = 0; i < trees.length; i++) { - if (i > 0) buf.append(','); - append(buf, trees[i], showType); - } - buf.append(']'); - } - - private static void append(StringBuffer buf, Tree[][] trees) { - for (int i = 0; i < trees.length; i++) { - buf.append('['); - append(buf, trees[i]); - buf.append(']'); - } - } - - private static void append(StringBuffer buf, Tree tree, boolean showType) { - switch (tree) { - case Empty: - buf.append("Empty("); - break; - case Attributed(Tree attribute, Tree definition): - buf.append("Attributed("); - append(buf, attribute); - buf.append(','); - append(buf, definition); - break; - case DocDef(String comment, Tree definition): - buf.append("DocDef("); - append(buf, comment); - buf.append(','); - append(buf, definition); - break; - case ClassDef(int mods, Name name, Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, Tree tpe, Tree.Template impl): - buf.append("ClassDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tparams); - buf.append(','); - append(buf, vparams); - buf.append(','); - append(buf, tpe); - buf.append(','); - append(buf, impl); - break; - case PackageDef(Tree packaged, Tree.Template impl): - buf.append("PackageDef("); - append(buf, packaged); - buf.append(','); - append(buf, impl); - break; - case ModuleDef(int mods, Name name, Tree tpe, Tree.Template impl): - buf.append("ModuleDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tpe); - buf.append(','); - append(buf, impl); - break; - case ValDef(int mods, Name name, Tree tpe, Tree rhs): - buf.append("ValDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tpe, showType); - buf.append(','); - append(buf, rhs, showType); - break; - case PatDef(int mods, Tree pat, Tree rhs): - buf.append("PatDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, pat); - buf.append(','); - append(buf, rhs); - break; - case DefDef(int mods, Name name, Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, Tree tpe, Tree rhs): - buf.append("DefDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tparams); - buf.append(','); - append(buf, vparams); - buf.append(','); - append(buf, tpe); - buf.append(','); - append(buf, rhs); - break; - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - buf.append("AbsTypeDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, rhs); - buf.append(','); - append(buf, lobound); - break; - case AliasTypeDef(int mods, Name name, Tree.AbsTypeDef[] tparams, Tree rhs): - buf.append("AliasTypeDef("); - Modifiers.Helper.toString(buf, mods); - buf.append(','); - append(buf, name); - buf.append(','); - append(buf, tparams); - buf.append(','); - append(buf, rhs); - break; - case Import(Tree expr, Name[] selectors): - buf.append("Import("); - append(buf, expr); - buf.append(","); - append(buf, selectors); - break; - case CaseDef(Tree pat, Tree guard, Tree body): - buf.append("CaseDef("); - buf.append(","); - append(buf, pat); - buf.append(","); - append(buf, guard); - buf.append(","); - append(buf, body); - break; - case Template(Tree[] parents, Tree[] body): - buf.append("Template("); - append(buf, parents); - buf.append(','); - append(buf, body); - break; - case LabelDef(Name name, Tree.Ident[] params, Tree rhs): - buf.append("LabelDef("); - buf.append(","); - append(buf, name); - buf.append(','); - append(buf, params); - buf.append(','); - append(buf, rhs); - break; - case Block(Tree[] stats, Tree expr): - buf.append("Block("); - append(buf, stats); - buf.append(','); - append(buf, expr); - break; - case Sequence(Tree[] trees): - buf.append("Sequence("); - buf.append(','); - append(buf, trees); - break; - case Alternative(Tree[] trees): - buf.append("Alternative("); - buf.append(','); - append(buf, trees); - break; - case Bind(Name name, Tree rhs): - buf.append("Bind("); - append(buf, name); - buf.append(','); - append(buf, rhs); - break; - case Visitor(Tree.CaseDef[] cases): - buf.append("ClassDef("); - append(buf, cases); - break; - case Function(Tree.ValDef[] vparams, Tree body): - buf.append("Function("); - append(buf, vparams); - buf.append(','); - append(buf, body); - break; - case Assign(Tree lhs, Tree rhs): - buf.append("Assign("); - append(buf, lhs); - buf.append(','); - append(buf, rhs); - break; - case If(Tree cond, Tree thenp, Tree elsep): - buf.append("If("); - append(buf, cond); - buf.append(','); - append(buf, thenp); - buf.append(','); - append(buf, elsep); - break; - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - buf.append("Switch("); - buf.append(','); - append(buf, test); - buf.append(','); - buf.append(tags); // TODO - buf.append(','); - append(buf, bodies); - buf.append(","); - append(buf, otherwise); - break; - case Return(Tree expr): - buf.append("Return("); - append(buf, expr, showType); - buf.append(')'); - break; - case Throw(Tree expr): - buf.append("Throw("); - append(buf, expr, showType); - break; - case New(Tree init): - buf.append("New("); - append(buf, init, showType); - break; - case Create(Tree qualifier, Tree[] targs): - buf.append("Create("); - append(buf, qualifier); - buf.append(','); - append(buf, targs); - break; - case Typed(Tree expr, Tree tpe): - buf.append("Typed("); - append(buf, expr, showType); - buf.append(","); - append(buf, tpe, showType); - break; - case TypeApply(Tree fun, Tree[] args): - buf.append("TypeApply("); - append(buf, fun, showType); - buf.append(','); - append(buf, args, showType); - break; - case Apply(Tree fun, Tree[] args): - buf.append("Apply("); - append(buf, fun, showType); - buf.append(','); - append(buf, args, showType); - break; - case Super(Name qualifier, Name mixin): - buf.append("Super("); - append(buf, qualifier); - buf.append(','); - append(buf, mixin); - break; - case This(Name qualifier): - buf.append("This("); - append(buf, qualifier); - break; - case Select(Tree qualifier, Name selector): - buf.append("Select("); - append(buf, qualifier, showType); - buf.append(','); - append(buf, selector); - break; - case Ident(Name name): - buf.append("Ident("); - append(buf, name); - break; - case Literal(scalac.atree.AConstant value): - buf.append("Literal(" + value); - break; - case TypeTerm(): - buf.append("TypeTerm("); - break; - case SingletonType(Tree ref): - buf.append("SingletonType("); - append(buf, ref, showType); - break; - case SelectFromType(Tree qualifier, Name selector): - buf.append("SelectFromType("); - append(buf, qualifier, showType); - buf.append(','); - append(buf, selector); - break; - case FunType(Tree[] argtpes, Tree restpe): - buf.append("FunType("); - append(buf, argtpes); - buf.append(','); - append(buf, restpe); - break; - case CompoundType(Tree[] parents, Tree[] refinements): - buf.append("CompoundType("); - append(buf, parents); - buf.append(','); - append(buf, refinements); - break; - case AppliedType(Tree tpe, Tree[] args): - buf.append("AppliedType("); - append(buf, tpe); - buf.append(','); - append(buf, args); - break; - case Try(Tree block, Tree catcher, Tree finalizer): - buf.append("Try("); - append(buf, block); - buf.append(','); - append(buf, catcher); - buf.append(','); - append(buf, finalizer); - break; - default: - buf.append(tree.getClass().getName() + "("); - } - buf.append(')'); - if (showType) buf.append(":" + tree.type); - } - - public static String showTree(Tree tree, boolean showType) { - StringBuffer buf = new StringBuffer(); - append(buf, tree, showType); - return buf.toString(); - } - - public static String showTree(Tree tree) { - return showTree(tree, false); - } - - public static String showTree(Tree[] trees, boolean showType) { - StringBuffer buf = new StringBuffer(); - append(buf, trees, showType); - return buf.toString(); - } - - public static String showTree(Tree[] trees) { - return showTree(trees, false); - } - - //######################################################################## -} - -/** This class implements a debugger for symbols. */ -public class SymbolDebugger implements Debugger { - - //######################################################################## - // Public Constants - - /** The unique instance of this class. */ - public static final SymbolDebugger object = new SymbolDebugger(); - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected SymbolDebugger() {} - - //######################################################################## - // Public Methods - - public boolean canAppend(Object object) { - return object instanceof Symbol; - } - - public void append(StringBuffer buffer, Object object) { - Symbol symbol = (Symbol)object; - if (!symbol.isNone() && !symbol.owner().isRoot() && !symbol.isRoot()) { - Debug.append(buffer, symbol.owner()); - buffer.append("."); - } - buffer.append(symbol.name); - if (Global.instance.uniqid) { - buffer.append('#'); - buffer.append(symbol.id); - } - if (symbol.isConstructor()) { - buffer.append('('); - buffer.append(symbol.constructorClass().name); - buffer.append(')'); - } - } - - //######################################################################## -} - -/** This class implements a debugger for scopes. */ -public class ScopeDebugger implements Debugger { - - //######################################################################## - // Public Constants - - /** The unique instance of this class. */ - public static final ScopeDebugger object = new ScopeDebugger(); - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected ScopeDebugger() {} - - //######################################################################## - // Public Methods - - public boolean canAppend(Object object) { - return object instanceof Scope; - } - - public void append(StringBuffer buffer, Object object) { - Scope scope = (Scope)object; - buffer.append('{'); - for (Scope.SymbolIterator i = scope.iterator(); i.hasNext();) { - Debug.append(buffer, i.next()); - if (i.hasNext()) buffer.append(','); - } - buffer.append('}'); - } - - //######################################################################## -} diff --git a/sources/scalac/util/EmptyPhase.java b/sources/scalac/util/EmptyPhase.java deleted file mode 100644 index 5600fc85b9..0000000000 --- a/sources/scalac/util/EmptyPhase.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -/** This class implements a phase that does nothing. */ -public class EmptyPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public EmptyPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - // do nothing - } - - //######################################################################## -} diff --git a/sources/scalac/util/FreshNameCreator.java b/sources/scalac/util/FreshNameCreator.java deleted file mode 100644 index 3675f359f0..0000000000 --- a/sources/scalac/util/FreshNameCreator.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.util.HashMap; - -public class FreshNameCreator { - - protected int counter = 0; - protected HashMap counters = new HashMap(); - - /** - * Create a fresh name with the given prefix. It is guaranteed - * that the returned name has never been returned by a previous - * call to this function with the same separator character (which - * has to be a non-digit). - */ - public Name newName(String prefix, char separator) { - prefix += separator; - Integer ival = (Integer)counters.get(prefix); - if (ival == null) - counters.put(prefix, ival = new Integer(0)); - else - counters.put(prefix, ival = new Integer(ival.intValue() + 1)); - return Name.fromString(prefix + ival); - } - - /** Same, with `$' as the separator character - */ - public Name newName(String prefix) { - return newName(prefix, '$'); - } - - /** Same, but with a name as prefix. The new name is a type - * (respectively, constructor) name if the prefix is one. - */ - public Name newName(Name prefixName, char separator) { - Name name = newName(prefixName.toString(), separator); - if (prefixName.isTypeName()) return name.toTypeName(); - else return name; - } - - /** Same, with `$' as the separator character - */ - public Name newName(Name prefix) { - return newName(prefix, '$'); - } - - public Name newName() { - return Name.fromString("$" + (counter++) + "$"); - } -} diff --git a/sources/scalac/util/Name.java b/sources/scalac/util/Name.java deleted file mode 100644 index af088d6f79..0000000000 --- a/sources/scalac/util/Name.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -/** This class implements the common part of TermName and TypeName. */ -public abstract class Name { - - //######################################################################## - // Public Fields - - /** The unique identifier */ - public final int index; - - //######################################################################## - // Private Fields - - /** The related term name */ - private final TermName term; - - /** The related type name (null if not yet created) */ - private TypeName type; - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected Name(int index, TermName term) { - this.index = index; - this.term = term == null ? (TermName)this : term; - this.type = term == null ? null : (TypeName)this; - } - - //######################################################################## - // Public Factories - - /** Returns the term name with given ASCII representation. */ - public static TermName fromAscii(byte[] bytes, int start, int count) { - return TermName.fromAscii(bytes, start, count); - } - - /** Returns the term name with given string representation. */ - public static TermName fromString(String string) { - return TermName.fromString(string); - } - - //######################################################################## - // Public Methods - - /** Is this name a variable identifier? */ - public final boolean isVariable() { - char first = charAt(0); - return (('a' <= first && first <= 'z') || first == '_') - && this != Names.false_ - && this != Names.true_ - && this != Names.null_; - } - - /** Is this name a term name? */ - public final boolean isTermName() { - return this == term; - } - - /** Is this name a type name? */ - public final boolean isTypeName() { - return this == type; - } - - /** Returns the term name with the same representation. */ - public final TermName toTermName() { - return term; - } - - /** Returns the type name with the same representation. */ - public final TypeName toTypeName() { - return type != null ? type : (type = new TypeName(term)); - } - - /** Returns the result of "toString().length()". */ - public final int length() { - return toString().length(); - } - - /** Returns the result of "toString().charAt(index)". */ - public final char charAt(int index) { - return toString().charAt(index); - } - - /** Returns the result of "toString().indexOf(ch)". */ - public final int indexOf(char ch) { - return toString().indexOf(ch); - } - - /** Returns the result of "toString().indexOf(ch, start)". */ - public final int indexOf(char ch, int start) { - return toString().indexOf(ch, start); - } - - /** Returns the result of "toString().lastIndexOf(ch)". */ - public final int lastIndexOf(char ch) { - return toString().lastIndexOf(ch); - } - - /** Returns the result of "toString().lastIndexOf(ch, start)". */ - public final int lastIndexOf(char ch, int start) { - return toString().lastIndexOf(ch, start); - } - - /** Returns the hash code of this name. */ - public final int hashCode() { - return index; - } - - /** Returns the string representation of this name. */ - public String toString() { - return term.toString(); - } - - /** - * Returns the ASCII representation of this name. The returned - * array is not a copy. Therefore, it is forbidden to modify it. - */ - public byte[] toAsciiUnsafe() { - return term.toAsciiUnsafe(); - } - - //######################################################################## -} diff --git a/sources/scalac/util/NameTransformer.java b/sources/scalac/util/NameTransformer.java deleted file mode 100644 index b04b665379..0000000000 --- a/sources/scalac/util/NameTransformer.java +++ /dev/null @@ -1,100 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.util; - -/** A name transformer for replacing operator symbols in names by predefined - * names of the form $opname. - * - * @author Martin Odersky, Christine Roeckl - * @version 1.1 - */ -public class NameTransformer { - - public static String[] operatorName = new String[128]; - - static { - operatorName['~'] = "$tilde"; - operatorName['='] = "$eq"; - operatorName['<'] = "$less"; - operatorName['>'] = "$greater"; - operatorName['!'] = "$bang"; - operatorName['#'] = "$hash"; - operatorName['%'] = "$percent"; - operatorName['^'] = "$up"; - operatorName['&'] = "$amp"; - operatorName['|'] = "$bar"; - operatorName['*'] = "$times"; - operatorName['/'] = "$div"; - operatorName['+'] = "$plus"; - operatorName['-'] = "$minus"; - operatorName[':'] = "$colon"; - operatorName['\\']= "$bslash"; - } - - /** Replace operator symbols by corresponding "$op_name" in names. - */ - public static Name encode(Name name) { - String string = name.toString(); - StringBuffer buffer = null; - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - if (c < 128) { - String operator = operatorName[c]; - if (operator != null) { - if (buffer == null) { - int capacity = string.length() - 1 + operator.length(); - buffer = new StringBuffer(capacity); - buffer.append(string.substring(0, i)); - } - buffer.append(operator); - continue; - } - } - if (buffer != null) buffer.append(c); - } - return buffer == null ? name : Name.fromString(buffer.toString()); - } - - /** Replace "$op_name" by corresponding operator symbols in names. - */ - public static String decode(Name name) { - return decode(name.toString()); - } - public static String decode(String string) { - StringBuffer buffer = null; - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - if (c == '$') { - int index = -1; - int length = -1; // an operator may be a prefix of another one - for (int j = 0; j < operatorName.length; j++) { - String operator = operatorName[j]; - if (operator == null) continue; - if (operator.length() <= length) continue; - if (!string.startsWith(operator, i)) continue; - index = j; - length = operator.length(); - } - if (length >= 0) { - if (buffer == null) { - int capacity = string.length() - length + 1; - buffer = new StringBuffer(capacity); - buffer.append(string.substring(0, i)); - } - buffer.append((char)index); - i += length - 1; - continue; - } - } - if (buffer != null) buffer.append(c); - } - return buffer == null ? string : buffer.toString(); - } - -} diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java deleted file mode 100644 index 66a67f819c..0000000000 --- a/sources/scalac/util/Names.java +++ /dev/null @@ -1,268 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2004, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** -** $Id$ -\* */ -package scalac.util; - -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; -import scalac.symtab.ClassSymbol; - -public class Names { - - private static final SymbolNameWriter writer = - new SymbolNameWriter().setAllSeparators('$').setRootSeparator('\0'); - - private static final String ALIAS_PREFIX = "alias$"; - private static final String LOCAL_PREFIX = "local$"; - private static final String MIXIN_PREFIX = "mixin$"; - private static final String OUTER_PREFIX = "outer$"; - private static final String SUPER_PREFIX = "super$"; - private static final String ACCESS_PREFIX = "access$"; - private static final String TUPLE_FIELD_PREFIX = "_"; - private static final String TYPE_PREFIX = "type$"; - private static final String INSTANTIATE_PREFIX = "instantiate$"; - private static final String LAZYPARENTS_PREFIX = "LazyParents$"; - private static final String TYPECONSTRUCTOR_PREFIX = "tConstructor$"; - - public static Name ALIAS(ClassSymbol clasz) { - return Name.fromString(ALIAS_PREFIX + clasz.name).toTypeName(); - } - - public static Name LOCAL(Symbol clasz) { - return Name.fromString(LOCAL_PREFIX + clasz.name); - } - - public static Name MIXIN(Symbol member) { - Name name = Name.fromString(MIXIN_PREFIX + member.owner().name - + (member.isInitializer() ? INLINED_INITIALIZER : member.name)); - if (member.name.isTypeName()) name = name.toTypeName(); - return name; - } - - public static Name OUTER(Symbol constructor) { - if (constructor.isClass()) - return Name.fromString(OUTER_PREFIX + constructor.owner().name); - assert constructor.isConstructor(): Debug.show(constructor); - Symbol clasz = constructor.constructorClass(); - Symbol[] constructors = clasz.allConstructors().alternativeSymbols(); - int index = 0; - while (constructors[index] != constructor) index++; - String name = OUTER_PREFIX + index +"$"+ clasz.owner().name; - return Name.fromString(name); - } - - public static Name OUTER(Symbol constructor, Symbol member) { - Name name = Name.fromString(OUTER(constructor) + "$" + member.name); - if (member.name.isTypeName()) name = name.toTypeName(); - return name; - } - - public static Name ACCESS(Symbol member, boolean svper) { - assert member.isTerm() && member.owner().isClass(): Debug.show(member); - String prefix = svper ? ACCESS_PREFIX + SUPER_PREFIX : ACCESS_PREFIX; - return Name.fromString(writer.toString(prefix, member)); - } - - public static Name TUPLE_FIELD(int index) { - return Name.fromString(TUPLE_FIELD_PREFIX + index); - } - - public static Name TYPE(Symbol sym) { - return Name.fromString(TYPE_PREFIX + sym.name); - } - - public static Name INSTANTIATE(Symbol sym, boolean isStatic) { - return Name.fromString(INSTANTIATE_PREFIX - + sym.name - + (isStatic ? "$" : "")); - } - - public static Name LAZYPARENTS(Symbol clsSym) { - return Name.fromString(LAZYPARENTS_PREFIX + clsSym.name).toTypeName(); - } - - public static Name TYPECONSTRUCTOR(Symbol sym, boolean isStatic) { - return Name.fromString(TYPECONSTRUCTOR_PREFIX - + sym.name - + (isStatic ? "$" : "")); - } - - public static final Name ERROR = Name.fromString("<error>"); - public static final Name NOSYMBOL = Name.fromString("<none>"); - public static final Name EMPTY = Name.fromString(""); - public static final Name IMPORT_WILDCARD = Name.fromString("_"); - public static final Name PATTERN_WILDCARD = Name.fromString("_"); - public static final Name COMPOUND_NAME = Name.fromString("<ct>"); - public static final Name ANON_CLASS_NAME = Name.fromString("$anon"); - public static final Name ZERO = Name.fromString("<zero>"); - public static final Name STAR = Name.fromString("*"); - public static final Name ROOT = Name.fromString("<root>"); - - public static final Name CONSTRUCTOR = Name.fromString("<init>"); - public static final Name CLASS_CONSTRUCTOR = Name.fromString("<clinit>"); - public static final Name INITIALIZER = Name.fromString("<init>"); - public static final Name INLINED_INITIALIZER = Name.fromString("$init$"); - - public static final Name _EQ = encode("_="); - public static final Name MINUS = encode("-"); - public static final Name PLUS = encode("+"); - public static final Name TILDE = encode("~"); - public static final Name EQEQ = encode("=="); - public static final Name BANG = encode("!"); - public static final Name BANGEQ = encode("!="); - public static final Name BARBAR = encode("||"); - public static final Name AMPAMP = encode("&&"); - public static final Name COLONCOLON = encode("::"); - public static final Name PERCENT = encode("%"); - public static final Name PLUSEQ = encode("+="); - public static final Name MINUSEQ = encode("-="); - - public static final Name All = Name.fromString("All"); - public static final Name AllRef = Name.fromString("AllRef"); - public static final Name Any = Name.fromString("Any"); - public static final Name AnyVal = Name.fromString("AnyVal"); - public static final Name AnyRef = Name.fromString("AnyRef"); - public static final Name Array = Name.fromString("Array"); - public static final Name Byte = Name.fromString("Byte"); - public static final Name CaseClass = Name.fromString("CaseClass"); - public static final Name Catch = Name.fromString("Catch"); - public static final Name Char = Name.fromString("Char"); - public static final Name Boolean = Name.fromString("Boolean"); - public static final Name Do = Name.fromString("Do"); - public static final Name Double = Name.fromString("Double"); - public static final Name Element = Name.fromString("Element"); - public static final Name Finally = Name.fromString("Finally"); - public static final Name Float = Name.fromString("Float"); - public static final Name Function = Name.fromString("Function"); - public static final Name GetType = Name.fromString("GetType"); - public static final Name Int = Name.fromString("Int"); - public static final Name Labelled = Name.fromString("Labelled"); - public static final Name List = Name.fromString("List"); - public static final Name Long = Name.fromString("Long"); - public static final Name Nil = Name.fromString("Nil"); - public static final Name Object = Name.fromString("Object"); - public static final Name PartialFunction = Name.fromString("PartialFunction"); - public static final Name Predef = Name.fromString("Predef"); - public static final Name ScalaObject = Name.fromString("ScalaObject"); - public static final Name ScalaRunTime = Name.fromString("ScalaRunTime"); - public static final Name Seq = Name.fromString("Seq"); - public static final Name Short = Name.fromString("Short"); - public static final Name String = Name.fromString("String"); - public static final Name Symbol = Name.fromString("Symbol"); - public static final Name Text = Name.fromString("Text"); - public static final Name Throwable = Name.fromString("Throwable"); - public static final Name Try = Name.fromString("Try"); - public static final Name Tuple = Name.fromString("Tuple"); - public static final Name Type = Name.fromString("Type"); - public static final Name Tuple2 = Name.fromString("Tuple2"); - public static final Name Unit = Name.fromString("Unit"); - public static final Name While = Name.fromString("While"); - public static final Name apply = Name.fromString("apply"); - public static final Name array = Name.fromString("array"); - public static final Name asInstanceOf = Name.fromString("asInstanceOf"); - public static final Name asInstanceOfE = Name.fromString("asInstanceOf$erased"); - public static final Name box = Name.fromString("box"); - public static final Name caseArity = Name.fromString("caseArity"); - public static final Name caseElement = Name.fromString("caseElement"); - public static final Name cur = Name.fromString("cur"); // used in translation of automata - public static final Name cast = Name.fromString("cast"); - public static final Name clone = Name.fromString("clone"); - public static final Name coerce = Name.fromString("coerce"); - public static final Name defaultValue = Name.fromString("defaultValue"); - public static final Name elem = Name.fromString("elem"); - public static final Name elements = Name.fromString("elements"); - public static final Name emptyArray = Name.fromString("EMPTY_ARRAY"); - public static final Name eq = Name.fromString("eq"); - public static final Name equals = Name.fromString("equals"); - public static final Name fail = Name.fromString("fail"); - public static final Name false_ = Name.fromString("false"); - public static final Name filter = Name.fromString("filter"); - public static final Name finalize = Name.fromString("finalize"); - public static final Name flatmap = Name.fromString("flatMap"); - public static final Name foreach = Name.fromString("foreach"); - public static final Name force = Name.fromString("force"); - public static final Name functionOuter = Name.fromString("FUNCTION_OUTER"); - public static final Name get = Name.fromString("get"); - public static final Name getClass = Name.fromString("getClass"); - public static final Name getInstantiation = Name.fromString("getInstantiation"); - public static final Name getScalaType = Name.fromString("getScalaType"); - public static final Name isInstance = Name.fromString("isInstance"); - public static final Name hashCode = Name.fromString("hashCode"); - public static final Name hasNext = Name.fromString("hasNext"); - public static final Name head = Name.fromString("head"); - public static final Name isInstanceOf = Name.fromString("isInstanceOf"); - public static final Name isInstanceOfE = Name.fromString("isInstanceOf$erased"); - public static final Name isDefinedAt = Name.fromString("isDefinedAt"); - public static final Name isEmpty = Name.fromString("isEmpty"); - public static final Name instantiate = Name.fromString("instantiate"); - public static final Name java = Name.fromString("java"); - public static final Name javaRefArrayType = Name.fromString("javaRefArrayType"); - public static final Name javaArrayType = Name.fromString("javaArrayType"); - public static final Name javaClassType = Name.fromString("javaClassType"); - public static final Name lang = Name.fromString("lang"); - public static final Name length = Name.fromString("length"); - public static final Name _match = Name.fromString("match"); - public static final Name map = Name.fromString("map"); - public static final Name n = Name.fromString("n"); - public static final Name ne = Name.fromString("ne"); - public static final Name nobinding = Name.fromString("nobinding"); - public static final Name next = Name.fromString("next"); - public static final Name newArray = Name.fromString("newArray"); - public static final Name notify = Name.fromString("notify"); - public static final Name notifyAll = Name.fromString("notifyAll"); - public static final Name null_ = Name.fromString("null"); - public static final Name predef = Name.fromString("predef"); - public static final Name print = Name.fromString("print"); - public static final Name readResolve = Name.fromString("readResolve"); - public static final Name report = Name.fromString("report"); - public static final Name result = Name.fromString("$result"); - public static final Name runtime = Name.fromString("runtime"); - public static final Name scala = Name.fromString("scala"); - public static final Name setParents = Name.fromString("setParents"); - public static final Name synchronized_ = Name.fromString("synchronized"); - public static final Name tag = Name.fromString("$tag"); - public static final Name tail = Name.fromString("tail"); - public static final Name toString = Name.fromString("toString"); - public static final Name that = Name.fromString("that"); - public static final Name that1 = Name.fromString("that1"); - public static final Name this_ = Name.fromString("this"); - public static final Name throw_ = Name.fromString("throw"); - public static final Name true_ = Name.fromString("true"); - public static final Name update = Name.fromString("update"); - public static final Name view = Name.fromString("view"); - public static final Name wait = Name.fromString("wait"); - public static final Name isNonTrivialInstance = Name.fromString("isNonTrivialInstance"); - public static final Name xml = Name.fromString("xml"); - - - public static final Name - ZNOT = encode("!"), - ZAND = encode("&&"), - ZOR = encode("||"), - NOT = encode("~"), - ADD = encode("+"), - SUB = encode("-"), - MUL = encode("*"), - DIV = encode("/"), - MOD = encode("%"), - EQ = encode("=="), - NE = encode("!="), - LT = encode("<"), - LE = encode("<="), - GT = encode(">"), - GE = encode(">="), - OR = encode("|"), - XOR = encode("^"), - AND = encode("&"), - LSL = encode("<<"), - LSR = encode(">>>"), - ASR = encode(">>"); - - private static Name encode(String string) { - return NameTransformer.encode(Name.fromString(string)); - } -} diff --git a/sources/scalac/util/OptionParser.java b/sources/scalac/util/OptionParser.java deleted file mode 100644 index 9521ca388e..0000000000 --- a/sources/scalac/util/OptionParser.java +++ /dev/null @@ -1,541 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import scala.tools.util.Position; -import scala.tools.util.Reporter; - -import java.text.Format; -import java.text.MessageFormat; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.StringTokenizer; - -import scalac.PhaseDescriptor; -//import scalac.optimizer.OptimizePhase; - -public class CommandParser { - - private final String product; - private final String version; - private final String syntax; - private final Reporter reporter; - private final List/*<ArgumentParser>*/ parsers; - - public CommandParser(String product, String version, String syntax, - Reporter reporter) - { - this.product = product; - this.version = version; - this.syntax = syntax; - this.reporter = reporter; - this.parsers = new ArrayList(); - } - - public String product() { - return product; - } - - public String version() { - return version; - } - - public String syntax() { - return syntax; - } - - public Reporter reporter() { - return reporter; - } - - public boolean add(ArgumentParser parser) { - return parsers.add(parser); - } - - public void add(int index, ArgumentParser parser) { - parsers.add(index, parser); - } - - public boolean remove(ArgumentParser parser) { - return parsers.remove(parser); - } - - public List parsers() { - return parsers; - } - - public boolean parse(String[] args) { - int errors = reporter.errors(); - for (int i = 0; i < args.length; ) { - for (int j = 0; j < parsers.size(); j++) { - ArgumentParser parser = (ArgumentParser)parsers.get(j); - if (parser.matches(args, i)) { - i = parser.consume(args, i); - break; - } - } - } - return reporter.errors() == errors; - } - - public String getHelpMessage() { - Format format = new MessageFormat(" {0}\t {1}"); - List options = new ArrayList(parsers.size()); - for (int i = 0; i < parsers.size(); i++) { - if (!(parsers.get(i) instanceof OptionParser)) continue; - OptionParser parser = (OptionParser)parsers.get(i); - String option = parser.getHelpMessage(format); - if (option != null) options.add(option); - } - StringBuffer buffer = new StringBuffer(); - buffer.append("usage: ").append(product()); - if (options.size() > 0) buffer.append(" <options>"); - if (syntax != null) buffer.append(' ').append(syntax); - buffer.append(Strings.EOL); - if (options.size() > 0) { - buffer.append("where possible options include:"); - buffer.append(Strings.EOL); - buffer.append(Strings.format(options)); - } - return buffer.toString(); - } - - public void error(String message) { - reporter.error(new Position(product), message); - } - - public void warning(String message) { - reporter.warning(new Position(product), message); - } -} - -public abstract class ArgumentParser { - - public final CommandParser command; - - public ArgumentParser(CommandParser command) { - this.command = command; - } - - public abstract boolean matches(String[] args, int index); - public abstract int consume(String[] args, int index); - -} - -public class UnknownArgumentParser extends ArgumentParser { - - public UnknownArgumentParser(CommandParser command) { - super(command); - } - - public boolean matches(String[] args, int index) { - return true; - } - - public int consume(String[] args, int index) { - command.error("don't known what to do with '" + args[index] + "'"); - return index + 1; - } -} - -public class ScalaFileArgumentParser extends ArgumentParser { - - public final List list; - - public ScalaFileArgumentParser(CommandParser command) { - super(command); - this.list = new ArrayList(); - } - - public boolean matches(String[] args, int index) { - return args[index].endsWith(".scala"); - } - - public int consume(String[] args, int index) { - list.add(args[index]); - return index + 1; - } - - public String[] toArray() { - return (String[])list.toArray(new String[list.size()]); - } -} - -public class ScalaProgramArgumentParser extends ArgumentParser { - - public String main; - public String[] args; - - public ScalaProgramArgumentParser(CommandParser command) { - super(command); - } - - public boolean matches(String[] args, int index) { - return args[index].equals("--"); - } - - public int consume(String[] args, int index) { - if (index + 1 < args.length) { - this.main = args[index + 1]; - this.args = new String[args.length - index - 2]; - System.arraycopy(args, index + 2, this.args, 0, this.args.length); - return args.length; - } else { - command.error("option --: missing module name"); - return args.length; - } - } -} - -public abstract class OptionParser extends ArgumentParser { - - public final String option; - public final String description; - - public OptionParser(CommandParser command, String option, - String description) - { - super(command); - this.option = option; - this.description = description; - } - - public String getHelpSyntax() { - return "-" + option; - } - - public String getHelpDescription() { - return description; - } - - public void getHelpMessageArgs(List args) { - args.add(getHelpSyntax()); - args.add(getHelpDescription()); - } - - public String getHelpMessage(Format format) { - if (description == null) return null; - List args = new ArrayList(); - getHelpMessageArgs(args); - return format.format(args.toArray()); - } - - public void error(String message) { - command.error("option -" + option + ": " + message); - } - - public void warning(String message) { - command.warning("option -" + option + ": " + message); - } -} -/* -public class OptimizeOptionParser extends OptionParser { - - private final OptimizePhase optimizer; - public boolean optimize; - - public OptimizeOptionParser(CommandParser command, - String option, String description, OptimizePhase optimizer) - { - super(command, option, description); - this.optimizer = optimizer; - this.optimize = false; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - optimizer.setOptions(args[index].substring(1 + option.length())); - optimize = true; - return index + 1; - } - - public String getHelpSyntax() { - return super.getHelpSyntax() + "[:<options>]"; - } -} -*/ -public class VersionOptionParser extends OptionParser { - - private final String version; - - public VersionOptionParser(CommandParser command, - String option, String description, String version) - { - super(command, option, description); - this.version = version; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - System.out.println(version); - System.exit(0); - return index + 1; - } -} - -public class HelpOptionParser extends OptionParser { - - public HelpOptionParser(CommandParser command, - String option, String description) - { - super(command, option, description); - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-?") || - args[index].equals("-" + option) || - args[index].equals("--" + option); - } - - public int consume(String[] args, int index) { - System.out.println(command.getHelpMessage()); - System.exit(0); - return index + 1; - } - - public String getHelpSyntax() { - return "-? " + super.getHelpSyntax(); - } -} - -public class UnknownOptionParser extends OptionParser { - - public UnknownOptionParser(CommandParser command) { - super(command, "", null); - } - - public boolean matches(String[] args, int index) { - return args[index].startsWith("-"); - } - - public int consume(String[] args, int index) { - command.error("unknown option " + args[index]); - return index + 1; - } -} - -public class BooleanOptionParser extends OptionParser { - - public boolean value; - - public BooleanOptionParser(CommandParser command, - String option, String description, boolean value) - { - super(command, option, description); - this.value = value; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - value = true; - return index + 1; - } -} - -public class StringOptionParser extends OptionParser { - - public String value; - public String argument; - - public StringOptionParser(CommandParser command, - String option, String description, String argument, String value) - { - super(command, option, description); - this.argument = argument; - this.value = value; - } - - public boolean matches(String[] args, int index) { - return args[index].equals("-" + option); - } - - public int consume(String[] args, int index) { - if (index + 1 < args.length) { - value = args[index + 1]; - return index + 2; - } else { - error("missing argument"); - return index + 1; - } - } - - public String getHelpSyntax() { - String syntax = super.getHelpSyntax(); - if (argument != null) syntax = syntax + " <" + argument + ">"; - return syntax; - } -} - -public class PhaseSetOptionParser extends OptionParser { - - private final PhaseDescriptor[] phases; - private final int flag; - private final PrefixMatcher matcher; - - public PhaseSetOptionParser(CommandParser command, - String option, String description, PhaseDescriptor[] phases, int flag) - { - super(command, option, description); - this.phases = phases; - this.flag = flag; - this.matcher = new PrefixMatcher(); - for (int i = 0; i < phases.length; i++) { - PhaseDescriptor phase = phases[i]; - matcher.insert(phase.name(), phase, phase.description()); - } - } - - public boolean matches(String[] args, int index) { - return args[index].startsWith("-" + option + ":"); - } - - public int consume(String[] args, int index) { - StringTokenizer tokens = new StringTokenizer( - args[index].substring(option.length() + 2), ","); - while (tokens.hasMoreTokens()) consumePhase(tokens.nextToken()); - return index + 1; - } - - public void consumePhase(String token) { - if (token.equals("all")) { - for (int i = 0; i < phases.length; i++) - phases[i].addFlag(flag, false); - return; - } - PhaseDescriptor phase = lookup(getPhaseName(token)); - if (phase != null) { - boolean before = getBeforeFlag(token); - boolean after = getAfterFlag(token) || !before; - if (before) phase.addFlag(flag, true); - if (after) phase.addFlag(flag, false); - } - } - - public PhaseDescriptor lookup(String name) { - if (name.length() == 0) { - error("illegal zero-length phase name"); - return null; - } - PrefixMatcher.Entry[] entries = matcher.lookup(name); - if (entries.length == 1) return (PhaseDescriptor)entries[0].value; - error(matcher.getErrorMessage(name, entries, "phase name")); - return null; - } - - public boolean getBeforeFlag(String token) { - for (int i = token.length(); 0 < i--; ) { - switch (token.charAt(i)) { - case '-': return true; - case '+': continue; - default : return false; - } - } - return false; - } - - public boolean getAfterFlag(String token) { - for (int i = token.length(); 0 < i--; ) { - switch (token.charAt(i)) { - case '-': continue; - case '+': return true; - default : return false; - } - } - return false; - } - - public String getPhaseName(String token) { - for (int i = token.length(); 0 < i--; ) { - switch (token.charAt(i)) { - case '-': continue; - case '+': continue; - default : return token.substring(0, i + 1); - } - } - return ""; - } - - public String getHelpSyntax() { - return super.getHelpSyntax() + ":<phases>"; - } -} - -public class PrintOptionParser extends PhaseSetOptionParser { - - public boolean tokens; - - public PrintOptionParser(CommandParser command, - String option, String description, PhaseDescriptor[] phases, int flag) - { - super(command, option, description, phases, flag); - this.tokens = false; - } - - public void consumePhase(String token) { - if ("tokens".equals(token)) - tokens = true; - else - super.consumePhase(token); - } - -} - -public class ChoiceOptionParser extends OptionParser { - - public final String argument; - public final String[] choices; - - public String value; - - public ChoiceOptionParser(CommandParser command, - String option, String description, String argument, String[] choices, - String value) - { - super(command, option, description); - this.argument = argument; - this.choices = choices; - this.value = value; - } - - public boolean matches(String[] args, int index) { - return args[index].startsWith("-" + option + ":"); - } - - public int consume(String[] args, int index) { - String choice = args[index].substring(option.length() + 2); - boolean found = false; - for (int i = 0; i < choices.length; i++) { - if (choices[i].equals(choice)) { found = true; break; } - } - if (found) { - value = choice; - } else if (choice.length() > 0) { - error("unknown " + argument + " '" + choice + "'"); - } else { - error("missing " + argument); - } - return index + 1; - } - - public String getHelpSyntax() { - String syntax = super.getHelpSyntax(); - if (argument != null) syntax = syntax + ":<" + argument + ">"; - return syntax; - } -} diff --git a/sources/scalac/util/PrefixMatcher.java b/sources/scalac/util/PrefixMatcher.java deleted file mode 100644 index 1b0acd8d7a..0000000000 --- a/sources/scalac/util/PrefixMatcher.java +++ /dev/null @@ -1,114 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; - -public class PrefixMatcher { - - public static class Entry { - - private Entry prev; - private Entry next; - - public final String key; - public final Object value; - public final String argument; - public final String description; - - public Entry(String key, Object value, String argument, - String description) - { - this.key = key; - this.value = value; - this.argument = argument; - this.description = description; - } - } - - private final Map entries; - private Entry first; - private Entry last; - - public PrefixMatcher() { - this.entries = new HashMap(); - } - - public void insert(String key, Object value) { - insert(key, value, null, null); - } - - public void insert(String key, Object value, String description) { - insert(key, value, null, description); - } - - public void insert(String key, Object value, String argument, - String description) - { - assert key != null && !entries.containsKey(key) : key; - Entry entry = new Entry(key, value, argument, description); - if (first == null) { - first = last = entry; - } else { - last.next = entry; - entry.prev = last; - last = entry; - } - entries.put(key, entry); - } - - public Entry[] lookup(String key) { - Object value = entries.get(key); - if (value != null) return new Entry[] { (Entry)value }; - List list = new ArrayList(); - for (Entry i = first; i != null; i = i.next) { - if (i.key.startsWith(key)) list.add(i); - } - return (Entry[])list.toArray(new Entry[list.size()]); - } - - public String getErrorMessage(String key, Entry[] entries, String what) { - switch (entries.length) { - case 0: - return "unknown " + what + " '" + key + "'"; - case 1: - return null; - case 2: - return "ambigous " + what + " '" + key + "', both '" + - entries[0].key + "' and '" + entries[1].key + "' match"; - default: - StringBuffer buffer = new StringBuffer(); - buffer.append("ambigous ").append(what); - buffer.append(" '").append(key).append("'"); - for (int i = 0; i < entries.length; i++) { - buffer.append(i < entries.length - 1 ? ", " : " and "); - buffer.append('\'').append(entries[i].key).append('\''); - } - buffer.append(" match"); - return buffer.toString(); - } - } - - public List getHelpStrings(String separator1, String separator2) { - List strings = new ArrayList(); - for (Entry entry = first; entry != null; entry = entry.next) { - if (entry.description != null) - if (entry.argument != null) - strings.add(entry.key + separator1 + entry.argument + - separator2 + entry.description); - else - strings.add(entry.key + separator2 + entry.description); - } - return strings; - } - -} diff --git a/sources/scalac/util/SourceRepresentation.java b/sources/scalac/util/SourceRepresentation.java deleted file mode 100644 index 83c1372769..0000000000 --- a/sources/scalac/util/SourceRepresentation.java +++ /dev/null @@ -1,227 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.io.File; - -import scalac.symtab.Symbol; -import scalac.symtab.SymbolNameWriter; - -public final class SourceRepresentation { - - /** The file name writer */ - private static SymbolNameWriter fileNameWriter = new SymbolNameWriter() - .setAllSeparators(File.separatorChar) - .setRootSeparator('\0'); - - public static int digit2int(char ch, int base) { - if ('0' <= ch && ch <= '9' && ch < '0' + base) - return ch - '0'; - else if ('A' <= ch && ch < 'A' + base - 10) - return ch - 'A' + 10; - else if ('a' <= ch && ch < 'a' + base - 10) - return ch - 'a' + 10; - else - return -1; - } - - public static byte int2digit(int x) { - if (x <= 9) - return (byte)(x + '0'); - else - return (byte)(x - 10 + 'A'); - } - -/* the next 4 functions convert between three fundamental name - * representations: - * - string each character 16 bit, - * - source characters outside 0..127 are represented by - * unicode escapes, \ u X X X X - * - ascii characters outside 0..127 are represented by two or three - * byte sequences with high bit set (as in class file format). - */ - -/** convert source bytes in source[offset..offset+len-1] to ascii. - */ - public static int source2ascii(byte source[], int offset, int len, byte ascii[]) { - int j = 0; - int i = 0; - while (i < len) { - if (source[offset + i] == '\\' && i + 1 < len) { - i++; - switch (source[offset + i]) { - case 'n': - ascii[j++] = (byte)'\n'; i++; continue; - case 't': - ascii[j++] = (byte)'\t'; i++; continue; - case 'b': - ascii[j++] = (byte)'\b'; i++; continue; - case 'r': - ascii[j++] = (byte)'\r'; i++; continue; - case 'f': - ascii[j++] = (byte)'\f'; i++; continue; - case 'u': - if (i + 4 < len) { - int code = 0; - int k = 1; - int d = 0; - while (k <= 4 && d >= 0) { - // !!! (char) - d = digit2int((char)source[offset + i + k], 16); - code = code * 16 + d; - k++; - } - if (d >= 0) { - if (code <= 0x7F) - ascii[j++] = (byte)code; - else - if (code <= 0x3FF) { - ascii[j++] = (byte)(0xC0 | (code >> 6)); - ascii[j++] = (byte)(0x80 | (code & 0x3F)); - } else { - ascii[j++] = (byte)(0xE0 | (code >> 12)); - ascii[j++] = (byte)(0x80 | - ((code >> 6) & 0x3F)); - ascii[j++] = (byte)(0x80 | (code & 0x3F)); - } - i = i + 5; - continue; - } - } - } - } - byte b = source[offset + i++]; - if (b >= 0) - ascii[j++] = b; - else { - ascii[j++] = (byte)(0xC0 | ((b >> 6) & 0x3)); - ascii[j++] = (byte)(0x80 | (b & 0x3F)); - } - } - return j; - } - -/** convert ascii bytes in ascii[offset..offset+len-1] to a string - */ - public static String ascii2string(byte ascii[], int offset, int len) { - char cs[] = new char[len]; - int i = offset; - int j = 0; - len += offset; - while (i < len) { - int b = ascii[i++] & 0xFF; - if (b >= 0xE0) { - b = ((b & 0x0F) << 12) | (ascii[i++] & 0x3F) << 6; - b = b | (ascii[i++] & 0x3F); - } - else - if (b >= 0xC0) - b = ((b & 0x1F) << 6) | (ascii[i++] & 0x3F); - cs[j++] = (char)b; - } - return new String(cs, 0, j); - } - -/** convert string to array of source bytes - */ - public static byte[] string2source(String s) { - byte[] source = new byte[s.length() * 6]; - int j = 0; - for (int i = 0; i < s.length(); i++) { - char ch = s.charAt(i); - switch (ch) { - case '\n': - source[j++] = (byte)'\\'; - source[j++] = (byte)'n'; - break; - case '\t': - source[j++] = (byte)'\\'; - source[j++] = (byte)'t'; - break; - case '\b': - source[j++] = (byte)'\\'; - source[j++] = (byte)'b'; - break; - case '\r': - source[j++] = (byte)'\\'; - source[j++] = (byte)'r'; - break; - case '\f': - source[j++] = (byte)'\\'; - source[j++] = (byte)'f'; - break; - case '\"': - source[j++] = (byte)'\\'; - source[j++] = (byte)'\"'; - break; - case '\'': - source[j++] = (byte)'\\'; - source[j++] = (byte)'\''; - break; - case '\\': - source[j++] = (byte)'\\'; - source[j++] = (byte)'\\'; - break; - default: - if ((' ' <= ch) && (ch <= 127)) - source[j++] = (byte)ch; - else { - source[j++] = (byte)'\\'; - source[j++] = (byte)'u'; - source[j++] = int2digit((ch >> 12) & 0xF); - source[j++] = int2digit((ch >> 8) & 0xF); - source[j++] = int2digit((ch >> 4) & 0xF); - source[j++] = int2digit(ch & 0xF); - } - } - } - byte[] res = new byte[j]; - System.arraycopy(source, 0, res, 0, j); - return res; - } - -/** convert string to array of ascii bytes - */ - public static byte[] string2ascii(String s) { - byte[] source = string2source(s); - byte[] ascii = new byte[source.length * 2]; - int alen = source2ascii(source, 0, source.length, ascii); - byte[] res = new byte[alen]; - System.arraycopy(ascii, 0, res, 0, alen); - return res; - } - -/** escape all characters outside 32..127 in string s - */ - public static String escape(String s) { - try { - return new String(string2source(s), "8859_1"); - } catch (java.io.UnsupportedEncodingException e) { - throw new InternalError(e.getMessage()); - } - } - -/** escape character c, if outside 32..127. - */ - public static String escape(char c) { - char[] s = {c}; - return escape(new String(s)); - } - - /** - * Returns the external file name with given suffix associated to - * given class. The file name use File.separatorChar as file - * separator. - */ - public static String externalizeFileName(Symbol clasz, String suffix) { - assert clasz.isClassType(): Debug.show(clasz); - return fileNameWriter.toString(clasz, suffix); - } - -} diff --git a/sources/scalac/util/Strings.java b/sources/scalac/util/Strings.java deleted file mode 100644 index 8d5c1d85c5..0000000000 --- a/sources/scalac/util/Strings.java +++ /dev/null @@ -1,102 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; - -public abstract class Strings { - - //######################################################################## - // Strings constants - - final public static String[] EMPTY_ARRAY = new String[0]; - - //######################################################################## - // Strings interface - - /** The line separator */ - public static String EOL = System.getProperty("line.separator", "\n"); - - /** Returns a string where all tabs have been replaced by white - * spaces to make the corresponding fields the same width. - */ - public static String format(List strings) { - List[] lines = new List[strings.size()]; - List widths = new ArrayList(); - int height = 0; - for (Iterator iterator = strings.iterator(); iterator.hasNext(); ) { - String string = (String)iterator.next(); - List line = lines[height++] = new ArrayList(); - for (int last = 0; last < string.length(); ) { - int next = string.indexOf('\t', last); - if (next < 0) next = string.length(); - String substring = string.substring(last, next); - int index = line.size(); - if (index == widths.size()) widths.add(new Integer(0)); - int width = ((Integer)widths.get(index)).intValue(); - widths.set( - index, new Integer(Math.max(width, substring.length()))); - line.add(substring); - last = next + 1; - } - } - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < lines.length; i++) { - List line = lines[i]; - for (int j = 0; true; j++) { - String string = (String)line.get(j); - buffer.append(string); - if (j == line.size() - 1) break; - int width = ((Integer)widths.get(j)).intValue(); - for (int k = string.length(); k<width; k++) buffer.append(' '); - } - buffer.append(EOL); - } - return buffer.toString(); - } - - /** Returns the first char of the string or -1 if the string is empty. */ - public static int firstChar(String string) { - return string.length() == 0 ? -1 : string.charAt(0); - } - - /** Returns the last char of the string or -1 if the string is empty. */ - public static int lastChar(String string) { - return string.length() == 0 ? -1 : string.charAt(string.length() - 1); - } - - /** Returns a copy of the string, with leading whitespace omitted. */ - public static String trimLeading(String string) { - for (int i = 0; i < string.length(); i++) - if (string.charAt(i) > ' ') return string.substring(i); - return ""; - } - - /** Returns a copy of the string, with trailing whitespace omitted. */ - public static String trimTrailing(String string) { - for (int i = string.length() - 1; i >= 0; i--) - if (string.charAt(i) > ' ') return string.substring(0, i + 1); - return ""; - } - - /** Returns the stack trace of the exception */ - public static String stackTrace(Throwable exception) { - StringWriter buffer = new StringWriter(); - PrintWriter writer = new PrintWriter(buffer); - exception.printStackTrace(writer); - writer.close(); - return buffer.toString(); - } - - //######################################################################## -} diff --git a/sources/scalac/util/TermName.java b/sources/scalac/util/TermName.java deleted file mode 100644 index 8215a8ce2e..0000000000 --- a/sources/scalac/util/TermName.java +++ /dev/null @@ -1,119 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -import java.util.HashMap; - -/** Instances of this class represent term names. */ -public final class TermName extends Name { - - //######################################################################## - // Private Variables - - /** Hashtable from string representation to term names. */ - private static HashMap/*<String,TermName>*/ strings = new HashMap(); - - /** Hashtable from ASCII representation to term names. */ - private static TermName[] asciis = new TermName[0x00008000]; - - //######################################################################## - // Private Fields - - /** The string representation */ - private final String string; - - /** The ASCII representation (null if not yet computed) */ - private byte[] ascii; - - /** The next name stored in the same bucket of the ASCII table */ - private TermName next; - - //######################################################################## - // Private Constructors - - /** Initializes this instance. */ - private TermName(String string) { - super(2 * strings.size(), null); - this.string = string; - strings.put(string, this); - } - - //######################################################################## - // Public Factories - - /** Returns the term name with given ASCII representation. */ - public static TermName fromAscii(byte[] bytes, int start, int count) { - int index = hashValue(bytes, start, count) & (asciis.length - 1); - for (TermName name = asciis[index]; name != null; name = name.next) - if (name.equals(bytes, start, count)) return name; - TermName name = fromString( - SourceRepresentation.ascii2string(bytes, start, count)); - byte[] ascii = new byte[count]; - for (int i = 0; i < ascii.length; i++) ascii[i] = bytes[start + i]; - name.setAscii(ascii, index); - return name; - } - - /** Returns the term name with given string representation. */ - public static TermName fromString(String string) { - Object value = strings.get(string); - return value != null ? (TermName)value : new TermName(string); - } - - //######################################################################## - // Public Methods - - /** Returns the string representation of this name. */ - public String toString() { - return string; - } - - /** - * Returns the ASCII representation of this name. The returned - * array is not a copy. Therefore, it is forbidden to modify it. - */ - public byte[] toAsciiUnsafe() { - if (ascii == null) { - byte[] ascii = SourceRepresentation.string2ascii(string); - int index = hashValue(ascii, 0, ascii.length) & (asciis.length-1); - setAscii(ascii, index); - } - return ascii; - } - - //######################################################################## - // Private Methods & Functions - - /** Sets the ASCII representation to given one. */ - private void setAscii(byte[] ascii, int index) { - assert this.ascii == null: this; - this.ascii = ascii; - this.next = asciis[index]; - asciis[index] = this; - } - - /** Is this name's ASCII representations equal to given one? */ - private boolean equals(byte[] bytes, int start, int count) { - if (ascii.length != count) return false; - for (int i = 0; i < count; i++) - if (ascii[i] != bytes[start + i]) return false; - return true; - } - - /** Returns the hash code of the ASCII representation. */ - private static int hashValue(byte[] bytes, int start, int count) { - if (count <= 0) return 0; - return count * (41 * 41 * 41) - + bytes[start] * (41 * 41) - + bytes[start + count - 1] * 41 - + bytes[start + (count >> 1)]; - } - - //######################################################################## -} diff --git a/sources/scalac/util/TypeName.java b/sources/scalac/util/TypeName.java deleted file mode 100644 index cfe3b5193f..0000000000 --- a/sources/scalac/util/TypeName.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -/** Instances of this class represent type names. */ -public final class TypeName extends Name { - - //######################################################################## - // Protected Constructors - - /** Initializes this instance. */ - protected TypeName(TermName term) { - super(term.index + 1, term); - } - - //######################################################################## - // Public Factories - - /** Returns the type name with given ASCII representation. */ - public static TypeName fromAscii(byte[] bytes, int start, int count) { - return TermName.fromAscii(bytes, start, count).toTypeName(); - } - - /** Returns the type name with given string representation. */ - public static TypeName fromString(String string) { - return TermName.fromString(string).toTypeName(); - } - - //######################################################################## -} diff --git a/sources/scalac/util/TypeNames.java b/sources/scalac/util/TypeNames.java deleted file mode 100644 index 9f7fea1144..0000000000 --- a/sources/scalac/util/TypeNames.java +++ /dev/null @@ -1,16 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.util; - -public class TypeNames { - - public static final Name EMPTY = Names.EMPTY.toTypeName(); - public static final Name WILDCARD_STAR = Name.fromString("_*").toTypeName(); - -} |