diff options
author | Martin Odersky <odersky@gmail.com> | 2007-01-03 15:56:13 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-01-03 15:56:13 +0000 |
commit | a961d3dcd6f93ee006cff1d386052bf62326739a (patch) | |
tree | 5af3312932236340708522dfd078f32beed20519 /src/compiler | |
parent | 02a45e20bb6f68808708dca377bc72ccaf5bba3d (diff) | |
download | scala-a961d3dcd6f93ee006cff1d386052bf62326739a.tar.gz scala-a961d3dcd6f93ee006cff1d386052bf62326739a.tar.bz2 scala-a961d3dcd6f93ee006cff1d386052bf62326739a.zip |
1.
Diffstat (limited to 'src/compiler')
10 files changed, 236 insertions, 150 deletions
diff --git a/src/compiler/scala/tools/ant/ScalaTool.scala b/src/compiler/scala/tools/ant/ScalaTool.scala index 13a46070b5..c88939f502 100644 --- a/src/compiler/scala/tools/ant/ScalaTool.scala +++ b/src/compiler/scala/tools/ant/ScalaTool.scala @@ -300,10 +300,10 @@ package scala.tools.ant { } private def expandUnixVar(vars: Map[String,String]): Map[String,String] = - vars map { case Pair(_, vari) => vari.replaceAll("#([^#]*)#", "\\$$1") } + vars transform { (x, vari) => vari.replaceAll("#([^#]*)#", "\\$$1") } private def expandWinVar(vars: Map[String,String]): Map[String,String] = - vars map { case Pair(_, vari) => vari.replaceAll("#([^#]*)#", "%_$1%") } + vars transform { (x, vari) => vari.replaceAll("#([^#]*)#", "%_$1%") } private def pipeTemplate(template: String, patches: Map[String,String]) = { val resourceRoot = "scala/tools/ant/templates/" diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 3ac528844e..0ba2519e0d 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -318,7 +318,9 @@ abstract class TreePrinters { case WildcardTypeTree(lo, hi) => print("_ "); printOpt(" >: ", lo); printOpt(" <: ", hi) - case tree if (tree ne null) => print(tree.toString()) + + case tree => + print("<unknown tree of class "+tree.getClass+">") } if (global.settings.printtypes.value && tree.isTerm && !tree.isEmpty) { print("{"); print(if (tree.tpe eq null) "<null>" else tree.tpe.toString()); print("}") diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index f40a759dc3..454eed1755 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -74,6 +74,8 @@ trait Parsers requires SyntaxAnalyzer { def freshName(prefix: String): Name = unit.fresh.newName(prefix) } + var implicitClassViews: List[Tree] = Nil + /** this is the general parse method */ def parse(): Tree = { @@ -928,7 +930,7 @@ trait Parsers requires SyntaxAnalyzer { /** PostfixExpr ::= [`.'] InfixExpr [Id [NewLine]] * InfixExpr ::= PrefixExpr - * | InfixExpr Id [NewLine] InfixExpr + * | InfixExpr Id [NewLine] (InfixExpr | ArgumentExprs) */ def postfixExpr(): Tree = { val base = opstack @@ -936,11 +938,12 @@ trait Parsers requires SyntaxAnalyzer { while (isIdent) { top = reduceStack( true, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) - opstack = OpInfo(top, in.name, in.currentPos) :: opstack + val op = in.name + opstack = OpInfo(top, op, in.currentPos) :: opstack ident() newLineOptWhenFollowing(isExprIntroToken) if (isExprIntro) { - top = prefixExpr() + top = secondInfixOperandExpr(op) } else { val topinfo = opstack.head opstack = opstack.tail @@ -952,6 +955,17 @@ trait Parsers requires SyntaxAnalyzer { reduceStack(true, base, top, 0, true) } + def secondInfixOperandExpr(op: Name): Tree = + if (in.token == LPAREN && treeInfo.isLeftAssoc(op)) { + val pos = in.currentPos + val args = argumentExprs() + if (args.isEmpty) simpleExprRest(Literal(()) setPos pos, false) + else if (args.tail.isEmpty) simpleExprRest(args.head, false) + else ArgumentExprs(args) + } else { + prefixExpr() + } + /** PrefixExpr ::= [`-' | `+' | `~' | `!' | `&' | `/'] SimpleExpr */ def prefixExpr(): Tree = @@ -1052,25 +1066,23 @@ trait Parsers requires SyntaxAnalyzer { syntaxError("illegal start of simple expression", true) t = errorTermTree } - while (true) { - in.token match { - case DOT => - t = atPos(in.skipToken()) { selector(t) } - case LBRACKET => - t match { - case Ident(_) | Select(_, _) => - t = atPos(in.currentPos) { TypeApply(t, typeArgs(false)) } - case _ => - return t - } - case LPAREN | LBRACE if (!isNew) => - t = atPos(in.currentPos) { Apply(t, argumentExprs()) } + simpleExprRest(t, isNew) + } + + def simpleExprRest(t: Tree, isNew: boolean): Tree = in.token match { + case DOT => + simpleExprRest(atPos(in.skipToken()) { selector(t) }, false) + case LBRACKET => + t match { + case Ident(_) | Select(_, _) => + simpleExprRest(atPos(in.currentPos) { TypeApply(t, typeArgs(false)) }, false) case _ => - return t + t } - isNew = false - } - null;//dummy + case LPAREN | LBRACE if (!isNew) => + simpleExprRest(atPos(in.currentPos) { Apply(t, argumentExprs()) }, false) + case _ => + t } /** ArgumentExprs ::= `(' [Exprs] `)' @@ -1244,13 +1256,25 @@ trait Parsers requires SyntaxAnalyzer { while (isIdent && in.name != BAR) { top = reduceStack( false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) - opstack = OpInfo(top, in.name, in.currentPos) :: opstack + val op = in.name + opstack = OpInfo(top, op, in.currentPos) :: opstack ident() - top = simplePattern(seqOK) + top = secondInfixOperandPattern(op, seqOK) } reduceStack(false, base, top, 0, true) } + def secondInfixOperandPattern(op: Name, seqOK: boolean): Tree = + if (in.token == LPAREN && treeInfo.isLeftAssoc(op)) { + val pos = in.currentPos + val args = argumentPatterns() + if (args.isEmpty) Literal(()) setPos pos + else if (args.tail.isEmpty) args.head + else ArgumentExprs(args) + } else { + simplePattern(seqOK) + } + /** SimplePattern ::= varid * | `_' * | literal @@ -1289,22 +1313,9 @@ trait Parsers requires SyntaxAnalyzer { } else */ if (in.token == LPAREN) { - atPos(in.skipToken()) { - val ps = if (in.token == RPAREN) List() else patterns(true, false) - accept(RPAREN) - Apply(convertToTypeId(t), ps) - } + atPos(in.currentPos) { Apply(convertToTypeId(t), argumentPatterns()) } } else if (in.token == LBRACE) { - in.nextToken() - val ts = if (in.token == RBRACE) List() - else { - val p1 = pattern() - accept(COMMA) - p1 :: (if (in.token == RBRACE) List() else patterns(false, true)) - } - checkSize("tuple elements", ts.length, definitions.MaxTupleArity) - accept(RBRACE) - makeTupleTerm(ts, false) + atPos(in.currentPos) { Apply(convertToTypeId(t), List(tuplePattern())) } } else t case USCORE => atPos(in.skipToken()) { Ident(nme.WILDCARD) } @@ -1319,6 +1330,8 @@ trait Parsers requires SyntaxAnalyzer { else Literal(()).setPos(pos) accept(RPAREN) p + case LBRACE => + tuplePattern() case XMLSTART => xmlp.xLiteralPattern case _ => @@ -1329,6 +1342,26 @@ trait Parsers requires SyntaxAnalyzer { errorPatternTree } + def argumentPatterns(): List[Tree] = { + accept(LPAREN) + val ps = if (in.token == RPAREN) List() else patterns(true, false) + accept(RPAREN) + ps + } + + def tuplePattern(): Tree = { + in.nextToken() + val ts = if (in.token == RBRACE) List() + else { + val p1 = pattern() + accept(COMMA) + p1 :: (if (in.token == RBRACE) List() else patterns(false, true)) + } + checkSize("tuple elements", ts.length, definitions.MaxTupleArity) + accept(RBRACE) + makeTuplePattern(ts) + } + ////////// MODIFIERS //////////////////////////////////////////////////////////// /** Modifiers ::= {Modifier} @@ -1511,7 +1544,7 @@ trait Parsers requires SyntaxAnalyzer { * FunTypeParamClauseOpt ::= [[NewLine] `[' TypeParam {`,' TypeParam} `]'] * TypeParam ::= Id TypeBounds [<% Type] */ - def typeParamClauseOpt(owner: Name, implicitViews: ListBuffer[Tree]): List[AbsTypeDef] = { + def typeParamClauseOpt(owner: Name, implicitViewBuf: ListBuffer[Tree]): List[AbsTypeDef] = { def typeParam(): AbsTypeDef = { var mods = Modifiers(Flags.PARAM) if (owner.isTypeName && isIdent) { @@ -1525,8 +1558,8 @@ trait Parsers requires SyntaxAnalyzer { } val pname = ident() val param = atPos(in.currentPos) { typeBounds(mods, pname) } - if (in.token == VIEWBOUND && (implicitViews ne null)) - implicitViews += atPos(in.skipToken()) { + if (in.token == VIEWBOUND && (implicitViewBuf ne null)) + implicitViewBuf += atPos(in.skipToken()) { makeFunctionTypeTree(List(Ident(pname.toTypeName)), typ()) } param @@ -1743,16 +1776,16 @@ trait Parsers requires SyntaxAnalyzer { atPos(in.skipToken()) { if (in.token == THIS) { in.nextToken() - val vparamss = paramClauses(nme.CONSTRUCTOR, List(), false) - val rhs = if (in.token == LBRACE) constrBlock() - else { accept(EQUALS); constrExpr() } + val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (.duplicate), false) + val rhs = if (in.token == LBRACE) constrBlock(vparamss) + else { accept(EQUALS); constrExpr(vparamss) } DefDef(mods, nme.CONSTRUCTOR, List(), vparamss, TypeTree(), rhs) } else { var newmods = mods val name = ident() - val implicitViews = new ListBuffer[Tree] - val tparams = typeParamClauseOpt(name, implicitViews) - val vparamss = paramClauses(name, implicitViews.toList, false) + val implicitViewBuf = new ListBuffer[Tree] + val tparams = typeParamClauseOpt(name, implicitViewBuf) + val vparamss = paramClauses(name, implicitViewBuf.toList, false) var restype = typedOpt() val rhs = if (in.token == SEMI || in.token == NEWLINE || in.token == RBRACE) { @@ -1770,24 +1803,25 @@ trait Parsers requires SyntaxAnalyzer { /** ConstrExpr ::= SelfInvocation * | ConstrBlock */ - def constrExpr(): Tree = - if (in.token == LBRACE) constrBlock() else selfInvocation() + def constrExpr(vparamss: List[List[ValDef]]): Tree = + if (in.token == LBRACE) constrBlock(vparamss) else selfInvocation(vparamss) /** SelfInvocation ::= this ArgumentExprs {ArgumentExprs} */ - def selfInvocation(): Tree = + def selfInvocation(vparamss: List[List[ValDef]]): Tree = atPos(accept(THIS)) { var t = Apply(Ident(nme.CONSTRUCTOR), argumentExprs()) while (in.token == LPAREN) t = Apply(t, argumentExprs()) + if (!implicitClassViews.isEmpty) t = Apply(t, vparamss.last.map(vd => Ident(vd.name))) t } /** ConstrBlock ::= `{' SelfInvocation {StatementSeparator BlockStat} `}' */ - def constrBlock(): Tree = + def constrBlock(vparamss: List[List[ValDef]]): Tree = atPos(in.skipToken()) { val statlist = new ListBuffer[Tree] - statlist += selfInvocation() + statlist += selfInvocation(vparamss) val stats = if (in.token == SEMI || in.token == NEWLINE) { in.nextToken(); blockStatSeq(statlist) @@ -1844,17 +1878,21 @@ trait Parsers requires SyntaxAnalyzer { def classDef(mods: Modifiers): ClassDef = atPos(in.skipToken()) { val name = ident().toTypeName - val implicitViews = new ListBuffer[Tree] - val tparams = typeParamClauseOpt(name, implicitViews) + val savedViews = implicitClassViews + val implicitViewBuf = new ListBuffer[Tree] + val tparams = typeParamClauseOpt(name, implicitViewBuf) + implicitClassViews = implicitViewBuf.toList //if (mods.hasFlag(Flags.CASE) && in.token != LPAREN) accept(LPAREN) val vparamss = if (mods.hasFlag(Flags.TRAIT)) List() - else paramClauses(name, implicitViews.toList, mods.hasFlag(Flags.CASE)) + else paramClauses(name, implicitClassViews, mods.hasFlag(Flags.CASE)) val thistpe = requiresTypeOpt() val template = classTemplate(mods, name, vparamss) val mods1 = if (mods.hasFlag(Flags.TRAIT) && (template.body forall treeInfo.isInterfaceMember)) mods | Flags.INTERFACE else mods - ClassDef(mods1, name, tparams, thistpe, template) + val result = ClassDef(mods1, name, tparams, thistpe, template) + implicitClassViews = savedViews + result } /** ObjectDef ::= Id ClassTemplate diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 3fe1bd28b8..e2d2fb4a97 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -92,6 +92,11 @@ abstract class TreeBuilder { case _ => makeTuple(trees, false) } + def makeTuplePattern(trees: List[Tree]): Tree = trees match { + case List() => Literal(()) + case _ => makeTuple(trees, true) + } + def makeTupleType(trees: List[Tree], flattenUnary: boolean): Tree = trees match { case List() => scalaUnitConstr case List(tree) if flattenUnary => tree @@ -109,10 +114,14 @@ abstract class TreeBuilder { } /** Create tree representing (unencoded) binary operation expression or pattern. */ - def makeBinop(isExpr: boolean, left: Tree, op: Name, right: Tree): Tree = + def makeBinop(isExpr: boolean, left: Tree, op: Name, right: Tree): Tree = { + val arguments = right match { + case ArgumentExprs(args) => args + case _ => List(right) + } if (isExpr) { if (treeInfo.isLeftAssoc(op)) { - Apply(Select(left, op.encode), List(right)) + Apply(Select(left, op.encode), arguments) } else { val x = freshName(); Block( @@ -120,8 +129,9 @@ abstract class TreeBuilder { Apply(Select(right, op.encode), List(Ident(x)))) } } else { - Apply(Ident(op.encode.toTypeName), List(left, right)) + Apply(Ident(op.encode.toTypeName), left :: arguments) } + } /** Create tree representing an object creation <new parents { stats }> */ def makeNew(parents: List[Tree], stats: List[Tree], argss: List[List[Tree]]): Tree = @@ -425,4 +435,6 @@ abstract class TreeBuilder { case Select(qual, name) => makePackaging(qual, List(PackageDef(name, stats))) } + + case class ArgumentExprs(args: List[Tree]) extends Tree } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 82692e9ac7..433f4f055a 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -792,7 +792,7 @@ abstract class GenJVM extends SubComponent { val mtype = new JMethodType(javaType(boxedClass), Array(javaType(kind))) jcode.emitINVOKESTATIC(javaName(boxedClass), "box", mtype) - case UNBOX(BOOL) /* if (boxType.symbol == definitions.BooleanClass) */=> + case UNBOX(BOOL) /* if (boxType.symbol == definitions.BooleanClass) */ => // if null emit false val nonNull = jcode.newLabel() jcode.emitDUP() @@ -874,7 +874,8 @@ abstract class GenJVM extends SubComponent { if (settings.debug.value) log("Emitting SWITHCH:\ntags: " + tags + "\nbranches: " + branches); jcode.emitSWITCH(tagArray, - (branches map labels dropRight 1).copyToArray(branchArray, 0), + { (branches map labels dropRight 1).copyToArray(branchArray, 0); + branchArray }, labels(branches.last), MIN_SWITCH_DENSITY); diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 676d2e5530..3203637130 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -329,6 +329,7 @@ trait Definitions requires SymbolTable { // special attributes var SerializableAttr: Symbol = _ + var DeprecatedAttr: Symbol = _ var BeanPropertyAttr: Symbol = _ var AnnotationDefaultAttr: Symbol = _ @@ -789,6 +790,7 @@ trait Definitions requires SymbolTable { nme.AnnotationDefaultATTR, List(AttributeClass.typeConstructor)) SerializableAttr = getClass("scala.serializable") + DeprecatedAttr = getClass("scala.deprecated") BeanPropertyAttr = if (forCLDC) null else getClass("scala.reflect.BeanProperty") } } diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 3673f1f4fc..7863e4c714 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -47,7 +47,7 @@ trait Types requires SymbolTable { private var explainSwitch = false private var checkMalformedSwitch = true - private var globalVariance = 1 + private var globalVariance = 1//only necessary of healTypes = true? private final val healTypes = false private final val LubGlbMargin = 0 @@ -1436,7 +1436,7 @@ trait Types requires SymbolTable { } /** Map this function over given list of symbols */ - private def mapOver(syms: List[Symbol]): List[Symbol] = { + def mapOver(syms: List[Symbol]): List[Symbol] = { val infos = syms map (.info) val infos1 = List.mapConserve(infos)(this) if (infos1 eq infos) syms diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 0428161cc2..45d7f3f863 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -107,8 +107,10 @@ trait Infer requires Analyzer { * @param targs ... * @return ... */ - private def isWithinBounds(tparams: List[Symbol], targs: List[Type]): boolean = { - val bounds = tparams map (.info.subst(tparams, targs).bounds) + private def isWithinBounds(pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type]): boolean = { + val bounds = tparams map { tparam => + tparam.info.asSeenFrom(pre, owner).subst(tparams, targs).bounds + } !(List.map2(bounds, targs)((bound, targ) => bound containsType targ) contains false) } @@ -284,7 +286,7 @@ trait Infer requires Analyzer { for { val sym1 <- syms1 val sym2 <- syms2 - sym1 != sym2 && sym1.name == sym2.name + sym1 != sym2 && sym1.toString == sym2.toString } yield { val name = sym1.name explainName(sym1) @@ -526,7 +528,7 @@ trait Infer requires Analyzer { val uninstantiated = new ListBuffer[Symbol] val targs = methTypeArgs(undetparams, formals, restpe, argtpes, pt, uninstantiated) (exprTypeArgs(uninstantiated.toList, restpe.subst(undetparams, targs), pt) ne null) && - isWithinBounds(undetparams, targs) + isWithinBounds(NoPrefix, NoSymbol, undetparams, targs) } catch { case ex: NoInstance => false } @@ -573,10 +575,10 @@ trait Infer requires Analyzer { /** error if arguments not within bounds. */ def checkBounds(pos: PositionType, tparams: List[Symbol], targs: List[Type], prefix: String): unit = - if (!isWithinBounds(tparams, targs)) { + if (!isWithinBounds(NoPrefix, NoSymbol, tparams, targs)) { if (!(targs exists (.isErroneous)) && !(tparams exists (.isErroneous))) { //Console.println("tparams = "+tparams+", bounds = "+tparams.map(.info)+", targs="+targs)//DEBUG - //withTypesExplained(isWithinBounds(tparams, targs))//DEBUG + //withTypesExplained(isWithinBounds(NoPrefix, tparams, targs))//DEBUG error(pos, prefix + "type arguments " + targs.mkString("[", ",", "]") + " do not conform to " + tparams.head.owner + "'s type parameter bounds " + @@ -839,7 +841,7 @@ trait Infer requires Analyzer { } def inferTypedPattern(tpt: Tree, pt: Type): Type = { - //Console.println("infer typed pattern: "+tpt)//DEBUG + //Console.println("infer typed pattern: "+tpt+" wrt "+pt)//debug checkCheckable(tpt.pos, tpt.tpe) if (!(tpt.tpe <:< pt)) { val tpparams = freeTypeParamsOfTerms.collect(tpt.tpe) @@ -1047,19 +1049,38 @@ trait Infer requires Analyzer { * @param tree ... * @param nparams ... */ - def inferPolyAlternatives(tree: Tree, nparams: int): unit = tree.tpe match { + def inferPolyAlternatives(tree: Tree, argtypes: List[Type]): unit = tree.tpe match { case OverloadedType(pre, alts) => - val sym = tree.symbol filter (alt => alt.typeParams.length == nparams) + val sym0 = tree.symbol filter { alt => alt.typeParams.length == argtypes.length } + if (sym0 == NoSymbol) { + error( + tree.pos, + if (alts exists (alt => alt.typeParams.length > 0)) + "wrong number of type parameters for " + treeSymTypeMsg(tree) + else treeSymTypeMsg(tree) + " does not take type parameters") + return + } + val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) } if (sym == NoSymbol) { - errorTree(tree, - if (alts exists (alt => alt.typeParams.length > 0)) - "wrong number of type parameters for " + treeSymTypeMsg(tree) - else treeSymTypeMsg(tree) + " does not take type parameters") - } else if (sym.hasFlag(OVERLOADED)) { - val tparams = sym.alternatives.head.typeParams + 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 (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, tparams map (.tpe)), sym.alternatives)) + OverloadedType(AntiPolyType(pre, bounds), sym.alternatives)) sym.setInfo(tpe) tree.setSymbol(sym).setType(tpe) } else { diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index cb6e29650f..8e4e0d317e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -533,6 +533,7 @@ trait Namers requires Analyzer { var result = tp; if (sym hasFlag IMPLICIT) { val p = provided(tp); + //Console.println("check contractive: "+sym+" "+p+"/"+required(tp)) for (val r <- required(tp)) { if (!isContainedIn(r, p) || (r =:= p)) { context.error(sym.pos, "implicit " + sym + " is not contractive," + @@ -549,6 +550,10 @@ trait Namers requires Analyzer { makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe); def typeSig(tree: Tree): Type = { + tree match { + case md: MemberDef => attributes(md) + case _ => + } val result = try { val sym: Symbol = tree.symbol @@ -644,6 +649,66 @@ 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 @ Attribute(constr, elements) <- defn.mods.attributes) yield { + typer.typed(constr, EXPRmode | CONSTmode, AttributeClass.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") + } + Triple(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 26799b4fd9..a55ba1045e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -424,9 +424,16 @@ trait Typers requires Analyzer { * </ol> */ private def stabilize(tree: Tree, pre: Type, mode: int, pt: Type): Tree = { + def isDeprecated(sym: Symbol) = + sym.attributes exists (attr => attr._1.symbol == DeprecatedAttr) if (tree.symbol.hasFlag(OVERLOADED) && (mode & FUNmode) == 0) inferExprAlternative(tree, pt) val sym = tree.symbol + if (!phase.erasedTypes && + isDeprecated(sym) && !context.owner.ownerChain.exists(isDeprecated)) { + unit.deprecationWarning(tree.pos, + sym+sym.locationString+" is deprecated;\n see API documentation for alternatives") + } if (tree.tpe.isError) tree else if ((mode & (PATTERNmode | FUNmode)) == PATTERNmode && tree.isTerm) { // (1) checkStable(tree) @@ -807,7 +814,7 @@ trait Typers requires Analyzer { * @return ... */ def typedClassDef(cdef: ClassDef): Tree = { - attributes(cdef) +// attributes(cdef) val clazz = cdef.symbol reenterTypeParams(cdef.tparams) val tparams1 = List.mapConserve(cdef.tparams)(typedAbsTypeDef) @@ -826,7 +833,7 @@ trait Typers requires Analyzer { */ def typedModuleDef(mdef: ModuleDef): Tree = { //Console.println("sourcefile of " + mdef.symbol + "=" + mdef.symbol.sourceFile) - attributes(mdef) +// attributes(mdef) val clazz = mdef.symbol.moduleClass val impl1 = newTyper(context.make(mdef.impl, clazz, newTemplateScope(mdef.impl, clazz))) .typedTemplate(mdef.impl, parentTypes(mdef.impl)) @@ -917,7 +924,7 @@ trait Typers requires Analyzer { * @return ... */ def typedValDef(vdef: ValDef): ValDef = { - attributes(vdef) +// attributes(vdef) val sym = vdef.symbol val typer1 = if (sym.hasFlag(PARAM) && sym.owner.isConstructor) newTyper(context.makeConstructorContext) @@ -1001,7 +1008,7 @@ trait Typers requires Analyzer { * @return ... */ def typedDefDef(ddef: DefDef): DefDef = { - attributes(ddef) +// attributes(ddef) val meth = ddef.symbol @@ -1450,69 +1457,6 @@ trait Typers requires Analyzer { } /** - * @param defn ... - */ - protected def attributes(defn: MemberDef): Unit = { - var attrError: Boolean = false; - 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) - attrError = true; - null - } - val attrInfos = - for (val t @ Attribute(constr, elements) <- defn.mods.attributes) yield { - typed(constr, EXPRmode | CONSTmode, AttributeClass.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.filter(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) - attrError = true - null - } else if (!names.contains(sym)) { - error(ntree.pos, "duplicate value for element " + name) - attrError = true - null - } else { - names -= sym - Pair(sym.name, getConstant(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) - attrError = true; - } - } - 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") - } - Triple(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(); - } - - /** * @param tree ... * @param mode ... * @param pt ... @@ -1524,7 +1468,7 @@ trait Typers requires Analyzer { def typedTypeApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match { case OverloadedType(pre, alts) => - inferPolyAlternatives(fun, args.length) + inferPolyAlternatives(fun, args map (.tpe)) typedTypeApply(fun, args) case PolyType(tparams, restpe) if (tparams.length != 0) => if (tparams.length == args.length) { @@ -2153,7 +2097,8 @@ trait Typers requires Analyzer { tree setType ref1.tpe.resultType case SelectFromTypeTree(qual, selector) => - tree setType typedSelect(typedType(qual), selector).tpe + val sel = typedSelect(typedType(qual), selector) + tree setSymbol sel.symbol setType typedSelect(typedType(qual), selector).tpe case tree @ CompoundTypeTree(templ: Template) => tree setType { |