diff options
author | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2005-12-18 18:33:03 +0000 |
---|---|---|
committer | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2005-12-18 18:33:03 +0000 |
commit | d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a (patch) | |
tree | dfc6f7f497e58ea3321e6f687b11313d2afa86b5 /sources/scalac/symtab | |
parent | 0e82079908655682e5140ad521cef0572cb6d2a4 (diff) | |
download | scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.tar.gz scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.tar.bz2 scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.zip |
Removed old Scalac code in sources and various ...
Removed old Scalac code in sources and various other obsolete elements.
Diffstat (limited to 'sources/scalac/symtab')
35 files changed, 0 insertions, 14147 deletions
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(); - } - } -} - |