8271258: @param with non-ascii variable names produces incorrect results

Reviewed-by: hannesw
This commit is contained in:
Jonathan Gibbons 2021-08-24 14:41:24 +00:00
parent 7454306920
commit 94f5e441f6
3 changed files with 86 additions and 30 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@ -67,10 +67,9 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
}
/**
* Given an array of <code>Parameter</code>s, return
* a name/rank number map. If the array is null, then
* null is returned.
* @param params The array of parameters (from type or executable member) to
* Given a list of parameters, return a name/rank number map.
* If the list is null, then null is returned.
* @param params The list of parameters (from type or executable member) to
* check.
* @return a name-rank number map.
*/
@ -245,28 +244,24 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
CommentHelper ch = writer.configuration().utils.getCommentHelper(e);
for (ParamTree dt : paramTags) {
String name = ch.getParameterName(dt);
String paramName = kind != ParamKind.TYPE_PARAMETER
? name.toString()
: "<" + name + ">";
String paramName = kind == ParamKind.TYPE_PARAMETER ? "<" + name + ">" : name;
if (!rankMap.containsKey(name)) {
String key;
switch (kind) {
case PARAMETER: key = "doclet.Parameters_warn" ; break;
case TYPE_PARAMETER: key = "doclet.TypeParameters_warn" ; break;
case RECORD_COMPONENT: key = "doclet.RecordComponents_warn" ; break;
default: throw new IllegalArgumentException(kind.toString());
}
String key = switch (kind) {
case PARAMETER -> "doclet.Parameters_warn";
case TYPE_PARAMETER -> "doclet.TypeParameters_warn";
case RECORD_COMPONENT -> "doclet.RecordComponents_warn";
default -> throw new IllegalArgumentException(kind.toString());
};
messages.warning(ch.getDocTreePath(dt), key, paramName);
}
String rank = rankMap.get(name);
if (rank != null && alreadyDocumented.contains(rank)) {
String key;
switch (kind) {
case PARAMETER: key = "doclet.Parameters_dup_warn" ; break;
case TYPE_PARAMETER: key = "doclet.TypeParameters_dup_warn" ; break;
case RECORD_COMPONENT: key = "doclet.RecordComponents_dup_warn" ; break;
default: throw new IllegalArgumentException(kind.toString());
}
String key = switch (kind) {
case PARAMETER -> "doclet.Parameters_dup_warn";
case TYPE_PARAMETER -> "doclet.TypeParameters_dup_warn";
case RECORD_COMPONENT -> "doclet.RecordComponents_dup_warn";
default -> throw new IllegalArgumentException(kind.toString());
};
messages.warning(ch.getDocTreePath(dt), key, paramName);
}
result.add(processParamTag(e, kind, writer, dt,

View File

@ -139,7 +139,7 @@ public class CommentHelper {
public String getParameterName(DocTree dtree) {
if (dtree.getKind() == PARAM) {
return ((ParamTree) dtree).getName().toString();
return ((ParamTree) dtree).getName().getName().toString();
} else {
return null;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -23,7 +23,7 @@
/*
* @test
* @bug 8203176
* @bug 8203176 8271258
* @summary javadoc handles non-ASCII characters incorrectly
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@ -33,7 +33,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javadoc.tester.JavadocTester;
import toolbox.ToolBox;
@ -42,20 +41,20 @@ public class TestUnicode extends JavadocTester {
public static void main(String... args) throws Exception {
TestUnicode tester = new TestUnicode();
tester.runTests();
tester.runTests(m -> new Object[] { Path.of(m.getName())});
}
ToolBox tb = new ToolBox();
@Test
public void test() throws Exception {
public void testUnicode(Path base) throws Exception {
char ellipsis = '\u2026';
Path src = Files.createDirectories(Paths.get("src"));
Path src = Files.createDirectories(base.resolve("src"));
tb.writeJavaFiles(src,
"/** Hel" + ellipsis + "lo {@code World(" + ellipsis + ")}. */\n"
+ "public class Code { }\n");
javadoc("-d", "out",
javadoc("-d", base.resolve("out").toString(),
"-encoding", "utf-8",
src.resolve("Code.java").toString());
checkExit(Exit.OK);
@ -65,4 +64,66 @@ public class TestUnicode extends JavadocTester {
checkOutput("Code.html", false,
"\\u");
}
@Test
public void testParam(Path base) throws Exception {
String chineseElephant = "\u5927\u8c61"; // taken from JDK-8271258
Path src = Files.createDirectories(base.resolve("src"));
tb.writeJavaFiles(src,
"""
/**
* Comment. ##.
* @param <##> the ##
*/
public class Code<##> {
/**
* Comment. ##.
* @param ## the ##
*/
public void set##(int ##) { }
}""".replaceAll("##", chineseElephant));
javadoc("-d", base.resolve("out").toString(),
"-encoding", "utf-8",
"--no-platform-links",
src.resolve("Code.java").toString());
checkExit(Exit.OK);
checkOutput("Code.html", true,
"""
<h1 title="Class Code" class="title">Class Code&lt;##&gt;</h1>
""".replaceAll("##", chineseElephant),
"""
<div class="inheritance" title="Inheritance Tree">java.lang.Object
<div class="inheritance">Code&lt;##&gt;</div>
</div>
""".replaceAll("##", chineseElephant),
"""
<dl class="notes">
<dt>Type Parameters:</dt>
<dd><code>##</code> - the ##</dd>
</dl>
""".replaceAll("##", chineseElephant),
"""
<section class="detail" id="set##(int)">
<h3>set##</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span c\
lass="return-type">void</span>&nbsp;<span class="element-name">set##</span><wbr>\
<span class="parameters">(int&nbsp;##)</span></div>
<div class="block">Comment. ##.</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>##</code> - the ##</dd>
</dl>
</section>
""".replaceAll("##", chineseElephant)
);
// The following checks for the numeric forms of the Unicode characters being tested:
// these numeric forms should not show up as literal character sequences.
checkOutput("Code.html", false,
Integer.toHexString(chineseElephant.charAt(0)),
Integer.toHexString(chineseElephant.charAt(1))
);
}
}