Skip to content

Commit 53a0ace

Browse files
8286101: Support formatting in @value tag
Reviewed-by: prappo
1 parent 8f400b9 commit 53a0ace

File tree

18 files changed

+334
-12
lines changed

18 files changed

+334
-12
lines changed

src/jdk.compiler/share/classes/com/sun/source/doctree/ValueTree.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
3030
*
3131
* <pre>
3232
* {&#064;value reference}
33+
* {&#064;value format reference}
3334
* </pre>
3435
*
3536
* @since 1.8
@@ -40,4 +41,16 @@ public interface ValueTree extends InlineTagTree {
4041
* @return the reference
4142
*/
4243
ReferenceTree getReference();
44+
45+
/**
46+
* Returns the format string, or {@code null} if none was provided.
47+
*
48+
* @return the format string
49+
*
50+
* @implSpec This implementation returns {@code null}.
51+
* @since 19
52+
*/
53+
default TextTree getFormat() {
54+
return null;
55+
}
4356
}

src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -413,6 +413,19 @@ default SummaryTree newSummaryTree(List<? extends DocTree> summary) {
413413
*/
414414
ValueTree newValueTree(ReferenceTree ref);
415415

416+
/**
417+
* Creates a new {@code ValueTree} object, to represent a {@code {@value }} tag.
418+
* @param format a format string for the value
419+
* @param ref a reference to the value
420+
* @return a {@code ValueTree} object
421+
*
422+
* @implSpec This implementation calls {@link #newValueTree(ReferenceTree) newValueTree(ref)}.
423+
* @since 19
424+
*/
425+
default ValueTree newValueTree(TextTree format, ReferenceTree ref) {
426+
return newValueTree(ref);
427+
}
428+
416429
/**
417430
* Creates a new {@code VersionTree} object, to represent a {@code {@version }} tag.
418431
* @param text the content of the tag

src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -638,7 +638,9 @@ public R visitUses(UsesTree node, P p) {
638638
*/
639639
@Override
640640
public R visitValue(ValueTree node, P p) {
641-
return scan(node.getReference(), p);
641+
R r = scan(node.getFormat(), p);
642+
r = scanAndReduce(node.getReference(), p, r);
643+
return r;
642644
}
643645

644646
/**

src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,15 +1579,32 @@ public DCTree parse(int pos) throws ParseException {
15791579
}
15801580
},
15811581

1582-
// {@value package.class#field}
1582+
// {@value [format-string] package.class#field}
15831583
new TagParser(TagParser.Kind.INLINE, DCTree.Kind.VALUE) {
15841584
@Override
15851585
public DCTree parse(int pos) throws ParseException {
1586+
skipWhitespace();
1587+
DCText format;
1588+
switch (ch) {
1589+
case '%' -> {
1590+
format = inlineWord();
1591+
skipWhitespace();
1592+
}
1593+
case '"' -> {
1594+
format = quotedString();
1595+
skipWhitespace();
1596+
}
1597+
default -> {
1598+
format = null;
1599+
}
1600+
}
15861601
DCReference ref = reference(true);
15871602
skipWhitespace();
15881603
if (ch == '}') {
15891604
nextChar();
1590-
return m.at(pos).newValueTree(ref);
1605+
return format == null
1606+
? m.at(pos).newValueTree(ref)
1607+
: m.at(pos).newValueTree(format, ref);
15911608
}
15921609
nextChar();
15931610
throw new ParseException("dc.unexpected.content");

src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1310,9 +1310,11 @@ public List<? extends DocTree> getDescription() {
13101310
}
13111311

13121312
public static class DCValue extends DCInlineTag implements ValueTree {
1313+
public final DCText format;
13131314
public final DCReference ref;
13141315

1315-
DCValue(DCReference ref) {
1316+
DCValue(DCText format, DCReference ref) {
1317+
this.format = format;
13161318
this.ref = ref;
13171319
}
13181320

@@ -1326,6 +1328,11 @@ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
13261328
return v.visitValue(this, d);
13271329
}
13281330

1331+
@Override @DefinedBy(Api.COMPILER_TREE)
1332+
public TextTree getFormat() {
1333+
return format;
1334+
}
1335+
13291336
@Override @DefinedBy(Api.COMPILER_TREE)
13301337
public ReferenceTree getReference() {
13311338
return ref;

src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,10 @@ public Void visitValue(ValueTree node, Void p) {
632632
try {
633633
print("{");
634634
printTagName(node);
635+
if (node.getFormat() != null) {
636+
print(" ");
637+
print(node.getFormat());
638+
}
635639
if (node.getReference() != null) {
636640
print(" ");
637641
print(node.getReference());

src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,13 @@ public DCUses newUsesTree(ReferenceTree name, List<? extends DocTree> descriptio
480480

481481
@Override @DefinedBy(Api.COMPILER_TREE)
482482
public DCValue newValueTree(ReferenceTree ref) {
483+
return newValueTree(null, ref);
484+
}
485+
486+
@Override @DefinedBy(Api.COMPILER_TREE)
487+
public DCValue newValueTree(TextTree format, ReferenceTree ref) {
483488
// TODO: verify the reference is to a constant value
484-
DCValue tree = new DCValue((DCReference) ref);
489+
DCValue tree = new DCValue((DCText) format, (DCReference) ref);
485490
tree.pos = pos;
486491
return tree;
487492
}

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Messages.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ public void error(FileObject fo, int start, int pos, int end, String key, Object
123123
report(ERROR, fo, start, pos, end, resources.getText(key, args));
124124
}
125125

126+
/**
127+
* Reports an error message to the doclet's reporter.
128+
*
129+
* @param e an element identifying the position to be included with the message
130+
* @param key the name of a resource containing the message to be printed
131+
* @param args optional arguments to be replaced in the message
132+
*/
133+
public void error(Element e, String key, Object... args) {
134+
report(ERROR, e, resources.getText(key, args));
135+
}
136+
126137
// ***** Warnings *****
127138

128139
/**

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ doclet.Groupname_already_used=In -group option, groupname already used: {0}
203203
doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference.
204204
doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants.
205205
doclet.value_tag_invalid_use=@value tag cannot be used here.
206+
doclet.value_tag_invalid_format=invalid format: {0}
206207
doclet.dest_dir_create=Creating destination directory: "{0}"
207208
doclet.in={0} in {1}
208209
doclet.Fields=Fields

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ValueTaglet.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@
2626
package jdk.javadoc.internal.doclets.toolkit.taglets;
2727

2828
import java.util.EnumSet;
29+
import java.util.IllegalFormatException;
30+
import java.util.Optional;
2931
import javax.lang.model.element.Element;
3032
import javax.lang.model.element.VariableElement;
3133

3234
import com.sun.source.doctree.DocTree;
35+
import com.sun.source.doctree.TextTree;
36+
import com.sun.source.doctree.ValueTree;
3337
import jdk.javadoc.doclet.Taglet.Location;
3438
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
3539
import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -95,8 +99,27 @@ public Content getInlineTagOutput(Element holder, DocTree tag, TagletWriter writ
9599
"doclet.value_tag_invalid_reference", tag.toString());
96100
}
97101
} else if (field.getConstantValue() != null) {
102+
TextTree format = ((ValueTree) tag).getFormat();
103+
String text;
104+
if (format != null) {
105+
String f = format.getBody();
106+
if (f.startsWith("\"")) {
107+
f = f.substring(1, f.length() - 1);
108+
}
109+
try {
110+
text = String.format(configuration.getLocale(), f, field.getConstantValue());
111+
} catch (IllegalFormatException e) {
112+
messages.error(holder,
113+
"doclet.value_tag_invalid_format", format);
114+
return writer.invalidTagOutput(
115+
messages.getResources().getText("doclet.value_tag_invalid_format", format),
116+
Optional.empty());
117+
}
118+
} else {
119+
text = utils.constantValueExpression(field);
120+
}
98121
return writer.valueTagOutput(field,
99-
utils.constantValueExpression(field),
122+
text,
100123
// TODO: investigate and cleanup
101124
// in the j.l.m world, equals will not be accurate
102125
// !field.equals(tag.holder())

0 commit comments

Comments
 (0)