Skip to content

Commit

Permalink
Language Server Improvements: find references, basic autocompletion (c…
Browse files Browse the repository at this point in the history
…hapel-lang#24213)

This PR implements a few extra features in the Python-based language
server.

* It adds `Scope` objects to the Python API. This makes it possible for
Python code to inspect scopes (currently, just listing used/imported
modules in a scope).
* It refactors the binary search code to be stored in a class, so that
other things (definitions) can be binary searched via cursor position.
* It uses the used/imported modules from the given file to provide
autocomplete suggestions for identifiers (currently not intelligent
enough to filter based on type / `bla.`).
* It builds another segment list for _defined_ symbols, and uses that
(and some additional bookkeeping) to find references _within a file_.

I'm planning on a refactor to keep track of workspace changes, so that
_global_ 'find references' works too.

Reviewed by @jabraham17 -- thanks!

## Testing
- [x] paratest for the parser changes
  • Loading branch information
DanilaFe authored Jan 19, 2024
2 parents 42580aa + 580c9ee commit 77511bf
Show file tree
Hide file tree
Showing 10 changed files with 749 additions and 445 deletions.
8 changes: 6 additions & 2 deletions frontend/lib/parsing/ParserContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,9 @@ struct ParserContext {
bool isOverride);

AstNode*
buildFormal(YYLTYPE location, Formal::Intent intent,
buildFormal(YYLTYPE location,
YYLTYPE locName,
Formal::Intent intent,
PODUniqueString name,
AstNode* typeExpr,
AstNode* initExpr,
Expand Down Expand Up @@ -677,7 +679,9 @@ struct ParserContext {
buildForwardingDecl(YYLTYPE location, owned<AttributeGroup> attributeGroup,
CommentsAndStmt cs);

AstNode* buildInterfaceFormal(YYLTYPE location, PODUniqueString name);
AstNode* buildInterfaceFormal(YYLTYPE location,
YYLTYPE locName,
PODUniqueString name);

CommentsAndStmt buildInterfaceStmt(YYLTYPE location,
PODUniqueString name,
Expand Down
10 changes: 7 additions & 3 deletions frontend/lib/parsing/ParserContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,9 @@ ParserContext::buildFunctionExpr(YYLTYPE location, FunctionParts& fp) {
}

AstNode*
ParserContext::buildFormal(YYLTYPE location, Formal::Intent intent,
ParserContext::buildFormal(YYLTYPE location,
YYLTYPE locName,
Formal::Intent intent,
PODUniqueString name,
AstNode* typeExpr,
AstNode* initExpr,
Expand All @@ -1166,6 +1168,7 @@ ParserContext::buildFormal(YYLTYPE location, Formal::Intent intent,
auto node = Formal::build(builder, loc, std::move(attr), name, intent,
toOwned(typeExpr),
toOwned(initExpr));
builder->noteDeclNameLocation(node.get(), convertLocation(locName));
this->noteIsBuildingFormal(false);
if (consumeAttributeGroup) resetAttributeGroupPartsState();
return node.release();
Expand Down Expand Up @@ -3001,8 +3004,9 @@ ParserContext::buildSelectStmt(YYLTYPE location, owned<AstNode> expr,
}

AstNode* ParserContext::buildInterfaceFormal(YYLTYPE location,
YYLTYPE locName,
PODUniqueString name) {
return buildFormal(location, Formal::Intent::TYPE, name,
return buildFormal(location, locName, Formal::Intent::TYPE, name,
/* typeExpr */ nullptr,
/* initExpr */ nullptr,
/* consumeAttributeGroup */ false);
Expand All @@ -3027,7 +3031,7 @@ CommentsAndStmt ParserContext::buildInterfaceStmt(YYLTYPE location,
formalList = consumeList(formals);
} else {
auto selfStr = PODUniqueString::get(context(), "Self");
formalList.push_back(toOwned(buildInterfaceFormal(location, selfStr)));
formalList.push_back(toOwned(buildInterfaceFormal(location, {}, selfStr)));
}

AstList bodyStmts = bodyExprLst
Expand Down
Loading

0 comments on commit 77511bf

Please sign in to comment.