fixed bugs 954/958/957, plus problem with the interpreter.
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@10041 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
dd034e6794
commit
6218a1e31c
|
@ -1119,8 +1119,10 @@ trait Trees requires Global {
|
||||||
}
|
}
|
||||||
case ClassDef(mods, name, tparams, self, impl) =>
|
case ClassDef(mods, name, tparams, self, impl) =>
|
||||||
atOwner(tree.symbol) {
|
atOwner(tree.symbol) {
|
||||||
copy.ClassDef(tree, mods, name, transformAbsTypeDefs(tparams),
|
copy.ClassDef(tree, mods, name,
|
||||||
transformValDef(self), transformTemplate(impl))
|
transformAbsTypeDefs(tparams),
|
||||||
|
if (self ne emptyValDef) transformValDef(self) else self,
|
||||||
|
transformTemplate(impl))
|
||||||
}
|
}
|
||||||
case ModuleDef(mods, name, impl) =>
|
case ModuleDef(mods, name, impl) =>
|
||||||
atOwner(tree.symbol.moduleClass) {
|
atOwner(tree.symbol.moduleClass) {
|
||||||
|
@ -1263,7 +1265,9 @@ trait Trees requires Global {
|
||||||
}
|
}
|
||||||
case ClassDef(mods, name, tparams, self, impl) =>
|
case ClassDef(mods, name, tparams, self, impl) =>
|
||||||
atOwner(tree.symbol) {
|
atOwner(tree.symbol) {
|
||||||
traverseTrees(tparams); traverse(self); traverse(impl)
|
traverseTrees(tparams);
|
||||||
|
if (self ne emptyValDef) traverse(self);
|
||||||
|
traverse(impl)
|
||||||
}
|
}
|
||||||
case ModuleDef(mods, name, impl) =>
|
case ModuleDef(mods, name, impl) =>
|
||||||
atOwner(tree.symbol.moduleClass) {
|
atOwner(tree.symbol.moduleClass) {
|
||||||
|
|
|
@ -280,7 +280,6 @@ trait Parsers requires SyntaxAnalyzer {
|
||||||
ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree)
|
ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree)
|
||||||
case _ =>
|
case _ =>
|
||||||
syntaxError(tree.pos, "not a legal formal parameter", false)
|
syntaxError(tree.pos, "not a legal formal parameter", false)
|
||||||
throw new Error()
|
|
||||||
ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree, EmptyTree)
|
ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree, EmptyTree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1043,7 @@ trait Parsers requires SyntaxAnalyzer {
|
||||||
val pos = in.skipToken()
|
val pos = in.skipToken()
|
||||||
val ts = if (in.token == RPAREN) List() else exprs()
|
val ts = if (in.token == RPAREN) List() else exprs()
|
||||||
accept(RPAREN)
|
accept(RPAREN)
|
||||||
t = Parens(ts)
|
t = Parens(ts) setPos pos
|
||||||
case LBRACE =>
|
case LBRACE =>
|
||||||
t = blockExpr()
|
t = blockExpr()
|
||||||
canApply = false
|
canApply = false
|
||||||
|
@ -1325,7 +1324,7 @@ trait Parsers requires SyntaxAnalyzer {
|
||||||
val pos = in.skipToken()
|
val pos = in.skipToken()
|
||||||
val ps = if (in.token == RPAREN) List() else patterns(false)
|
val ps = if (in.token == RPAREN) List() else patterns(false)
|
||||||
accept(RPAREN)
|
accept(RPAREN)
|
||||||
Parens(ps)
|
Parens(ps) setPos pos
|
||||||
case XMLSTART =>
|
case XMLSTART =>
|
||||||
xmlp.xLiteralPattern
|
xmlp.xLiteralPattern
|
||||||
case _ =>
|
case _ =>
|
||||||
|
@ -2056,9 +2055,9 @@ trait Parsers requires SyntaxAnalyzer {
|
||||||
*/
|
*/
|
||||||
def templateBody(): Pair[ValDef, List[Tree]] = {
|
def templateBody(): Pair[ValDef, List[Tree]] = {
|
||||||
accept(LBRACE)
|
accept(LBRACE)
|
||||||
val result = templateStatSeq()
|
val result @ Pair(self, stats) = templateStatSeq()
|
||||||
accept(RBRACE)
|
accept(RBRACE)
|
||||||
result
|
if (stats.isEmpty) Pair(self, List(EmptyTree)) else result
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Refinement ::= [nl] `{' RefineStat {semi RefineStat} `}'
|
/** Refinement ::= [nl] `{' RefineStat {semi RefineStat} `}'
|
||||||
|
@ -2150,7 +2149,7 @@ trait Parsers requires SyntaxAnalyzer {
|
||||||
}
|
}
|
||||||
if (in.token != RBRACE && in.token != EOF) acceptStatSep()
|
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}
|
/** RefineStatSeq ::= RefineStat {semi RefineStat}
|
||||||
|
|
|
@ -1077,31 +1077,32 @@ trait Infer requires Analyzer {
|
||||||
else treeSymTypeMsg(tree) + " does not take type parameters")
|
else treeSymTypeMsg(tree) + " does not take type parameters")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) }
|
if (sym0.hasFlag(OVERLOADED)) {
|
||||||
if (sym == NoSymbol) {
|
val sym = sym0 filter { alt => isWithinBounds(pre, alt.owner, alt.typeParams, argtypes) }
|
||||||
if (!(argtypes exists (.isErroneous))) {
|
if (sym == NoSymbol) {
|
||||||
Console.println(":"+sym0.alternatives.map(
|
if (!(argtypes exists (.isErroneous))) {
|
||||||
alt => alt.typeParams.map(
|
error(
|
||||||
p => p.info.asSeenFrom(pre, alt.owner))))
|
tree.pos,
|
||||||
error(
|
"type arguments " + argtypes.mkString("[", ",", "]") +
|
||||||
tree.pos,
|
" conform to the bounds of none of the overloaded alternatives of\n "+sym0+
|
||||||
"type arguments " + argtypes.mkString("[", ",", "]") +
|
": "+sym0.info)
|
||||||
" conform to the bounds of none of the overloaded alternatives of\n "+sym0+
|
return
|
||||||
": "+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 {
|
} else {
|
||||||
tree.setSymbol(sym).setType(pre.memberType(sym))
|
tree.setSymbol(sym0).setType(pre.memberType(sym0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -567,13 +567,19 @@ trait Namers requires Analyzer {
|
||||||
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
|
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
|
||||||
|
|
||||||
def typeSig(tree: Tree): Type = {
|
def typeSig(tree: Tree): Type = {
|
||||||
|
val sym: Symbol = tree.symbol
|
||||||
tree match {
|
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 _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
val result =
|
val result =
|
||||||
try {
|
try {
|
||||||
val sym: Symbol = tree.symbol
|
|
||||||
tree match {
|
tree match {
|
||||||
case ClassDef(_, _, tparams, self, impl) =>
|
case ClassDef(_, _, tparams, self, impl) =>
|
||||||
new Namer(makeNewScope(context, tree, sym)).classSig(tparams, self, impl)
|
new Namer(makeNewScope(context, tree, sym)).classSig(tparams, self, impl)
|
||||||
|
@ -666,66 +672,6 @@ trait Namers requires Analyzer {
|
||||||
deSkolemize(result)
|
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:
|
/** Check that symbol's definition is well-formed. This means:
|
||||||
* - no conflicting modifiers
|
* - no conflicting modifiers
|
||||||
* - `abstract' modifier only for classes
|
* - `abstract' modifier only for classes
|
||||||
|
|
|
@ -877,6 +877,7 @@ trait Typers requires Analyzer {
|
||||||
if (getter hasFlag OVERLOADED)
|
if (getter hasFlag OVERLOADED)
|
||||||
error(getter.pos, getter+" is defined twice")
|
error(getter.pos, getter+" is defined twice")
|
||||||
val getterDef: DefDef = {
|
val getterDef: DefDef = {
|
||||||
|
getter.attributes = value.attributes
|
||||||
val result = DefDef(getter, vparamss =>
|
val result = DefDef(getter, vparamss =>
|
||||||
if (mods hasFlag DEFERRED) EmptyTree
|
if (mods hasFlag DEFERRED) EmptyTree
|
||||||
else typed(atPos(vdef.pos)(Select(This(value.owner), value)), EXPRmode, value.tpe))
|
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)
|
checkNoEscaping.privates(getter, result.tpt)
|
||||||
copy.DefDef(result, result.mods withAnnotations vdef.mods.attributes, result.name,
|
copy.DefDef(result, result.mods withAnnotations vdef.mods.attributes, result.name,
|
||||||
result.tparams, result.vparamss, result.tpt, result.rhs)
|
result.tparams, result.vparamss, result.tpt, result.rhs)
|
||||||
|
//todo: withAnnotations is probably unnecessary
|
||||||
}
|
}
|
||||||
def setterDef: DefDef = {
|
def setterDef: DefDef = {
|
||||||
val setr = getter.setter(value.owner)
|
val setr = getter.setter(value.owner)
|
||||||
|
setr.attributes = value.attributes
|
||||||
val result = atPos(vdef.pos)(
|
val result = atPos(vdef.pos)(
|
||||||
DefDef(setr, vparamss =>
|
DefDef(setr, vparamss =>
|
||||||
if ((mods hasFlag DEFERRED) || (setr hasFlag OVERLOADED))
|
if ((mods hasFlag DEFERRED) || (setr hasFlag OVERLOADED))
|
||||||
|
|
Loading…
Reference in New Issue