Skip to content

Commit d188b71

Browse files
authored
Merge pull request scala#10823 from som-snytt/issue/11788-java-pkg
Use Java lookup rule for root of selection
2 parents c30afe3 + f64a398 commit d188b71

File tree

11 files changed

+75
-4
lines changed

11 files changed

+75
-4
lines changed

src/compiler/scala/tools/nsc/javac/JavaParsers.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
297297
if (in.token == FINAL) in.nextToken()
298298
if (in.token == IDENTIFIER) {
299299
var t = typeArgs(atPos(in.currentPos)(Ident(ident())))
300-
// typeSelect generates Select nodes is the lhs is an Ident or Select,
300+
// typeSelect generates Select nodes if the lhs is an Ident or Select,
301301
// SelectFromTypeTree otherwise. See #3567.
302302
// Select nodes can be later
303303
// converted in the typechecker to SelectFromTypeTree if the class
@@ -306,6 +306,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
306306
case Ident(_) | Select(_, _) => Select(t, name)
307307
case _ => SelectFromTypeTree(t, name.toTypeName)
308308
}
309+
if (in.token == DOT)
310+
t.updateAttachment(RootSelection)
309311
while (in.token == DOT) {
310312
in.nextToken()
311313
t = typeArgs(atPos(in.currentPos)(typeSelect(t, ident())))

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5391,12 +5391,31 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
53915391
if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree
53925392
}
53935393

5394-
53955394
// For Java, instance and static members are in the same scope, but we put the static ones in the companion object
53965395
// so, when we can't find a member in the class scope, check the companion
53975396
def inCompanionForJavaStatic(cls: Symbol, name: Name): Symbol =
53985397
if (!(context.unit.isJava && cls.isClass)) NoSymbol
53995398
else context.javaFindMember(cls.typeOfThis, name, s => s.isStaticMember || s.isStaticModule)._2
5399+
// For Java, a selection p.q requires checking if p is a type with member q; otherwise it is a package.
5400+
// If a non-package term was found, look for a class; otherwise just look for a package.
5401+
def repairJavaSelection(qual: Tree, name: Name): Symbol =
5402+
if (!context.unit.isJava || !qual.hasAttachment[RootSelection.type] || qual.symbol.hasPackageFlag) NoSymbol
5403+
else qual match {
5404+
case Ident(qname) =>
5405+
val found =
5406+
if (qual.symbol.isTerm) {
5407+
val lookup = context.lookupSymbol(qname.toTypeName, s => qualifies(s) && s.isClass)
5408+
if (lookup.isSuccess) inCompanionForJavaStatic(lookup.symbol, name) else NoSymbol
5409+
}
5410+
else NoSymbol
5411+
found.orElse {
5412+
context.lookupSymbol(qname, s => qualifies(s) && s.hasPackageFlag) match {
5413+
case LookupSucceeded(_, pkg) => member(pkg.info, name)
5414+
case _ => NoSymbol
5415+
}
5416+
}
5417+
case _ => NoSymbol
5418+
}
54005419

54015420
// If they try C.tupled, make it (C.apply _).tupled
54025421
def fixUpCaseTupled(tree: Tree, qual: Tree, name: Name, mode: Mode): Tree =
@@ -5435,7 +5454,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
54355454
if (!isPastTyper && isUniversalMember(result.symbol))
54365455
context.warning(tree.pos, s"dubious usage of ${result.symbol} with unit value", WarningCategory.LintUniversalMethods)
54375456

5438-
val sym = tree.symbol orElse member(qualTp, name) orElse inCompanionForJavaStatic(qualTp.typeSymbol, name)
5457+
val sym = tree.symbol
5458+
.orElse(member(qualTp, name))
5459+
.orElse(inCompanionForJavaStatic(qualTp.typeSymbol, name))
5460+
.orElse(repairJavaSelection(qual, name))
54395461
if ((sym eq NoSymbol) && name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) {
54405462
// symbol not found? --> try to convert implicitly to a type that does have the required
54415463
// member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an
@@ -5655,7 +5677,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
56555677
startContext.lookupSymbol(name.toTypeName, qualifies).symbol
56565678
} else NoSymbol
56575679

5658-
// in Java, only pick a package if it is rooted
5680+
// in Java, only pick a package p if it is rooted (no relative packaging)
56595681
def termQualifies(sym: Symbol) = qualifies(sym) && (
56605682
!startContext.unit.isJava || !sym.hasPackageFlag
56615683
|| sym.owner.isEffectiveRoot || sym.owner.isRootPackage || sym.isRootPackage

test/files/neg/t11788.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
t11788/Foo.java:5: error: cannot find symbol
2+
return java.lang.Integer.valueOf(42);
3+
^
4+
symbol: variable lang
5+
location: variable java of type String
6+
1 error

test/files/neg/t11788/Bar.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Bar extends App {
2+
println(new Foo().test())
3+
}

test/files/neg/t11788/Foo.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class Foo {
2+
private String java;
3+
4+
public java.lang.Integer test() {
5+
return java.lang.Integer.valueOf(42);
6+
}
7+
}

test/files/neg/t11788b.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
t11788b/Foo.java:5: error: incompatible types: java.lang.Integer cannot be converted to java.lang.Integer
2+
return Integer.valueOf(42);
3+
^
4+
1 error

test/files/neg/t11788b/Bar.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Bar extends App {
2+
println(new Foo().test())
3+
}

test/files/neg/t11788b/Foo.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class Foo {
2+
private String java;
3+
4+
public java.lang.Integer test() {
5+
return Integer.valueOf(42);
6+
}
7+
}

test/files/neg/t11788b/java.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
public class java {
3+
public static class lang {
4+
public static class Integer {
5+
}
6+
}
7+
}

test/files/pos/t11788/Bar.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Bar extends App {
2+
println(new Foo().test())
3+
}

0 commit comments

Comments
 (0)