Skip to content

JavaParsers doesn't support JEP 445: Unnamed Classes and Instance Main Methods #12878

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

Open
xuwei-k opened this issue Sep 22, 2023 · 4 comments · May be fixed by scala/scala#11066
Open

JavaParsers doesn't support JEP 445: Unnamed Classes and Instance Main Methods #12878

xuwei-k opened this issue Sep 22, 2023 · 4 comments · May be fixed by scala/scala#11066

Comments

@xuwei-k
Copy link

xuwei-k commented Sep 22, 2023

Reproduction steps

A.java

void main() {
  System.out.println("hello");
}

B.scala

class B

build.sbt

javacOptions ++= Seq(
  "-Xlint:preview",
  "--enable-preview",
  "--release",
  scala.util.Properties.javaSpecVersion
)

scalaVersion := "2.13.12"

project/build.properties

sbt.version=1.9.6

Problem

sbt -J--enable-preview compile

https://github.com/scala/scala/blob/e67d287447c09720468f8bebcb0302bd92d75f43/src/compiler/scala/tools/nsc/javac/JavaParsers.scala#L1074

[error] /home/runner/work/Scala-JEP-445/Scala-JEP-445/A.java:1:6: illegal start of type declaration
[error] void main() {
[error]      ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
@xuwei-k
Copy link
Author

xuwei-k commented May 16, 2025

https://openjdk.org/jeps/512 finalize in JDK 25

@som-snytt
Copy link

It kind of makes you not want to support Java.

@lrytz
Copy link
Member

lrytz commented May 21, 2025

Support for simpler main methods seems to just work with Scala bytecode

$ cat T.scala
class T {
  def main(): Unit = println("hi")
}

$ sc T.scala
> scala compile --server=false -S 2.13 -d . -release 8 T.scala

$ java -version
openjdk version "25-ea" 2025-09-16

$ sr T
> scala run -S 2.13 -cp . -M T
hi

@lrytz
Copy link
Member

lrytz commented May 22, 2025

Took a quick look. Spec diff (via https://docs.oracle.com/javase/specs/).

Quirks


// T.java
class K
void main() { }

This defines classes T and T$K. Commenting the main method turns the class K top-level. So the nesting in final class T { ... } has to happen at the end of parsing the compilation unit.


Compact compilation units have an implicit import module java.base which brings more symbols in scope than the import java.lang.* in ordinary compilation units.

import module x is not supported in Scala 2.13 nor Scala 3 (scala/scala-dev#529).


With the version I tested (25-ea+22-2667), a compact compilation unit cannot referenced in joint compilation (as expected by the JEP). But the resulting Filename.class can be referenced in separate compilation.


Perhaps the best way to support this JEP is to set unit.body = EmptyTree when encountering a sparse compilation unit. What ever is in there cannot be referenced anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants