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:
odersky 2007-02-19 16:34:11 +00:00
parent dd034e6794
commit 6218a1e31c
5 changed files with 47 additions and 94 deletions

View File

@ -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) {

View File

@ -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}

View File

@ -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))
}
}
}

View File

@ -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

View File

@ -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))