Skip to content
This repository has been archived by the owner on Jan 13, 2024. It is now read-only.

Commit

Permalink
Allow customization of location dumping in ESTreeJSONDumper.
Browse files Browse the repository at this point in the history
Summary:
There are use cases for which we don't want to dump both "loc" and "range"
in the AST.
Allow this by making the API more flexible and introducing a LocationDumpMode.

Reviewed By: tmikov

Differential Revision: D23810725

fbshipit-source-id: 595920cd7113469e5b8111717a769df1ea1c09b5
  • Loading branch information
avp authored and facebook-github-bot committed Oct 6, 2020
1 parent dd542ec commit c3876bb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 33 deletions.
16 changes: 14 additions & 2 deletions include/hermes/AST/ESTreeJSONDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ enum class ESTreeDumpMode {
DumpAll,
};

/// Specifies which location information should be dumped by ESTreeJSONDumper.
enum class LocationDumpMode {
/// Only output locations: line and column.
Loc,
/// Only output byte ranges.
Range,
/// Output both locations and byte ranges.
LocAndRange,
};

/// Print out the contents of the given tree to \p os.
/// \p pretty for pretty print the JSON.
/// When \p sm is not null, print the source locations for the AST nodes.
Expand All @@ -33,7 +43,8 @@ void dumpESTreeJSON(
ESTree::NodePtr rootNode,
bool pretty,
ESTreeDumpMode mode,
SourceErrorManager *sm = nullptr);
SourceErrorManager *sm = nullptr,
LocationDumpMode locMode = LocationDumpMode::LocAndRange);

/// Print out the contents of \p rootNode to \p json.
/// Does not call json.endJSONL(), caller should do that if necessary.
Expand All @@ -42,7 +53,8 @@ void dumpESTreeJSON(
JSONEmitter &json,
ESTree::NodePtr rootNode,
ESTreeDumpMode mode,
SourceErrorManager *sm = nullptr);
SourceErrorManager *sm = nullptr,
LocationDumpMode locMode = LocationDumpMode::LocAndRange);

} // namespace hermes

Expand Down
72 changes: 41 additions & 31 deletions lib/AST/ESTreeJSONDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ESTreeJSONDumper {
JSONEmitter &json_;
SourceErrorManager *sm_{nullptr};
ESTreeDumpMode mode_;
LocationDumpMode locMode_;

/// A collection of fields to ignore if they are empty (null or []).
/// Mapping from node name to a set of ignored field names for that node.
Expand All @@ -31,8 +32,9 @@ class ESTreeJSONDumper {
explicit ESTreeJSONDumper(
JSONEmitter &json,
SourceErrorManager *sm,
ESTreeDumpMode mode)
: json_(json), sm_(sm), mode_(mode) {
ESTreeDumpMode mode,
LocationDumpMode locMode)
: json_(json), sm_(sm), mode_(mode), locMode_(locMode) {
#define ESTREE_NODE_0_ARGS(NAME, ...)
#define ESTREE_NODE_1_ARGS(NAME, ...)
#define ESTREE_NODE_2_ARGS(NAME, ...)
Expand Down Expand Up @@ -62,32 +64,38 @@ class ESTreeJSONDumper {
!sm_->findBufferLineAndLoc(rng.End, end))
return;

json_.emitKey("loc");
json_.openDict();
json_.emitKey("start");
json_.openDict();
json_.emitKeyValue("line", start.line);
json_.emitKeyValue("column", start.col);
json_.closeDict();
json_.emitKey("end");
json_.openDict();
json_.emitKeyValue("line", end.line);
json_.emitKeyValue("column", end.col);
json_.closeDict();
json_.closeDict();
if (locMode_ == LocationDumpMode::Loc ||
locMode_ == LocationDumpMode::LocAndRange) {
json_.emitKey("loc");
json_.openDict();
json_.emitKey("start");
json_.openDict();
json_.emitKeyValue("line", start.line);
json_.emitKeyValue("column", start.col);
json_.closeDict();
json_.emitKey("end");
json_.openDict();
json_.emitKeyValue("line", end.line);
json_.emitKeyValue("column", end.col);
json_.closeDict();
json_.closeDict();
}

const llvh::MemoryBuffer *buffer = sm_->findBufferForLoc(rng.Start);
assert(buffer && "The buffer must exist");
const char *bufStart = buffer->getBufferStart();
assert(
rng.Start.getPointer() >= bufStart &&
rng.End.getPointer() <= buffer->getBufferEnd() &&
"The range must be within the buffer");
json_.emitKey("range");
json_.openArray();
json_.emitValues(
{rng.Start.getPointer() - bufStart, rng.End.getPointer() - bufStart});
json_.closeArray();
if (locMode_ == LocationDumpMode::Range ||
locMode_ == LocationDumpMode::LocAndRange) {
const llvh::MemoryBuffer *buffer = sm_->findBufferForLoc(rng.Start);
assert(buffer && "The buffer must exist");
const char *bufStart = buffer->getBufferStart();
assert(
rng.Start.getPointer() >= bufStart &&
rng.End.getPointer() <= buffer->getBufferEnd() &&
"The range must be within the buffer");
json_.emitKey("range");
json_.openArray();
json_.emitValues(
{rng.Start.getPointer() - bufStart, rng.End.getPointer() - bufStart});
json_.closeArray();
}
}

void visit(Node *node, StringRef type) {
Expand Down Expand Up @@ -427,18 +435,20 @@ void dumpESTreeJSON(
NodePtr rootNode,
bool pretty,
ESTreeDumpMode mode,
SourceErrorManager *sm) {
SourceErrorManager *sm,
LocationDumpMode locMode) {
JSONEmitter json{os, pretty};
ESTreeJSONDumper(json, sm, mode).doIt(rootNode);
ESTreeJSONDumper(json, sm, mode, locMode).doIt(rootNode);
json.endJSONL();
}

void dumpESTreeJSON(
JSONEmitter &json,
NodePtr rootNode,
ESTreeDumpMode mode,
SourceErrorManager *sm) {
ESTreeJSONDumper(json, sm, mode).doIt(rootNode);
SourceErrorManager *sm,
LocationDumpMode locMode) {
ESTreeJSONDumper(json, sm, mode, locMode).doIt(rootNode);
}

} // namespace hermes

0 comments on commit c3876bb

Please sign in to comment.