5076751: System properties documentation needed in javadocs
authorpmuthuswamy
Mon, 12 Nov 2018 13:31:41 +0530
changeset 52487 5d1d07b72f15
parent 52486 6f5948597697
child 52488 43081c586d77
5076751: System properties documentation needed in javadocs Reviewed-by: jjg
src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java
src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java
src/jdk.compiler/share/classes/com/sun/source/doctree/SystemPropertyTree.java
src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java
src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java
src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java
src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java
src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java
src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SystemPropertyTaglet.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java
test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java
test/langtools/jdk/javadoc/doclet/testTaglets/TestTaglets.out
test/langtools/tools/javac/doctree/DocCommentTester.java
test/langtools/tools/javac/doctree/SystemPropertyTest.java
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java	Mon Nov 12 13:31:41 2018 +0530
@@ -211,6 +211,12 @@
         START_ELEMENT,
 
         /**
+         * Used for instances of {@link SystemPropertyTree}
+         * representing an @systemProperty tag.
+         */
+        SYSTEM_PROPERTY("systemProperty"),
+
+        /**
          * Used for instances of {@link SummaryTree}
          * representing the summary of a comment description.
          */
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java	Mon Nov 12 13:31:41 2018 +0530
@@ -311,6 +311,21 @@
     }
 
     /**
+     * Visits a SystemPropertyTree node.
+     *
+     * @implSpec Visits a {@code SystemPropertyTree} node
+     * by calling {@code visitOther(node, p)}.
+     *
+     * @param node the node being visited
+     * @param p a parameter value
+     * @return a result value
+     * @since 12
+     */
+    default R visitSystemProperty(SystemPropertyTree node, P p) {
+        return visitOther(node, p);
+    }
+
+    /**
      * Visits a TextTree node.
      * @param node the node being visited
      * @param p a parameter value
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/SystemPropertyTree.java	Mon Nov 12 13:31:41 2018 +0530
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.source.doctree;
+
+
+import javax.lang.model.element.Name;
+
+/**
+ * A tree node for an {@code @systemProperty} inline tag.
+ *
+ * <p>
+ * {&#064;systemProperty property-name}
+ *
+ * @since 12
+ */
+public interface SystemPropertyTree extends InlineTagTree {
+    /**
+     * Returns the specified system property name.
+     * @return the system property name
+     */
+    Name getPropertyName();
+}
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java	Mon Nov 12 13:31:41 2018 +0530
@@ -60,6 +60,7 @@
 import com.sun.source.doctree.SinceTree;
 import com.sun.source.doctree.StartElementTree;
 import com.sun.source.doctree.SummaryTree;
+import com.sun.source.doctree.SystemPropertyTree;
 import com.sun.source.doctree.TextTree;
 import com.sun.source.doctree.ThrowsTree;
 import com.sun.source.doctree.UnknownBlockTagTree;
