8169561: jshell tool: double shift-tab on variable crashes tool
Summary: Avoid crashe for unknown HTML tags; avoid crash for non-existing documentation; fix signature for JShell variables
Reviewed-by: rfield
--- a/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java Wed Jul 05 22:27:20 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java Wed Nov 16 17:48:43 2016 +0100
@@ -246,7 +246,7 @@
@Override @DefinedBy(Api.COMPILER_TREE)
public Object visitStartElement(StartElementTree node, Object p) {
- switch (HtmlTag.get(node.getName())) {
+ switch (getHtmlTag(node.getName())) {
case P:
if (lastNode!= null && lastNode.getKind() == DocTree.Kind.START_ELEMENT &&
HtmlTag.get(((StartElementTree) lastNode).getName()) == HtmlTag.LI) {
@@ -397,7 +397,7 @@
}
private void handleEndElement(Name name) {
- switch (HtmlTag.get(name)) {
+ switch (getHtmlTag(name)) {
case BLOCKQUOTE:
indent -= INDENT;
break;
@@ -629,6 +629,12 @@
}
}
+ private static HtmlTag getHtmlTag(Name name) {
+ HtmlTag tag = HtmlTag.get(name);
+
+ return tag != null ? tag : HtmlTag.HTML; //using HtmlTag.HTML as default no-op value
+ }
+
private static Map<StartElementTree, Integer> countTableColumns(DocCommentTree dct) {
Map<StartElementTree, Integer> result = new IdentityHashMap<>();
@@ -639,7 +645,7 @@
@Override @DefinedBy(Api.COMPILER_TREE)
public Void visitStartElement(StartElementTree node, Void p) {
- switch (HtmlTag.get(node.getName())) {
+ switch (getHtmlTag(node.getName())) {
case TABLE: currentTable = node; break;
case TR:
currentMaxColumns = Math.max(currentMaxColumns, currentRowColumns);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Jul 05 22:27:20 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Nov 16 17:48:43 2016 +0100
@@ -283,9 +283,9 @@
if (firstInvocation) {
convertor = d -> d.signature();
} else {
- convertor = d -> formatter.formatJavadoc(d.signature(),
- d.javadoc() != null ? d.javadoc()
- : repl.messageFormat("jshell.console.no.javadoc"));
+ convertor = d -> formatter.formatJavadoc(d.signature(), d.javadoc()) +
+ (d.javadoc() == null ? repl.messageFormat("jshell.console.no.javadoc")
+ : "");
}
doc = repl.analysis.documentation(prefix + buffer, cursor + prefix.length(), !firstInvocation)
.stream()
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Jul 05 22:27:20 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Nov 16 17:48:43 2016 +0100
@@ -1341,9 +1341,9 @@
.collect(joining(" & "));
}
case FIELD:
- return elementHeader(at, el.getEnclosingElement(), includeParameterNames, false) + "." + el.getSimpleName() + ":" + el.asType();
+ return appendDot(elementHeader(at, el.getEnclosingElement(), includeParameterNames, false)) + el.getSimpleName() + ":" + el.asType();
case ENUM_CONSTANT:
- return elementHeader(at, el.getEnclosingElement(), includeParameterNames, false) + "." + el.getSimpleName();
+ return appendDot(elementHeader(at, el.getEnclosingElement(), includeParameterNames, false)) + el.getSimpleName();
case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE:
return el.getSimpleName() + ":" + el.asType();
case CONSTRUCTOR: case METHOD: {
@@ -1407,6 +1407,9 @@
return el.toString();
}
}
+ private String appendDot(String fqn) {
+ return fqn.isEmpty() ? fqn : fqn + ".";
+ }
private TypeMirror unwrapArrayType(TypeMirror arrayType) {
if (arrayType.getKind() == TypeKind.ARRAY) {
return ((ArrayType)arrayType).getComponentType();
--- a/langtools/test/jdk/internal/shellsupport/doc/JavadocFormatterTest.java Wed Jul 05 22:27:20 2017 +0200
+++ b/langtools/test/jdk/internal/shellsupport/doc/JavadocFormatterTest.java Wed Nov 16 17:48:43 2016 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8131019
+ * @bug 8131019 8169561
* @summary Test JavadocFormatter
* @library /tools/lib
* @modules jdk.compiler/jdk.internal.shellsupport.doc
@@ -388,6 +388,17 @@
if (!Objects.equals(actual, expected)) {
throw new AssertionError("Incorrect output: " + actual);
}
+
+ //unknown HTML tag:
+ actual = new JavadocFormatter(66, false).formatJavadoc("test",
+ "1234 <unknown any any>1234</unknown> 1234");
+
+ expected = "test\n" +
+ "1234 1234 1234\n";
+
+ if (!Objects.equals(actual, expected)) {
+ throw new AssertionError("Incorrect output: " + actual);
+ }
}
}
--- a/langtools/test/jdk/jshell/JavadocTest.java Wed Jul 05 22:27:20 2017 +0200
+++ b/langtools/test/jdk/jshell/JavadocTest.java Wed Nov 16 17:48:43 2016 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8131019
+ * @bug 8131019 8169561
* @summary Test Javadoc
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -65,6 +65,11 @@
assertJavadoc("clz.undef|");
}
+ public void testVariableInRepl() {
+ assertEval("Object o;");
+ assertSignature("o|", "o:java.lang.Object");
+ }
+
private void prepareZip() {
String clazz =
"package test;\n" +