summaryrefslogtreecommitdiff
path: root/sources/scalac/ast
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/ast')
-rw-r--r--sources/scalac/ast/TreeGen.java3
-rw-r--r--sources/scalac/ast/TreeInfo.java6
-rw-r--r--sources/scalac/ast/parser/Parser.java62
-rw-r--r--sources/scalac/ast/printer/TextTreePrinter.java23
4 files changed, 54 insertions, 40 deletions
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index 864609e7f8..47df5ae26c 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -252,7 +252,8 @@ public class TreeGen implements Kinds, Modifiers {
pos,
sym.flags & SOURCEFLAGS,
sym.name,
- TypeTerm(pos, symtype))
+ TypeTerm(pos, symtype),
+ TypeTerm(pos, sym.loBound()))
.setSymbol(sym).setType(definitions.UNIT_TYPE);
}
diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java
index 17ca034316..f377468e08 100644
--- a/sources/scalac/ast/TreeInfo.java
+++ b/sources/scalac/ast/TreeInfo.java
@@ -44,7 +44,7 @@ public class TreeInfo {
case ModuleDef(_, _, _, _):
case DefDef(_, _, _, _, _, _):
case ValDef(_, _, _, _):
- case TypeDef(_, _, _):
+ case TypeDef(_, _, _, _):
case Import(_, _):
return true;
default:
@@ -58,7 +58,7 @@ public class TreeInfo {
return rhs == Tree.Empty;
case ValDef(_, _, _, Tree rhs):
return rhs == Tree.Empty;
- case TypeDef(_, _, _):
+ case TypeDef(_, _, _, _):
return true;
default:
return false;
@@ -72,7 +72,7 @@ public class TreeInfo {
case ClassDef(_, _, _, _, _, _):
case ModuleDef(_, _, _, _):
case DefDef(_, _, _, _, _, _):
- case TypeDef(_, _, _):
+ case TypeDef(_, _, _, _):
case Import(_, _):
return true;
case ValDef(int mods, _, _, Tree rhs):
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 1f086f93ba..589d33c31c 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -15,8 +15,6 @@ import scalac.symtab.Modifiers;
import scalac.ast.*;
import Tree.*;
-//todo: add type idents?
-
/** A recursive descent parser for the programming language Scala.
*
* @author Martin Odersky, Matthias Zenger
@@ -1198,26 +1196,29 @@ public class Parser implements Tokens {
return (ValDef)make.ValDef(pos, mods, name, tp, Tree.Empty);
}
- /** TypeParamClauseOpt ::= [`[' TypeSig {`,' TypeSig} `]']
+ /** TypeParamClauseOpt ::= [`[' TypeParam {`,' TypeParam} `]']
+ * FunTypeParamClauseOpt ::= [`[' FunTypeParam {`,' FunTypeParam} `]']
*/
- TypeDef[] typeParamClauseOpt() {
+ TypeDef[] typeParamClauseOpt(boolean variant) {
TreeList params = new TreeList();
if (s.token == LBRACKET) {
s.nextToken();
- params.append(typeSig(Modifiers.PARAM));
+ params.append(typeParam(variant));
while (s.token == COMMA) {
s.nextToken();
- params.append(typeSig(Modifiers.PARAM));
+ params.append(typeParam(variant));
}
accept(RBRACKET);
}
return (TypeDef[])params.copyTo(new TypeDef[params.length()]);
}
- /** TypeSig ::= [+ | -] Id TypeBounds
+ /** TypeParam ::= [`+' | `-'] FunTypeParam
+ * FunTypeParam ::= Id TypeBounds
*/
- Tree typeSig(int mods) {
- if (s.token == IDENTIFIER) {
+ Tree typeParam(boolean variant) {
+ int mods = Modifiers.PARAM;
+ if (variant && s.token == IDENTIFIER) {
if (s.name == PLUS) {
s.nextToken();
mods |= Modifiers.COVARIANT;
@@ -1229,7 +1230,7 @@ public class Parser implements Tokens {
return typeBounds(s.pos, mods, ident());
}
- /** TypeBounds ::= [>: Type] [<: Type]
+ /** TypeBounds ::= [`>:' Type] [`<:' Type]
*/
Tree typeBounds(int pos, int mods, Name name) {
Tree lobound;
@@ -1246,7 +1247,7 @@ public class Parser implements Tokens {
} else {
hibound = scalaDot(pos, Names.Any.toTypeName());
}
- return make.TypeDef(pos, mods, name.toTypeName(), hibound);
+ return make.TypeDef(pos, mods, name.toTypeName(), hibound, lobound);
}
//////// DEFS ////////////////////////////////////////////////////////////////
@@ -1351,7 +1352,7 @@ public class Parser implements Tokens {
* | var ValSig {`,' ValSig}
* | def FunSig {`,' FunSig}
* | constr ConstrSig {`,' ConstrSig}
- * | type TypeSig {`,' TypeSig}
+ * | type TypeDcl {`,' TypeDcl}
*/
Tree[] defOrDcl(int mods) {
TreeList ts = new TreeList();
@@ -1470,13 +1471,13 @@ public class Parser implements Tokens {
}
}
- /** FunDef ::= Id [TypeParamClause] {ParamClause} [`:' Type] `=' Expr
- * FunSig ::= Id [TypeParamClause] {ParamClause} `:' Type
+ /** FunDef ::= Id [FunTypeParamClause] {ParamClause} [`:' Type] `=' Expr
+ * FunSig ::= Id [FunTypeParamClause] {ParamClause} `:' Type
*/
Tree funDefOrSig(int mods) {
int pos = s.pos;
Name name = ident();
- TypeDef[] tparams = typeParamClauseOpt();
+ TypeDef[] tparams = typeParamClauseOpt(false);
ValDef[][] vparams = paramClauses();
Tree restype = typedOpt();
if (s.token == EQUALS || restype == Tree.Empty)
@@ -1487,12 +1488,12 @@ public class Parser implements Tokens {
tparams, vparams, restype, Tree.Empty);
}
- /* ConstrDef ::= Id [TypeParamClause] [ParamClause] [`:' Type] `=' (Constr | BlockConstr)
+ /* ConstrDef ::= Id [FunTypeParamClause] [ParamClause] [`:' Type] `=' (Constr | BlockConstr)
*/
Tree constrDefOrSig(int mods) {
int pos = s.pos;
Name name = ident().toConstrName();
- TypeDef[] tparams = typeParamClauseOpt();
+ TypeDef[] tparams = typeParamClauseOpt(false);
ValDef[][] vparams = new ValDef[][]{paramClause()};
Tree restype = typedOpt();
if (s.token == EQUALS || restype == Tree.Empty) {
@@ -1505,24 +1506,23 @@ public class Parser implements Tokens {
}
/** TypeDef ::= Id `=' Type
- * TypeSig ::= [`+' | `-'] Id [`>:' Type] [`<:' Type]
+ * TypeDcl ::= Id TypeBounds
*/
Tree typeDefOrSig(int mods) {
int pos = s.pos;
- if (s.token == IDENTIFIER && (s.name == PLUS || s.name == MINUS))
- return typeSig(mods | Modifiers.DEFERRED);
Name name = ident().toTypeName();
- if (s.token == SUPERTYPE || s.token == SUBTYPE) {
- return typeBounds(pos, mods | Modifiers.DEFERRED, name);
- } else if (s.token == EQUALS) {
+ switch (s.token) {
+ case EQUALS:
s.nextToken();
- return make.TypeDef(pos, mods, name, type());
- } else if (s.token == SEMI || s.token == COMMA || s.token == RBRACE) {
- return make.TypeDef(
- pos, mods | Modifiers.DEFERRED, name,
- scalaDot(pos, Names.Any.toTypeName()));
- } else {
- return syntaxError("`=', `>:', or `<:' expected", true);
+ return make.TypeDef(pos, mods, name, type(), Tree.Empty);
+ case SUPERTYPE:
+ case SUBTYPE:
+ case SEMI:
+ case COMMA:
+ case RBRACE:
+ return typeBounds(pos, mods | Modifiers.DEFERRED, name);
+ default:
+ return syntaxError("`=', `>:', or `<:' expected", true);
}
}
@@ -1531,7 +1531,7 @@ public class Parser implements Tokens {
Tree classDef(int mods) {
int pos = s.pos;
Name name = ident();
- TypeDef[] tparams = typeParamClauseOpt();
+ TypeDef[] tparams = typeParamClauseOpt(true);
ValDef[][] params = (s.token == LPAREN) ? new ValDef[][]{paramClause()}
: Tree.ValDef_EMPTY_ARRAY_ARRAY;
return make.ClassDef(pos, mods, name.toTypeName(), tparams, params,
diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java
index c7375c1fcc..a943ca20f4 100644
--- a/sources/scalac/ast/printer/TextTreePrinter.java
+++ b/sources/scalac/ast/printer/TextTreePrinter.java
@@ -182,6 +182,7 @@ public class TextTreePrinter implements TreePrinter {
protected static final Text TXT_DOT = Text.Simple(".");
protected static final Text TXT_COMMA = Text.Simple(",");
protected static final Text TXT_EQUAL = Text.Simple("=");
+ protected static final Text TXT_SUPERTYPE = Text.Simple(">:");
protected static final Text TXT_SUBTYPE = Text.Simple("<:");
protected static final Text TXT_HASH = Text.Simple("#");
protected static final Text TXT_RIGHT_ARROW = Text.Simple("=>");
@@ -317,13 +318,17 @@ public class TextTreePrinter implements TreePrinter {
case TypeDef(int mods,
Name name,
- Tree rhs):
+ Tree rhs,
+ Tree lobound):
printModifiers(mods);
print(KW_TYPE);
print(Text.Space);
printSymbolDefinition(tree.symbol(), name);
- if ((mods & (Modifiers.DEFERRED | Modifiers.PARAM)) != 0) printOpt(TXT_SUBTYPE, rhs, true);
- else printOpt(TXT_EQUAL, rhs, true);
+ if ((mods & (Modifiers.DEFERRED | Modifiers.PARAM)) != 0) {
+ printBounds(lobound, rhs);
+ } else {
+ printOpt(TXT_EQUAL, rhs, true);
+ }
break;
case Import(Tree expr, Name[] selectors):
@@ -683,10 +688,10 @@ public class TextTreePrinter implements TreePrinter {
protected void printParam(Tree tree) {
switch (tree) {
- case TypeDef(int mods, Name name, Tree bound):
+ case TypeDef(int mods, Name name, Tree bound, Tree lobound):
printModifiers(mods);
printSymbolDefinition(tree.symbol(), name);
- printOpt(TXT_SUBTYPE, bound, true);
+ printBounds(lobound, bound);
break;
case ValDef(int mods, Name name, Tree tpe, Tree.Empty):
@@ -699,4 +704,12 @@ public class TextTreePrinter implements TreePrinter {
Debug.abort("bad parameter: " + tree);
}
}
+
+ protected void printBounds(Tree lobound, Tree hibound) {
+ if (lobound.toString() != "scala.All")
+ printOpt(TXT_SUPERTYPE, lobound, true);
+ if (hibound.toString() != "scala.Any")
+ printOpt(TXT_SUBTYPE, hibound, true);
+ }
+
}