libSyntax: when printing syntax tree with kind, optionally give syntax kind a visual highlight.

This commit is contained in:
Xi Ge
2017-10-21 15:47:16 -07:00
parent b245061874
commit e4e486edea
3 changed files with 24 additions and 6 deletions

View File

@@ -186,6 +186,7 @@ enum class SourcePresence {
/// The print option to specify when printing a raw syntax node. /// The print option to specify when printing a raw syntax node.
struct SyntaxPrintOptions { struct SyntaxPrintOptions {
bool Visual = false;
bool PrintSyntaxKind = false; bool PrintSyntaxKind = false;
}; };

View File

@@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "swift/Basic/ColorUtils.h"
#include "swift/Syntax/RawSyntax.h" #include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/TokenSyntax.h" #include "swift/Syntax/TokenSyntax.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
@@ -33,14 +34,26 @@ static bool isTrivialSyntaxKind(SyntaxKind Kind) {
return false; return false;
} }
} }
static void printSyntaxKind(SyntaxKind Kind, llvm::raw_ostream &OS,
SyntaxPrintOptions Opts, bool Open) {
std::unique_ptr<swift::OSColor> Color;
if (Opts.Visual) {
Color.reset(new swift::OSColor(OS, llvm::raw_ostream::GREEN));
}
OS << "<";
if (!Open)
OS << "/";
dumpSyntaxKind(OS, Kind);
OS << ">";
}
} // end of anonymous namespace } // end of anonymous namespace
void RawSyntax::print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const { void RawSyntax::print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const {
const bool PrintKind = Opts.PrintSyntaxKind && !isToken() && const bool PrintKind = Opts.PrintSyntaxKind && !isToken() &&
!isTrivialSyntaxKind(Kind); !isTrivialSyntaxKind(Kind);
if (PrintKind) { if (PrintKind) {
OS << "<"; printSyntaxKind(Kind, OS, Opts, true);
dumpSyntaxKind(OS, Kind);
OS << ">";
} }
if (const auto Tok = dyn_cast<RawTokenSyntax>(this)) { if (const auto Tok = dyn_cast<RawTokenSyntax>(this)) {
@@ -51,9 +64,7 @@ void RawSyntax::print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const {
LE->print(OS, Opts); LE->print(OS, Opts);
} }
if (PrintKind) { if (PrintKind) {
OS << "</"; printSyntaxKind(Kind, OS, Opts, false);
dumpSyntaxKind(OS, Kind);
OS << ">";
} }
} }

View File

@@ -84,6 +84,11 @@ PrintNodeKind("print-node-kind",
llvm::cl::desc("To print syntax node kind"), llvm::cl::desc("To print syntax node kind"),
llvm::cl::cat(Category), llvm::cl::cat(Category),
llvm::cl::init(false)); llvm::cl::init(false));
static llvm::cl::opt<bool>
Visual("v",
llvm::cl::desc("Print visually"),
llvm::cl::cat(Category),
llvm::cl::init(false));
} // end namespace options } // end namespace options
namespace { namespace {
@@ -283,6 +288,7 @@ int dumpParserGen(const char *MainExecutablePath,
SourceFile *SF = getSourceFile(Instance, InputFileName, MainExecutablePath); SourceFile *SF = getSourceFile(Instance, InputFileName, MainExecutablePath);
SyntaxPrintOptions Opts; SyntaxPrintOptions Opts;
Opts.PrintSyntaxKind = options::PrintNodeKind; Opts.PrintSyntaxKind = options::PrintNodeKind;
Opts.Visual = options::Visual;
SF->getSyntaxRoot().print(llvm::outs(), Opts); SF->getSyntaxRoot().print(llvm::outs(), Opts);
return 0; return 0;
} }