split syntax highlighting of macros from keywords and comments,
allowing us to use a cheaper means to highlight keywords and making it so that comments won't foul up macro expansions. Start highlighting macro expansions. llvm-svn: 49779
This commit is contained in:
parent
060d8aa2ed
commit
a5a75e7a10
|
@ -61,8 +61,10 @@ HTMLPrinter::~HTMLPrinter() {
|
||||||
|
|
||||||
// If we have a preprocessor, relex the file and syntax hilight. We might not
|
// If we have a preprocessor, relex the file and syntax hilight. We might not
|
||||||
// have a preprocessor if we come from a deserialized AST file, for example.
|
// have a preprocessor if we come from a deserialized AST file, for example.
|
||||||
if (PP)
|
if (PP) {
|
||||||
html::SyntaxHighlight(R, FileID, *PP);
|
html::SyntaxHighlight(R, FileID, *PP);
|
||||||
|
html::HighlightMacros(R, FileID, *PP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Open the output.
|
// Open the output.
|
||||||
|
|
|
@ -45,11 +45,16 @@ namespace html {
|
||||||
void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID);
|
void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID);
|
||||||
|
|
||||||
/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
|
/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
|
||||||
/// information about keywords, macro expansions etc. This uses the macro
|
/// information about keywords, comments, etc.
|
||||||
/// table state from the end of the file, so it won't be perfectly perfect,
|
|
||||||
/// but it will be reasonably close.
|
|
||||||
void SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP);
|
void SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP);
|
||||||
|
|
||||||
|
/// HighlightMacros - This uses the macro table state from the end of the
|
||||||
|
/// file, to reexpand macros and insert (into the HTML) information about the
|
||||||
|
/// macro expansions. This won't be perfectly perfect, but it will be
|
||||||
|
/// reasonably close.
|
||||||
|
void HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor &PP);
|
||||||
|
|
||||||
|
|
||||||
} // end html namespace
|
} // end html namespace
|
||||||
} // end clang namespace
|
} // end clang namespace
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,8 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, unsigned FileID) {
|
||||||
" .code { border-spacing:0px; width:100%; }\n"
|
" .code { border-spacing:0px; width:100%; }\n"
|
||||||
" .code { font-family: \"Andale Mono\", monospace; font-size:10pt }\n"
|
" .code { font-family: \"Andale Mono\", monospace; font-size:10pt }\n"
|
||||||
" .code { line-height: 1.2em }\n"
|
" .code { line-height: 1.2em }\n"
|
||||||
" .comment { color:#A0A0A0 }\n"
|
" .comment { color: #A0A0A0 }\n"
|
||||||
|
" .macro { color: #FF0000; background-color:#FFC0C0 }\n"
|
||||||
" .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
|
" .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
|
||||||
" .num { text-align:right; font-size: smaller }\n"
|
" .num { text-align:right; font-size: smaller }\n"
|
||||||
" .num { color:#444444 }\n"
|
" .num { color:#444444 }\n"
|
||||||
|
@ -232,11 +233,12 @@ void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
|
||||||
// Start parsing the specified input file.
|
// Start parsing the specified input file.
|
||||||
PP.EnterMainSourceFile();
|
PP.EnterMainSourceFile();
|
||||||
|
|
||||||
// Lex all the tokens.
|
// Lex all the tokens in raw mode, to avoid entering #includes or expanding
|
||||||
|
// macros.
|
||||||
const SourceManager &SourceMgr = PP.getSourceManager();
|
const SourceManager &SourceMgr = PP.getSourceManager();
|
||||||
Token Tok;
|
Token Tok;
|
||||||
do {
|
do {
|
||||||
PP.Lex(Tok);
|
PP.LexUnexpandedToken(Tok);
|
||||||
// Ignore tokens whose logical location was not the main file.
|
// Ignore tokens whose logical location was not the main file.
|
||||||
SourceLocation LLoc = SourceMgr.getLogicalLoc(Tok.getLocation());
|
SourceLocation LLoc = SourceMgr.getLogicalLoc(Tok.getLocation());
|
||||||
std::pair<unsigned, unsigned> LLocInfo =
|
std::pair<unsigned, unsigned> LLocInfo =
|
||||||
|
@ -249,6 +251,8 @@ void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
|
||||||
unsigned TokLen = Tok.getLength();
|
unsigned TokLen = Tok.getLength();
|
||||||
switch (Tok.getKind()) {
|
switch (Tok.getKind()) {
|
||||||
default: break;
|
default: break;
|
||||||
|
// FIXME: Add keywords here.
|
||||||
|
|
||||||
case tok::comment:
|
case tok::comment:
|
||||||
RB.InsertTextAfter(TokOffs, "<span class='comment'>",
|
RB.InsertTextAfter(TokOffs, "<span class='comment'>",
|
||||||
strlen("<span class='comment'>"));
|
strlen("<span class='comment'>"));
|
||||||
|
@ -257,4 +261,66 @@ void html::SyntaxHighlight(Rewriter &R, unsigned FileID, Preprocessor &PP) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (Tok.isNot(tok::eof));
|
} while (Tok.isNot(tok::eof));
|
||||||
|
PP.SetCommentRetentionState(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HighlightMacros - This uses the macro table state from the end of the
|
||||||
|
/// file, to reexpand macros and insert (into the HTML) information about the
|
||||||
|
/// macro expansions. This won't be perfectly perfect, but it will be
|
||||||
|
/// reasonably close.
|
||||||
|
void html::HighlightMacros(Rewriter &R, unsigned FileID, Preprocessor &PP) {
|
||||||
|
RewriteBuffer &RB = R.getEditBuffer(FileID);
|
||||||
|
|
||||||
|
// Inform the preprocessor that we don't want comments.
|
||||||
|
PP.SetCommentRetentionState(false, false);
|
||||||
|
|
||||||
|
// Start parsing the specified input file.
|
||||||
|
PP.EnterMainSourceFile();
|
||||||
|
|
||||||
|
// Lex all the tokens.
|
||||||
|
const SourceManager &SourceMgr = PP.getSourceManager();
|
||||||
|
Token Tok;
|
||||||
|
PP.Lex(Tok);
|
||||||
|
while (Tok.isNot(tok::eof)) {
|
||||||
|
// Ignore non-macro tokens.
|
||||||
|
if (!Tok.getLocation().isMacroID()) {
|
||||||
|
PP.Lex(Tok);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore tokens whose logical location was not the main file.
|
||||||
|
SourceLocation LLoc = SourceMgr.getLogicalLoc(Tok.getLocation());
|
||||||
|
std::pair<unsigned, unsigned> LLocInfo =
|
||||||
|
SourceMgr.getDecomposedFileLoc(LLoc);
|
||||||
|
|
||||||
|
if (LLocInfo.first != FileID) {
|
||||||
|
PP.Lex(Tok);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay, we have the first token of a macro expansion: highlight the
|
||||||
|
// instantiation.
|
||||||
|
|
||||||
|
// Get the size of current macro call itself.
|
||||||
|
// FIXME: This should highlight the args of a function-like
|
||||||
|
// macro, using a heuristic.
|
||||||
|
unsigned TokLen = Lexer::MeasureTokenLength(LLoc, SourceMgr);
|
||||||
|
|
||||||
|
unsigned TokOffs = LLocInfo.second;
|
||||||
|
RB.InsertTextAfter(TokOffs, "<span class='macro'>",
|
||||||
|
strlen("<span class='macro'>"));
|
||||||
|
RB.InsertTextBefore(TokOffs+TokLen, "</span>", strlen("</span>"));
|
||||||
|
|
||||||
|
// Okay, eat this token, getting the next one.
|
||||||
|
PP.Lex(Tok);
|
||||||
|
|
||||||
|
// Skip all the rest of the tokens that are part of this macro
|
||||||
|
// instantiation. It would be really nice to pop up a window with all the
|
||||||
|
// spelling of the tokens or something.
|
||||||
|
while (!Tok.is(tok::eof) &&
|
||||||
|
SourceMgr.getLogicalLoc(Tok.getLocation()) == LLoc)
|
||||||
|
PP.Lex(Tok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue