diff options
author | Martin Odersky <odersky@gmail.com> | 2003-02-13 14:41:36 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-02-13 14:41:36 +0000 |
commit | 4177daab2f54bdb20c71f623296a8bb32616fd12 (patch) | |
tree | 23f08b43f3758e825d5965b336030603a65bbcf7 /sources/scalac/symtab/Definitions.java | |
parent | 33d6e170c97ca7b2f991896a0729941a7240b6d6 (diff) | |
download | scala-4177daab2f54bdb20c71f623296a8bb32616fd12.tar.gz scala-4177daab2f54bdb20c71f623296a8bb32616fd12.tar.bz2 scala-4177daab2f54bdb20c71f623296a8bb32616fd12.zip |
Initial version.
Diffstat (limited to 'sources/scalac/symtab/Definitions.java')
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java new file mode 100644 index 0000000000..6d67edac42 --- /dev/null +++ b/sources/scalac/symtab/Definitions.java @@ -0,0 +1,421 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +** $Id$ +\* */ + +package scalac.symtab; + +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 scala module + */ + public final Symbol SCALA; + public final Symbol SCALA_CLASS; + public final Type SCALA_TYPE; + + /** the java module + */ + public final Symbol JAVA; + public final Symbol JAVA_CLASS; + public final Type JAVA_TYPE; + + /** the java.lang module + */ + public final Symbol JAVALANG; + public final Symbol JAVALANG_CLASS; + public final Type JAVALANG_TYPE; + + /** the scala.runtime module + */ + public final Symbol SCALARUNTIME; + public final Symbol SCALARUNTIME_CLASS; + public final Type SCALARUNTIME_TYPE; + + /** the null value + */ + public final Symbol NULL; + + /** the scala.Any class + */ + public final Symbol ANY_CLASS; + public final Type ANY_TYPE; + + /** some methods of the scala.Any class + */ + public final Symbol MATCH; + public final Symbol IS; + public final Symbol AS; + public final Symbol EQEQ; + public final Symbol BANGEQ; + public final Symbol TOSTRING; + public final Symbol HASHCODE; + + /** a method of class java.lang.Throwable + */ + public final Symbol THROW; + + /** the scala.AnyVal class + */ + public final Symbol ANYVAL_CLASS; + public final Type ANYVAL_TYPE; + + /** the scala.AnyRef class + */ + public final Symbol ANYREF_CLASS; + public final Type ANYREF_TYPE; + + /** the java.lang.Object class + */ + public final Symbol JAVA_OBJECT_CLASS; + public final Type JAVA_OBJECT_TYPE; + + /** the scala.Object class + */ + public final Symbol OBJECT_CLASS; + public final Type OBJECT_TYPE; + + /** the primitive types + */ + public final Symbol BYTE_CLASS; + public final Type BYTE_TYPE; + public final Symbol SHORT_CLASS; + public final Type SHORT_TYPE; + public final Symbol CHAR_CLASS; + public final Type CHAR_TYPE; + public final Symbol INT_CLASS; + public final Type INT_TYPE; + public final Symbol LONG_CLASS; + public final Type LONG_TYPE; + public final Symbol FLOAT_CLASS; + public final Type FLOAT_TYPE; + public final Symbol DOUBLE_CLASS; + public final Type DOUBLE_TYPE; + public final Symbol BOOLEAN_CLASS; + public final Type BOOLEAN_TYPE; + public final Symbol UNIT_CLASS; + public final Type UNIT_TYPE; + + /** the array class + */ + public final Symbol ARRAY_CLASS; + + /** types from java.lang + */ + public final Symbol JAVA_STRING_CLASS; + public final Type JAVA_STRING_TYPE; + public final Symbol JAVA_THROWABLE_CLASS; + public final Type JAVA_THROWABLE_TYPE; + + /** types from scala + */ + public final Symbol STRING_CLASS; + public final Type STRING_TYPE; + + /** string concatenation pseudo-methods of classes scala.Any and + * java.lang.String + */ + //public final Symbol ANY_PLUS_STRING; + public final Symbol STRING_PLUS_ANY; + + /** members of class Boolean + */ + private Symbol TRUE; + private Symbol FALSE; + private Symbol BARBAR; + private Symbol AMPAMP; + + public Symbol TRUE () { loadBooleanMembers(); return TRUE ; } + public Symbol FALSE () { loadBooleanMembers(); return FALSE ; } + public Symbol BARBAR() { loadBooleanMembers(); return BARBAR; } + public Symbol AMPAMP() { loadBooleanMembers(); return AMPAMP; } + + 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.EMPTY, 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 module + SCALA = getModule(Names.scala); + // the scala class + SCALA_CLASS = SCALA.moduleClass(); + // the scala package as a prefix + SCALA_TYPE = Type.singleType(ROOT_TYPE, SCALA); + + // the java module + JAVA = getModule(Names.java); + // the java class + JAVA_CLASS = JAVA.moduleClass(); + // the java package as a prefix + JAVA_TYPE = Type.singleType(ROOT_TYPE, JAVA); + + // the java.lang module + JAVALANG = getModule(Names.java_lang); + // the java.lang class + JAVALANG_CLASS = JAVALANG.moduleClass(); + // the java.lang package as a prefix + JAVALANG_TYPE = Type.singleType(JAVA_TYPE, JAVALANG); + + // the scala.runtime module + SCALARUNTIME = getModule(Names.scala_runtime); + // the scala.runtime class + SCALARUNTIME_CLASS = SCALARUNTIME.moduleClass(); + // the scala.runtime package as a prefix + SCALARUNTIME_TYPE = Type.singleType(SCALA_TYPE, SCALARUNTIME); + + // the scala.ANY classs + ANY_CLASS = new ClassSymbol( + Position.NOPOS, Names.Any.toTypeName(), SCALA_CLASS, Modifiers.JAVA); + SCALA_CLASS.members().enter(ANY_CLASS); + ANY_TYPE = monoType(ANY_CLASS); + ANY_CLASS.setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), ANY_CLASS)); + ANY_CLASS.constructor().setInfo( + Type.PolyType(Symbol.EMPTY_ARRAY, ANY_TYPE)); + + // the java.lang.OBJECT class + JAVA_OBJECT_CLASS = getClass(Names.java_lang_Object); + JAVA_OBJECT_TYPE = monoType(JAVA_OBJECT_CLASS); + JAVA_OBJECT_CLASS.setInfo(pparser.classCompletion); + + // the scala.ANYREF class + ANYREF_CLASS = new TypeSymbol( + Kinds.ALIAS, Position.NOPOS, Names.AnyRef.toTypeName(), + SCALA_CLASS, Modifiers.JAVA) + .setInfo(JAVA_OBJECT_TYPE); + ANYREF_CLASS.constructor().setInfo( + Type.PolyType(Symbol.EMPTY_ARRAY, Type.NoType)); + + ANYREF_TYPE = monoType(ANYREF_CLASS); + SCALA.members().enter(ANYREF_CLASS); + + // the scala.OBJECT class + OBJECT_CLASS = getClass(Names.scala_Object); + OBJECT_TYPE = monoType(OBJECT_CLASS); + + // the scala.ANYVAL class + ANYVAL_CLASS = getClass(Names.scala_AnyVal); + ANYVAL_TYPE = monoType(ANYVAL_CLASS); + + // the primitive types + DOUBLE_CLASS = getClass(Names.scala_Double); + DOUBLE_TYPE = monoType(DOUBLE_CLASS); + FLOAT_CLASS = getClass(Names.scala_Float); + FLOAT_TYPE = monoType(FLOAT_CLASS); + LONG_CLASS = getClass(Names.scala_Long); + LONG_TYPE = monoType(LONG_CLASS); + INT_CLASS = getClass(Names.scala_Int); + INT_TYPE = monoType(INT_CLASS); + CHAR_CLASS = getClass(Names.scala_Char); + CHAR_TYPE = monoType(CHAR_CLASS); + SHORT_CLASS = getClass(Names.scala_Short); + SHORT_TYPE = monoType(SHORT_CLASS); + BYTE_CLASS = getClass(Names.scala_Byte); + BYTE_TYPE = monoType(BYTE_CLASS); + BOOLEAN_CLASS = getClass(Names.scala_Boolean); + BOOLEAN_TYPE = monoType(BOOLEAN_CLASS); + UNIT_CLASS = getClass(Names.scala_Unit); + UNIT_TYPE = monoType(UNIT_CLASS); + + // the array class + ARRAY_CLASS = getClass(Names.scala_Array); + + // add members to java.lang.Throwable + JAVA_THROWABLE_CLASS = getClass(Names.java_lang_Throwable); + JAVA_THROWABLE_TYPE = monoType(JAVA_THROWABLE_CLASS); + THROW = new TermSymbol( + Position.NOPOS, Names.throw_, JAVA_THROWABLE_CLASS, Modifiers.FINAL); + Symbol tvar = newTypeParameter(THROW, ANY_TYPE); + THROW.setInfo(Type.PolyType(new Symbol[]{tvar}, tvar.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); + JAVA_STRING_TYPE = monoType(JAVA_STRING_CLASS); + STRING_CLASS = new TypeSymbol( + Kinds.ALIAS, Position.NOPOS, Names.String.toTypeName(), SCALA_CLASS, 0) + .setInfo(JAVA_STRING_TYPE); + STRING_CLASS.constructor().setInfo( + Type.PolyType(Symbol.EMPTY_ARRAY, Type.NoType)); + STRING_TYPE = monoType(STRING_CLASS); + SCALA.members().enter(STRING_CLASS); + + /* + 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, STRING_CLASS, Modifiers.FINAL); + STRING_PLUS_ANY.setInfo( + Type.MethodType( + new Symbol[]{newParameter(STRING_PLUS_ANY, ANY_TYPE)}, + STRING_TYPE)); + STRING_CLASS.members().enter(STRING_PLUS_ANY); + + // add members to class scala.Any + MATCH = new TermSymbol( + Position.NOPOS, Names.match, ANY_CLASS, Modifiers.FINAL); + MATCH.setInfo( + Type.MethodType( + new Symbol[]{newParameter(MATCH, OBJECT_TYPE)}, + OBJECT_TYPE)); + ANY_CLASS.members().enter(MATCH); + + AS = new TermSymbol( + Position.NOPOS, Names.as, ANY_CLASS, Modifiers.FINAL); + 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.is, 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, 0); + 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, 0); + BANGEQ.setInfo(Type.MethodType(new Symbol[]{newParameter(BANGEQ, ANY_TYPE)}, + BOOLEAN_TYPE)); + ANY_CLASS.members().enter(BANGEQ); + + 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); + tvar = newTypeParameter(NULL, ANYREF_TYPE); + NULL.setInfo(Type.PolyType(new Symbol[]{tvar}, tvar.type())); + ROOT.members().enter(NULL); + } + + 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 TypeSymbol( + Kinds.TYPE, 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(); + } + + public Type monoType(Symbol c) { + return Type.TypeRef(c.owner().thisType(), c, Type.EMPTY_ARRAY); + } + + public Type getJavaType(Name fullname) { + return monoType(getClass(fullname)); + } + + private void loadBooleanMembers() { + if (TRUE != null) return; + Symbol booleanStatics = getModule(Names.scala_Boolean); + TRUE = booleanStatics.members().lookup(Names.True); + FALSE = booleanStatics.members().lookup(Names.False); + BARBAR = BOOLEAN_TYPE.lookup(Names.BARBAR); + AMPAMP = BOOLEAN_TYPE.lookup(Names.AMPAMP); + } + + public Type arrayType(Type elemtpe) { + return Type.appliedType(monoType(ARRAY_CLASS), new Type[]{elemtpe}); + } + + public Type functionType(Type[] argtps, Type restp) { + Type[] argtps1 = new Type[argtps.length + 1]; + System.arraycopy(argtps, 0, argtps1, 0, argtps.length); + argtps1[argtps.length] = Type.covarType(restp); + return Type.appliedType( + getType(Name.fromString("scala.Function" + argtps.length)), + argtps1); + } + + public Type tupleType(Type[] args) { + assert args.length > 0; + Type[] args1 = new Type[args.length]; + for (int i = 0; i < args.length; i++) + args1[i] = Type.covarType(args[i]); + return Type.appliedType( + getType(Name.fromString("scala.Tuple" + args.length)), args1); + } +} |