Skip to content

Commit

Permalink
Search in inlined struct properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
pherrymason committed Jan 20, 2025
1 parent 9dde4fa commit e299a44
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
29 changes: 29 additions & 0 deletions server/internal/lsp/analysis/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ func resolveChildSymbol(symbol *Symbol, nextIdent string, moduleName ModuleName,
}

case ast.STRUCT:
inlinedCandidates := []ast.Ident{}

// Search In Members
for _, member := range symbol.NodeDecl.(*ast.StructDecl).Members {
if member.Names[0].Name == nextIdent {
Expand Down Expand Up @@ -263,6 +265,8 @@ func resolveChildSymbol(symbol *Symbol, nextIdent string, moduleName ModuleName,
} else {
return nil
}
} else if member.IsInlined {
inlinedCandidates = append(inlinedCandidates, member.Type.Identifier)
}
}

Expand All @@ -273,6 +277,31 @@ func resolveChildSymbol(symbol *Symbol, nextIdent string, moduleName ModuleName,
}
}

// Not found, look inside each inlinedCandidates, maybe is a subproperty of them
for _, inlinedTypeIdent := range inlinedCandidates {
inlinedTypeSymbol := symbolTable.FindSymbolByPosition(
inlinedTypeIdent.Range.Start,
fileName,
inlinedTypeIdent.Name,
moduleName,
0,
)
if inlinedTypeSymbol.IsSome() {
inlinedStructSymbol := inlinedTypeSymbol.Get()
child := resolveChildSymbol(
inlinedStructSymbol,
nextIdent,
moduleName,
fileName,
symbolTable,
solveType,
)
if child != nil && child.Name == nextIdent {
return child
}
}
}

case ast.FUNCTION:
fn := symbol.NodeDecl.(*ast.FunctionDecl)
returnType := fn.Signature.ReturnType
Expand Down
24 changes: 24 additions & 0 deletions server/internal/lsp/analysis/analysis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,29 @@ func TestFindsSymbol_Declaration_struct(t *testing.T) {
assert.Equal(t, ast.Token(ast.FUNCTION), symbol.Kind)
})

t.Run("Find struct member that is inlined", func(t *testing.T) {
source := `
struct Foo {
int a;
int b;
}
struct Bar {
inline Foo sub;
}
fn void main() {
Bar obj;
obj.a = 3;
}`

fileName := "app.c3"
tree := getTree(source, fileName)
symbolTable := BuildSymbolTable(tree, fileName)

cursorPosition := lsp.Position{Line: 10, Column: 7}
symbolOpt := FindSymbolAtPosition(cursorPosition, fileName, symbolTable, tree)
assert.True(t, symbolOpt.IsSome(), "Symbol not found")
})

t.Run("Find interface struct is implementing", func(t *testing.T) {
source := `
interface Animal{fn void run();}
Expand All @@ -595,6 +618,7 @@ func TestFindsSymbol_Declaration_struct(t *testing.T) {
assert.Equal(t, lsp.NewRange(1, 2, 1, 34), symbol.NodeDecl.GetRange())
assert.Equal(t, ast.Token(ast.INTERFACE), symbol.Kind)
})

}

func TestFindsSymbol_Declaration_def(t *testing.T) {
Expand Down
1 change: 0 additions & 1 deletion server/internal/lsp/ast/factory/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,6 @@ func (c *ASTConverter) convert_bitstruct_declaration(node *sitter.Node, sourceCo

switch child.Type() {
case "interface_impl":
// TODO
for x := 0; x < int(child.ChildCount()); x++ {
n := child.Child(x)
if n.Type() == "interface" {
Expand Down

0 comments on commit e299a44

Please sign in to comment.