зеркало из https://github.com/microsoft/clang-1.git
Make concepts of optional and forbidden end tags separate. Thanks Jordan for pointing this!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160149 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
23458208b2
Коммит
3d986980bd
|
@ -156,7 +156,9 @@ public:
|
|||
unsigned getBlockCommandNumArgs(StringRef Name);
|
||||
|
||||
bool isInlineCommand(StringRef Name);
|
||||
bool HTMLOpenTagNeedsClosing(StringRef Name);
|
||||
|
||||
bool isHTMLCloseTagOptional(StringRef Name);
|
||||
bool isHTMLCloseTagForbidden(StringRef Name);
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
|
|
|
@ -26,6 +26,10 @@ def note_doc_html_tag_started_here : Note<
|
|||
|
||||
// HTML semantic errors
|
||||
|
||||
def warn_doc_html_close_forbidden : Warning<
|
||||
"HTML closing tag '%0' is forbidden">,
|
||||
InGroup<DocumentationHTML>, DefaultIgnore;
|
||||
|
||||
def warn_doc_html_close_unbalanced : Warning<
|
||||
"HTML closing tag does not match any opening tag">,
|
||||
InGroup<DocumentationHTML>, DefaultIgnore;
|
||||
|
|
|
@ -289,7 +289,7 @@ HTMLOpenTagComment *Sema::actOnHTMLOpenTagFinish(
|
|||
Tag->setGreaterLoc(GreaterLoc);
|
||||
if (IsSelfClosing)
|
||||
Tag->setSelfClosing();
|
||||
else
|
||||
else if (!isHTMLCloseTagForbidden(Tag->getTagName()))
|
||||
HTMLOpenTags.push_back(Tag);
|
||||
return Tag;
|
||||
}
|
||||
|
@ -299,6 +299,12 @@ HTMLCloseTagComment *Sema::actOnHTMLCloseTag(SourceLocation LocBegin,
|
|||
StringRef TagName) {
|
||||
HTMLCloseTagComment *HCT =
|
||||
new (Allocator) HTMLCloseTagComment(LocBegin, LocEnd, TagName);
|
||||
if (isHTMLCloseTagForbidden(TagName)) {
|
||||
Diag(HCT->getLocation(), diag::warn_doc_html_close_forbidden)
|
||||
<< TagName << HCT->getSourceRange();
|
||||
return HCT;
|
||||
}
|
||||
|
||||
bool FoundOpen = false;
|
||||
for (SmallVectorImpl<HTMLOpenTagComment *>::const_reverse_iterator
|
||||
I = HTMLOpenTags.rbegin(), E = HTMLOpenTags.rend();
|
||||
|
@ -321,7 +327,7 @@ HTMLCloseTagComment *Sema::actOnHTMLCloseTag(SourceLocation LocBegin,
|
|||
if (LastNotClosedTagName == TagName)
|
||||
break;
|
||||
|
||||
if (!HTMLOpenTagNeedsClosing(LastNotClosedTagName))
|
||||
if (isHTMLCloseTagOptional(LastNotClosedTagName))
|
||||
continue;
|
||||
|
||||
bool OpenLineInvalid;
|
||||
|
@ -448,12 +454,29 @@ bool Sema::isInlineCommand(StringRef Name) {
|
|||
.Default(false);
|
||||
}
|
||||
|
||||
bool Sema::HTMLOpenTagNeedsClosing(StringRef Name) {
|
||||
bool Sema::isHTMLCloseTagOptional(StringRef Name) {
|
||||
return llvm::StringSwitch<bool>(Name)
|
||||
.Case("br", false)
|
||||
.Case("hr", false)
|
||||
.Case("li", false)
|
||||
.Default(true);
|
||||
.Case("p", true)
|
||||
.Case("li", true)
|
||||
.Case("dt", true)
|
||||
.Case("dd", true)
|
||||
.Case("tr", true)
|
||||
.Case("th", true)
|
||||
.Case("td", true)
|
||||
.Case("thead", true)
|
||||
.Case("tfoot", true)
|
||||
.Case("tbody", true)
|
||||
.Case("colgroup", true)
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
bool Sema::isHTMLCloseTagForbidden(StringRef Name) {
|
||||
return llvm::StringSwitch<bool>(Name)
|
||||
.Case("br", true)
|
||||
.Case("hr", true)
|
||||
.Case("img", true)
|
||||
.Case("col", true)
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
} // end namespace comments
|
||||
|
|
|
@ -45,6 +45,9 @@ int test_html9(int);
|
|||
*/
|
||||
int test_html10(int);
|
||||
|
||||
// expected-warning@+1 {{HTML closing tag 'br' is forbidden}}
|
||||
/// <br></br>
|
||||
int test_html11(int);
|
||||
|
||||
/// <blockquote>Meow</blockquote>
|
||||
int test_html_nesting1(int);
|
||||
|
|
Загрузка…
Ссылка в новой задаче