Add support for dumping AST comment nodes to JSON.

llvm-svn: 361265
This commit is contained in:
Aaron Ballman 2019-05-21 14:38:29 +00:00
parent 6c0531222a
commit 86abee8185
4 changed files with 1670 additions and 6 deletions

View File

@ -111,6 +111,8 @@ public:
// information presented is correct.
class JSONNodeDumper
: public ConstAttrVisitor<JSONNodeDumper>,
public comments::ConstCommentVisitor<JSONNodeDumper, void,
const comments::FullComment *>,
public ConstTemplateArgumentVisitor<JSONNodeDumper>,
public ConstStmtVisitor<JSONNodeDumper>,
public TypeVisitor<JSONNodeDumper>,
@ -120,8 +122,12 @@ class JSONNodeDumper
const SourceManager &SM;
PrintingPolicy PrintPolicy;
const comments::CommandTraits *Traits;
using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>;
using InnerCommentVisitor =
comments::ConstCommentVisitor<JSONNodeDumper, void,
const comments::FullComment *>;
using InnerTemplateArgVisitor = ConstTemplateArgumentVisitor<JSONNodeDumper>;
using InnerStmtVisitor = ConstStmtVisitor<JSONNodeDumper>;
using InnerTypeVisitor = TypeVisitor<JSONNodeDumper>;
@ -163,10 +169,14 @@ class JSONNodeDumper
}
void addPreviousDeclaration(const Decl *D);
StringRef getCommentCommandName(unsigned CommandID) const;
public:
JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr,
const PrintingPolicy &PrintPolicy)
: NodeStreamer(OS), SM(SrcMgr), PrintPolicy(PrintPolicy) {}
const PrintingPolicy &PrintPolicy,
const comments::CommandTraits *Traits)
: NodeStreamer(OS), SM(SrcMgr), PrintPolicy(PrintPolicy), Traits(Traits) {
}
void Visit(const Attr *A);
void Visit(const Stmt *Node);
@ -237,6 +247,28 @@ public:
void VisitLabelStmt(const LabelStmt *LS);
void VisitGotoStmt(const GotoStmt *GS);
void VisitWhileStmt(const WhileStmt *WS);
void visitTextComment(const comments::TextComment *C,
const comments::FullComment *);
void visitInlineCommandComment(const comments::InlineCommandComment *C,
const comments::FullComment *);
void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
const comments::FullComment *);
void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
const comments::FullComment *);
void visitBlockCommandComment(const comments::BlockCommandComment *C,
const comments::FullComment *);
void visitParamCommandComment(const comments::ParamCommandComment *C,
const comments::FullComment *FC);
void visitTParamCommandComment(const comments::TParamCommandComment *C,
const comments::FullComment *FC);
void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
const comments::FullComment *);
void
visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
const comments::FullComment *);
void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
const comments::FullComment *);
};
class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
@ -314,8 +346,9 @@ class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
public:
JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr,
const PrintingPolicy &PrintPolicy)
: NodeDumper(OS, SrcMgr, PrintPolicy) {}
const PrintingPolicy &PrintPolicy,
const comments::CommandTraits *Traits)
: NodeDumper(OS, SrcMgr, PrintPolicy, Traits) {}
JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; }

View File

