Skip to content

Commit

Permalink
Merge pull request #114 from PgBiel/arg-improvements
Browse files Browse the repository at this point in the history
Support more function arguments
  • Loading branch information
pherrymason authored Jan 28, 2025
2 parents d7199a2 + 7bb1b5d commit 5d795f1
Show file tree
Hide file tree
Showing 10 changed files with 869 additions and 432 deletions.
25 changes: 22 additions & 3 deletions server/cmd/stdlib_indexer/blurp.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,34 @@ const InternalPackageName = "github.com/pherrymason/c3-lsp/internal/lsp/"
const PackageName = "github.com/pherrymason/c3-lsp/pkg/"

func Generate_variable(variable *s.Variable, module *s.Module) jen.Code {
return jen.
varDef := jen.
Qual(PackageName+"symbols", "NewVariableBuilder").
Call(
jen.Lit(variable.GetName()),
Generate_type(variable.GetType(), module.GetName()),
jen.Lit(module.GetName()),
jen.Lit(module.GetDocumentURI()),
).
Dot("Build").Call()
)

if variable.Arg.VarArg {
varDef.
Dot("IsVarArg").
Call()
}

if variable.Arg.Default.IsSome() {
varDef.
Dot("WithArgDefault").
Call(
jen.Lit(variable.Arg.Default.Get()),
)
}

varDef.
Dot("Build").
Call()

return varDef
}

func Generate_struct(strukt *s.Struct, module *s.Module) jen.Code {
Expand Down
244 changes: 122 additions & 122 deletions server/internal/lsp/stdlib/v064.go

Large diffs are not rendered by default.

256 changes: 128 additions & 128 deletions server/internal/lsp/stdlib/v065.go

Large diffs are not rendered by default.

276 changes: 138 additions & 138 deletions server/internal/lsp/stdlib/v066.go

Large diffs are not rendered by default.

83 changes: 65 additions & 18 deletions server/pkg/parser/node_to_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/pherrymason/c3-lsp/pkg/cast"
"github.com/pherrymason/c3-lsp/pkg/option"
idx "github.com/pherrymason/c3-lsp/pkg/symbols"
sitter "github.com/smacker/go-tree-sitter"
protocol "github.com/tliron/glsp/protocol_3_16"
Expand Down Expand Up @@ -111,41 +112,84 @@ func (p *Parser) nodeToFunction(node *sitter.Node, currentModule *idx.Module, do

// nodeToArgument Very similar to nodeToVariable, but arguments have optional identifiers (for example when using `self` for struct methods)
/*
_parameter: $ => choice(
seq($.type, $.ident, optional($.attributes)), // 3
seq($.type, '...', $.ident, optional($.attributes)), // 3/4
seq($.type, '...', $.ct_ident), // 3
seq($.type, $.ct_ident), // 2
seq($.type, '...', optional($.attributes)), // 2/3
seq($.type, $.hash_ident, optional($.attributes)), // 2/3
seq($.type, '&', $.ident, optional($.attributes)), // 3/4
seq($.type, optional($.attributes)), // 1/2
seq('&', $.ident, optional($.attributes)), // 2/3
seq($.hash_ident, optional($.attributes)), // 1/2
'...', // 1
seq($.ident, optional($.attributes)), // 1/2
seq($.ident, '...', optional($.attributes)), // 2/3
$.ct_ident, // 1
seq($.ct_ident, '...'), // 2
_assign_right_expr: $ => seq('=', field('right', $._expr)),
parameter_default: $ => $._assign_right_expr,
parameter: $ => seq($._parameter, optional($.parameter_default))
_parameter: $ => choice(
// Typed parameters
seq(
field('type', $.type), // 1
optional(choice(
'...', // 2
seq(optional('...'), field('name', $.ident), optional($.attributes)), // 2/3/4
// Macro parameters
seq(field('name', $.ct_ident), optional($.attributes)), // 2/3
seq(field('name', $.hash_ident), optional($.attributes)), // 2/3
seq('&', field('name', $.ident), optional($.attributes)), // 3/4
))
),
// Untyped parameters
'...', // 1
seq(field('name', $.ident), optional('...'), optional($.attributes)), // 2/3/4
// Macro parameters
seq(field('name', $.ct_ident), optional($.attributes)), // 1/2
seq(field('name', $.hash_ident), optional($.attributes)), // 1/2
seq('&', field('name', $.ident), optional($.attributes)), // 2/3
),
*/
func (p *Parser) nodeToArgument(argNode *sitter.Node, methodIdentifier string, currentModule *idx.Module, docId *string, sourceCode []byte, parameterIndex int) *idx.Variable {
var identifier = ""
var idRange idx.Range
var argType idx.Type
foundType := false
varArg := false
ref := ""
paramDefault := option.None[string]()

for i := uint32(0); i < argNode.ChildCount(); i++ {
n := argNode.Child(int(i))

switch n.Type() {
case "type":
argType = p.typeNodeToType(n, currentModule, sourceCode)
foundType = true
case "...":
varArg = true
if foundType {
// int.. args. -> int[] args
argType = argType.UnsizedCollectionOf()
} else {
// args... -> any*... args -> any*[] args
argType = idx.
NewTypeFromString("any*", currentModule.GetModuleString()).
UnsizedCollectionOf()
}
case "&":
ref = "*"
case "ident":
identifier = n.Content(sourceCode)
idRange = idx.NewRangeFromTreeSitterPositions(n.StartPoint(), n.EndPoint())
// When detecting a self, the type is the Struct type
// When detecting a self, the type is the Struct type, plus '*' for '&self'
if identifier == "self" && methodIdentifier != "" {
argType = idx.NewTypeFromString(methodIdentifier, currentModule.GetModuleString())
argType = idx.NewTypeFromString(methodIdentifier+ref, currentModule.GetModuleString())
}

// $arg (macro)
case "ct_ident":
identifier = n.Content(sourceCode)
idRange = idx.NewRangeFromTreeSitterPositions(n.StartPoint(), n.EndPoint())

// #arg (macro)
case "hash_ident":
identifier = n.Content(sourceCode)
idRange = idx.NewRangeFromTreeSitterPositions(n.StartPoint(), n.EndPoint())

// = default
case "parameter_default":
assigned := n.ChildByFieldName("right")
if assigned != nil {
paramDefault = option.Some(assigned.Content(sourceCode))
}
}
}
Expand All @@ -165,6 +209,9 @@ func (p *Parser) nodeToArgument(argNode *sitter.Node, methodIdentifier string, c
argNode.EndPoint()),
)

variable.Arg.VarArg = varArg
variable.Arg.Default = paramDefault

return &variable
}

Expand Down
Loading

0 comments on commit 5d795f1

Please sign in to comment.