summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorschinz <schinz@epfl.ch>2005-04-20 14:48:13 +0000
committerschinz <schinz@epfl.ch>2005-04-20 14:48:13 +0000
commit4582381b8aace9eb91abb3c84bf2e935ff010dad (patch)
tree4b16c4d0366b7c0278fc2376c319662bd66a12d1 /sources/scalac
parent278cb7cc7bc469939f9789e35a54a41c4f31f1f7 (diff)
downloadscala-4582381b8aace9eb91abb3c84bf2e935ff010dad.tar.gz
scala-4582381b8aace9eb91abb3c84bf2e935ff010dad.tar.bz2
scala-4582381b8aace9eb91abb3c84bf2e935ff010dad.zip
- optimisation: treat strongly trivial Scala cl...
- optimisation: treat strongly trivial Scala classes as if they were Java classes: they receive no type constructor and no instantiation method, and their type is a JavaClassType
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/transformer/TypesAsValuesPhase.java126
1 files changed, 62 insertions, 64 deletions
diff --git a/sources/scalac/transformer/TypesAsValuesPhase.java b/sources/scalac/transformer/TypesAsValuesPhase.java
index 74161c356e..4b7f555108 100644
--- a/sources/scalac/transformer/TypesAsValuesPhase.java
+++ b/sources/scalac/transformer/TypesAsValuesPhase.java
@@ -49,7 +49,7 @@ import java.util.Collections;
* - For all polymorphic methods/constructors, add a value parameter
* for each type parameter.
*
- * - Add a method getType to every class, to obtain its type as a
+ * - Add a method getScalaType to every class, to obtain its type as a
* value.
*
* - Transform all type expressions into value expressions: type
@@ -180,15 +180,10 @@ public class TypesAsValuesPhase extends Phase {
? classSym.newStaticMethod(pos, 0, imName)
: classSym.owner().newMethodOrFunction(pos, flags, imName);
- // TODO special case for monomorphic instantiations
Symbol[] argTypes;
- if (true || classSym.typeParams().length > 0) {
- Symbol typesP =
- imSym.newVParam(pos, 0, Name.fromString("types"));
- typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE()));
- argTypes = new Symbol[]{ typesP };
- } else
- argTypes = Symbol.EMPTY_ARRAY;
+ Symbol typesP = imSym.newVParam(pos, 0, Name.fromString("types"));
+ typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE()));
+ argTypes = new Symbol[]{ typesP };
imSym.setInfo(new Type.MethodType(argTypes,
isStatic
@@ -252,7 +247,7 @@ public class TypesAsValuesPhase extends Phase {
toAddL.add(getInstMethSym(member));
}
- if (!isNestedClass(classSym)) {
+ if (needsInstantiationMethod(classSym)) {
toAddL.add(getTConstructorSym(classSym));
toAddL.add(getClassInitSym(classSym));
toAddL.add(getInstMethSym(classSym));
@@ -334,10 +329,50 @@ public class TypesAsValuesPhase extends Phase {
return type;
}
+ /**
+ * Return true iff the given type is trivial, that is if it
+ * has neither a prefix, nor type parameters.
+ */
+ private boolean isTrivial(Type tp) {
+ switch (tp) {
+ case TypeRef(_, Symbol sym, Type[] args):
+ if (sym == defs.ARRAY_CLASS)
+ return isTrivial(args[0]);
+ else
+ return sym.isStatic() && args.length == 0;
+ case SingleType(_, _):
+ case ThisType(_):
+ case CompoundType(_, _):
+ return false;
+ default:
+ throw Debug.abort("unexpected type", tp);
+ }
+ }
+
+ /**
+ * Return true iff the given type is strongly trivial, that is
+ * if it and all its ancestors are trivial.
+ */
+ private boolean isStronglyTrivial(Type tp) {
+ if (isTrivial(tp)) {
+ Type[] parents = tp.parents();
+ for (int i = 0; i < parents.length; ++i) {
+ if (!isStronglyTrivial(parents[i]))
+ return false;
+ }
+ return true;
+ } else
+ return false;
+ }
+
private boolean isNestedClass(Symbol classSym) {
return !classSym.owner().isPackageClass();
}
+ private boolean needsInstantiationMethod(Symbol classSym) {
+ return !(isNestedClass(classSym) || isStronglyTrivial(classSym.type()));
+ }
+
public void apply(CompilationUnit unit) {
transformer.apply(unit);
}
@@ -355,7 +390,7 @@ public class TypesAsValuesPhase extends Phase {
Symbol clsSym = tree.symbol();
TreeList newBody = new TreeList();
- if (!isNestedClass(clsSym)) {
+ if (needsInstantiationMethod(clsSym)) {
Symbol tcSym = getTConstructorSym(clsSym);
newBody.append(tConstructorVal(clsSym, tcSym));
Symbol ciSym = getClassInitSym(clsSym);
@@ -375,9 +410,9 @@ public class TypesAsValuesPhase extends Phase {
Symbol symbol = getSymbolFor(tree);
if (symbol.name == Names.getScalaType && symbol.isSynthetic()) {
- // Correct the body of the getType method which,
- // until now, was a placeholder (introduced by
- // RefCheck).
+ // Correct the body of the getScalaType method
+ // which, until now, was a placeholder (introduced
+ // by RefCheck).
return gen.DefDef(symbol,
scalaClassType(symbol.pos,
symbol.owner().type(),
@@ -764,7 +799,7 @@ public class TypesAsValuesPhase extends Phase {
Symbol isNonTrivialInst = defs.CLASSTYPE_ISNONTRIVIALINSTANCE();
Tree scalaTpVal = gen.mkAsInstanceOf(pos,
tpVal,
- defs.SCALACLASSTYPE_TYPE(),
+ defs.CLASSTYPE_TYPE(),
true);
Tree expensiveTest =
gen.mkApply_V(pos,
@@ -795,42 +830,6 @@ public class TypesAsValuesPhase extends Phase {
return gen.mkAsInstanceOf(pos, castCall, tp);
}
- /**
- * Return true iff the given type is trivial, that is if it
- * has neither a prefix, nor type parameters.
- */
- private boolean isTrivial(Type tp) {
- switch (tp) {
- case TypeRef(_, Symbol sym, Type[] args):
- if (sym == defs.ARRAY_CLASS)
- return isTrivial(args[0]);
- else
- return sym.isStatic() && args.length == 0;
- case SingleType(_, _):
- case ThisType(_):
- case CompoundType(_, _):
- return false;
- default:
- throw Debug.abort("unexpected type", tp);
- }
- }
-
- /**
- * Return true iff the given type is strongly trivial, that is
- * if it and all its ancestors are trivial.
- */
- private boolean isStronglyTrivial(Type tp) {
- if (isTrivial(tp)) {
- Type[] parents = tp.parents();
- for (int i = 0; i < parents.length; ++i) {
- if (!isStronglyTrivial(parents[i]))
- return false;
- }
- return true;
- } else
- return false;
- }
-
private boolean isSpecial(Type tp) {
switch (tp) {
case TypeRef(_, Symbol sym, _):
@@ -872,7 +871,7 @@ public class TypesAsValuesPhase extends Phase {
} else if (sym.isJava()) {
assert args.length <= 1
: Debug.show(sym) + " " + args.length;
- return javaType(pos, sym);
+ return javaClassType(pos, sym);
} else if (!sym.isParameter()) {
// Reference to a "global" type.
return scalaClassType(pos, tp, owner, env);
@@ -933,7 +932,7 @@ public class TypesAsValuesPhase extends Phase {
}
}
- private Tree javaType(int pos, Symbol sym) {
+ private Tree javaClassType(int pos, Symbol sym) {
Tree constr =
gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVACLASSTYPE());
Tree nameLit = gen.mkSymbolNameLit(pos, sym);
@@ -975,6 +974,9 @@ public class TypesAsValuesPhase extends Phase {
}
private Tree scalaClassType(int pos, Type tp, Symbol owner, TEnv env) {
+ if (isStronglyTrivial(tp))
+ return javaClassType(pos, tp.symbol());
+
switch (tp) {
case TypeRef(Type pre, Symbol sym, Type[] args):
Symbol insSym = getInstMethSym(sym);
@@ -982,18 +984,14 @@ public class TypesAsValuesPhase extends Phase {
? gen.Select(pos, gen.mkQualifier(pos, pre), insSym)
: gen.Ident(pos, insSym);
- // TODO special case for monomorphic cases
Tree[] insArgs;
- if (true || args.length > 0) {
- Tree[] elems = new Tree[args.length];
- int[] perm = typeParamsPermutation(sym.typeParams());
- for (int i = 0; i < args.length; ++i)
- elems[i] = typeAsValue(pos, args[perm[i]], owner, env);
- insArgs = new Tree[] {
- gen.mkNewArray(pos, defs.TYPE_TYPE(), elems, owner)
- };
- } else
- insArgs = Tree.EMPTY_ARRAY;
+ Tree[] elems = new Tree[args.length];
+ int[] perm = typeParamsPermutation(sym.typeParams());
+ for (int i = 0; i < args.length; ++i)
+ elems[i] = typeAsValue(pos, args[perm[i]], owner, env);
+ insArgs = new Tree[] {
+ gen.mkNewArray(pos, defs.TYPE_TYPE(), elems, owner)
+ };
return gen.mkApply_V(pos, preFun, insArgs);