Skip to content

Commit

Permalink
Parse function arguments declaration.
Browse files Browse the repository at this point in the history
  • Loading branch information
pherrymason committed Jan 13, 2024
1 parent 414e68c commit 9576e8b
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 63 deletions.
23 changes: 12 additions & 11 deletions server/lsp/indexables/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const (
)

type Function struct {
fType FunctionType
name string
returnType string
arguments []string // Used to list which variables are defined in function signature. They are fully defined in Variables
fType FunctionType
name string
returnType string
argumentIds []string // Used to list which variables are defined in function signature. They are fully defined in Variables

Variables map[string]Variable
Enums map[string]*Enum
Expand All @@ -24,18 +24,19 @@ type Function struct {
}

func NewAnonymousScopeFunction(name string, docId string, docRange Range, kind protocol.CompletionItemKind) Function {
return newFunctionType(Anonymous, name, "", docId, Range{}, docRange, kind)
return newFunctionType(Anonymous, name, "", nil, docId, Range{}, docRange, kind)
}

func NewFunction(name string, returnType string, docId string, idRange Range, docRange Range, kind protocol.CompletionItemKind) Function {
return newFunctionType(UserDefined, name, returnType, docId, idRange, docRange, kind)
func NewFunction(name string, returnType string, argumentIds []string, docId string, idRange Range, docRange Range, kind protocol.CompletionItemKind) Function {
return newFunctionType(UserDefined, name, returnType, argumentIds, docId, idRange, docRange, kind)
}

func newFunctionType(fType FunctionType, name string, returnType string, docId string, identifierRangePosition Range, docRange Range, kind protocol.CompletionItemKind) Function {
func newFunctionType(fType FunctionType, name string, returnType string, argumentIds []string, docId string, identifierRangePosition Range, docRange Range, kind protocol.CompletionItemKind) Function {
return Function{
fType: fType,
name: name,
returnType: returnType,
fType: fType,
name: name,
returnType: returnType,
argumentIds: argumentIds,
BaseIndexable: BaseIndexable{
documentURI: docId,
identifierRange: identifierRangePosition,
Expand Down
4 changes: 2 additions & 2 deletions server/lsp/indexables/variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ type Variable struct {
BaseIndexable
}

func NewVariable(name string, variableType string, uri string, identifierRangePosition Range, documentRangePosition Range, kind protocol.CompletionItemKind) Variable {
func NewVariable(name string, variableType string, uri string, identifierRangePosition Range, documentRangePosition Range) Variable {
return Variable{
Name: name,
Type: variableType,
BaseIndexable: BaseIndexable{
documentURI: uri,
identifierRange: identifierRangePosition,
documentRange: documentRangePosition,
Kind: kind,
Kind: protocol.CompletionItemKindVariable,
},
}
}
Expand Down
27 changes: 3 additions & 24 deletions server/lsp/language_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_same_scope(t *testin

symbol, _ := language.FindSymbolDeclarationInWorkspace(doc.URI, "value", params.Position)

expectedSymbol := idx.NewVariable(
"value",
"int",
"x",
idx.NewRange(1, 6, 1, 11),
idx.NewRange(1, 6, 1, 11),
protocol.CompletionItemKindVariable,
)
expectedSymbol := idx.NewVariable("value", "int", "x", idx.NewRange(1, 6, 1, 11), idx.NewRange(1, 6, 1, 11))
assert.Equal(t, expectedSymbol, symbol)
}

Expand All @@ -240,14 +233,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_func

symbol, _ := language.FindSymbolDeclarationInWorkspace(doc.URI, "value", params.Position)

expectedSymbol := idx.NewVariable(
"value",
"int",
"x",
idx.NewRange(1, 6, 1, 11),
idx.NewRange(1, 6, 1, 11),
protocol.CompletionItemKindVariable,
)
expectedSymbol := idx.NewVariable("value", "int", "x", idx.NewRange(1, 6, 1, 11), idx.NewRange(1, 6, 1, 11))
assert.Equal(t, expectedSymbol, symbol)
}

Expand All @@ -273,14 +259,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_file

symbol, _ := language.FindSymbolDeclarationInWorkspace(doc.URI, "value", params.Position)

expectedSymbol := idx.NewVariable(
"value",
"int",
"y",
idx.NewRange(0, 4, 0, 9),
idx.NewRange(0, 4, 0, 9),
protocol.CompletionItemKindVariable,
)
expectedSymbol := idx.NewVariable("value", "int", "y", idx.NewRange(0, 4, 0, 9), idx.NewRange(0, 4, 0, 9))
assert.Equal(t, expectedSymbol, symbol)
}

Expand Down
45 changes: 29 additions & 16 deletions server/lsp/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,31 +107,44 @@ func (p *Parser) ExtractSymbols(doc *Document) idx.Function {
return scopeTree
}

func (p *Parser) nodeToVariable(doc *Document, node *sitter.Node, sourceCode []byte, content string) idx.Variable {
typeNode := node.PrevSibling()
func (p *Parser) nodeToVariable(doc *Document, identifierNode *sitter.Node, sourceCode []byte, content string) idx.Variable {
typeNode := identifierNode.PrevSibling()
typeNodeContent := typeNode.Content(sourceCode)
variable := idx.NewVariable(
content,
typeNodeContent,
doc.URI,
idx.NewRangeFromSitterPositions(node.StartPoint(), node.EndPoint()),
idx.NewRangeFromSitterPositions(node.StartPoint(), node.EndPoint()), // TODO Should this include the var type range?
protocol.CompletionItemKindVariable,
)
variable := idx.NewVariable(content, typeNodeContent, doc.URI, idx.NewRangeFromSitterPositions(identifierNode.StartPoint(), identifierNode.EndPoint()), idx.NewRangeFromSitterPositions(identifierNode.StartPoint(), identifierNode.EndPoint()))

return variable
}

func (p *Parser) nodeToFunction(doc *Document, node *sitter.Node, sourceCode []byte) idx.Function {

nameNode := node.ChildByFieldName("name")
symbol := idx.NewFunction(
nameNode.Content(sourceCode),
node.ChildByFieldName("return_type").Content(sourceCode),
doc.URI,
idx.NewRangeFromSitterPositions(nameNode.StartPoint(), nameNode.EndPoint()), idx.NewRangeFromSitterPositions(node.StartPoint(), node.EndPoint()), protocol.CompletionItemKindFunction)

// Extract function arguments
arguments := []idx.Variable{}
parameters := node.ChildByFieldName("parameters")
for i := uint32(0); i < parameters.ChildCount(); i++ {
argNode := parameters.Child(int(i))
switch argNode.Type() {
case "parameter":
for j := uint32(0); j < argNode.ChildCount(); j++ {
arggNode := argNode.Child(int(j))
switch arggNode.Type() {
case "identifier":
arguments = append(arguments, p.nodeToVariable(doc, arggNode, sourceCode, arggNode.Content(sourceCode)))
}
}
}
}

var argumentIds []string
for _, arg := range arguments {
argumentIds = append(argumentIds, arg.GetName())
}

symbol := idx.NewFunction(nameNode.Content(sourceCode), node.ChildByFieldName("return_type").Content(sourceCode), argumentIds, doc.URI, idx.NewRangeFromSitterPositions(nameNode.StartPoint(), nameNode.EndPoint()), idx.NewRangeFromSitterPositions(node.StartPoint(), node.EndPoint()), protocol.CompletionItemKindFunction)

variables := p.FindVariableDeclarations(doc, node)
variables = append(arguments, variables...)

// TODO Previous node has the info about which function is belongs to.

Expand Down Expand Up @@ -259,7 +272,7 @@ func (p *Parser) FindFunctionDeclarations(doc *Document) []idx.Indexable {
c.Node.Parent().Type()
if _, exists := found[content]; !exists {
found[content] = true
identifier := idx.NewFunction(content, "", doc.URI, idx.NewRangeFromSitterPositions(c.Node.StartPoint(), c.Node.EndPoint()), idx.NewRangeFromSitterPositions(c.Node.StartPoint(), c.Node.EndPoint()), protocol.CompletionItemKindFunction)
identifier := idx.NewFunction(content, "", []string{}, doc.URI, idx.NewRangeFromSitterPositions(c.Node.StartPoint(), c.Node.EndPoint()), idx.NewRangeFromSitterPositions(c.Node.StartPoint(), c.Node.EndPoint()), protocol.CompletionItemKindFunction)

identifiers = append(identifiers, identifier)
}
Expand Down
22 changes: 12 additions & 10 deletions server/lsp/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ func TestExtractSymbols_finds_function_root_and_global_variables_declarations(t
protocol.CompletionItemKindModule,
)
expectedRoot.AddVariables([]idx.Variable{
idx.NewVariable(
"value",
"int",
"x",
idx.NewRange(0, 4, 0, 9),
idx.NewRange(0, 4, 0, 9), protocol.CompletionItemKindVariable),
idx.NewVariable("value", "int", "x", idx.NewRange(0, 4, 0, 9), idx.NewRange(0, 4, 0, 9)),
})

assert.Equal(t, expectedRoot, symbols)
Expand Down Expand Up @@ -196,16 +191,23 @@ func TestExtractSymbols_finds_function_declaration_identifiers(t *testing.T) {
fn int test2(int number, char ch){
return 2;
}`
doc := NewDocumentFromString("x", source)
docId := "x"
doc := NewDocumentFromString(docId, source)
parser := createParser()
tree := parser.ExtractSymbols(&doc)

function1 := idx.NewFunction("test", "void", "x", idx.NewRange(0, 8, 0, 12), idx.NewRange(0, 0, 2, 2), protocol.CompletionItemKindFunction)
function2 := idx.NewFunction("test2", "int", "x", idx.NewRange(3, 8, 3, 13), idx.NewRange(3, 1, 5, 2), protocol.CompletionItemKindFunction)
function1 := idx.NewFunction("test", "void", nil, docId, idx.NewRange(0, 8, 0, 12), idx.NewRange(0, 0, 2, 2), protocol.CompletionItemKindFunction)
function2 := idx.NewFunction("test2", "int", []string{"number", "ch"}, docId, idx.NewRange(3, 8, 3, 34), idx.NewRange(3, 1, 5, 2), protocol.CompletionItemKindFunction)

var1 := idx.NewVariable("number", "int", docId,
idx.NewRange(3, 18, 3, 24), idx.NewRange(3, 18, 3, 24))
var2 := idx.NewVariable("ch", "char", docId,
idx.NewRange(3, 31, 3, 33), idx.NewRange(3, 31, 3, 33))
function2.AddVariables([]idx.Variable{var1, var2})

root := idx.NewAnonymousScopeFunction(
"main",
"x",
docId,
idx.NewRange(0, 0, 0, 14),
protocol.CompletionItemKindModule,
)
Expand Down

0 comments on commit 9576e8b

Please sign in to comment.