libSyntax: several enhancements on source location bridging. (#13956)

libSyntax nodes don't maintain absolute source location on each
individual node. Instead, the absolute locations are calculated on
demand with a given root by accumulating the length of all the other
nodes before the target node. This bridging is important for issuing
diagnostics from libSyntax entities.

With the observation that our current implementation of the source
location calculation has multiple bugs, this patch re-implemented this
bridging by using the newly-added syntax visitor. Also, we moved the function
from RawSyntax to Syntax for better visibility.

To test this source location calculation, we added a new action in
swift-syntax-test. This action parses a given file as a
SourceFileSyntax, calculates the absolute location of the
EOF token in the SourceFileSyntax, and dump the buffer from the start
of the input file to the absolute location of the EOF. Finally, we compare
the dump with the original input to ensure they are identical.
This commit is contained in:
Xi Ge
2018-01-15 16:39:17 -08:00
committed by GitHub
parent 28d84eada3
commit 031488bada
9 changed files with 101 additions and 47 deletions

View File

@@ -44,6 +44,7 @@ enum class ActionType {
FullParseRoundTrip,
SerializeRawTree,
ParserGen,
EOFPos,
None
};
@@ -72,7 +73,12 @@ Action(llvm::cl::desc("Action (required):"),
clEnumValN(ActionType::SerializeRawTree,
"serialize-raw-tree",
"Parse the source file and serialize the raw tree"
"to JSON")));
"to JSON"),
clEnumValN(ActionType::EOFPos,
"eof",
"Parse the source file, calculate the absolute position"
"of the EOF token, and dump the buffer from the start of the"
"file to the EOF token")));
static llvm::cl::opt<std::string>
InputSourceFilename("input-source-filename",
@@ -239,6 +245,21 @@ int dumpParserGen(const char *MainExecutablePath,
return 0;
}
int dumpEOFSourceLoc(const char *MainExecutablePath,
const StringRef InputFileName) {
CompilerInstance Instance;
SourceFile *SF = getSourceFile(Instance, InputFileName, MainExecutablePath);
auto BufferId = *SF->getBufferID();
SyntaxPrintOptions Opts;
auto Root = SF->getSyntaxRoot();
auto Offset = Root.getEOFToken().getAbsolutePosition(Root).getOffset();
SourceManager &SourceMgr = SF->getASTContext().SourceMgr;
auto StartLoc = SourceMgr.getLocForBufferStart(BufferId);
auto EndLoc = SourceMgr.getLocForOffset(BufferId, Offset);
llvm::outs() << CharSourceRange(SourceMgr, StartLoc, EndLoc).str();
return 0;
}
}// end of anonymous namespace
int main(int argc, char *argv[]) {
@@ -272,6 +293,9 @@ int main(int argc, char *argv[]) {
case ActionType::ParserGen:
ExitCode = dumpParserGen(argv[0], options::InputSourceFilename);
break;
case ActionType::EOFPos:
ExitCode = dumpEOFSourceLoc(argv[0], options::InputSourceFilename);
break;
case ActionType::None:
llvm::errs() << "an action is required\n";
llvm::cl::PrintHelpMessage();