diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-08-09 16:18:16 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@odersky.com> | 2016-08-09 17:28:04 -0700 |
commit | d59de7d571c503064d3d2ad0db3312b9e6793616 (patch) | |
tree | 80e5ad05d9ab885eb7e654f22f018662f4f923fd | |
parent | 86647e20f3d9ff935d1be2a2ccf04e17f852e712 (diff) | |
download | scala-d59de7d571c503064d3d2ad0db3312b9e6793616.tar.gz scala-d59de7d571c503064d3d2ad0db3312b9e6793616.tar.bz2 scala-d59de7d571c503064d3d2ad0db3312b9e6793616.zip |
Javadoc: java static name resolution
[Jakob Odersky <jodersky@gmail.com>: remove obsolete comments and fix tests]
-rw-r--r-- | src/compiler/scala/tools/nsc/javac/JavaParsers.scala | 22 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 16 | ||||
-rw-r--r-- | test/files/pos/t2377b/Q.java | 10 | ||||
-rw-r--r-- | test/files/pos/t2377b/a.scala | 3 |
4 files changed, 28 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 633fdcc870..e6291934db 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -609,26 +609,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { Import(Ident(cdef.name.toTermName), ImportSelector.wildList) } - // Importing the companion object members cannot be done uncritically: see - // ticket #2377 wherein a class contains two static inner classes, each of which - // has a static inner class called "Builder" - this results in an ambiguity error - // when each performs the import in the enclosing class's scope. - // - // To address this I moved the import Companion._ inside the class, as the first - // statement. This should work without compromising the enclosing scope, but may (?) - // end up suffering from the same issues it does in scala - specifically that this - // leaves auxiliary constructors unable to access members of the companion object - // as unqualified identifiers. - def addCompanionObject(statics: List[Tree], cdef: ClassDef): List[Tree] = { - def implWithImport(importStmt: Tree) = deriveTemplate(cdef.impl)(importStmt :: _) - // if there are no statics we can use the original cdef, but we always - // create the companion so import A._ is not an error (see ticket #1700) - val cdefNew = - if (statics.isEmpty) cdef - else deriveClassDef(cdef)(_ => implWithImport(importCompanionObject(cdef))) - - List(makeCompanionObject(cdefNew, statics), cdefNew) - } + def addCompanionObject(statics: List[Tree], cdef: ClassDef): List[Tree] = + List(makeCompanionObject(cdef, statics), cdef) def importDecl(): List[Tree] = { accept(IMPORT) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ba104fb7a6..ad58859f25 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4677,6 +4677,16 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree } + + // For Java, instance and static members are in the same scope, but we put the static ones in the companion object + // so, when we can't find a member in the class scope, check the companion + def inCompanionForJavaStatic(pre: Type, cls: Symbol, name: Name): Symbol = + if (!(context.unit.isJava && cls.isClass && !cls.isModuleClass)) NoSymbol else { + val companion = companionSymbolOf(cls, context) + if (!companion.exists) NoSymbol + else member(gen.mkAttributedRef(pre, companion), name) // assert(res.isStatic, s"inCompanionJavaStatic($pre, $cls, $name) = $res ${res.debugFlagString}") + } + /* Attribute a selection where `tree` is `qual.name`. * `qual` is already attributed. */ @@ -4703,7 +4713,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper dyna.wrapErrors(t, (_.typed1(t, mode, pt))) } - val sym = tree.symbol orElse member(qual, name) orElse { + val sym = tree.symbol orElse member(qual, name) orElse inCompanionForJavaStatic(qual.tpe.prefix, qual.symbol, name) orElse { // symbol not found? --> try to convert implicitly to a type that does have the required // member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an // xml member to StringContext, which in turn has an unapply[Seq] method) @@ -4876,10 +4886,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case LookupAmbiguous(msg) => issue(AmbiguousIdentError(tree, name, msg)) case LookupInaccessible(sym, msg) => issue(AccessError(tree, sym, context, msg)) case LookupNotFound => - inEmptyPackage orElse lookupInRoot(name) match { + inCompanionForJavaStatic(NoPrefix, context.enclClass.owner, name) orElse inEmptyPackage orElse lookupInRoot(name) match { case NoSymbol => issue(SymbolNotFoundError(tree, name, context.owner, startContext)) case sym => typed1(tree setSymbol sym, mode, pt) - } + } case LookupSucceeded(qual, sym) => (// this -> Foo.this if (sym.isThisSym) diff --git a/test/files/pos/t2377b/Q.java b/test/files/pos/t2377b/Q.java new file mode 100644 index 0000000000..1dfdd5991d --- /dev/null +++ b/test/files/pos/t2377b/Q.java @@ -0,0 +1,10 @@ +public class Q { + + public static class Builder {} + + public static class Inner { + public static class Builder {} + public Builder foo() { return new Builder(); } // this line gives an error, that Builder is ambiguous + } + +} diff --git a/test/files/pos/t2377b/a.scala b/test/files/pos/t2377b/a.scala new file mode 100644 index 0000000000..14be23cfa2 --- /dev/null +++ b/test/files/pos/t2377b/a.scala @@ -0,0 +1,3 @@ +object Test { + (new Q.Inner).foo // make sure foo's type is well-formed +} |