@@ -325,6 +326,15 @@
     }
 
     /**
+     * Create a new {@code SystemPropertyTree} object, to represent a {@code {@systemProperty } } tag.
+     *
+     * @param propertyName the system property name
+     * @return a {@code SystemPropertyTree} object
+     * @since 12
+     */
+    SystemPropertyTree newSystemPropertyTree(Name propertyName);
+
+    /**
      * Create a new {@code TextTree} object, to represent some plain text.
      * @param text the text
      * @return a {@code TextTree} object
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java	Mon Nov 12 13:31:41 2018 +0530
@@ -469,6 +469,19 @@
      * @param node  {@inheritDoc}
      * @param p  {@inheritDoc}
      * @return the result of scanning
+     * @since 12
+     */
+    @Override
+    public R visitSystemProperty(SystemPropertyTree node, P p) {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc} This implementation returns {@code null}.
+     *
+     * @param node  {@inheritDoc}
+     * @param p  {@inheritDoc}
+     * @return the result of scanning
      */
     @Override
     public R visitText(TextTree node, P p) {
--- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java	Mon Nov 12 13:31:41 2018 +0530
@@ -431,6 +431,19 @@
      * @param node {@inheritDoc}
      * @param p {@inheritDoc}
      * @return  the result of {@code defaultAction}
+     * @since 12
+     */
+    @Override
+    public R visitSystemProperty(SystemPropertyTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    /**
+     * {@inheritDoc} This implementation calls {@code defaultAction}.
+     *
+     * @param node {@inheritDoc}
+     * @param p {@inheritDoc}
+     * @return  the result of {@code defaultAction}
      */
     @Override
     public R visitText(TextTree node, P p) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Mon Nov 12 13:31:41 2018 +0530
@@ -1032,6 +1032,14 @@
         return names.fromChars(buf, start, bp - start);
     }
 
+    protected Name readSystemPropertyName() {
+        int pos = bp;
+        nextChar();
+        while (bp < buflen && Character.isUnicodeIdentifierPart(ch) || ch == '.')
+            nextChar();
+        return names.fromChars(buf, pos, bp - pos);
+    }
+
     protected boolean isDecimalDigit(char ch) {
         return ('0' <= ch && ch <= '9');
     }
@@ -1360,6 +1368,28 @@
                 }
             },
 
+            // @systemProperty property-name
+            new TagParser(Kind.INLINE, DCTree.Kind.SYSTEM_PROPERTY) {
+                public DCTree parse(int pos) throws ParseException {
+                    skipWhitespace();
+                    if (ch == '}') {
+                        throw new ParseException("dc.no.content");
+                    }
+                    Name propertyName = readSystemPropertyName();
+                    if (propertyName == null) {
+                        throw new ParseException("dc.no.content");
+                    }
+                    skipWhitespace();
+                    if (ch != '}') {
+                        nextChar();
+                        throw new ParseException("dc.unexpected.content");
+                    } else {
+                        nextChar();
+                        return m.at(pos).newSystemPropertyTree(propertyName);
+                    }
+                }
+            },
+
             // @throws class-name description
             new TagParser(Kind.BLOCK, DCTree.Kind.THROWS) {
                 public DCTree parse(int pos) throws ParseException {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java	Mon Nov 12 13:31:41 2018 +0530
@@ -887,6 +887,29 @@
         }
     }
 
