diff options
author | Martin Odersky <odersky@gmail.com> | 2008-05-02 14:55:17 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2008-05-02 14:55:17 +0000 |
commit | 76c76b28f952584210fd851f95877b84f0b688a2 (patch) | |
tree | 20dfff67c5d7d092104fd17c66cb597e1c9327b7 /src/compiler | |
parent | 8c35b8f863e5b7104deb7bfdce957d6d428cc25f (diff) | |
download | scala-76c76b28f952584210fd851f95877b84f0b688a2.tar.gz scala-76c76b28f952584210fd851f95877b84f0b688a2.tar.bz2 scala-76c76b28f952584210fd851f95877b84f0b688a2.zip |
fixed #828, #789, #828.
Diffstat (limited to 'src/compiler')
3 files changed, 29 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 09b0f6ca2a..ef2248be02 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -423,7 +423,7 @@ abstract class ClassfileParser { sawPrivateConstructor = true in.skip(2); skipAttributes() } else { - if ((jflags & JAVA_ACC_BRIDGE) != 0 && global.settings.target.value == "jvm-1.5") + if ((jflags & JAVA_ACC_BRIDGE) != 0) sflags |= BRIDGE if ((sflags & PRIVATE) != 0 && global.settings.XO.value) { in.skip(4); skipAttributes() diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index dcaea1041b..10d226ace2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -569,7 +569,10 @@ trait Namers { self: Analyzer => } else { enterValueParams(meth, vparamss) } - if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) tpt.tpe = context.enclClass.owner.tpe + if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) { + tpt.tpe = context.enclClass.owner.tpe + tpt setPos meth.pos + } if (onlyPresentation) methodArgumentNames(meth) = vparamss.map(_.map(_.symbol)); @@ -673,6 +676,7 @@ trait Namers { self: Analyzer => for (vparam <- vparams) { if (vparam.tpt.isEmpty) { vparam.tpt.tpe = pfs.head + vparam.tpt setPos vparam.pos vparam.symbol setInfo pfs.head } pfs = pfs.tail @@ -705,9 +709,10 @@ trait Namers { self: Analyzer => if (tpt.isEmpty) { val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) tpt.tpe = widenIfNotFinal(meth, typer.computeType(rhs, pt), pt) + tpt setPos meth.pos tpt.tpe } else typer.typedType(tpt).tpe) - } + } /** If `sym' is an implicit value, check that its type signature `tp' is contractive. * This means: The type of every implicit parameter is properly contained @@ -840,6 +845,7 @@ trait Namers { self: Analyzer => sym, newTyper(typer1.context.make(vdef, sym)).computeType(rhs, WildcardType), WildcardType) + tpt setPos vdef.pos tpt.tpe } } else typer1.typedType(tpt).tpe @@ -947,6 +953,7 @@ trait Namers { self: Analyzer => checkNoConflict(FINAL, SEALED) checkNoConflict(PRIVATE, PROTECTED) checkNoConflict(PRIVATE, OVERRIDE) + //checkNoConflict(PRIVATE, FINAL) // can't do this because FINAL also means compile-time constant checkNoConflict(DEFERRED, FINAL) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index de1f3f3119..d22ab4942e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -249,8 +249,20 @@ abstract class RefChecks extends InfoTransform { else clazz.toString() + " needs to be abstract") + ", since " + msg); clazz.setFlag(ABSTRACT) } + // Find a concrete Java method that overrides `sym' under the erasure model. + // Bridge symbols qualify. + // Used as a fall back if no overriding symbol of a Java abstract method can be found + def javaErasedOverridingSym(sym: Symbol): Symbol = + clazz.tpe.findMember(sym.name, PRIVATE, 0, false).filter(other => + !other.isDeferred && + (other hasFlag JAVA) && { + val tp1 = erasure.erasure(clazz.thisType.memberType(sym)) + val tp2 = erasure.erasure(clazz.thisType.memberType(other)) + atPhase(currentRun.erasurePhase.next)(tp1 matches tp2) + }) for (val member <- clazz.tpe.nonPrivateMembers) - if (member.isDeferred && !(clazz hasFlag ABSTRACT)) { + if (member.isDeferred && !(clazz hasFlag ABSTRACT) && + !((member hasFlag JAVA) && javaErasedOverridingSym(member) != NoSymbol)) { abstractClassError( false, infoString(member) + " is not defined" + analyzer.varNotice(member)) } else if ((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(clazz)) { @@ -263,6 +275,12 @@ abstract class RefChecks extends InfoTransform { } // 3. Check that concrete classes do not have deferred definitions // that are not implemented in a subclass. + // Note that this is not the same as (2); In a situation like + // + // class C { def m: Int = 0} + // class D extends C { def m: Int } + // + // (3) is violated but not (2). def checkNoAbstractDecls(bc: Symbol) { for (val decl <- bc.info.decls.elements) { if (decl.isDeferred) { |