Skip to content

Commit

Permalink
Parse of simple structs.
Browse files Browse the repository at this point in the history
  • Loading branch information
pherrymason committed Jan 12, 2024
1 parent 0c312c8 commit 2fd2e8c
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 34 deletions.
25 changes: 13 additions & 12 deletions server/lsp/indexables/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,30 @@ type Function struct {

Variables map[string]Variable
Enums map[string]*Enum
Structs map[string]Struct
ChildrenFunctions map[string]*Function
}

func NewAnonymousScopeFunction(name string, docId string, docRange Range, kind protocol.CompletionItemKind) Function {
return Function{
_type: Anonymous,
Name: name,
ReturnType: "??",
DocumentURI: docId,
documentRange: docRange,
Kind: kind,
Variables: make(map[string]Variable),
Enums: make(map[string]*Enum),
ChildrenFunctions: make(map[string]*Function),
}
return newFunctionType(Anonymous, name, docId, Range{}, docRange, kind)
}

func NewFunction(name string, docId string, identifierRangePosition Range, docRange Range, kind protocol.CompletionItemKind) Function {
return newFunctionType(UserDefined, name, docId, identifierRangePosition, docRange, kind)
}

func newFunctionType(fType FunctionType, name string, docId string, identifierRangePosition Range, docRange Range, kind protocol.CompletionItemKind) Function {
return Function{
_type: UserDefined,
_type: fType,
Name: name,
ReturnType: "??",
DocumentURI: docId,
identifierRange: identifierRangePosition,
documentRange: docRange,
Kind: kind,
Variables: make(map[string]Variable),
Enums: make(map[string]*Enum),
Structs: make(map[string]Struct),
ChildrenFunctions: make(map[string]*Function),
}
}
Expand Down Expand Up @@ -88,3 +85,7 @@ func (f *Function) AddEnum(enum *Enum) {
func (f Function) AddFunction(f2 *Function) {
f.ChildrenFunctions[f2.Name] = f2
}

func (f Function) AddStruct(s Struct) {
f.Structs[s.name] = s
}
35 changes: 27 additions & 8 deletions server/lsp/indexables/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,31 @@ package indexables
import protocol "github.com/tliron/glsp/protocol_3_16"

type Struct struct {
Name string
Members []string
DocumentURI string
identifierRange Range
documentRange Range
Kind protocol.CompletionItemKind
name string
members []StructMember
BaseIndexable
}

func NewStruct(name string, members []StructMember, docId string) Struct {
return Struct{
name: name,
members: members,
BaseIndexable: BaseIndexable{
documentURI: docId,
},
}
}

func (s Struct) GetName() string {
return s.Name
return s.name
}

func (s Struct) GetKind() protocol.CompletionItemKind {
return s.Kind
}

func (s Struct) GetDocumentURI() string {
return s.DocumentURI
return s.documentURI
}

func (s Struct) GetDeclarationRange() Range {
Expand All @@ -29,3 +36,15 @@ func (s Struct) GetDeclarationRange() Range {
func (s Struct) GetDocumentRange() Range {
return s.documentRange
}

type StructMember struct {
name string
baseType string
}

func NewStructMember(name string, baseType string) StructMember {
return StructMember{
name: name,
baseType: baseType,
}
}
47 changes: 33 additions & 14 deletions server/lsp/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const FunctionDeclarationQuery = `(function_declaration
body: (_) @body
)`
const EnumDeclaration = `(enum_declaration) @enum_dec`
const StructDeclaration = `(struct_declaration) @struct_dec`

type Parser struct {
logger commonlog.Logger
Expand Down Expand Up @@ -55,7 +56,8 @@ func GetParsedTreeFromString(source string) *sitter.Tree {
func (p *Parser) FindSymbols(doc *Document) idx.Function {
query := `[
(source_file ` + VarDeclarationQuery + `)
(source_file ` + EnumDeclaration + `)
(source_file ` + EnumDeclaration + `)
(source_file ` + StructDeclaration + `)
` + FunctionDeclarationQuery + `]`

//fmt.Println(doc.parsedTree.RootNode())
Expand Down Expand Up @@ -104,9 +106,12 @@ func (p *Parser) FindSymbols(doc *Document) idx.Function {
functionsMap[content] = &identifier
scopeTree.AddFunction(&identifier)
}
} else if c.Node.Type() == "enum_declaration" {
} else if nodeType == "enum_declaration" {
enum := p.nodeToEnum(doc, c.Node, sourceCode)
scopeTree.AddEnum(&enum)
} else if nodeType == "struct_declaration" {
_struct := p.nodeToStruct(doc, c.Node, sourceCode)
scopeTree.AddStruct(_struct)
} else if nodeType == "compound_statement" {
variables := p.FindVariableDeclarations(doc, c.Node)

Expand Down Expand Up @@ -143,7 +148,33 @@ func (p *Parser) nodeToVariable(doc *Document, node *sitter.Node, sourceCode []b
return variable
}

func (p *Parser) nodeToStruct(doc *Document, node *sitter.Node, sourceCode []byte) idx.Struct {
name := node.Child(1).Content(sourceCode)
// TODO parse attributes
bodyNode := node.Child(2)

fields := make([]idx.StructMember, 0)

for i := uint32(0); i < bodyNode.ChildCount(); i++ {
child := bodyNode.Child(int(i))
switch child.Type() {
case "field_declaration":
fieldName := child.ChildByFieldName("name").Content(sourceCode)
fieldType := child.ChildByFieldName("type").Content(sourceCode)
fields = append(fields, idx.NewStructMember(fieldName, fieldType))

case "field_struct_declaration":
case "field_union_declaration":
}
}

_struct := idx.NewStruct(name, fields, doc.URI)

return _struct
}

func (p *Parser) nodeToEnum(doc *Document, node *sitter.Node, sourceCode []byte) idx.Enum {
// TODO parse attributes
nodesCount := node.ChildCount()
nameNode := node.Child(1)

Expand Down Expand Up @@ -181,18 +212,6 @@ func (p *Parser) nodeToEnum(doc *Document, node *sitter.Node, sourceCode []byte)
return enum
}

/**
func FindIdentifiers(doc *Document) []idx.Indexable {
//variableIdentifiers := FindVariableDeclarations(doc, doc.parsedTree.RootNode())
functionIdentifiers := FindFunctionDeclarations(doc)
var elements []idx.Indexable
//elements = append(elements, variableIdentifiers...)
elements = append(elements, functionIdentifiers...)
return elements
}*/

func (p *Parser) FindVariableDeclarations(doc *Document, node *sitter.Node) []idx.Variable {
query := VarDeclarationQuery
q, err := sitter.NewQuery([]byte(query), getLanguage())
Expand Down
22 changes: 22 additions & 0 deletions server/lsp/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,28 @@ func TestFindSymbols_finds_function_root_and_global_enum_with_base_type_declarat
assert.Equal(t, &enum, symbols.Enums["Colors"])
}

func TestFindSymbols_finds_function_root_and_global_struct_declarations(t *testing.T) {
source := `struct MyStructure {
bool enabled;
char key;
}`
doc := NewDocumentFromString("x", source)
parser := createParser()

symbols := parser.FindSymbols(&doc)

expectedStruct := idx.NewStruct(
"MyStructure",
[]idx.StructMember{
idx.NewStructMember("enabled", "bool"),
idx.NewStructMember("key", "char"),
},
"x",
)

assert.Equal(t, expectedStruct, symbols.Structs["MyStructure"])
}

func TestFindSymbols_finds_function_declaration_identifiers(t *testing.T) {
source := `fn void test() {
return 1;
Expand Down

0 comments on commit 2fd2e8c

Please sign in to comment.