summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-02-12 15:10:40 +0000
committerpaltherr <paltherr@epfl.ch>2004-02-12 15:10:40 +0000
commit2014d1feeefd1bc6bcfee0cee347c4a77db05253 (patch)
treedeffe18f0bf6527171d655885445abc8bb17023b
parentb62de8dc4f94efa47bf6714865b8bbf4df700046 (diff)
downloadscala-2014d1feeefd1bc6bcfee0cee347c4a77db05253.tar.gz
scala-2014d1feeefd1bc6bcfee0cee347c4a77db05253.tar.bz2
scala-2014d1feeefd1bc6bcfee0cee347c4a77db05253.zip
- Changed Tree.Block(Tree[]) to Tree.Block(Tree...
- Changed Tree.Block(Tree[]) to Tree.Block(Tree[],Tree)
-rw-r--r--sources/meta/scalac/ast/Tree.java3
-rw-r--r--sources/scala/tools/scalac/ast/parser/Parser.scala42
-rw-r--r--sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala9
-rw-r--r--sources/scala/tools/scalac/transformer/TransMatch.scala5
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala48
-rw-r--r--sources/scala/tools/scalac/typechecker/Context.scala2
-rw-r--r--sources/scala/tools/scalac/typechecker/DeSugarize.scala7
-rw-r--r--sources/scala/tools/scalai/ExpressionCompiler.java12
-rw-r--r--sources/scalac/ast/Transformer.java.tmpl4
-rw-r--r--sources/scalac/ast/TreeGen.java100
-rw-r--r--sources/scalac/ast/parser/Parser.java44
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java9
-rw-r--r--sources/scalac/atree/ATreeFromSTree.java16
-rw-r--r--sources/scalac/backend/jvm/GenJVM.java15
-rw-r--r--sources/scalac/backend/msil/GenMSIL.java29
-rw-r--r--sources/scalac/checkers/TreeChecker.java7
-rw-r--r--sources/scalac/symtab/Type.java8
-rw-r--r--sources/scalac/transformer/AddConstructors.java9
-rw-r--r--sources/scalac/transformer/Erasure.java16
-rw-r--r--sources/scalac/transformer/LambdaLift.java8
-rw-r--r--sources/scalac/transformer/TailCallPhase.java9
-rw-r--r--sources/scalac/transformer/TransMatch.java5
-rw-r--r--sources/scalac/transformer/matching/AlgebraicMatcher.java14
-rw-r--r--sources/scalac/transformer/matching/Autom2Scala.java8
-rw-r--r--sources/scalac/transformer/matching/LeftTracerInScala.java3
-rw-r--r--sources/scalac/transformer/matching/PatternMatcher.java52
-rw-r--r--sources/scalac/transformer/matching/RightTracerInScala.java65
-rw-r--r--sources/scalac/transformer/matching/SequenceMatcher.java16
-rw-r--r--sources/scalac/transformer/matching/WordAutomInScala.java4
-rw-r--r--sources/scalac/typechecker/Analyzer.java39
-rw-r--r--sources/scalac/typechecker/Context.java2
-rw-r--r--sources/scalac/typechecker/DeSugarize.java7
-rw-r--r--sources/scalac/typechecker/RefCheck.java13
-rw-r--r--test/files/shl/basic.check2
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)