Skip to content

Commit 0fc47e9

Browse files
Pavel Rappojonathan-gibbonshns
committed
8266666: Implementation for snippets
Co-authored-by: Jonathan Gibbons <[email protected]> Co-authored-by: Hannes Wallnöfer <[email protected]> Reviewed-by: jjg
1 parent 6d91a3e commit 0fc47e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+5204
-25
lines changed

src/java.compiler/share/classes/javax/tools/DocumentationTool.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2021, 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
@@ -184,7 +184,12 @@ enum Location implements JavaFileManager.Location {
184184
/**
185185
* Location to search for taglets.
186186
*/
187-
TAGLET_PATH;
187+
TAGLET_PATH,
188+
189+
/**
190+
* Location to search for snippets.
191+
*/
192+
SNIPPET_PATH;
188193

189194
public String getName() { return name(); }
190195

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

Lines changed: 2 additions & 2 deletions
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, 2021, 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
@@ -29,7 +29,7 @@
2929
import javax.lang.model.element.Name;
3030

3131
/**
32-
* A tree node for an attribute in an HTML element.
32+
* A tree node for an attribute in an HTML element or tag.
3333
*
3434
* @since 1.8
3535
*/

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public interface DocTree {
3737
enum Kind {
3838
/**
3939
* Used for instances of {@link AttributeTree}
40-
* representing an HTML attribute.
40+
* representing an attribute in an HTML element or tag.
4141
*/
4242
ATTRIBUTE,
4343

@@ -204,6 +204,12 @@ enum Kind {
204204
*/
205205
SINCE("since"),
206206

207+
/**
208+
* Used for instances of {@link SnippetTree}
209+
* representing an {@code @snippet} tag.
210+
*/
211+
SNIPPET("snippet"),
212+
207213
/**
208214
* Used for instances of {@link EndElementTree}
209215
* representing the start of an HTML element.

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,21 @@ default R visitProvides(ProvidesTree node, P p) {
287287
*/
288288
R visitSince(SinceTree node, P p);
289289

290+
/**
291+
* Visits a {@code SnippetTree} node.
292+
*
293+
* @implSpec Visits the provided {@code SnippetTree} node
294+
* by calling {@code visitOther(node, p)}.
295+
*
296+
* @param node the node being visited
297+
* @param p a parameter value
298+
* @return a result value
299+
* @since 18
300+
*/
301+
default R visitSnippet(SnippetTree node, P p) {
302+
return visitOther(node, p);
303+
}
304+
290305
/**
291306
* Visits a {@code StartElementTree} node.
292307
* @param node the node being visited
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package com.sun.source.doctree;
27+
28+
import java.util.List;
29+
30+
/**
31+
* A tree node for an {@code @snippet} inline tag.
32+
*
33+
* <pre>
34+
* {&#064;snippet :
35+
* body
36+
* }
37+
*
38+
* {&#064;snippet attributes}
39+
*
40+
* {&#064;snippet attributes :
41+
* body
42+
* }
43+
* </pre>
44+
*
45+
* @since 18
46+
*/
47+
public interface SnippetTree extends InlineTagTree {
48+
49+
/**
50+
* Returns the list of the attributes of the {@code @snippet} tag.
51+
*
52+
* @return the list of the attributes
53+
*/
54+
List<? extends DocTree> getAttributes();
55+
56+
/**
57+
* Returns the body of the {@code @snippet} tag, or {@code null} if there is no body.
58+
*
59+
* @apiNote
60+
* An instance of {@code SnippetTree} with an empty body differs from an
61+
* instance of {@code SnippetTree} with no body.
62+
* If a tag has no body, then calling this method returns {@code null}.
63+
* If a tag has an empty body, then this method returns a {@code TextTree}
64+
* whose {@link TextTree#getBody()} returns an empty string.
65+
*
66+
* @return the body of the tag, or {@code null} if there is no body
67+
*/
68+
TextTree getBody();
69+
}

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

Lines changed: 12 additions & 2 deletions
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, 2021, 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
@@ -58,6 +58,7 @@
5858
import com.sun.source.doctree.SerialFieldTree;
5959
import com.sun.source.doctree.SerialTree;
6060
import com.sun.source.doctree.SinceTree;
61+
import com.sun.source.doctree.SnippetTree;
6162
import com.sun.source.doctree.StartElementTree;
6263
import com.sun.source.doctree.SummaryTree;
6364
import com.sun.source.doctree.SystemPropertyTree;
@@ -79,7 +80,7 @@
7980
*/
8081
public interface DocTreeFactory {
8182
/**
82-
* Creates a new {@code AttributeTree} object, to represent an HTML attribute in an HTML tag.
83+
* Creates a new {@code AttributeTree} object, to represent an attribute in an HTML element or tag.
8384
* @param name the name of the attribute
8485
* @param vkind the kind of the attribute value
8586
* @param value the value, if any, of the attribute
@@ -326,6 +327,15 @@ default ReturnTree newReturnTree(boolean isInline, List<? extends DocTree> descr
326327
*/
327328
SinceTree newSinceTree(List<? extends DocTree> text);
328329

330+
/**
331+
* Creates a new {@code SnippetTree} object, to represent a {@code {@snippet }} tag.
332+
* @param attributes the attributes of the tag
333+
* @param text the body of the tag, or {@code null} if the tag has no body (not to be confused with an empty body)
334+
* @return a {@code SnippetTree} object
335+
* @since 18
336+
*/
337+
SnippetTree newSnippetTree(List<? extends DocTree> attributes, TextTree text);
338+
329339
/**
330340
* Creates a new {@code StartElementTree} object, to represent the start of an HTML element.
331341
* @param name the name of the HTML element

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,23 @@ public R visitSince(SinceTree node, P p) {
492492
return scan(node.getBody(), p);
493493
}
494494

495+
/**
496+
* {@inheritDoc}
497+
*
498+
* @implSpec This implementation scans the children in left to right order.
499+
*
500+
* @param node {@inheritDoc}
501+
* @param p {@inheritDoc}
502+
* @return the result of scanning
503+
* @since 18
504+
*/
505+
@Override
506+
public R visitSnippet(SnippetTree node, P p) {
507+
R r = scan(node.getAttributes(), p);
508+
r = scanAndReduce(node.getBody(), p, r);
509+
return r;
510+
}
511+
495512
/**
496513
* {@inheritDoc}
497514
*

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,21 @@ public R visitSince(SinceTree node, P p) {
448448
return defaultAction(node, p);
449449
}
450450

451+
/**
452+
* {@inheritDoc}
453+
*
454+
* @implSpec This implementation calls {@code defaultAction}.
455+
*
456+
* @param node {@inheritDoc}
457+
* @param p {@inheritDoc}
458+
* @return the result of {@code defaultAction}
459+
* @since 18
460+
*/
461+
@Override
462+
public R visitSnippet(SnippetTree node, P p) {
463+
return defaultAction(node, p);
464+
}
465+
451466
/**
452467
* {@inheritDoc}
453468
*

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

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2021, 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
@@ -1062,6 +1062,13 @@ protected boolean isWhitespace(char ch) {
10621062
return Character.isWhitespace(ch);
10631063
}
10641064

1065+
protected boolean isHorizontalWhitespace(char ch) {
1066+
// This parser treats `\f` as a line break (see `nextChar`).
1067+
// To be consistent with that behaviour, this method does the same.
1068+
// (see JDK-8273809)
1069+
return ch == ' ' || ch == '\t';
1070+
}
1071+
10651072
protected void skipWhitespace() {
10661073
while (bp < buflen && isWhitespace(ch)) {
10671074
nextChar();
@@ -1397,6 +1404,93 @@ public DCTree parse(int pos) {
13971404
}
13981405
},
13991406

1407+
// {@snippet attributes :
1408+
// body}
1409+
new TagParser(TagParser.Kind.INLINE, DCTree.Kind.SNIPPET) {
1410+
@Override
1411+
DCTree parse(int pos) throws ParseException {
1412+
skipWhitespace();
1413+
List<DCTree> attributes = tagAttrs();
1414+
// expect "}" or ":"
1415+
if (ch == '}') {
1416+
nextChar();
1417+
return m.at(pos).newSnippetTree(attributes, null);
1418+
} else if (ch == ':') {
1419+
newline = false;
1420+
// consume ':'
1421+
nextChar();
1422+
// expect optional whitespace followed by mandatory newline
1423+
while (bp < buflen && isHorizontalWhitespace(ch)) {
1424+
nextChar();
1425+
}
1426+
// check that we are looking at newline
1427+
if (!newline) {
1428+
if (bp >= buf.length - 1) {
1429+
throw new ParseException("dc.no.content");
1430+
}
1431+
throw new ParseException("dc.unexpected.content");
1432+
}
1433+
// consume newline
1434+
nextChar();
1435+
DCText text = inlineText(WhitespaceRetentionPolicy.RETAIN_ALL);
1436+
nextChar();
1437+
return m.at(pos).newSnippetTree(attributes, text);
1438+
} else if (bp >= buf.length - 1) {
1439+
throw new ParseException("dc.no.content");
1440+
} else {
1441+
throw new ParseException("dc.unexpected.content");
1442+
}
1443+
}
1444+
1445+
/*
1446+
* Reads a series of inline snippet tag attributes.
1447+
*
1448+
* Attributes are terminated by the first of ":" (colon) or
1449+
* an unmatched "}" (closing curly).
1450+
*/
1451+
private List<DCTree> tagAttrs() {
1452+
ListBuffer<DCTree> attrs = new ListBuffer<>();
1453+
skipWhitespace();
1454+
while (bp < buflen && isIdentifierStart(ch)) {
1455+
int namePos = bp;
1456+
Name name = readAttributeName();
1457+
skipWhitespace();
1458+
List<DCTree> value = null;
1459+
ValueKind vkind = ValueKind.EMPTY;
1460+
if (ch == '=') {
1461+
ListBuffer<DCTree> v = new ListBuffer<>();
1462+
nextChar();
1463+
skipWhitespace();
1464+
if (ch == '\'' || ch == '"') {
1465+
newline = false;
1466+
vkind = (ch == '\'') ? ValueKind.SINGLE : ValueKind.DOUBLE;
1467+
char quote = ch;
1468+
nextChar();
1469+
textStart = bp;
1470+
while (bp < buflen && ch != quote) {
1471+
nextChar();
1472+
}
1473+
addPendingText(v, bp - 1);
1474+
nextChar();
1475+
} else {
1476+
vkind = ValueKind.UNQUOTED;
1477+
textStart = bp;
1478+
// Stop on '}' and ':' for them to be re-consumed by non-attribute parts of tag
1479+
while (bp < buflen && (ch != '}' && ch != ':' && !isUnquotedAttrValueTerminator(ch))) {
1480+
nextChar();
1481+
}
1482+
addPendingText(v, bp - 1);
1483+
}
1484+
skipWhitespace();
1485+
value = v.toList();
1486+
}
1487+
DCAttribute attr = m.at(namePos).newAttributeTree(name, vkind, value);
1488+
attrs.add(attr);
1489+
}
1490+
return attrs.toList();
1491+
}
1492+
},
1493+
14001494
// {@summary summary-text}
14011495
new TagParser(TagParser.Kind.INLINE, DCTree.Kind.SUMMARY) {
14021496
@Override

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,36 @@ public List<? extends DocTree> getBody() {
857857
}
858858
}
859859

860+
public static class DCSnippet extends DCInlineTag implements SnippetTree {
861+
public final List<? extends DocTree> attributes;
862+
public final DCText body;
863+
864+
public DCSnippet(List<DCTree> attributes, DCText body) {
865+
this.body = body;
866+
this.attributes = attributes;
867+
}
868+
869+
@Override @DefinedBy(Api.COMPILER_TREE)
870+
public Kind getKind() {
871+
return Kind.SNIPPET;
872+
}
873+
874+
@Override @DefinedBy(Api.COMPILER_TREE)
875+
public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
876+
return v.visitSnippet(this, d);
877+
}
878+
879+
@Override @DefinedBy(Api.COMPILER_TREE)
880+
public List<? extends DocTree> getAttributes() {
881+
return attributes;
882+
}
883+
884+
@Override @DefinedBy(Api.COMPILER_TREE)
885+
public TextTree getBody() {
886+
return body;
887+
}
888+
}
889+
860890
public static class DCStartElement extends DCEndPosTree<DCStartElement> implements StartElementTree {
861891
public final Name name;
862892
public final List<DCTree> attrs;

0 commit comments

Comments
 (0)