diff options
author | Martin Odersky <odersky@gmail.com> | 2005-06-15 16:05:25 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-06-15 16:05:25 +0000 |
commit | 7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39 (patch) | |
tree | 7577a98bbeb2e40dda69e562ee1e95535793a071 /sources | |
parent | 1ec9209a8d92e7e25dc40f3624af44451da260b7 (diff) | |
download | scala-7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39.tar.gz scala-7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39.tar.bz2 scala-7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39.zip |
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/tools/nsc/CompilationUnits.scala | 1 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/Global.scala | 42 | ||||
-rw-r--r-- | sources/scala/tools/nsc/SubComponent.scala | 8 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/TreePrinters.scala | 19 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/Trees.scala | 38 | ||||
-rw-r--r-- | sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Scopes.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Types.scala | 1 | ||||
-rw-r--r-- | sources/scala/tools/nsc/transform/Transform.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/transform/UnCurry.scala | 136 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Namers.scala | 3 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/RefChecks.scala | 3 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 66 |
13 files changed, 213 insertions, 110 deletions
diff --git a/sources/scala/tools/nsc/CompilationUnits.scala b/sources/scala/tools/nsc/CompilationUnits.scala index 3cf6ab9c8b..c3320d22d9 100644 --- a/sources/scala/tools/nsc/CompilationUnits.scala +++ b/sources/scala/tools/nsc/CompilationUnits.scala @@ -26,6 +26,7 @@ abstract class CompilationUnits: Global { def error(pos: int, msg: String) = reporter.error(position(pos), msg); def warning(pos: int, msg: String) = reporter.warning(position(pos), msg); override def toString() = source.toString(); + } } diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala index f51dda9d2b..c065cc60eb 100755 --- a/sources/scala/tools/nsc/Global.scala +++ b/sources/scala/tools/nsc/Global.scala @@ -121,6 +121,15 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable // Phases ------------------------------------------------------------ + abstract class StdPhase(prev: Phase) extends Phase(prev) { + def run: unit = units foreach applyPhase; + def apply(unit: CompilationUnit): unit; + def applyPhase(unit: CompilationUnit): unit = { + if (settings.debug.value) inform("[running phase " + name + " on " + unit + "]"); + apply(unit) + } + } + object syntaxAnalyzer extends SyntaxAnalyzer { val global: Global.this.type = Global.this @@ -156,12 +165,10 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable } val refchecksPhase = new refchecks.Phase(picklePhase); -/* object uncurry extends UnCurry { val global: Global.this.type = Global.this; } - val refchecksPhase = new uncurry.Phase(refchecksPhase); -*/ + val uncurryPhase = new uncurry.Phase(refchecksPhase); //object transmatcher extends TransMatcher { // val global: Global.this.type = Global.this; @@ -174,7 +181,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable object sampleTransform extends SampleTransform { val global: Global.this.type = Global.this; } - val samplePhase = new sampleTransform.Phase(refchecksPhase); + val samplePhase = new sampleTransform.Phase(uncurryPhase); //val transMatchPhase = new transmatcher.TransMatchPhase(picklePhase); /* @@ -213,6 +220,8 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable /** A map from compiled top-level symbols to their picklers */ val symData = new HashMap[Symbol, PickleBuffer]; + var globalPhase: Phase = NoPhase; + def compileSources(sources: List[SourceFile]): unit = { val startTime = System.currentTimeMillis(); unitbuf.clear; @@ -223,16 +232,17 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable for (val source <- sources) addUnit(new CompilationUnit(source)); - phase = NoPhase.next; - while (phase != terminalPhase && reporter.errors() == 0) { - if (!(settings.skip contains phase.name)) { + globalPhase = NoPhase.next; + while (globalPhase != terminalPhase && reporter.errors() == 0) { + if (!(settings.skip contains globalPhase.name)) { val startTime = System.currentTimeMillis(); - phase.run; - if (settings.print contains phase.name) treePrinter.printAll(); - informTime(phase.description, startTime); + phase = globalPhase; + globalPhase.run; + if (settings.print contains globalPhase.name) treePrinter.printAll(); + informTime(globalPhase.description, startTime); } - phase = if (settings.stop contains phase.name) terminalPhase else phase.next; - if (settings.check contains phase.name) checker.checkTrees; + globalPhase = if (settings.stop contains globalPhase.name) terminalPhase else globalPhase.next; + if (settings.check contains globalPhase.name) checker.checkTrees; } if (settings.Xshowcls.value != "") showDef(newTermName(settings.Xshowcls.value), false); if (settings.Xshowobj.value != "") showDef(newTermName(settings.Xshowobj.value), true); @@ -262,8 +272,12 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable else if (!(fileset contains file)) { val unit = new CompilationUnit(getSourceFile(file)); addUnit(unit); - atPhase(parserPhase) { parserPhase(unit) } - atPhase(namerPhase) { namerPhase(unit) } + var localPhase = parserPhase.asInstanceOf[StdPhase]; + while (localPhase.id < globalPhase.id || localPhase.id <= namerPhase.id) { + if (!(settings.skip contains localPhase.name)) + atPhase(localPhase)(localPhase.applyPhase(unit)); + localPhase = localPhase.next.asInstanceOf[StdPhase]; + } } def compileFiles(files: List[AbstractFile]): unit = diff --git a/sources/scala/tools/nsc/SubComponent.scala b/sources/scala/tools/nsc/SubComponent.scala index dbec8b8f93..9bed9fc07e 100644 --- a/sources/scala/tools/nsc/SubComponent.scala +++ b/sources/scala/tools/nsc/SubComponent.scala @@ -11,13 +11,5 @@ abstract class SubComponent { val global: Global; - abstract class StdPhase(prev: Phase) extends Phase(prev) { - def run: unit = - for (val unit <- global.units) { - if (global.settings.debug.value) System.out.println("[running phase " + name + " on " + unit + "]");//debug - apply(unit); - } - def apply(unit: global.CompilationUnit): unit; - } } diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala index ab51837d21..d04c658778 100644 --- a/sources/scala/tools/nsc/ast/TreePrinters.scala +++ b/sources/scala/tools/nsc/ast/TreePrinters.scala @@ -88,7 +88,7 @@ abstract class TreePrinters { def print(str: String): unit = out.print(str); def print(name: Name): unit = print(name.toString()); - def print(tree: Tree): unit = { + def printRaw(tree: Tree): unit = { tree match { case EmptyTree => print("<empty>"); @@ -170,6 +170,9 @@ abstract class TreePrinters { case Bind(name, t) => print("("); print(symName(tree, name)); print(" @ "); print(t); print(")"); + case SeqTerm(trees) => + printRow(trees, "[", ", ", "]") + case Function(vparams, body) => print("("); printValueParams(vparams); print(" => "); print(body); print(")") @@ -255,6 +258,20 @@ abstract class TreePrinters { } } + def print(tree: Tree): unit = + printRaw( + if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.hasFlag(INITIALIZED)) { + tree match { + case ClassDef(_, _, _, _, impl) => ClassDef(tree.symbol, impl) + case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl) + case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs) + case DefDef(_, _, _, _, _, rhs) => DefDef(tree.symbol, vparamss => rhs) + case AbsTypeDef(_, _, _, _) => AbsTypeDef(tree.symbol) + case AliasTypeDef(_, _, _, rhs) => AliasTypeDef(tree.symbol, rhs) + case _ => tree + } + } else tree); + def print(unit: CompilationUnit): unit = { print("// Scala source: " + unit.source + "\n"); if (unit.body != null) { diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala index d207a0352d..bde6629010 100644 --- a/sources/scala/tools/nsc/ast/Trees.scala +++ b/sources/scala/tools/nsc/ast/Trees.scala @@ -128,10 +128,17 @@ abstract class Trees: Global { case class ModuleDef(mods: int, name: Name, impl: Template) extends DefTree; + def ModuleDef(sym: Symbol, impl: Template): ModuleDef = + posAssigner.atPos(sym.pos) { + atPhase(phase.next) { + ModuleDef(flags2mods(sym.flags), sym.name, impl) + } + } + /** Value definition */ case class ValDef(mods: int, name: Name, tpt: Tree, rhs: Tree) extends DefTree { - assert(tpt.isType); assert(rhs.isTerm) + assert(tpt.isType, tpt); assert(rhs.isTerm, rhs) } def ValDef(sym: Symbol, rhs: Tree): ValDef = @@ -262,12 +269,7 @@ abstract class Trees: Global { /** casedef shorthand */ def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body); - /** Sequence of expression/patterns (comma separated expressions), - * in patterns, eliminated by TransMatch - * in expressions, seq constructors that need to be translated in backend, - * ideally like this: Sequence(t1,...,tn) = Vector({t1,...,tn}), - * where { ... } is an array. - */ + /** Sequence of patterns (comma separated expressions), eliminated by TransMatch */ case class Sequence(trees: List[Tree]) extends TermTree; @@ -285,6 +287,13 @@ abstract class Trees: Global { case class Bind(name: Name, body: Tree) extends DefTree; + /** Sequence of expressions, needs to be translated in backend, + * ideally like this: SeqTerm(t1,...,tn) = Vector({t1,...,tn}), + * where { ... } is an array. + */ + case class SeqTerm(trees: List[Tree]) + extends TermTree; + /** Anonymous function, eliminated by analyzer */ case class Function(vparams: List[ValDef], body: Tree) extends TermTree; @@ -441,6 +450,7 @@ abstract class Trees: Global { case Alternative(trees) => (eliminated by transmatch) case Star(elem) => (eliminated by transmatch) case Bind(name, body) => (eliminated by transmatch) + case SeqTerm(trees) => case Function(vparams, body) => (eliminated by typecheck) case Assign(lhs, rhs) => case If(cond, thenp, elsep) => @@ -483,6 +493,7 @@ abstract class Trees: Global { def Alternative(tree: Tree, trees: List[Tree]): Alternative; def Star(tree: Tree, elem: Tree): Star; def Bind(tree: Tree, name: Name, body: Tree): Bind; + def SeqTerm(tree: Tree, trees: List[Tree]): SeqTerm; def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function; def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign; def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If; @@ -543,6 +554,8 @@ abstract class Trees: Global { new Star(elem).copyAttrs(tree); def Bind(tree: Tree, name: Name, body: Tree) = new Bind(name, body).copyAttrs(tree); + def SeqTerm(tree: Tree, trees: List[Tree]) = + new SeqTerm(trees).copyAttrs(tree); def Function(tree: Tree, vparams: List[ValDef], body: Tree) = new Function(vparams, body).copyAttrs(tree); def Assign(tree: Tree, lhs: Tree, rhs: Tree) = @@ -679,6 +692,11 @@ abstract class Trees: Global { if ((name0 == name) && (body0 == body)) => t case _ => copy.Bind(tree, name, body) } + def SeqTerm(tree: Tree, trees: List[Tree]) = tree match { + case t @ SeqTerm(trees0) + if ((trees0 == trees)) => t + case _ => copy.SeqTerm(tree, trees) + } def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match { case t @ Function(vparams0, body0) if ((vparams0 == vparams) && (body0 == body)) => t @@ -842,6 +860,8 @@ abstract class Trees: Global { copy.Star(tree, transform(elem)) case Bind(name, body) => copy.Bind(tree, name, transform(body)) + case SeqTerm(trees) => + copy.SeqTerm(tree, transformTrees(trees)) case Function(vparams, body) => copy.Function(tree, transformValDefs(vparams), transform(body)) case Assign(lhs, rhs) => @@ -968,6 +988,8 @@ abstract class Trees: Global { traverse(elem) case Bind(name, body) => traverse(body) + case SeqTerm(trees) => + traverseTrees(trees) case Function(vparams, body) => traverseTrees(vparams); traverse(body) case Assign(lhs, rhs) => @@ -1066,7 +1088,5 @@ abstract class Trees: Global { tree } } - - } diff --git a/sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala index 9d6395b48c..c0e06262dc 100644 --- a/sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala +++ b/sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.ast.parser; /** An nsc sub-component. */ abstract class SyntaxAnalyzer extends SubComponent with Parsers with Scanners { - class ParserPhase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) { + class ParserPhase(prev: scala.tools.nsc.Phase) extends global.StdPhase(prev) { def name = "parser"; def apply(unit: global.CompilationUnit): unit = { global.informProgress("parsing " + unit); diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala index e606d5370b..58f82382be 100755 --- a/sources/scala/tools/nsc/symtab/Scopes.scala +++ b/sources/scala/tools/nsc/symtab/Scopes.scala @@ -60,10 +60,12 @@ abstract class Scopes: SymbolTable { def this(base: Scope) = { this(base.elems); +/* if (base.hashtable != null) { this.hashtable = new Array[ScopeEntry](HASHSIZE); System.arraycopy(base.hashtable, 0, this.hashtable, 0, HASHSIZE); } +*/ nestinglevel = base.nestinglevel + 1 } diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index 8a16b3a2c1..f0b46afdc2 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -572,6 +572,7 @@ abstract class Types: SymbolTable { if (parents.isEmpty) this else parents.head.erasure; override def toString(): String = + "<" + symbol.toString() + ">" + //debug parents.mkString("", " with ", "") + (if (settings.debug.value || parents.isEmpty || decls.elems != null) decls.mkString("{", "; ", "}") else "") diff --git a/sources/scala/tools/nsc/transform/Transform.scala b/sources/scala/tools/nsc/transform/Transform.scala index 886ccf931f..bac2825028 100644 --- a/sources/scala/tools/nsc/transform/Transform.scala +++ b/sources/scala/tools/nsc/transform/Transform.scala @@ -13,7 +13,7 @@ abstract class Transform extends SubComponent { protected val phaseName: String; protected def newTransformer(unit: global.CompilationUnit): global.Transformer; - class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) { + class Phase(prev: scala.tools.nsc.Phase) extends global.StdPhase(prev) { def name: String = phaseName; def apply(unit: global.CompilationUnit): unit = unit.body = newTransformer(unit).transform(unit.body); diff --git a/sources/scala/tools/nsc/transform/UnCurry.scala b/sources/scala/tools/nsc/transform/UnCurry.scala index f1bc9027f4..069958c07f 100755 --- a/sources/scala/tools/nsc/transform/UnCurry.scala +++ b/sources/scala/tools/nsc/transform/UnCurry.scala @@ -56,76 +56,98 @@ abstract class UnCurry extends InfoTransform { /** - return symbol's transformed type, * - if symbol is a def parameter with transformed type T, return () => T */ - def transformInfo(sym: Symbol, tp: Type): Type = uncurry(tp); + def transformInfo(sym: Symbol, tp: Type): Type = if (sym.isType) tp else uncurry(tp); class UnCurryTransformer(unit: CompilationUnit) extends Transformer { private var inPattern = false; - override def transform(tree: Tree): Tree = { - def transformArgs(args: List[Tree], formals: List[Type]) = { - if (formals.isEmpty) { - assert(args.isEmpty); List() - } else { - def mkSequence(args: List[Tree], pt: Type): Tree = typed { atPos(tree.pos) { - if (inPattern) Sequence(args) setType pt - else Apply(gen.mkRef(SeqFactory), args) - }} - val args1 = - formals.last match { - case TypeRef(pre, sym, List(pt)) if (sym == RepeatedParamClass) => - if (args.isEmpty) List(mkSequence(args, pt)) - else { - val suffix = args.last match { - case Typed(arg, Ident(name)) if name == nme.WILDCARD_STAR.toTypeName => - arg setType seqType(arg.tpe) - case _ => - mkSequence(args.drop(formals.length - 1), pt) - } - args.take(formals.length - 1) ::: List(suffix) + override def transform(tree: Tree): Tree = postTransform(mainTransform(tree)); + + /* Is tree a reference `x' to a call by name parameter that neeeds to be converted to + * x.apply()? Note that this is not the case if `x' is used as an argument to another + * call by name parameter. + */ + def isByNameRef(tree: Tree): boolean = + tree.isTerm && tree.hasSymbol && + tree.symbol.tpe.symbol == ByNameParamClass && tree.tpe == tree.symbol.tpe.typeArgs.head; + + /** Uncurry a type of a tree node. + * This function is sensitive to whether or not we are in a pattern -- when in a pattern + * additional parameter sections of a case class are skipped. + */ + def uncurryTreeType(tp: Type): Type = tp match { + case MethodType(formals, MethodType(formals1, restpe)) if (inPattern) => + uncurryTreeType(MethodType(formals, restpe)) + case _ => + uncurry(tp) + } + + def transformArgs(pos: int, args: List[Tree], formals: List[Type]) = { + if (formals.isEmpty) { + assert(args.isEmpty); List() + } else { + val args1 = + formals.last match { + case TypeRef(pre, sym, List(elempt)) if (sym == RepeatedParamClass) => + def mkSequence(args: List[Tree]) = atPos(pos)(SeqTerm(args) setType formals.last); + if (args.isEmpty) List(mkSequence(args)) + else { + val suffix = args.last match { + case Typed(arg, Ident(name)) if name == nme.WILDCARD_STAR.toTypeName => + arg setType seqType(arg.tpe) + case _ => + mkSequence(args.drop(formals.length - 1)) } - case _ => args - } - List.map2(formals, args1) ((formal, arg) => - if (formal.symbol == ByNameParamClass) - arg.tpe match { - case TypeRef(pre, sym, List(targ)) if (sym == ByNameParamClass) => - arg setType functionType(List(), targ) - case _ => - typed(Function(List(), arg) setPos arg.pos) + args.take(formals.length - 1) ::: List(suffix) } - else arg) - } + case _ => args + } + List.map2(formals, args1) ((formal, arg) => + if (formal.symbol != ByNameParamClass) arg + else if (isByNameRef(arg)) arg setType functionType(List(), arg.tpe) + else typed(Function(List(), arg) setPos arg.pos)) } - val prevtpe = tree.tpe; - var result = tree match { - case Apply(fn, args) => - copy.Apply(tree, super.transform(fn), - super.transformTrees(transformArgs(args, fn.tpe.paramTypes))) - case CaseDef(pat, guard, body) => - inPattern = true; - val pat1 = super.transform(pat); - inPattern = false; - copy.CaseDef(tree, pat1, super.transform(guard), super.transform(body)) - case _ => - super.transform(tree) - } setType uncurry(tree.tpe); - result match { + } + + def mainTransform(tree: Tree): Tree = (tree match { + case Apply(fn, args) => + val formals = fn.tpe.paramTypes; + copy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, args, formals))) + case CaseDef(pat, guard, body) => + inPattern = true; + val pat1 = transform(pat); + inPattern = false; + copy.CaseDef(tree, pat1, transform(guard), transform(body)) + case _ => + val tree1 = super.transform(tree); + if (isByNameRef(tree1)) + typed(atPos(tree1.pos)( + Apply(Select(tree1 setType functionType(List(), tree1.tpe), nme.apply), List()))) + else tree1; + }) setType uncurryTreeType(tree.tpe); + + def postTransform(tree: Tree): Tree = atPhase(phase.next) { + def applyUnary(tree: Tree): Tree = + if ((tree.symbol.tpe.isInstanceOf[MethodType] || tree.symbol.tpe.isInstanceOf[PolyType]) && + (!tree.tpe.isInstanceOf[PolyType] || tree.tpe.typeParams.isEmpty)) { + if (!tree.tpe.isInstanceOf[MethodType]) tree.tpe = MethodType(List(), tree.tpe); + atPos(tree.pos)(Apply(tree, List()) setType tree.tpe.resultType) + } else tree; + tree match { case Apply(Apply(fn, args), args1) => - result = copy.Apply(result, fn, args ::: args1) + copy.Apply(tree, fn, args ::: args1) case Ident(name) => - if (name == nme.WILDCARD_STAR.toTypeName) + if (name == nme.WILDCARD_STAR.toTypeName) unit.error(tree.pos, " argument does not correspond to `*'-parameter"); - else if (prevtpe.symbol == ByNameParamClass) - result = typed(atPos(result.pos)(Select(result, nme.apply))) + applyUnary(tree); + case Select(_, _) => + applyUnary(tree) + case TypeApply(_, _) => + applyUnary(tree) case _ => + tree } - result.tpe match { - case MethodType(List(), restpe) => - if (!prevtpe.isInstanceOf[MethodType]) - result = typed(atPos(result.pos)(Apply(result, List()))) - } - result } } } diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index 3c553ad48c..4b1a2ec39f 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -116,7 +116,7 @@ trait Namers: Analyzer { def enterSym(tree: Tree): Namer = { def finishWith(tparams: List[AbsTypeDef]): unit = { - if (settings.debug.value) log("entered " + tree.symbol + " in " + context.owner); + if (settings.debug.value) log("entered " + tree.symbol + " in " + context.owner + ", scope-id = " + context.scope.hashCode()); var ltype: LazyType = innerNamer.typeCompleter(tree); if (!tparams.isEmpty) { new Namer(context.makeNewScope(tree, tree.symbol)).enterSyms(tparams); @@ -269,6 +269,7 @@ trait Namers: Analyzer { val clazz = context.owner; val parents = typer.parentTypes(templ) map (.tpe); val decls = new Scope(); + log("members of " + clazz + "=" + decls.hashCode());//debug new Namer(context.make(templ, clazz, decls)).enterSyms(templ.body); ClassInfoType(parents, decls, clazz) } diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala index 344e606b3e..9f8ec0aa2f 100755 --- a/sources/scala/tools/nsc/typechecker/RefChecks.scala +++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala @@ -512,6 +512,9 @@ abstract class RefChecks extends Transform { } List(tree1) + case Import(_, _) => + List() + case _ => List(transform(tree)) } diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 027956badc..95e67bba77 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -198,8 +198,22 @@ abstract class Typers: Analyzer { else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !sym.isValue) // (2) errorTree(tree, sym.toString() + " is not a value"); else if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass && - (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || sym.isModule)) { // (3) - tree.setType(singleType(pre, sym)) + (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || + sym.isModule && !sym.tpe.isInstanceOf[MethodType])) { + tree.setType(singleType(pre, sym)) + } else tree + } + + def stabilizeFun(tree: Tree, mode: int, pt: Type): Tree = { + val sym = tree.symbol; + val pre = tree match { + case Select(qual, _) => qual.tpe + case _ => NoPrefix + } + if (tree.tpe.isInstanceOf[MethodType] && pre.isStable && + (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || sym.isModule)) { + assert(sym.tpe.paramTypes.isEmpty); + tree.setType(MethodType(List(), singleType(pre, sym))) } else tree } @@ -803,7 +817,7 @@ abstract class Typers: Analyzer { copy.Select(tree, Apply(coercion, List(qual)) setPos qual.pos, name), mode, pt) } if (sym.info == NoType) { - if (settings.debug.value) log("qual = " + qual + ":" + qual.tpe + "\nmembers = " + qual.tpe.members + "\nfound = " + sym); + if (settings.debug.value) log("qual = " + qual + ":" + qual.tpe + "\nSymbol=" + qual.tpe.symbol + "\nsymbol-info = " + qual.tpe.symbol.info + "\nscope-id = " + qual.tpe.symbol.info.decls.hashCode() + "\nmembers = " + qual.tpe.members + "\nfound = " + sym); errorTree(tree, decode(name) + " is not a member of " + qual.tpe.widen + (if (Position.line(tree.pos) > Position.line(qual.pos)) @@ -978,6 +992,14 @@ abstract class Typers: Analyzer { if (vble.name != nme.WILDCARD) namer.enterInScope(vble); copy.Bind(tree, name, body1) setSymbol vble setType pt + case SeqTerm(elems) => + val elempt = pt.baseType(SeqClass) match { + case TypeRef(pre, seqClass, List(arg)) => arg + case _ => WildcardType + } + val elems1 = List.mapConserve(elems)(elem => typed(elem, mode, elempt)); + copy.SeqTerm(tree, elems1) setType ptOrLub(elems1 map (.tpe)) + case fun @ Function(_, _) => newTyper(context.makeNewScope(tree, context.owner)).typedFunction(fun, mode, pt) @@ -1073,21 +1095,29 @@ abstract class Typers: Analyzer { typedTypeApply(typed(fun, funmode | TAPPmode, WildcardType), args1) case Apply(fun, args) => - val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType; - var fun1 = typed(fun, funmode, funpt); - // if function is overloaded, filter all alternatives that match - // number of arguments and expected result type. - // if (settings.debug.value) log("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG - if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) { - val argtypes = args map (arg => AllClass.tpe); - val pre = fun1.symbol.tpe.prefix; - val sym = fun1.symbol filter (alt => - isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt)); - if (sym != NoSymbol) - fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType) - } - appcnt = appcnt + 1; - typedApply(fun1, args) + val stableApplication = + fun.symbol != null && fun.symbol.tpe.isInstanceOf[MethodType] && fun.symbol.isStable; + if (stableApplication && (mode & PATTERNmode) != 0) { + // treat stable function applications f() as expressions. + typed1(tree, mode & ~PATTERNmode | EXPRmode, pt) + } else { + val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType; + var fun1 = typed(fun, funmode, funpt); + if (stableApplication) fun1 = stabilizeFun(fun1, mode, pt); + // if function is overloaded, filter all alternatives that match + // number of arguments and expected result type. + // if (settings.debug.value) log("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG + if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) { + val argtypes = args map (arg => AllClass.tpe); + val pre = fun1.symbol.tpe.prefix; + val sym = fun1.symbol filter (alt => + isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt)); + if (sym != NoSymbol) + fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType) + } + appcnt = appcnt + 1; + typedApply(fun1, args) + } case Super(qual, mix) => val clazz = if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(qual); |