summaryrefslogblamecommitdiff
path: root/sources/scalac/symtab/Definitions.java
blob: c30138a0b4f0b5b7da268709b4f56fe16b8636b3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                          
                                  





                                             


                          



                                                                              

                                   
                                                               
 

                                                                              
 
                              
                                  
                                                             
 
                                 
                                     
                                                                   
 
                                 
                                     

                                                                   
                                 


                                                                   
                              

                                                             
 



                                                                              
                                          

                                                                             
                                     


                                                                             
                                        


                                                                                   

                                                                              
 

                                   


                                             
 

                                      


                                                
 
                               
                                   


                                             

                                
                                    


                                              

                               
                                   


                                             

                              
                                  


                                            

                               
                                   


                                             

                                
                                    


                                              

                                 
                                     


                                               
 



































































                                                                               








                                                                    
































                                                                              


















                                                                
 

                                                                              
 

                                    
 












                                                           

     

                                                                     

                                                     
                                                       





                                                                                                  

                                                                       
 
                                             
                                                           
                                          
                                                                                


                                     
                                             







                                                                                             

                                      
 



                                                                         
     
 


                                      
 








                                                                       

     

                                 
 



                                                           

     
                                  



















                                                               
                                        







                                                               







                                                                              
 
                                

                                         
                                                                              













                                                                              


                                     
                                       
                                                                  
                                  

                                             
 
                          
                                               
                                                                
                                        
 

                                                     
 
                                     
                                                          
                                                    
                                                                

                                                                
 
                           
                                                             

                                                                   
 
                                  
                                                







                                                      
 
                                      
                                                    


                                                                

                                                            
         
                                                

                                                                      
                                                        
                                                        
                                              

                                                  
                                                       







                                                           
                              









                                                             












                                                                             

































                                                                               
                          
                                  
                                
















                                                                            
                                                                         
                                 

     



                                                                              




















                                                                          
                                                                   













                                                                                       
                                                                 



                                         






























































                                                                               


                                                                              


                   
                                                                          

                                                  
     

                                                                           
                                                     
                                                    
     

                                                                              
 
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
**                                                                      **
** $Id$
\*                                                                      */

package scalac.symtab;

import ch.epfl.lamp.util.Position;

import scalac.Global;
import scalac.symtab.classfile.PackageParser;
import scalac.util.Debug;
import scalac.util.Name;
import scalac.util.Names;

public class Definitions {

    //########################################################################
    // Public Fields & Methods - Root module

    /** The root module */
    public final Symbol ROOT;
    public final Symbol ROOT_CLASS;
    public final Type   ROOT_TYPE() {return ROOT_CLASS.type();}

    //########################################################################
    // Public Fields & Methods - Top and bottom classes

    /** The scala.Any class */
    public final Symbol ANY_CLASS;
    public final Type   ANY_TYPE() {return ANY_CLASS.type();}

    /** The scala.AnyVal class */
    public final Symbol ANYVAL_CLASS;
    public final Type   ANYVAL_TYPE() {return ANYVAL_CLASS.type();}

    /** The scala.AnyRef class */
    public final Symbol ANYREF_CLASS;
    public final Type   ANYREF_TYPE() {return ANYREF_CLASS.type();}

    /** The scala.AllRef class */
    public final Symbol ALLREF_CLASS;
    public final Type   ALLREF_TYPE() {return ALLREF_CLASS.type();}

    /** The scala.All class */
    public final Symbol ALL_CLASS;
    public final Type   ALL_TYPE() {return ALL_CLASS.type();}

    //########################################################################
    // Public Fields & Methods - Java classes

    /** The java.lang.Object class */
    public final Symbol JAVA_OBJECT_CLASS;
    public final Type   JAVA_OBJECT_TYPE() {return JAVA_OBJECT_CLASS.type();}

    /** The java.lang.String class */
    public final Symbol JAVA_STRING_CLASS;
    public final Type   JAVA_STRING_TYPE() {return JAVA_STRING_CLASS.type();}

