Skip to content

Commit ff7ce85

Browse files
committed
better support for goto definition
1 parent 0dee315 commit ff7ce85

File tree

5 files changed

+120
-16
lines changed

5 files changed

+120
-16
lines changed

lib/dialect/src/Interfaces.td

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,27 @@ def TypeDeclarer : RLC_Interface<"TypeDeclarer"> {
6666
];
6767
}
6868

69+
def DefinitionUser : RLC_Interface<"DefinitionUser"> {
70+
let description = [{
71+
A element of the AST where the user refers to some other element.
72+
example
73+
some_function(x, y, z) refers to some_function, x, y, and z
74+
}];
75+
76+
let methods = [
77+
InterfaceMethod<
78+
"the used operations",
79+
"llvm::SmallVector<mlir::Operation*, 2>", "getUsedOperations",
80+
(ins)
81+
>,
82+
InterfaceMethod<
83+
"the used operations",
84+
"llvm::SmallVector<mlir::Type, 2>", "getUsedTypes",
85+
(ins)
86+
>,
87+
];
88+
}
89+
6990
def TypeUser : RLC_Interface<"TypeUser"> {
7091
let description = [{
7192
A element of the AST where the user has written a type, or more than one for example in class declarations.

lib/dialect/src/Operations.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,3 +3471,35 @@ mlir::ArrayAttr mlir::rlc::ExplicitConstructOp::getResAttrsAttr()
34713471
{
34723472
return mlir::ArrayAttr::get(getContext(), {});
34733473
}
3474+
3475+
llvm::SmallVector<mlir::Type, 2> mlir::rlc::MemberAccess::getUsedTypes()
3476+
{
3477+
llvm::SmallVector<mlir::Type, 2> toReturn;
3478+
if (auto casted = mlir::dyn_cast<mlir::rlc::ClassType>(getValue().getType()))
3479+
{
3480+
toReturn.push_back(casted);
3481+
}
3482+
return toReturn;
3483+
}
3484+
3485+
llvm::SmallVector<mlir::Operation *, 2>
3486+
mlir::rlc::MemberAccess::getUsedOperations()
3487+
{
3488+
return {};
3489+
}
3490+
3491+
llvm::SmallVector<mlir::Type, 2> mlir::rlc::CallOp::getUsedTypes()
3492+
{
3493+
return {};
3494+
}
3495+
3496+
llvm::SmallVector<mlir::Operation *, 2> mlir::rlc::CallOp::getUsedOperations()
3497+
{
3498+
llvm::SmallVector<mlir::Operation *, 2> toReturn;
3499+
if (auto casted = mlir::dyn_cast_or_null<mlir::rlc::TemplateInstantiationOp>(
3500+
getCallee().getDefiningOp()))
3501+
toReturn.push_back(casted.getInputTemplate().getDefiningOp());
3502+
else
3503+
toReturn.push_back(getCallee().getDefiningOp());
3504+
return toReturn;
3505+
}

lib/dialect/src/Operations.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,9 +1155,11 @@ def RLC_CallOp : RLC_Dialect<"call",
11551155
[CallOpInterface,
11561156
DeclareOpInterfaceMethods<SymbolUserOpInterface>,
11571157
DeclareOpInterfaceMethods<TypeCheckable>,
1158-
DeclareOpInterfaceMethods<Serializable>
1158+
DeclareOpInterfaceMethods<Serializable>,
1159+
DeclareOpInterfaceMethods<DefinitionUser>
11591160
]>
11601161
{
1162+
11611163
let summary = "Call operation.";
11621164

11631165
let arguments = (ins AnyFunctionType:$callee, BoolAttr:$is_member_call, Variadic<AnyType>:$args);
@@ -1340,7 +1342,7 @@ def RLC_Constant : RLC_Dialect<"constant", [DeclareOpInterfaceMethods<TypeChecka
13401342

13411343

13421344

1343-
def RLC_MemberAccess : RLC_Dialect<"member_access", [DeclareOpInterfaceMethods<TypeCheckable>, DeclareOpInterfaceMethods<Serializable>]> {
1345+
def RLC_MemberAccess : RLC_Dialect<"member_access", [DeclareOpInterfaceMethods<TypeCheckable>, DeclareOpInterfaceMethods<Serializable>, DeclareOpInterfaceMethods<DefinitionUser>]> {
13441346
let summary = "constant.";
13451347

13461348
let description = [{

lib/lsp/src/LSP.cpp

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class mlir::rlc::lsp::LSPModuleInfoImpl
102102
explicit LSPModuleInfoImpl(
103103
llvm::StringRef path, llvm::StringRef contents, LSPContext &lspContext)
104104
: context(mlir::MLIRContext::Threading::DISABLED),
105+
path(path.str()),
105106
diagnosticHandler(
106107
&context,
107108
[this](mlir::Diagnostic &diagnostic) {
@@ -651,34 +652,81 @@ class mlir::rlc::lsp::LSPModuleInfoImpl
651652
return mlir::success();
652653
}
653654

655+
template<template<class> class trait>
656+
mlir::Operation *getNearestOpWithTrait(const mlir::lsp::Position &defPos)
657+
{
658+
mlir::Operation *nearest = nullptr;
659+
int column = 0;
660+
module.walk([&](mlir::Operation *op) {
661+
if (not op->hasTrait<trait>())
662+
return;
663+
mlir::Location loc = op->getLoc();
664+
if (loc == nullptr)
665+
return;
666+
667+
auto pos = locToPos(loc);
668+
669+
if (defPos.line != pos.line)
670+
return;
671+
672+
auto castedBegin = mlir::cast<mlir::FileLineColLoc>(loc);
673+
if (path != castedBegin.getFilename())
674+
return;
675+
676+
if (abs(defPos.character - pos.character) < abs(column - pos.character))
677+
{
678+
column = pos.character;
679+
nearest = op;
680+
}
681+
});
682+
return nearest;
683+
}
684+
685+
mlir::Operation *findDeclarationOf(mlir::Type type)
686+
{
687+
if (auto casted = mlir::dyn_cast<mlir::rlc::ClassType>(type))
688+
for (auto classDecl : module.getOps<mlir::rlc::ClassDeclaration>())
689+
{
690+
if (classDecl.getName() == casted.getName())
691+
return classDecl;
692+
}
693+
694+
return nullptr;
695+
}
696+
654697
void getLocationsOf(
655698
const mlir::lsp::Position &defPos,
656699
std::vector<mlir::lsp::Location> &locations)
657700
{
658-
auto *nearestDecl = getOperation(defPos);
701+
auto *nearestDecl =
702+
getNearestOpWithTrait<mlir::rlc::DefinitionUser::Trait>(defPos);
659703
if (nearestDecl == nullptr)
660704
return;
661705

662-
auto casted = mlir::dyn_cast<mlir::rlc::CallOp>(nearestDecl);
706+
auto casted = mlir::dyn_cast<mlir::rlc::DefinitionUser>(nearestDecl);
663707
if (not casted)
664708
return;
665709

666-
auto templateInst =
667-
mlir::dyn_cast<mlir::rlc::TemplateInstantiationOp>(nearestDecl);
668-
if (templateInst)
710+
for (auto *op : casted.getUsedOperations())
669711
{
670-
auto maybeLoc = locToLoc(templateInst.getInputTemplate().getLoc());
712+
auto maybeLoc = locToLoc(op->getLoc());
671713
if (maybeLoc)
672714
locations.push_back(*maybeLoc);
673715
else
674716
llvm::consumeError(maybeLoc.takeError());
675-
return;
676-
};
677-
auto maybeLoc = locToLoc(casted.getCallee().getLoc());
678-
if (maybeLoc)
679-
locations.push_back(*maybeLoc);
680-
else
681-
llvm::consumeError(maybeLoc.takeError());
717+
}
718+
719+
for (auto type : casted.getUsedTypes())
720+
{
721+
auto op = findDeclarationOf(type);
722+
if (not op)
723+
continue;
724+
auto maybeLoc = locToLoc(op->getLoc());
725+
if (maybeLoc)
726+
locations.push_back(*maybeLoc);
727+
else
728+
llvm::consumeError(maybeLoc.takeError());
729+
}
682730
}
683731

684732
void findReferencesOf(
@@ -769,6 +817,7 @@ class mlir::rlc::lsp::LSPModuleInfoImpl
769817
llvm::SmallVector<mlir::rlc::lsp::Diagnostic> diagnostics;
770818
mlir::DialectRegistry Registry;
771819
mlir::MLIRContext context;
820+
std::string path;
772821
mlir::ScopedDiagnosticHandler diagnosticHandler;
773822
mlir::ModuleOp module;
774823
std::string currentFileContent;

python/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def copy_binaries(source_directory, destination_directory):
9999
target_bin_dir if os.name != "nt" else os.path.join("Lib", "site-packages")
100100
)
101101

102-
version="0.4.8"
102+
version="0.4.9"
103103
setup(
104104
name="rl_language_core",
105105
version=version,

0 commit comments

Comments
 (0)