[cfe-commits] r162407 - in /cfe/trunk: lib/AST/CommentLexer.cpp test/Sema/warn-documentation.cpp unittests/AST/CommentLexer.cpp
Dmitri Gribenko
gribozavr at gmail.com
Wed Aug 22 15:56:08 PDT 2012
Author: gribozavr
Date: Wed Aug 22 17:56:08 2012
New Revision: 162407
URL: http://llvm.org/viewvc/llvm-project?rev=162407&view=rev
Log:
Comment parsing: parse "<blah" as an HTML tag only if "blah" is a known tag
name. This should reduce the amount of warning false positives about bad HTML
in comments when the comment author intended to put a reference to a template.
This change will also enable us parse the comment as intended in these cases.
Fixes part 1 of PR13374.
Modified:
cfe/trunk/lib/AST/CommentLexer.cpp
cfe/trunk/test/Sema/warn-documentation.cpp
cfe/trunk/unittests/AST/CommentLexer.cpp
Modified: cfe/trunk/lib/AST/CommentLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentLexer.cpp?rev=162407&r1=162406&r2=162407&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentLexer.cpp (original)
+++ cfe/trunk/lib/AST/CommentLexer.cpp Wed Aug 22 17:56:08 2012
@@ -28,6 +28,33 @@
(C >= 'a' && C <= 'f') ||
(C >= 'A' && C <= 'F');
}
+
+bool isHTMLTagName(StringRef Name) {
+ return llvm::StringSwitch<bool>(Name)
+ .Cases("em", "strong", true)
+ .Cases("tt", "i", "b", "big", "small", true)
+ .Cases("strike", "s", "u", "font", true)
+ .Case("a", true)
+ .Case("hr", true)
+ .Cases("div", "span", true)
+ .Cases("h1", "h2", "h3", true)
+ .Cases("h4", "h5", "h6", true)
+ .Case("code", true)
+ .Case("blockquote", true)
+ .Cases("sub", "sup", true)
+ .Case("img", true)
+ .Case("p", true)
+ .Case("br", true)
+ .Case("pre", true)
+ .Cases("ins", "del", true)
+ .Cases("ul", "ol", "li", true)
+ .Cases("dl", "dt", "dd", true)
+ .Cases("table", "caption", true)
+ .Cases("thead", "tfoot", "tbody", true)
+ .Cases("colgroup", "col", true)
+ .Cases("tr", "th", "td", true)
+ .Default(false);
+}
} // unnamed namespace
StringRef Lexer::resolveHTMLNamedCharacterReference(StringRef Name) const {
@@ -585,8 +612,12 @@
assert(BufferPtr[0] == '<' &&
isHTMLIdentifierStartingCharacter(BufferPtr[1]));
const char *TagNameEnd = skipHTMLIdentifier(BufferPtr + 2, CommentEnd);
-
StringRef Name(BufferPtr + 1, TagNameEnd - (BufferPtr + 1));
+ if (!isHTMLTagName(Name)) {
+ formTextToken(T, TagNameEnd);
+ return;
+ }
+
formTokenWithChars(T, TagNameEnd, tok::html_start_tag);
T.setHTMLTagStartName(Name);
@@ -665,11 +696,16 @@
const char *TagNameBegin = skipWhitespace(BufferPtr + 2, CommentEnd);
const char *TagNameEnd = skipHTMLIdentifier(TagNameBegin, CommentEnd);
+ StringRef Name(TagNameBegin, TagNameEnd - TagNameBegin);
+ if (!isHTMLTagName(Name)) {
+ formTextToken(T, TagNameEnd);
+ return;
+ }
const char *End = skipWhitespace(TagNameEnd, CommentEnd);
formTokenWithChars(T, End, tok::html_end_tag);
- T.setHTMLTagEndName(StringRef(TagNameBegin, TagNameEnd - TagNameBegin));
+ T.setHTMLTagEndName(Name);
if (BufferPtr != CommentEnd && *BufferPtr == '>')
State = LS_HTMLEndTag;
Modified: cfe/trunk/test/Sema/warn-documentation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.cpp?rev=162407&r1=162406&r2=162407&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-documentation.cpp (original)
+++ cfe/trunk/test/Sema/warn-documentation.cpp Wed Aug 22 17:56:08 2012
@@ -38,13 +38,13 @@
int test_html8(int);
// expected-warning at +2 {{HTML start tag prematurely ended, expected attribute name or '>'}} expected-note at +1 {{HTML tag started here}}
-/** Aaa bbb<ccc ddd eee
+/** Aaa bbb<img ddd eee
* fff ggg.
*/
int test_html9(int);
// expected-warning at +1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
-/** Aaa bbb<ccc ddd eee 42%
+/** Aaa bbb<img ddd eee 42%
* fff ggg.
*/
int test_html10(int);
Modified: cfe/trunk/unittests/AST/CommentLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CommentLexer.cpp?rev=162407&r1=162406&r2=162407&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/CommentLexer.cpp (original)
+++ cfe/trunk/unittests/AST/CommentLexer.cpp Wed Aug 22 17:56:08 2012
@@ -822,7 +822,7 @@
TEST_F(CommentLexerTest, HTML3) {
const char *Source =
- "// < tag";
+ "// < img";
std::vector<Token> Toks;
@@ -837,15 +837,15 @@
ASSERT_EQ(StringRef("<"), Toks[1].getText());
ASSERT_EQ(tok::text, Toks[2].getKind());
- ASSERT_EQ(StringRef(" tag"), Toks[2].getText());
+ ASSERT_EQ(StringRef(" img"), Toks[2].getText());
ASSERT_EQ(tok::newline, Toks[3].getKind());
}
TEST_F(CommentLexerTest, HTML4) {
const char *Sources[] = {
- "// <tag",
- "// <tag "
+ "// <img",
+ "// <img "
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -859,7 +859,7 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::newline, Toks[2].getKind());
}
@@ -867,7 +867,7 @@
TEST_F(CommentLexerTest, HTML5) {
const char *Source =
- "// <tag 42";
+ "// <img 42";
std::vector<Token> Toks;
@@ -879,7 +879,7 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::text, Toks[2].getKind());
ASSERT_EQ(StringRef("42"), Toks[2].getText());
@@ -888,7 +888,7 @@
}
TEST_F(CommentLexerTest, HTML6) {
- const char *Source = "// <tag> Meow";
+ const char *Source = "// <img> Meow";
std::vector<Token> Toks;
@@ -900,7 +900,7 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_greater, Toks[2].getKind());
@@ -911,7 +911,7 @@
}
TEST_F(CommentLexerTest, HTML7) {
- const char *Source = "// <tag=";
+ const char *Source = "// <img=";
std::vector<Token> Toks;
@@ -923,7 +923,7 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::text, Toks[2].getKind());
ASSERT_EQ(StringRef("="), Toks[2].getText());
@@ -932,7 +932,7 @@
}
TEST_F(CommentLexerTest, HTML8) {
- const char *Source = "// <tag attr=> Meow";
+ const char *Source = "// <img src=> Meow";
std::vector<Token> Toks;
@@ -944,10 +944,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::html_equals, Toks[3].getKind());
@@ -961,8 +961,8 @@
TEST_F(CommentLexerTest, HTML9) {
const char *Sources[] = {
- "// <tag attr",
- "// <tag attr "
+ "// <img src",
+ "// <img src "
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -976,10 +976,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::newline, Toks[3].getKind());
}
@@ -987,8 +987,8 @@
TEST_F(CommentLexerTest, HTML10) {
const char *Sources[] = {
- "// <tag attr=",
- "// <tag attr ="
+ "// <img src=",
+ "// <img src ="
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1002,10 +1002,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::html_equals, Toks[3].getKind());
@@ -1015,10 +1015,10 @@
TEST_F(CommentLexerTest, HTML11) {
const char *Sources[] = {
- "// <tag attr=\"",
- "// <tag attr = \"",
- "// <tag attr=\'",
- "// <tag attr = \'"
+ "// <img src=\"",
+ "// <img src = \"",
+ "// <img src=\'",
+ "// <img src = \'"
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1032,10 +1032,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::html_equals, Toks[3].getKind());
@@ -1047,7 +1047,7 @@
}
TEST_F(CommentLexerTest, HTML12) {
- const char *Source = "// <tag attr=@";
+ const char *Source = "// <img src=@";
std::vector<Token> Toks;
@@ -1059,10 +1059,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::html_equals, Toks[3].getKind());
@@ -1074,10 +1074,10 @@
TEST_F(CommentLexerTest, HTML13) {
const char *Sources[] = {
- "// <tag attr=\"val\\\"\\'val",
- "// <tag attr=\"val\\\"\\'val\"",
- "// <tag attr=\'val\\\"\\'val",
- "// <tag attr=\'val\\\"\\'val\'"
+ "// <img src=\"val\\\"\\'val",
+ "// <img src=\"val\\\"\\'val\"",
+ "// <img src=\'val\\\"\\'val",
+ "// <img src=\'val\\\"\\'val\'"
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1091,10 +1091,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::html_equals, Toks[3].getKind());
@@ -1107,8 +1107,8 @@
TEST_F(CommentLexerTest, HTML14) {
const char *Sources[] = {
- "// <tag attr=\"val\\\"\\'val\">",
- "// <tag attr=\'val\\\"\\'val\'>"
+ "// <img src=\"val\\\"\\'val\">",
+ "// <img src=\'val\\\"\\'val\'>"
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1122,10 +1122,10 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_ident, Toks[2].getKind());
- ASSERT_EQ(StringRef("attr"), Toks[2].getHTMLIdent());
+ ASSERT_EQ(StringRef("src"), Toks[2].getHTMLIdent());
ASSERT_EQ(tok::html_equals, Toks[3].getKind());
@@ -1140,8 +1140,8 @@
TEST_F(CommentLexerTest, HTML15) {
const char *Sources[] = {
- "// <tag/>",
- "// <tag />"
+ "// <img/>",
+ "// <img />"
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1155,7 +1155,7 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::html_slash_greater, Toks[2].getKind());
@@ -1165,8 +1165,8 @@
TEST_F(CommentLexerTest, HTML16) {
const char *Sources[] = {
- "// <tag/ Aaa",
- "// <tag / Aaa"
+ "// <img/ Aaa",
+ "// <img / Aaa"
};
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1180,7 +1180,7 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagStartName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagStartName());
ASSERT_EQ(tok::text, Toks[2].getKind());
ASSERT_EQ(StringRef("/"), Toks[2].getText());
@@ -1201,13 +1201,13 @@
ASSERT_EQ(3U, Toks.size());
- ASSERT_EQ(tok::text, Toks[0].getKind());
- ASSERT_EQ(StringRef(" "), Toks[0].getText());
+ ASSERT_EQ(tok::text, Toks[0].getKind());
+ ASSERT_EQ(StringRef(" "), Toks[0].getText());
- ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef(""), Toks[1].getHTMLTagEndName());
+ ASSERT_EQ(tok::text, Toks[1].getKind());
+ ASSERT_EQ(StringRef("</"), Toks[1].getText());
- ASSERT_EQ(tok::newline, Toks[2].getKind());
+ ASSERT_EQ(tok::newline, Toks[2].getKind());
}
TEST_F(CommentLexerTest, HTML18) {
@@ -1219,20 +1219,20 @@
ASSERT_EQ(4U, Toks.size());
- ASSERT_EQ(tok::text, Toks[0].getKind());
- ASSERT_EQ(StringRef(" "), Toks[0].getText());
+ ASSERT_EQ(tok::text, Toks[0].getKind());
+ ASSERT_EQ(StringRef(" "), Toks[0].getText());
- ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef(""), Toks[1].getHTMLTagEndName());
+ ASSERT_EQ(tok::text, Toks[1].getKind());
+ ASSERT_EQ(StringRef("</"), Toks[1].getText());
- ASSERT_EQ(tok::text, Toks[2].getKind());
- ASSERT_EQ(StringRef("@"), Toks[2].getText());
+ ASSERT_EQ(tok::text, Toks[2].getKind());
+ ASSERT_EQ(StringRef("@"), Toks[2].getText());
- ASSERT_EQ(tok::newline, Toks[3].getKind());
+ ASSERT_EQ(tok::newline, Toks[3].getKind());
}
TEST_F(CommentLexerTest, HTML19) {
- const char *Source = "// </tag";
+ const char *Source = "// </img";
std::vector<Token> Toks;
@@ -1244,35 +1244,51 @@
ASSERT_EQ(StringRef(" "), Toks[0].getText());
ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagEndName());
+ ASSERT_EQ(StringRef("img"), Toks[1].getHTMLTagEndName());
ASSERT_EQ(tok::newline, Toks[2].getKind());
}
-TEST_F(CommentLexerTest, HTML20) {
- const char *Sources[] = {
- "// </tag>",
- "// </ tag>",
- "// </ tag >"
- };
+TEST_F(CommentLexerTest, NotAKnownHTMLTag1) {
+ const char *Source = "// <tag>";
- for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
- std::vector<Token> Toks;
+ std::vector<Token> Toks;
- lexString(Sources[i], Toks);
+ lexString(Source, Toks);
- ASSERT_EQ(4U, Toks.size());
+ ASSERT_EQ(4U, Toks.size());
- ASSERT_EQ(tok::text, Toks[0].getKind());
- ASSERT_EQ(StringRef(" "), Toks[0].getText());
+ ASSERT_EQ(tok::text, Toks[0].getKind());
+ ASSERT_EQ(StringRef(" "), Toks[0].getText());
- ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
- ASSERT_EQ(StringRef("tag"), Toks[1].getHTMLTagEndName());
+ ASSERT_EQ(tok::text, Toks[1].getKind());
+ ASSERT_EQ(StringRef("<tag"), Toks[1].getText());
- ASSERT_EQ(tok::html_greater, Toks[2].getKind());
+ ASSERT_EQ(tok::text, Toks[2].getKind());
+ ASSERT_EQ(StringRef(">"), Toks[2].getText());
- ASSERT_EQ(tok::newline, Toks[3].getKind());
- }
+ ASSERT_EQ(tok::newline, Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, NotAKnownHTMLTag2) {
+ const char *Source = "// </tag>";
+
+ std::vector<Token> Toks;
+
+ lexString(Source, Toks);
+
+ ASSERT_EQ(4U, Toks.size());
+
+ ASSERT_EQ(tok::text, Toks[0].getKind());
+ ASSERT_EQ(StringRef(" "), Toks[0].getText());
+
+ ASSERT_EQ(tok::text, Toks[1].getKind());
+ ASSERT_EQ(StringRef("</tag"), Toks[1].getText());
+
+ ASSERT_EQ(tok::text, Toks[2].getKind());
+ ASSERT_EQ(StringRef(">"), Toks[2].getText());
+
+ ASSERT_EQ(tok::newline, Toks[3].getKind());
}
TEST_F(CommentLexerTest, HTMLCharacterReferences1) {
More information about the cfe-commits
mailing list