summaryrefslogtreecommitdiff
path: root/source/compiler-core/slang-diagnostic-sink.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-06-07 14:10:49 -0700
committerGitHub <noreply@github.com>2022-06-07 14:10:49 -0700
commit0c64995ea28febcc7d38e1519da8d93391ce2e7d (patch)
tree8696ab86b29caf80c3ebbd205c700e24b8c20bf3 /source/compiler-core/slang-diagnostic-sink.cpp
parent8c4a15c522861d2f30eacc9cd2b03ad793018639 (diff)
Major language server features. (#2264)
* Major language server features. * Include slangd in binary release. * Fix compiler issues. * Fix compiler error. * Completion resolve. * Various improvements. * Update diagnostic test expected output. * Bug fix for source locations. * Adjust diagnostic update frequency. * Update github actions to store artifacts. * Fix infinite parser loop. * Fix parser recovery. * Fix parser recovery. * Update test. * Fix test. * Disable IR gen for language server. * Allow commit characters in auto completion. * Fix lookup for invoke exprs. * More parser robustness fixes. * update solution file Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/compiler-core/slang-diagnostic-sink.cpp')
-rw-r--r--source/compiler-core/slang-diagnostic-sink.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/source/compiler-core/slang-diagnostic-sink.cpp b/source/compiler-core/slang-diagnostic-sink.cpp
index 314ec1c2c..0110b16d7 100644
--- a/source/compiler-core/slang-diagnostic-sink.cpp
+++ b/source/compiler-core/slang-diagnostic-sink.cpp
@@ -138,6 +138,10 @@ static void formatDiagnostic(const HumaneSourceLoc& humaneLoc, Diagnostic const&
outBuilder << humaneLoc.pathInfo.foundPath;
outBuilder << "(";
outBuilder << Int32(humaneLoc.line);
+ if (flags & DiagnosticSink::Flag::LanguageServer)
+ {
+ outBuilder << ", " << humaneLoc.column;
+ }
outBuilder << "): ";
}
@@ -348,6 +352,47 @@ static void _sourceLocationNoteDiagnostic(DiagnosticSink* sink, SourceView* sour
sb << caretLine << "\n";
}
+// Output the length of the token at `sourceLoc`. This is used by language server.
+static void _tokenLengthNoteDiagnostic(
+ DiagnosticSink* sink, SourceView* sourceView, SourceLoc sourceLoc, StringBuilder& sb)
+{
+ SourceFile* sourceFile = sourceView->getSourceFile();
+ if (!sourceFile)
+ {
+ return;
+ }
+
+ UnownedStringSlice content = sourceFile->getContent();
+
+ // Make sure the offset is within content.
+ // This is important because it's possible to have a 'SourceFile' that doesn't contain any
+ // content (for example when reconstructed via serialization with just line offsets, the actual
+ // source text 'content' isn't available).
+ const int offset = sourceView->getRange().getOffset(sourceLoc);
+ if (offset < 0 || offset >= content.getLength())
+ {
+ return;
+ }
+
+ // Work out the position of the SourceLoc in the source
+ const char* const pos = content.begin() + offset;
+
+ UnownedStringSlice line = _extractLineContainingPosition(content, pos);
+
+ // Trim any trailing white space
+ line = UnownedStringSlice(line.begin(), line.trim().end());
+
+ auto lexer = sink->getSourceLocationLexer();
+ if (lexer)
+ {
+ UnownedStringSlice token = lexer(UnownedStringSlice(pos, line.end()));
+
+ if (token.getLength() > 1)
+ {
+ sb << "^+" << token.getLength() << "\n";
+ }
+ }
+}
static void formatDiagnostic(
DiagnosticSink* sink,
@@ -365,6 +410,7 @@ static void formatDiagnostic(
{
humaneLoc = sourceView->getHumaneLoc(sourceLoc);
}
+
formatDiagnostic(humaneLoc, diagnostic, sink->getFlags(), sb);
{
@@ -404,6 +450,12 @@ static void formatDiagnostic(
}
}
+ // If we are a language server, output additional token length info.
+ if (sourceView && sink->isFlagSet(DiagnosticSink::Flag::LanguageServer))
+ {
+ _tokenLengthNoteDiagnostic(sink, sourceView, sourceLoc, sb);
+ }
+
// We don't don't output source line information if this is a 'note' as a note is extra information for one
// of the other main severity types, and so the information should already be output on the initial line
if (sourceView && sink->isFlagSet(DiagnosticSink::Flag::SourceLocationLine) && diagnostic.severity != Severity::Note)