diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-03-11 22:12:11 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-03-26 08:48:47 +0100 |
commit | 8383b65fb53ae9424cf9c6f1314ee73321ad3b9a (patch) | |
tree | dc9c1a18064a0f8f990f87ca22c8a7d24e5b286c | |
parent | 59d4998cf4a19eb5d44118d4867c2370e9a935e5 (diff) | |
download | scala-8383b65fb53ae9424cf9c6f1314ee73321ad3b9a.tar.gz scala-8383b65fb53ae9424cf9c6f1314ee73321ad3b9a.tar.bz2 scala-8383b65fb53ae9424cf9c6f1314ee73321ad3b9a.zip |
SI-7232 Fix Java import vs defn. binding precendence
Java Spec:
> A single-type-import declaration d in a compilation unit c
> of package p that imports a type named n shadows, throughout
> c, the declarations of:
> - any top level type named n declared in another compilation
> unit of p
> - any type named n imported by a type-import-on-demand
> declaration in c
> - any type named n imported by a static-import-on-demand
> declaration in c
Scala Spec:
> Bindings of different kinds have a precedence defined on them:
> 1. Definitions and declarations that are local, inherited, or made
> available by a package clause in the same compilation unit where
> the definition occurs have highest precedence.
> 2. Explicit imports have next highest precedence.
This is a forward port of 6e79370, which did not merge cleanly
and was omitted in the regular merge from 2.10.x to master.
Conflicts:
src/compiler/scala/tools/nsc/typechecker/Typers.scala
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 8 | ||||
-rw-r--r-- | test/files/pos/t7232.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t7232/Foo.java | 9 | ||||
-rw-r--r-- | test/files/pos/t7232/List.java | 4 | ||||
-rw-r--r-- | test/files/pos/t7232/Test.scala | 5 | ||||
-rw-r--r-- | test/files/pos/t7232b.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t7232b/Foo.java | 8 | ||||
-rw-r--r-- | test/files/pos/t7232b/List.java | 5 | ||||
-rw-r--r-- | test/files/pos/t7232b/Test.scala | 5 | ||||
-rw-r--r-- | test/files/pos/t7232c.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t7232c/Foo.java | 10 | ||||
-rw-r--r-- | test/files/pos/t7232c/Test.scala | 4 | ||||
-rw-r--r-- | test/files/pos/t7232d.flags | 1 | ||||
-rw-r--r-- | test/files/pos/t7232d/Entry.java | 4 | ||||
-rw-r--r-- | test/files/pos/t7232d/Foo.java | 8 | ||||
-rw-r--r-- | test/files/pos/t7232d/Test.scala | 4 |
17 files changed, 96 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 9d5a9c819c..272e7af48b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -912,7 +912,25 @@ trait Contexts { self: Analyzer => def lookupImport(imp: ImportInfo, requireExplicit: Boolean) = importedAccessibleSymbol(imp, name, requireExplicit) filter qualifies - while (!impSym.exists && imports.nonEmpty && imp1.depth > symbolDepth) { + // Java: A single-type-import declaration d in a compilation unit c of package p + // that imports a type named n shadows, throughout c, the declarations of: + // + // 1) any top level type named n declared in another compilation unit of p + // + // A type-import-on-demand declaration never causes any other declaration to be shadowed. + // + // Scala: Bindings of different kinds have a precedence defined on them: + // + // 1) Definitions and declarations that are local, inherited, or made available by a + // package clause in the same compilation unit where the definition occurs have + // highest precedence. + // 2) Explicit imports have next highest precedence. + def depthOk(imp: ImportInfo) = ( + imp.depth > symbolDepth + || (unit.isJava && imp.isExplicitImport(name) && imp.depth == symbolDepth) + ) + + while (!impSym.exists && imports.nonEmpty && depthOk(imports.head)) { impSym = lookupImport(imp1, requireExplicit = false) if (!impSym.exists) imports = imports.tail diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index e966cc9060..9bdf429dce 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -530,7 +530,13 @@ trait Namers extends MethodSynthesis { // Setting the position at the import means that if there is // more than one hidden name, the second will not be warned. // So it is the position of the actual hidden name. - checkNotRedundant(tree.pos withPoint fromPos, from, to) + // + // Note: java imports have precence over definitions in the same package + // so don't warn for them. There is a corresponding special treatment + // in the shadowing rules in typedIdent to (SI-7232). In any case, + // we shouldn't be emitting warnings for .java source files. + if (!context.unit.isJava) + checkNotRedundant(tree.pos withPoint fromPos, from, to) } } diff --git a/test/files/pos/t7232.flags b/test/files/pos/t7232.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7232.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t7232/Foo.java b/test/files/pos/t7232/Foo.java new file mode 100644 index 0000000000..3478301b30 --- /dev/null +++ b/test/files/pos/t7232/Foo.java @@ -0,0 +1,9 @@ +package pack; + +import java.util.List; + +public class Foo { + public static java.util.List okay() { throw new Error(); } + + public static List wrong() { throw new Error(); } +} diff --git a/test/files/pos/t7232/List.java b/test/files/pos/t7232/List.java new file mode 100644 index 0000000000..e42c63aa67 --- /dev/null +++ b/test/files/pos/t7232/List.java @@ -0,0 +1,4 @@ +package pack; + +public class List { +} diff --git a/test/files/pos/t7232/Test.scala b/test/files/pos/t7232/Test.scala new file mode 100644 index 0000000000..49c3c12aed --- /dev/null +++ b/test/files/pos/t7232/Test.scala @@ -0,0 +1,5 @@ +object Test { + import pack._ + Foo.okay().size() + Foo.wrong().size() +} diff --git a/test/files/pos/t7232b.flags b/test/files/pos/t7232b.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7232b.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t7232b/Foo.java b/test/files/pos/t7232b/Foo.java new file mode 100644 index 0000000000..94f08d545e --- /dev/null +++ b/test/files/pos/t7232b/Foo.java @@ -0,0 +1,8 @@ +package pack; + +import java.util.*; + +public class Foo { + // should be pack.List. + public static List list() { throw new Error(); } +} diff --git a/test/files/pos/t7232b/List.java b/test/files/pos/t7232b/List.java new file mode 100644 index 0000000000..ce977152b9 --- /dev/null +++ b/test/files/pos/t7232b/List.java @@ -0,0 +1,5 @@ +package pack; + +public class List { + public void packList() {} +} diff --git a/test/files/pos/t7232b/Test.scala b/test/files/pos/t7232b/Test.scala new file mode 100644 index 0000000000..6377e26bec --- /dev/null +++ b/test/files/pos/t7232b/Test.scala @@ -0,0 +1,5 @@ +object Test { + import pack._ + + Foo.list().packList() +} diff --git a/test/files/pos/t7232c.flags b/test/files/pos/t7232c.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7232c.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t7232c/Foo.java b/test/files/pos/t7232c/Foo.java new file mode 100644 index 0000000000..bbda09a2da --- /dev/null +++ b/test/files/pos/t7232c/Foo.java @@ -0,0 +1,10 @@ +package pack; + +import java.util.List; + +public class Foo { + public static class List { + public void isInnerList() {} + } + public static List innerList() { throw new Error(); } +} diff --git a/test/files/pos/t7232c/Test.scala b/test/files/pos/t7232c/Test.scala new file mode 100644 index 0000000000..aa7c710948 --- /dev/null +++ b/test/files/pos/t7232c/Test.scala @@ -0,0 +1,4 @@ +object Test { + import pack._ + Foo.innerList().isInnerList() +} diff --git a/test/files/pos/t7232d.flags b/test/files/pos/t7232d.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7232d.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t7232d/Entry.java b/test/files/pos/t7232d/Entry.java new file mode 100644 index 0000000000..0cfb6fb25b --- /dev/null +++ b/test/files/pos/t7232d/Entry.java @@ -0,0 +1,4 @@ +package pack; + +public class Entry { +} diff --git a/test/files/pos/t7232d/Foo.java b/test/files/pos/t7232d/Foo.java new file mode 100644 index 0000000000..df7114a0f0 --- /dev/null +++ b/test/files/pos/t7232d/Foo.java @@ -0,0 +1,8 @@ +package pack; + +import java.util.Map.Entry; + +public class Foo { + public static Entry mapEntry() { throw new Error(); } + public static void javaTest() { mapEntry().getKey(); } +} diff --git a/test/files/pos/t7232d/Test.scala b/test/files/pos/t7232d/Test.scala new file mode 100644 index 0000000000..89a8063b3c --- /dev/null +++ b/test/files/pos/t7232d/Test.scala @@ -0,0 +1,4 @@ +object Test { + import pack._ + Foo.mapEntry().getKey() +} |