summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-04-06 08:52:16 +0000
committerpaltherr <paltherr@epfl.ch>2004-04-06 08:52:16 +0000
commit5dc50833450033d06f845bc7473808731a155f82 (patch)
tree79a532329ec0350504285ecc00decb3b7c16a045
parent43505887a331fbf647ba39a85bdf16c321ce8037 (diff)
downloadscala-5dc50833450033d06f845bc7473808731a155f82.tar.gz
scala-5dc50833450033d06f845bc7473808731a155f82.tar.bz2
scala-5dc50833450033d06f845bc7473808731a155f82.zip
- Added Tree.Create
-rw-r--r--sources/meta/scalac/ast/Tree.java7
-rw-r--r--sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala10
-rw-r--r--sources/scala/tools/scalai/Compiler.java4
-rw-r--r--sources/scala/tools/scalai/ExpressionCompiler.java3
-rw-r--r--sources/scalac/ast/Transformer.java.tmpl6
-rw-r--r--sources/scalac/ast/TreeGen.java126
-rw-r--r--sources/scalac/atree/ATreeFromSTree.java17
-rw-r--r--sources/scalac/backend/jvm/GenJVM.java2
-rw-r--r--sources/scalac/checkers/TreeChecker.java23
-rw-r--r--sources/scalac/symtab/Symbol.java1
-rw-r--r--sources/scalac/transformer/AddConstructors.java22
-rw-r--r--sources/scalac/transformer/AddInterfaces.java2
-rw-r--r--sources/scalac/transformer/Erasure.java3
13 files changed, 190 insertions, 36 deletions
diff --git a/sources/meta/scalac/ast/Tree.java b/sources/meta/scalac/ast/Tree.java
index 4545d6915a..8df7d2221d 100644
--- a/sources/meta/scalac/ast/Tree.java
+++ b/sources/meta/scalac/ast/Tree.java
@@ -96,6 +96,7 @@ public class Tree {
n_Return = node("Return" , Term, HasSym),
n_Throw = node("Throw" , Term, NoSym),
n_New = node("New" , Term, NoSym),
+ n_Create = node("Create" , Term, HasSym),
n_Typed = node("Typed" , Term, NoSym),
n_TypeApply = node("TypeApply" , Term, NoSym),
n_Apply = node("Apply" , Term, NoSym),
@@ -296,6 +297,12 @@ public class Tree {
setRange(Phase.PARSER, Phase.END).
addField(t_TermTree, "init");
+ n_Create.
+ setDescription("Instance creation").
+ setRange(Phase.ANALYZER, Phase.END).
+ addField(t_TermTree, "qualifier").
+ addField(t_TypeTrees, "targs");
+
n_Typed.
setDescription("Type annotation").
setRange(Phase.PARSER, Phase.EXPLICITOUTER).
diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala
index 1aabbfd2e6..35f0d1a4be 100644
--- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala
+++ b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala
@@ -425,6 +425,16 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter {
print(init);
printType(tree);
+ case Tree$Create(qualifier, targs) =>
+ if (qualifier != Tree.Empty) {
+ print(qualifier);
+ print(TXT_DOT);
+ }
+ printSymbolUse(tree.symbol(), tree.symbol().name);
+ if (targs.length != 0) {
+ printArray(targs, TXT_LEFT_BRACKET, TXT_RIGHT_BRACKET, TXT_COMMA_SP);
+ }
+
case Tree$Typed(expr, tpe) =>
print(TXT_LEFT_PAREN);
print(expr);
diff --git a/sources/scala/tools/scalai/Compiler.java b/sources/scala/tools/scalai/Compiler.java
index a52e002dea..6a6f34e4e8 100644
--- a/sources/scala/tools/scalai/Compiler.java
+++ b/sources/scala/tools/scalai/Compiler.java
@@ -305,7 +305,7 @@ public class Compiler {
return;
default:
- throw Debug.abort("illegal case", tree);
+ throw Debug.abort("illegal case");
}
}
@@ -429,7 +429,7 @@ public class Compiler {
Symbol clasz = symbol.moduleClass();
Symbol initializer = clasz.lookup(Names.INITIALIZER);
compiler.global.prevPhase();
- Tree code =gen.New(gen.Apply(gen.Ident(symbol.pos, initializer)));
+ Tree code = gen.mkNew__(symbol.pos, Tree.Empty, initializer);
compiler.global.nextPhase();
return compiler.compile(source, symbol, code, Symbol.EMPTY_ARRAY);
}
diff --git a/sources/scala/tools/scalai/ExpressionCompiler.java b/sources/scala/tools/scalai/ExpressionCompiler.java
index 3f285af077..2ecd93a733 100644
--- a/sources/scala/tools/scalai/ExpressionCompiler.java
+++ b/sources/scala/tools/scalai/ExpressionCompiler.java
@@ -213,6 +213,9 @@ public class ExpressionCompiler {
case Select(Super(_, _), _):
return Code.Self;
+ case Select(Create(_, _), _):
+ return Code.Null;
+
case Select(Tree expr, _):
return compute(expr);
diff --git a/sources/scalac/ast/Transformer.java.tmpl b/sources/scalac/ast/Transformer.java.tmpl
index 2c8d355587..ff70a542be 100644
--- a/sources/scalac/ast/Transformer.java.tmpl
+++ b/sources/scalac/ast/Transformer.java.tmpl
@@ -239,6 +239,12 @@ public class GenTransformer {
case New(Tree init):
return gen.New(tree.pos, transform(init));
+ case Create(Tree qualifier, Tree[] args):
+ Symbol symbol = getSymbolFor(tree);
+ qualifier = transform(qualifier);
+ args = transform(args);
+ return gen.Create(tree.pos, qualifier, symbol, args);
+
case Typed(Tree expr, Tree tpe):
return gen.Typed(tree.pos, transform(expr), transform(tpe));
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index f298d4a9a8..1bbb32aebf 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -460,23 +460,76 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
//########################################################################
// Public Methods - Building new instances
+ /**
+ * Builds a new instance creation with given qualifier,
+ * initializer, type arguments and value arguments.
+ */
+ public Tree mkNewTV(int pos, Tree qual, Symbol init, Type[] targs,
+ Tree[] vargs)
+ {
+ return mkNewTV(pos, qual, init, mkTypes(pos, targs), vargs);
+ }
+ public Tree mkNewTV(Tree qual, Symbol init, Type[] targs, Tree[] vargs) {
+ return mkNewTV(qual.pos, qual, init, targs, vargs);
+ }
+ public Tree mkNewTV(int pos, Tree qual, Symbol init, Tree[] targs,
+ Tree[] vargs)
+ {
+ assert init.isInitializer(): Debug.show(init);
+ Tree instance = Create(pos, qual, init.owner(), targs);
+ return New(pos, Apply(pos, Select(pos, instance, init), vargs));
+ }
+ public Tree mkNewTV(Tree qual, Symbol init, Tree[] targs, Tree[] vargs) {
+ return mkNewTV(qual.pos, qual, init, targs, vargs);
+ }
+
+ /**
+ * Builds a new instance creation with given qualifier,
+ * initializer and type arguments and no value arguments.
+ */
+ public Tree mkNewT_(int pos, Tree qual, Symbol init, Type[] targs) {
+ return mkNewTV(pos, qual, init, targs, Tree.EMPTY_ARRAY);
+ }
+ public Tree mkNewT_(Tree qual, Symbol init, Type[] targs) {
+ return mkNewT_(qual.pos, qual, init, targs);
+ }
+ public Tree mkNewT_(int pos, Tree qual, Symbol init, Tree[] targs) {
+ return mkNewTV(pos, qual, init, targs, Tree.EMPTY_ARRAY);
+ }
+ public Tree mkNewT_(Tree qual, Symbol init, Tree[] targs) {
+ return mkNewT_(qual.pos, qual, init, targs);
+ }
+
+ /**
+ * Builds a new instance creation with given qualifier,
+ * initializer and value arguments and no type arguments.
+ */
+ public Tree mkNew_V(int pos, Tree qual, Symbol init, Tree[] vargs) {
+ return mkNewTV(pos, qual, init, Tree.EMPTY_ARRAY, vargs);
+ }
+ public Tree mkNew_V(Tree qual, Symbol init, Tree[] vargs) {
+ return mkNew_V(qual.pos, qual, init, vargs);
+ }
+
+ /**
+ * Builds a new instance creation with given qualifier, and
+ * initializer and no type arguments and no value arguments.
+ */
+ public Tree mkNew__(int pos, Tree qual, Symbol init) {
+ return mkNewTV(pos, qual, init, Tree.EMPTY_ARRAY, Tree.EMPTY_ARRAY);
+ }
+ public Tree mkNew__(Tree qual, Symbol init) {
+ return mkNew__(qual.pos, qual, init);
+ }
+
/** Builds a New node corresponding to "new <init>". */
public New New(int pos, Tree init) {
- New tree = make.New(pos, init);
- tree.setType(init.type);
- // after AddConstructor use type of symbol
+ New tree = make.New(pos, init);
+ tree.setType(init.type());
+ // after AddConstructor use type of Create node
switch (init) {
- case Apply(TypeApply(Tree fun, Tree[] targs), _):
- Symbol sym = fun.symbol();
- if (sym == null || sym.isConstructor()) break;
- Type[] args = Tree.typeOf(targs);
- tree.setType(Type.appliedType(sym.owner().nextType(), args));
- break;
- case Apply(Tree fun, _):
- Symbol sym = fun.symbol();
- if (sym == null || sym.isConstructor()) break;
- tree.setType(sym.owner().nextType());
- break;
+ case Apply(Select(Tree qual, _), _):
+ if (qual instanceof Tree.Create) tree.setType(qual.type());
}
return tree;
}
@@ -484,6 +537,51 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
return New(init.pos, init);
}
+ /**
+ * Builds a Create node with given qualifier, clasz and type
+ * arguments.
+ */
+ public Create Create(int pos, Tree qual, Symbol clasz, Type[] targs) {
+ return Create(pos, qual, clasz, mkTypes(pos, targs));
+ }
+ public Create Create(Tree qual, Symbol clasz, Type[] targs) {
+ return Create(qual.pos, qual, clasz, targs);
+ }
+ public Create Create(int pos, Tree qual, Symbol clasz, Tree[] targs) {
+ assert clasz.isClass(): Debug.show(clasz);
+ Create tree = make.Create(pos, clasz, qual, targs);
+ global.nextPhase();
+ assert targs.length == clasz.typeParams().length: tree;
+ Type prefix = qual == Tree.Empty ? Type.NoPrefix:qual.type();
+ tree.setType(Type.typeRef(prefix, clasz, Tree.typeOf(targs)));
+ global.prevPhase();
+ return tree;
+ }
+ public Create Create(Tree qual, Symbol clasz, Tree[] targs) {
+ return Create(qual.pos, qual, clasz, targs);
+ }
+
+ /**
+ * Builds a Create node with given qualifier, clasz and no type
+ * arguments.
+ */
+ public Create Create(int pos, Tree qual, Symbol clasz) {
+ return Create(pos, qual, clasz, Tree.EMPTY_ARRAY);
+ }
+ public Create Create(Tree qual, Symbol clasz) {
+ return Create(qual.pos, qual, clasz);
+ }
+
+ /** Builds a Create node with given type. */
+ public Create Create(int pos, Type type) {
+ switch (type) {
+ case TypeRef(Type prefix, Symbol clasz, Type[] targs):
+ return Create(pos, mkQualifier(pos, prefix), clasz, targs);
+ default:
+ throw Debug.abort("illegal case", type);
+ }
+ }
+
//########################################################################
// Public Methods - Building expressions - Simple nodes
diff --git a/sources/scalac/atree/ATreeFromSTree.java b/sources/scalac/atree/ATreeFromSTree.java
index c092280d70..65d5bb5357 100644
--- a/sources/scalac/atree/ATreeFromSTree.java
+++ b/sources/scalac/atree/ATreeFromSTree.java
@@ -227,8 +227,13 @@ public class ATreeFromSTree {
case Throw(Tree value):
return make.Throw(tree, expression(value));
- case New(Tree init):
- return expression(init);
+ case New(Apply(Tree fun, Tree[] vargs)):
+ switch (fun) {
+ case Select(Create(_, Tree[] targs), _):
+ return apply(tree, fun, targs, vargs);
+ default:
+ throw Debug.abort("illegal case", tree);
+ }
case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs):
return apply(tree, fun, targs, vargs);
@@ -280,14 +285,16 @@ public class ATreeFromSTree {
Symbol symbol = tree.symbol();
switch (tree) {
+ case Select(Create(_, _), _):
+ AInvokeStyle style = AInvokeStyle.New;
+ return AFunction.Method(make.Void, symbol, style);
+
case Select(Tree qualifier, _):
AInvokeStyle style = invokeStyle(qualifier);
return AFunction.Method(expression(qualifier), symbol, style);
case Ident(_):
- AInvokeStyle style = symbol.isInitializer()
- ? AInvokeStyle.New
- : AInvokeStyle.StaticClass;
+ AInvokeStyle style = AInvokeStyle.StaticClass;
return AFunction.Method(make.Void, symbol, style);
default:
diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java
index ac19bf7088..6ed92f6a1a 100644
--- a/sources/scalac/backend/jvm/GenJVM.java
+++ b/sources/scalac/backend/jvm/GenJVM.java
@@ -588,6 +588,8 @@ class GenJVM {
switch (tree) {
case Ident(_):
break;
+ case Select(Create(_, _), _):
+ break;
case Select(Tree qualifier, _):
genLoad(ctx, qualifier, JAVA_LANG_OBJECT_T);
break;
diff --git a/sources/scalac/checkers/TreeChecker.java b/sources/scalac/checkers/TreeChecker.java
index 6e15c8cbfb..37446bd7ba 100644
--- a/sources/scalac/checkers/TreeChecker.java
+++ b/sources/scalac/checkers/TreeChecker.java
@@ -264,12 +264,18 @@ public class TreeChecker {
return expression(value, definitions.THROWABLE_TYPE());
case New(Tree init):
- Tree fun = TreeInfo.methPart(init);
- assert fun instanceof Tree.Ident: show(tree);
- Symbol symbol = fun.symbol();
- assert symbol != null && !symbol.isLabel(): show(tree);
- assert symbol.isInitializer(): show(tree);
- return expression(init, definitions.UNIT_TYPE());
+ switch (init) {
+ case Apply(Select(Create(_, Tree[] targs), _), Tree[] vargs):
+ return expression(init, definitions.UNIT_TYPE());
+ default:
+ throw Debug.abort("illegal case", show(tree));
+ }
+
+ case Create(Tree qualifier, Tree[] targs):
+ assert qualifier == Tree.Empty: show(tree);
+ Symbol symbol = tree.symbol();
+ assert symbol != null && symbol.isClass(): show(tree);
+ return true;
case Apply(Tree vfun, Tree[] vargs):
vapply(tree, vfun.type(), vargs);
@@ -298,7 +304,7 @@ public class TreeChecker {
return true;
default:
- throw Debug.abort("illegal case", tree);
+ throw Debug.abort("illegal case", show(tree));
}
}
@@ -339,10 +345,11 @@ public class TreeChecker {
switch (tree) {
case Select(Tree qualifier, _):
+ if (qualifier instanceof Tree.Create)
+ assert symbol.isInitializer(): show(tree);
return selection(tree);
case Ident(_):
- if (!symbol.isLabel() && symbol.isInitializer()) return true;
if (!symbol.isLabel() && symbol.isStatic()) return true;
assert labels.contains(symbol): show(tree);
assert symbol.owner() == currentMember(): show(tree);
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index c0aeecaa8f..c65bdcdc6c 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -845,7 +845,6 @@ public abstract class Symbol implements Modifiers, Kinds {
*/
public Name simpleName() {
if (isConstructor()) return constructorClass().name.toTermName();
- if (isInitializer()) return owner().name.toTermName();
return name;
}
diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java
index d592f83be7..b8e71d0c3f 100644
--- a/sources/scalac/transformer/AddConstructors.java
+++ b/sources/scalac/transformer/AddConstructors.java
@@ -221,20 +221,21 @@ public class AddConstructors extends GenTransformer {
return gen.New(transform(init, true));
case TypeApply(Tree fun, Tree[] args):
- if (!inNew && fun.symbol().isConstructor()) return transform(fun);
- return gen.TypeApply(transform(fun, inNew), transform(args));
+ if (!fun.symbol().isConstructor()) return super.transform(tree);
+ if (!inNew) return transform(fun);
+ assert fun instanceof Tree.Ident: tree;
+ return transform(tree, fun.symbol(), transform(args));
case Apply(Tree fun, Tree[] args):
return gen.Apply(transform(fun, inNew), transform(args));
case Ident(_):
Symbol symbol = tree.symbol();
+ if (inNew) return transform(tree, symbol, Tree.EMPTY_ARRAY);
if (symbol.isConstructor()) {
symbol = getInitializer(symbol);
- if (!inNew) {
- Symbol clasz = symbol.owner();
- return gen.Select(gen.This(tree.pos, clasz), symbol);
- }
+ Symbol clasz = symbol.owner();
+ return gen.Select(gen.This(tree.pos, clasz), symbol);
} else if (symbol.owner().isConstructor()) {
symbol = subst.lookupSymbol(symbol);
}
@@ -249,4 +250,13 @@ public class AddConstructors extends GenTransformer {
} // transform()
+ /** Transforms the new instance creation. */
+ private Tree transform(Tree tree, Symbol constructor, Tree[] targs) {
+ assert constructor.isConstructor(): tree;
+ Symbol initializer = getInitializer(constructor);
+ Symbol clasz = initializer.owner();
+ Tree instance = gen.Create(tree.pos, Tree.Empty, clasz, targs);
+ return gen.Select(tree.pos, instance, initializer);
+ }
+
} // class AddConstructors
diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java
index cb94006d98..53187d5018 100644
--- a/sources/scalac/transformer/AddInterfaces.java
+++ b/sources/scalac/transformer/AddInterfaces.java
@@ -79,6 +79,8 @@ public class AddInterfaces extends GenTransformer {
/** Transforms the given symbol. */
public Symbol getSymbolFor(Tree tree) {
switch (tree) {
+ case Create(_, _):
+ return phase.getClassSymbol(tree.symbol());
case Return(_):
return member;
case This(_):
diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java
index 430c157b0e..81a1356ab4 100644
--- a/sources/scalac/transformer/Erasure.java
+++ b/sources/scalac/transformer/Erasure.java
@@ -157,6 +157,9 @@ public class Erasure extends GenTransformer implements Modifiers {
}
return gen.New(tree.pos, transform(init));
+ case Create(_, _):
+ return gen.Create(tree.pos, Tree.Empty, tree.symbol());
+
case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs):
fun = transform(fun);
vargs = transform(vargs);