diff options
author | Martin Odersky <odersky@gmail.com> | 2007-02-19 16:34:11 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-02-19 16:34:11 +0000 |
commit | 53c115ff4c8a6cf81659e0ac7bb878b32765107a (patch) | |
tree | 01c06cfac1acc49c78d6ec578a755a7cd73c0666 | |
parent | f1e1fcc733c025710368cdba5648954ef1057d80 (diff) | |
download | scala-53c115ff4c8a6cf81659e0ac7bb878b32765107a.tar.gz scala-53c115ff4c8a6cf81659e0ac7bb878b32765107a.tar.bz2 scala-53c115ff4c8a6cf81659e0ac7bb878b32765107a.zip |
fixed bugs 954/958/957, plus problem with the i...
fixed bugs 954/958/957, plus problem with the interpreter.
5 files changed, 47 insertions, 94 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index b385760a80..ac9a1ab02c 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -1119,8 +1119,10 @@ trait Trees requires Global { } case ClassDef(mods, name, tparams, self, impl) => atOwner(tree.symbol) { - copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams), - transformValDef(self), transformTemplate(impl)) + copy.ClassDef(tree, mods, name, + transformAbsTypeDefs(tparams), + if (self ne emptyValDef) transformValDef(self) else self, + transformTemplate(impl)) } case ModuleDef(mods, name, impl) => atOwner(tree.symbol.moduleClass) { @@ -1263,7 +1265,9 @@ trait Trees requires Global { } case ClassDef(mods, name, tparams, self, impl) => atOwner(tree.symbol) { - traverseTrees(tparams); traverse(self); traverse(impl) + traverseTrees(tparams); + if (self ne emptyValDef) traverse(self); + traverse(impl) } case ModuleDef(mods, name, impl) => atOwner(tree.symbol.moduleClass) { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 9affe5be75..e21460633c 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -280,7 +280,6 @@ trait Parsers requires SyntaxAnalyzer { ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree) case _ => syntaxError(tree.pos, "not a legal formal parameter", false) - throw new Error() ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree, EmptyTree) } } @@ -1044,7 +1043,7 @@ trait Parsers requires SyntaxAnalyzer { val pos = in.skipToken() val ts = if (in.token == RPAREN) List() else exprs() accept(RPAREN) - t = Parens(ts) + t = Parens(ts) setPos pos case LBRACE => t = blockExpr() canApply = false @@ -1325,7 +1324,7 @@ trait Parsers requires SyntaxAnalyzer { val pos = in.skipToken() val ps = if (in.token == RPAREN) List() else patterns(false) accept(RPAREN) - Parens(ps) + Parens(ps) setPos pos case XMLSTART => xmlp.xLiteralPattern case _ => @@ -2056,9 +2055,9 @@ trait Parsers requires SyntaxAnalyzer { */ def templateBody(): Pair[ValDef, List[Tree]] = { accept(LBRACE) - val result = templateStatSeq() + val result @ Pair(self, stats) = templateStatSeq() accept(RBRACE) - result + if (stats.isEmpty) Pair(self, List(EmptyTree)) else result } /** Refinement ::= [nl] `{' RefineStat {semi RefineStat} `}' @@ -2150,7 +2149,7 @@ trait Parsers requires SyntaxAnalyzer { } if (in.token != RBRACE && in.token != EOF) acceptStatSep() } - Pair(self, if (!stats.hasNext) List(EmptyTree) else stats.toList) + Pair(self, stats.toList) } /** RefineStatSeq ::= RefineStat {semi RefineStat} diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 52672ed014..fe0ffa65f8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1077,31 +1077,32 @@ trait Infer requires Analyzer { else treeSymTypeMsg(tree) + " does not take type parameters") return } - val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) } - if (sym == NoSymbol) { - if (!(argtypes exists (.isErroneous))) { - Console.println(":"+sym0.alternatives.map( - alt => alt.typeParams.map( - p => p.info.asSeenFrom(pre, alt.owner)))) - error( - tree.pos, - "type arguments " + argtypes.mkString("[", ",", "]") + - " conform to the bounds of none of the overloaded alternatives of\n "+sym0+ - ": "+sym0.info) - return + if (sym0.hasFlag(OVERLOADED)) { + val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) } + if (sym == NoSymbol) { + if (!(argtypes exists (.isErroneous))) { + error( + tree.pos, + "type arguments " + argtypes.mkString("[", ",", "]") + + " conform to the bounds of none of the overloaded alternatives of\n "+sym0+ + ": "+sym0.info) + return + } + } + if (sym.hasFlag(OVERLOADED)) { + val tparams = new AsSeenFromMap(pre, sym.alternatives.head.owner).mapOver( + sym.alternatives.head.typeParams) + val bounds = tparams map (.tpe) + val tpe = + PolyType(tparams, + OverloadedType(AntiPolyType(pre, bounds), sym.alternatives)) + sym.setInfo(tpe) + tree.setSymbol(sym).setType(tpe) + } else { + tree.setSymbol(sym).setType(pre.memberType(sym)) } - } - if (sym.hasFlag(OVERLOADED)) { - val tparams = new AsSeenFromMap(pre, sym.alternatives.head.owner).mapOver( - sym.alternatives.head.typeParams) - val bounds = tparams map (.tpe) - val tpe = - PolyType(tparams, - OverloadedType(AntiPolyType(pre, bounds), sym.alternatives)) - sym.setInfo(tpe) - tree.setSymbol(sym).setType(tpe) } else { - tree.setSymbol(sym).setType(pre.memberType(sym)) + tree.setSymbol(sym0).setType(pre.memberType(sym0)) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 000c57d766..17b22403c4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -567,13 +567,19 @@ trait Namers requires Analyzer { makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe); def typeSig(tree: Tree): Type = { + val sym: Symbol = tree.symbol tree match { - case md: MemberDef => attributes(md) + case defn: MemberDef => + val annots = for { + val Annotation(constr, elements) <- defn.mods.attributes + val ainfo = typer.typedAnnotation(constr, elements) + !ainfo.atp.isError + } yield ainfo + if (!annots.isEmpty) sym.attributes = annots case _ => } val result = try { - val sym: Symbol = tree.symbol tree match { case ClassDef(_, _, tparams, self, impl) => new Namer(makeNewScope(context, tree, sym)).classSig(tparams, self, impl) @@ -666,66 +672,6 @@ trait Namers requires Analyzer { deSkolemize(result) } - /** - * @param defn ... - */ - protected def attributes(defn: MemberDef): Unit = { - var attrError: Boolean = false; - def error(pos: PositionType, msg: String): Null = { - context.error(pos, msg) - attrError = true - null - } - def getConstant(tree: Tree): Constant = tree match { - case Literal(value) => value - case arg => error(arg.pos, "attribute argument needs to be a constant; found: "+arg) - } - val attrInfos = - for (val t @ Annotation(constr, elements) <- defn.mods.attributes) yield { - typer.typed(constr, EXPRmode | CONSTmode, AnnotationClass.tpe) match { - case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => - val constrArgs = args map getConstant - val attrScope = tpt.tpe.decls. - filter(sym => sym.isMethod && !sym.isConstructor && sym.hasFlag(JAVA)); - val names = new collection.mutable.HashSet[Symbol] - names ++= attrScope.elements.filter(.isMethod) - if (args.length == 1) { - names.retain(sym => sym.name != nme.value) - } - val nvPairs = elements map { - case Assign(ntree @ Ident(name), rhs) => { - val sym = attrScope.lookup(name); - if (sym == NoSymbol) { - error(ntree.pos, "unknown attribute element name: " + name) - } else if (!names.contains(sym)) { - error(ntree.pos, "duplicate value for element " + name) - } else { - names -= sym - Pair(sym.name, getConstant(typer.typed(rhs, EXPRmode | CONSTmode, sym.tpe.resultType))) - } - } - } - for (val name <- names) { - if (!name.attributes.contains(Triple(AnnotationDefaultAttr.tpe, List(), List()))) { - error(t.pos, "attribute " + tpt.tpe.symbol.fullNameString + " is missing element " + name.name) - } - } - if (tpt.tpe.symbol.hasFlag(JAVA) && settings.target.value == "jvm-1.4") { - context.unit.warning (t.pos, "Java annotation will not be emitted in classfile unless you use the '-target:jvm-1.5' option") - } - AttrInfo(tpt.tpe, constrArgs, nvPairs) - } - } - if (!attrError) { - val attributed = - if (defn.symbol.isModule) defn.symbol.moduleClass else defn.symbol - if (!attrInfos.isEmpty) { - attributed.attributes = attrInfos - } - } -// defn.mods setAttr List(); - } - /** Check that symbol's definition is well-formed. This means: * - no conflicting modifiers * - `abstract' modifier only for classes diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index dc82bfdc9c..be1472307a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -877,6 +877,7 @@ trait Typers requires Analyzer { if (getter hasFlag OVERLOADED) error(getter.pos, getter+" is defined twice") val getterDef: DefDef = { + getter.attributes = value.attributes val result = DefDef(getter, vparamss => if (mods hasFlag DEFERRED) EmptyTree else typed(atPos(vdef.pos)(Select(This(value.owner), value)), EXPRmode, value.tpe)) @@ -884,9 +885,11 @@ trait Typers requires Analyzer { checkNoEscaping.privates(getter, result.tpt) copy.DefDef(result, result.mods withAnnotations vdef.mods.attributes, result.name, result.tparams, result.vparamss, result.tpt, result.rhs) + //todo: withAnnotations is probably unnecessary } def setterDef: DefDef = { val setr = getter.setter(value.owner) + setr.attributes = value.attributes val result = atPos(vdef.pos)( DefDef(setr, vparamss => if ((mods hasFlag DEFERRED) || (setr hasFlag OVERLOADED)) |