summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-01-03 15:56:13 +0000
committerMartin Odersky <odersky@gmail.com>2007-01-03 15:56:13 +0000
commita961d3dcd6f93ee006cff1d386052bf62326739a (patch)
tree5af3312932236340708522dfd078f32beed20519 /src/compiler
parent02a45e20bb6f68808708dca377bc72ccaf5bba3d (diff)
downloadscala-a961d3dcd6f93ee006cff1d386052bf62326739a.tar.gz
scala-a961d3dcd6f93ee006cff1d386052bf62326739a.tar.bz2
scala-a961d3dcd6f93ee006cff1d386052bf62326739a.zip
1.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/ant/ScalaTool.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala148
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala18
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala53
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala65
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala83
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 {