Skip to content

Commit 63eae68

Browse files
authored
Merge pull request #410 from alephium/go_to_def
Go to def
2 parents 697a68c + 7d96c52 commit 63eae68

File tree

19 files changed

+1961
-375
lines changed

19 files changed

+1961
-375
lines changed

compiler-access/src/main/scala/org/alephium/ralph/lsp/access/compiler/parser/soft/ast/SoftAST.scala

+25-35
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ sealed trait SoftAST extends Product { self =>
5656
* @return `true` if `current`'s position is before `anchor`'s position, `false` otherwise.
5757
*/
5858
def isBehind(anchor: SoftAST): Boolean =
59-
this.index isBehind anchor.index
59+
isBehind(anchor.index)
60+
61+
def isBehind(anchor: SourceIndex): Boolean =
62+
this.index isBehind anchor
63+
64+
def contains(anchor: Node[SoftAST, SoftAST]): Boolean =
65+
contains(anchor.data)
6066

6167
def contains(anchor: SoftAST): Boolean =
6268
contains(anchor.index)
@@ -87,28 +93,22 @@ object SoftAST {
8793

8894
}
8995

90-
sealed trait BlockPartAST extends SoftAST
96+
implicit class NodeIdentifierExtensions(val node: Node[SoftAST.Identifier, SoftAST]) extends AnyVal {
9197

92-
sealed trait ExpressionAST extends BlockPartAST
98+
def isReferenceCall(): Boolean =
99+
node.parent match {
100+
case Some(Node(_: SoftAST.ReferenceCall, _)) => true
101+
case _ => false
102+
}
103+
104+
}
93105

94106
/**
95-
* Represents an AST that contains a block of code ([[Block]])
96-
* or a group of type definitions ([[Group]]) local to the AST identifier.
97-
*
98-
* For example:
99-
*
100-
* {{{
101-
* struct MyStruct {
102-
* type: Name // local to the identifier `MyStruct`
103-
* }
104-
*
105-
* // Parameter `param` is local to the identifier `function`
106-
* fn function(param: Type) -> () {
107-
* let variable = 1 // local to the identifier `function`
108-
* }
109-
* }}}
107+
* Represents types that can be implemented within a [[Block]].
110108
*/
111-
sealed trait IsLocallyScoped extends SoftAST
109+
sealed trait BlockPartAST extends SoftAST
110+
sealed trait DeclarationAST extends BlockPartAST
111+
sealed trait ExpressionAST extends BlockPartAST
112112

113113
case class ExpressionExpected(
114114
index: SourceIndex)
@@ -207,8 +207,7 @@ object SoftAST {
207207
postParamSpace: Option[Space],
208208
inheritance: Seq[Inheritance],
209209
block: Option[Block])
210-
extends BlockPartAST
211-
with IsLocallyScoped
210+
extends DeclarationAST
212211

213212
case class Abstract(
214213
index: SourceIndex,
@@ -223,8 +222,7 @@ object SoftAST {
223222
identifier: IdentifierAST,
224223
preParamSpace: Option[Space],
225224
params: Group[Token.OpenParen.type, Token.CloseParen.type])
226-
extends BlockPartAST
227-
with IsLocallyScoped
225+
extends DeclarationAST
228226

229227
case class Struct(
230228
index: SourceIndex,
@@ -233,8 +231,7 @@ object SoftAST {
233231
identifier: IdentifierAST,
234232
preParamSpace: Option[Space],
235233
params: Group[Token.OpenCurly.type, Token.CloseCurly.type])
236-
extends BlockPartAST
237-
with IsLocallyScoped
234+
extends DeclarationAST
238235

239236
case class Enum(
240237
index: SourceIndex,
@@ -243,15 +240,14 @@ object SoftAST {
243240
identifier: IdentifierAST,
244241
preBlockSpace: Option[Space],
245242
block: Option[Block])
246-
extends BlockPartAST
247-
with IsLocallyScoped
243+
extends DeclarationAST
248244

249245
case class Const(
250246
index: SourceIndex,
251247
constToken: TokenDocumented[Token.Const.type],
252248
preAssignmentSpace: Option[Space],
253249
assignment: Assignment)
254-
extends BlockPartAST
250+
extends DeclarationAST
255251

256252
case class Import(
257253
index: SourceIndex,
@@ -321,7 +317,6 @@ object SoftAST {
321317
parts: Seq[BlockPartAST],
322318
closeCurly: TokenDocExpectedAST[Token.CloseCurly.type])
323319
extends BlockAST
324-
with IsLocallyScoped
325320

326321
case class ExpressionBlock(
327322
index: SourceIndex,
@@ -349,8 +344,7 @@ object SoftAST {
349344
signature: FunctionSignature,
350345
postSignatureSpace: Option[Space],
351346
block: Option[Block])
352-
extends BlockPartAST
353-
with IsLocallyScoped
347+
extends DeclarationAST
354348

355349
case class FunctionSignature(
356350
index: SourceIndex,
@@ -531,7 +525,6 @@ object SoftAST {
531525
postCloseParenSpace: Option[Space],
532526
block: Option[Block])
533527
extends ExpressionAST
534-
with IsLocallyScoped
535528

536529
case class While(
537530
index: SourceIndex,
@@ -545,7 +538,6 @@ object SoftAST {
545538
postCloseParenSpace: Option[Space],
546539
block: Option[Block])
547540
extends ExpressionAST
548-
with IsLocallyScoped
549541

550542
case class Assignment(
551543
index: SourceIndex,
@@ -648,15 +640,13 @@ object SoftAST {
648640
preElseSpace: Option[Space],
649641
elseStatement: Option[Else])
650642
extends ExpressionAST
651-
with IsLocallyScoped
652643

653644
case class Else(
654645
index: SourceIndex,
655646
elseToken: TokenDocumented[Token.Else.type],
656647
preBlockSpace: Option[Space],
657648
block: Option[Block])
658649
extends ExpressionAST
659-
with IsLocallyScoped
660650

661651
case class Space(
662652
code: CodeString)

lsp-server/src/main/scala/org/alephium/ralph/lsp/server/RalphLangServer.scala

+12-3
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,12 @@ class RalphLangServer private (
501501
val line = params.getPosition.getLine
502502
val character = params.getPosition.getCharacter
503503

504+
val settings =
505+
GoToDefSetting(
506+
includeAbstractFuncDef = false,
507+
includeInheritance = true
508+
)
509+
504510
// Compute soft AST locations asynchronously
505511
val softASTLocationsFuture =
506512
if (enableSoftParser)
@@ -510,7 +516,7 @@ class RalphLangServer private (
510516
fileURI = fileURI,
511517
line = line,
512518
character = character,
513-
searchSettings = (SoftAST, GoToDefSetting(includeAbstractFuncDef = false)),
519+
searchSettings = (SoftAST, settings),
514520
cancelChecker = cancelChecker,
515521
currentState = getPCState()
516522
)
@@ -524,7 +530,7 @@ class RalphLangServer private (
524530
fileURI = fileURI,
525531
line = line,
526532
character = character,
527-
searchSettings = GoToDefSetting(includeAbstractFuncDef = false),
533+
searchSettings = settings,
528534
cancelChecker = cancelChecker,
529535
currentState = getPCState()
530536
)
@@ -558,7 +564,10 @@ class RalphLangServer private (
558564
includeDeclaration = isIncludeDeclaration,
559565
includeTemplateArgumentOverrides = false,
560566
includeEventFieldReferences = true,
561-
goToDefSetting = GoToDefSetting(includeAbstractFuncDef = false)
567+
goToDefSetting = GoToDefSetting(
568+
includeAbstractFuncDef = false,
569+
includeInheritance = true
570+
)
562571
)
563572

564573
val locations =

presentation-compiler/src/main/scala/org/alephium/ralph/lsp/pc/search/gotodef/GoToDefSetting.scala

+13-1
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,17 @@ package org.alephium.ralph.lsp.pc.search.gotodef
3232
* fn >>function()<< -> () { }
3333
* }
3434
* }}}
35+
* @param includeInheritance If `true`, inherited parameters are included in the search results.
36+
* If `false`, inherited parameters are excluded.
37+
* For example, in the following case, the `param` in the `Parent` contract
38+
* should be excluded from the search. To achieve this,
39+
* `enableInheritanceSearch` must be set to `false`.
40+
* {{{
41+
* Abstract Contract Parent(param: Type)
42+
*
43+
* Contract MyContract(>>param<<: Type) extends Parent(para@@m)
44+
* }}}
3545
*/
36-
case class GoToDefSetting(includeAbstractFuncDef: Boolean)
46+
case class GoToDefSetting(
47+
includeAbstractFuncDef: Boolean,
48+
includeInheritance: Boolean)

presentation-compiler/src/main/scala/org/alephium/ralph/lsp/pc/search/gotodef/ScopeWalker.scala

+9-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package org.alephium.ralph.lsp.pc.search.gotodef
1818

19-
import org.alephium.ralph.Ast
19+
import org.alephium.ralph.{Ast, SourceIndex}
2020
import org.alephium.ralph.lsp.access.compiler.ast.AstExtra
2121
import org.alephium.ralph.lsp.access.compiler.message.SourceIndexExtra
2222
import org.alephium.ralph.lsp.access.compiler.parser.soft.ast.SoftAST
@@ -89,24 +89,25 @@ private[search] object ScopeWalker {
8989
*/
9090
def walk[T](
9191
from: Node[SoftAST, SoftAST],
92-
anchor: SoftAST
93-
)(pf: PartialFunction[Node[SoftAST, SoftAST], T]): Iterable[T] = {
92+
anchor: SourceIndex
93+
)(pf: PartialFunction[Node[SoftAST, SoftAST], Iterator[T]]): Iterable[T] = {
9494
val found = ListBuffer.empty[T]
9595
var walker = from.walkDown
9696

9797
while (walker.hasNext)
9898
walker.next() match {
9999
// Check: Is this a scoped node that does not contain the anchor node within its scope? If yes, drop all its child nodes.
100-
case block @ Node(_: SoftAST.IsLocallyScoped, _) if !block.data.contains(anchor) =>
100+
case block @ Node(_: SoftAST.While | _: SoftAST.For | _: SoftAST.IfElse | _: SoftAST.Else | _: SoftAST.Block, _) if !block.data.contains(anchor) =>
101101
// drop all child nodes
102102
walker = walker dropWhile block.contains
103103

104104
// Check:
105105
// - Is this node (i.e. within the scope) defined by the partial-function?
106-
// - And is it before the anchor node?
107-
// - If it's defined after the anchor node (node in scope), then only add it if currently collected items are empty.
108-
case node @ Node(ast, _) if pf.isDefinedAt(node) && (ast.isBehind(anchor) || found.isEmpty) =>
109-
found addOne pf(node)
106+
// - If it is a declaration, process the node because declarations do not require ordering and are available locally to all code.
107+
// - If it is not a declaration, is it before the anchor node?
108+
// - If it is defined after the anchor node (node in scope), then only add it if currently collected items are empty.
109+
case node @ Node(ast, _) if pf.isDefinedAt(node) && (ast.isInstanceOf[SoftAST.DeclarationAST] || ast.isBehind(anchor) || found.isEmpty) =>
110+
found addAll pf(node)
110111
// This node is processed, drop all its children.
111112
walker = walker dropWhile node.contains
112113

presentation-compiler/src/main/scala/org/alephium/ralph/lsp/pc/search/rename/GoToRenameAll.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ private object GoToRenameAll extends StrictImplicitLogging {
9797
includeDeclaration = true,
9898
includeTemplateArgumentOverrides = true,
9999
includeEventFieldReferences = false, // do not rename event field references
100-
goToDefSetting = GoToDefSetting(includeAbstractFuncDef = true)
100+
goToDefSetting = GoToDefSetting(
101+
includeAbstractFuncDef = true,
102+
includeInheritance = true
103+
)
101104
)
102105

103106
// Start collect the nodes to rename

presentation-compiler/src/main/scala/org/alephium/ralph/lsp/pc/search/soft/gotodef/GoToDefCodeString.scala

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package org.alephium.ralph.lsp.pc.search.soft.gotodef
22

33
import org.alephium.ralph.lsp.access.compiler.parser.soft.ast.SoftAST
4+
import org.alephium.ralph.lsp.pc.search.gotodef.GoToDefSetting
45
import org.alephium.ralph.lsp.pc.sourcecode.SourceLocation
6+
import org.alephium.ralph.lsp.pc.workspace.WorkspaceState
57
import org.alephium.ralph.lsp.utils.Node
8+
import org.alephium.ralph.lsp.utils.log.ClientLogger
69

710
private object GoToDefCodeString {
811

@@ -12,11 +15,15 @@ private object GoToDefCodeString {
1215
* @param node The node representing the [[SoftAST.CodeString]] being searched.
1316
* @param sourceCode The body part and its parsed [[org.alephium.ralph.lsp.pc.sourcecode.SourceCodeState]],
1417
* which contains the [[SoftAST.CodeString]].
18+
* @param workspace The workspace state where the source-code is located.
1519
* @return An iterator over definition search results.
1620
*/
1721
def apply(
1822
node: Node[SoftAST.CodeString, SoftAST],
19-
sourceCode: SourceLocation.CodeSoft): Iterator[SourceLocation.GoToDefSoft] =
23+
sourceCode: SourceLocation.CodeSoft,
24+
workspace: WorkspaceState.IsSourceAware,
25+
settings: GoToDefSetting
26+
)(implicit logger: ClientLogger): Iterator[SourceLocation.GoToDefSoft] =
2027
node.parent match {
2128
case Some(Node(_: SoftAST.Space, _)) =>
2229
// Spaces do not require go-to-definition
@@ -25,7 +32,9 @@ private object GoToDefCodeString {
2532
case Some(node @ Node(id: SoftAST.Identifier, _)) =>
2633
GoToDefIdentifier(
2734
identNode = node.upcast(id),
28-
sourceCode = sourceCode
35+
sourceCode = sourceCode,
36+
workspace = workspace,
37+
settings = settings
2938
)
3039

3140
case _ =>

0 commit comments

Comments
 (0)