diff options
34 files changed, 313 insertions, 319 deletions
diff --git a/sources/meta/scalac/ast/Tree.java b/sources/meta/scalac/ast/Tree.java index 6efdfea707..eb853b7164 100644 --- a/sources/meta/scalac/ast/Tree.java +++ b/sources/meta/scalac/ast/Tree.java @@ -225,7 +225,8 @@ public class Tree { setDescription("Block of expressions " + "(semicolon separated expressions)"). setRange(Phase.PARSER, Phase.END). - addField(t_Trees, "stats"); + addField(t_Trees, "stats"). + addField(t_TermTree, "expr"); n_Sequence. setDescription("Sequence of expressions (comma separated expressions)"). diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala index fcf48c48a5..97c19417a2 100644 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ b/sources/scala/tools/scalac/ast/parser/Parser.scala @@ -9,6 +9,7 @@ import scalac.ast.parser.PatternNormalizer; import scalac.symtab.Modifiers; import scalac.ast._; +import scalac.atree.AConstant; import scalac._; import scalac.util._; import ch.epfl.lamp.util.Position; @@ -228,11 +229,11 @@ class Parser(unit: Unit) { make.Block( pos, NewArray.Tree( - make.ValDef(pos, 0, x, Tree.Empty, left), + make.ValDef(pos, 0, x, Tree.Empty, left)), make.Apply( pos, make.Select(pos, right, NameTransformer.encode(op)), - NewArray.Tree(make.Ident(left.pos, x))))); + NewArray.Tree(make.Ident(left.pos, x)))); } } else { make.Apply( @@ -339,8 +340,8 @@ class Parser(unit: Unit) { val rhs = make.If( pos, cond, - make.Block(body.pos, NewArray.Tree(body, continu)), - make.Block(pos, Tree.EMPTY_ARRAY)); + make.Block(body.pos, NewArray.Tree(body), continu), + gen.mkUnitLit(pos)); make.LabelDef(pos, lname, new Array[Tree$Ident](0), rhs); } @@ -350,12 +351,12 @@ class Parser(unit: Unit) { val rhs = make.Block( body.pos, NewArray.Tree( - body, + body), make.If( cond.pos, cond, continu, - make.Block(pos, Tree.EMPTY_ARRAY)))); + gen.mkUnitLit(pos))); make.LabelDef(pos, lname, new Array[Tree$Ident](0), rhs) } @@ -402,7 +403,7 @@ class Parser(unit: Unit) { params case Tree$Ident(_) | Tree$Typed(Tree$Ident(_), _) => NewArray.ValDef(convertToParam(t)); - case Tree$Block(stats) if (stats.length == 0) => + case Tree$Literal(AConstant.UNIT) => // !!! Tree.ValDef_EMPTY_ARRAY; case _ => syntaxError(t.pos, "malformed formal parameter list", false); @@ -887,7 +888,7 @@ class Parser(unit: Unit) { val pos = s.skipToken(); val e = if (isExprIntro()) expr() - else make.Block(pos, Tree.EMPTY_ARRAY); + else gen.mkUnitLit(pos); make.Return(pos, e) } else if (s.token == THROW) { val pos = s.skipToken(); @@ -994,7 +995,7 @@ class Parser(unit: Unit) { val pos = s.skipToken(); if (s.token == RPAREN) { s.nextToken(); - t = make.Block(pos, Tree.EMPTY_ARRAY); + t = gen.mkUnitLit(pos); } else { t = expr(); if (s.token == COMMA) { @@ -1167,9 +1168,20 @@ class Parser(unit: Unit) { /** Block ::= BlockStatSeq */ def block(pos: int): Tree = { - val stats = blockStatSeq(new myTreeList()); - if (stats.length == 1 && stats(0).isTerm()) stats(0) - else make.Block(pos, stats) + block(pos, blockStatSeq(new myTreeList())); + } + private def block(pos: int, stats: Array[Tree]): Tree = { + if (stats.length == 0) + gen.mkUnitLit(pos); + else if (!stats(stats.length - 1).isTerm()) + make.Block(pos, stats, gen.mkUnitLit(pos)); + else if (stats.length == 1) + return stats(0); + else { + val trees: Array[Tree] = new Array[Tree](stats.length - 1); + System.arraycopy(stats, 0, trees, 0, trees.length); + return make.Block(pos, trees, stats(stats.length - 1)); + } } /** caseClause : =>= case Pattern [if PostfixExpr] `=>' Block @@ -1845,7 +1857,7 @@ class Parser(unit: Unit) { if (s.token == SEMI) { s.nextToken(); blockStatSeq(statlist) } else statlist.toArray(); accept(RBRACE); - make.Block(pos, stats) + block(pos, stats) } else { selfInvocation() } @@ -2100,13 +2112,13 @@ class Parser(unit: Unit) { stats.append(defOrDcl(0)); accept(SEMI); if (s.token == RBRACE || s.token == CASE) { - stats.append(make.Block(s.pos, Tree.EMPTY_ARRAY)); + stats.append(gen.mkUnitLit(s.pos)); } } else if (isLocalModifier()) { stats.append(clsDef(localClassModifiers())); accept(SEMI); if (s.token == RBRACE || s.token == CASE) { - stats.append(make.Block(s.pos, Tree.EMPTY_ARRAY)); + stats.append(gen.mkUnitLit(s.pos)); } } else if (s.token == SEMI) { s.nextToken(); diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala index 950083dda9..cc7a89a9a7 100644 --- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala +++ b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala @@ -334,8 +334,13 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter { printArray(params.asInstanceOf[Array[Tree]], TXT_LEFT_PAREN, TXT_RIGHT_PAREN, TXT_COMMA_SP); print(rhs); - case Tree$Block(stats) => - printArray(stats, TXT_BLOCK_BEGIN, TXT_BLOCK_END, TXT_BLOCK_SEP); + case Tree$Block(stats, value) => + printArray(stats, TXT_BLOCK_BEGIN, TXT_SEMICOLON, TXT_BLOCK_SEP); + indent(); + printNewLine(); + print(value); + undent(); + print(TXT_BLOCK_END); printType(tree); case Tree$Sequence(trees) => diff --git a/sources/scala/tools/scalac/transformer/TransMatch.scala b/sources/scala/tools/scalac/transformer/TransMatch.scala index 3167bf242b..ce7f9af50e 100644 --- a/sources/scala/tools/scalac/transformer/TransMatch.scala +++ b/sources/scala/tools/scalac/transformer/TransMatch.scala @@ -86,7 +86,7 @@ class TransMatch( global:scalac_Global ) var nilvars:Set = TestRegTraverser.getNilVariables(); if( !nilvars.isEmpty() ) { //System.err.println("nilvars present"); - val newBody = new Array[Tree]( nilvars.size() + 1 ); + val newBody = new Array[Tree]( nilvars.size() ); var j=0; var it:Iterator = nilvars.iterator(); while( it.hasNext() ) { @@ -94,8 +94,7 @@ class TransMatch( global:scalac_Global ) val n = gen.mkNil(cases(i).pos); newBody.update( {j = j + 1; j} , gen.ValDef(v, n)); } - newBody.update( newBody.length - 1, cases(i).body); - cases(i).body = gen.mkBlock( newBody ); + cases(i).body = gen.mkBlock( newBody, cases(i).body ); } i = i+1; } diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index b0085163c9..561104267e 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -1419,7 +1419,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( } if ((mode & EXPRmode) != 0) { if (pt.symbol() == definitions.UNIT_CLASS) { - return gen.Block(NewArray.Tree(tree, gen.mkUnitLit(tree.pos))); + return gen.mkUnitBlock(tree); } else if (infer.isCompatible(tree.getType(), pt)) { val coerceMeth: Symbol = tree.getType().lookup(Names.coerce); if (coerceMeth != Symbol.NONE) { @@ -2037,7 +2037,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( else transform( rhs, if (name == Names.CONSTRUCTOR) CONSTRmode else EXPRmode, - tpe1.getType()); + if (name == Names.CONSTRUCTOR) definitions.UNIT_TYPE() else tpe1.getType()); popContext(); context.enclClass.owner.flags = context.enclClass.owner.flags & ~INCONSTRUCTOR; sym.flags = sym.flags | LOCKED; @@ -2086,36 +2086,29 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( context.imports = new ImportList(tree, context.scope, context.imports); Tree.Empty - case Tree$Block(stats) => + case Tree$Block(stats, value) => pushContext(tree, context.owner, new Scope(context.scope)); val stats1 = desugarize.Statements(stats, true); enterSyms(stats1); context.imports = context.outer.imports; val curmode: int = mode; + var start: Int = 0; + var valuemode: Int = curmode; + if ((curmode & CONSTRmode) != 0) { + stats1(0) = transform(stats1(0), curmode, pt); + context.enclClass.owner.flags = context.enclClass.owner.flags & ~INCONSTRUCTOR; + start = 1; + valuemode = (curmode & ~CONSTRmode) | EXPRmode; + } + var i = start; while (i < stats1.length) { + stats1(i) = transform(stats1(i), EXPRmode); + i = i + 1 + } + val value1: Tree = transform(value, valuemode & ~FUNmode, pt); val owntype: Type = - if ((curmode & CONSTRmode) != 0) { - stats1(0) = transform(stats1(0), curmode, pt); - context.enclClass.owner.flags = context.enclClass.owner.flags & ~INCONSTRUCTOR; - var i = 1; while (i < stats1.length) { - stats1(i) = transform(stats1(i), EXPRmode); - i = i + 1 - } - stats1(0).getType() - } else { - var i = 0; while (i < stats1.length - 1) { - stats1(i) = transform(stats1(i), EXPRmode); - i = i + 1 - } - if (stats1.length > 0) { - stats1(stats1.length - 1) = - transform(stats1(stats1.length - 1), curmode & ~FUNmode, pt); - checkNoEscape(tree.pos, stats1(stats1.length - 1).getType().deconst()) - } else { - definitions.UNIT_TYPE() - } - } + checkNoEscape(tree.pos, value1.getType().deconst()); popContext(); - copy.Block(tree, stats1) + copy.Block(tree, stats1, value1) .setType(owntype); case Tree$Sequence(trees) => @@ -2220,8 +2213,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( var elsep1: Tree = _; if (elsep == Tree.Empty) { thenp1 = transform(thenp, EXPRmode, definitions.UNIT_TYPE()); - elsep1 = make.Block(tree.pos, Tree.EMPTY_ARRAY) - .setType(definitions.UNIT_TYPE()); + elsep1 = gen.mkUnitLit(tree.pos); } else { thenp1 = transform(thenp, EXPRmode, pt); elsep1 = transform(elsep, EXPRmode, pt); @@ -2307,7 +2299,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( Tree.EMPTY_ARRAY)) .setType(owntype); popContext(); - make.Block(tree.pos, NewArray.Tree(cd1, alloc)) + make.Block(tree.pos, NewArray.Tree(cd1), alloc) .setType(owntype); } } diff --git a/sources/scala/tools/scalac/typechecker/Context.scala b/sources/scala/tools/scalac/typechecker/Context.scala index 81089e0b26..56e3852a18 100644 --- a/sources/scala/tools/scalac/typechecker/Context.scala +++ b/sources/scala/tools/scalac/typechecker/Context.scala @@ -51,7 +51,7 @@ class Context { } def isTopLevel(): boolean = tree match { - case Tree$Block(_) => + case Tree$Block(_,_) => false case Tree$Template(_, _) => outer.tree.isInstanceOf[Tree$PackageDef] diff --git a/sources/scala/tools/scalac/typechecker/DeSugarize.scala b/sources/scala/tools/scalac/typechecker/DeSugarize.scala index 37ba3cef27..a74a2ba790 100644 --- a/sources/scala/tools/scalac/typechecker/DeSugarize.scala +++ b/sources/scala/tools/scalac/typechecker/DeSugarize.scala @@ -99,7 +99,7 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala def mkTuple(pos: int, trees: Array[Tree]): Tree = if (trees.length == 0) - make.Block(pos, trees); + gen.mkUnitLit(pos); else make.Apply( pos, @@ -353,7 +353,7 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala pos, mods, vars(i), Tree.Empty, make.Select(pos, make.Ident(pos, vble), tupleSelectorName(i + 1))); } - print(pat, "patdef", new Tree$Block(res));//debug + print(pat, "patdef", new Tree$Block(res, gen.mkUnitLit(pos)));//debug shareComment(res, tree); } } @@ -416,8 +416,7 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala val defs: TreeList = new TreeList(); val lambda: Tree = toFunction(toApply(liftoutPrefix(tree, defs), tpe), tpe); - defs.append(lambda); - val result: Tree = make.Block(tree.pos, defs.toArray()); + val result: Tree = make.Block(tree.pos, defs.toArray(), lambda); print(tree, "eta", result);//debug result } diff --git a/sources/scala/tools/scalai/ExpressionCompiler.java b/sources/scala/tools/scalai/ExpressionCompiler.java index bb4e3ad9cb..3f88b6d128 100644 --- a/sources/scala/tools/scalai/ExpressionCompiler.java +++ b/sources/scala/tools/scalai/ExpressionCompiler.java @@ -116,16 +116,14 @@ public class ExpressionCompiler { context.insertLabel(symbol); return Code.Label(symbol, vars, compute(body)); - case Block(Tree[] stats): - if (stats.length == 0) return Code.Literal(constants.literal()); - // !!! assert stats.length > 0; + case Block(Tree[] stats, Tree value): + if (stats.length == 0) return compute(value); CodeBuffer buffer = new CodeBuffer(); int stacksize = context.stacksize(); - for (int i = 0; i < stats.length - 1; i++) - declare(stats[i], buffer); - Code value = compute(stats[stats.length - 1]); + for (int i = 0; i < stats.length; i++) declare(stats[i], buffer); + Code result = compute(value); context.stacksize(stacksize); - return buffer.code(value); + return buffer.code(result); case Assign(Tree lhs, Tree rhs): return store(lhs, lhs.symbol(), compute(rhs)); diff --git a/sources/scalac/ast/Transformer.java.tmpl b/sources/scalac/ast/Transformer.java.tmpl index 69aef7dfca..1af073fc86 100644 --- a/sources/scalac/ast/Transformer.java.tmpl +++ b/sources/scalac/ast/Transformer.java.tmpl @@ -206,8 +206,8 @@ public class GenTransformer { Symbol symbol = getSymbolFor(tree); return gen.LabelDef(symbol, transform(params), transform(rhs)); - case Block(Tree[] stats): - return gen.Block(tree.pos, transform(stats)); + case Block(Tree[] stats, Tree value): + return gen.Block(tree.pos, transform(stats), transform(value)); // case Sequence(Tree[] trees): // case Alternative(Tree[] trees): diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 1ebcaf7c53..27b168abd8 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -468,7 +468,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { // Public Methods - Building expressions - Simple nodes /** Flattens the given tree array by inlining Block nodes. */ - public Tree[] flatten(Tree[] trees) { + public Tree[] flatten_(Tree[] trees) { boolean copy = false; int length = 0; for (int i = 0; i < trees.length; i++) { @@ -477,10 +477,9 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { copy = true; length -= 1; continue; - case Block(Tree[] stats): - if (stats.length == 0) break; // preserve unit literals + case Block(Tree[] stats, Tree value): copy = true; - length += stats.length; + length += stats.length + 1; continue; } length += 1; @@ -491,9 +490,9 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { switch (trees[i]) { case Empty: continue; - case Block(Tree[] stats): - if (stats.length == 0) break; // preserve unit literals + case Block(Tree[] stats, Tree value): for (int j = 0; j < stats.length; j++) clone[o++] = stats[j]; + clone[o++] = value; continue; } clone[o++] = trees[i]; @@ -530,16 +529,43 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { return mkAsInstanceOf(value.pos, value, type); } - /** Builds an expression with given non-empty tree array. */ - public Tree mkBlock(int pos, Tree[] trees) { - assert trees.length != 0; - Tree[] flatten = flatten(trees); - assert flatten.length != 0: Debug.show(trees); - return Block(pos, flatten); + /** Builds an expression of type Unit with given statements. */ + public Tree mkUnitBlock(int pos, Tree[] stats) { + return mkBlock(pos, stats, mkUnitLit(pos)); } - public Tree mkBlock(Tree[] trees) { - assert trees.length != 0; - return mkBlock(trees[0].pos, trees); + + /** Builds an expression of type Unit with given statement. */ + public Tree mkUnitBlock(int pos, Tree stat) { + return mkUnitBlock(pos, new Tree[]{stat}); + } + public Tree mkUnitBlock(Tree stat) { + return mkUnitBlock(stat.pos, stat); + } + + /** Builds an expression with given statements and value. */ + public Tree mkBlock(int pos, Tree[] stats, Tree value) { + if (stats.length == 0) return value; + return Block(pos, stats, value); // !!! add flatten? + } + public Tree mkBlock(Tree[] stats, Tree value) { + return mkBlock((stats.length!=0 ? stats[0] : value).pos, stats, value); + } + + /** Builds an expression with given statement and value. */ + public Tree mkBlock(int pos, Tree stat, Tree value) { + switch (stat) { + case Empty: + return value; + case Block(Tree[] block_stats, Tree block_value): + Tree[] stats = Tree.cloneArray(block_stats, 1); + stats[block_stats.length] = block_value; + return Block(stat.pos, stats, value); + default: + return Block(pos, new Tree[]{stat}, value); + } + } + public Tree mkBlock(Tree stat, Tree value) { + return mkBlock(stat.pos, stat, value); } /** Builds an Import node with given qualifier and names. */ @@ -562,20 +588,29 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { return tree; } - /** Builds a Block node with given statements. */ - public Tree Block(int pos, Tree[] stats) { - Block tree = make.Block(pos, stats); - global.nextPhase(); - tree.setType(stats.length == 0 - ? definitions.UNIT_TYPE() - : stats[stats.length - 1].type); - global.prevPhase(); + /** Builds a Block node with given statements and value. */ + public Block Block(int pos, Tree[] stats, Tree value) { + inline: + switch (value) { + case Block(Tree[] value_stats, Tree value_value): + int count = 0; + for (int i = 0; i < value_stats.length; i++) { + if (value_stats[i].definesSymbol()) break inline; + if (value_stats[i] != Tree.Empty) count++; + } + Tree[] array = Tree.cloneArray(stats, count); + for (int i = 0, j = stats.length; i < value_stats.length; i++) { + if (value_stats[i] != Tree.Empty) array[j++] = value_stats[i]; + } + stats = array; + value = value_value; + } + Block tree = make.Block(pos, stats, value); + tree.setType(value.type()); return tree; } - - /** Builds a Block node with given non-empty statements list. */ - public Tree Block(Tree[] stats) { - return Block(stats[0].pos, stats); + public Block Block(Tree[] stats, Tree value) { + return Block((stats.length != 0 ? stats[0] : value).pos, stats, value); } /** Builds an Assign node corresponding to "<lhs> = <rhs>". */ @@ -762,14 +797,13 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { */ public Tree mkNewArray(int pos, Type element, Tree[] values, Symbol owner){ if (values.length == 0) return mkNewArray(pos, element, 0); - Tree[] trees = new Tree[1 + values.length + 1]; + Tree[] trees = new Tree[1 + values.length]; Symbol array = newLocal(pos, Names.array, owner, definitions.ARRAY_TYPE(element)); trees[0] = ValDef(array, mkNewArray(pos, element, values.length)); for (int i = 0; i < values.length; i++) trees[1 + i] = mkArraySet(Ident(pos, array), i, values[i]); - trees[values.length + 1] = Ident(pos, array); - return Block(pos, trees); + return Block(pos, trees, Ident(pos, array)); } /** Builds an array length operation. */ @@ -1101,7 +1135,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { Tree classDef = ClassDef(clazz, memberTrees); Tree alloc = New(mkApply__(mkPrimaryConstructorLocalRef(pos, clazz))) .setType(parentTypes[1]); // !!! - return Block(new Tree[]{classDef, alloc}); + return mkBlock(classDef, alloc); } @@ -1123,7 +1157,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { Tree classDef = ClassDef(clazz, memberTrees); Tree alloc = New(mkApply__(mkPrimaryConstructorLocalRef(pos, clazz))) .setType(parentTypes[1]); // !!! - return Block(new Tree[]{classDef, alloc}); + return mkBlock(classDef, alloc); } //where private Tree makeVisitorMethod(int pos, Name name, Tree visitor, @@ -1172,7 +1206,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags { .setInfo(obj.type); Tree tmpdef = ValDef(tmp, obj); Tree expr = postfixApply(Ident(obj.pos, tmp), fn, owner); - return Block(new Tree[]{tmpdef, expr}); + return mkBlock(tmpdef, expr); } } diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index 12226aa922..6cbf3e342a 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -15,6 +15,7 @@ import scalac.*; import scalac.util.*; import scalac.symtab.Modifiers; import scalac.ast.*; +import scalac.atree.AConstant; import Tree.*; /** A recursive descent parser for the programming language Scala. @@ -243,10 +244,10 @@ public class Parser implements Tokens { Name x = fresh(); return make.Block(pos, new Tree[]{ - make.ValDef(pos, 0, x, Tree.Empty, left), + make.ValDef(pos, 0, x, Tree.Empty, left)}, make.Apply(pos, make.Select(pos, right, NameTransformer.encode(op)), - new Tree[]{make.Ident(left.pos, x)})}); + new Tree[]{make.Ident(left.pos, x)})); } } else { return make.Apply(pos, @@ -370,8 +371,8 @@ public class Parser implements Tokens { Tree rhs = make.If( pos, cond, - make.Block(body.pos, new Tree[]{body, continu}), - make.Block(pos, Tree.EMPTY_ARRAY)); + make.Block(body.pos, new Tree[]{body}, continu), + gen.mkUnitLit(pos)); return make.LabelDef(pos, lname, new Ident[0], rhs); } @@ -381,12 +382,12 @@ public class Parser implements Tokens { Tree rhs = make.Block( body.pos, new Tree[]{ - body, + body}, make.If( cond.pos, cond, continu, - make.Block(pos, Tree.EMPTY_ARRAY))}); + gen.mkUnitLit(pos))); return make.LabelDef(pos, lname, new Ident[0], rhs); } @@ -399,8 +400,8 @@ public class Parser implements Tokens { case Ident(_): case Typed(Ident(_), _): return new ValDef[]{convertToParam(t)}; - case Block(Tree[] stats): - if (stats.length == 0) return Tree.ValDef_EMPTY_ARRAY; + case Literal(AConstant.UNIT): + return Tree.ValDef_EMPTY_ARRAY; // !!! } syntaxError(t.pos, "malformed formal parameter list", false); return Tree.ValDef_EMPTY_ARRAY; @@ -912,7 +913,7 @@ public class Parser implements Tokens { } else if (s.token == RETURN) { int pos = s.skipToken(); Tree e = (isExprIntro()) ? expr() - : make.Block(pos, Tree.EMPTY_ARRAY); + : gen.mkUnitLit(pos); return make.Return(pos, e); } else if (s.token == THROW) { int pos = s.skipToken(); @@ -1031,7 +1032,7 @@ public class Parser implements Tokens { int pos = s.skipToken(); if (s.token == RPAREN) { s.nextToken(); - t = make.Block(pos, Tree.EMPTY_ARRAY); + t = gen.mkUnitLit(pos); } else { t = expr(); if (s.token == COMMA) { @@ -1126,9 +1127,20 @@ public class Parser implements Tokens { /** Block ::= BlockStatSeq */ Tree block(int pos) { - Tree[] stats = blockStatSeq(new TreeList()); - if (stats.length == 1 && stats[0].isTerm()) return stats[0]; - else return make.Block(pos, stats); + return block(pos, blockStatSeq(new TreeList())); + } + private Tree block(int pos, Tree[] stats) { + if (stats.length == 0) + return gen.mkUnitLit(pos); + else if (!stats[stats.length - 1].isTerm()) + return make.Block(pos, stats, gen.mkUnitLit(pos)); + else if (stats.length == 1) + return stats[0]; + else { + Tree[] trees = new Tree[stats.length - 1]; + System.arraycopy(stats, 0, trees, 0, trees.length); + return make.Block(pos, trees, stats[stats.length - 1]); + } } /** CaseClause ::= case Pattern [if PostfixExpr] `=>' Block @@ -1832,7 +1844,7 @@ public class Parser implements Tokens { stats = statlist.toArray(); } accept(RBRACE); - return make.Block(pos, stats); + return block(pos, stats); } else { return selfInvocation(); } @@ -2070,13 +2082,13 @@ public class Parser implements Tokens { stats.append(defOrDcl(0)); accept(SEMI); if (s.token == RBRACE || s.token == CASE) { - stats.append(make.Block(s.pos, Tree.EMPTY_ARRAY)); + stats.append(gen.mkUnitLit(s.pos)); } } else if (isLocalModifier()) { stats.append(clsDef(localClassModifiers())); accept(SEMI); if (s.token == RBRACE || s.token == CASE) { - stats.append(make.Block(s.pos, Tree.EMPTY_ARRAY)); + stats.append(gen.mkUnitLit(s.pos)); } } else if (s.token == SEMI) { s.nextToken(); diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java index 9cefa783d8..6a8be8f696 100644 --- a/sources/scalac/ast/printer/TextTreePrinter.java +++ b/sources/scalac/ast/printer/TextTreePrinter.java @@ -391,8 +391,13 @@ public class TextTreePrinter implements TreePrinter { print(rhs); break; - case Block(Tree[] stats): - printArray(stats, TXT_BLOCK_BEGIN, TXT_BLOCK_END, TXT_BLOCK_SEP); + case Block(Tree[] stats, Tree value): + printArray(stats, TXT_BLOCK_BEGIN, TXT_SEMICOLON, TXT_BLOCK_SEP); + indent(); + printNewLine(); + print(value); + undent(); + print(TXT_BLOCK_END); printType(tree); break; diff --git a/sources/scalac/atree/ATreeFromSTree.java b/sources/scalac/atree/ATreeFromSTree.java index cf62f951fa..e5eccc8fe8 100644 --- a/sources/scalac/atree/ATreeFromSTree.java +++ b/sources/scalac/atree/ATreeFromSTree.java @@ -149,9 +149,9 @@ public class ATreeFromSTree { // Private Methods - Translating statements /** Translates the statements. */ - private ACode[] statement(List locals, Tree[] trees, int start, int count){ + private ACode[] statement(List locals, Tree[] trees) { List codes = new ArrayList(); - for (int i = start; i < start + count; i++) { + for (int i = 0; i < trees.length; i++) { ACode code = statement(locals, trees[i]); if (code != ACode.Void) codes.add(code); } @@ -194,16 +194,14 @@ public class ATreeFromSTree { Symbol[] locals = Tree.symbolOf(idents); return make.Label(tree, tree.symbol(), locals, expression(rhs)); - case Block(Tree[] statements): - if (statements.length == 0) return make.Void; - int statement_count = statements.length - 1; + case Block(Tree[] stats, Tree value): List locals = new ArrayList(); - ACode[] codes = statement(locals,statements,0, statement_count); - ACode value = expression(statements[statement_count]); - if (locals.size() == 0 && codes.length == 0) return value; + ACode[] codes = statement(locals, stats); + ACode code = expression(value); + if (locals.size() == 0 && codes.length == 0) return code; Symbol[] symbols = (Symbol[])locals.toArray(new Symbol[locals.size()]); - return make.Block(tree, symbols, codes, value); + return make.Block(tree, symbols, codes, code); case Assign(Tree lhs, Tree rhs): return make.Block(tree, Symbol.EMPTY_ARRAY, new ACode[] { diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java index a4a134654e..d808131b36 100644 --- a/sources/scalac/backend/jvm/GenJVM.java +++ b/sources/scalac/backend/jvm/GenJVM.java @@ -234,14 +234,11 @@ class GenJVM { ctx.labels.remove(sym); } break; - case Block(Tree[] stats): { + case Block(Tree[] stats, Tree value): { int statsNum = stats.length; - for (int i = 0; i < statsNum - 1; ++i) + for (int i = 0; i < stats.length; ++i) gen(ctx, stats[i]); - if (statsNum == 0) - maybeGenLoadUnit(ctx, expectedType); - else - genLoad(ctx, stats[stats.length - 1], expectedType); + genLoad(ctx, value, expectedType); generatedType = expectedType; } break; @@ -1276,12 +1273,6 @@ class GenJVM { return args[0]; } else return tree; - case Block(Tree[] stats): - if (stats.length == 2 - && prims.getPrimitive(stats[1].symbol()) == Primitive.BOX) { - return stats[0]; - } else - return tree; default: return tree; } diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java index c12cfea8ea..417c4e2592 100644 --- a/sources/scalac/backend/msil/GenMSIL.java +++ b/sources/scalac/backend/msil/GenMSIL.java @@ -326,7 +326,7 @@ public final class GenMSIL { // emit the call to the superconstructor switch (rhs) { - case Block(Tree[] stats): + case Block(Tree[] stats, _): // this is the call to the super constructor drop(gen(stats[0], MSILType.VOID)); break; @@ -346,11 +346,12 @@ public final class GenMSIL { code.Emit(OpCodes.Newobj, ctor); code.Emit(OpCodes.Stsfld, moduleField); switch (rhs) { - case Block(Tree[] stats): + case Block(Tree[] stats, Tree value): int n = stats.length; assert n > 0; for (int i = 1; i < n; i++) drop(gen(stats[i], MSILType.VOID)); + drop(gen(value, MSILType.VOID)); break; } code.Emit(OpCodes.Ret); @@ -396,21 +397,6 @@ public final class GenMSIL { } - /** Generate code for array of trees - */ - Item gen(Tree[] trees) { - int n = trees.length; - if (n == 0) - return items.VoidItem(); - boolean tmpLastStatement = lastStatement; lastStatement = false; - for (int i = 0; i < n-1; i++) { - drop(gen(trees[i], MSILType.VOID)); - } - lastStatement = tmpLastStatement; - return gen(trees[n-1], type2MSILType(trees[n-1].type)); - } - - Item gen(Tree tree) { return gen(tree, type2MSILType(tree.type)); } @@ -452,8 +438,13 @@ public final class GenMSIL { case Empty: return items.VoidItem(); - case Block(Tree[] stats): - return gen(stats); + case Block(Tree[] stats, Tree value): + boolean tmpLastStatement = lastStatement; lastStatement = false; + for (int i = 0; i < stats.length; i++) { + drop(gen(stats[i], MSILType.VOID)); + } + lastStatement = tmpLastStatement; + return gen(value, type2MSILType(value.type)); case ValDef(_, Name name, Tree tpe, Tree rhs): LocalBuilder local = code.DeclareLocal(tc.getType(sym)); diff --git a/sources/scalac/checkers/TreeChecker.java b/sources/scalac/checkers/TreeChecker.java index c6d2af5052..9351110558 100644 --- a/sources/scalac/checkers/TreeChecker.java +++ b/sources/scalac/checkers/TreeChecker.java @@ -227,12 +227,11 @@ public class TreeChecker { scopeRemoveLabel(symbol); return true; - case Block(Tree[] statements): + case Block(Tree[] statements, Tree value): Set locals = new HashSet(); - for (int i = 0; i < statements.length - 1; i++) + for (int i = 0; i < statements.length; i++) statement(locals, statements[i]); - if (statements.length > 0) - expression(statements[statements.length - 1], expected); + expression(value, expected); for (Iterator i = locals.iterator(); i.hasNext(); ) scopeRemoveVVariable((Symbol)i.next()); return true; diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index f0041be728..430718607e 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -3166,10 +3166,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { * the "void" type. */ public Type fullErasure() { - if (Global.instance.definitions.UNIT_CLASS == symbol()) - return unbox(); - else - return erasure(); + Type erasure = erasure(); + if (Global.instance.definitions.UNIT_CLASS == erasure.symbol()) + erasure = erasure.unbox(); + return erasure; } // Object Interface ----------------------------------------------------------------- diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java index 5ef1e1c406..d08581aa7c 100644 --- a/sources/scalac/transformer/AddConstructors.java +++ b/sources/scalac/transformer/AddConstructors.java @@ -179,10 +179,9 @@ public class AddConstructors extends GenTransformer { // add valdefs and class-level expression to the constructorr body constrBody.addAll(constrBody2); - Tree constrTree = constrBody.size() > 1 ? - gen.Block((Tree[])constrBody. - toArray(new Tree[constrBody.size()])): - (Tree) constrBody.get(0); + Tree constrTree = gen.mkUnitBlock( + clasz.primaryConstructor().pos, + (Tree[])constrBody.toArray(new Tree[constrBody.size()])); classBody.add(gen.DefDef(clasz.primaryConstructor(),constrTree)); @@ -210,7 +209,7 @@ public class AddConstructors extends GenTransformer { subst.removeSymbol(constructor.valueParams()); subst.removeSymbol(constructor.typeParams()); // add consistent result expression - rhs = gen.mkBlock(new Tree[] { rhs, gen.mkUnitLit(rhs.pos) }); + rhs = gen.mkUnitBlock(rhs); return gen.DefDef(initializer, rhs); case ValDef(_, _, _, _): diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java index e6a5fdd795..5da45dd2c5 100644 --- a/sources/scalac/transformer/Erasure.java +++ b/sources/scalac/transformer/Erasure.java @@ -220,7 +220,7 @@ public class Erasure extends GenTransformer implements Modifiers { case Literal(AConstant.ZERO): return gen.mkNullLit(tree.pos); - case Block(_): + case Block(_, _): case If(_, _, _): case Switch(_, _, _, _): return transform(tree, tree.getType().fullErasure()); @@ -251,13 +251,8 @@ public class Erasure extends GenTransformer implements Modifiers { private Tree transform(Tree tree, Type pt) { switch (tree) { - case Block(Tree[] stats): - if (stats.length == 0) return transformUnit(tree.pos, pt); - stats = Tree.cloneArray(stats); - for (int i = 0; i < stats.length - 1; i++) - stats[i] = transform(stats[i]); - stats[stats.length - 1] = transform(stats[stats.length - 1], pt); - return gen.Block(tree.pos, stats); + case Block(Tree[] stats, Tree value): + return gen.Block(tree.pos, transform(stats), transform(value, pt)); case If(Tree cond, Tree thenp, Tree elsep): cond = transform(cond, UNBOXED_BOOLEAN); @@ -272,8 +267,9 @@ public class Erasure extends GenTransformer implements Modifiers { return gen.Switch(tree.pos, test, tags, bodies, otherwise, pt); case Return(_): + // !!! why do we build a block here? Tree value = transform(gen.mkDefaultValue(tree.pos, pt), pt); - return gen.mkBlock(new Tree[] {transform(tree), value}); + return gen.mkBlock(transform(tree), value); case LabelDef(_, _, _): case Assign(_, _): @@ -354,7 +350,7 @@ public class Erasure extends GenTransformer implements Modifiers { Symbol symbol = primitives.getBoxValueSymbol(tree.getType()); Tree boxtree = gen.mkGlobalRef(tree.pos, symbol); return tree.getType().equals(UNBOXED_UNIT) - ? gen.Block(new Tree[]{tree, gen.mkApply__(boxtree)}) + ? gen.mkBlock(tree, gen.mkApply__(boxtree)) : gen.mkApply_V(boxtree, new Tree[]{tree}); } diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java index 7129d5bdab..b580812ecb 100644 --- a/sources/scalac/transformer/LambdaLift.java +++ b/sources/scalac/transformer/LambdaLift.java @@ -350,10 +350,10 @@ public class LambdaLift extends OwnerTransformer tree.type = descr.transform(tree.type, currentOwner); //System.out.println(tree.type);//DEBUG switch (tree) { - case Block(Tree[] stats): + case Block(Tree[] stats, Tree value): for (int i = 0; i < stats.length; i++) liftSymbol(stats[i]); - return copy.Block(tree, transform(stats)); + return copy.Block(tree, transform(stats), transform(value)); case ClassDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): Symbol sym = tree.symbol(); @@ -461,9 +461,7 @@ public class LambdaLift extends OwnerTransformer // fn2 may be like "{ println("hello"); Predef}.Array" switch (fn2) { case Select(Tree qualifier, _): - return gen.Block( - args[0].pos, - new Tree[] {qualifier, array}); + return gen.mkBlock(args[0].pos, qualifier, array); default: throw Debug.abort("illegal case", fn2); } diff --git a/sources/scalac/transformer/TailCallPhase.java b/sources/scalac/transformer/TailCallPhase.java index 60574ad00c..a170671880 100644 --- a/sources/scalac/transformer/TailCallPhase.java +++ b/sources/scalac/transformer/TailCallPhase.java @@ -109,13 +109,8 @@ public class TailCallPhase extends Phase { method = null; return tree; - case Block(Tree[] stats): - if (stats.length == 0) return tree; - Tree expr = transform(stats[stats.length - 1]); - if (expr == stats[stats.length - 1]) return tree; - stats = Tree.cloneArray(stats); - stats[stats.length - 1] = expr; - return gen.Block(tree.pos, stats); + case Block(Tree[] stats, Tree value): + return gen.Block(tree.pos, stats, transform(value)); case If(Tree cond, Tree thenp, Tree elsep): Type type = tree.type(); diff --git a/sources/scalac/transformer/TransMatch.java b/sources/scalac/transformer/TransMatch.java index 19d1fc0eb8..e64191f385 100644 --- a/sources/scalac/transformer/TransMatch.java +++ b/sources/scalac/transformer/TransMatch.java @@ -94,14 +94,13 @@ public class TransMatch extends OwnerTransformer { Set nilvars = TestRegTraverser.getNilVariables(); if(!nilvars.isEmpty()) { //System.err.println("nilvars present"); - Tree[] newBody = new Tree[ nilvars.size() + 1 ]; + Tree[] newBody = new Tree[ nilvars.size() ]; int j=0; for( Iterator it = nilvars.iterator(); it.hasNext(); ) { Symbol v = (Symbol) it.next(); newBody[ j++ ] = gen.ValDef(v, gen.mkNil(cases[i].pos)); } - newBody[ newBody.length - 1 ] = cases[i].body; - cases[i].body = gen.mkBlock( newBody ); + cases[i].body = gen.mkBlock( newBody, cases[i].body ); } i++; } diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java index 6b96072bae..fc70741cd4 100644 --- a/sources/scalac/transformer/matching/AlgebraicMatcher.java +++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java @@ -79,13 +79,13 @@ public class AlgebraicMatcher extends PatternMatcher { //////////// generator methods public Tree toTree() { - TreeList ts = new TreeList(); - ts.append( gen.ValDef(root.symbol(), _m.selector )); - ts.append( gen.ValDef(resultVar, - gen.mkDefaultValue(_m.pos, resultVar.info()) )); - ts.append( gen.If( toTree(root.and), + Tree[] ts = { + gen.ValDef(root.symbol(), _m.selector ), + gen.ValDef(resultVar, + gen.mkDefaultValue(_m.pos, resultVar.info()) )}; + Tree res = gen.If( toTree(root.and), gen.Ident( _m.pos, resultVar ), - cf.ThrowMatchError( _m.pos, _m.resultType ))); + cf.ThrowMatchError( _m.pos, _m.resultType )); /* gen.If( _m.pos, @@ -93,7 +93,7 @@ public class AlgebraicMatcher extends PatternMatcher { gen.Ident( _m.pos, resultVar ), cf.ThrowMatchError( _m.resultType )); */ - return gen.mkBlock(_m.pos, ts.toArray()); + return gen.mkBlock(_m.pos, ts, res); } protected Tree toTree(PatternNode node, Tree selector) { diff --git a/sources/scalac/transformer/matching/Autom2Scala.java b/sources/scalac/transformer/matching/Autom2Scala.java index 6f99a699cf..102353c8d4 100644 --- a/sources/scalac/transformer/matching/Autom2Scala.java +++ b/sources/scalac/transformer/matching/Autom2Scala.java @@ -92,9 +92,9 @@ public class Autom2Scala { cf.gen.ValDef( this.curSym, gen.If( gen.Ident( pos, hasnSym ), cf._next( _iter() ), - gen.mkDefaultValue(cf.pos,curSym.type()))), + gen.mkDefaultValue(cf.pos,curSym.type())))}, - body }); + body ); } /** bug ?? */ @@ -189,10 +189,10 @@ public class Autom2Scala { /** some error happened which is due to bug in translation/automaton */ final Tree code_error() { - return gen.Block( new Tree[] { + return gen.mkBlock( gen.Console_print( pos, "System error during pattern matching. Please file bug report\n"), cf.ThrowMatchError( pos, funRetType() ) - }); + ); } Tree code_fail() { diff --git a/sources/scalac/transformer/matching/LeftTracerInScala.java b/sources/scalac/transformer/matching/LeftTracerInScala.java index 4c02ce28dc..875b1dd89b 100644 --- a/sources/scalac/transformer/matching/LeftTracerInScala.java +++ b/sources/scalac/transformer/matching/LeftTracerInScala.java @@ -208,7 +208,8 @@ public class LeftTracerInScala extends TracerInScala { new Ident[] { gen.Ident( pos, stateSym ), gen.Ident( pos, accumSym ) - }, code_body() /* code_body_new ? */ ))}); + }, code_body() /* code_body_new ? */ ))}, + gen.Ident( cf.pos, resultSym )); } // calling the AlgebraicMatcher here diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index b2c45278ef..eeebe6321d 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -766,16 +766,15 @@ public class PatternMatcher extends PatternTool { } public Tree generalSwitchToTree() { - TreeList ts = new TreeList(); - ts.append(gen.ValDef(root.symbol(), selector)); - ts.append(gen.ValDef(resultVar, gen.mkDefaultValue(selector.pos, resultVar.getType()))); - ts.append( - gen.If( - selector.pos, - toTree(root.and), - gen.Ident(selector.pos, resultVar), - cf.ThrowMatchError(selector.pos, resultVar.getType()))); - return gen.mkBlock(selector.pos, ts.toArray()); + Tree[] ts = { + gen.ValDef(root.symbol(), selector), + gen.ValDef(resultVar, gen.mkDefaultValue(selector.pos, resultVar.getType()))}; + Tree res = gen.If( + selector.pos, + toTree(root.and), + gen.Ident(selector.pos, resultVar), + cf.ThrowMatchError(selector.pos, resultVar.getType())); + return gen.mkBlock(selector.pos, ts, res); } protected Tree toTree(PatternNode node) { @@ -799,18 +798,15 @@ public class PatternMatcher extends PatternTool { } else if (!doBinding) bound = new ValDef[][]{new ValDef[]{}}; for (int i = guard.length - 1; i >= 0; i--) { - Tree[] ts = new Tree[bound[i].length + 1]; - System.arraycopy(bound[i], 0, ts, 0, bound[i].length); - ts[bound[i].length] = gen.mkBlock( - new Tree[]{ - gen.Assign( - gen.Ident(body[i].pos, resultVar), - body[i]), - gen.mkBooleanLit(body[i].pos, true) - }); + Tree[] ts = bound[i]; + Tree res0 = gen.mkBlock( + gen.Assign( + gen.Ident(body[i].pos, resultVar), + body[i]), + gen.mkBooleanLit(body[i].pos, true)); if (guard[i] != Tree.Empty) - ts[bound[i].length] = cf.And(guard[i], ts[bound[i].length]); - res = cf.Or(gen.mkBlock(body[i].pos, ts), res); + res0 = cf.And(guard[i], res0); + res = cf.Or(gen.mkBlock(body[i].pos, ts, res0), res); } return res; default: @@ -922,10 +918,9 @@ public class PatternMatcher extends PatternTool { return gen.If( gen.mkIsInstanceOf(selector.duplicate(), node.type), gen.mkBlock( - new Tree[]{ - gen.ValDef(casted, - gen.mkAsInstanceOf(selector.duplicate(), node.type)), - toTree(node.and)}), + gen.ValDef(casted, + gen.mkAsInstanceOf(selector.duplicate(), node.type)), + toTree(node.and)), toTree(node.or, selector.duplicate())); case SequencePat(Symbol casted, int len): return gen.If( @@ -939,10 +934,9 @@ public class PatternMatcher extends PatternTool { defs.SEQ_LENGTH())), gen.mkIntLit(selector.pos, len))), gen.mkBlock( - new Tree[]{ - gen.ValDef(casted, - gen.mkAsInstanceOf(selector.duplicate(), node.type)), - toTree(node.and)}), + gen.ValDef(casted, + gen.mkAsInstanceOf(selector.duplicate(), node.type)), + toTree(node.and)), toTree(node.or, selector.duplicate())); case ConstantPat(AConstant value): return gen.If( diff --git a/sources/scalac/transformer/matching/RightTracerInScala.java b/sources/scalac/transformer/matching/RightTracerInScala.java index e7ef7ae029..e6fc1378ae 100644 --- a/sources/scalac/transformer/matching/RightTracerInScala.java +++ b/sources/scalac/transformer/matching/RightTracerInScala.java @@ -32,7 +32,7 @@ public class RightTracerInScala extends TracerInScala { HashMap helpMap; HashMap helpMap2 ; - Vector helpVarDefs; + TreeList helpVarDefs; /** translate right tracer to code @@ -60,7 +60,7 @@ public class RightTracerInScala extends TracerInScala { this.helpMap = new HashMap(); helpMap2 = new HashMap(); - helpVarDefs = new Vector(); + helpVarDefs = new TreeList(); for( Iterator it = seqVars.iterator(); it.hasNext(); ) { makeHelpVar( (Symbol) it.next() ); @@ -110,7 +110,7 @@ public class RightTracerInScala extends TracerInScala { helpVar.flags |= Modifiers.MUTABLE; Tree varDef = gen.ValDef( helpVar, rhs ); //((ValDef) varDef).kind = Kinds.VAR; - helpVarDefs.add( varDef ); + helpVarDefs.append( varDef ); } @@ -174,16 +174,16 @@ public class RightTracerInScala extends TracerInScala { // load current elem and trace Tree loadCurrentElem( Tree body ) { - return gen.mkBlock( new Tree[] { + return gen.If( cf.isEmpty( _iter() ), run_finished( 0 ), // we are done gen.mkBlock( new Tree[] { gen.ValDef( this.targetSym, cf.SeqTrace_headState( gen.Ident( pos, iterSym))), gen.ValDef( this.curSym, - cf.SeqTrace_headElem( gen.Ident( pos, iterSym ))), - body }) - )}); + cf.SeqTrace_headElem( gen.Ident( pos, iterSym )))}, + body ) + ); } /** see code_state0_NEW @@ -354,7 +354,7 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); // case _ => false - Tree res[] = new Tree[ helpMap3.keySet().size() + 1 ]; + Tree ts[] = new Tree[ helpMap3.keySet().size() ]; int j = 0; for( Iterator it = helpMap3.keySet().iterator(); it.hasNext(); ) { Symbol vsym = (Symbol) it.next(); @@ -362,12 +362,12 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); //hv.setType( defs.LIST_TYPE( elementType ) ) ; DEBUG ALARM ? Tree refv = gen.Ident(cf.pos, vsym); Tree refhv = gen.Ident(cf.pos, hv); - res[ j++ ] = gen.Assign( refhv, refv ); + ts[ j++ ] = gen.Assign( refhv, refv ); // System.out.println( "the assign" + res[ j - 1 ] ); } - res[ j ] = gen.mkBooleanLit( cf.pos, true ); // just `true' - Tree theBody = gen.mkBlock(res); + Tree res = gen.mkBooleanLit( cf.pos, true ); // just `true' + Tree theBody = gen.mkBlock(ts, res); am.construct( m, new CaseDef[] { @@ -417,8 +417,7 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); assert vars != null; Tree stms[] = new Tree[ vars.size() - + ((algMatchTree != null )? 1 : 0 ) - + 1 ]; + + ((algMatchTree != null )? 1 : 0 ) ]; int j = 0; for( Iterator it = vars.iterator(); it.hasNext(); ) { Symbol var = (Symbol) it.next(); @@ -431,10 +430,10 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); if( algMatchTree != null ) stms[ j++ ] = algMatchTree ; - stms[ j ] = callFun( new Tree[] { cf.SeqTrace_tail( _iter() ), - gen.mkIntLit( cf.pos, ntarget.intValue() ) } ); + Tree value = callFun( new Tree[] { cf.SeqTrace_tail( _iter() ), + gen.mkIntLit( cf.pos, ntarget.intValue() ) } ); - return gen.mkBlock( pos, stms ); + return gen.mkBlock( pos, stms, value ); } Tree stateWrap(int i) { @@ -445,23 +444,23 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); /* returns statements that do the work of the right-transducer */ - Tree[] getStms( Tree trace, Unit unit, Tree body ) { + Tree getStms( Tree trace, Unit unit, Tree body ) { - Vector v = new Vector(); + TreeList stms = new TreeList(); Tree loopbody = code_body_NEW(); - v.add( gen.ValDef( iterSym, trace ) ); - v.add( gen.ValDef( stateSym, gen.mkIntLit( cf.pos, 0 ) ) ); - v.addAll( helpVarDefs ); - v.add( gen.LabelDef( this.funSym, - new Ident[] { - gen.Ident( pos, iterSym ), - gen.Ident( pos, stateSym ) - }, loopbody )); + stms.append( gen.ValDef( iterSym, trace ) ); + stms.append( gen.ValDef( stateSym, gen.mkIntLit( cf.pos, 0 ) ) ); + stms.append( helpVarDefs ); + stms.append( gen.LabelDef( this.funSym, + new Ident[] { + gen.Ident( pos, iterSym ), + gen.Ident( pos, stateSym ) + }, loopbody )); // bind variables handled by this righttracer for( Iterator it = seqVars.iterator(); it.hasNext(); ) { - v.add( bindVar( (Symbol) it.next() ) ); + stms.append( bindVar( (Symbol) it.next() ) ); } Transformer treeCloner = new Transformer(unit.global) { @@ -475,15 +474,7 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); } }; - v.add( treeCloner.transform( body ) ); - - Tree result[] = new Tree[ v.size() ]; - int j = 0; - for( Iterator it = v.iterator(); it.hasNext(); ) { - result[ j++ ] = (Tree) it.next(); - } - - return result; + return gen.mkBlock(stms.toArray(), treeCloner.transform( body )); } @@ -492,7 +483,7 @@ System.out.println("RightTracerInScala - the seqVars"+seqVars); * todo: move tree generation of Unit somewhere else */ Tree run_finished( int state ) { - return gen.Block(Position.FIRSTPOS, Tree.EMPTY_ARRAY); + return gen.mkUnitLit(Position.FIRSTPOS); } Tree current() { return gen.Ident( pos, targetSym );} diff --git a/sources/scalac/transformer/matching/SequenceMatcher.java b/sources/scalac/transformer/matching/SequenceMatcher.java index 68d698986c..78334e5c10 100644 --- a/sources/scalac/transformer/matching/SequenceMatcher.java +++ b/sources/scalac/transformer/matching/SequenceMatcher.java @@ -55,8 +55,6 @@ public class SequenceMatcher extends PatternTool { Tree trace = ltis.getTrace(); - Tree theTrace = gen.Ident( cf.pos, ltis.resultSym ); - // (c) determinize + translate R DetWordAutom dRight = new DetWordAutom( right, left, dLeft ); @@ -67,16 +65,10 @@ public class SequenceMatcher extends PatternTool { new RightTracerInScala( dRight, seqVars, _m.owner, cf, pat, elementType ); - Tree stms2[] = rtis.getStms( theTrace, unit, body ); - - // paste statements together - - Tree items[] = new Tree[ 1 + stms2.length ]; - - items[ 0 ] = trace; - System.arraycopy( stms2, 0, items, 1, stms2.length ); - - return gen.mkBlock( body.pos, items ); + // !!! Tree stms2 = rtis.getStms( theTrace, unit, body ); + // !!! gen.mkBlock_( body.pos, trace, stms2 ); + Tree stms2 = rtis.getStms( trace, unit, body ); + return stms2; } private NondetWordAutom[] buildNfas( Tree[] pat ) { diff --git a/sources/scalac/transformer/matching/WordAutomInScala.java b/sources/scalac/transformer/matching/WordAutomInScala.java index bb05f6f63b..c84291b9ae 100644 --- a/sources/scalac/transformer/matching/WordAutomInScala.java +++ b/sources/scalac/transformer/matching/WordAutomInScala.java @@ -60,8 +60,8 @@ public class WordAutomInScala extends Autom2Scala { result = cf.gen.mkBlock( cf.pos, new Tree[] { gen.ValDef( iterSym, cf.newIterator( selector )), gen.ValDef( stateSym, gen.mkIntLit( cf.pos, 0) ), - gen.ValDef( resultSym, theDefDef ), - result } ); + gen.ValDef( resultSym, theDefDef )}, + result ); //unit.global.debugPrinter.print( result ); return result; } diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 9953f1dde7..7d889f4aef 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -1402,7 +1402,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } if ((mode & EXPRmode) != 0) { if (pt.symbol() == definitions.UNIT_CLASS) { - return gen.Block(new Tree[]{tree, gen.mkUnitLit(tree.pos)}); + return gen.mkUnitBlock(tree); } else { Symbol coerceMeth = tree.type.lookup(Names.coerce); if (coerceMeth != Symbol.NONE) { @@ -1939,7 +1939,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { rhs1 = transform( rhs, (name == Names.CONSTRUCTOR) ? CONSTRmode : EXPRmode, - tpe1.type); + (name == Names.CONSTRUCTOR) ? definitions.UNIT_TYPE() : tpe1.type); } popContext(); context.enclClass.owner.flags &= ~INCONSTRUCTOR; @@ -1988,33 +1988,27 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { context.imports = new ImportList(tree, context.scope, context.imports); return Tree.Empty; - case Block(Tree[] stats): + case Block(Tree[] stats, Tree value): pushContext(tree, context.owner, new Scope(context.scope)); Tree[] stats1 = desugarize.Statements(stats, true); enterSyms(stats1); context.imports = context.outer.imports; - Type owntype; int curmode = mode; + int start = 0; + int valuemode = curmode; if ((curmode & CONSTRmode) != 0) { stats1[0] = transform(stats1[0], curmode, pt); context.enclClass.owner.flags &= ~INCONSTRUCTOR; - for (int i = 1; i < stats1.length; i++) - stats1[i] = transform(stats1[i], EXPRmode); - owntype = stats1[0].type; - } else { - for (int i = 0; i < stats1.length - 1; i++) - stats1[i] = transform(stats1[i], EXPRmode); - if (stats1.length > 0) { - stats1[stats1.length - 1] = - transform(stats1[stats1.length - 1], curmode & ~FUNmode, pt); - owntype = checkNoEscape(tree.pos, stats1[stats1.length - 1].type); - } else { - owntype = definitions.UNIT_TYPE(); - } - } + start = 1; + valuemode = (curmode & ~CONSTRmode) | EXPRmode; + } + for (int i = start; i < stats1.length; i++) + stats1[i] = transform(stats1[i], EXPRmode); + Tree value1 = transform(value, valuemode & ~FUNmode, pt); + Type owntype = checkNoEscape(tree.pos, value1.type); popContext(); - return copy.Block(tree, stats1) - .setType(owntype); + return copy.Block(tree, stats1, value1) + .setType(owntype); case Sequence( Tree[] trees ): for( int i = 0; i < trees.length; i++ ) { @@ -2115,8 +2109,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree thenp1, elsep1; if (elsep == Tree.Empty) { thenp1 = transform(thenp, EXPRmode, definitions.UNIT_TYPE()); - elsep1 = make.Block(tree.pos, Tree.EMPTY_ARRAY) - .setType(definitions.UNIT_TYPE()); + elsep1 = gen.mkUnitLit(tree.pos); } else { thenp1 = transform(thenp, EXPRmode, pt); elsep1 = transform(elsep, EXPRmode, pt); @@ -2202,7 +2195,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Tree.EMPTY_ARRAY)) .setType(owntype); popContext(); - return make.Block(tree.pos, new Tree[]{cd, alloc}) + return make.Block(tree.pos, new Tree[]{cd}, alloc) .setType(owntype); } default: diff --git a/sources/scalac/typechecker/Context.java b/sources/scalac/typechecker/Context.java index 61bf0a8299..347e6d565d 100644 --- a/sources/scalac/typechecker/Context.java +++ b/sources/scalac/typechecker/Context.java @@ -51,7 +51,7 @@ public class Context { boolean isTopLevel() { switch (tree) { - case Block(_): + case Block(_, _): return false; case Template(_, _): return outer.tree instanceof Tree.PackageDef; diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index 5cb654a636..a996ae9fa4 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -143,7 +143,7 @@ public class DeSugarize implements Kinds, Modifiers { public Tree mkTuple(int pos, Tree[] trees) { if (trees.length == 0) - return make.Block(pos, trees); + return gen.mkUnitLit(pos); else return make.Apply(pos, make.Select(pos, @@ -420,7 +420,7 @@ public class DeSugarize implements Kinds, Modifiers { pos, mods, vars[i], Tree.Empty, make.Select(pos, make.Ident(pos, var), tupleSelectorName(i + 1))); } - print(pat, "patdef", new Block(res));//debug + print(pat, "patdef", new Block(res, gen.mkUnitLit(pos)));//debug return shareComment(res, tree); } default: @@ -484,8 +484,7 @@ public class DeSugarize implements Kinds, Modifiers { TreeList defs = new TreeList(); Tree lambda = toFunction(toApply(liftoutPrefix(tree, defs), type), type); - defs.append(lambda); - Tree result = make.Block(tree.pos, defs.toArray()); + Tree result = make.Block(tree.pos, defs.toArray(), lambda); print(tree, "eta", result);//debug return result; } diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index ac84a1dbac..3ffe63cf40 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -538,14 +538,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { // { if (null == m$) m$ = new m$class; m$ } Symbol eqMethod = getUnaryMemberMethod( sym.type(), Names.EQEQ, defs.ANY_TYPE()); - Tree body = gen.Block(new Tree[]{ + Tree body = gen.mkBlock( gen.If( gen.Apply( gen.Select(gen.mkNullLit(tree.pos), eqMethod), new Tree[]{gen.mkLocalRef(tree.pos, mvar)}), gen.Assign(gen.mkLocalRef(tree.pos, mvar), alloc), - gen.Block(tree.pos, Tree.EMPTY_ARRAY)), - gen.mkLocalRef(tree.pos, mvar)}); + gen.mkUnitLit(tree.pos)), + gen.mkLocalRef(tree.pos, mvar)); // def m: T = { if (m$ == null[T]) m$ = new m$class; m$ } sym.flags |= STABLE; @@ -704,7 +704,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { qualCaseField(clazz, gen.mkLocalRef(clazz.pos, that1sym), i))}); } - thenpart = gen.Block(new Tree[]{that1def, cmp}); + thenpart = gen.mkBlock(that1def, cmp); } Tree body = gen.If(cond, thenpart, gen.mkBooleanLit(clazz.pos, false)); return gen.DefDef(equalsSym, body); @@ -970,9 +970,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { } return copy.Template(tree, bases1, body1); - case Block(Tree[] stats): + case Block(Tree[] stats, Tree value): Tree[] stats1 = transformStats(stats); - return copy.Block(tree, stats1); + Tree value1 = transform(value); + return copy.Block(tree, stats1, value1); case This(_): return tree; diff --git a/test/files/shl/basic.check b/test/files/shl/basic.check index 9439e81b3b..1cac379455 100644 --- a/test/files/shl/basic.check +++ b/test/files/shl/basic.check @@ -1,4 +1,4 @@ -> > > > > > (): scala.Unit +> > > > > > (): scala.Unit(()) > false: scala.Boolean(false) > 1: scala.Char('1') > 2: scala.Int(2) |