Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ public enum Feature {
STRUCTURED_CONCURRENCY,
CLASSFILE_API,
STREAM_GATHERERS,
@JEP(number=494, title="Module Import Declarations", status="Second Preview")
MODULE_IMPORTS,
MODULE_IMPORTS, //remove when the boot JDK is JDK 25
@JEP(number=478, title="Key Derivation Function API", status="Preview")
KEY_DERIVATION,
LANGUAGE_MODEL,
Expand Down
22 changes: 4 additions & 18 deletions src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -408,24 +408,10 @@ private Builder readModuleAttribute(DataInput in, ConstantPool cpool, int major,
throw invalidModuleDescriptor("The requires entry for java.base"
+ " has ACC_SYNTHETIC set");
}
// requires transitive java.base is illegal unless:
// - the major version is 53 (JDK 9), or:
// - the classfile is a preview classfile, or:
// - the module is deemed to be participating in preview
// (i.e. the module is a java.* module)
// requires static java.base is illegal unless:
// - the major version is 53 (JDK 9), or:
if (major >= 54
&& ((mods.contains(Requires.Modifier.TRANSITIVE)
&& !isPreview
&& !"java.se".equals(mn))
|| mods.contains(Requires.Modifier.STATIC))) {
String flagName;
if (mods.contains(Requires.Modifier.STATIC)) {
flagName = "ACC_STATIC_PHASE";
} else {
flagName = "ACC_TRANSITIVE";
}
// requires static java.base is illegal unless
// the major version is 53 (JDK 9)
if (major >= 54 && mods.contains(Requires.Modifier.STATIC)) {
String flagName = "ACC_STATIC_PHASE";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A minor comment on the style here, do you mind combin L413+414 as it will make it easier to read. The change is okay of course.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this:
029e0dd
Please let me know if something more/different is needed.

throw invalidModuleDescriptor("The requires entry for java.base"
+ " has " + flagName + " set");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@

package com.sun.source.tree;

import jdk.internal.javac.PreviewFeature;

/**
* A tree node for an import declaration.
*
Expand All @@ -49,11 +47,11 @@ public interface ImportTree extends Tree {
* @return true if this is a static import
*/
boolean isStatic();

/**
* {@return true if this is an module import declaration.}
* @since 23
* @since 25
*/
@PreviewFeature(feature=PreviewFeature.Feature.MODULE_IMPORTS, reflective=true)
boolean isModule();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,7 @@ public boolean participatesInPreview(Symtab syms, ModuleSymbol m) {
// s participates in the preview API
return syms.java_base.exports.stream()
.filter(ed -> ed.packge.fullname == names.jdk_internal_javac)
.anyMatch(ed -> ed.modules.contains(m)) ||
//the specification lists the java.se module as participating in preview:
m.name == names.java_se;
.anyMatch(ed -> ed.modules.contains(m));
}

/**
Expand Down Expand Up @@ -231,8 +229,6 @@ public boolean isPreview(Feature feature) {
case IMPLICIT_CLASSES -> true;
case FLEXIBLE_CONSTRUCTORS -> true;
case PRIMITIVE_PATTERNS -> true;
case MODULE_IMPORTS -> true;
case JAVA_BASE_TRANSITIVE -> true;
//Note: this is a backdoor which allows to optionally treat all features as 'preview' (for testing).
//When real preview features will be added, this method can be implemented to return 'true'
//for those selected features, and 'false' for all the others.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ public enum Feature {
UNNAMED_VARIABLES(JDK22, Fragments.FeatureUnnamedVariables, DiagKind.PLURAL),
PRIMITIVE_PATTERNS(JDK23, Fragments.FeaturePrimitivePatterns, DiagKind.PLURAL),
FLEXIBLE_CONSTRUCTORS(JDK22, Fragments.FeatureFlexibleConstructors, DiagKind.NORMAL),
MODULE_IMPORTS(JDK23, Fragments.FeatureModuleImports, DiagKind.PLURAL),
JAVA_BASE_TRANSITIVE(JDK24, Fragments.FeatureJavaBaseTransitive, DiagKind.PLURAL),
MODULE_IMPORTS(JDK25, Fragments.FeatureModuleImports, DiagKind.PLURAL),
JAVA_BASE_TRANSITIVE(JDK25, Fragments.FeatureJavaBaseTransitive, DiagKind.PLURAL),
PRIVATE_MEMBERS_IN_PERMITS_CLAUSE(JDK19),
ERASE_POLY_SIG_RETURN_TYPE(JDK24),
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1202,11 +1202,6 @@ protected void read(Symbol sym, int attrLen) {
ModuleSymbol rsym = poolReader.getModule(nextChar());
Set<RequiresFlag> flags = readRequiresFlags(nextChar());
if (rsym == syms.java_base && majorVersion >= V54.major) {
if (flags.contains(RequiresFlag.TRANSITIVE) &&
(majorVersion != Version.MAX().major || !previewClassFile) &&
!preview.participatesInPreview(syms, msym)) {
throw badClassFile("bad.requires.flag", RequiresFlag.TRANSITIVE);
}
if (flags.contains(RequiresFlag.STATIC_PHASE)) {
throw badClassFile("bad.requires.flag", RequiresFlag.STATIC_PHASE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
import static jdk.jshell.Snippet.SubKind.TEMP_VAR_EXPRESSION_SUBKIND;
import static jdk.jshell.Snippet.SubKind.VAR_VALUE_SUBKIND;
import static java.util.stream.Collectors.toMap;
import javax.lang.model.SourceVersion;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_COMPA;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_EVNT;
Expand Down Expand Up @@ -642,7 +643,10 @@ Options parse(OptionSet options) {
} else {
String packedStartup = prefs.get(STARTUP_KEY);
boolean preview = previewEnabled(options);
initialStartup = Startup.unpack(packedStartup, preview, new InitMessageHandler());
String sourceLevel = detectSourceLevel(options.valuesOf(argC)
.toArray(String[]::new));
initialStartup = Startup.unpack(packedStartup, sourceLevel,
preview, new InitMessageHandler());
}
if (options.has(argExecution)) {
executionControlSpec = options.valueOf(argExecution);
Expand Down Expand Up @@ -2311,7 +2315,8 @@ boolean setStart(ArgTokenizer at) {
}
} else if (defaultOption) {
boolean preview = options.hasOption(OptionKind.ENABLE_PREVIEW);
startup = Startup.defaultStartup(preview, this);
String sourceLevel = detectSourceLevel(options.compilerOptions());
startup = Startup.defaultStartup(sourceLevel, preview, this);
} else if (noneOption) {
startup = Startup.noStartup();
}
Expand All @@ -2329,7 +2334,8 @@ void showSetStart() {
String retained = prefs.get(STARTUP_KEY);
if (retained != null) {
boolean preview = options.hasOption(OptionKind.ENABLE_PREVIEW);
Startup retainedStart = Startup.unpack(retained, preview, this);
String sourceLevel = detectSourceLevel(options.compilerOptions());
Startup retainedStart = Startup.unpack(retained, sourceLevel, preview, this);
boolean currentDifferent = !startup.equals(retainedStart);
sb.append(retainedStart.show(true));
if (currentDifferent) {
Expand All @@ -2346,6 +2352,19 @@ void showSetStart() {
hard(escape(sb));
}

private String detectSourceLevel(String[] compilerOptions) {
for (int i = 0; i < compilerOptions.length; i++) {
switch (compilerOptions[i]) {
case "-source", "--source", "--release":
if (i + 1 < compilerOptions.length) {
return compilerOptions[i + 1];
}
}
}

return Integer.toString(SourceVersion.latest().runtimeVersion().feature());
}

private void showIndent() {
hard("/set indent %s", indent());
}
Expand Down
97 changes: 64 additions & 33 deletions src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Startup.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@

package jdk.internal.jshell.tool;

import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Source.Feature;
import java.nio.file.AccessDeniedException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static java.util.stream.Collectors.joining;
import static jdk.internal.jshell.tool.JShellTool.RECORD_SEPARATOR;
Expand Down Expand Up @@ -118,13 +123,10 @@ public boolean equals(Object o) {
}

private static final String DEFAULT_STARTUP_NAME = "DEFAULT";
private static final String PREVIEW_DEFAULT_STARTUP_NAME = "PREVIEW_DEFAULT";

// cached DEFAULT start-up
private static Startup[] defaultStartup = new Startup[] {
null, //standard startup
null //preview startup
};
private static Map<DefaultStartupType, Startup> defaultStartup =
new EnumMap<>(DefaultStartupType.class);

// the list of entries
private List<StartupEntry> entries;
Expand Down Expand Up @@ -170,8 +172,10 @@ boolean isEmpty() {
boolean isDefault() {
if (entries.size() == 1) {
StartupEntry sue = entries.get(0);
if (sue.isBuiltIn && (sue.name.equals(DEFAULT_STARTUP_NAME) ||
sue.name.equals(PREVIEW_DEFAULT_STARTUP_NAME))) {
if (sue.isBuiltIn &&
Arrays.stream(DefaultStartupType.values())
.map(DefaultStartupType::getResourceName)
.anyMatch(sue.name::equals)) {
return true;
}
}
Expand Down Expand Up @@ -222,7 +226,7 @@ String showDetail() {
* @param mh handler for error messages
* @return Startup, or default startup when error (message has been printed)
*/
static Startup unpack(String storedForm, boolean preview, MessageHandler mh) {
static Startup unpack(String storedForm, String sourceLevel, boolean preview, MessageHandler mh) {
if (storedForm != null) {
if (storedForm.isEmpty()) {
return noStartup();
Expand All @@ -243,14 +247,18 @@ static Startup unpack(String storedForm, boolean preview, MessageHandler mh) {
String name = all[i + 1];
String timeStamp = all[i + 2];
String content = all[i + 3];
if (isBuiltIn) {
// update to current definition, use stored if removed/error
String resource = getResource(name);
if (resource != null) {
content = resource;
if (isBuiltIn && DEFAULT_STARTUP_NAME.equals(name)) {
e.addAll(defaultStartup(sourceLevel, preview, mh).entries);
} else {
if (isBuiltIn) {
// update to current definition, use stored if removed/error
String resource = getResource(name);
if (resource != null) {
content = resource;
}
}
e.add(new StartupEntry(isBuiltIn, name, content, timeStamp));
}
e.add(new StartupEntry(isBuiltIn, name, content, timeStamp));
}
return new Startup(e);
} else {
Expand All @@ -260,7 +268,7 @@ static Startup unpack(String storedForm, boolean preview, MessageHandler mh) {
mh.errormsg("jshell.err.corrupted.stored.startup", ex.getMessage());
}
}
return defaultStartup(preview, mh);
return defaultStartup(sourceLevel, preview, mh);
}

/**
Expand Down Expand Up @@ -329,26 +337,49 @@ static Startup noStartup() {
* @param mh handler for error messages
* @return The default Startup, or empty startup when error (message has been printed)
*/
static Startup defaultStartup(boolean preview, MessageHandler mh) {
int idx = preview ? 1 : 0;
static Startup defaultStartup(String sourceLevel, boolean preview, MessageHandler mh) {
Source source = Source.lookup(sourceLevel);
DefaultStartupType type;
if (preview) {
type = DefaultStartupType.PREVIEW_DEFAULT_STARTUP;
} else if (source == null ||
Feature.MODULE_IMPORTS.allowedInSource(source)) {
type = DefaultStartupType.DEFAULT_STARTUP;
} else {
type = DefaultStartupType.DEFAULT_STARTUP_NO_MODULE_IMPORTS;
}

return defaultStartup.computeIfAbsent(type, t -> {
String resourceName = t.getResourceName();

try {
String content = readResource(resourceName);
return new Startup(
new StartupEntry(true, DEFAULT_STARTUP_NAME, content));
} catch (AccessDeniedException e) {
mh.errormsg("jshell.err.file.not.accessible", "jshell", resourceName, e.getMessage());
} catch (NoSuchFileException e) {
mh.errormsg("jshell.err.file.not.found", "jshell", resourceName);
} catch (Exception e) {
mh.errormsg("jshell.err.file.exception", "jshell", resourceName, e);
}
return noStartup();
});
}

private enum DefaultStartupType {
DEFAULT_STARTUP("DEFAULT"),
DEFAULT_STARTUP_NO_MODULE_IMPORTS("DEFAULT_NO_MODULE_IMPORTS"),
PREVIEW_DEFAULT_STARTUP("PREVIEW_DEFAULT");

if (defaultStartup[idx] != null) {
return defaultStartup[idx];
private final String resourceName;

private DefaultStartupType(String resourceName) {
this.resourceName = resourceName;
}
String resourceName = preview ? PREVIEW_DEFAULT_STARTUP_NAME
: DEFAULT_STARTUP_NAME;
try {
String content = readResource(resourceName);
return defaultStartup[idx] = new Startup(
new StartupEntry(true, resourceName, content));
} catch (AccessDeniedException e) {
mh.errormsg("jshell.err.file.not.accessible", "jshell", resourceName, e.getMessage());
} catch (NoSuchFileException e) {
mh.errormsg("jshell.err.file.not.found", "jshell", resourceName);
} catch (Exception e) {
mh.errormsg("jshell.err.file.exception", "jshell", resourceName, e);

public String getResourceName() {
return resourceName;
}
return defaultStartup[idx] = noStartup();
}

}
4 changes: 1 addition & 3 deletions src/jdk.jshell/share/classes/jdk/jshell/Snippet.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import jdk.internal.javac.PreviewFeature;

/**
* A Snippet represents a snippet of Java source code as passed to
Expand Down Expand Up @@ -219,9 +218,8 @@ public enum SubKind {
* Import Module Declaration.
* An import declaration of a module.
* @jls 7.5.5 Import Module Declarations
* @since 23
* @since 25
*/
@PreviewFeature(feature=PreviewFeature.Feature.MODULE_IMPORTS, reflective=true)
MODULE_IMPORT_SUBKIND(Kind.IMPORT),

/**
Expand Down
Loading