    /** The java.lang.Throwable class */
    public final Symbol JAVA_THROWABLE_CLASS;
    public final Type   JAVA_THROWABLE_TYPE() {return JAVA_THROWABLE_CLASS.type();}

    //########################################################################
    // Public Fields & Methods - Scala value classes

    /** The scala.Unit class */
    public final Symbol UNIT_CLASS;
    public final Type   UNIT_TYPE() {
        return UNIT_TYPE.type().resultType();
    }

    /** The scala.Boolean class */
    public final Symbol BOOLEAN_CLASS;
    public final Type   BOOLEAN_TYPE() {
        return BOOLEAN_TYPE.type().resultType();
    }

    /** The scala.Byte class */
    public final Symbol BYTE_CLASS;
    public final Type   BYTE_TYPE() {
        return BYTE_TYPE.type().resultType();
    }

    /** The scala.Short class */
    public final Symbol SHORT_CLASS;
    public final Type   SHORT_TYPE() {
        return SHORT_TYPE.type().resultType();
    }

    /** The scala.Char class */
    public final Symbol CHAR_CLASS;
    public final Type   CHAR_TYPE() {
        return CHAR_TYPE.type().resultType();
    }

    /** The scala.Int class */
    public final Symbol INT_CLASS;
    public final Type   INT_TYPE() {
        return INT_TYPE.type().resultType();
    }

    /** The scala.Long class */
    public final Symbol LONG_CLASS;
    public final Type   LONG_TYPE() {
        return LONG_TYPE.type().resultType();
    }

    /** The scala.Float class */
    public final Symbol FLOAT_CLASS;
    public final Type   FLOAT_TYPE() {
        return FLOAT_TYPE.type().resultType();
    }

    /** The scala.Double class */
    public final Symbol DOUBLE_CLASS;
    public final Type   DOUBLE_TYPE() {
        return DOUBLE_TYPE.type().resultType();
    }

    //########################################################################
    // Public Fields & Methods - Scala reference classes

    /** The scala.Object class */
    public final Symbol OBJECT_CLASS;
    public final Type   OBJECT_TYPE() {return OBJECT_CLASS.type();}

    /** The scala.String class */
    public final Symbol STRING_CLASS;
    public final Type   STRING_TYPE() {return STRING_CLASS.type();}

