summaryrefslogblamecommitdiff
path: root/sources/scalac/symtab/Definitions.java
blob: 2dd6c8f4814e805525efda410f47aadea7b37acc (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.*;
import scalac.util.*;
import scalac.symtab.classfile.*;
import Type.*;

public class Definitions {

    /** the root module
     */
    public final Symbol ROOT;
    public final Symbol ROOT_CLASS;
    public final Type   ROOT_TYPE;

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

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

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

    public final Symbol MATCH;
    public final Symbol IS;
    public final Symbol AS;
    public final Symbol EQEQ;
    public final Symbol BANGEQ;
    public final Symbol EQUALS;
    public final Symbol EQ;
    public final Symbol TOSTRING;
    public final Symbol HASHCODE;

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

    /** 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 final Symbol THROW;

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

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

    /** the primitive types
     */
    public final Symbol BYTE_CLASS;
    public final Type   BYTE_TYPE() {return BYTE_CLASS.type();}
    public final Symbol SHORT_CLASS;
    public final Type   SHORT_TYPE() {return SHORT_CLASS.type();}
    public final Symbol CHAR_CLASS;
    public final Type   CHAR_TYPE() {return CHAR_CLASS.type();}
    public final Symbol INT_CLASS;
    public final Type   INT_TYPE() {return INT_CLASS.type();}
    public final Symbol LONG_CLASS;
    public final Type   LONG_TYPE() {return LONG_CLASS.type();}
    public final Symbol FLOAT_CLASS;
    public final Type   FLOAT_TYPE() {return FLOAT_CLASS.type();}
    public final Symbol DOUBLE_CLASS;
    public final Type   DOUBLE_TYPE() {return DOUBLE_CLASS.type();}
    public final Symbol BOOLEAN_CLASS;
    public final Type   BOOLEAN_TYPE() {return BOOLEAN_CLASS.type();}
    public final Symbol UNIT_CLASS;
    public final Type   UNIT_TYPE() {return UNIT_CLASS.type();}

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

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

    /** the scala.TupleX classes
     */
    public final int  TUPLE_count = 10;
    public final Symbol[] TUPLE_CLASS = new Symbol[TUPLE_count];

    public Type tupleType(Type[] args) {
        assert 0 < args.length && args.length < TUPLE_count: args.length;
	return getType(TUPLE_CLASS[args.length], args);
    }

    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];
    }

    /** the scala.FunctionX classes
     */
    public final int  FUNCTION_count = 10;
    public final Symbol[] FUNCTION_CLASS = new Symbol[FUNCTION_count];

    public Type functionType(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);
    }

    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];
    }

    /** the scala.PartialFunction class
     */
    public final Symbol PARTIALFUNCTION_CLASS;

    public Type partialFunctionType(Type arg, Type result) {
	return getType(PARTIALFUNCTION_CLASS, new Type[] { arg, result });
    }

    private Symbol PARTIALFUNCTION_ISDEFINEDAT;

    public Symbol PARTIALFUNCTION_ISDEFINEDAT() {
        if (PARTIALFUNCTION_ISDEFINEDAT == null)
            PARTIALFUNCTION_ISDEFINEDAT = loadTerm(PARTIALFUNCTION_CLASS, Names.isDefinedAt);
        return PARTIALFUNCTION_ISDEFINEDAT;
    }

    /** the scala.Ref class
     */
    public final Symbol REF_CLASS;

    public Type refType(Type element) {
        return getType(REF_CLASS, element);
    }

    private Symbol REF_ELEM;

    public Symbol REF_ELEM() {
        if (REF_ELEM == null)
            REF_ELEM = loadTerm(REF_CLASS, Names.elem);
        return REF_ELEM;
    }

    /** the scala.List class
     */
    public final Symbol LIST_CLASS;
    // !!! public final Symbol LIST_NIL_CLASS;
    // !!! public final Symbol LIST_CONS_CLASS;

    public Type listType(Type element) {
        return getType(LIST_CLASS, element);
    }

    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.Iterator class
     */
    public final Symbol ITERATOR_CLASS;

    public Type iteratorType(Type element) {
        return getType(ITERATOR_CLASS, element);
    }

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

    /** the scala.Iterable class
     */
    public final Symbol ITERABLE_CLASS;

    public Type iterableType(Type element) {
        return getType(ITERABLE_CLASS, element);
    }

    private Symbol ITERABLE_ELEMENTS;

    public Symbol ITERABLE_ELEMENTS() {
        if (ITERABLE_ELEMENTS == null)
            ITERABLE_ELEMENTS = loadTerm(ITERABLE_CLASS, Names.elements);
        return ITERABLE_ELEMENTS;
    }

    /** the scala.Seq class
     */
    public final Symbol SEQ_CLASS;

    public Type seqType(Type element) {
	return getType(SEQ_CLASS, element);
    }

    private Symbol SEQ_LENGTH;

    public Symbol SEQ_LENGTH() {
        if (SEQ_LENGTH == null)
            SEQ_LENGTH = loadTerm(SEQ_CLASS, Names.length);
        return SEQ_LENGTH;
    }

    /** the scala.Array class
     */
    public final Symbol ARRAY_CLASS;

    public Type arrayType(Type element) {
        return getType(ARRAY_CLASS, element);
    }

    /** the scala.MatchError class
     */
    public final Symbol MATCHERROR;
    public final Symbol MATCHERROR_CLASS;

    private Symbol MATCHERROR_FAIL;

    public Symbol MATCHERROR_FAIL() {
        if (MATCHERROR_FAIL == null)
            MATCHERROR_FAIL = loadTerm(MATCHERROR, Names.fail);
        return MATCHERROR_FAIL;
    }

    /** string concatenation pseudo-methods of classes scala.Any and
     *  java.lang.String
     */
    //public final Symbol ANY_PLUS_STRING;
    public final Symbol STRING_PLUS_ANY;

    public final Symbol PATTERN_WILDCARD;

    public Definitions(Global global) {
        // a hack to make definitions accessible earlier to other
        // components
        global.definitions = this;
        PackageParser pparser = new PackageParser(global);

        // this is the root value; all top-level functions,
        // modules etc. are a member of this value
        ROOT = TermSymbol.newJavaPackageModule(
            Names.ROOT, Symbol.NONE, pparser);
        ROOT_CLASS = ROOT.moduleClass();
        // this is a prefix for all types inside of the anonymous package
        ROOT_TYPE = ROOT_CLASS.thisType();

        // the scala class
        Symbol SCALA_CLASS = getClass(Names.scala);

        // the scala.ANY classs
        ANY_CLASS = new ClassSymbol(
	    Position.NOPOS, Names.Any.toTypeName(), SCALA_CLASS, Modifiers.JAVA);
        SCALA_CLASS.members().enter(ANY_CLASS);
        ANY_CLASS.setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), ANY_CLASS));
        ANY_CLASS.primaryConstructor().setInfo(
	    Type.MethodType(Symbol.EMPTY_ARRAY, ANY_CLASS.typeConstructor()));

        // the java.lang.OBJECT class
        JAVA_OBJECT_CLASS = getClass(Names.java_lang_Object);

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

        // the scala.ANYREF class
	ANYREF_CLASS = new AliasTypeSymbol(
	    Position.NOPOS, Names.AnyRef.toTypeName(),
	    SCALA_CLASS, Modifiers.JAVA)
	    .setInfo(JAVA_OBJECT_TYPE());
        SCALA_CLASS.members().enter(ANYREF_CLASS);
	ANYREF_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, JAVA_OBJECT_TYPE()));

        // the scala.OBJECT class
	OBJECT_CLASS = getClass(Names.scala_Object);

        // the scala.ANYVAL class
	ANYVAL_CLASS = getClass(Names.scala_AnyVal);

        // the scala.ALL class
        ALL_CLASS = new ClassSymbol(
	    Position.NOPOS, Names.All.toTypeName(), SCALA_CLASS, 0);
        SCALA_CLASS.members().enter(ALL_CLASS);
        ALL_CLASS.setInfo(Type.compoundType(new Type[]{ANY_TYPE()}, new Scope(), ALL_CLASS));
        ALL_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALL_CLASS.typeConstructor()));

        // the scala.ALLREF class
        ALLREF_CLASS = new ClassSymbol(
	    Position.NOPOS, Names.AllRef.toTypeName(), SCALA_CLASS, 0);
        SCALA_CLASS.members().enter(ALLREF_CLASS);
        ALLREF_CLASS.setInfo(Type.compoundType(new Type[]{ANYREF_TYPE()}, new Scope(), ALLREF_CLASS));
        ALLREF_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALLREF_CLASS.typeConstructor()));

        // the array class
        ARRAY_CLASS = getClass(Names.scala_Array);

        // add members to java.lang.Throwable
        JAVA_THROWABLE_CLASS = getClass(Names.java_lang_Throwable);
        THROW = new TermSymbol(
	    Position.NOPOS, Names.throw_, JAVA_THROWABLE_CLASS, Modifiers.FINAL);
        THROW.setInfo(Type.PolyType(Symbol.EMPTY_ARRAY, ALL_TYPE()));
        JAVA_THROWABLE_CLASS.members().enter(THROW);

        // add the java.lang.String class to the scala package
        JAVA_STRING_CLASS = getClass(Names.java_lang_String);
        STRING_CLASS = new AliasTypeSymbol(
	    Position.NOPOS, Names.String.toTypeName(), SCALA_CLASS, 0)
	    .setInfo(JAVA_STRING_TYPE());
        SCALA_CLASS.members().enter(STRING_CLASS);
	STRING_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, STRING_CLASS.typeConstructor()));

        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);
        REF_CLASS = getClass(Names.scala_Ref);
	LIST_CLASS = getClass(Names.scala_List);
	ITERATOR_CLASS = getClass(Names.scala_Iterator);
	ITERABLE_CLASS = getClass(Names.scala_Iterable);
	SEQ_CLASS = getClass(Names.scala_Seq);
	MATCHERROR = getModule(Names.scala_MatchError);
	MATCHERROR_CLASS = getClass(Names.scala_MatchError);

	/*
        ANY_PLUS_STRING = new TermSymbol(
	    Position.NOPOS, Names.PLUS, ANY_CLASS, Modifiers.FINAL);
        ANY_PLUS_STRING.setInfo(
	    Type.MethodType(
		new Symbol[]{newParameter(ANY_PLUS_STRING, STRING_TYPE)},
		STRING_TYPE));
        ANY_CLASS.members().enter(ANY_PLUS_STRING);
	*/

        STRING_PLUS_ANY = new TermSymbol(
	    Position.NOPOS, Names.PLUS, JAVA_STRING_CLASS, Modifiers.FINAL);
        STRING_PLUS_ANY.setInfo(
	    Type.MethodType(
		new Symbol[]{newParameter(STRING_PLUS_ANY, ANY_TYPE())},
		STRING_TYPE()));
        JAVA_STRING_CLASS.members().enter(STRING_PLUS_ANY);

        // add members to class scala.Any
        MATCH = new TermSymbol(
	    Position.NOPOS, Names.match, ANY_CLASS, Modifiers.FINAL);
	Symbol matchTyParam1 = newTypeParameter(MATCH, ANY_TYPE());
	Symbol matchTyParam2 = newTypeParameter(MATCH, ANY_TYPE());
        MATCH.setInfo(
	    Type.PolyType(
		new Symbol[]{matchTyParam1, matchTyParam2},
		Type.MethodType(
		    new Symbol[]{
			newParameter(
			    MATCH,
			    functionType(
				new Type[]{matchTyParam1.typeConstructor()},
				matchTyParam2.typeConstructor()))},
		    matchTyParam2.typeConstructor())));
        ANY_CLASS.members().enter(MATCH);

        AS = new TermSymbol(
	    Position.NOPOS, Names.asInstanceOf, ANY_CLASS, Modifiers.FINAL);
        Symbol tvar = newTypeParameter(AS, ANY_TYPE());
        AS.setInfo(Type.PolyType(new Symbol[]{tvar}, tvar.type()));
        ANY_CLASS.members().enter(AS);

        IS = new TermSymbol(
	    Position.NOPOS, Names.isInstanceOf, ANY_CLASS, Modifiers.FINAL);
        IS.setInfo(Type.PolyType(new Symbol[]{newTypeParameter(IS, ANY_TYPE())},
				 BOOLEAN_TYPE()));
        ANY_CLASS.members().enter(IS);

        EQEQ = new TermSymbol(
	    Position.NOPOS, Names.EQEQ, ANY_CLASS, Modifiers.FINAL);
        EQEQ.setInfo(Type.MethodType(new Symbol[]{newParameter(EQEQ, ANY_TYPE())},
				     BOOLEAN_TYPE()));
        ANY_CLASS.members().enter(EQEQ);

        BANGEQ = new TermSymbol(
	    Position.NOPOS, Names.BANGEQ, ANY_CLASS, Modifiers.FINAL);
        BANGEQ.setInfo(Type.MethodType(new Symbol[]{newParameter(BANGEQ, ANY_TYPE())},
				       BOOLEAN_TYPE()));
        ANY_CLASS.members().enter(BANGEQ);

        EQUALS = new TermSymbol(
	    Position.NOPOS, Names.equals, ANY_CLASS, 0);
        EQUALS.setInfo(Type.MethodType(new Symbol[]{newParameter(EQUALS, ANY_TYPE())},
				     BOOLEAN_TYPE()));
        ANY_CLASS.members().enter(EQUALS);

	EQ = new TermSymbol(
	    Position.NOPOS, Names.eq, ANY_CLASS, 0);
        EQ.setInfo(Type.MethodType(new Symbol[]{newParameter(EQ, ANY_TYPE())},
				   BOOLEAN_TYPE()));
        ANY_CLASS.members().enter(EQ);

        TOSTRING = new TermSymbol(
	    Position.NOPOS, Names.toString, ANY_CLASS, 0);
        TOSTRING.setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, STRING_TYPE()));
        ANY_CLASS.members().enter(TOSTRING);

        HASHCODE = new TermSymbol(
	    Position.NOPOS, Names.hashCode, ANY_CLASS, 0);
        HASHCODE.setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, INT_TYPE()));
        ANY_CLASS.members().enter(HASHCODE);

        // add a null value to the root scope
	NULL = new TermSymbol(
	    Position.NOPOS, Names.null_, ROOT_CLASS, 0);
        NULL.setInfo(ALLREF_TYPE());
        ROOT.members().enter(NULL);

        // add a null value to the root scope
	ZERO = new TermSymbol(
	    Position.NOPOS, Names.ZERO, ROOT_CLASS, 0);
        ZERO.setInfo(ALL_TYPE());
        ROOT.members().enter(ZERO);

        PATTERN_WILDCARD = new TermSymbol(
            Position.NOPOS, Names.PATTERN_WILDCARD, Symbol.NONE, 0);
        PATTERN_WILDCARD.setType(ALL_TYPE());
    }

    private Symbol newParameter(Symbol owner, Type tp) {
	return new TermSymbol(Position.NOPOS, Name.fromString("v"), owner, Modifiers.PARAM)
	    .setInfo(tp);
    }

    private Symbol newTypeParameter(Symbol owner, Type bound) {
	return new AbsTypeSymbol(
	    Position.NOPOS, Name.fromString("T").toTypeName(), owner, Modifiers.PARAM)
	    .setInfo(bound);
    }

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

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

    public Type getType(Name fullname) {
	return getClass(fullname).type();
    }

    private Symbol loadTerm(Symbol clasz, Name name) {
        Symbol sym = clasz.lookup(name);
        assert sym.isTerm() && !sym.isOverloaded(): clasz+"."+name+" -> "+sym;
        return sym;
    }

    private Type getType(Symbol clasz, Type arg) {
	return getType(clasz, new Type[] { arg });
    }
    private Type getType(Symbol clasz, Type[] args) {
        return Type.appliedType(clasz.typeConstructor(), args);
    }
}