@ -184,7 +184,8 @@ LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
const SourceManager &SM = Ctx.getSourceManager();
if (ADOF_JSON == Format) {
JSONDumper P(OS, SM, Ctx.getPrintingPolicy());
JSONDumper P(OS, SM, Ctx.getPrintingPolicy(),
&Ctx.getCommentCommandTraits());
(void)Deserialize; // FIXME?
P.Visit(this);
} else {

View File

@ -111,7 +111,17 @@ void JSONNodeDumper::Visit(const Decl *D) {
}
void JSONNodeDumper::Visit(const comments::Comment *C,
const comments::FullComment *FC) {}
const comments::FullComment *FC) {
if (!C)
return;
JOS.attribute("id", createPointerRepresentation(C));
JOS.attribute("kind", C->getCommentKindName());
JOS.attribute("loc", createSourceLocation(C->getLocation()));
JOS.attribute("range", createSourceRange(C->getSourceRange()));
InnerCommentVisitor::visit(C, FC);
}
void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
const Decl *From, StringRef Label) {
@ -803,3 +813,131 @@ void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {
void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {
attributeOnlyIfTrue("hasVar", WS->hasVarStorage());
}
StringRef JSONNodeDumper::getCommentCommandName(unsigned CommandID) const {
if (Traits)
return Traits->getCommandInfo(CommandID)->Name;
if (const comments::CommandInfo *Info =
comments::CommandTraits::getBuiltinCommandInfo(CommandID))
return Info->Name;
return "<invalid>";
}
void JSONNodeDumper::visitTextComment(const comments::TextComment *C,
const comments::FullComment *) {
JOS.attribute("text", C->getText());
}
void JSONNodeDumper::visitInlineCommandComment(
const comments::InlineCommandComment *C, const comments::FullComment *) {
JOS.attribute("name", getCommentCommandName(C->getCommandID()));
switch (C->getRenderKind()) {
case comments::InlineCommandComment::RenderNormal:
JOS.attribute("renderKind", "normal");
break;
case comments::InlineCommandComment::RenderBold:
JOS.attribute("renderKind", "bold");
break;
case comments::InlineCommandComment::RenderEmphasized:
JOS.attribute("renderKind", "emphasized");
break;
case comments::InlineCommandComment::RenderMonospaced:
JOS.attribute("renderKind", "monospaced");
break;
}
llvm::json::Array Args;
for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
Args.push_back(C->getArgText(I));
if (!Args.empty())
JOS.attribute("args", std::move(Args));
}
void JSONNodeDumper::visitHTMLStartTagComment(
const comments::HTMLStartTagComment *C, const comments::FullComment *) {
JOS.attribute("name", C->getTagName());
attributeOnlyIfTrue("selfClosing", C->isSelfClosing());
attributeOnlyIfTrue("malformed", C->isMalformed());
llvm::json::Array Attrs;
for (unsigned I = 0, E = C->getNumAttrs(); I < E; ++I)
Attrs.push_back(
{{"name", C->getAttr(I).Name}, {"value", C->getAttr(I).Value}});
if (!Attrs.empty())
JOS.attribute("attrs", std::move(Attrs));
}
void JSONNodeDumper::visitHTMLEndTagComment(
const comments::HTMLEndTagComment *C, const comments::FullComment *) {
JOS.attribute("name", C->getTagName());
}
void JSONNodeDumper::visitBlockCommandComment(
const comments::BlockCommandComment *C, const comments::FullComment *) {
JOS.attribute("name", getCommentCommandName(C->getCommandID()));
llvm::json::Array Args;
for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
Args.push_back(C->getArgText(I));
if (!Args.empty())
JOS.attribute("args", std::move(Args));
}
void JSONNodeDumper::visitParamCommandComment(
const comments::ParamCommandComment *C, const comments::FullComment *FC) {
switch (C->getDirection()) {
case comments::ParamCommandComment::In:
JOS.attribute("direction", "in");
break;
case comments::ParamCommandComment::Out:
JOS.attribute("direction", "out");
break;
case comments::ParamCommandComment::InOut:
JOS.attribute("direction", "in,out");
break;
}
attributeOnlyIfTrue("explicit", C->isDirectionExplicit());
if (C->hasParamName())
JOS.attribute("param", C->isParamIndexValid() ? C->getParamName(FC)
: C->getParamNameAsWritten());
if (C->isParamIndexValid() && !C->isVarArgParam())
JOS.attribute("paramIdx", C->getParamIndex());
}
void JSONNodeDumper::visitTParamCommandComment(
const comments::TParamCommandComment *C, const comments::FullComment *FC) {
if (C->hasParamName())
JOS.attribute("param", C->isPositionValid() ? C->getParamName(FC)
: C->getParamNameAsWritten());
if (C->isPositionValid()) {
llvm::json::Array Positions;
for (unsigned I = 0, E = C->getDepth(); I < E; ++I)
Positions.push_back(C->getIndex(I));
if (!Positions.empty())
JOS.attribute("positions", std::move(Positions));
}
}
void JSONNodeDumper::visitVerbatimBlockComment(
const comments::VerbatimBlockComment *C, const comments::FullComment *) {
JOS.attribute("name", getCommentCommandName(C->getCommandID()));
JOS.attribute("closeName", C->getCloseName());
}
void JSONNodeDumper::visitVerbatimBlockLineComment(
const comments::VerbatimBlockLineComment *C,
const comments::FullComment *) {
JOS.attribute("text", C->getText());
}
void JSONNodeDumper::visitVerbatimLineComment(
const comments::VerbatimLineComment *C, const comments::FullComment *) {
JOS.attribute("text", C->getText());
}

File diff suppressed because it is too large Load Diff