+    public static class DCSystemProperty extends DCInlineTag implements SystemPropertyTree {
+        public final Name propertyName;
+
+        DCSystemProperty(Name propertyName) {
+            this.propertyName = propertyName;
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public Kind getKind() {
+            return Kind.SYSTEM_PROPERTY;
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+            return v.visitSystemProperty(this, d);
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public Name getPropertyName() {
+            return propertyName;
+        }
+    }
+
     public static class DCText extends DCTree implements TextTree {
         public final String text;
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java	Mon Nov 12 13:31:41 2018 +0530
@@ -529,6 +529,20 @@
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitSystemProperty(SystemPropertyTree node, Void p) {
+        try {
+            print("{");
+            printTagName(node);
+            print(" ");
+            print(node.getPropertyName());
+            print("}");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        return null;
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public Void visitText(TextTree node, Void p) {
         try {
             print(node.getBody());
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java	Mon Nov 12 13:31:41 2018 +0530
@@ -82,6 +82,7 @@
 import com.sun.tools.javac.tree.DCTree.DCSince;
 import com.sun.tools.javac.tree.DCTree.DCStartElement;
 import com.sun.tools.javac.tree.DCTree.DCSummary;
+import com.sun.tools.javac.tree.DCTree.DCSystemProperty;
 import com.sun.tools.javac.tree.DCTree.DCText;
 import com.sun.tools.javac.tree.DCTree.DCThrows;
 import com.sun.tools.javac.tree.DCTree.DCUnknownBlockTag;
@@ -448,6 +449,13 @@
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
+    public DCSystemProperty newSystemPropertyTree(Name propertyName) {
+        DCSystemProperty tree = new DCSystemProperty(propertyName);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public DCText newTextTree(String text) {
         DCText tree = new DCText(text);
         tree.pos = pos;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Mon Nov 12 13:31:41 2018 +0530
@@ -65,6 +65,7 @@
 import com.sun.source.doctree.SeeTree;
 import com.sun.source.doctree.StartElementTree;
 import com.sun.source.doctree.SummaryTree;
+import com.sun.source.doctree.SystemPropertyTree;
 import com.sun.source.doctree.TextTree;
 import com.sun.source.util.SimpleDocTreeVisitor;
 
@@ -1531,6 +1532,17 @@
                     return false;
                 }
 
+                @Override
+                public Boolean visitSystemProperty(SystemPropertyTree node, Content p) {
+                    Content output = TagletWriter.getInlineTagOutput(element,
+                            configuration.tagletManager, holderTag, tag,
+                            getTagletWriterInstance(isFirstSentence, inSummary));
+                    if (output != null) {
+                        result.addContent(output);
+                    }
+                    return false;
+                }
+
                 private CharSequence textCleanup(String text, boolean isLast) {
                     return textCleanup(text, isLast, false);
                 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java	Mon Nov 12 13:31:41 2018 +0530
@@ -37,6 +37,7 @@
 
 import com.sun.source.doctree.DocTree;
 import com.sun.source.doctree.IndexTree;
+import com.sun.source.doctree.SystemPropertyTree;
 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
@@ -45,6 +46,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
 import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.Resources;
 import jdk.javadoc.internal.doclets.toolkit.builders.SerializedFormBuilder;
 import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter;
 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
@@ -72,6 +74,7 @@
     private final HtmlConfiguration configuration;
     private final Utils utils;
     private final boolean inSummary;
+    private final Resources resources;
 
     public TagletWriterImpl(HtmlDocletWriter htmlWriter, boolean isFirstSentence) {
         this(htmlWriter, isFirstSentence, false);
@@ -83,6 +86,7 @@
         configuration = htmlWriter.configuration;
         this.utils = configuration.utils;
         this.inSummary = inSummary;
+        resources = configuration.getResources();
     }
 
     /**
@@ -112,61 +116,7 @@
         }
         String desc = ch.getText(itt.getDescription());
 
-        String anchorName = htmlWriter.links.getName(tagText);
-        Content result = null;
-        if (isFirstSentence && inSummary) {
-            result = new StringContent(tagText);
-        } else {
-            result = HtmlTree.A_ID(HtmlStyle.searchTagResult, anchorName, new StringContent(tagText));
-            if (configuration.createindex && !tagText.isEmpty()) {
-                SearchIndexItem si = new SearchIndexItem();
-                si.setLabel(tagText);
-                si.setDescription(desc);
-                DocPaths docPaths = configuration.docPaths;
-                new SimpleElementVisitor9<Void, Void>() {
-                    @Override
-                    public Void visitModule(ModuleElement e, Void p) {
-                        si.setUrl(docPaths.moduleSummary(e).getPath() + "#" + anchorName);
-                        si.setHolder(utils.getFullyQualifiedName(element));
-                        return null;
-                    }
-
-                    @Override
-                    public Void visitPackage(PackageElement e, Void p) {
-                        si.setUrl(docPaths.forPackage(e).getPath()
-                                + "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName);
-                        si.setHolder(utils.getSimpleName(element));
-                        return null;
-                    }
-
-                    @Override
-                    public Void visitType(TypeElement e, Void p) {
-                        si.setUrl(docPaths.forClass(e).getPath() + "#" + anchorName);
-                        si.setHolder(utils.getFullyQualifiedName(e));
-                        return null;
-                    }
-
-                    @Override
-                    public Void visitVariable(VariableElement e, Void p) {
-                        TypeElement te = utils.getEnclosingTypeElement(e);
-                        si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
-                        si.setHolder(utils.getFullyQualifiedName(e) + "." + utils.getSimpleName(e));
-                        return null;
-                    }
-
-                    @Override
-                    protected Void defaultAction(Element e, Void p) {
-                        TypeElement te = utils.getEnclosingTypeElement(e);
-                        si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
-                        si.setHolder(utils.getFullyQualifiedName(e));
-                        return null;
-                    }
-                }.visit(element);
-                si.setCategory(configuration.getContent("doclet.SearchTags").toString());
-                configuration.tagSearchIndex.add(si);
-            }
-        }
-        return result;
+        return createAnchorAndSearchIndex(element, tagText,desc);
     }
 
     /**
@@ -367,6 +317,16 @@
     /**
      * {@inheritDoc}
      */
+    protected Content systemPropertyTagOutput(Element element, DocTree tag) {
+        SystemPropertyTree itt = (SystemPropertyTree)tag;
+        String tagText = itt.getPropertyName().toString();
+        return HtmlTree.CODE(createAnchorAndSearchIndex(element, tagText,
+                resources.getText("doclet.System_Property")));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public Content getThrowsHeader() {
         HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.throwsLabel,
                 new StringContent(configuration.getText("doclet.Throws"))));
@@ -449,4 +409,62 @@
     public BaseConfiguration configuration() {
         return configuration;
     }
+
+    private Content createAnchorAndSearchIndex(Element element, String tagText, String desc){
+        String anchorName = htmlWriter.links.getName(tagText);
+        Content result = null;
+        if (isFirstSentence && inSummary) {
+            result = new StringContent(tagText);
+        } else {
+            result = HtmlTree.A_ID(HtmlStyle.searchTagResult, anchorName, new StringContent(tagText));
+            if (configuration.createindex && !tagText.isEmpty()) {
+                SearchIndexItem si = new SearchIndexItem();
+                si.setLabel(tagText);
+                si.setDescription(desc);
+                DocPaths docPaths = configuration.docPaths;
+                new SimpleElementVisitor9<Void, Void>() {
+                    @Override
+                    public Void visitModule(ModuleElement e, Void p) {
+                        si.setUrl(docPaths.moduleSummary(e).getPath() + "#" + anchorName);
+                        si.setHolder(utils.getFullyQualifiedName(element));
+                        return null;
+                    }
+
+                    @Override
+                    public Void visitPackage(PackageElement e, Void p) {
+                        si.setUrl(docPaths.forPackage(e).getPath()
+                                + "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName);
+                        si.setHolder(utils.getSimpleName(element));
+                        return null;
+                    }
+
+                    @Override
+                    public Void visitType(TypeElement e, Void p) {
+                        si.setUrl(docPaths.forClass(e).getPath() + "#" + anchorName);
+                        si.setHolder(utils.getFullyQualifiedName(e));
+                        return null;
+                    }
+
+                    @Override
+                    public Void visitVariable(VariableElement e, Void p) {
+                        TypeElement te = utils.getEnclosingTypeElement(e);
+                        si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
+                        si.setHolder(utils.getFullyQualifiedName(e) + "." + utils.getSimpleName(e));
+                        return null;
+                    }
+
+                    @Override
+                    protected Void defaultAction(Element e, Void p) {
+                        TypeElement te = utils.getEnclosingTypeElement(e);
+                        si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
+                        si.setHolder(utils.getFullyQualifiedName(e));
+                        return null;
+                    }
+                }.visit(element);
+                si.setCategory(configuration.getContent("doclet.SearchTags").toString());
+                configuration.tagSearchIndex.add(si);
+            }
+        }
+        return result;
+    }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Mon Nov 12 13:31:41 2018 +0530
@@ -95,6 +95,7 @@
 doclet.Interfaces=Interfaces
 doclet.Enclosing_Class=Enclosing class:
 doclet.Enclosing_Interface=Enclosing interface:
+doclet.System_Property=System Property
 doclet.Window_Source_title=Source code
 doclet.Window_Help_title=API Help
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SystemPropertyTaglet.java	Mon Nov 12 13:31:41 2018 +0530
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package jdk.javadoc.internal.doclets.toolkit.taglets;
+
+import com.sun.source.doctree.DocTree;
+import jdk.javadoc.internal.doclets.toolkit.Content;
+
+import javax.lang.model.element.Element;
+import java.util.EnumSet;
+
+import static com.sun.source.doctree.DocTree.Kind.SYSTEM_PROPERTY;
+
+/**
+ * A taglet that represents the {@code @systemProperty} tag.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+
+public class SystemPropertyTaglet extends BaseTaglet {
+
+    SystemPropertyTaglet(){
+        super(SYSTEM_PROPERTY.tagName, true, EnumSet.of(Site.CONSTRUCTOR, Site.METHOD, Site.FIELD,
+                Site.PACKAGE, Site.MODULE, Site.TYPE));
+    }
+
+    @Override
+    public Content getTagletOutput(Element element, DocTree tag, TagletWriter writer) {
+        return writer.systemPropertyTagOutput(element, tag);
+    }
+}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Mon Nov 12 13:31:41 2018 +0530
@@ -609,6 +609,7 @@
         addStandardTaglet(new CodeTaglet());
         addStandardTaglet(new IndexTaglet());
         addStandardTaglet(new SummaryTaglet());
+        addStandardTaglet(new SystemPropertyTaglet());
 
         // Keep track of the names of standard tags for error checking purposes.
         // The following are not handled above.
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java	Mon Nov 12 13:31:41 2018 +0530
@@ -172,6 +172,15 @@
     protected abstract Content simpleTagOutput(Element element, DocTree simpleTag, String header);
 
     /**
+     * Return the system property tag output.
+     *
+     * @param element
+     * @param systemPropertyTag the system property tag
+     * @return the output of system property tag
+     */
+    protected abstract Content systemPropertyTagOutput(Element element, DocTree systemPropertyTag);
+
+    /**
      * Return the header for the throws tag.
      *
      * @return the header for the throws tag.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java	Mon Nov 12 13:31:41 2018 +0530
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018, 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
+ * @bug 5076751
+ * @summary System properties documentation needed in javadocs
+ * @library /tools/lib ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build JavadocTester toolbox.ToolBox builder.ClassBuilder
+ * @run main TestSystemPropertyTaglet
+ */
+
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import builder.ClassBuilder;
+import builder.ClassBuilder.MethodBuilder;
+import toolbox.ToolBox;
+
+public class TestSystemPropertyTaglet extends JavadocTester {
+
+    final ToolBox tb;
+
+    public static void main(String... args) throws Exception {
+        TestSystemPropertyTaglet tester = new TestSystemPropertyTaglet();
+        tester.runTests(m -> new Object[]{Paths.get(m.getName())});
+    }
+
+    TestSystemPropertyTaglet() {
+        tb = new ToolBox();
+    }
+
+    @Test
+    void test(Path base) throws Exception {
+        Path srcDir = base.resolve("src");
+        createTestClass(srcDir);
+
+        Path outDir = base.resolve("out");
+        javadoc("-d", outDir.toString(),
+                "-sourcepath", srcDir.toString(),
+                "pkg");
+
+        checkExit(Exit.OK);
+
+        checkOrder("pkg/A.html",
+                "<h2 title=\"Class A\" class=\"title\">Class A</h2>",
+                "test with <code><a id=\"user.name\" class=\"searchTagResult\">user.name</a></code>",
+                "<h3>Method Detail</h3>",
+                "test with <code><a id=\"java.version\" class=\"searchTagResult\">java.version</a></code>");
+
+        checkOrder("index-all.html",
+                "<h2 class=\"title\">J</h2>",
+                "<dt><span class=\"searchTagLink\"><a href=\"pkg/A.html#java.version\">java.version</a>"
+                + "</span> - Search tag in pkg.A</dt>\n<dd>System Property</dd>",
+                "<h2 class=\"title\">U</h2>",
+                "<dt><span class=\"searchTagLink\"><a href=\"pkg/A.html#user.name\">user.name</a></span>"
+                + " - Search tag in pkg.A</dt>\n<dd>System Property</dd>");
+
+        checkOutput("tag-search-index.js", true,
+                "{\"l\":\"java.version\",\"h\":\"pkg.A\",\"d\":\"System Property\","
+                + "\"u\":\"pkg/A.html#java.version\"}");
+
+        checkOutput("tag-search-index.js", true,
+                "{\"l\":\"user.name\",\"h\":\"pkg.A\",\"d\":\"System Property\","
+                + "\"u\":\"pkg/A.html#user.name\"}");
+    }
+
+    void createTestClass(Path srcDir) throws Exception {
+        MethodBuilder method = MethodBuilder
+                .parse("public void func(A a) {}")
+                .setComments("test with {@systemProperty java.version}");
+
+        new ClassBuilder(tb, "pkg.A")
+                .setComments("test with {@systemProperty user.name}")
+                .setModifiers("public", "class")
+                .addMembers(method)
+                .write(srcDir);
+    }
+}
--- a/test/langtools/jdk/javadoc/doclet/testTaglets/TestTaglets.out	Sun Nov 11 21:24:46 2018 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testTaglets/TestTaglets.out	Mon Nov 12 13:31:41 2018 +0530
@@ -23,6 +23,7 @@
         @serialField: ........ ...... ....... .... ........... ...... field ...... ........
               @since: overview module package type constructor method field ...... ........
           {@summary}: overview module package type constructor method field inline ........
+   {@systemProperty}: ........ module package type constructor method field inline ........
              @throws: ........ ...... ....... .... constructor method ..... ...... ........
      @treatAsPrivate: ........ ...... ....... type ........... method field ...... ........
                @uses: ........ module ....... .... ........... ...... ..... ...... ........
--- a/test/langtools/tools/javac/doctree/DocCommentTester.java	Sun Nov 11 21:24:46 2018 +0100
+++ b/test/langtools/tools/javac/doctree/DocCommentTester.java	Mon Nov 12 13:31:41 2018 +0530
@@ -613,6 +613,17 @@
                 return null;
             }
 
+            @Override
+            public Void visitSystemProperty(SystemPropertyTree node, Void p) {
+                header(node);
+                indent(+1);
+                print("property name", node.getPropertyName().toString());
+                indent(-1);
+                indent();
+                out.println("]");
+                return null;
+            }
+
             public Void visitText(TextTree node, Void p) {
                 header(node, compress(node.getBody()));
                 return null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/SystemPropertyTest.java	Mon Nov 12 13:31:41 2018 +0530
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018, 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
+ * @bug 5076751
+ * @summary System properties documentation needed in javadocs
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.file
+ *          jdk.compiler/com.sun.tools.javac.tree
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @build DocCommentTester
+ * @run main DocCommentTester SystemPropertyTest.java
+ */
+
+class SystemPropertyTest {
+    /**
+     * abc {@systemProperty xyz.qwe} def
+     */
+    void simple_term() {}
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 3
+    Text[TEXT, pos:1, abc_]
+    SystemProperty[SYSTEM_PROPERTY, pos:5
+      property name: xyz.qwe
+    ]
+    Text[TEXT, pos:30, _def]
+  body: empty
+  block tags: empty
+]
+*/
+
+    /**
+     * abc {@systemProperty xyz qwe}
+     */
+    void bad_with_whitespace() {}
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 3
+    Text[TEXT, pos:1, abc_]
+    Erroneous[ERRONEOUS, pos:5
+      code: compiler.err.dc.unexpected.content
+      body: {@systemProperty_xyz_q
+    ]
+    Text[TEXT, pos:27, we}]
+  body: empty
+  block tags: empty
+]
+*/
+
+    /**
+     * abc {@systemProperty}
+     */
+    void bad_no_property() {}
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 3
+    Text[TEXT, pos:1, abc_]
+    Erroneous[ERRONEOUS, pos:5
+      code: compiler.err.dc.no.content
+      body: {@systemProperty
+    ]
+    Text[TEXT, pos:21, }]
+  body: empty
+  block tags: empty
+]
+*/
+
+}