summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac')
-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
-rw-r--r--sources/scalac/symtab/Definitions.java2
-rw-r--r--sources/scalac/symtab/Modifiers.java2
-rw-r--r--sources/scalac/symtab/Symbol.java14
-rw-r--r--sources/scalac/symtab/Type.java28
-rw-r--r--sources/scalac/symtab/classfile/AttributeParser.java14
-rw-r--r--sources/scalac/symtab/classfile/ClassfileParser.java12
-rw-r--r--sources/scalac/transformer/AddConstructors.java4
-rw-r--r--sources/scalac/transformer/ExpandMixins.java3
-rw-r--r--sources/scalac/typechecker/Analyzer.java158
-rw-r--r--sources/scalac/typechecker/DeSugarize.java59
-rw-r--r--sources/scalac/typechecker/RefCheck.java90
18 files changed, 373 insertions, 217 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) {
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java
index de31e34a06..3fe8cc7dee 100644
--- a/sources/scalac/symtab/Definitions.java
+++ b/sources/scalac/symtab/Definitions.java
@@ -194,7 +194,7 @@ public class Definitions {
ANY_TYPE = ANY_CLASS.typeConstructor();
ANY_CLASS.setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), ANY_CLASS));
ANY_CLASS.constructor().setInfo(
- Type.PolyType(Symbol.EMPTY_ARRAY, ANY_TYPE));
+ Type.MethodType(Symbol.EMPTY_ARRAY, ANY_TYPE));
// the java.lang.OBJECT class
JAVA_OBJECT_CLASS = getClass(Names.java_lang_Object);
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index cbfafae068..8d161ce117 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -55,7 +55,7 @@ public interface Modifiers {
int SNDTIME = 0x40000000; //debug
// masks
- int SOURCEFLAGS = 0x00000077 | PARAM | TRAIT; // these modifiers can be set in source programs.
+ int SOURCEFLAGS = 0x00000077 | DEF | REPEATED | MODUL | MUTABLE | PACKAGE | PARAM | TRAIT; // these modifiers can be set in source programs.
int ACCESSFLAGS = PRIVATE | PROTECTED;
public static class Helper {
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index b76b8c2869..7ecbfe543a 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -104,6 +104,14 @@ public abstract class Symbol implements Modifiers, Kinds {
}
public Symbol setInfo(Type info, int limit) {
+ assert !isConstructor()
+ || info instanceof Type.LazyType
+ || info == Type.ErrorType
+ || info instanceof Type.MethodType
+ || info instanceof Type.OverloadedType
+ || info instanceof Type.PolyType &&
+ ((Type.PolyType)info).result instanceof Type.MethodType
+ : "illegal type for " + this + ": " + info;
if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) {
if (infos == TypeIntervalList.EMPTY)
infos = new TypeIntervalList(TypeIntervalList.EMPTY);
@@ -748,7 +756,7 @@ public abstract class Symbol implements Modifiers, Kinds {
if ((flags & TRAIT) != 0)
return "trait";
else if ((flags & MODUL) != 0 && Global.instance.debug)
- return "module class";
+ return "object class";
else
return "class";
case TYPE:
@@ -756,7 +764,7 @@ public abstract class Symbol implements Modifiers, Kinds {
return "type";
case VAL:
if (isVariable()) return "variable";
- else if (isModule()) return "module";
+ else if (isModule()) return "object";
else if (isConstructor()) return "constructor";
else if (isInitializedMethod() &&
(Global.instance.debug || (flags & STABLE) == 0) )
@@ -775,7 +783,7 @@ public abstract class Symbol implements Modifiers, Kinds {
case ALIAS: return "type";
case VAL:
if (isVariable()) return "var";
- else if (isModule()) return "module";
+ else if (isModule()) return "object";
else if (isInitializedMethod()) return "def";
else return "val";
default: return "";
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index 571e12061a..d579ea9685 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -26,7 +26,9 @@ public class Type implements Modifiers, Kinds, TypeTags {
public case ThisType(Symbol sym);
- public case TypeRef(Type pre, Symbol sym, Type[] args);
+ public case TypeRef(Type pre, Symbol sym, Type[] args) {
+ assert pre.isLegalPrefix() || pre == ErrorType : pre + "#" + sym;
+ }
public case SingleType(Type pre, Symbol sym) {
assert this instanceof ExtSingleType;
@@ -80,11 +82,12 @@ public class Type implements Modifiers, Kinds, TypeTags {
public static final Type[] NO_ARRAY = new Type[0];
public static SingleType singleType(Type pre, Symbol sym) {
- if (pre.isStable() || pre == ErrorType)
+ if (pre.isStable() || pre == ErrorType) {
return new ExtSingleType(pre, sym);
- else
+ } else {
throw new Type.Error(
- "malformed type: " + pre + "." + sym.nameString() + ".type");
+ "malformed type: " + pre + "#" + sym.nameString() + ".type");
+ }
}
public static TypeRef appliedType(Type tycon, Type[] args) {
@@ -116,7 +119,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
SYNTHETIC | ABSTRACTCLASS);
res.tsym.setInfo(res);
res.tsym.constructor().setInfo(
- Type.PolyType(Symbol.EMPTY_ARRAY, Type.NoType));
+ Type.MethodType(Symbol.EMPTY_ARRAY, Type.NoType));
return res;
}
@@ -127,7 +130,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
return pre.memberInfo(sym);
else // todo: handle Java-style inner classes
throw new Type.Error(
- "malformed type: " + pre + "." + sym.nameString());
+ "malformed type: " + pre + "#" + sym.nameString());
}
static class ExtSingleType extends SingleType {
@@ -634,7 +637,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
Type pre1 = apply(pre);
Type[] args1 = map(args);
if (pre1 == pre && args1 == args) return tp;
- else return TypeRef(pre1, sym, args1);
+ else return typeRef(pre1, sym, args1);
case SingleType(Type pre, Symbol sym):
Type pre1 = apply(pre);
if (pre1 == pre) return tp;
@@ -866,7 +869,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
Type[] args1 = map(args);
typeArg = prevTypeArg;
if (prefix1 == prefix && args1 == args) return t;
- else return TypeRef(prefix1, sym1, args1);
+ else return typeRef(prefix1, sym1, args1);
}
case SingleType(Type prefix, Symbol sym):
@@ -1075,7 +1078,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
protected Type replacement(int i, Type fromtp) {
switch (fromtp) {
case TypeRef(Type pre, Symbol sym, Type[] args):
- return TypeRef(pre, to[i], args);
+ return typeRef(pre, to[i], args);
case SingleType(Type pre, Symbol sym):
return singleType(pre, to[i]);
default:
@@ -1822,7 +1825,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
if (args[j] == NoType)
args[j] = CovarType(lub(argss[j]));
}
- return TypeRef(pre, sym, args);
+ return typeRef(pre, sym, args);
}
/** The frontier of a closure C is the minimal set of types such that
@@ -2050,7 +2053,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
Type this1 = unbox();
if (this1 != this) return this1;
else if (args.length == 0) return this;
- else return TypeRef(pre, sym, Type.EMPTY_ARRAY);
+ else return typeRef(pre, sym, Type.EMPTY_ARRAY);
}
default: throw new ApplicationError();
@@ -2104,6 +2107,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
case ThisType(Symbol sym):
if (sym.isRoot()) return "<root>.this.type";
else if (this == localThisType) return "<local>.this.type";
+ else if (sym.isAnonymousClass()) return "this.type";
else {
Type this1 = (Global.instance.debug) ? this : expandModuleThis();
if (this1 == this) return sym.nameString() + ".this.type";
@@ -2195,7 +2199,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
else if (spre.endsWith(".type"))
return spre.substring(0, spre.length() - 4);
else
- return spre + "@";
+ return spre + "#";
}
}
diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java
index 8cc8e296d0..a6ae0a9083 100644
--- a/sources/scalac/symtab/classfile/AttributeParser.java
+++ b/sources/scalac/symtab/classfile/AttributeParser.java
@@ -253,7 +253,9 @@ public class AttributeParser implements ClassfileConstants {
if ((parser.c.flags & Modifiers.INTERFACE) != 0) {
parser.c.constructor().setInfo(
- Type.PolyType(smbls, constrtype), parser.phaseId);
+ Type.PolyType(
+ smbls, Type.MethodType(Symbol.EMPTY_ARRAY, constrtype)),
+ parser.phaseId);
//System.out.println("info = " + parser.c.constructor().info());//DEBUG
}
Symbol[] constrs;
@@ -269,13 +271,9 @@ public class AttributeParser implements ClassfileConstants {
switch (constrs[i].rawInfo()) {
case MethodType(Symbol[] vparams, _):
constrs[i].setInfo(
- Type.PolyType(smbls,
- Type.MethodType(
- vparams, constrtype)), parser.phaseId);
- break;
- case PolyType(_, _):
- constrs[i].setInfo(
- Type.PolyType(smbls, constrtype), parser.phaseId);
+ Type.PolyType(
+ smbls, Type.MethodType(vparams, constrtype)),
+ parser.phaseId);
break;
}
//System.out.println("*** constructor " + e.sym + ": " + e.sym.info());//DEBUG
diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java
index 69d95f79f0..a0d69c4bed 100644
--- a/sources/scalac/symtab/classfile/ClassfileParser.java
+++ b/sources/scalac/symtab/classfile/ClassfileParser.java
@@ -117,10 +117,9 @@ public class ClassfileParser implements ClassfileConstants {
assert constrs.length == 1;
c.constructor().setInfo(constrs[0].info(), phaseId);
} else {
- Type constrtype = ((c.flags & Modifiers.INTERFACE) != 0)
- ? Type.PolyType(Symbol.EMPTY_ARRAY, ctype)
- : Type.MethodType(new Symbol[]{Symbol.NONE}, ctype);
- c.constructor().setInfo(constrtype, phaseId);
+ Symbol[] cparams = ((c.flags & Modifiers.INTERFACE) != 0) ? Symbol.EMPTY_ARRAY
+ : new Symbol[]{Symbol.NONE};
+ c.constructor().setInfo(Type.MethodType(cparams, ctype), phaseId);
}
attrib.readAttributes(c, classType, CLASS_ATTR);
//System.out.println("dynamic class: " + c);
@@ -214,10 +213,7 @@ public class ClassfileParser implements ClassfileConstants {
}
switch (type) {
case MethodType(Symbol[] vparams, _):
- if (c == defs.OBJECT_CLASS)
- type = Type.PolyType(Symbol.EMPTY_ARRAY, ctype);
- else
- type = Type.MethodType(vparams, ctype);
+ type = Type.MethodType(vparams, ctype);
break;
default:
throw new ApplicationError();
diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java
index 6e69d191c3..14ee843677 100644
--- a/sources/scalac/transformer/AddConstructors.java
+++ b/sources/scalac/transformer/AddConstructors.java
@@ -139,7 +139,9 @@ public class AddConstructors extends Transformer {
getConstructor(fun.symbol()));
constrBody.add(gen.Apply(superConstr, transform(args)));
break;
- default: assert false;
+ default:
+ new scalac.ast.printer.TextTreePrinter().print(baseClasses[0]).println().end();
+ assert false;
}
}
diff --git a/sources/scalac/transformer/ExpandMixins.java b/sources/scalac/transformer/ExpandMixins.java
index 19984b4b61..9ce484ab12 100644
--- a/sources/scalac/transformer/ExpandMixins.java
+++ b/sources/scalac/transformer/ExpandMixins.java
@@ -345,9 +345,10 @@ public class ExpandMixins extends Transformer {
case Apply(Select(Tree qualifier, Name selector), Tree[] args): {
Tree fun = ((Tree.Apply)newTree).fun;
Symbol funOwnerSym = fun.symbol().owner();
- Symbol qualSym = qualifier.type.symbol();
+ Symbol qualSym = qualifier.type.symbol().moduleClass();
if (! (qualifier instanceof Tree.Super
|| qualSym.isSubClass(funOwnerSym))) {
+ global.log("inserting cast from " + qualSym + " to " + funOwnerSym);//debug
Type ownerTp = funOwnerSym.type();
Tree castQualifier =
gen.Apply(gen.TypeApply(gen.Select(qualifier, defs.AS),
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index da24b2ea86..ee545ac7d3 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -85,7 +85,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (sym.pos == Position.NOPOS) {
sym.setInfo(Type.ErrorType);
String kind;
- if (sym.name.isTermName()) kind = "module or method ";
+ if (sym.name.isTermName()) kind = "object or method ";
else if (sym.name.isTypeName()) kind = "class ";
else kind = "constructor ";
throw new Type.Error("file " + unit.source + " does not define public " +
@@ -213,7 +213,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
String decode(Name name) {
if (name.isTypeName()) return "type " + name;
else if (name.isConstrName()) return "constructor " + name;
- else return name.toString();
+ else return "value " + name.toString();
}
/** Is `sym' accessible as a member of tree `site' in current context?
@@ -318,6 +318,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if ((bsym.flags & INTERFACE) != 0)
error(constrs[0].pos, "superclass may not be a Java interface");
} else {
+ if ((bsym.flags & (JAVA | INTERFACE)) == JAVA)
+ error(constrs[i].pos, "Java class may not be used as mixin");
Type[] grandparents = parents[i].parents();
if (grandparents.length > 0 &&
!parents[0].isSubType(grandparents[0]))
@@ -421,17 +423,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
}
- /** Check that found type conforms to required one.
- */
- Type checkType(int pos, Type found, Type required) {
- if (found.isSubType(required)) return found;
- else {
- typeError(pos, found, required);
- explainTypes(found, required);
- return Type.ErrorType;
- }
- }
-
/** Check that type is eta-expandable (i.e. no `def' parameters)
*/
void checkEtaExpandable(int pos, Type tp) {
@@ -545,14 +536,21 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Tree checkStable(Tree tree) {
if (TreeInfo.isPureExpr(tree) || tree.type == Type.ErrorType) return tree;
//new TextTreePrinter().print(tree).end();//DEBUG
- //System.out.println(" " + tree.type);//DEBUG
+ //System.out.println(" " + tree.symbol() + ":" + tree.type);//DEBUG
return error(tree.pos, "stable identifier required");
}
- /** Check that (abstract) type can be instantiated.
+ /** Check that class can be instantiated.
*/
void checkInstantiatable(int pos, Type tp) {
- error(pos, tp.symbol() + " is abstract; cannot be instantiated");
+ Symbol clazz = tp.symbol();
+ if (clazz.kind == CLASS) {
+ if ((clazz.flags & ABSTRACTCLASS) != 0)
+ error(pos, clazz + " is abstract, so it cannot be instantiated");
+ else if (!tp.isSubType(tp.instanceType()))
+ error(pos, tp + " does not conform to its self-type " +
+ tp.instanceType() + ", so it cannot be instantiated");
+ }
}
/** Check all members of class `clazz' for overriding conditions.
@@ -851,9 +849,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// Definining Symbols -------------------------------------------------------
- /** Define symbol associated with `tree' using given `context'.
+ /** Define symbol associated with `tree' using given `unit' and `context'.
*/
- void defineSym(Tree tree, Unit unit, Infer infer, Context curcontext) {
+ void defineSym(Tree tree, Unit unit, Context curcontext) {
Unit savedUnit = this.unit;
this.unit = unit;
Context savedContext = this.context;
@@ -878,6 +876,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
pushContext(tree, sym.constructor(), new Scope(context.scope));
Symbol[] tparamSyms = enterParams(tparams);
Symbol[][] vparamSyms = enterParams(vparams);
+ if (vparamSyms.length == 0)
+ vparamSyms = new Symbol[][]{Symbol.EMPTY_ARRAY};
if ((mods & CASE) != 0 && vparams.length > 0)
templ.body = desugarize.addCaseElements(templ.body, vparams[0]);
@@ -891,7 +891,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
sym.constructor().flags |= INITIALIZED;
if (tpe != Tree.Empty)
- sym.setTypeOfThis(transform(tpe, TYPEmode).type);
+ sym.setTypeOfThis(new LazySelfType(tpe));
defineTemplate(templ, sym);
owntype = templ.type;
@@ -1001,7 +1001,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
void defineTemplate(Tree.Template templ, Symbol clazz) {
// attribute parent constructors
Tree[] constrs = transformConstrInvocations(
- templ.pos, templ.parents, true, Type.AnyType);
+ templ.pos, templ.parents, true);
Type[] parents = new Type[constrs.length];
for (int i = 0; i < parents.length; i++)
@@ -1068,6 +1068,21 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
reenterParams(vparams[i]);
}
+ /** Define self type of class or module `sym'
+ * associated with `tree' using given `unit' and `context'.
+ */
+ void defineSelfType(Symbol sym, Tree tree, Unit unit, Context curcontext) {
+ Unit savedUnit = this.unit;
+ this.unit = unit;
+ Context savedContext = this.context;
+ this.context = curcontext;
+
+ sym.setInfo(transform(tree, TYPEmode).type);
+
+ this.unit = savedUnit;
+ this.context= savedContext;
+ }
+
// Attribution and Transform -------------------------------------------------
/** Attribute an identifier consisting of a simple name or an outer reference.
@@ -1284,12 +1299,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
/** Attribute a sequence of constructor invocations.
*/
- Tree[] transformConstrInvocations(int pos, Tree[] constrs,
- boolean delayArgs, Type pt) {
+ Tree[] transformConstrInvocations(int pos, Tree[] constrs, boolean delayArgs) {
for (int i = 0; i < constrs.length; i++) {
pushContext(constrs[i], context.owner, context.scope);
context.delayArgs = delayArgs;
- constrs[i] = transform(constrs[i], CONSTRmode, pt);
+ constrs[i] = transform(constrs[i], CONSTRmode, Type.AnyType);
Symbol f = TreeInfo.methSymbol(constrs[i]);
if (f != null) {
Symbol c = f.primaryConstructorClass();
@@ -1306,7 +1320,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (global.debug) global.log("transforming " + owner);//debug
//System.out.println(owner.info());//DEBUG
Tree[] parents1 = transformConstrInvocations(
- templ.pos, templ.parents, false, Type.AnyType);
+ templ.pos, templ.parents, false);
if (owner.kind != ERROR) {
validateParentClasses(
templ.parents, owner.info().parents(), owner.typeOfThis());
@@ -1636,7 +1650,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
" does not conform to sequence " + clazz);
}
} else if (tree.type != Type.ErrorType) {
- error(tree.pos, tree.symbol() +
+ error(tree.pos, tree.type.symbol() +
" is neither a case class constructor nor a sequence class constructor");
}
}
@@ -1648,20 +1662,26 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
// check that other idents or selects are stable.
switch (tree) {
case Ident(Name name):
- if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0) {
- ((Ident)tree).name = name.toTypeName();
- return transform(tree, mode, pt);
- } else {
+ if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0)
+ return transform(
+ make.Apply(
+ tree.pos,
+ copy.Ident(tree, name.toTypeName()),
+ Tree.EMPTY_ARRAY),
+ mode, pt);
+ else
checkStable(tree);
- }
break;
- case Select(_, Name selector):
- if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0) {
- ((Select)tree).selector = selector.toTypeName();
- return transform(tree, mode, pt);
- } else {
+ case Select(Tree qual, Name name):
+ if (sym != null && isNullaryMethod(sym) && (sym.flags & CASE) != 0)
+ return transform(
+ make.Apply(
+ tree.pos,
+ copy.Select(tree, qual, name.toTypeName()),
+ Tree.EMPTY_ARRAY),
+ mode, pt);
+ else
checkStable(tree);
- }
}
}
} else if ((mode & EXPRmode) != 0) {
@@ -1700,9 +1720,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
}
- if (!(tree.type instanceof Type.PolyType))
- tree.type = checkType(tree.pos, tree.type, pt);
-
+ Type owntype = tree.type;
+ if ((mode & (CONSTRmode | FUNmode)) == (CONSTRmode))
+ owntype = owntype.instanceType();
+ if (!(owntype instanceof Type.PolyType || owntype.isSubType(pt))) {
+ typeError(tree.pos, owntype, pt);
+ explainTypes(owntype, pt);
+ tree.type = Type.ErrorType;
+ }
return tree;
}
//where
@@ -1757,6 +1782,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol sym = tree1.symbol();
if ((mode & FUNmode) == 0 && sym != null && sym.typeParams().length != 0)
return error(tree.pos, sym + " takes type parameters.");
+// else if (tree1.isType())
+// return gen.mkType(tree1.pos, tree1.type);
else
return tree1;
}
@@ -1807,12 +1834,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Tree.ValDef[][] vparams1 = transform(vparams);
Tree tpe1 = transform(tpe);
Tree.Template templ1 = transformTemplate(templ, sym);
-
- if ((sym.flags & ABSTRACTCLASS) == 0 &&
- !sym.type().isSubType(sym.typeOfThis()))
- error(sym.pos, sym +
- " needs to be abstract; it does not conform to its self-type " +
- sym.typeOfThis());
popContext();
return copy.ClassDef(tree, mods, name, tparams1, vparams1, tpe1, templ1)
.setType(definitions.UNIT_TYPE);
@@ -1954,8 +1975,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
copy.Template(templ, new Tree[]{parent1}, body)
.setType(parent1.type).setSymbol(Symbol.NONE);
Type owntype = parent1.type;
- if ((owntype.symbol().constructor().flags & ABSTRACTCLASS) != 0)
- checkInstantiatable(tree.pos, owntype);
+ checkInstantiatable(tree.pos, owntype);
return copy.New(tree, templ1)
.setType(owntype.instanceType());
} else {
@@ -2078,7 +2098,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
switch (enclClazz.info()) {
case CompoundType(Type[] parents, _):
return copy.Super(tree, tpe1)
- .setType(Type.compoundType(parents, Scope.EMPTY));
+ .setType(Type.compoundType(parents, Scope.EMPTY).symbol().thisType());
case ErrorType:
return tree.setType(Type.ErrorType);
default:
@@ -2086,7 +2106,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
} else {
return error(tree.pos,
- "super can be used only in a class, module, or template");
+ "super can be used only in a class, object, or template");
}
case This(Tree qual):
@@ -2099,16 +2119,16 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
} else {
return error(
tree.pos, tree +
- " can be used only in a class, module, or template");
+ " can be used only in a class, object, or template");
}
} else {
Tree qual1 = transform(qual, TYPEmode | FUNmode);
- clazz = qual1.symbol();
+ clazz = qual1.type.symbol();
if (clazz.kind == CLASS) {
Context clazzContext = context.outerContext(clazz);
if (clazzContext != Context.NONE) {
if (!(qual1 instanceof Tree.Ident))
- qual1 = gen.Ident(tree.pos, qual1.symbol());
+ qual1 = gen.Ident(tree.pos, clazz);
tree1 = copy.This(tree, qual1);
} else {
return error(qual.pos,
@@ -2245,20 +2265,18 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
class LazyTreeType extends Type.LazyType {
Tree tree;
Unit u;
- Infer i;
Context c;
LazyTreeType(Tree tree) {
this.tree = tree;
this.u = unit;
- this.i = infer;
this.c = context;
}
public void complete(Symbol sym) {
//System.out.println("completing " + sym);//DEBUG
//if (sym.isConstructor()) sym.constructorClass().initialize();
//else if (sym.isModule()) sym.moduleClass().initialize();
- defineSym(tree, u, i, c);
+ defineSym(tree, u, c);
}
}
@@ -2270,7 +2288,35 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
super(tree);
}
public void complete(Symbol sym) {
- sym.setInfo(tree.symbol().constructor().type().instanceType());
+ Type constrtype = tree.symbol().constructor().type().instanceType();
+ switch (tree) {
+ case ClassDef(_, _, _, ValDef[][] vparams, _, _):
+ if (vparams.length == 0) {
+ constrtype = removeMethod(constrtype);
+ }
+ }
+ sym.setInfo(constrtype);
+ }
+ private Type removeMethod(Type tp) {
+ switch (tp) {
+ case MethodType(_, Type restp):
+ return restp;
+ case PolyType(Symbol[] tparams, Type restp):
+ return Type.PolyType(tparams, removeMethod(restp));
+ default:
+ return tp;
+ }
+ }
+ }
+
+ /** A lazy type for self types
+ */
+ class LazySelfType extends LazyTreeType {
+ LazySelfType(Tree tree) {
+ super(tree);
+ }
+ public void complete(Symbol sym) {
+ defineSelfType(sym, tree, u, c);
}
}
}
diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java
index ae7dd9b970..91faf4adb6 100644
--- a/sources/scalac/typechecker/DeSugarize.java
+++ b/sources/scalac/typechecker/DeSugarize.java
@@ -164,7 +164,7 @@ public class DeSugarize implements Kinds, Modifiers {
}
/** (x_1: T_1, ..., x_n: T_N) => e ==>
- * new scala.Function[T_1, ..., T_N, T] with {
+ * new new scala.Object() with scala.Function[T_1, ..., T_N, T]() {
* def apply(x_1: T_1, ..., x_N: T_N): T = e
* }
* where T = `restpe'
@@ -182,14 +182,23 @@ public class DeSugarize implements Kinds, Modifiers {
for (int i = 0; i < length; i++)
argtpes[i] = vparams[i].tpe;
argtpes[vparams.length] = restpe;
- Tree objConstr = make.Select(tree.pos,
- make.Ident(tree.pos, Names.scala),
- Names.Object.toConstrName());
- Tree constr = make.TypeApply(tree.pos,
- make.Select(tree.pos,
- make.Ident(tree.pos, Names.scala),
- Name.fromString("Function" + length).toConstrName()),
- argtpes);
+ Tree objConstr = make.Apply(
+ tree.pos,
+ make.Select(
+ tree.pos,
+ make.Ident(tree.pos, Names.scala),
+ Names.Object.toConstrName()),
+ Tree.EMPTY_ARRAY);
+ Tree constr = make.Apply(
+ tree.pos,
+ make.TypeApply(
+ tree.pos,
+ make.Select(
+ tree.pos,
+ make.Ident(tree.pos, Names.scala),
+ Name.fromString("Function" + length).toConstrName()),
+ argtpes),
+ Tree.EMPTY_ARRAY);
Tree applyDef = make.DefDef(
tree.pos, 0, Names.apply,
@@ -225,7 +234,7 @@ public class DeSugarize implements Kinds, Modifiers {
}
/** Cases, Argtpe, Restpe ==>
- * (new scala.PartialFunction[Argtpe, Restpe] {
+ * (new scala.PartialFunction[Argtpe, Restpe]() {
* def apply(x: Argtpe): Restpe = x match {Cases}
* def isDefinedAt(x: Argtpe): scala.Boolean = x match {Cases'}
* }: scala.PartialFunction[Argtpe, +Restpe])
@@ -236,12 +245,18 @@ public class DeSugarize implements Kinds, Modifiers {
* Restpe = targs[1]
*/
public Tree partialFunction(Tree tree, Type pattpe, Type restpe) {
- Tree constr = make.TypeApply(tree.pos,
- make.Select(tree.pos,
- make.Ident(tree.pos, Names.scala),
- Names.PartialFunction.toConstrName()),
- new Tree[]{gen.mkType(tree.pos, pattpe),
- gen.mkType(tree.pos, restpe)});
+ Tree constr =
+ make.Apply(
+ tree.pos,
+ make.TypeApply(
+ tree.pos,
+ make.Select(
+ tree.pos,
+ make.Ident(tree.pos, Names.scala),
+ Names.PartialFunction.toConstrName()),
+ new Tree[]{gen.mkType(tree.pos, pattpe),
+ gen.mkType(tree.pos, restpe)}),
+ Tree.EMPTY_ARRAY);
Name x = getvar();
ValDef param = (ValDef) make.ValDef(
tree.pos, PARAM, x, gen.mkType(tree.pos, pattpe), Tree.Empty);
@@ -547,9 +562,17 @@ public class DeSugarize implements Kinds, Modifiers {
public Tree toConstructor(Tree tree, Symbol constr) {
switch (tree) {
case Apply(Tree fn, Tree[] args):
- return copy.Apply(tree, toConstructor(fn, constr), args);
+ return toConstructor1(tree, constr);
+ default:
+ return make.Apply(tree.pos, toConstructor1(tree, constr), Tree.EMPTY_ARRAY);
+ }
+ }
+ private Tree toConstructor1(Tree tree, Symbol constr) {
+ switch (tree) {
+ case Apply(Tree fn, Tree[] args):
+ return copy.Apply(tree, toConstructor1(fn, constr), args);
case TypeApply(Tree fn, Tree[] args):
- return copy.TypeApply(tree, toConstructor(fn, constr), args);
+ return copy.TypeApply(tree, toConstructor1(fn, constr), args);
case Ident(Name name):
return copy.Ident(tree, constr.name).setSymbol(constr);
case Select(Tree qual, Name name):
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index af02095030..74ab754ae0 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -3,16 +3,6 @@
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
\* */
-
-// $Id$
-
-// todo: Any cannot be inherited.
-// todo: check that only stable defs override stable defs
-// todo: admit vardefs w/o rhs
-// ClassTemplate ::= [extends Constr {with Constr}]
-// [with `(' TemplateStatSeq `)']
-// todo: pretty printer prints wrong precedence for `new' (-> lambdalift.scala).
-
package scalac.typechecker;
import java.util.HashMap;
@@ -126,6 +116,18 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
return stats;
}
+ public Tree nullTree(int pos, Type tp) {
+ return gen.TypeApply(
+ gen.Ident(pos, global.definitions.NULL),
+ new Tree[]{gen.mkType(pos, tp)});
+ }
+
+ private boolean isGlobalModule(Symbol sym) {
+ return
+ sym.isModule() &&
+ (sym.owner().isPackage() || isGlobalModule(sym.owner().module()));
+ }
+
/** The main checking functions
*/
public Tree[] transformStat(Tree tree, int index) {
@@ -133,38 +135,55 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
switch (tree) {
case ModuleDef(int mods, Name name, Tree tpe, Tree.Template templ):
Symbol sym = tree.symbol();
- // local modules are not yet supported but the interpreter
- // accepts modules at the console level
- if (sym.isLocal()) unit.error("local modules are not yet supported");
-
- Tree[] result = new Tree[2];
- result[0] = make.ClassDef(
+ Tree cdef = make.ClassDef(
tree.pos,
mods | FINAL | MODUL,
name.toTypeName(),
- new Tree.TypeDef[0],
- new Tree.ValDef[][]{{}},
+ Tree.ExtTypeDef.EMPTY_ARRAY,
+ Tree.ExtValDef.EMPTY_ARRAY_ARRAY,
Tree.Empty,
templ)
.setSymbol(sym.moduleClass()).setType(tree.type);
- result[1] = make.ValDef(
+ Tree alloc = gen.New(
tree.pos,
- mods | MODUL,
- name,
- (tpe == Tree.Empty) ? gen.mkType(tree.pos, sym.type()) : tpe,
- gen.New(
- tree.pos,
- sym.type().prefix(),
- sym.moduleClass(),
- Tree.EMPTY_ARRAY))
- .setSymbol(sym).setType(tree.type);
+ sym.type().prefix(),
+ sym.moduleClass(),
+ Tree.EMPTY_ARRAY);
+ Tree[] result;
+ if (isGlobalModule(sym)) {
+ Tree vdef = gen.ValDef(sym, alloc);
+ result = new Tree[]{cdef, vdef};
+ } else {
+ // var m$: T = null[T];
+ Name varname = Name.fromString(name + "$");
+ Symbol mvar = new TermSymbol(
+ tree.pos, varname, sym.owner(), PRIVATE | MUTABLE | SYNTHETIC)
+ .setInfo(sym.type());
+ Tree vdef = gen.ValDef(mvar, nullTree(tree.pos, sym.type()));
+
+ // { if (m$ == null[T]) m$ = new m$class; m$ }
+ Tree body = gen.Block(new Tree[]{
+ gen.If(
+ gen.Apply(
+ gen.Select(gen.mkRef(tree.pos, mvar), global.definitions.EQEQ),
+ new Tree[]{nullTree(tree.pos, sym.type())}),
+ gen.Assign(gen.mkRef(tree.pos, mvar), alloc),
+ gen.Block(tree.pos, Tree.EMPTY_ARRAY)),
+ gen.mkRef(tree.pos, mvar)});
+
+ // def m: T = { if (m$ == null[T]) m$ = new m$class; m$ }
+ sym.updateInfo(Type.PolyType(Symbol.EMPTY_ARRAY, sym.type()));
+ sym.flags |= STABLE;
+ Tree ddef = gen.DefDef(sym, body);
+ result = new Tree[]{cdef, vdef, ddef};
+ }
return transform(result);
case ValDef(int mods, Name name, Tree tpe, Tree rhs):
Symbol sym = tree.symbol();
resultTree = transform(tree);
//todo: handle variables
- if (sym.isLocal() && index <= maxindex[level]) {
+ if (sym.isLocal() && !sym.isModule() && index <= maxindex[level]) {
if (Global.instance.debug)
System.out.println(refsym[level] + ":" + refsym[level].type());
unit.error(
@@ -180,6 +199,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
}
public Tree transform(Tree tree) {
+ Tree tree1;
switch (tree) {
case Template(Tree[] bases, Tree[] body):
Tree[] bases1 = transform(bases);
@@ -188,6 +208,10 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
case Block(Tree[] stats):
Tree[] stats1 = transformStats(stats);
return copy.Block(tree, stats1);
+ case This(_):
+ return tree;
+ case PackageDef(Tree pkg, Template packaged):
+ return copy.PackageDef(tree, pkg, super.transform(packaged));
case Ident(Name name):
Scope.Entry e = scopes[level].lookupEntry(name);
Symbol sym = tree.symbol();
@@ -202,10 +226,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
maxindex[i] = symindex;
}
}
- return tree;
+ tree1 = tree;
+ break;
default:
- return super.transform(tree);
+ tree1 = super.transform(tree);
}
+ if (tree1.isType() && !tree1.isMissing())
+ tree1 = gen.mkType(tree1.pos, tree1.type);
+ return tree1;
}
}