    /** The scala.Ref class */
    public final Symbol REF_CLASS;
    public final Type   REF_TYPE(Type element) {
        return getType(REF_CLASS, 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 getType(TUPLE_CLASS[args.length], 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 && args.length < FUNCTION_COUNT: args.length;
        args = Type.cloneArray(args, 1);
        args[args.length - 1] = result;
	return getType(FUNCTION_CLASS[args.length - 1], args);
    }

    /** The scala.PartialFunction class */
    public final Symbol PARTIALFUNCTION_CLASS;
    public final Type   PARTIALFUNCTION_TYPE(Type argument, Type result) {
	return getType(PARTIALFUNCTION_CLASS, new Type[] { argument, result });
    }

    /** The scala.Iterable class */
    public final Symbol ITERABLE_CLASS;
    public final Type   ITERABLE_TYPE(Type element) {
        return getType(ITERABLE_CLASS, element);
    }

    /** The scala.Iterator class */
    public final Symbol ITERATOR_CLASS;
    public final Type   ITERATOR_TYPE(Type element) {
        return getType(ITERATOR_CLASS, element);
    }

    /** The scala.Seq class */
    public final Symbol SEQ_CLASS;
    public final Type   SEQ_TYPE(Type element) {
	return getType(SEQ_CLASS, element);
    }

    /** The scala.List class */
    public final Symbol LIST_CLASS;
    public final Type   LIST_TYPE(Type element) {
        return getType(LIST_CLASS, element);
    }

    /** The scala.Array class */
    public final Symbol ARRAY_CLASS;
    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);
        }
    }

    /** The scala.MatchError module */
    public final Symbol MATCHERROR;

    //########################################################################
    // Public Fields & Methods - Top and bottom class methods

    /** Some scala.Any methods */
    public final Symbol ANY_EQ;
    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_AS;
    public final Symbol ANY_MATCH;

    //########################################################################
    // Public Fields & Methods - Java class methods

    /** Some java.lang.String methods */
    public final Symbol JAVA_STRING_PLUS;

    /** Some java.lang.Throwable methods */
    public final Symbol JAVA_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.Object methods */
    private Symbol OBJECT_TAG;

    public Symbol OBJECT_TAG() {
        if (OBJECT_TAG == null)
            OBJECT_TAG = loadTerm(OBJECT_CLASS, Names.tag);
        return OBJECT_TAG;
    }

    /** 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;
    }

    /** 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;
    }

    //########################################################################
    // Public Fields - Global values

    /** The null value */
    public final Symbol NULL;

    /** The zero value (a default null for type variables with bound Any) */
    public final Symbol ZERO;

    /** The universal pattern */
    public final Symbol PATTERN_WILDCARD;

    //########################################################################
    // Private Fields - Symbol

    private final Symbol UNIT_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;
        // force initialization of class Type
        Type.localThisType.symbol();

        // the root module
        ROOT = TermSymbol.newJavaPackageModule(
            Names.ROOT, Symbol.NONE, new PackageParser(global));
        ROOT_CLASS = ROOT.moduleClass();

        // the scala package
        Symbol SCALA_PACKAGE = getClass(Names.scala);

        // the top and bottom classes
        ANY_CLASS = newClass(SCALA_PACKAGE, Names.Any, 0);
	ANYVAL_CLASS = getClass(Names.scala_AnyVal);
	ANYREF_CLASS = newAlias(SCALA_PACKAGE, Names.AnyRef, 0);
        ALLREF_CLASS = newClass(SCALA_PACKAGE, Names.AllRef, 0);
        ALL_CLASS = newClass(SCALA_PACKAGE, Names.All, 0);

        // the java classes
        JAVA_OBJECT_CLASS = getClass(Names.java_lang_Object);
        JAVA_THROWABLE_CLASS = getClass(Names.java_lang_Throwable);
        JAVA_STRING_CLASS = getClass(Names.java_lang_String);

        // the scala value classes
        UNIT_CLASS = getClass(Names.scala_Unit);
        BOOLEAN_CLASS = getClass(Names.scala_Boolean);
        BYTE_CLASS = getClass(Names.scala_Byte);
        SHORT_CLASS = getClass(Names.scala_Short);
        CHAR_CLASS = getClass(Names.scala_Char);
        INT_CLASS = getClass(Names.scala_Int);
        LONG_CLASS = getClass(Names.scala_Long);
        FLOAT_CLASS = getClass(Names.scala_Float);
        DOUBLE_CLASS = getClass(Names.scala_Double);

        // the scala reference classes
	OBJECT_CLASS = getClass(Names.scala_Object);
        STRING_CLASS = newAlias(SCALA_PACKAGE, Names.String, 0);
        REF_CLASS = getClass(Names.scala_Ref);
        for (int i = 1; i < TUPLE_COUNT; i++) {
            TUPLE_CLASS[i] = getClass(Names.scala_Tuple(i));
            TUPLE_FIELD[i] = new Symbol[i];
        }
        for (int i = 0; i < FUNCTION_COUNT; i++)
            FUNCTION_CLASS[i] = getClass(Names.scala_Function(i));
	PARTIALFUNCTION_CLASS = getClass(Names.scala_PartialFunction);
	ITERABLE_CLASS = getClass(Names.scala_Iterable);
	ITERATOR_CLASS = getClass(Names.scala_Iterator);
	SEQ_CLASS = getClass(Names.scala_Seq);
	LIST_CLASS = getClass(Names.scala_List);
        ARRAY_CLASS = getClass(Names.scala_Array);
	MATCHERROR = getModule(Names.scala_MatchError);

        // initialize generated classes and aliases
        initClass(ANY_CLASS, Type.EMPTY_ARRAY);
        initAlias(ANYREF_CLASS, JAVA_OBJECT_TYPE());
        initClass(ALLREF_CLASS, new Type[]{ANYREF_TYPE()});
        initClass(ALL_CLASS, new Type[]{ANY_TYPE()});
        initAlias(STRING_CLASS, JAVA_STRING_TYPE());

        // create type symbols
        UNIT_TYPE    = newTerm(ROOT_CLASS, Names.Unit   , 0);
        BOOLEAN_TYPE = newTerm(ROOT_CLASS, Names.Boolean, 0);
        BYTE_TYPE    = newTerm(ROOT_CLASS, Names.Byte   , 0);
        SHORT_TYPE   = newTerm(ROOT_CLASS, Names.Short  , 0);
        CHAR_TYPE    = newTerm(ROOT_CLASS, Names.Char   , 0);
        INT_TYPE     = newTerm(ROOT_CLASS, Names.Int    , 0);
        LONG_TYPE    = newTerm(ROOT_CLASS, Names.Long   , 0);
        FLOAT_TYPE   = newTerm(ROOT_CLASS, Names.Float  , 0);
        DOUBLE_TYPE  = newTerm(ROOT_CLASS, Names.Double , 0);
        ARRAY_TYPE   = newTerm(ROOT_CLASS, Names.Array  , 0);

        initMethod(UNIT_TYPE   , Type.EMPTY_ARRAY, UNIT_CLASS.type());
        initMethod(BOOLEAN_TYPE, Type.EMPTY_ARRAY, BOOLEAN_CLASS.type());
        initMethod(BYTE_TYPE   , Type.EMPTY_ARRAY, BYTE_CLASS.type());
        initMethod(SHORT_TYPE  , Type.EMPTY_ARRAY, SHORT_CLASS.type());
        initMethod(CHAR_TYPE   , Type.EMPTY_ARRAY, CHAR_CLASS.type());
        initMethod(INT_TYPE    , Type.EMPTY_ARRAY, INT_CLASS.type());
        initMethod(LONG_TYPE   , Type.EMPTY_ARRAY, LONG_CLASS.type());
        initMethod(FLOAT_TYPE  , Type.EMPTY_ARRAY, FLOAT_CLASS.type());
        initMethod(DOUBLE_TYPE , Type.EMPTY_ARRAY, DOUBLE_CLASS.type());
        initMethod(ARRAY_TYPE  , Type.EMPTY_ARRAY,
            Type.appliedType(ARRAY_CLASS.type(), new Type[]{ANYREF_TYPE()}));

        // add members to scala.Any
	ANY_EQ       = newTerm(ANY_CLASS, Names.eq          , 0);
        ANY_EQEQ     = newTerm(ANY_CLASS, Names.EQEQ        , Modifiers.FINAL);
        ANY_BANGEQ   = newTerm(ANY_CLASS, Names.BANGEQ      , Modifiers.FINAL);
        ANY_EQUALS   = newTerm(ANY_CLASS, Names.equals      , 0);
        ANY_HASHCODE = newTerm(ANY_CLASS, Names.hashCode    , 0);
        ANY_TOSTRING = newTerm(ANY_CLASS, Names.toString    , 0);
        // ANY_PLUS  = newTerm(ANY_CLASS, Names.PLUS        , Modifiers.FINAL);
        ANY_IS       = newTerm(ANY_CLASS, Names.isInstanceOf, Modifiers.FINAL);
        ANY_AS       = newTerm(ANY_CLASS, Names.asInstanceOf, Modifiers.FINAL);
        ANY_MATCH    = newTerm(ANY_CLASS, Names.match       , Modifiers.FINAL);

        initMethod(ANY_EQ      , new Type[]{ANY_TYPE()}   , BOOLEAN_TYPE());
        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_AS_TPARAMS = {newTParam(ANY_AS, 0, ANY_TYPE())};
        ANY_AS.setInfo(Type.PolyType(ANY_AS_TPARAMS,ANY_AS_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.String
        JAVA_STRING_PLUS =
            newTerm(JAVA_STRING_CLASS, Names.PLUS, Modifiers.FINAL);
        initMethod(JAVA_STRING_PLUS, new Type[]{ANY_TYPE()}, STRING_TYPE());

        // add members to java.lang.Throwable
        JAVA_THROWABLE_THROW =
            newTerm(JAVA_THROWABLE_CLASS, Names.throw_, Modifiers.FINAL);
        JAVA_THROWABLE_THROW.setInfo(
            Type.PolyType(Symbol.EMPTY_ARRAY, ALL_TYPE()));

        // create global values
	NULL = newTerm(ROOT_CLASS, Names.null_, 0).setInfo(ALLREF_TYPE());
	ZERO = newTerm(ROOT_CLASS, Names.ZERO, 0).setInfo(ALL_TYPE());
        PATTERN_WILDCARD = newTerm(ROOT_CLASS, Names.PATTERN_WILDCARD, 0)
            .setType(ALL_TYPE());
    }

    //########################################################################
    // Public Methods

    /** Returns the symbol of the module with the given fullname. */
    public Symbol getModule(Name fullname) {
	Scope scope = ROOT_CLASS.members();
        int i = 0;
        int j = fullname.pos((byte)'.', i);
	while (j < fullname.length()) {
	    scope = scope.lookup(fullname.subName(i, j)).members();
	    i = j + 1;
	    j = fullname.pos((byte)'.', i);
	}
	Symbol sym = scope.lookup(fullname.subName(i, fullname.length()));
        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;
            }
        }
        assert sym.isModule() : "no module '" + fullname + "'";
        return sym;
    }

    /** Returns the symbol of the class with the given fullname. */
    public Symbol getClass(Name fullname) {
	Scope scope = ROOT_CLASS.members();
        int i = 0;
        int j = fullname.pos((byte)'.', i);
	while (j < fullname.length()) {
	    scope = scope.lookup(fullname.subName(i, j)).members();
	    i = j + 1;
	    j = fullname.pos((byte)'.', i);
	}
	Symbol sym = scope.lookup(fullname.subName(i, fullname.length()).toTypeName());
	assert sym.kind != Kinds.NONE : "no class '" + fullname + "'";
	return sym;
    }

    /** Returns the type of the class with the given fullname. */
    public Type getType(Name fullname) {
	return getClass(fullname).type();
    }

    //########################################################################
    // Private Methods

    /** Creates a new class */
    private Symbol newClass(Symbol owner, Name name, int flags) {
        name = name.toTypeName();
        Symbol clasz = new ClassSymbol(Position.NOPOS, name, owner, flags);
        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 = new AliasTypeSymbol(Position.NOPOS, name, owner, flags);
        owner.members().enter(alias);
        return alias;
    }

    /** Creates a new term */
    private Symbol newTerm(Symbol owner, Name name, int flags) {
        Symbol method = new TermSymbol(Position.NOPOS, name, owner, flags);
        if (owner != Symbol.NONE) owner.members().enterOrOverload(method);
        return method;
    }

    /** Creates a new type parameter */
    private Symbol newTParam(Symbol owner, int index, Type bound) {
        Name name = Name.fromString("T" + index).toTypeName();
	return new AbsTypeSymbol(Position.NOPOS, name, owner, Modifiers.PARAM)
	    .setInfo(bound);
    }

    /** Creates a new value parameter */
    private Symbol newVParam(Symbol owner, int index, Type type) {
        Name name = Name.fromString("v" + index);
        return new TermSymbol(Position.NOPOS, name, owner, Modifiers.PARAM)
	    .setInfo(type);
    }

    /** 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() && !sym.isOverloaded(): clasz+"."+name+" -> "+sym;
        return sym;
    }

    /** Returns the type of given class applied to given type argument. */
    private Type getType(Symbol clasz, Type arg) {
	return getType(clasz, new Type[] { arg });
    }

    /** Returns the type of given class applied to given type arguments. */
    private Type getType(Symbol clasz, Type[] args) {
        return Type.appliedType(clasz.type(), args);
    }

    //########################################################################
}