src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java
changeset 54135 67f72165dca5
parent 52871 c09bff7928e8
child 57723 54a04db114d8
equal deleted inserted replaced
54133:829bf950287e 54135:67f72165dca5
     1 /*
     1 /*
     2  * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    59 import com.sun.source.doctree.EntityTree;
    59 import com.sun.source.doctree.EntityTree;
    60 import com.sun.source.doctree.ErroneousTree;
    60 import com.sun.source.doctree.ErroneousTree;
    61 import com.sun.source.doctree.IdentifierTree;
    61 import com.sun.source.doctree.IdentifierTree;
    62 import com.sun.source.doctree.IndexTree;
    62 import com.sun.source.doctree.IndexTree;
    63 import com.sun.source.doctree.InheritDocTree;
    63 import com.sun.source.doctree.InheritDocTree;
    64 import com.sun.source.doctree.InlineTagTree;
       
    65 import com.sun.source.doctree.LinkTree;
    64 import com.sun.source.doctree.LinkTree;
    66 import com.sun.source.doctree.LiteralTree;
    65 import com.sun.source.doctree.LiteralTree;
    67 import com.sun.source.doctree.ParamTree;
    66 import com.sun.source.doctree.ParamTree;
    68 import com.sun.source.doctree.ProvidesTree;
    67 import com.sun.source.doctree.ProvidesTree;
    69 import com.sun.source.doctree.ReferenceTree;
    68 import com.sun.source.doctree.ReferenceTree;
   138             return String.valueOf(tag);
   137             return String.valueOf(tag);
   139         }
   138         }
   140     }
   139     }
   141 
   140 
   142     private final Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well
   141     private final Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well
   143     private HtmlTag currHeaderTag;
   142     private HtmlTag currHeadingTag;
   144 
   143 
   145     private final int implicitHeaderLevel;
   144     private int implicitHeadingRank;
   146 
   145 
   147     // <editor-fold defaultstate="collapsed" desc="Top level">
   146     // <editor-fold defaultstate="collapsed" desc="Top level">
   148 
   147 
   149     Checker(Env env) {
   148     Checker(Env env) {
   150         this.env = Assert.checkNonNull(env);
   149         this.env = Assert.checkNonNull(env);
   151         tagStack = new LinkedList<>();
   150         tagStack = new LinkedList<>();
   152         implicitHeaderLevel = env.implicitHeaderLevel;
       
   153     }
   151     }
   154 
   152 
   155     public Void scan(DocCommentTree tree, TreePath p) {
   153     public Void scan(DocCommentTree tree, TreePath p) {
   156         env.initTypes();
   154         env.initTypes();
   157         env.setCurrent(p, tree);
   155         env.setCurrent(p, tree);
   186                 return null;
   184                 return null;
   187             }
   185             }
   188         }
   186         }
   189 
   187 
   190         tagStack.clear();
   188         tagStack.clear();
   191         currHeaderTag = null;
   189         currHeadingTag = null;
   192 
   190 
   193         foundParams.clear();
   191         foundParams.clear();
   194         foundThrows.clear();
   192         foundThrows.clear();
   195         foundInheritDoc = false;
   193         foundInheritDoc = false;
   196         foundReturn = false;
   194         foundReturn = false;
   197         hasNonWhitespaceText = false;
   195         hasNonWhitespaceText = false;
       
   196 
       
   197         switch (p.getLeaf().getKind()) {
       
   198             // the following are for declarations that have their own top-level page,
       
   199             // and so the doc comment comes after the <h1> page title.
       
   200             case MODULE:
       
   201             case PACKAGE:
       
   202             case CLASS:
       
   203             case INTERFACE:
       
   204             case ENUM:
       
   205             case ANNOTATION_TYPE:
       
   206                 implicitHeadingRank = 1;
       
   207                 break;
       
   208 
       
   209             // this is for html files
       
   210             // ... if it is a legacy package.html, the doc comment comes after the <h1> page title
       
   211             // ... otherwise, (e.g. overview file and doc-files/*.html files) no additional headings are inserted
       
   212             case COMPILATION_UNIT:
       
   213                 implicitHeadingRank = fo.isNameCompatible("package", JavaFileObject.Kind.HTML) ? 1 : 0;
       
   214                 break;
       
   215 
       
   216             // the following are for member declarations, which appear in the page
       
   217             // for the enclosing type, and so appear after the <h2> "Members"
       
   218             // aggregate heading and the specific <h3> "Member signature" heading.
       
   219             case METHOD:
       
   220             case VARIABLE:
       
   221                 implicitHeadingRank = 3;
       
   222                 break;
       
   223 
       
   224             default:
       
   225                 Assert.error("unexpected tree kind: " + p.getLeaf().getKind() + " " + fo);
       
   226         }
   198 
   227 
   199         scan(new DocTreePath(p, tree), null);
   228         scan(new DocTreePath(p, tree), null);
   200 
   229 
   201         if (!isOverridingMethod) {
   230         if (!isOverridingMethod) {
   202             switch (env.currElement.getKind()) {
   231             switch (env.currElement.getKind()) {
   326             markEnclosingTag(Flag.HAS_ELEMENT);
   355             markEnclosingTag(Flag.HAS_ELEMENT);
   327             checkStructure(tree, t);
   356             checkStructure(tree, t);
   328 
   357 
   329             // tag specific checks
   358             // tag specific checks
   330             switch (t) {
   359             switch (t) {
   331                 // check for out of sequence headers, such as <h1>...</h1>  <h3>...</h3>
   360                 // check for out of sequence headings, such as <h1>...</h1>  <h3>...</h3>
   332                 case H1: case H2: case H3: case H4: case H5: case H6:
   361                 case H1: case H2: case H3: case H4: case H5: case H6:
   333                     checkHeader(tree, t);
   362                     checkHeading(tree, t);
   334                     break;
   363                     break;
   335             }
   364             }
   336 
   365 
   337             if (t.flags.contains(HtmlTag.Flag.NO_NEST)) {
   366             if (t.flags.contains(HtmlTag.Flag.NO_NEST)) {
   338                 for (TagStackItem i: tagStack) {
   367                 for (TagStackItem i: tagStack) {
   444         }
   473         }
   445 
   474 
   446         env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName);
   475         env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName);
   447     }
   476     }
   448 
   477 
   449     private void checkHeader(StartElementTree tree, HtmlTag tag) {
   478     private void checkHeading(StartElementTree tree, HtmlTag tag) {
   450         // verify the new tag
   479         // verify the new tag
   451         if (getHeaderLevel(tag) > getHeaderLevel(currHeaderTag) + 1) {
   480         if (getHeadingRank(tag) > getHeadingRank(currHeadingTag) + 1) {
   452             if (currHeaderTag == null) {
   481             if (currHeadingTag == null) {
   453                 env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.1", tag);
   482                 env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.1",
       
   483                         tag, implicitHeadingRank);
   454             } else {
   484             } else {
   455                 env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.2",
   485                 env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.2",
   456                     tag, currHeaderTag);
   486                     tag, currHeadingTag);
   457             }
   487             }
   458         }
   488         } else if (getHeadingRank(tag) <= implicitHeadingRank) {
   459 
   489             env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.3",
   460         currHeaderTag = tag;
   490                     tag, implicitHeadingRank);
   461     }
   491         }
   462 
   492 
   463     private int getHeaderLevel(HtmlTag tag) {
   493         currHeadingTag = tag;
       
   494     }
       
   495 
       
   496     private int getHeadingRank(HtmlTag tag) {
   464         if (tag == null)
   497         if (tag == null)
   465             return implicitHeaderLevel;
   498             return implicitHeadingRank;
   466         switch (tag) {
   499         switch (tag) {
   467             case H1: return 1;
   500             case H1: return 1;
   468             case H2: return 2;
   501             case H2: return 2;
   469             case H3: return 3;
   502             case H3: return 3;
   470             case H4: return 4;
   503             case H4: return 4;
   664             case INVALID:
   697             case INVALID:
   665                 env.messages.error(HTML, tree, "dc.attr.unknown", name);
   698                 env.messages.error(HTML, tree, "dc.attr.unknown", name);
   666                 break;
   699                 break;
   667 
   700 
   668             case OBSOLETE:
   701             case OBSOLETE:
   669                 env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name);
   702                 env.messages.warning(HTML, tree, "dc.attr.obsolete", name);
   670                 break;
   703                 break;
   671 
   704 
   672             case USE_CSS:
   705             case USE_CSS:
   673                 env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name);
   706                 env.messages.warning(HTML, tree, "dc.attr.obsolete.use.css", name);
   674                 break;
   707                 break;
   675 
   708 
   676             case HTML5:
   709             case HTML5:
   677                 env.messages.error(HTML, tree, "dc.attr.not.supported.html4", name);
   710                 env.messages.error(HTML, tree, "dc.attr.not.supported.html4", name);
   678                 break;
   711                 break;