This commit is contained in:
Lana Steuck 2016-10-20 20:01:40 +00:00
commit 2b068e0158
46 changed files with 1846 additions and 863 deletions

View File

@ -2398,6 +2398,7 @@ public class Attr extends JCTree.Visitor {
try {
if (needsRecovery && isSerializable(pt())) {
localEnv.info.isSerializable = true;
localEnv.info.isLambda = true;
}
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
@ -2969,7 +2970,7 @@ public class Attr extends JCTree.Visitor {
}
if (isTargetSerializable) {
chk.checkElemAccessFromSerializableLambda(that);
chk.checkAccessFromSerializableElement(that, true);
}
}
@ -3364,7 +3365,7 @@ public class Attr extends JCTree.Visitor {
}
if (env.info.isSerializable) {
chk.checkElemAccessFromSerializableLambda(tree);
chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
}
result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
@ -3507,7 +3508,7 @@ public class Attr extends JCTree.Visitor {
}
if (env.info.isSerializable) {
chk.checkElemAccessFromSerializableLambda(tree);
chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
}
env.info.selectSuper = selectSuperPrev;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -56,10 +56,15 @@ public class AttrContext {
*/
boolean selectSuper = false;
/** Is the current target of lambda expression or method reference serializable?
/** Is the current target of lambda expression or method reference serializable or is this a
* serializable class?
*/
boolean isSerializable = false;
/** Is this a lambda environment?
*/
boolean isLambda = false;
/** Is this a speculative attribution environment?
*/
boolean isSpeculative = false;
@ -117,6 +122,7 @@ public class AttrContext {
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
info.isSerializable = isSerializable;
info.isLambda = isLambda;
info.isSpeculative = isSpeculative;
info.isAnonymousDiamond = isAnonymousDiamond;
info.isNewClass = isNewClass;

View File

@ -87,7 +87,7 @@ public class Check {
private final JavaFileManager fileManager;
private final Source source;
private final Profile profile;
private final boolean warnOnAccessToSensitiveMembers;
private final boolean warnOnAnyAccessToMembers;
// The set of lint options currently in effect. It is initialized
// from the context, and then is set/reset as needed by Attr as it
@ -131,7 +131,7 @@ public class Check {
allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
Target target = Target.instance(context);
syntheticNameChar = target.syntheticNameChar();
@ -2605,8 +2605,11 @@ public class Check {
}
}
void checkElemAccessFromSerializableLambda(final JCTree tree) {
if (warnOnAccessToSensitiveMembers) {
void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
if (warnOnAnyAccessToMembers ||
(lint.isEnabled(LintCategory.SERIAL) &&
!lint.isSuppressed(LintCategory.SERIAL) &&
isLambda)) {
Symbol sym = TreeInfo.symbol(tree);
if (!sym.kind.matches(KindSelector.VAL_MTH)) {
return;
@ -2622,9 +2625,16 @@ public class Check {
}
if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
isEffectivelyNonPublic(sym)) {
log.warning(tree.pos(),
"access.to.sensitive.member.from.serializable.element", sym);
isEffectivelyNonPublic(sym)) {
if (isLambda) {
if (belongsToRestrictedPackage(sym)) {
log.warning(LintCategory.SERIAL, tree.pos(),
"access.to.member.from.serializable.lambda", sym);
}
} else {
log.warning(tree.pos(),
"access.to.member.from.serializable.element", sym);
}
}
}
}
@ -2643,6 +2653,14 @@ public class Check {
return false;
}
private boolean belongsToRestrictedPackage(Symbol sym) {
String fullName = sym.packge().fullname.toString();
return fullName.startsWith("java.") ||
fullName.startsWith("javax.") ||
fullName.startsWith("sun.") ||
fullName.contains(".internal.");
}
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {

View File

@ -1712,8 +1712,12 @@ compiler.warn.varargs.redundant.trustme.anno=\
Redundant {0} annotation. {1}
# 0: symbol
compiler.warn.access.to.sensitive.member.from.serializable.element=\
access to sensitive member {0} from serializable element can be publicly accessible to untrusted code
compiler.warn.access.to.member.from.serializable.element=\
access to member {0} from serializable element can be publicly accessible to untrusted code
# 0: symbol
compiler.warn.access.to.member.from.serializable.lambda=\
access to member {0} from serializable lambda can be publicly accessible to untrusted code
#####

View File

@ -220,7 +220,8 @@ javac.opt.Xlint.desc.rawtypes=\
Warn about use of raw types.
javac.opt.Xlint.desc.serial=\
Warn about Serializable classes that do not provide a serial version ID.
Warn about Serializable classes that do not provide a serial version ID. \n\
\ Also warn about access to non-public members from a serializable element.
javac.opt.Xlint.desc.static=\
Warn about accessing a static member using an instance.

View File

@ -353,11 +353,12 @@ public class HtmlWriter {
protected Content getFramesJavaScript() {
HtmlTree script = HtmlTree.SCRIPT();
String scriptCode = DocletConstants.NL +
" targetPage = \"\" + window.location.search;" + DocletConstants.NL +
" if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
" targetPage = targetPage.substring(1);" + DocletConstants.NL +
" if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL +
" targetPage = \"undefined\";" + DocletConstants.NL +
" tmpTargetPage = \"\" + window.location.search;" + DocletConstants.NL +
" if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")" + DocletConstants.NL +
" tmpTargetPage = tmpTargetPage.substring(1);" + DocletConstants.NL +
" if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))" + DocletConstants.NL +
" tmpTargetPage = \"undefined\";" + DocletConstants.NL +
" targetPage = tmpTargetPage;" + DocletConstants.NL +
" function validURL(url) {" + DocletConstants.NL +
" try {" + DocletConstants.NL +
" url = decodeURIComponent(url);" + DocletConstants.NL +

View File

@ -234,11 +234,12 @@ public class HtmlWriter {
protected Content getFramesJavaScript() {
HtmlTree scriptTree = HtmlTree.SCRIPT();
String scriptCode = "\n" +
" targetPage = \"\" + window.location.search;\n" +
" if (targetPage != \"\" && targetPage != \"undefined\")\n" +
" targetPage = targetPage.substring(1);\n" +
" if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n" +
" targetPage = \"undefined\";\n" +
" tmpTargetPage = \"\" + window.location.search;\n" +
" if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" +
" tmpTargetPage = tmpTargetPage.substring(1);\n" +
" if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" +
" tmpTargetPage = \"undefined\";\n" +
" targetPage = tmpTargetPage;\n" +
" function validURL(url) {\n" +
" try {\n" +
" url = decodeURIComponent(url);\n" +

View File

@ -308,9 +308,7 @@ public abstract class Configuration {
public CommentUtils cmtUtils;
/**
* A sorted set of packages specified on the command-line merged with a
* collection of packages that contain the classes specified on the
* command-line.
* A sorted set of included packages.
*/
public SortedSet<PackageElement> packages = null;
@ -399,10 +397,8 @@ public abstract class Configuration {
private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator());
packages.addAll(getSpecifiedPackages());
for (TypeElement aClass : getSpecifiedClasses()) {
packages.add(utils.containingPackage(aClass));
}
// add all the included packages
packages.addAll(docEnv.getIncludedPackageElements());
}
public Set<Doclet.Option> getSupportedOptions() {
@ -647,7 +643,7 @@ public abstract class Configuration {
if (docencoding == null) {
docencoding = encoding;
}
typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
typeElementCatalog = new TypeElementCatalog(docEnv.getIncludedTypeElements(), this);
initTagletManager(customTagStrs);
groups.stream().forEach((grp) -> {
group.checkPackageGroups(grp.value1, grp.value2);

View File

@ -587,18 +587,28 @@ public class ElementsTable {
}
private Set<PackageElement> computeModulePackages() throws ToolException {
final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
accessValue = accessFilter.getAccessValue(ElementKind.MODULE);
final boolean moduleDetailedMode = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
for (ModuleElement mdle : specifiedModuleElements) {
// add all exported packages belonging to a specified module
if (specifiedModuleElements.contains(mdle)) {
if (documentAllModulePackages) { // include all packages
List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
expandedModulePackages.addAll(packages);
expandedModulePackages.addAll(getAllModulePackages(mdle));
} else { // selectively include required packages
List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
for (ExportsDirective export : exports) {
expandedModulePackages.add(export.getPackage());
// add if fully exported or add qualified exports only if desired
if (export.getTargetModules() == null
|| documentAllModulePackages || moduleDetailedMode) {
expandedModulePackages.add(export.getPackage());
}
}
}
@ -613,27 +623,6 @@ public class ElementsTable {
}
}
}
if (!documentAllModulePackages) {
List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
// check exported packages
for (ExportsDirective export : exports) {
List<? extends ModuleElement> targetModules = export.getTargetModules();
if (targetModules == null) { // no qualified exports, add 'em all
expandedModulePackages.add(export.getPackage());
} else { // qualified export, add only if target module is being considered
for (ModuleElement target : targetModules) {
if (specifiedModuleElements.contains(target)) {
expandedModulePackages.add(export.getPackage());
}
}
}
}
} else { // add all exported and module private packages
List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
expandedModulePackages.addAll(packages);
expandedModulePackages.addAll(getAllModulePackages(mdle));
}
}
return expandedModulePackages;
}
@ -668,8 +657,7 @@ public class ElementsTable {
if (!mdle.isUnnamed())
imodules.add(mdle);
PackageElement pkg = toolEnv.elements.getPackageOf(klass);
if (!pkg.isUnnamed())
ipackages.add(pkg);
ipackages.add(pkg);
addAllClasses(iclasses, klass, true);
});

View File

@ -30,7 +30,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
/**
@ -78,7 +77,12 @@ class ArgTokenizer {
while (true) {
nextToken();
if (sval != null && !isQuoted() && sval.startsWith("-")) {
foundOption(sval);
// allow POSIX getopt() option format,
// to be consistent with command-line
String opt = sval.startsWith("--")
? sval.substring(1)
: sval;
foundOption(opt);
} else {
break;
}
@ -104,28 +108,13 @@ class ArgTokenizer {
}
}
String[] next(String... strings) {
return next(Arrays.stream(strings));
}
String[] next(Stream<String> stream) {
next();
if (sval == null) {
return null;
}
String[] matches = stream
.filter(s -> s.startsWith(sval))
.toArray(size -> new String[size]);
return matches;
}
/**
* Set the allowed options. Must be called before any options would be read
* and before calling any of the option functionality below.
*/
void allowedOptions(String... opts) {
for (String opt : opts) {
options.put(opt, false);
options.putIfAbsent(opt, false);
}
}

View File

@ -31,6 +31,7 @@ import jdk.jshell.SourceCodeAnalysis.Suggestion;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.lang.reflect.Method;
@ -61,6 +62,8 @@ import jdk.internal.jline.console.history.History;
import jdk.internal.jline.console.history.MemoryHistory;
import jdk.internal.jline.extra.EditingHistory;
import jdk.internal.jshell.tool.StopDetectingInputStream.State;
import jdk.internal.misc.Signal;
import jdk.internal.misc.Signal.Handler;
class ConsoleIOContext extends IOContext {
@ -170,6 +173,21 @@ class ConsoleIOContext extends IOContext {
bind(shortcuts + computer.shortcut, (ActionListener) evt -> fixes(computer));
}
}
try {
Signal.handle(new Signal("CONT"), new Handler() {
@Override public void handle(Signal sig) {
try {
in.getTerminal().reset();
in.redrawLine();
in.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
} catch (IllegalArgumentException ignored) {
//the CONT signal does not exist on this platform
}
}
@Override
@ -390,7 +408,7 @@ class ConsoleIOContext extends IOContext {
private int inputBytesPointer;
@Override
public synchronized int readUserInput() {
public synchronized int readUserInput() throws IOException {
while (inputBytes == null || inputBytes.length <= inputBytesPointer) {
boolean prevHandleUserInterrupt = in.getHandleUserInterrupt();
History prevHistory = in.getHistory();
@ -401,12 +419,8 @@ class ConsoleIOContext extends IOContext {
in.setHistory(userInputHistory);
inputBytes = (in.readLine("") + System.getProperty("line.separator")).getBytes();
inputBytesPointer = 0;
} catch (IOException ex) {
ex.printStackTrace();
return -1;
} catch (UserInterruptException ex) {
repl.state.stop();
return -1;
throw new InterruptedIOException();
} finally {
in.setHistory(prevHistory);
in.setHandleUserInterrupt(prevHandleUserInterrupt);

View File

@ -54,7 +54,7 @@ abstract class IOContext implements AutoCloseable {
public abstract void replaceLastHistoryEntry(String source);
public abstract int readUserInput();
public abstract int readUserInput() throws IOException;
class InputInterruptedException extends Exception {
private static final long serialVersionUID = 1L;

View File

@ -204,12 +204,13 @@ public class JShellTool implements MessageHandler {
JShell state = null;
Subscription shutdownSubscription = null;
static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false);
private boolean debug = false;
public boolean testPrompt = false;
private String cmdlineClasspath = null;
private String startup = null;
private String[] editor = null;
private boolean editorWait = false;
private EditorSetting editor = BUILT_IN_EDITOR;
// Commands and snippets which should be replayed
private List<String> replayableHistory;
@ -273,7 +274,8 @@ public class JShellTool implements MessageHandler {
* @param format printf format
* @param args printf args
*/
void hard(String format, Object... args) {
@Override
public void hard(String format, Object... args) {
rawout(feedback.getPre() + format + feedback.getPost(), args);
}
@ -287,6 +289,15 @@ public class JShellTool implements MessageHandler {
rawout(feedback.getErrorPre() + format + feedback.getErrorPost(), args);
}
/**
* Should optional informative be displayed?
* @return true if they should be displayed
*/
@Override
public boolean showFluff() {
return feedback.shouldDisplayCommandFluff() && interactive();
}
/**
* Optional output
*
@ -295,7 +306,7 @@ public class JShellTool implements MessageHandler {
*/
@Override
public void fluff(String format, Object... args) {
if (feedback.shouldDisplayCommandFluff() && interactive()) {
if (showFluff()) {
hard(format, args);
}
}
@ -307,7 +318,7 @@ public class JShellTool implements MessageHandler {
* @param args printf args
*/
void fluffRaw(String format, Object... args) {
if (feedback.shouldDisplayCommandFluff() && interactive()) {
if (showFluff()) {
rawout(format, args);
}
}
@ -389,7 +400,8 @@ public class JShellTool implements MessageHandler {
* @param key the resource key
* @param args
*/
void hardmsg(String key, Object... args) {
@Override
public void hardmsg(String key, Object... args) {
cmdout.println(prefix(messageFormat(key, args)));
}
@ -428,7 +440,7 @@ public class JShellTool implements MessageHandler {
*/
@Override
public void fluffmsg(String key, Object... args) {
if (feedback.shouldDisplayCommandFluff() && interactive()) {
if (showFluff()) {
hardmsg(key, args);
}
}
@ -502,16 +514,9 @@ public class JShellTool implements MessageHandler {
}
// Read retained editor setting (if any)
String editorString = prefs.get(EDITOR_KEY, "");
if (editorString == null || editorString.isEmpty()) {
editor = null;
} else {
char waitMarker = editorString.charAt(0);
if (waitMarker == '-' || waitMarker == '*') {
editorWait = waitMarker == '-';
editorString = editorString.substring(1);
}
editor = editorString.split(RECORD_SEPARATOR);
editor = EditorSetting.fromPrefs(prefs);
if (editor == null) {
editor = BUILT_IN_EDITOR;
}
resetState(); // Initialize
@ -680,10 +685,25 @@ public class JShellTool implements MessageHandler {
//ignore
}
@Override
public void hard(String format, Object... args) {
//ignore
}
@Override
public void hardmsg(String messageKey, Object... args) {
//ignore
}
@Override
public void errormsg(String messageKey, Object... args) {
startmsg(messageKey, args);
}
@Override
public boolean showFluff() {
return false;
}
}
private void resetState() {
@ -745,7 +765,7 @@ public class JShellTool implements MessageHandler {
startUpRun(getResourceString("startup.feedback"));
// These predefined modes are read-only
feedback.markModesReadOnly();
// Restore user defined modes retained on previous run with /retain mode
// Restore user defined modes retained on previous run with /set mode -retain
String encoded = prefs.get(MODE_KEY, null);
if (encoded != null && !encoded.isEmpty()) {
if (!feedback.restoreEncodedModes(initmh, encoded)) {
@ -755,7 +775,7 @@ public class JShellTool implements MessageHandler {
}
if (commandLineFeedbackMode != null) {
// The feedback mode to use was specified on the command line, use it
if (!feedback.setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
if (!setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
regenerateOnDeath = false;
}
commandLineFeedbackMode = null;
@ -763,8 +783,8 @@ public class JShellTool implements MessageHandler {
String fb = prefs.get(FEEDBACK_KEY, null);
if (fb != null) {
// Restore the feedback mode to use that was retained
// on a previous run with /retain feedback
feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb));
// on a previous run with /set feedback -retain
setFeedback(initmh, new ArgTokenizer("previous retain feedback", "-retain " + fb));
}
}
}
@ -1227,14 +1247,6 @@ public class JShellTool implements MessageHandler {
"editor", fileCompletions(Files::isExecutable),
"start", FILE_COMPLETION_PROVIDER),
STARTSWITH_MATCHER)));
registerCommand(new Command("/retain",
arg -> cmdRetain(arg),
new ContinuousCompletionProvider(Map.of(
"feedback", feedback.modeCompletions(),
"mode", feedback.modeCompletions(),
"editor", fileCompletions(Files::isExecutable),
"start", FILE_COMPLETION_PROVIDER),
STARTSWITH_MATCHER)));
registerCommand(new Command("/?",
"help.quest",
arg -> cmdHelp(arg),
@ -1293,9 +1305,6 @@ public class JShellTool implements MessageHandler {
private static final String[] SET_SUBCOMMANDS = new String[]{
"format", "truncation", "feedback", "mode", "prompt", "editor", "start"};
private static final String[] RETAIN_SUBCOMMANDS = new String[]{
"feedback", "mode", "editor", "start"};
final boolean cmdSet(String arg) {
String cmd = "/set";
ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
@ -1304,95 +1313,61 @@ public class JShellTool implements MessageHandler {
return false;
}
switch (which) {
case "_retain": {
errormsg("jshell.err.setting.to.retain.must.be.specified", at.whole());
return false;
}
case "_blank": {
// show top-level settings
new SetEditor().set();
showSetStart();
setFeedback(this, at); // no args so shows feedback setting
hardmsg("jshell.msg.set.show.mode.settings");
return true;
}
case "format":
return feedback.setFormat(this, at);
case "truncation":
return feedback.setTruncation(this, at);
case "feedback":
return feedback.setFeedback(this, at);
return setFeedback(this, at);
case "mode":
return feedback.setMode(this, at);
return feedback.setMode(this, at,
retained -> prefs.put(MODE_KEY, retained));
case "prompt":
return feedback.setPrompt(this, at);
case "editor":
return setEditor(at, true);
return new SetEditor(at).set();
case "start":
return setStart(cmd, at, true);
return setStart(at);
default:
errormsg("jshell.err.arg", cmd, at.val());
return false;
}
}
final boolean cmdRetain(String arg) {
String cmd = "/retain";
ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
String which = subCommand(cmd, at, RETAIN_SUBCOMMANDS);
if (which == null) {
return false;
}
switch (which) {
case "feedback": {
String fb = feedback.retainFeedback(this, at);
if (fb != null) {
// If a feedback mode has been set now, or in the past, retain it
prefs.put(FEEDBACK_KEY, fb);
return true;
}
return false;
}
case "mode":
String retained = feedback.retainMode(this, at);
if (retained != null) {
// Retain this mode and all previously retained modes
prefs.put(MODE_KEY, retained);
return true;
}
return false;
case "editor":
if (!setEditor(at, false)) {
return false;
}
// retain editor setting
prefs.put(EDITOR_KEY, (editor == null)
? ""
: (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor));
return true;
case "start": {
if (!setStart(cmd, at, false)) {
return false;
}
// retain startup setting
prefs.put(STARTUP_KEY, startup);
return true;
}
default:
errormsg("jshell.err.arg", cmd, at.val());
return false;
}
boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
return feedback.setFeedback(messageHandler, at,
fb -> prefs.put(FEEDBACK_KEY, fb));
}
// Print the help doc for the specified sub-command
boolean printSubCommandHelp(String cmd, ArgTokenizer at, String helpPrefix, String[] subs) {
String which = subCommand(cmd, at, subs);
if (which == null) {
return false;
}
hardrb(helpPrefix + which);
return true;
}
// Find which, if any, sub-command matches
// Find which, if any, sub-command matches.
// Return null on error
String subCommand(String cmd, ArgTokenizer at, String[] subs) {
String[] matches = at.next(subs);
if (matches == null) {
at.allowedOptions("-retain");
String sub = at.next();
if (sub == null) {
// No sub-command was given
errormsg("jshell.err.sub.arg", cmd);
return null;
return at.hasOption("-retain")
? "_retain"
: "_blank";
}
String[] matches = Arrays.stream(subs)
.filter(s -> s.startsWith(sub))
.toArray(size -> new String[size]);
if (matches.length == 0) {
// There are no matching sub-commands
errormsg("jshell.err.arg", cmd, at.val());
errormsg("jshell.err.arg", cmd, sub);
fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs)
.collect(Collectors.joining(", "))
);
@ -1400,7 +1375,7 @@ public class JShellTool implements MessageHandler {
}
if (matches.length > 1) {
// More than one sub-command matches the initial characters provided
errormsg("jshell.err.sub.ambiguous", cmd, at.val());
errormsg("jshell.err.sub.ambiguous", cmd, sub);
fluffmsg("jshell.msg.use.one.of", Arrays.stream(matches)
.collect(Collectors.joining(", "))
);
@ -1409,69 +1384,221 @@ public class JShellTool implements MessageHandler {
return matches[0];
}
// The sub-command: /set editor <editor-command-line>>
boolean setEditor(ArgTokenizer at, boolean argsRequired) {
at.allowedOptions("-default", "-wait");
String prog = at.next();
List<String> ed = new ArrayList<>();
while (at.val() != null) {
ed.add(at.val());
at.nextToken();
static class EditorSetting {
static String BUILT_IN_REP = "-default";
static char WAIT_PREFIX = '-';
static char NORMAL_PREFIX = '*';
final String[] cmd;
final boolean wait;
EditorSetting(String[] cmd, boolean wait) {
this.wait = wait;
this.cmd = cmd;
}
if (!checkOptionsAndRemainingInput(at)) {
return false;
// returns null if not stored in preferences
static EditorSetting fromPrefs(Preferences prefs) {
// Read retained editor setting (if any)
String editorString = prefs.get(EDITOR_KEY, "");
if (editorString == null || editorString.isEmpty()) {
return null;
} else if (editorString.equals(BUILT_IN_REP)) {
return BUILT_IN_EDITOR;
} else {
boolean wait = false;
char waitMarker = editorString.charAt(0);
if (waitMarker == WAIT_PREFIX || waitMarker == NORMAL_PREFIX) {
wait = waitMarker == WAIT_PREFIX;
editorString = editorString.substring(1);
}
String[] cmd = editorString.split(RECORD_SEPARATOR);
return new EditorSetting(cmd, wait);
}
}
boolean defaultOption = at.hasOption("-default");
boolean waitOption = at.hasOption("-wait");
if (prog != null) {
if (defaultOption) {
void toPrefs(Preferences prefs) {
prefs.put(EDITOR_KEY, (this == BUILT_IN_EDITOR)
? BUILT_IN_REP
: (wait ? WAIT_PREFIX : NORMAL_PREFIX) + String.join(RECORD_SEPARATOR, cmd));
}
@Override
public boolean equals(Object o) {
if (o instanceof EditorSetting) {
EditorSetting ed = (EditorSetting) o;
return Arrays.equals(cmd, ed.cmd) && wait == ed.wait;
} else {
return false;
}
}
@Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + Arrays.deepHashCode(this.cmd);
hash = 71 * hash + (this.wait ? 1 : 0);
return hash;
}
}
class SetEditor {
private final ArgTokenizer at;
private final String[] command;
private final boolean hasCommand;
private final boolean defaultOption;
private final boolean waitOption;
private final boolean retainOption;
SetEditor(ArgTokenizer at) {
at.allowedOptions("-default", "-wait", "-retain");
String prog = at.next();
List<String> ed = new ArrayList<>();
while (at.val() != null) {
ed.add(at.val());
at.nextToken(); // so that options are not interpreted as jshell options
}
this.at = at;
this.command = ed.toArray(new String[ed.size()]);
this.hasCommand = command.length > 0;
this.defaultOption = at.hasOption("-default");
this.waitOption = at.hasOption("-wait");
this.retainOption = at.hasOption("-retain");
}
SetEditor() {
this(new ArgTokenizer("", ""));
}
boolean set() {
if (!check()) {
return false;
}
if (!hasCommand && !defaultOption && !retainOption) {
// No settings or -retain, so this is a query
EditorSetting retained = EditorSetting.fromPrefs(prefs);
if (retained != null) {
// retained editor is set
hard("/set editor -retain %s", format(retained));
}
if (retained == null || !retained.equals(editor)) {
// editor is not retained or retained is different from set
hard("/set editor %s", format(editor));
}
return true;
}
install();
if (retainOption) {
editor.toPrefs(prefs);
fluffmsg("jshell.msg.set.editor.retain", format(editor));
}
return true;
}
private boolean check() {
if (!checkOptionsAndRemainingInput(at)) {
return false;
}
if (hasCommand && defaultOption) {
errormsg("jshell.err.default.option.or.program", at.whole());
return false;
}
editor = ed.toArray(new String[ed.size()]);
editorWait = waitOption;
fluffmsg("jshell.msg.set.editor.set", prog);
} else if (defaultOption) {
if (waitOption) {
if (waitOption && !hasCommand) {
errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
return false;
}
editor = null;
} else if (argsRequired) {
errormsg("jshell.err.set.editor.arg");
return false;
return true;
}
private void install() {
if (hasCommand) {
editor = new EditorSetting(command, waitOption);
} else if (defaultOption) {
editor = BUILT_IN_EDITOR;
} else {
return;
}
fluffmsg("jshell.msg.set.editor.set", format(editor));
}
private String format(EditorSetting ed) {
if (ed == BUILT_IN_EDITOR) {
return "-default";
} else {
Stream<String> elems = Arrays.stream(ed.cmd);
if (ed.wait) {
elems = Stream.concat(Stream.of("-wait"), elems);
}
return elems.collect(joining(" "));
}
}
return true;
}
// The sub-command: /set start <start-file>
boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) {
at.allowedOptions("-default", "-none");
boolean setStart(ArgTokenizer at) {
at.allowedOptions("-default", "-none", "-retain");
String fn = at.next();
if (!checkOptionsAndRemainingInput(at)) {
return false;
}
int argCount = at.optionCount() + ((fn != null) ? 1 : 0);
if (argCount > 1 || argsRequired && argCount == 0) {
boolean defaultOption = at.hasOption("-default");
boolean noneOption = at.hasOption("-none");
boolean retainOption = at.hasOption("-retain");
boolean hasFile = fn != null;
int argCount = (defaultOption ? 1 : 0) + (noneOption ? 1 : 0) + (hasFile ? 1 : 0);
if (argCount > 1) {
errormsg("jshell.err.option.or.filename", at.whole());
return false;
}
if (fn != null) {
String init = readFile(fn, cmd + " start");
if (argCount == 0 && !retainOption) {
// no options or filename, show current setting
showSetStart();
return true;
}
if (hasFile) {
String init = readFile(fn, "/set start");
if (init == null) {
return false;
} else {
startup = init;
return true;
}
} else if (at.hasOption("-default")) {
startup = init;
} else if (defaultOption) {
startup = DEFAULT_STARTUP;
} else if (at.hasOption("-none")) {
} else if (noneOption) {
startup = "";
}
if (retainOption) {
// retain startup setting
prefs.put(STARTUP_KEY, startup);
}
return true;
}
void showSetStart() {
String retained = prefs.get(STARTUP_KEY, null);
if (retained != null) {
showSetStart(true, retained);
}
if (retained == null || !startup.equals(retained)) {
showSetStart(false, startup);
}
}
void showSetStart(boolean isRetained, String start) {
String cmd = "/set start" + (isRetained ? " -retain " : " ");
String stset;
if (start.equals(DEFAULT_STARTUP)) {
stset = cmd + "-default";
} else if (start.isEmpty()) {
stset = cmd + "-none";
} else {
stset = prefix("startup.jsh:\n" + start + "\n" + cmd + "startup.jsh", "");
}
hard(stset);
}
boolean cmdClasspath(String arg) {
if (arg.isEmpty()) {
errormsg("jshell.err.classpath.arg");
@ -1559,17 +1686,18 @@ public class JShellTool implements MessageHandler {
Command[] matches = commands.values().stream()
.filter(c -> c.command.startsWith(subject))
.toArray(size -> new Command[size]);
at.mark();
String sub = at.next();
if (sub != null && matches.length == 1) {
if (matches.length == 1) {
String cmd = matches[0].command;
switch (cmd) {
case "/set":
at.rewind();
return printSubCommandHelp(cmd, at, "help.set.", SET_SUBCOMMANDS);
case "/retain":
at.rewind();
return printSubCommandHelp(cmd, at, "help.retain.", RETAIN_SUBCOMMANDS);
if (cmd.equals("/set")) {
// Print the help doc for the specified sub-command
String which = subCommand(cmd, at, SET_SUBCOMMANDS);
if (which == null) {
return false;
}
if (!which.equals("_blank")) {
hardrb("help.set." + which);
return true;
}
}
}
if (matches.length > 0) {
@ -1813,7 +1941,7 @@ public class JShellTool implements MessageHandler {
String src = sb.toString();
Consumer<String> saveHandler = new SaveHandler(src, srcSet);
Consumer<String> errorHandler = s -> hard("Edit Error: %s", s);
if (editor == null) {
if (editor == BUILT_IN_EDITOR) {
try {
EditPad.edit(errorHandler, src, saveHandler);
} catch (RuntimeException ex) {
@ -1822,8 +1950,8 @@ public class JShellTool implements MessageHandler {
return false;
}
} else {
ExternalEditor.edit(editor, errorHandler, src, saveHandler, input,
editorWait, this::hardrb);
ExternalEditor.edit(editor.cmd, errorHandler, src, saveHandler, input,
editor.wait, this::hardrb);
}
return true;
}

View File

@ -37,5 +37,11 @@ public interface MessageHandler {
void fluffmsg(String messageKey, Object... args);
void hard(String format, Object... args);
void hardmsg(String messageKey, Object... args);
void errormsg(String messageKey, Object... args);
boolean showFluff();
}

View File

@ -52,12 +52,17 @@ jshell.err.unexpected.exception = Unexpected exception: {0}
jshell.err.no.such.command.or.snippet.id = No such command or snippet id: {0}
jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1}
jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument
jshell.msg.set.editor.set = Editor set to: {0}
jshell.msg.set.editor.retain = Editor setting retained: {0}
jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0}
jshell.msg.try.set.editor = Try /set editor to use external editor.
jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode.
jshell.err.wait.applies.to.external.editor = -wait applies to external editors, cannot be used with -default
jshell.err.wait.applies.to.external.editor = -wait applies to external editors
jshell.err.setting.to.retain.must.be.specified = The setting to retain must be specified -- {0}
jshell.msg.set.show.mode.settings = \nTo show mode settings use ''/set prompt'', ''/set truncation'', ...\n\
or use ''/set mode'' followed by the feedback mode name.
jshell.err.continuation.prompt.required = Continuation prompt required -- {0}
jshell.msg.try.command.without.args = Try ''{0}'' without arguments.
jshell.msg.no.active = There are no active definitions.
@ -104,12 +109,10 @@ jshell.msg.help.for.help = Type /help for help.
jshell.err.mode.name = Expected a feedback mode name: {0}
jshell.err.missing.mode = Missing the feedback mode -- {0}
jshell.err.field.name = Expected a field name: {0} -- {1}
jshell.err.missing.field = Missing the field name -- {0}
jshell.err.mode.unknown = No feedback mode named: {0} -- {1}
jshell.err.feedback.does.not.match.mode = Does not match any current feedback mode: {0} -- {1}
jshell.err.feedback.ambiguous.mode = Matches more then one current feedback mode: {0} -- {1}
jshell.err.feedback.expected.format = Expected format missing -- {0}
jshell.err.feedback.must.be.quoted = Format ''{0}'' must be quoted -- {1}
jshell.err.feedback.not.a.valid.selector = Not a valid selector ''{0}'' in ''{1}'' -- {2}
jshell.err.feedback.multiple.sections = Selector kind in multiple sections of selector list ''{0}'' in ''{1}'' -- {2}
@ -117,22 +120,25 @@ jshell.err.feedback.different.selector.kinds = Different selector kinds in same
jshell.msg.feedback.new.mode = Created new feedback mode: {0}
jshell.msg.feedback.mode = Feedback mode: {0}
jshell.msg.feedback.mode.following = The feedback mode should be one of the following:
jshell.msg.feedback.mode.following = Available feedback modes:
jshell.msg.feedback.retained.mode.following = Retained feedback modes:
jshell.err.mode.creation = To create a new mode either the -command or the -quiet option must be used -- {0}
jshell.err.mode.exists = Mode to be created already exists: {0} -- {1}
jshell.err.truncation.expected.length = Expected truncation length -- {0}
jshell.err.truncation.length.not.integer = Truncation length must be an integer: {0} -- {1}
jshell.err.not.valid.with.predefined.mode = Not valid with a predefined mode: {0} -- {1}
jshell.err.retained.feedback.mode.must.be.retained.or.predefined = \
''/retain feedback <mode>'' requires that <mode> is predefined or has been retained with ''/retain mode'' -- {0}
''/set feedback -retain <mode>'' requires that <mode> is predefined or has been retained with ''/set mode -retain'' -- {0}
jshell.err.unknown.option = Unknown option: {0} -- {1}
jshell.err.default.option.or.program = Specify -default option or program, not both -- {0}
jshell.err.option.or.filename = Specify either one option or a startup file name -- {0}
jshell.err.option.or.filename = Specify no more than one of -default, -none, or a startup file name -- {0}
jshell.err.unexpected.at.end = Unexpected arguments at end of command: {0} -- {1}
jshell.err.conflicting.options = Conflicting options -- {0}
jshell.err.cannot.delete.current.mode = The current feedback mode ''{0}'' cannot be deleted, use ''/set feedback'' first -- {1}
jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/retain feedback'' first -- {1}
jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/set feedback -retain'' first -- {1}
jshell.err.may.not.specify.options.and.snippets = Options and snippets must not both be used: {0}
jshell.err.no.such.snippets = No such snippet: {0}
jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1}
@ -374,36 +380,20 @@ the command prompt, the feedback mode to use, or the format of output.\n\
The contents of the specified <file> become the default start-up snippets and commands.\n\n\
/set feedback <mode>\n\t\
Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\t\
/set mode <mode> [<old-mode>] -command|-quiet|-delete\n\t\
Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\
/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\
Set the displayed prompts for a given feedback mode.\n\n\
/set truncation <mode> <length> <selector>...\n\t\
Set the maximum length of a displayed value\n\
Set the maximum length of a displayed value.\n\n\
/set format <mode> <field> "<format>" <selector>...\n\t\
Configure a feedback mode by setting the format of a field when the selector matchs.\n\n\
Configure a feedback mode by setting the format of a field when the selector matches.\n\n\
/set\n\t\
Show editor, start, and feedback settings as /set commands.\n\t\
To show the settings of any of the above, omit the set value.\n\n\
To get more information about one of these forms, use /help with the form specified.\n\
For example: /help /set format
help.retain.summary = retain jshell configuration information for subsequent sessions
help.retain.args = editor|start|feedback|mode
help.retain =\
Retain jshell configuration information for future invocations of the jshell tool,\n\
including: the external editor to use, the start-up definitions to use, the\n\
configuration of a feedback mode, or the feedback mode to use.\n\
\n\
/retain editor [<command> <optional-arg>...]\n\t\
Specify the command to launch for the /edit command.\n\t\
The <command> is an operating system dependent string.\n\n\
/retain start [<file>]\n\t\
The contents of the specified <file> become the default start-up snippets and commands.\n\n\
/retain feedback [<mode>]\n\t\
Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
/retain mode <mode>\n\t\
Create a user-defined feedback mode, optionally copying from an existing mode.\n\n\
To get more information about one of these forms, use /help with the form specified.\n\
For example: /help /retain feedback
help.quest.summary = get information about jshell
help.quest.args = [<command>|<subject>]
help.quest =\
@ -467,11 +457,24 @@ Shift-<tab>\n\t\t\
possible fully qualified names based on the content of the specified classpath.\n\t\t\
The "<fix-shortcut>" is either Alt-F1 or Alt-Enter, depending on the platform.
help.set._retain = \
The '-retain' option saves a setting so that it is used in future sessions.\n\
The -retain option can be used on the following forms of /set:\n\n\t\
/set editor -retain\n\t\
/set start -retain\n\t\
/set feedback -retain\n\t\
/set mode -retain\n\n\
See these commands for more detail -- for example /help /set editor
help.set.format = \
Set the format for reporting a snippet event.\n\
Set the format for reporting a snippet event:\n\
\n\t\
/set format <mode> <field> "<format>" <selector>...\n\
\n\
Show the format settings:\n\
\n\t\
/set format [<mode> [<field>]]\n\
\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <field> is the name of context-specific format to define.\n\
Where <format> is a quoted string which will be the value of the field if one of\n\
@ -541,13 +544,24 @@ Examples:\n\t\
/set format myformat action 'Update replaced' replaced-update\n\t\
/set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t\
/set format myformat display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update\n\n\
Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
\n\
The form without <format> shows the current format settings.\n\
When the <mode> is specified only the format settings for that mode are shown.\n\
When both the <mode> and <field> are specified only the format settings for that\n\
mode and field are shown. Example:\n\t\
/set format myformat\n\
shows the format settings for the mode myformat\n
help.set.truncation = \
Set the max length a displayed value.\n\
Set the max length of a displayed value:\n\
\n\t\
/set truncation <mode> <length> <selector>...\n\
\n\
Show the current truncation settings:\n\
\n\t\
/set truncation [<mode>]\n\
\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <length> is an unsigned integer representing a maximum length.\n\
Where <selector> is only needed if you wish to fine-tune value truncation length\n\
@ -571,46 +585,108 @@ Examples:\n\t\
/set trunc mymode 80\n\t\
/set truncation mymode 45 expression\n\t\
/set truncation mymode 0 vardecl-modified,replaced\n\n\
Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
\n\
The form without <length> shows the truncation settings.\n\
When the <mode> is specified only the truncation settings for that mode are shown.\n\
Example:\n\t\
/set truncation myformat\n\
shows the truncation settings for the mode myformat\n
help.set.feedback = \
Set the feedback mode describing displayed feedback for entered snippets and commands.\n\
Set the feedback mode describing displayed feedback for entered snippets and commands:\n\
\n\t\
/set feedback <mode>\n\
/set feedback [-retain] <mode>\n\
\n\
Retain the current feedback mode for future sessions:\n\
\n\t\
/set feedback -retain\n\
\n\
Show the feedback mode and list available modes:\n\
\n\t\
/set feedback\n\
\n\
Where <mode> is the name of a previously defined feedback mode.\n\
You may use just enough letters to make it unique.\n\
User-defined modes can be added, see '/help /set mode'\n\
Currently defined feedback modes:\n
\n\
When the -retain option is used, the setting will be used in this and future\n\
runs of the jshell tool.\n\
\n\
The form without <mode> or -retain displays the current feedback mode and available modes.\n
help.set.mode = \
Create a user-defined feedback mode, optionally copying from an existing mode.\n\
Create a user-defined feedback mode, optionally copying from an existing mode:\n\
\n\t\
/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\
Retain a user-defined feedback mode for future sessions:\n\
\n\t\
/set mode -retain <mode>\n\
\n\
Delete a user-defined feedback mode:\n\
\n\t\
/set mode -delete [-retain] <mode>\n\
\n\
Show feedback mode settings:\n\
\n\t\
/set mode [<mode>]\n\
\n\
Where <new-mode> is the name of a mode you wish to create.\n\
Where <old-mode> is the name of a previously defined feedback mode.\n\
If <old-mode> is present, its settings are copied to the new mode.\n\
'-command' vs '-quiet' determines if informative/verifying command feedback is displayed.\n\
\n\
Once the new mode is created, use '/set format' and '/set prompt' to configure it.\n\
Use '/set feedback' to use the new mode.\n\
Once the new mode is created, use '/set format', '/set prompt' and '/set truncation'\n\
to configure it. Use '/set feedback' to use the new mode.\n\
\n\
When the -retain option is used, the mode (including its component prompt, format,\n\
and truncation settings) will be used in this and future runs of the jshell tool.\n\
When both -retain and -delete are used, the mode is deleted from the current\n\
and future sessions.\n\
\n\
The form without options shows the mode settings.\n\
When the <mode> is specified only the mode settings for that mode are shown.\n\
Note: the settings for the mode include the settings for prompt, format, and\n\
truncation -- so these are displayed as well.\n\
Example:\n\t\
/set mode myformat\n\
shows the mode, prompt, format, and truncation settings for the mode myformat\n
help.set.prompt = \
Set the prompts. Both the normal prompt and the continuation-prompt must be set.\n\
Set the prompts. Both the normal prompt and the continuation-prompt must be set:\n\
\n\t\
/set prompt <mode> \"<prompt>\" \"<continuation-prompt>\"\n\
\n\
Show the normal prompt and the continuation-prompts:\n\
\n\t\
/set prompt [<mode>]\n\
\n\
Where <mode> is the name of a previously defined feedback mode.\n\
Where <prompt> and <continuation-prompt> are quoted strings printed as input prompts;\n\
Both may optionally contain '%s' which will be substituted with the next snippet id --\n\
note that what is entered may not be assigned that id, for example it may be an error or command.\n\
The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n
The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n\
\n\
The form without <prompt> shows the currently set prompts.\n\
When the <mode> is specified only the prompts for that mode are shown.\n\
Example:\n\t\
/set prompt myformat\n\
shows the prompts set for the mode myformat\n
help.set.editor =\
Specify the command to launch for the /edit command.\n\
Specify the command to launch for the /edit command:\n\
\n\t\
/set editor [-wait] <command>|-default\n\
/set editor [-retain] [-wait] <command>\n\
\n\t\
/set editor [-retain] [-retain] -default\n\
\n\
Retain the current editor setting for future sessions:\n\
\n\t\
/set editor -retain\n\
\n\
Show the command to launch for the /edit command:\n\
\n\t\
/set editor\n\
\n\
The <command> is an operating system dependent string.\n\
The <command> may include space-separated arguments (such as flags)\n\n\
@ -622,12 +698,29 @@ will exit immediately (for example, if the edit window exists) either external e
flags should be used to prevent immediate exit, or the -wait option should be used to\n\
prompt the user to indicate when edit mode should end.\n\n\
Note: while in edit mode no command inputs are seen. After leaving edit mode changes\n\
to the edited snippets are not seen.
to the edited snippets are not seen.\n\
\n\
When the -retain option is used, the setting will be used in this and future\n\
runs of the jshell tool.\n\
\n\
The form without <command> or options shows the editor setting.\n
help.set.start =\
Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\
Set the start-up configuration -- a sequence of snippets and commands read at start-up:\n\
\n\t\
/set start <file>|-default|-none\n\
/set start [-retain] <file>\n\
\n\t\
/set start [-retain] -default\n\
\n\t\
/set start [-retain] -none\n\
\n\
Retain the start-up configuration for future sessions:\n\
\n\t\
/set start -retain\n\
\n\
Show the start-up setting:\n\
\n\t\
/set start\n\
\n\
The contents of the specified <file> become the start-up snippets and commands used\n\
when the /reset or /reload commands are used in this session.\n\
@ -637,59 +730,14 @@ If the -none option is used, the start-up will be empty -- no start-up snippets\
or commands will be used.\n\
This command is good for testing the start-up settings. To retain them for future\n\
runs of the jshell tool use the command:\n\t\
/retain start\n
help.retain.feedback = \
Retain which feedback mode to use for displayed feedback for entered snippets and commands.\n\
This feedback mode will be used in this and future sessions of the jshell tool.\n\
\n\t\
/retain feedback [<mode>]\n\
/set start -retain\n\
\n\
Where <mode> is the name of a previously defined feedback mode.\n\
You may use just enough letters to make it unique.\n\
If the <mode> is not specified, this command retains the current mode (as set\n\
with the most recent /set feedback or /retain feedback command.)\n\
help.retain.mode = \
Retain the existence and configuration of a user-defined feedback mode.\n\
This mode will be available in this and future sessions of the jshell tool.
\n\t\
/retain mode <mode>\n\
When the -retain option is used, the setting will be used in this and future\n\
runs of the jshell tool.\n\
\n\
Where <mode> is the name of a mode you wish to retain.\n\
The <mode> must previously have been created with /set mode and\n\
configured as desired with /set prompt, /set format, and /set truncation.\n
help.retain.editor =\
Retain the command to launch for the /edit command. This command will be invoked when\n\
the /edit command is used in this and future sessions of the jshell tool.\n\
\n\t\
/retain editor [<command>|-default]\n\
\n\
If <command> is specified, it is an operating system dependent string which\n\
may include space-separated arguments (such as flags). When /edit is used, the\n\
temporary file to edit will be appended as the last argument.\n\
If instead the -default option is specified, the built-in default editor will be used.\n\
If neither is specified, the editor set in the last /set editor or /retain editor\n\
command will be used.\n\
The editor will be retained and used in this and future runs of the jshell tool.
help.retain.start =\
Retain the start-up configuration -- a sequence of snippets and commands read\n\
at start-up.\n\
\n\t\
/retain start [<file>|-default|-none]\n\
\n\
If <file> is specified, the contents of the specified <file> become the\n\
start-up snippets\n\
and commands.\n\
If instead the -default option is specified, the predefined start-up snippets\n\
will be the start-up.\n\
If the -none option is used, the start-up will be empty -- no start-up snippets\n\
or commands will be used.\n\
If none of these is specified, the start-up is the last specified in a\n\
''/set start'' or ''/retain start'' command.\n\
The start-up will be retained and used when the jshell tool is started or reset
The form without <file> or options shows the start-up setting.\n\
Note: if the start-up was last set from a file, this is shown with the\n\
contents of the file followed by a 'set start' command.
startup.feedback = \
/set mode verbose -command \n\
@ -773,6 +821,8 @@ startup.feedback = \
\n\
/set mode silent -quiet \n\
/set prompt silent '-> ' '>> ' \n\
/set truncation silent 80\n\
/set truncation silent 1000 varvalue,expression\n\
/set format silent pre '| ' \n\
/set format silent post '%n' \n\
/set format silent errorpre '| ' \n\

View File

@ -28,6 +28,7 @@ package jdk.jshell;
import jdk.jshell.spi.ExecutionControl;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.ArrayList;
@ -167,6 +168,10 @@ public class JShell implements AutoCloseable {
* user input cannot use {@code System.in} as the input stream for
* the remote process.
* <p>
* The {@code read} method of the {@code InputStream} may throw the {@link InterruptedIOException}
* to signal the user canceled the input. The currently running snippet will be automatically
* {@link JShell#stop() stopped}.
* <p>
* The default, if this is not set, is to provide an empty input stream
* -- {@code new ByteArrayInputStream(new byte[0])}.
*

View File

@ -42,7 +42,7 @@ class PipeInputStream extends InputStream {
@Override
public synchronized int read() throws IOException {
if (start == end) {
if (start == end && !closed) {
inputNeeded();
}
while (start == end) {
@ -62,6 +62,32 @@ class PipeInputStream extends InputStream {
}
}
@Override
public synchronized int read(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int totalRead = 1;
while (totalRead < len && start != end) {
int r = read();
if (r == (-1))
break;
b[off + totalRead++] = (byte) r;
}
return totalRead;
}
protected void inputNeeded() throws IOException {}
private synchronized void write(int b) {

View File

@ -28,6 +28,7 @@ import jdk.jshell.spi.ExecutionEnv;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
@ -42,6 +43,7 @@ import java.util.function.Consumer;
import com.sun.jdi.VirtualMachine;
import jdk.jshell.spi.ExecutionControl;
import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
/**
@ -54,6 +56,10 @@ import jdk.jshell.spi.ExecutionControl;
*/
public class Util {
private static final int TAG_DATA = 0;
private static final int TAG_CLOSED = 1;
private static final int TAG_EXCEPTION = 2;
// never instanciated
private Util() {}
@ -131,6 +137,25 @@ public class Util {
inputSignal.write('1');
inputSignal.flush();
}
@Override
public synchronized int read() throws IOException {
int tag = super.read();
switch (tag) {
case TAG_DATA: return super.read();
case TAG_CLOSED: close(); return -1;
case TAG_EXCEPTION:
int len = (super.read() << 0) + (super.read() << 8) + (super.read() << 16) + (super.read() << 24);
byte[] message = new byte[len];
for (int i = 0; i < len; i++) {
message[i] = (byte) super.read();
}
throw new IOException(new String(message, "UTF-8"));
case -1:
return -1;
default:
throw new IOException("Internal error: unrecognized message tag: " + tag);
}
}
};
inputs.put(e.getKey(), inputPipe.createOutput());
e.getValue().accept(inputPipe);
@ -163,6 +188,7 @@ public class Util {
public static ExecutionControl remoteInputOutput(InputStream input, OutputStream output,
Map<String, OutputStream> outputStreamMap, Map<String, InputStream> inputStreamMap,
BiFunction<ObjectInput, ObjectOutput, ExecutionControl> factory) throws IOException {
ExecutionControl[] result = new ExecutionControl[1];
Map<String, OutputStream> augmentedStreamMap = new HashMap<>(outputStreamMap);
ObjectOutput commandOut = new ObjectOutputStream(Util.multiplexingOutputStream("$command", output));
for (Entry<String, InputStream> e : inputStreamMap.entrySet()) {
@ -172,7 +198,28 @@ public class Util {
@Override
public void write(int b) throws IOException {
//value ignored, just a trigger to read from the input
inTarget.write(in.read());
try {
int r = in.read();
if (r == (-1)) {
inTarget.write(TAG_CLOSED);
} else {
inTarget.write(new byte[] {TAG_DATA, (byte) r});
}
} catch (InterruptedIOException exc) {
try {
result[0].stop();
} catch (ExecutionControlException ex) {
debug(ex, "$" + e.getKey() + "-input-requested.write");
}
} catch (IOException exc) {
byte[] message = exc.getMessage().getBytes("UTF-8");
inTarget.write(TAG_EXCEPTION);
inTarget.write((message.length >> 0) & 0xFF);
inTarget.write((message.length >> 8) & 0xFF);
inTarget.write((message.length >> 16) & 0xFF);
inTarget.write((message.length >> 24) & 0xFF);
inTarget.write(message);
}
}
});
}
@ -180,7 +227,7 @@ public class Util {
OutputStream commandInTarget = commandIn.createOutput();
augmentedStreamMap.put("$command", commandInTarget);
new DemultiplexInput(input, augmentedStreamMap, Arrays.asList(commandInTarget)).start();
return factory.apply(new ObjectInputStream(commandIn), commandOut);
return result[0] = factory.apply(new ObjectInputStream(commandIn), commandOut);
}
/**
@ -198,4 +245,13 @@ public class Util {
}
}
/**
* Log a serious unexpected internal exception.
*
* @param ex the exception
* @param where a description of the context of the exception
*/
private static void debug(Throwable ex, String where) {
// Reserved for future logging
}
}

View File

@ -157,11 +157,6 @@ ifdef TESTBOOTCLASSPATH
-refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH)
endif
ifeq ($(ARCH_DATA_MODEL),32)
# Set the GC options for test vms
JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
JTREG_OPTIONS += $(JTREG_GC_OPTION)
endif
# Set the max memory for jtreg target test JVMs
JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx768m
JTREG_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
@ -256,6 +251,17 @@ JTREG_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jtreg
JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
# Is the test JVM 32-bit?
DATA_MODEL := \
$(shell $(JT_JAVA)/bin/java -XshowSettings:properties -version 2>&1 | \
grep 'sun\.arch\.data\.model' | \
awk '{print $$3}')
ifeq ($(DATA_MODEL), 32)
# Set the GC options for test vms having a smaller address space
JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
JTREG_OPTIONS += $(JTREG_GC_OPTION)
endif
# Default make rule -- warning, may take a while
all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
@echo "Testing completed successfully"

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756
* @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8151921
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib
@ -54,11 +54,12 @@ public class TestJavascript extends JavadocTester {
checkOutput("index.html", true,
"<script type=\"text/javascript\">\n"
+ " targetPage = \"\" + window.location.search;\n"
+ " if (targetPage != \"\" && targetPage != \"undefined\")\n"
+ " targetPage = targetPage.substring(1);\n"
+ " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
+ " targetPage = \"undefined\";\n"
+ " tmpTargetPage = \"\" + window.location.search;\n"
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+ " tmpTargetPage = tmpTargetPage.substring(1);\n"
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+ " tmpTargetPage = \"undefined\";\n"
+ " targetPage = tmpTargetPage;\n"
+ " function validURL(url) {\n"
+ " try {\n"
+ " url = decodeURIComponent(url);\n"

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985
* @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib
@ -54,11 +54,12 @@ public class TestJavascript extends JavadocTester {
checkOutput("index.html", true,
"<script type=\"text/javascript\">\n"
+ " targetPage = \"\" + window.location.search;\n"
+ " if (targetPage != \"\" && targetPage != \"undefined\")\n"
+ " targetPage = targetPage.substring(1);\n"
+ " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
+ " targetPage = \"undefined\";\n"
+ " tmpTargetPage = \"\" + window.location.search;\n"
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+ " tmpTargetPage = tmpTargetPage.substring(1);\n"
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+ " tmpTargetPage = \"undefined\";\n"
+ " targetPage = tmpTargetPage;\n"
+ " function validURL(url) {\n"
+ " try {\n"
+ " url = decodeURIComponent(url);\n"

View File

@ -23,7 +23,7 @@
/**
* @test
* @bug 8159305
* @bug 8159305 8167383
* @summary Tests elements filtering options
* @modules
* jdk.javadoc/jdk.javadoc.internal.api
@ -73,6 +73,10 @@ public class FilterOptions extends ModuleTestBase {
"--module", "m1", "--show-module-contents", "api");
checkModuleMode("API");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesNotIncluded("pro", "pqe");
}
@Test
@ -81,6 +85,10 @@ public class FilterOptions extends ModuleTestBase {
"--module", "m1", "--show-module-contents", "all");
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub", "pqe");
checkPackagesNotIncluded("pro");
}
@Test
@ -92,6 +100,7 @@ public class FilterOptions extends ModuleTestBase {
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
}
@ -102,9 +111,10 @@ public class FilterOptions extends ModuleTestBase {
"--show-packages", "all");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub", "pro");
checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
"pqe.A", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
"pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
}
@ -221,6 +231,7 @@ public class FilterOptions extends ModuleTestBase {
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.PublicNested");
checkMembers(Visibility.PUBLIC);
@ -235,6 +246,7 @@ public class FilterOptions extends ModuleTestBase {
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
checkMembers(Visibility.PROTECTED);
@ -250,6 +262,7 @@ public class FilterOptions extends ModuleTestBase {
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
checkMembers(Visibility.PROTECTED);
@ -264,10 +277,10 @@ public class FilterOptions extends ModuleTestBase {
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesIncluded("pro");
checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
"pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
"pqe.A", "pqe.A.Nested", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
"pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
"pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
@ -283,12 +296,13 @@ public class FilterOptions extends ModuleTestBase {
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
checkPackagesIncluded("pro");
checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
"pub.B.PublicNested",
"pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
"pub.A.PublicNested",
"pqe.A", "pqe.A.PrivateNested", "pqe.A.Nested", "pqe.A.ProtectedNested",
"pqe.A.PublicNested",
"pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
"pro.B.PublicNested",
"pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
@ -365,8 +379,17 @@ public class FilterOptions extends ModuleTestBase {
.classes(createClass("pub", "B", false))
.classes(createClass("pro", "A", true))
.classes(createClass("pro", "B", false))
.classes(createClass("pqe", "A", true))
.exports("pub")
.exportsTo("pqe", "m2")
.write(src);
ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
mb2.comment("The second module")
.classes(createClass("m2pub", "A", true))
.requires("m1")
.write(src);
return src.toString();
}

View File

@ -222,7 +222,10 @@ public class Modules extends ModuleTestBase {
.classes("package pkg2; /** @see pkg1.A */ public class B { }")
.write(src);
Path out = base.resolve("out-1");
Files.createDirectories(out);
String log = new JavadocTask(tb)
.outdir(out)
.options("--module-source-path", src.toString(),
"--module-path", modulePath.toString(),
"--module", "m2")
@ -233,7 +236,10 @@ public class Modules extends ModuleTestBase {
throw new Exception("Error not found");
}
out = base.resolve("out-2");
Files.createDirectories(out);
new JavadocTask(tb)
.outdir(out)
.options("--module-source-path", src.toString(),
"--module-path", modulePath.toString(),
"--add-modules", "m1",

View File

@ -54,7 +54,7 @@ public class CommandCompletionTest extends ReplToolTesting {
public void testCommand() {
assertCompletion("/deb|", false);
assertCompletion("/re|", false, "/reload ", "/reset ", "/retain ");
assertCompletion("/re|", false, "/reload ", "/reset ");
assertCompletion("/h|", false, "/help ", "/history ");
}
@ -195,34 +195,6 @@ public class CommandCompletionTest extends ReplToolTesting {
);
}
public void testRetain() throws IOException {
List<String> p1 = listFiles(Paths.get(""));
FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
Collections.sort(p1);
String[] modes = {"concise ", "normal ", "silent ", "verbose "};
test(false, new String[] {"--no-startup"},
a -> assertCompletion(a, "/ret|", false, "/retain "),
a -> assertCompletion(a, "/retain |", false, "editor ", "feedback ", "mode ", "start "),
// /retain editor
a -> assertCompletion(a, "/retain e|", false, "editor "),
a -> assertCompletion(a, "/retain editor |", false, p1.toArray(new String[p1.size()])),
// /retain feedback
a -> assertCompletion(a, "/retain fe|", false, "feedback "),
a -> assertCompletion(a, "/retain fe |", false, modes),
// /retain mode
a -> assertCompletion(a, "/retain mo|", false, "mode "),
a -> assertCompletion(a, "/retain mo |", false, modes),
// /retain start
a -> assertCompletion(a, "/retain st|", false, "start "),
a -> assertCompletion(a, "/retain st |", false, p1.toArray(new String[p1.size()]))
);
}
private void createIfNeeded(Path file) throws IOException {
if (!Files.exists(file))
Files.createFile(file);

View File

@ -193,7 +193,6 @@ public class ExternalEditorTest extends EditorTestBase {
@Test
public void setUnknownEditor() {
test(
a -> assertCommand(a, "/set editor", "| The '/set editor' command requires a path argument"),
a -> assertCommand(a, "/set editor UNKNOWN", "| Editor set to: UNKNOWN"),
a -> assertCommand(a, "int a;", null),
a -> assertCommandOutputStartsWith(a, "/ed 1",

View File

@ -21,7 +21,10 @@
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.StringWriter;
import java.lang.reflect.Method;
@ -83,7 +86,7 @@ public class KullaTesting {
private SourceCodeAnalysis analysis = null;
private JShell state = null;
private TestingInputStream inStream = null;
private InputStream inStream = null;
private ByteArrayOutputStream outStream = null;
private ByteArrayOutputStream errStream = null;
@ -106,7 +109,11 @@ public class KullaTesting {
}
public void setInput(String s) {
inStream.setInput(s);
setInput(new ByteArrayInputStream(s.getBytes()));
}
public void setInput(InputStream in) {
inStream = in;
}
public String getOutput() {
@ -159,11 +166,27 @@ public class KullaTesting {
}
public void setUp(Consumer<JShell.Builder> bc) {
inStream = new TestingInputStream();
InputStream in = new InputStream() {
@Override
public int read() throws IOException {
assertNotNull(inStream);
return inStream.read();
}
@Override
public int read(byte[] b) throws IOException {
assertNotNull(inStream);
return inStream.read(b);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
assertNotNull(inStream);
return inStream.read(b, off, len);
}
};
outStream = new ByteArrayOutputStream();
errStream = new ByteArrayOutputStream();
JShell.Builder builder = JShell.builder()
.in(inStream)
.in(in)
.out(new PrintStream(outStream))
.err(new PrintStream(errStream));
bc.accept(builder);

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test 8167461
* @summary Verify PipeInputStream works.
* @modules jdk.compiler/com.sun.tools.javac.util
* jdk.jshell
* @run testng PipeInputStreamTest
*/
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import com.sun.tools.javac.util.Pair;
import static org.testng.Assert.*;
@Test
public class PipeInputStreamTest {
public void testReadArrayNotBlocking() throws Exception {
Pair<InputStream, OutputStream> streams = createPipeStream();
InputStream in = streams.fst;
OutputStream out = streams.snd;
out.write('a');
byte[] data = new byte[12];
assertEquals(in.read(data), 1);
assertEquals(data[0], 'a');
out.write('a'); out.write('b'); out.write('c');
assertEquals(in.read(data), 3);
assertEquals(data[0], 'a');
assertEquals(data[1], 'b');
assertEquals(data[2], 'c');
}
private Pair<InputStream, OutputStream> createPipeStream() throws Exception {
Class<?> pipeStreamClass = Class.forName("jdk.jshell.execution.PipeInputStream");
Constructor<?> c = pipeStreamClass.getDeclaredConstructor();
c.setAccessible(true);
Object pipeStream = c.newInstance();
Method createOutputStream = pipeStreamClass.getDeclaredMethod("createOutput");
createOutputStream.setAccessible(true);
return Pair.of((InputStream) pipeStream, (OutputStream) createOutputStream.invoke(pipeStream));
}
}

View File

@ -431,12 +431,12 @@ public class ToolBasicTest extends ReplToolTesting {
(a) -> assertMethod(a, "void f() {}", "()V", "f"),
(a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
(a) -> assertCommand(a, "/save " + startUpFile.toString(), null),
(a) -> assertCommand(a, "/retain start " + startUpFile.toString(), null)
(a) -> assertCommand(a, "/set start -retain " + startUpFile.toString(), null)
);
Path unknown = compiler.getPath("UNKNOWN");
test(
(a) -> assertCommandOutputStartsWith(a, "/retain start " + unknown.toString(),
"| File '" + unknown + "' for '/retain start' is not found.")
(a) -> assertCommandOutputStartsWith(a, "/set start -retain " + unknown.toString(),
"| File '" + unknown + "' for '/set start' is not found.")
);
test(false, new String[0],
(a) -> {

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8157395 8157393 8157517 8158738 8167128
* @bug 8157395 8157393 8157517 8158738 8167128 8163840
* @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolCommandOptionTest ReplToolTesting
@ -128,46 +128,73 @@ public class ToolCommandOptionTest extends ReplToolTesting {
(a) -> assertCommand(a, "/set editor prog",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/set editor prog -default",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/se ed prog -furball",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/set editor -default",
""),
(a) -> assertCommand(a, "/se edi -def",
""),
"| Editor set to: prog -default"),
(a) -> assertCommand(a, "/set editor",
"| The '/set editor' command requires a path argument")
"| /set editor prog -default"),
(a) -> assertCommand(a, "/se ed prog -furball",
"| Editor set to: prog -furball"),
(a) -> assertCommand(a, "/set editor",
"| /set editor prog -furball"),
(a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4",
"| Editor set to: prog arg1 -furball arg3 -default arg4"),
(a) -> assertCommand(a, "/set editor",
"| /set editor prog arg1 -furball arg3 -default arg4"),
(a) -> assertCommand(a, "/set editor -default",
"| Editor set to: -default"),
(a) -> assertCommand(a, "/se edi -def",
"| Editor set to: -default"),
(a) -> assertCommand(a, "/set editor",
"| /set editor -default")
);
}
public void retainEditorTest() {
test(
(a) -> assertCommand(a, "/retain editor -furball",
"| Unknown option: -furball -- /retain editor -furball"),
(a) -> assertCommand(a, "/retain editor -furball prog",
"| Unknown option: -furball -- /retain editor -furball prog"),
(a) -> assertCommand(a, "/retain editor -furball -mattress",
"| Unknown option: -furball -mattress -- /retain editor -furball -mattress"),
(a) -> assertCommand(a, "/retain editor -default prog",
"| Specify -default option or program, not both -- /retain editor -default prog"),
(a) -> assertCommand(a, "/retain editor -default -wait",
"| -wait applies to external editors, cannot be used with -default"),
(a) -> assertCommand(a, "/retain editor prog",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/retain editor prog -default",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/ret ed prog -furball",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/retain editor prog arg1 -furball arg3 -default arg4",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/retain editor -default",
""),
(a) -> assertCommand(a, "/reta edi -def",
""),
(a) -> assertCommand(a, "/retain editor",
"")
(a) -> assertCommand(a, "/set editor -retain -furball",
"| Unknown option: -furball -- /set editor -retain -furball"),
(a) -> assertCommand(a, "/set editor -retain -furball prog",
"| Unknown option: -furball -- /set editor -retain -furball prog"),
(a) -> assertCommand(a, "/set editor -retain -furball -mattress",
"| Unknown option: -furball -mattress -- /set editor -retain -furball -mattress"),
(a) -> assertCommand(a, "/set editor -retain -default prog",
"| Specify -default option or program, not both -- /set editor -retain -default prog"),
(a) -> assertCommand(a, "/set editor -retain -wait",
"| -wait applies to external editors"),
(a) -> assertCommand(a, "/set editor -retain -default -wait",
"| -wait applies to external editors"),
(a) -> assertCommand(a, "/set editor -retain prog",
"| Editor set to: prog\n" +
"| Editor setting retained: prog"),
(a) -> assertCommand(a, "/set editor",
"| /set editor -retain prog"),
(a) -> assertCommand(a, "/se ed other",
"| Editor set to: other"),
(a) -> assertCommand(a, "/set editor",
"| /set editor -retain prog\n" +
"| /set editor other"),
(a) -> assertCommand(a, "/set editor -retain prog -default",
"| Editor set to: prog -default\n" +
"| Editor setting retained: prog -default"),
(a) -> assertCommand(a, "/set editor",
"| /set editor -retain prog -default"),
(a) -> assertCommand(a, "/se ed -retain prog -furball",
"| Editor set to: prog -furball\n" +
"| Editor setting retained: prog -furball"),
(a) -> assertCommand(a, "/set editor -retain prog arg1 -furball arg3 -default arg4",
"| Editor set to: prog arg1 -furball arg3 -default arg4\n" +
"| Editor setting retained: prog arg1 -furball arg3 -default arg4"),
(a) -> assertCommand(a, "/set editor",
"| /set editor -retain prog arg1 -furball arg3 -default arg4"),
(a) -> assertCommand(a, "/set editor -retain -default",
"| Editor set to: -default\n" +
"| Editor setting retained: -default"),
(a) -> assertCommand(a, "/set editor",
"| /set editor -retain -default"),
(a) -> assertCommand(a, "/se e -ret -def",
"| Editor set to: -default\n" +
"| Editor setting retained: -default"),
(a) -> assertCommand(a, "/set editor -retain",
"| Editor setting retained: -default")
);
}
@ -182,45 +209,56 @@ public class ToolCommandOptionTest extends ReplToolTesting {
(a) -> assertCommand(a, "/set start -furball -mattress",
"| Unknown option: -furball -mattress -- /set start -furball -mattress"),
(a) -> assertCommand(a, "/set start foo -default",
"| Specify either one option or a startup file name -- /set start foo -default"),
"| Specify no more than one of -default, -none, or a startup file name -- /set start foo -default"),
(a) -> assertCommand(a, "/set start frfg",
"| File 'frfg' for '/set start' is not found."),
(a) -> assertCommand(a, "/set start -default",
""),
(a) -> assertCommand(a, "/set start",
"| /set start -default"),
(a) -> assertCommand(a, "/se sta -no",
""),
(a) -> assertCommand(a, "/set start",
"| Specify either one option or a startup file name -- /set start")
"| /set start -none")
);
}
public void retainStartTest() {
test(
(a) -> assertCommand(a, "/retain start -furball",
"| Unknown option: -furball -- /retain start -furball"),
(a) -> assertCommand(a, "/retain start -furball pyle",
"| Unknown option: -furball -- /retain start -furball pyle"),
(a) -> assertCommand(a, "/ret st pyle -furball",
"| Unknown option: -furball -- /retain st pyle -furball"),
(a) -> assertCommand(a, "/retain start -furball -mattress",
"| Unknown option: -furball -mattress -- /retain start -furball -mattress"),
(a) -> assertCommand(a, "/retain start foo -default",
"| Specify either one option or a startup file name -- /retain start foo -default"),
(a) -> assertCommand(a, "/retain start frfg",
"| File 'frfg' for '/retain start' is not found."),
(a) -> assertCommand(a, "/retain start -default",
(a) -> assertCommand(a, "/set start -retain -furball",
"| Unknown option: -furball -- /set start -retain -furball"),
(a) -> assertCommand(a, "/set start -retain -furball pyle",
"| Unknown option: -furball -- /set start -retain -furball pyle"),
(a) -> assertCommand(a, "/se st -re pyle -furball",
"| Unknown option: -furball -- /set st -re pyle -furball"),
(a) -> assertCommand(a, "/set start -retain -furball -mattress",
"| Unknown option: -furball -mattress -- /set start -retain -furball -mattress"),
(a) -> assertCommand(a, "/set start -retain foo -default",
"| Specify no more than one of -default, -none, or a startup file name -- /set start -retain foo -default"),
(a) -> assertCommand(a, "/set start -retain -default foo",
"| Specify no more than one of -default, -none, or a startup file name -- /set start -retain -default foo"),
(a) -> assertCommand(a, "/set start -retain frfg",
"| File 'frfg' for '/set start' is not found."),
(a) -> assertCommand(a, "/set start -retain -default",
""),
(a) -> assertCommand(a, "/ret sta -no",
(a) -> assertCommand(a, "/set start",
"| /set start -retain -default"),
(a) -> assertCommand(a, "/set sta -no",
""),
(a) -> assertCommand(a, "/retain start",
"")
(a) -> assertCommand(a, "/set start",
"| /set start -retain -default\n" +
"| /set start -none"),
(a) -> assertCommand(a, "/se st -ret",
""),
(a) -> assertCommand(a, "/se sta",
"| /set start -retain -none")
);
}
public void setModeTest() {
test(
(a) -> assertCommandOutputStartsWith(a, "/set mode",
"| Missing the feedback mode"),
(a) -> assertCommandOutputContains(a, "/set mode",
"| /set format verbose unresolved"),
(a) -> assertCommandOutputStartsWith(a, "/set mode *",
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/set mode -quiet",
@ -229,11 +267,13 @@ public class ToolCommandOptionTest extends ReplToolTesting {
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing",
"| Unexpected arguments at end of command: thing"),
(a) -> assertCommand(a, "/set mode mymode",
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
"| To create a new mode either the -command or the -quiet option must be used"),
(a) -> assertCommand(a, "/set mode mymode -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
(a) -> assertCommand(a, "/set mode mymode normal",
(a) -> assertCommand(a, "/set mode mymode normal -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set mode -del mymode",
""),
@ -245,18 +285,33 @@ public class ToolCommandOptionTest extends ReplToolTesting {
"| Conflicting options"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d",
"| No feedback mode named: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode normal",
"| Not valid with a predefined mode: normal"),
(a) -> assertCommandOutputStartsWith(a, "/set mode normal -c",
"| Mode to be created already exists: normal"),
(a) -> assertCommand(a, "/se mo -c mymode",
"| Created new feedback mode: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
"| /set mode mymode -command"),
(a) -> assertCommand(a, "/set feedback mymode",
"| Feedback mode: mymode"),
(a) -> assertCommand(a, "/se fe",
"| /set feedback mymode\n" +
"| \n" +
"| Available feedback modes:\n" +
"| concise\n" +
"| mymode\n" +
"| normal\n" +
"| silent\n" +
"| verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
"| The current feedback mode 'mymode' cannot be deleted"),
(a) -> assertCommand(a, "/set feedback no",
"| Feedback mode: normal"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
""),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
"| To create a new mode either the -command or the -quiet option must be used -- \n" +
"| Does not match any current feedback mode: mymode -- /set mode mymode\n" +
"| Available feedback modes:"),
(a) -> assertCommandCheckOutput(a, "/set feedback",
(s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s))
);
@ -272,8 +327,20 @@ public class ToolCommandOptionTest extends ReplToolTesting {
""),
(a) -> assertCommand(a, "45",
"blurb"),
(a) -> assertCommand(a, "/set mode mymode normal",
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode normal",
"| To create a new mode either the -command or the -quiet option must be used"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command normal",
"| Mode to be created already exists: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
"| The current feedback mode 'mymode' cannot be deleted, use '/set feedback' first"),
(a) -> assertCommand(a, "/set feedback normal",
"| Feedback mode: normal"),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
(a) -> assertCommand(a, "/set mode mymode -command normal",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set feedback mymode",
"| Feedback mode: mymode"),
(a) -> assertCommandOutputContains(a, "45",
" ==> 45")
);
@ -281,67 +348,89 @@ public class ToolCommandOptionTest extends ReplToolTesting {
public void retainModeTest() {
test(
(a) -> assertCommandOutputStartsWith(a, "/retain mode",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain",
"| Missing the feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode *",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain *",
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode amode normal",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain amode normal",
"| Unexpected arguments at end of command: normal"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode mymode",
"| Does not match any current feedback mode: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode mymode -delete",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode",
"| No feedback mode named: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode -d mymode",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode -delete",
"| No feedback mode named: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode normal",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain -d mymode",
"| No feedback mode named: mymode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain normal",
"| Not valid with a predefined mode: normal"),
(a) -> assertCommand(a, "/set mode mymode verbose",
(a) -> assertCommand(a, "/set mode mymode verbose -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/retain mode mymode",
(a) -> assertCommand(a, "/set mode -retain mymode",
""),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
(a) -> assertCommand(a, "/retain mode mymode -delete",
(a) -> assertCommand(a, "/set mode -retain mymode -delete",
""),
(a) -> assertCommand(a, "/set mode kmode normal",
(a) -> assertCommand(a, "/set mode kmode normal -command",
"| Created new feedback mode: kmode"),
(a) -> assertCommand(a, "/retain mode kmode",
(a) -> assertCommand(a, "/set mode -retain kmode",
""),
(a) -> assertCommand(a, "/set mode kmode -delete",
""),
(a) -> assertCommand(a, "/set mode tmode normal",
(a) -> assertCommand(a, "/set mode tmode normal -command",
"| Created new feedback mode: tmode"),
(a) -> assertCommandOutputStartsWith(a, "/retain feedback tmode",
"| '/retain feedback <mode>' requires that <mode> is predefined or has been retained with '/retain mode'"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode",
"| '/set feedback -retain <mode>' requires that <mode> is predefined or has been retained with '/set mode -retain'"),
(a) -> assertCommand(a, "/set format tmode display 'YES'",
""),
(a) -> assertCommand(a, "/set feedback tmode",
"| Feedback mode: tmode"),
(a) -> assertCommand(a, "45",
"YES"),
(a) -> assertCommand(a, "/retain mode tmode",
(a) -> assertCommand(a, "/set mode -retain tmode",
""),
(a) -> assertCommand(a, "/retain feedback tmode",
(a) -> assertCommand(a, "/set feedback -retain tmode",
"| Feedback mode: tmode"),
(a) -> assertCommand(a, "/set format tmode display 'blurb'",
""),
(a) -> assertCommand(a, "/set format tmode display",
"| /set format tmode display \"blurb\""),
(a) -> assertCommandOutputContains(a, "/set mode tmode",
"| /set format tmode display \"YES\""),
(a) -> assertCommand(a, "45",
"blurb")
);
test(
(a) -> assertCommand(a, "/set format tmode display",
"| /set format tmode display \"YES\""),
(a) -> assertCommandOutputContains(a, "/set mode tmode",
"| /set format tmode display \"YES\""),
(a) -> assertCommand(a, "45",
"YES"),
(a) -> assertCommand(a, "/set feedback kmode",
"| Feedback mode: kmode"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
(a) -> assertCommand(a, "/set feedback",
"| /set feedback -retain tmode\n" +
"| /set feedback kmode\n" +
"| \n" +
"| Retained feedback modes:\n" +
"| kmode\n" +
"| tmode\n" +
"| Available feedback modes:\n" +
"| concise\n" +
"| kmode\n" +
"| normal\n" +
"| silent\n" +
"| tmode\n" +
"| verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
"| The current feedback mode 'kmode' cannot be deleted"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode tmode -delete",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain tmode -delete",
"| The retained feedback mode 'tmode' cannot be deleted"),
(a) -> assertCommand(a, "/retain feedback normal",
(a) -> assertCommand(a, "/set feedback -retain normal",
"| Feedback mode: normal"),
(a) -> assertCommand(a, "/retain mode tmode -delete",
(a) -> assertCommand(a, "/set mode -retain tmode -delete",
""),
(a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
"")
);
test(

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261
* @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840
* @summary Tests for output customization
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@ -33,10 +33,17 @@
* @build KullaTesting TestingInputStream toolbox.ToolBox Compiler
* @run testng ToolFormatTest
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class ToolFormatTest extends ReplToolTesting {
@ -81,6 +88,58 @@ public class ToolFormatTest extends ReplToolTesting {
}
}
public void testSetFormatOverride() {
test(
(a) -> assertCommand(a, "/set mode tm -c", "| Created new feedback mode: tm"),
(a) -> assertCommand(a, "/se fo tm x \"aaa\"", ""),
(a) -> assertCommand(a, "/se fo tm x \"bbb\" class,method-added", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"bbb\" class,method-added"),
(a) -> assertCommand(a, "/se fo tm x \"ccc\" class,method-added,modified", ""),
(a) -> assertCommand(a, "/se fo tm x \"ddd\" class,method-added", ""),
(a) -> assertCommand(a, "/se fo tm x \"eee\" method-added", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"ccc\" class,method-added,modified\n" +
"| /set format tm x \"ddd\" class,method-added\n" +
"| /set format tm x \"eee\" method-added"),
(a) -> assertCommand(a, "/se fo tm x \"EEE\" method-added,replaced", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"ccc\" class,method-added,modified\n" +
"| /set format tm x \"ddd\" class,method-added\n" +
"| /set format tm x \"EEE\" method-added,replaced"),
(a) -> assertCommand(a, "/se fo tm x \"fff\" method-added,replaced-ok", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"ccc\" class,method-added,modified\n" +
"| /set format tm x \"ddd\" class,method-added\n" +
"| /set format tm x \"EEE\" method-added,replaced\n" +
"| /set format tm x \"fff\" method-added,replaced-ok"),
(a) -> assertCommand(a, "/se fo tm x \"ggg\" method-ok", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"ccc\" class,method-added,modified\n" +
"| /set format tm x \"ddd\" class,method-added\n" +
"| /set format tm x \"EEE\" method-added,replaced\n" +
"| /set format tm x \"ggg\" method-ok"),
(a) -> assertCommand(a, "/se fo tm x \"hhh\" method", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"ccc\" class,method-added,modified\n" +
"| /set format tm x \"ddd\" class,method-added\n" +
"| /set format tm x \"hhh\" method"),
(a) -> assertCommand(a, "/se fo tm x \"iii\" method,class", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"aaa\" \n" +
"| /set format tm x \"iii\" class,method"),
(a) -> assertCommand(a, "/se fo tm x \"jjj\"", ""),
(a) -> assertCommand(a, "/se fo tm x",
"| /set format tm x \"jjj\"")
);
}
public void testSetFormatSelector() {
List<ReplTest> tests = new ArrayList<>();
tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
@ -167,8 +226,14 @@ public class ToolFormatTest extends ReplToolTesting {
(a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""),
(a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""),
(a) -> assertCommand(a, "/set truncation test 20", ""),
(a) -> assertCommand(a, "/set truncation test", "| /set truncation test 20"),
(a) -> assertCommandOutputContains(a, "/set truncation", "/set truncation test 20"),
(a) -> assertCommand(a, "/set trunc test 10 varvalue", ""),
(a) -> assertCommand(a, "/set trunc test 3 assignment", ""),
(a) -> assertCommandOutputContains(a, "/set truncation",
"/set truncation test 10 varvalue"),
(a) -> assertCommandOutputContains(a, "/set truncation test",
"/set truncation test 10 varvalue"),
(a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."),
(a) -> assertCommand(a, "r", "String:\"ABACA ..."),
(a) -> assertCommand(a, "r=s", "String:\"AB")
@ -201,6 +266,45 @@ public class ToolFormatTest extends ReplToolTesting {
);
}
public void testPrompt() {
test(
(a) -> assertCommand(a, "/set mode tp -quiet", "| Created new feedback mode: tp"),
(a) -> assertCommand(a, "/set prompt tp 'aaa' 'bbb'", ""),
(a) -> assertCommand(a, "/set prompt tp",
"| /set prompt tp \"aaa\" \"bbb\""),
(a) -> assertCommandOutputContains(a, "/set prompt",
"| /set prompt tp \"aaa\" \"bbb\""),
(a) -> assertCommand(a, "/set mode -retain tp", ""),
(a) -> assertCommand(a, "/set prompt tp 'ccc' 'ddd'", ""),
(a) -> assertCommand(a, "/set prompt tp",
"| /set prompt tp \"ccc\" \"ddd\""),
(a) -> assertCommandCheckOutput(a, "/set mode tp",
(s) -> {
try {
BufferedReader rdr = new BufferedReader(new StringReader(s));
assertEquals(rdr.readLine(), "| /set mode tp -quiet",
"| /set mode tp -quiet");
assertEquals(rdr.readLine(), "| /set prompt tp \"aaa\" \"bbb\"",
"| /set prompt tp \"aaa\" \"bbb\"");
String l = rdr.readLine();
while (l.startsWith("| /set format tp ")) {
l = rdr.readLine();
}
assertEquals(l, "| /set mode -retain tp",
"| /set mode -retain tp");
assertEquals(rdr.readLine(), "| ",
"| ");
assertEquals(rdr.readLine(), "| /set mode tp -quiet",
"| /set mode tp -quiet");
assertEquals(rdr.readLine(), "| /set prompt tp \"ccc\" \"ddd\"",
"| /set prompt tp \"ccc\" \"ddd\"");
} catch (IOException ex) {
fail("threw " + ex);
}
})
);
}
public void testShowFeedbackModes() {
test(
(a) -> assertCommandOutputContains(a, "/set feedback", "normal")
@ -216,7 +320,8 @@ public class ToolFormatTest extends ReplToolTesting {
(a) -> assertCommand(a, "/se fee nmq2", ""),
(a) -> assertCommand(a, "/set mode nmc -command normal", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"),
(a) -> assertCommandOutputStartsWith(a, "/set mode nm", "| Created new feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set mode nm -command",
"| Created new feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")
);
@ -231,37 +336,35 @@ public class ToolFormatTest extends ReplToolTesting {
test(
(a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo",
"| Does not match any current feedback mode: foo"),
(a) -> assertCommandOutputStartsWith(a, "/set mode tee flurb",
(a) -> assertCommandOutputStartsWith(a, "/set mode tee -quiet flurb",
"| Does not match any current feedback mode: flurb"),
(a) -> assertCommandOutputStartsWith(a, "/set mode tee",
(a) -> assertCommandOutputStartsWith(a, "/set mode -command tee",
"| Created new feedback mode: tee"),
(a) -> assertCommandOutputStartsWith(a, "/set mode verbose",
"| Not valid with a predefined mode: verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode verbose -command",
"| Mode to be created already exists: verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal",
"| Created new feedback mode: te"),
(a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback te",
""),
(a) -> assertCommandOutputStartsWith(a, "/set ",
"ERROR: The '/set' command requires a sub-command"),
(a) -> assertCommandOutputStartsWith(a, "/set xyz",
"ERROR: Invalid '/set' argument: xyz"),
(a) -> assertCommandOutputStartsWith(a, "/set f",
"ERROR: Ambiguous sub-command argument to '/set': f"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback",
"ERROR: Missing the feedback mode"),
"| /set feedback te"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback xyz",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set format",
"ERROR: Missing the feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set feed",
"| /set feedback te"),
(a) -> assertCommandOutputStartsWith(a, "/set format xyz",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set format t",
"ERROR: Matches more then one current feedback mode: t"),
(a) -> assertCommandOutputStartsWith(a, "/set format te",
"ERROR: Missing the field name"),
(a) -> assertCommandOutputStartsWith(a, "/set format qqq",
"ERROR: Does not match any current feedback mode: qqq"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld",
"ERROR: Expected format missing"),
"ERROR: Expected a field name:"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' frog",
@ -274,30 +377,28 @@ public class ToolFormatTest extends ReplToolTesting {
"ERROR: Different selector kinds in same sections of"),
(a) -> assertCommandOutputStartsWith(a, "/set trunc te 20x",
"ERROR: Truncation length must be an integer: 20x"),
(a) -> assertCommandOutputStartsWith(a, "/set trunc te",
"ERROR: Expected truncation length"),
(a) -> assertCommandOutputStartsWith(a, "/set trunc qaz",
"ERROR: Does not match any current feedback mode: qaz -- /set trunc qaz"),
(a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added",
"ERROR: Different selector kinds in same sections of"),
(a) -> assertCommandOutputStartsWith(a, "/set mode",
(a) -> assertCommandOutputContains(a, "/set mode",
"| /set truncation verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode -command",
"ERROR: Missing the feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt",
"ERROR: Missing the feedback mode"),
"| /set prompt"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te",
"ERROR: Expected format missing"),
"| /set prompt te "),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz",
"ERROR: Format 'xyz' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt",
"ERROR: Missing the feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te",
"ERROR: Expected format missing"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa'",
"ERROR: Expected format missing"),
"ERROR: Continuation prompt required"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal",
"| Feedback mode: normal")
);

View File

@ -106,10 +106,11 @@ public class ToolLocaleMessageTest extends ReplToolTesting {
(a) -> assertCommandOK(a, "/set feedback test", "test"),
(a) -> assertCommandFail(a, "/list zebra"),
(a) -> assertCommandFail(a, "/set editor", "/set editor"),
(a) -> assertCommandFail(a, "/set editor -rot", "/set editor -rot"),
(a) -> assertCommandFail(a, "/set snowball", "/set", "snowball"),
(a) -> assertCommandFail(a, "/set", "/set", "/help"),
(a) -> assertCommandFail(a, "/set f", "feedback"),
(a) -> assertCommandOK(a, "/set", "| /set feedback test", "verbose"),
(a) -> assertCommandFail(a, "/set f", "/set"),
(a) -> assertCommandOK(a, "/set fe", "| /set feedback test"),
(a) -> assertCommandFail(a, "/classpath", "/classpath"),
(a) -> assertCommandFail(a, "/help rabbits", "rabbits"),
(a) -> assertCommandFail(a, "/drop"),
@ -164,27 +165,20 @@ public class ToolLocaleMessageTest extends ReplToolTesting {
(a) -> assertCommandOK(a, "/set format te errorpre 'ERROR: '"),
(a) -> assertCommandOK(a, "/set feedback te"),
(a) -> assertCommandFail(a, "/set "),
(a) -> assertCommandFail(a, "/set xyz", "xyz"),
(a) -> assertCommandFail(a, "/set f", "/set", "f"),
(a) -> assertCommandFail(a, "/set feedback"),
(a) -> assertCommandFail(a, "/set feedback xyz"),
(a) -> assertCommandFail(a, "/set format"),
(a) -> assertCommandFail(a, "/set format xyz"),
(a) -> assertCommandFail(a, "/set format t"),
(a) -> assertCommandFail(a, "/set format te"),
(a) -> assertCommandFail(a, "/set format te fld"),
(a) -> assertCommandFail(a, "/set format te fld aaa", "aaa"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' frog"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import-frog"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import-import"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import,added"),
(a) -> assertCommandFail(a, "/set mode"),
(a) -> assertCommandFail(a, "/set mode x xyz"),
(a) -> assertCommandFail(a, "/set mode x -quiet y"),
(a) -> assertCommandFail(a, "/set mode tee -command foo", "foo"),
(a) -> assertCommandFail(a, "/set prompt"),
(a) -> assertCommandFail(a, "/set prompt te"),
(a) -> assertCommandFail(a, "/set prompt te aaa xyz", "aaa"),
(a) -> assertCommandFail(a, "/set prompt te 'aaa' xyz", "xyz"),
(a) -> assertCommandFail(a, "/set prompt te aaa"),

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8157200
* @bug 8157200 8163840
* @summary Tests of what information is retained across jshell tool runs
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolRetainTest ReplToolTesting
@ -41,10 +41,12 @@ public class ToolRetainTest extends ReplToolTesting {
(a) -> assertCommand(a, "/set feedback trm", ""),
(a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""),
(a) -> assertCommand(a, "int x = 45", "x:45"),
(a) -> assertCommand(a, "/retain mode trm", ""),
(a) -> assertCommand(a, "/set mode -retain trm", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommandOutputContains(a, "/set mode trm",
"/set format trm display \"{name}:{value}\""),
(a) -> assertCommand(a, "/set feedback trm", ""),
(a) -> assertCommand(a, "int x = 45", "x:45")
);
@ -53,21 +55,25 @@ public class ToolRetainTest extends ReplToolTesting {
public void testRetain2Mode() {
test(
(a) -> assertCommand(a, "/set mode trm1 -quiet", "| Created new feedback mode: trm1"),
(a) -> assertCommand(a, "/retain mode trm1", ""),
(a) -> assertCommand(a, "/retain feedback trm1", ""),
(a) -> assertCommand(a, "/set mode -retain trm1", ""),
(a) -> assertCommand(a, "/set feedback -retain trm1", ""),
(a) -> assertCommand(a, "/set format trm1 display '{name}:{value}'", ""),
(a) -> assertCommand(a, "int x = 66", "x:66"),
(a) -> assertCommand(a, "/retain mode trm1", ""),
(a) -> assertCommand(a, "/set mode -retain trm1", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommand(a, "/set mode trm2 -quiet", ""),
(a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""),
(a) -> assertCommand(a, "int x = 45", "x:45"),
(a) -> assertCommand(a, "/retain mode trm2", ""),
(a) -> assertCommand(a, "/set mode -retain trm2", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommandOutputContains(a, "/set mode trm1",
"/set format trm1 display \"{name}:{value}\""),
(a) -> assertCommand(a, "/set format trm2 display",
"| /set format trm2 display \"{name}={value}\""),
(a) -> assertCommand(a, "int x = 99", "x:99"),
(a) -> assertCommand(a, "/set feedback trm2", ""),
(a) -> assertCommand(a, "int z = 77", "z=77")
@ -76,31 +82,48 @@ public class ToolRetainTest extends ReplToolTesting {
public void testRetainFeedback() {
test(
(a) -> assertCommand(a, "/retain feedback verbose", "| Feedback mode: verbose"),
(a) -> assertCommand(a, "/set feedback -retain verbose", "| Feedback mode: verbose"),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommandOutputStartsWith(a, "/set feedback",
"| /set feedback -retain verbose\n" +
"| \n" +
"| "),
(a) -> assertCommandOutputContains(a, "int h =8", "| created variable h : int")
);
}
public void testRetainFeedbackBlank() {
String feedbackOut =
"| /set feedback -retain verbose\n" +
"| \n" +
"| Available feedback modes:\n" +
"| concise\n" +
"| normal\n" +
"| silent\n" +
"| verbose";
test(
(a) -> assertCommand(a, "/set feedback verbose", "| Feedback mode: verbose"),
(a) -> assertCommand(a, "/retain feedback", ""),
(a) -> assertCommand(a, "/set feedback -retain", ""),
(a) -> assertCommand(a, "/set feedback", feedbackOut),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommand(a, "/set feedback", feedbackOut),
(a) -> assertCommandOutputContains(a, "int qw = 5", "| created variable qw : int")
);
}
public void testRetainEditor() {
test(
(a) -> assertCommand(a, "/retain editor nonexistent", "| Editor set to: nonexistent"),
(a) -> assertCommand(a, "/set editor -retain nonexistent",
"| Editor set to: nonexistent\n" +
"| Editor setting retained: nonexistent"),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommand(a, "/set editor", "| /set editor -retain nonexistent"),
(a) -> assertCommandOutputContains(a, "int h =8", ""),
(a) -> assertCommandOutputContains(a, "/edit h", "Edit Error:")
);
@ -109,7 +132,7 @@ public class ToolRetainTest extends ReplToolTesting {
public void testRetainEditorBlank() {
test(
(a) -> assertCommand(a, "/set editor nonexistent", "| Editor set to: nonexistent"),
(a) -> assertCommand(a, "/retain editor", ""),
(a) -> assertCommand(a, "/set editor -retain", "| Editor setting retained: nonexistent"),
(a) -> assertCommand(a, "/exit", "")
);
test(
@ -120,22 +143,25 @@ public class ToolRetainTest extends ReplToolTesting {
public void testRetainModeNeg() {
test(
(a) -> assertCommandOutputStartsWith(a, "/retain mode verbose",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain verbose",
"| Not valid with a predefined mode"),
(a) -> assertCommandOutputStartsWith(a, "/retain mode ????",
(a) -> assertCommandOutputStartsWith(a, "/set mode -retain ????",
"| Expected a feedback mode name: ????")
);
}
public void testRetainFeedbackNeg() {
test(
(a) -> assertCommandOutputStartsWith(a, "/retain feedback babble1",
(a) -> assertCommandOutputStartsWith(a, "/set feedback -retain babble1",
"| Does not match any current feedback mode"),
(a) -> assertCommand(a, "/set mode trfn",
(a) -> assertCommandOutputStartsWith(a, "/set mode trfn",
"| To create a new mode either the -command or the -quiet option must be used -- \n" +
"| Does not match any current feedback mode: trfn -- /set mode trfn"),
(a) -> assertCommand(a, "/set mode trfn -command",
"| Created new feedback mode: trfn"),
(a) -> assertCommandOutputContains(a, "/retain feedback trfn",
(a) -> assertCommandOutputContains(a, "/set feedback -retain trfn",
"is predefined or has been retained"),
(a) -> assertCommandOutputStartsWith(a, "/retain feedback !!!!",
(a) -> assertCommandOutputStartsWith(a, "/set feedback -retain !!!!",
"| Expected a feedback mode name: !!!!")
);
}

View File

@ -193,8 +193,8 @@ public class ToolSimpleTest extends ReplToolTesting {
"| '/save' requires a filename argument."),
(a) -> assertCommand(a, "/open",
"| '/open' requires a filename argument."),
(a) -> assertCommand(a, "/set start",
"| Specify either one option or a startup file name -- /set start")
(a) -> assertCommandOutputStartsWith(a, "/drop",
"| In the /drop argument, please specify an import, variable, method, or class to drop.")
);
}

View File

@ -23,12 +23,15 @@
/*
* @test
* @bug 8131023
* @bug 8131023 8167461
* @summary Verify that the user's code can read System.in
* @build KullaTesting TestingInputStream
* @run testng UserInputTest
*/
import java.io.IOException;
import java.io.InputStream;
import org.testng.annotations.Test;
@Test
@ -37,8 +40,61 @@ public class UserInputTest extends KullaTesting {
public void testReadInput() {
setInput("AB\n");
assertEval("System.in.read()", "65");
setInput("BC\n");
assertEval("System.in.read()", "66");
setInput("CD\n");
assertEval("System.in.read()", "67");
}
public void testScanner() {
assertEval("import java.util.Scanner;");
assertEval("Scanner s = new Scanner(System.in);");
setInput("12\n");
assertEval("s.nextInt();", "12");
}
public void testClose() {
setInput(new InputStream() {
private final byte[] data = new byte[] {0, 1, 2};
private int cursor;
@Override public int read() throws IOException {
if (cursor < data.length) {
return data[cursor++];
} else {
return -1;
}
}
});
assertEval("int read;", "0");
assertEval("System.in.read();", "0");
assertEval("System.in.read();", "1");
assertEval("System.in.read();", "2");
assertEval("System.in.read();", "-1");
assertEval("System.in.read();", "-1");
assertEval("System.in.read();", "-1");
}
public void testException() {
setInput(new InputStream() {
private final int[] data = new int[] {0, 1, -2, 2};
private int cursor;
@Override public int read() throws IOException {
if (cursor < data.length) {
int d = data[cursor++];
if (d == (-2)) {
throw new IOException("Crashed");
}
return d;
} else {
return -1;
}
}
});
assertEval("int read;", "0");
assertEval("System.in.read();", "0");
assertEval("System.in.read();", "1");
assertEval("java.io.IOException e;");
assertEval("try { System.in.read(); } catch (java.io.IOException exc) { e = exc; }");
assertEval("e", "java.io.IOException: Crashed");
assertEval("System.in.read();", "2");
assertEval("System.in.read();", "-1");
}
}

View File

@ -4,36 +4,36 @@
* @summary Enhance compiler warnings for Lambda
* Checks that the warning for accessing non public members of a class is
* fired correctly.
* @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java
* @compile/fail/ref=WarnSerializableElementTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableElementTest.java
*/
import java.io.Serializable;
public class WarnSerializableLambdaTest {
public class WarnSerializableElementTest {
void warnLambda() throws Exception {
SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod;
SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod;
SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod;
SAM t3 = (SAM & Serializable)WarnSerializableElementTest::packageClassMethod;
SAM t4 = (SAM & Serializable)WarnSerializableElementTest::protectedClassMethod;
SAM t5 = (SAM & Serializable)WarnSerializableElementTest::privateClassMethod;
WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
WarnSerializableElementTest test = new WarnSerializableElementTest();
SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
SAM t9 = (SAM & Serializable) c -> {
WarnSerializableLambdaTest.staticPackageField = "";
WarnSerializableLambdaTest.staticProtectedField = "";
WarnSerializableLambdaTest.staticPrivateField = "";
WarnSerializableElementTest.staticPackageField = "";
WarnSerializableElementTest.staticProtectedField = "";
WarnSerializableElementTest.staticPrivateField = "";
packageField = "";
protectedField = "";
privateField = "";
WarnSerializableLambdaTest.packageClassMethod(null);
WarnSerializableLambdaTest.protectedClassMethod(null);
WarnSerializableLambdaTest.privateClassMethod(null);
WarnSerializableElementTest.packageClassMethod(null);
WarnSerializableElementTest.protectedClassMethod(null);
WarnSerializableElementTest.privateClassMethod(null);
packageInstanceMethod(null);
protectedInstanceMethod(null);
@ -53,17 +53,17 @@ public class WarnSerializableLambdaTest {
private void warnAnoInnerClass() throws Exception {
new SerializableDesc() {
public void m(Object param) throws Exception {
WarnSerializableLambdaTest.staticPackageField = "";
WarnSerializableLambdaTest.staticProtectedField = "";
WarnSerializableLambdaTest.staticPrivateField = "";
WarnSerializableElementTest.staticPackageField = "";
WarnSerializableElementTest.staticProtectedField = "";
WarnSerializableElementTest.staticPrivateField = "";
packageField = "";
protectedField = "";
privateField = "";
WarnSerializableLambdaTest.packageClassMethod(null);
WarnSerializableLambdaTest.protectedClassMethod(null);
WarnSerializableLambdaTest.privateClassMethod(null);
WarnSerializableElementTest.packageClassMethod(null);
WarnSerializableElementTest.protectedClassMethod(null);
WarnSerializableElementTest.privateClassMethod(null);
packageInstanceMethod(null);
protectedInstanceMethod(null);
@ -80,9 +80,9 @@ public class WarnSerializableLambdaTest {
}
void dontWarnLambda() throws Exception {
SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod;
SAM t1 = (SAM & Serializable)WarnSerializableElementTest::publicClassMethod;
WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
WarnSerializableElementTest test = new WarnSerializableElementTest();
SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
int[] buffer = {0};
@ -92,9 +92,9 @@ public class WarnSerializableLambdaTest {
localVar = null;
param = null;
WarnSerializableLambdaTest.staticPublicField = "";
WarnSerializableElementTest.staticPublicField = "";
publicField = "";
WarnSerializableLambdaTest.publicClassMethod(null);
WarnSerializableElementTest.publicClassMethod(null);
publicInstanceMethod(null);
PublicClass.effectivelyPublicStaticField = "";
@ -118,9 +118,9 @@ public class WarnSerializableLambdaTest {
localVar = null;
param = null;
WarnSerializableLambdaTest.staticPublicField = "";
WarnSerializableElementTest.staticPublicField = "";
publicField = "";
WarnSerializableLambdaTest.publicClassMethod(null);
WarnSerializableElementTest.publicClassMethod(null);
publicInstanceMethod(null);
PublicClass.effectivelyPublicStaticField = "";
@ -138,20 +138,20 @@ public class WarnSerializableLambdaTest {
enum WarnEnum {
A {
public void m() throws Exception {
WarnSerializableLambdaTest.staticPackageField = "";
WarnSerializableLambdaTest.staticProtectedField = "";
WarnSerializableLambdaTest.staticPrivateField = "";
WarnSerializableElementTest.staticPackageField = "";
WarnSerializableElementTest.staticProtectedField = "";
WarnSerializableElementTest.staticPrivateField = "";
WarnSerializableLambdaTest test =
new WarnSerializableLambdaTest();
WarnSerializableElementTest test =
new WarnSerializableElementTest();
test.packageField = "";
test.protectedField = "";
test.privateField = "";
WarnSerializableLambdaTest.packageClassMethod(null);
WarnSerializableLambdaTest.protectedClassMethod(null);
WarnSerializableLambdaTest.privateClassMethod(null);
WarnSerializableElementTest.packageClassMethod(null);
WarnSerializableElementTest.protectedClassMethod(null);
WarnSerializableElementTest.privateClassMethod(null);
test.packageInstanceMethod(null);
test.protectedInstanceMethod(null);

View File

@ -0,0 +1,35 @@
WarnSerializableElementTest.java:56:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
WarnSerializableElementTest.java:57:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
WarnSerializableElementTest.java:58:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
WarnSerializableElementTest.java:60:17: compiler.warn.access.to.member.from.serializable.element: packageField
WarnSerializableElementTest.java:61:17: compiler.warn.access.to.member.from.serializable.element: protectedField
WarnSerializableElementTest.java:62:17: compiler.warn.access.to.member.from.serializable.element: privateField
WarnSerializableElementTest.java:64:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableElementTest.java:65:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableElementTest.java:66:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableElementTest.java:68:17: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableElementTest.java:69:17: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableElementTest.java:70:17: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableElementTest.java:72:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableElementTest.java:73:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableElementTest.java:76:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableElementTest.java:77:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
WarnSerializableElementTest.java:141:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
WarnSerializableElementTest.java:142:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
WarnSerializableElementTest.java:143:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
WarnSerializableElementTest.java:148:21: compiler.warn.access.to.member.from.serializable.element: packageField
WarnSerializableElementTest.java:149:21: compiler.warn.access.to.member.from.serializable.element: protectedField
WarnSerializableElementTest.java:150:21: compiler.warn.access.to.member.from.serializable.element: privateField
WarnSerializableElementTest.java:152:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableElementTest.java:153:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableElementTest.java:154:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableElementTest.java:156:21: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableElementTest.java:157:21: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableElementTest.java:158:21: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableElementTest.java:160:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableElementTest.java:161:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableElementTest.java:164:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableElementTest.java:165:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
- compiler.err.warnings.and.werror
1 error
32 warnings

View File

@ -1,57 +0,0 @@
WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
- compiler.err.warnings.and.werror
1 error
54 warnings

View File

@ -4,7 +4,7 @@
* @summary Enhance compiler warnings for Lambda
* Checks that the warning for accessing non public members of a class is
* fired correctly.
* @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java
* @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableLambdaTestb.java
*/
import java.io.Serializable;

View File

@ -1,7 +1,5 @@
WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j
WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r
WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.member.from.serializable.element: j
WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.member.from.serializable.element: r
- compiler.err.warnings.and.werror
1 error
4 warnings
2 warnings

View File

@ -0,0 +1,20 @@
/*
* @test /nodynamiccopyright/
* @bug 8026721
* @summary Enhance Lambda serialization
* Checks that the warning for accessing non public members of a class is fired correctly.
* @compile -Xlint:serial -Werror WarnSerializableLambdaTestc.java
*/
import javax.tools.SimpleJavaFileObject;
import java.io.Serializable;
public class WarnSerializableLambdaTestc {
public interface SerializableIntf<T> extends Serializable {
String get(T o);
}
private void dontWarn() {
SerializableIntf<SimpleJavaFileObject> s = SimpleJavaFileObject::getName;
}
}

View File

@ -0,0 +1,4 @@
WarnSerializableLambdaTestc.java:18:52: compiler.warn.access.to.member.from.serializable.lambda
- compiler.err.warnings.and.werror
1 error
1 warning

View File

@ -257,6 +257,8 @@ public class CheckResourceKeys {
// ignore package and class names
if (cs.matches("(com|java|javax|jdk|sun)\\.[A-Za-z.]+"))
continue;
if (cs.matches("(java|javax|sun)\\."))
continue;
// ignore debug flag names
if (cs.startsWith("debug."))
continue;

View File

@ -111,6 +111,7 @@ compiler.warn.file.from.future # warning for future mod
compiler.err.cant.inherit.from.anon # error for subclass of anonymous class
compiler.misc.bad.class.file # class file is malformed
compiler.misc.bad.const.pool.entry # constant pool entry has wrong type
compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package
# The following module-related messages will have to stay on the not-yet list for various reasons:
compiler.warn.locn.unknown.file.on.module.path # Never issued ATM (short circuited with an if (false))

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,21 +21,24 @@
* questions.
*/
// key: compiler.warn.access.to.sensitive.member.from.serializable.element
// options: -XDwarnOnAccessToSensitiveMembers
// key: compiler.warn.access.to.member.from.serializable.element
// options: -XDwarnOnAccessToMembers
import java.io.Serializable;
public class WarnSerializableLambda {
interface SAM {
void apply(String s);
}
private void m1() {
SAM s = (SAM & Serializable) c -> {
packageField = "";
new SerializableClass() {
@Override
public void m() {
packageField = "";
}
};
}
String packageField;
class SerializableClass implements Serializable {
public void m() {}
}
}

View File

@ -38,7 +38,9 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.tools.DocumentationTool.DocumentationTask;
import javax.tools.DocumentationTool;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
@ -303,7 +305,8 @@ public class JavadocTask extends AbstractTask<JavadocTask> {
if (fileManager == null)
fileManager = internalFileManager = jdtool.getStandardFileManager(null, null, null);
if (outdir != null)
setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singletonList(outdir));
setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT,
Collections.singletonList(outdir));
if (classpath != null)
setLocationFromPaths(StandardLocation.CLASS_PATH, classpath);
if (sourcepath != null)
@ -326,7 +329,7 @@ public class JavadocTask extends AbstractTask<JavadocTask> {
}
}
private void setLocationFromPaths(StandardLocation location, List<Path> files) throws IOException {
private void setLocationFromPaths(Location location, List<Path> files) throws IOException {
if (!(fileManager instanceof StandardJavaFileManager))
throw new IllegalStateException("not a StandardJavaFileManager");
((StandardJavaFileManager) fileManager).setLocationFromPaths(location, files);