summaryrefslogtreecommitdiff
path: root/sources/scalac/ast
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/ast')
-rw-r--r--sources/scalac/ast/Tree.java27
-rw-r--r--sources/scalac/ast/TreeGen.java19
-rw-r--r--sources/scalac/ast/TreeInfo.java2
-rw-r--r--sources/scalac/ast/parser/Parser.java94
-rw-r--r--sources/scalac/ast/parser/Scanner.java11
-rw-r--r--sources/scalac/ast/parser/Tokens.java29
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java22
7 files changed, 127 insertions, 77 deletions
diff --git a/sources/scalac/ast/Tree.java b/sources/scalac/ast/Tree.java
index 0c28016253..a3cc94cf3e 100644
--- a/sources/scalac/ast/Tree.java
+++ b/sources/scalac/ast/Tree.java
@@ -146,7 +146,7 @@ public class Tree {
/**
* Import declaration
* - introduced by: parser
- * - eliminated by: !!! ?
+ * - eliminated by: analyzer
*/
public case Import(Tree expr, Name[] selectors) {
if (!expr.isTerm())
@@ -204,8 +204,8 @@ public class Tree {
/**
* Tuple of expressions (comma separated expressions)
- * - introduced by: !!! ?
- * - eliminated by: !!! ?
+ * - introduced by: uncurry
+ * - eliminated by: lambdalift
*/
public case Tuple(Tree[] trees) {
if (trees != null) {
@@ -219,14 +219,14 @@ public class Tree {
/**
* Visitor (a sequence of cases)
* - introduced by: parser
- * - eliminated by: !!! ?
+ * - eliminated by: transmatch
*/
public case Visitor(CaseDef[] cases);
/**
* Anonymous function
* - introduced by: parser
- * - eliminated by: !!! ?
+ * - eliminated by: analyzer
*/
public case Function(ValDef[] vparams,
Tree body) {
@@ -237,7 +237,7 @@ public class Tree {
/**
* Assignment
* - introduced by: parser
- * - eliminated by: !!! ?
+ * - eliminated by: -
*/
public case Assign(Tree lhs,
Tree rhs) {
@@ -283,7 +283,7 @@ public class Tree {
/**
* Type application
* - introduced by: parser
- * - eliminated by: !!! ?
+ * - eliminated by: erasure
*/
public case TypeApply(Tree fun,
Tree[] args) {
@@ -422,7 +422,7 @@ public class Tree {
/**
* Applied type
* - introduced by: parser
- * - eliminated by: Analyzer
+ * - eliminated by: analyzer
*/
public case AppliedType(Tree tpe, Tree[] args) {
assert tpe.isType() : this;
@@ -492,6 +492,17 @@ public class Tree {
}
}
+ /** Returns true if this tree is empty or error. */
+ public boolean isMissing() {
+ switch(this) {
+ case Bad():
+ case Empty:
+ return true;
+ default:
+ return false;
+ }
+ }
+
//########################################################################
// Public Methods - tree type
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index 0c9c47eb88..ecb4705de5 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -165,13 +165,7 @@ public class TreeGen implements Kinds, Modifiers {
Tree ref = mkRef(pos, pre, sym.constructor());
Tree constr = (args.length == 0) ? ref
: TypeApply(ref, mkTypes(sym.pos, args));
- switch (parentType) {
- case MethodType(Symbol[] params, Type restpe):
- assert params.length == 0 : parentType;
- return Apply(constr, Tree.EMPTY_ARRAY);
- default:
- return constr;
- }
+ return Apply(constr, Tree.EMPTY_ARRAY);
default:
throw global.fail("invalid parent type", parentType);
}
@@ -357,9 +351,17 @@ public class TreeGen implements Kinds, Modifiers {
return TypeApply(fn.pos, fn, args);
}
+ public Tree If(int pos, Tree cond, Tree thenpart, Tree elsepart) {
+ return
+ make.If(pos, cond, thenpart, elsepart).setType(thenpart.type);
+ }
+
+ public Tree If(Tree cond, Tree thenpart, Tree elsepart) {
+ return If(cond.pos, cond, thenpart, elsepart);
+ }
+
/** Build and applied type node with given function
* and argument trees.
- */
public Tree AppliedType(int pos, Tree fn, Tree[] args) {
return make.AppliedType(pos, fn, args)
.setType(Type.appliedType(fn.type, Tree.typeOf(args)));
@@ -368,6 +370,7 @@ public class TreeGen implements Kinds, Modifiers {
public Tree AppliedType(Tree fn, Tree[] args) {
return AppliedType(fn.pos, fn, args);
}
+ */
/** Build and attribute select node of given symbol.
* It is assumed that the prefix is not empty.
diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java
index d07627724f..17ca034316 100644
--- a/sources/scalac/ast/TreeInfo.java
+++ b/sources/scalac/ast/TreeInfo.java
@@ -115,6 +115,8 @@ public class TreeInfo {
tree.symbol() != null && tree.symbol().isPrimaryConstructor();
case TypeApply(Tree constr, _):
return isPureConstr(constr);
+ case Apply(Tree fn, Tree[] args):
+ return args.length == 0 && isPureConstr(fn);
default:
return false;
}
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index f525398b3c..771979fcda 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -124,7 +124,7 @@ public class Parser implements Tokens {
boolean isDefIntro() {
switch (s.token) {
case VAL: case VAR: case DEF: case CONSTR: case TYPE:
- case MODULE: case CLASS: case CASECLASS: case TRAIT:
+ case OBJECT: case CASEOBJECT: case CLASS: case CASECLASS: case TRAIT:
return true;
default:
return false;
@@ -193,6 +193,15 @@ public class Parser implements Tokens {
return make.Select(pos, make.Ident(pos, Names.scala), name);
}
+ Tree scalaBooleanDot(int pos, Name name) {
+ return make.Select(pos, scalaDot(pos, Names.Boolean), name);
+ }
+
+ Tree scalaObjectConstr(int pos) {
+ return make.Apply(
+ pos, scalaDot(pos, Names.Object.toConstrName()), Tree.EMPTY_ARRAY);
+ }
+
/** Create tree for for-comprehension <for (enums) do body> or
* <for (enums) yield body> where mapName and flatmapName are chosen
* corresponding to whether this is a for-do or a for-yield.
@@ -310,6 +319,17 @@ public class Parser implements Tokens {
}
}
+ /** Complete unapplied constructor with `()' arguments
+ */
+ Tree applyConstr(Tree t) {
+ switch (t) {
+ case Apply(_, _):
+ return t;
+ default:
+ return make.Apply(t.pos, t, Tree.EMPTY_ARRAY);
+ }
+ }
+
/////// OPERAND/OPERATOR STACK /////////////////////////////////////////////////
Tree[] operands = new Tree[8];
@@ -383,6 +403,9 @@ public class Parser implements Tokens {
t = make.This(s.skipToken(), Tree.Empty);
if (!thisOK || s.token == DOT)
t = selectors(accept(DOT), t, typeOK);
+ } else if (s.token == SUPER) {
+ t = make.Super(s.skipToken(), Tree.Empty);
+ t = selectors(accept(DOT), t, typeOK);
} else {
t = make.Ident(s.pos, ident());
if (s.token == DOT) {
@@ -413,7 +436,7 @@ public class Parser implements Tokens {
}
}
- /** StableId ::= [[Ident `.'] this `.'] {Id `.'} Id
+ /** StableId ::= [[Ident `.'] this `.' | super] {Id `.'} Id
*/
Tree stableId() {
return stableRef(false, false);
@@ -498,6 +521,17 @@ public class Parser implements Tokens {
}
}
+ /** SimpleTypedOpt ::= [`:' Type]
+ */
+ Tree simpleTypedOpt() {
+ if (s.token == COLON) {
+ s.nextToken();
+ return simpleType();
+ } else {
+ return Tree.Empty;
+ }
+ }
+
/** Types ::= Type {`,' Type}
*/
Tree[] types() {
@@ -894,7 +928,8 @@ public class Parser implements Tokens {
switch (res) {
case Block(Tree[] stats):
if (stats.length > 0)
- stats[stats.length - 1] = convertToConstr(stats[stats.length - 1]);
+ stats[stats.length - 1] = applyConstr(
+ convertToConstr(stats[stats.length - 1]));
else
syntaxError(res.pos, "class constructor expected", false);
}
@@ -1337,9 +1372,7 @@ public class Parser implements Tokens {
}
/** TopDef ::= ([case] class | trait) ClassDef {`,' ClassDef}
- * | module ModuleDef {`,' ModuleDef}
- * LocalTopDef ::= class ClassDef {`,' ClassDef}//todo: keep?
- * | module ModuleDef {`,' ModuleDef}
+ * | [case] object ModuleDef {`,' ModuleDef}
*/
Tree[] topDef(int mods) {
TreeList ts = new TreeList();
@@ -1354,7 +1387,8 @@ public class Parser implements Tokens {
ts.append(classDef(mods));
} while (s.token == COMMA);
return ts.toArray();
- case MODULE:
+ case OBJECT:
+ case CASEOBJECT:
do {
s.nextToken();
ts.append(moduleDef(mods));
@@ -1441,10 +1475,7 @@ public class Parser implements Tokens {
TypeDef[] tparams = typeParamClauseOpt();
ValDef[][] vparams = new ValDef[][]{paramClause()};
Tree restype = typedOpt();
- if (s.token == LBRACE)
- return make.DefDef(pos, mods, name, tparams, vparams,
- restype, blockConstr());
- else if (s.token == EQUALS || restype == Tree.Empty) {
+ if (s.token == EQUALS || restype == Tree.Empty) {
accept(EQUALS);
return make.DefDef(pos, mods, name, tparams, vparams,
restype, (s.token == LBRACE) ? blockConstr() : constr());
@@ -1474,24 +1505,23 @@ public class Parser implements Tokens {
}
}
- /** ClassDef ::= Id [TypeParamClause] [`:' Type] ClassTemplate
+ /** ClassDef ::= Id [TypeParamClause] [`:' SimpleType] ClassTemplate
*/
Tree classDef(int mods) {
int pos = s.pos;
Name name = ident();
TypeDef[] tparams = typeParamClauseOpt();
- ValDef[][] params;
- if (s.token == LPAREN) params = new ValDef[][]{paramClause()};
- else params = Tree.ExtValDef.EMPTY_ARRAY_ARRAY;
+ ValDef[][] params = (s.token == LPAREN) ? new ValDef[][]{paramClause()}
+ : Tree.ExtValDef.EMPTY_ARRAY_ARRAY;
return make.ClassDef(pos, mods, name.toTypeName(), tparams, params,
- typedOpt(), classTemplate());
+ simpleTypedOpt(), classTemplate());
}
- /** ModuleDef ::= Id [`:' Type] ClassTemplate
+ /** ModuleDef ::= Id [`:' SimpleType] ClassTemplate
*/
Tree moduleDef(int mods) {
return make.ModuleDef(
- s.pos, mods, ident(), typedOpt(), classTemplate());
+ s.pos, mods, ident(), simpleTypedOpt(), classTemplate());
}
/** ClassTemplate ::= [`extends' Constr] {`with' Constr} [TemplateBody]
@@ -1504,21 +1534,16 @@ public class Parser implements Tokens {
} else if (s.token == WITH) {
s.nextToken();
TreeList parents = new TreeList();
- parents.append(scalaDot(pos, Names.Object.toConstrName()));
+ parents.append(scalaObjectConstr(pos));
return template(parents);
} else if (s.token == LBRACE) {
- return (Template)make.Template(pos,
- new Tree[]{scalaDot(pos, Names.Object.toConstrName())},
- templateBody());
- } else if (s.token == SEMI || s.token == COMMA || s.token == RBRACE) {
- return (Template)make.Template(pos,
- new Tree[]{scalaDot(pos, Names.Object.toConstrName())},
- Tree.EMPTY_ARRAY);
+ return (Template)make.Template(
+ pos, new Tree[]{scalaObjectConstr(pos)}, templateBody());
} else {
- syntaxError("`extends' or `{' expected", true);
- return (Template)make.Template(pos,
- new Tree[]{scalaDot(pos, Names.Object.toConstrName())},
- Tree.EMPTY_ARRAY);
+ if (!(s.token == SEMI || s.token == COMMA || s.token == RBRACE))
+ syntaxError("`extends' or `{' expected", true);
+ return (Template)make.Template(
+ pos, new Tree[]{scalaObjectConstr(pos)}, Tree.EMPTY_ARRAY);
}
}
@@ -1550,7 +1575,7 @@ public class Parser implements Tokens {
t = make.TypeApply(s.pos, t, typeArgs());
if (s.token == LPAREN)
t = make.Apply(s.pos, t, argumentExprs());
- return t;
+ return applyConstr(t);
}
/** TemplateBody ::= `{' [TemplateStat {`;' TemplateStat}] `}'
@@ -1601,11 +1626,12 @@ public class Parser implements Tokens {
} else if (s.token == CLASS ||
s.token == CASECLASS ||
s.token == TRAIT ||
- s.token == MODULE ||
+ s.token == OBJECT ||
+ s.token == CASEOBJECT ||
isModifier()) {
stats.append(topDef(modifiers()));
} else if (s.token != SEMI) {
- syntaxError("illegal start of class or module definition", true);
+ syntaxError("illegal start of class or object definition", true);
}
if (s.token != RBRACE && s.token != EOF) accept(SEMI);
}
@@ -1658,7 +1684,7 @@ public class Parser implements Tokens {
/** BlockStatSeq ::= { BlockStat `;' } [Expr]
* BlockStat ::= Import
* | Def
- * | LocalClassModifiers LocalTopDef
+ * | LocalClassModifiers TopDef
* | Expr
* |
*/
diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java
index 82eef0d408..5cfe8292a6 100644
--- a/sources/scalac/ast/parser/Scanner.java
+++ b/sources/scalac/ast/parser/Scanner.java
@@ -138,6 +138,8 @@ public class Scanner extends TokenData {
fetchToken();
if (token == CLASS) {
token = CASECLASS;
+ } else if (token == OBJECT) {
+ token = CASEOBJECT;
} else {
next.copyFrom(this);
this.copyFrom(prev);
@@ -479,8 +481,10 @@ public class Scanner extends TokenData {
void treatIdent(int start, int end) {
name = Name.fromAscii(buf, start, end - start);
- if (name.index <= maxKey)
+ if (name.index <= maxKey) {
token = key[name.index];
+ if (token == OBJECT1) token = OBJECT; //todo: elim
+ }
else
token = IDENTIFIER;
}
@@ -716,6 +720,8 @@ public class Scanner extends TokenData {
return "','";
case CASECLASS:
return "case class";
+ case CASEOBJECT:
+ return "case object";
default:
try {
return "'" + tokenName[token].toString() + "'";
@@ -796,7 +802,8 @@ public class Scanner extends TokenData {
enterKeyword("def", DEF);
enterKeyword("type", TYPE);
enterKeyword("extends", EXTENDS);
- enterKeyword("module", MODULE);
+ enterKeyword("object", OBJECT);
+ enterKeyword("module", OBJECT1);
enterKeyword("class",CLASS);
enterKeyword("constr",CONSTR);
enterKeyword("import", IMPORT);
diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java
index 10503ddd48..c4499522df 100644
--- a/sources/scalac/ast/parser/Tokens.java
+++ b/sources/scalac/ast/parser/Tokens.java
@@ -37,19 +37,20 @@ public interface Tokens {
SUPER = 27,
CASE = 28,
CASECLASS = 29,
- VAL = 30,
- ABSTRACT = 31,
- FINAL = 32,
- PRIVATE = 33,
- PROTECTED = 34,
- OVERRIDE = 35,
- VAR = 36,
- DEF = 37,
- TYPE = 38,
- EXTENDS = 39,
- TRUE = 40,
- FALSE = 41,
- MODULE = 43,
+ CASEOBJECT = 30,
+ VAL = 31,
+ ABSTRACT = 32,
+ FINAL = 33,
+ PRIVATE = 34,
+ PROTECTED = 35,
+ OVERRIDE = 36,
+ VAR = 37,
+ DEF = 38,
+ TYPE = 39,
+ EXTENDS = 40,
+ TRUE = 41,
+ FALSE = 42,
+ OBJECT = 43,
CLASS = 44,
CONSTR = 45,
IMPORT = 46,
@@ -60,6 +61,8 @@ public interface Tokens {
DO = 51,
TRAIT = 52,
+ OBJECT1 = 53, // todo: elim
+
/* special symbols */
COMMA = 61,
SEMI = 62,
diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java
index adbad7c3ad..0d4ff6022f 100644
--- a/sources/scalac/ast/printer/TextTreePrinter.java
+++ b/sources/scalac/ast/printer/TextTreePrinter.java
@@ -150,7 +150,7 @@ public class TextTreePrinter implements TreePrinter {
protected static final Text KW_IMPORT = Text.Keyword("import");
protected static final Text KW_INTERFACE = Text.Keyword("interface");
protected static final Text KW_LET = Text.Keyword("let");
- protected static final Text KW_MODULE = Text.Keyword("module");
+ protected static final Text KW_OBJECT = Text.Keyword("object");
protected static final Text KW_NEW = Text.Keyword("new");
protected static final Text KW_NULL = Text.Keyword("null");
protected static final Text KW_OUTER = Text.Keyword("outer");
@@ -171,8 +171,8 @@ public class TextTreePrinter implements TreePrinter {
protected static final Text TXT_ERROR = Text.Simple("<error>");
protected static final Text TXT_UNKNOWN = Text.Simple("<unknown>");
protected static final Text TXT_NULL = Text.Simple("<null>");
- protected static final Text TXT_MODULE_COMMENT
- = Text.Simple("/*module*/ ");
+ protected static final Text TXT_OBJECT_COMMENT
+ = Text.Simple("/*object*/ ");
protected static final Text TXT_EMPTY = Text.Simple("<empty>");
protected static final Text TXT_QUOTE = Text.Simple("\"");
@@ -192,10 +192,6 @@ public class TextTreePrinter implements TreePrinter {
protected static final Text TXT_LEFT_BRACKET = Text.Simple("[");
protected static final Text TXT_RIGHT_BRACKET = Text.Simple("]");
- protected static final Text TXT_WITH_BLOCK_BEGIN =
- Text.Sequence(new Text[] {
- Text.Space, KW_WITH, Text.Space, TXT_LEFT_BRACE, Text.Newline
- });
protected static final Text TXT_WITH_SP =
Text.Sequence(new Text[]{ Text.Space, KW_WITH, Text.Space });
protected static final Text TXT_BLOCK_BEGIN =
@@ -271,7 +267,7 @@ public class TextTreePrinter implements TreePrinter {
Tree tpe,
Tree.Template impl):
printModifiers(mods);
- print(KW_MODULE);
+ print(KW_OBJECT);
print(Text.Space);
printSymbolDefinition(tree.symbol(), name);
printOpt(TXT_COLON, tpe, false);
@@ -282,7 +278,7 @@ public class TextTreePrinter implements TreePrinter {
printModifiers(mods);
if ((mods & Modifiers.MUTABLE) != 0) print(KW_VAR);
else {
- if ((mods & Modifiers.MODUL) != 0) print(TXT_MODULE_COMMENT);
+ if ((mods & Modifiers.MODUL) != 0) print(TXT_OBJECT_COMMENT);
print(KW_VAL);
}
print(Text.Space);
@@ -506,7 +502,7 @@ public class TextTreePrinter implements TreePrinter {
case CompoundType(Tree[] baseTypes, Tree[] refinements):
printArray(baseTypes, Text.None, Text.None, TXT_WITH_SP);
- printArray(refinements, TXT_WITH_BLOCK_BEGIN, TXT_BLOCK_END, Text.Newline);
+ printArray(refinements, TXT_BLOCK_BEGIN, TXT_BLOCK_END, Text.Newline);
break;
case AppliedType(Tree tpe, Tree[] args):
@@ -649,8 +645,10 @@ public class TextTreePrinter implements TreePrinter {
printArray(templ.parents, Text.None, Text.None, TXT_WITH_SP);
}
- if (templ.body.length > 0)
- printArray(templ.body, TXT_WITH_BLOCK_BEGIN, TXT_BLOCK_END, TXT_BLOCK_SEP);
+ if (templ.body.length > 0) {
+ print(Text.Space);
+ printArray(templ.body, TXT_BLOCK_BEGIN, TXT_BLOCK_END, TXT_BLOCK_SEP);
+ }
}
protected void printParams(Tree.TypeDef[] tparams) {