langtools/src/share/classes/com/sun/tools/doclint/Checker.java
changeset 21017 f61558e07e14
parent 20256 9154c5cc0d9f
child 21500 475e59d3b40c
equal deleted inserted replaced
21016:0678607f30e5 21017:f61558e07e14
   211 
   211 
   212     @Override
   212     @Override
   213     public Void visitDocComment(DocCommentTree tree, Void ignore) {
   213     public Void visitDocComment(DocCommentTree tree, Void ignore) {
   214         super.visitDocComment(tree, ignore);
   214         super.visitDocComment(tree, ignore);
   215         for (TagStackItem tsi: tagStack) {
   215         for (TagStackItem tsi: tagStack) {
       
   216             warnIfEmpty(tsi, null);
   216             if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT
   217             if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT
   217                     && tsi.tag.endKind == HtmlTag.EndKind.REQUIRED) {
   218                     && tsi.tag.endKind == HtmlTag.EndKind.REQUIRED) {
   218                 StartElementTree t = (StartElementTree) tsi.tree;
   219                 StartElementTree t = (StartElementTree) tsi.tree;
   219                 env.messages.error(HTML, t, "dc.tag.not.closed", t.getName());
   220                 env.messages.error(HTML, t, "dc.tag.not.closed", t.getName());
   220             }
   221             }
   268 
   269 
   269     // <editor-fold defaultstate="collapsed" desc="HTML elements">
   270     // <editor-fold defaultstate="collapsed" desc="HTML elements">
   270 
   271 
   271     @Override
   272     @Override
   272     public Void visitStartElement(StartElementTree tree, Void ignore) {
   273     public Void visitStartElement(StartElementTree tree, Void ignore) {
   273         markEnclosingTag(Flag.HAS_ELEMENT);
       
   274         final Name treeName = tree.getName();
   274         final Name treeName = tree.getName();
   275         final HtmlTag t = HtmlTag.get(treeName);
   275         final HtmlTag t = HtmlTag.get(treeName);
   276         if (t == null) {
   276         if (t == null) {
   277             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
   277             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
   278         } else {
   278         } else {
   279             boolean done = false;
   279             boolean done = false;
   280             for (TagStackItem tsi: tagStack) {
   280             for (TagStackItem tsi: tagStack) {
   281                 if (tsi.tag.accepts(t)) {
   281                 if (tsi.tag.accepts(t)) {
   282                     while (tagStack.peek() != tsi) tagStack.pop();
   282                     while (tagStack.peek() != tsi) {
       
   283                         warnIfEmpty(tagStack.peek(), null);
       
   284                         tagStack.pop();
       
   285                     }
   283                     done = true;
   286                     done = true;
   284                     break;
   287                     break;
   285                 } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL) {
   288                 } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL) {
   286                     done = true;
   289                     done = true;
   287                     break;
   290                     break;
   288                 }
   291                 }
   289             }
   292             }
   290             if (!done && HtmlTag.BODY.accepts(t)) {
   293             if (!done && HtmlTag.BODY.accepts(t)) {
   291                 tagStack.clear();
   294                 while (!tagStack.isEmpty()) {
   292             }
   295                     warnIfEmpty(tagStack.peek(), null);
   293 
   296                     tagStack.pop();
       
   297                 }
       
   298             }
       
   299 
       
   300             markEnclosingTag(Flag.HAS_ELEMENT);
   294             checkStructure(tree, t);
   301             checkStructure(tree, t);
   295 
   302 
   296             // tag specific checks
   303             // tag specific checks
   297             switch (t) {
   304             switch (t) {
   298                 // check for out of sequence headers, such as <h1>...</h1>  <h3>...</h3>
   305                 // check for out of sequence headers, such as <h1>...</h1>  <h3>...</h3>
   445                                     && !top.flags.contains(Flag.TABLE_HAS_CAPTION)) {
   452                                     && !top.flags.contains(Flag.TABLE_HAS_CAPTION)) {
   446                                 env.messages.error(ACCESSIBILITY, tree,
   453                                 env.messages.error(ACCESSIBILITY, tree,
   447                                         "dc.no.summary.or.caption.for.table");
   454                                         "dc.no.summary.or.caption.for.table");
   448                             }
   455                             }
   449                     }
   456                     }
   450                     if (t.flags.contains(HtmlTag.Flag.EXPECT_CONTENT)
   457                     warnIfEmpty(top, tree);
   451                             && !top.flags.contains(Flag.HAS_TEXT)
       
   452                             && !top.flags.contains(Flag.HAS_ELEMENT)
       
   453                             && !top.flags.contains(Flag.HAS_INLINE_TAG)) {
       
   454                         env.messages.warning(HTML, tree, "dc.tag.empty", treeName);
       
   455                     }
       
   456                     tagStack.pop();
   458                     tagStack.pop();
   457                     done = true;
   459                     done = true;
   458                     break;
   460                     break;
   459                 } else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
   461                 } else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
   460                     tagStack.pop();
   462                     tagStack.pop();
   483             }
   485             }
   484         }
   486         }
   485 
   487 
   486         return super.visitEndElement(tree, ignore);
   488         return super.visitEndElement(tree, ignore);
   487     }
   489     }
       
   490 
       
   491     void warnIfEmpty(TagStackItem tsi, DocTree endTree) {
       
   492         if (tsi.tag != null && tsi.tree instanceof StartElementTree) {
       
   493             if (tsi.tag.flags.contains(HtmlTag.Flag.EXPECT_CONTENT)
       
   494                     && !tsi.flags.contains(Flag.HAS_TEXT)
       
   495                     && !tsi.flags.contains(Flag.HAS_ELEMENT)
       
   496                     && !tsi.flags.contains(Flag.HAS_INLINE_TAG)) {
       
   497                 DocTree tree = (endTree != null) ? endTree : tsi.tree;
       
   498                 Name treeName = ((StartElementTree) tsi.tree).getName();
       
   499                 env.messages.warning(HTML, tree, "dc.tag.empty", treeName);
       
   500             }
       
   501         }
       
   502     }
       
   503 
   488     // </editor-fold>
   504     // </editor-fold>
   489 
   505 
   490     // <editor-fold defaultstate="collapsed" desc="HTML attributes">
   506     // <editor-fold defaultstate="collapsed" desc="HTML attributes">
   491 
   507 
   492     @Override @SuppressWarnings("fallthrough")
   508     @Override @SuppressWarnings("fallthrough")