[
https://issues.apache.org/jira/browse/GROOVY-9273?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18141992#comment-18141992
]
ASF GitHub Bot commented on GROOVY-9273:
----------------------------------------
daniellansun commented on PR #3235:
URL: https://github.com/apache/groovy/pull/3235#issuecomment-6768672082
The module declaration is not a class (JLS §7.3, §7.7), and the per-class
pipeline is what we needed to reuse. `visitModuleDeclaration` builds a
`ModuleInfoNode` for the directives, then a carrier `ClassNode` named
`module-info` (`ACC_ABSTRACT | ACC_INTERFACE`) so resolution, annotation
checking, and class writing already have a class to visit. The declaration
itself has no field on `ClassNode`. Groovy's `ModuleNode` is the source unit,
so it is the wrong place to hang a JPMS module.
`putNodeMetaData(ModuleInfoNode.class, declaration)` is how
`ModuleInfoVerifier` and `AsmClassGenerator.emitModuleInfo` find the
directives; emission then writes a real `ACC_MODULE` class
(`module-info.class`, JVMS §4.7.25) and does not write the interface.
Annotations are also copied onto the carrier so `ExtendedVerifier` can check
`ElementType.MODULE`.
That does affect the joint compiler, and the stub generator is wrong for
this carrier today.
`JavaAwareCompilationUnit` runs `JavaStubGenerator.generateClass` at
`CONVERSION` for every non-private top-level class once any `.java` file is in
the compile. The carrier is that kind of class. The generator never reads node
metadata. It already special-cases a class named `package-info` and emits only
a package statement; it has no such case for `module-info`.
`generateStubContent` therefore prints a type, approximately:
```java
interface module-info {
}
```
into `module-info.java` (`createJavaStubFile` uses the class name). Two
problems follow. `module-info` is not a Java identifier, and JLS §7.3 makes
`module-info.java` a modular compilation unit: javac requires a module
declaration there, not a type. Joint compilation of `module-info.groovy`
together with any `.java` file fails at javac. Compiling the `.groovy` file
alone does not generate stubs, and ordinary Groovy classes in a joint compile
do not carry this metadata, so they are unaffected.
Metadata is not dropped inside this compilation unit. The stub generator
reads the same primary `ClassNode` it was given; `emitModuleInfo` still sees
`ModuleInfoNode.of` later. The failure is that the stubber never looks at the
key, so it treats the carrier as an interface. A copy that does not call
`copyNodeMetaData` (for example `ClassNode.getPlainNodeReference`) would also
lose the declaration and then really emit an interface class file.
What should change: `JavaStubGenerator.generateClass` should skip a class
for which `ModuleInfoNode.of(classNode)` is non-null, the same way it refuses
to emit a type for `package-info`. Sibling `.java` files in this joint compiler
are compiled from the classpath, not as a module-source-path compile, so javac
does not need a `module-info.java` stub to compile them. Groovy still writes
`module-info.class` at class generation. If we would rather have javac own the
descriptor, the stub has to be the JLS §7.7 declaration transcribed from
`ModuleInfoNode`, and Groovy must not write `module-info.class` as well. Either
fix is a special case in the stub generator; leaving the carrier as an ordinary
interface is what breaks the joint compile.
I will skip that carrier in `JavaStubGenerator.generateClass`, the same way
`package-info` is special-cased, and add a joint-compilation test.
> Support module descriptor, aka. module-info
> -------------------------------------------
>
> Key: GROOVY-9273
> URL: https://issues.apache.org/jira/browse/GROOVY-9273
> Project: Groovy
> Issue Type: New Feature
> Reporter: Daniel Sun
> Priority: Major
>
>
> [https://openjdk.java.net/projects/jigsaw/quick-start]
> [http://tutorials.jenkov.com/java/modules.html#java-module-basics]
> [https://www.oracle.com/corporate/features/understanding-java-9-modules.html]
> [https://www.concretepage.com/java/java-9/java-module]
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)