-
Notifications
You must be signed in to change notification settings - Fork 21
Scala's java interop disallows access to Scala nested class from Java #10490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Labels
Milestone
Comments
Related #3120. I'm trying to fix this issue. |
jvican
added a commit
to scalacenter/scala
that referenced
this issue
Sep 2, 2017
Java type selections, for example `Foo.Bar`, can represent two different trees depending on the context. On the one hand, it can be a type selection over an object `Foo`. On the other hand, it can be a type selection over a type (that is, a selection of a nested class). However, when we parse the Scala signatures is not possible to know which case the user meant. For example, `Foo.Bar` could be either: 1. `Select(Ident(TermName("Foo")), TypeName("Bar"))`; or 2. `SelectFromTypeTree(Ident(TypeName("Foo")), TypeName("Bar"))`. By default, the Scala compiler parses `Foo.Bar` in a type position as the first option, but it could very well be the case that the user meant the second one, as specified by the tests in this commit. To address the issue, then, there's nothing but the ugly solution of injecting special logic into typer so that we try to typecheck both trees for those different scenarios. To handle this specific logic and try to make it as isolated as possible, I've introduced a new context mode called `JavaTypeSelection`. This context mode is set by `typedSelectOrSuperCall` when the compilation unit is Java, the tree at hands select a type name and the qualifier is an identifier. `typedIdent` detects when this mode is on, and if the default term symbol lookup fails it tries to find the type symbol. If that succeeds, it then delegates to `typedType`. The different returning trees are handled in `typedSelectOrSuperCall`. Run tests in this commit illustrate both accesses. They are independent because if t10490 had the `Foo` companion, the bug that this commit fixes wouldn't have been required (i.e. it's a very subtle workaround).
jvican
added a commit
to scalacenter/scala
that referenced
this issue
Sep 2, 2017
Java type selections, for example `Foo.Bar`, can represent two different trees depending on the context. On the one hand, it can be a type selection over an object `Foo`. On the other hand, it can be a type selection over a type (that is, a selection of a nested class). However, when we parse the Scala signatures is not possible to know which case the user meant. For example, `Foo.Bar` could be either: 1. `Select(Ident(TermName("Foo")), TypeName("Bar"))`; or 2. `SelectFromTypeTree(Ident(TypeName("Foo")), TypeName("Bar"))`. By default, the Scala compiler parses `Foo.Bar` in a type position as the first option, but it could very well be the case that the user meant the second one, as specified by the tests in this commit. To address the issue, then, there's nothing but the ugly solution of injecting special logic into typer so that we try to typecheck both trees for those different scenarios. To handle this specific logic and try to make it as isolated as possible, I've introduced a new context mode called `JavaTypeSelection`. This context mode is set by `typedSelectOrSuperCall` when the compilation unit is Java, the tree at hands select a type name and the qualifier is an identifier. `typedIdent` detects when this mode is on, and if the default term symbol lookup fails it tries to find the type symbol. If that succeeds, it then delegates to `typedType`. The different returning trees are handled in `typedSelectOrSuperCall`. Run tests in this commit illustrate both accesses. They are independent because if t10490 had the `Foo` companion, the bug that this commit fixes wouldn't have been required (i.e. it's a very subtle workaround).
jvican
added a commit
to scalacenter/scala
that referenced
this issue
Sep 25, 2017
Java type selections, for example `Foo.Bar`, can represent two different trees depending on the context. On the one hand, it can be a type selection over an object `Foo`. On the other hand, it can be a type selection over a type (that is, a selection of a nested class). However, when we parse the Scala signatures is not possible to know which case the user meant. For example, `Foo.Bar` could be either: 1. `Select(Ident(TermName("Foo")), TypeName("Bar"))`; or 2. `SelectFromTypeTree(Ident(TypeName("Foo")), TypeName("Bar"))`. By default, the Scala compiler parses `Foo.Bar` in a type position as the first option, but it could very well be the case that the user meant the second one, as specified by the tests in this commit. To address the issue, then, there's nothing but the ugly solution of injecting special logic into typer so that we try to typecheck both trees for those different scenarios. To handle this specific logic and try to make it as isolated as possible, I've introduced a new context mode called `JavaTypeSelection`. This context mode is set by `typedSelectOrSuperCall` when the compilation unit is Java, the tree at hands select a type name and the qualifier is an identifier. `typedIdent` detects when this mode is on, and if the default term symbol lookup fails it tries to find the type symbol. If that succeeds, it then delegates to `typedType`. The different returning trees are handled in `typedSelectOrSuperCall`. Run tests in this commit illustrate both accesses. They are independent because if t10490 had the `Foo` companion, the bug that this commit fixes wouldn't have been required (i.e. it's a very subtle workaround). Fixes scala/bug#10490.
jvican
added a commit
to scalacenter/scala
that referenced
this issue
Sep 25, 2017
Java type selections, for example `Foo.Bar`, can represent two different trees depending on the context. On the one hand, it can be a type selection over an object `Foo`. On the other hand, it can be a type selection over a type (that is, a selection of a nested class). However, when we parse the Scala signatures is not possible to know which case the user meant. For example, `Foo.Bar` could be either: 1. `Select(Ident(TermName("Foo")), TypeName("Bar"))`; or 2. `SelectFromTypeTree(Ident(TypeName("Foo")), TypeName("Bar"))`. By default, the Scala compiler parses `Foo.Bar` in a type position as the first option, but it could very well be the case that the user meant the second one, as specified by the tests in this commit. To address the issue, then, there's nothing but the ugly solution of injecting special logic into typer so that we try to typecheck both trees for those different scenarios. To handle this specific logic and try to make it as isolated as possible, I've introduced a new context mode called `JavaTypeSelection`. This context mode is set by `typedSelectOrSuperCall` when the compilation unit is Java, the tree at hands select a type name and the qualifier is an identifier. `typedIdent` detects when this mode is on, and if the default term symbol lookup fails it tries to find the type symbol. If that succeeds, it then delegates to `typedType`. The different returning trees are handled in `typedSelectOrSuperCall`. Run tests in this commit illustrate both accesses. They are independent because if t10490 had the `Foo` companion, the bug that this commit fixes wouldn't have been required (i.e. it's a very subtle workaround). Fixes scala/bug#10490.
bishabosha
pushed a commit
to scalacenter/scala
that referenced
this issue
Jun 26, 2020
Java type selections, for example `Foo.Bar`, can represent two different trees depending on the context. On the one hand, it can be a type selection over an object `Foo`. On the other hand, it can be a type selection over a type (that is, a selection of a nested class). However, when we parse the Scala signatures is not possible to know which case the user meant. For example, `Foo.Bar` could be either: 1. `Select(Ident(TermName("Foo")), TypeName("Bar"))`; or 2. `SelectFromTypeTree(Ident(TypeName("Foo")), TypeName("Bar"))`. By default, the Scala compiler parses `Foo.Bar` in a type position as the first option, but it could very well be the case that the user meant the second one, as specified by the tests in this commit. To address the issue, then, there's nothing but the ugly solution of injecting special logic into typer so that we try to typecheck both trees for those different scenarios. To handle this specific logic and try to make it as isolated as possible, I've introduced a new context mode called `JavaTypeSelection`. This context mode is set by `typedSelectOrSuperCall` when the compilation unit is Java, the tree at hands select a type name and the qualifier is an identifier. `typedIdent` detects when this mode is on, and if the default term symbol lookup fails it tries to find the type symbol. If that succeeds, it then delegates to `typedType`. The different returning trees are handled in `typedSelectOrSuperCall`. Run tests in this commit illustrate both accesses. They are independent because if t10490 had the `Foo` companion, the bug that this commit fixes wouldn't have been required (i.e. it's a very subtle workaround). Fixes scala/bug#10490.
The associated PR was superseded scala/scala#7671 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Imagine you're compiling in mixed mode and you have a cyclic dependency between Java and Scala code. In particular, Java wants to access a nested class defined in an Scala class. This is often necessary when you want to define some field or method as static. Let's assume they're defined in the same package
java.interop.bug
.If you compile this in mixed mode, first scalac will run. Scalac will parse the java signature and will give the following compile error:
This happens because Scalac assumes that
Bar
is defined in a companion object (value) namedFoo
. This assumption is incorrect because it doesn't take into account thatBar
could also be a nested class defined inFoo
.I think this should be easy to fix, but I may be wrong. I've run into this issue twice: now, hacking on statistics in Scalac; and in the past while hacking on Zinc's Java API, which is also compiled in mixed mode.
The text was updated successfully, but these errors were encountered: