[TableGen:LSP] Resolve "go-to-def" on a let field to the base definition

This allows for go-to-def on the a `let` field to resolve to the definition
of the base class. This is kind of like how C++ works with go-to-def
from use->def->decl, with the decl in this case being the base definition
of the field.

Differential Revision: https://reviews.llvm.org/D134264
This commit is contained in:
River Riddle 2022-09-20 01:45:17 -07:00
parent 3e2ad37679
commit 99e24123e9
5 changed files with 25 additions and 11 deletions

View File

@ -109,6 +109,11 @@ Optional<std::string> lsp::extractSourceDocComment(llvm::SourceMgr &sourceMgr,
return llvm::join(llvm::reverse(commentLines), "\n");
}
bool lsp::contains(SMRange range, SMLoc loc) {
return range.Start.getPointer() <= loc.getPointer() &&
loc.getPointer() < range.End.getPointer();
}
//===----------------------------------------------------------------------===//
// SourceMgrInclude
//===----------------------------------------------------------------------===//

View File

@ -33,6 +33,11 @@ SMRange convertTokenLocToRange(SMLoc loc);
Optional<std::string> extractSourceDocComment(llvm::SourceMgr &sourceMgr,
SMLoc loc);
/// Returns true if the given range contains the given source location. Note
/// that this has different behavior than SMRange because it is inclusive of the
/// end location.
bool contains(SMRange range, SMLoc loc);
//===----------------------------------------------------------------------===//
// SourceMgrInclude
//===----------------------------------------------------------------------===//

View File

@ -62,14 +62,6 @@ static lsp::Location getLocationFromLoc(llvm::SourceMgr &mgr, SMRange range,
return lsp::Location(getURIFromLoc(mgr, range, uri), lsp::Range(mgr, range));
}
/// Returns true if the given range contains the given source location. Note
/// that this has different behavior than SMRange because it is inclusive of the
/// end location.
static bool contains(SMRange range, SMLoc loc) {
return range.Start.getPointer() <= loc.getPointer() &&
loc.getPointer() <= range.End.getPointer();
}
/// Convert the given MLIR diagnostic to the LSP form.
static Optional<lsp::Diagnostic>
getLspDiagnoticFromDiag(llvm::SourceMgr &sourceMgr, const ast::Diagnostic &diag,
@ -1188,7 +1180,8 @@ void PDLDocument::getInlayHints(const lsp::URIForFile &uri,
SMRange loc = node->getLoc();
// Check that the location of this node is within the input range.
if (!contains(rangeLoc, loc.Start) && !contains(rangeLoc, loc.End))
if (!lsp::contains(rangeLoc, loc.Start) &&
!lsp::contains(rangeLoc, loc.End))
return;
// Handle hints for various types of nodes.

View File

@ -471,6 +471,17 @@ void TableGenTextFile::getLocationsOf(const lsp::URIForFile &uri,
if (!symbol)
return;
// If this symbol is a record value and the def position is already the def of
// the symbol, check to see if the value has a base definition. This allows
// for a "go-to-def" on a "let" to resolve the definition in the base class.
auto *valSym = dyn_cast<TableGenRecordValSymbol>(symbol);
if (valSym && lsp::contains(valSym->defLoc, posLoc)) {
if (auto *val = getBaseValue(valSym->record, valSym->getValue()).second) {
locations.push_back(getLocationFromLoc(sourceMgr, val->getLoc(), uri));
return;
}
}
locations.push_back(getLocationFromLoc(sourceMgr, symbol->defLoc, uri));
}

View File

@ -40,11 +40,11 @@
// CHECK-NEXT: "range": {
// CHECK-NEXT: "end": {
// CHECK-NEXT: "character": 12,
// CHECK-NEXT: "line": 4
// CHECK-NEXT: "line": 1
// CHECK-NEXT: },
// CHECK-NEXT: "start": {
// CHECK-NEXT: "character": 6,
// CHECK-NEXT: "line": 4
// CHECK-NEXT: "line": 1
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "uri": "{{.*}}/foo.td"