From 5dc50833450033d06f845bc7473808731a155f82 Mon Sep 17 00:00:00 2001 From: paltherr Date: Tue, 6 Apr 2004 08:52:16 +0000 Subject: - Added Tree.Create --- sources/meta/scalac/ast/Tree.java | 7 ++ .../tools/scalac/ast/printer/TextTreePrinter.scala | 10 ++ sources/scala/tools/scalai/Compiler.java | 4 +- sources/scala/tools/scalai/ExpressionCompiler.java | 3 + sources/scalac/ast/Transformer.java.tmpl | 6 + sources/scalac/ast/TreeGen.java | 126 ++++++++++++++++++--- sources/scalac/atree/ATreeFromSTree.java | 17 ++- sources/scalac/backend/jvm/GenJVM.java | 2 + sources/scalac/checkers/TreeChecker.java | 23 ++-- sources/scalac/symtab/Symbol.java | 1 - sources/scalac/transformer/AddConstructors.java | 22 +++- sources/scalac/transformer/AddInterfaces.java | 2 + sources/scalac/transformer/Erasure.java | 3 + 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 ". */ 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); -- cgit v1.2.3