-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
8335989: Implement JEP 494: Module Import Declarations (Second Preview) #21431
Conversation
👋 Welcome back jlahoda! A progress list of the required criteria for merging this PR into |
@lahodaj This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 21 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
/jep JDK-8335987 |
@lahodaj |
assertEquals(javaBase.modifiers(), Set.of(Modifier.TRANSITIVE)); | ||
} | ||
|
||
private byte[] setClassFileVersion(int major, int minor, byte[] bytecode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to add a method description and re-format the overly long lines as it's currently impossible to look at the change side-by-side.
Can you check if test/jdk/java/lang/module/ClassFileVersionsTest.java should be updated too? |
@@ -189,6 +190,7 @@ private Attributes doRead(DataInput input) throws IOException { | |||
|
|||
int minor_version = in.readUnsignedShort(); | |||
int major_version = in.readUnsignedShort(); | |||
boolean previewClassfile = minor_version == ClassFile.PREVIEW_MINOR_VERSION; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you rename this to isPreview then it would make the uses further down easier to read.
!previewClassfile && | ||
//java.* modules are deemed participating in preview | ||
//and are allowed to use requires transitive java.base: | ||
!mn.startsWith("java.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A block comment before the if
statement would be a lot clearer here.
|
||
enum ScopeType { | ||
ORDINARY, | ||
START_IMPORT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a "start" import or a "star"* import? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Star import. Will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
return | ||
s == sym && | ||
!it.hasNext(); | ||
for (Scope scope : new Scope[] {toplevel.namedImportScope, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we could deal with this with a compound scope? (and avoid the loop)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In principle, we could, but the CompoundScope
is a bit heavier, so it might be better to keep the loop here.
@@ -450,16 +451,20 @@ private void doImport(JCImport tree) { | |||
if (name == names.asterisk) { | |||
// Import on demand. | |||
chk.checkCanonical(imp.selected); | |||
if (tree.staticImport) | |||
if (tree.staticImport) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I note a discrepancy here - static imports are reflected in the AST, but module import aren't. This is why we need to pass an extra parameter to this method, I believe. Should we generalize the import tree node to have a bunch of flags?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, I see why you need the flag - the code is building synthetic import statements on the fly, based on the packages exported by a module - and then you need to import these synthetic imports, but remember that they originated from an import module...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes in the import machinery look good (TypeEnter/Resolve).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good!
@@ -189,6 +190,7 @@ private Attributes doRead(DataInput input) throws IOException { | |||
|
|||
int minor_version = in.readUnsignedShort(); | |||
int major_version = in.readUnsignedShort(); | |||
boolean isPreview = minor_version == ClassFile.PREVIEW_MINOR_VERSION; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will need to throw invalidModuleDescriptor if isPreview && major version != ClassFile.latestMajorVersion, otherwise the check in readModuleAttribute will be defeated by hand craft class files (the VM doesn't read module-info class files so it won't reject it, and this code is called from exposed APIs such as ModuleDescriptor.read).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the check is already being done, right on the next line:
if (!VM.isSupportedModuleDescriptorVersion(major_version, minor_version)) { |
which leads to:
public static boolean isSupportedModuleDescriptorVersion(int major, int minor) { |
which then leads to:
public static boolean isSupportedClassFileVersion(int major, int minor) { |
which has this check:
return minor == 0 || (minor == ClassFile.PREVIEW_MINOR_VERSION && major == ClassFile.latestMajorVersion()); |
I tried with a module-info.class
with major version 65, and minor version 0xFFFF, and it correctly threw the exception for me.
Do I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I miss something?
Okay, so this must have been modified at some point to add/use isSupportedModuleDescriptorVersion, in which case readModuleAttribute won't be called. In that case, what you have is okay.
Minor nit, can you fix up the code style in the modified expression as it has ended up with && at the start and end of lines which looks a bit messy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, done:
9ae10e2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
/integrate |
Going to push as commit 1e97c1c.
Your commit was automatically rebased without conflicts. |
This is a current patch for module imports declarations, second preview. At least the JEP number and preview revision will need to be updated in
jdk.internal.javac.PreviewFeature.Feature
, but otherwise I believe this is ready to receive feedback.The main changes are:
requires transitive java.base;
is permitted, under the preview flag. Both javac and the runtime module system are updated to accept this directive when preview is enabled.java.se
module is usingrequires transitive java.base;
, and is deemed to be participating in preview, so its classfile version is not tainted. Runtime is updated to accessrequires transitive java.base;
in anyjava.*
, considering all of them to be participating in preview. Can be tighten up to onlyjava.se
is desired.but:
Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/21431/head:pull/21431
$ git checkout pull/21431
Update a local copy of the PR:
$ git checkout pull/21431
$ git pull https://git.openjdk.org/jdk.git pull/21431/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 21431
View PR using the GUI difftool:
$ git pr show -t 21431
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/21431.diff
Using Webrev
Link to Webrev Comment