diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-03-16 16:26:32 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-03-26 09:13:26 +0100 |
commit | 7d03dcc45ff3b892bc5db8c9f334697c103e767a (patch) | |
tree | d70bba55c0b5540d6cde71dd3620ba5bf23574a4 | |
parent | 59d4998cf4a19eb5d44118d4867c2370e9a935e5 (diff) | |
download | scala-7d03dcc45ff3b892bc5db8c9f334697c103e767a.tar.gz scala-7d03dcc45ff3b892bc5db8c9f334697c103e767a.tar.bz2 scala-7d03dcc45ff3b892bc5db8c9f334697c103e767a.zip |
SI-7259 Fix detection of Java defined Selects
The fix for SI-3120, 3ff7743, introduced a fallback within
`typedSelect` that accounted for the ambiguity of a Java
selection syntax. Does `A.B` refer to a member of the type `A`
or of the companion object `A`? (The companion object here is a
fiction used by scalac to group the static members of a Java
class.)
The fallback in `typedSelect` was predicated on
`context.owner.enclosingTopLevelClass.isJavaDefined`.
However, this was incorrectly including Select-s in top-level
annotations in Scala files, which are owned by the enclosing
package class, which is considered to be Java defined. This
led to nonsensical error messages ("type scala not found.")
Instead, this commit checks the compilation unit of the context,
which is more direct and correct. (As I learned recently,
`currentUnit.isJavaDefined` would *not* be correct, as a lazy type
might complete a Java signature while compiling some other compilation
unit!)
A bonus post factum test case is included for SI-3120.
Manual forward port of f046853 which was not merged as
part of the routine 2.10.x to master merge. The test case
uncovered a NullPointerExceptiion crasher in annotation
typechecking introduced in 5878099c; this has been prevented
with a null check.
Conflicts:
src/compiler/scala/tools/nsc/typechecker/Typers.scala
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 | ||||
-rw-r--r-- | test/files/neg/t7259.check | 7 | ||||
-rw-r--r-- | test/files/neg/t7259.scala | 9 | ||||
-rw-r--r-- | test/files/pos/t3120/J1.java | 4 | ||||
-rw-r--r-- | test/files/pos/t3120/J2.java | 4 | ||||
-rw-r--r-- | test/files/pos/t3120/Q.java | 3 | ||||
-rw-r--r-- | test/files/pos/t3120/Test.scala | 3 |
7 files changed, 34 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 0e57145343..7cbae17bd9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3558,7 +3558,7 @@ trait Typers extends Adaptations with Tags { // If there are dummy type arguments in typeFun part, it suggests we // must type the actual constructor call, not only the select. The value // arguments are how the type arguments will be inferred. - if (targs.isEmpty && typedFun0.exists(t => isDummyAppliedType(t.tpe))) + if (targs.isEmpty && typedFun0.exists(t => t.tpe != null && isDummyAppliedType(t.tpe))) logResult(s"Retyped $typedFun0 to find type args")(typed(argss.foldLeft(fun0)(Apply(_, _)))) else typedFun0 @@ -4692,7 +4692,9 @@ trait Typers extends Adaptations with Tags { def handleMissing: Tree = { def errorTree = missingSelectErrorTree(tree, qual, name) def asTypeSelection = ( - if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { + if (context.unit.isJava && name.isTypeName) { + // SI-3120 Java uses the same syntax, A.B, to express selection from the + // value A and from the type A. We have to try both. atPos(tree.pos)(gen.convertToSelectFromType(qual, name)) match { case EmptyTree => None case tree1 => Some(typed1(tree1, mode, pt)) diff --git a/test/files/neg/t7259.check b/test/files/neg/t7259.check new file mode 100644 index 0000000000..0ad627fc3b --- /dev/null +++ b/test/files/neg/t7259.check @@ -0,0 +1,7 @@ +t7259.scala:1: error: not found: type xxxxx +@xxxxx // error: not found: type xxxx + ^ +t7259.scala:8: error: type xxxxx is not a member of package annotation +@annotation.xxxxx // error: not found: type scala + ^ +two errors found diff --git a/test/files/neg/t7259.scala b/test/files/neg/t7259.scala new file mode 100644 index 0000000000..0fdfe18822 --- /dev/null +++ b/test/files/neg/t7259.scala @@ -0,0 +1,9 @@ +@xxxxx // error: not found: type xxxx +class Ok + +// +// This had the wrong error message in 2.9 and 2.10. +// + +@annotation.xxxxx // error: not found: type scala +class WrongErrorMessage diff --git a/test/files/pos/t3120/J1.java b/test/files/pos/t3120/J1.java new file mode 100644 index 0000000000..12b23c1c98 --- /dev/null +++ b/test/files/pos/t3120/J1.java @@ -0,0 +1,4 @@ +class J1 { + public class Inner1 { } + public static class Inner2 { } +} diff --git a/test/files/pos/t3120/J2.java b/test/files/pos/t3120/J2.java new file mode 100644 index 0000000000..db6e859020 --- /dev/null +++ b/test/files/pos/t3120/J2.java @@ -0,0 +1,4 @@ +public class J2 { + public void f1(J1.Inner1 p) { } + public void f2(J1.Inner2 p) { } +} diff --git a/test/files/pos/t3120/Q.java b/test/files/pos/t3120/Q.java new file mode 100644 index 0000000000..fe2269308a --- /dev/null +++ b/test/files/pos/t3120/Q.java @@ -0,0 +1,3 @@ +public class Q { + public static void passInner(J1.Inner1 myInner) {} +} diff --git a/test/files/pos/t3120/Test.scala b/test/files/pos/t3120/Test.scala new file mode 100644 index 0000000000..c02146fba1 --- /dev/null +++ b/test/files/pos/t3120/Test.scala @@ -0,0 +1,3 @@ +object Test { + Q.passInner(null) +} |