Skip to content

Commit

Permalink
Parse module name.
Browse files Browse the repository at this point in the history
  • Loading branch information
pherrymason committed Jan 14, 2024
1 parent 4de4748 commit 8622d8c
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 54 deletions.
4 changes: 3 additions & 1 deletion server/lsp/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

type Document struct {
parsedTree *sitter.Tree
ModuleName string
URI protocol.DocumentUri
Path string
NeedsRefreshDiagnostics bool
Expand Down Expand Up @@ -49,9 +50,10 @@ func NewDocumentFromFilePath(documentPath string) Document {
}
}

func NewDocumentFromString(documentPath string, documentContent string) Document {
func NewDocumentFromString(documentPath string, moduleName string, documentContent string) Document {
return Document{
parsedTree: GetParsedTreeFromString(documentContent),
ModuleName: moduleName,
URI: documentPath,
Path: documentPath,
Content: documentContent,
Expand Down
2 changes: 1 addition & 1 deletion server/lsp/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestWordInIndex(t *testing.T) {
}

source := "hello this is expected bye_bye"
doc := NewDocumentFromString("x", source)
doc := NewDocumentFromString("x", "x", source)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
word, _ := doc.WordInIndex(tt.position)
Expand Down
4 changes: 4 additions & 0 deletions server/lsp/documentstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (s *documentStore) DidOpen(params protocol.DidOpenTextDocumentParams, notif
Path: path,
Content: params.TextDocument.Text,
}

moduleName := parser.ExtractModuleName(doc)
doc.ModuleName = moduleName

s.documents[path] = doc
return doc, nil
}
Expand Down
4 changes: 2 additions & 2 deletions server/lsp/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ func createParser() Parser {
}
}

func createStruct(docId string, name string, members []idx.StructMember, idRange idx.Range) idx.Indexable {
return idx.NewStruct(name, members, "", docId, idRange)
func createStruct(docId string, module string, name string, members []idx.StructMember, idRange idx.Range) idx.Indexable {
return idx.NewStruct(name, members, module, docId, idRange)
}

func assertSameVariable(t *testing.T, expected idx.Variable, actual idx.Variable) {
Expand Down
3 changes: 2 additions & 1 deletion server/lsp/indexables/enumBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ type EnumBuilder struct {
enum Enum
}

func NewEnumBuilder(name string, baseType string, docId string) *EnumBuilder {
func NewEnumBuilder(name string, baseType string, module string, docId string) *EnumBuilder {
return &EnumBuilder{
enum: Enum{
name: name,
baseType: baseType,
BaseIndexable: BaseIndexable{
module: module,
documentURI: docId,
Kind: protocol.CompletionItemKindEnum,
},
Expand Down
2 changes: 1 addition & 1 deletion server/lsp/indexables/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type Function struct {
}

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

func NewFunction(name string, returnType string, argumentIds []string, module string, docId string, idRange Range, docRange Range, kind protocol.CompletionItemKind) Function {
Expand Down
3 changes: 2 additions & 1 deletion server/lsp/indexables/functionBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type FunctionBuilder struct {
function Function
}

func NewFunctionBuilder(name string, returnType string, docId string) *FunctionBuilder {
func NewFunctionBuilder(name string, returnType string, module string, docId string) *FunctionBuilder {
return &FunctionBuilder{
function: Function{
fType: UserDefined,
Expand All @@ -18,6 +18,7 @@ func NewFunctionBuilder(name string, returnType string, docId string) *FunctionB
Structs: make(map[string]Struct),
ChildrenFunctions: make(map[string]*Function),
BaseIndexable: BaseIndexable{
module: module,
documentURI: docId,
Kind: protocol.CompletionItemKindFunction,
},
Expand Down
3 changes: 2 additions & 1 deletion server/lsp/indexables/variableBuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ type VariableBuilder struct {
}

// NewVariableBuilder
func NewVariableBuilder(name string, variableType string, docId string) *VariableBuilder {
func NewVariableBuilder(name string, variableType string, module string, docId string) *VariableBuilder {
return &VariableBuilder{
variable: Variable{
name: name,
Type: variableType,
BaseIndexable: BaseIndexable{
module: module,
documentURI: docId,
Kind: protocol.CompletionItemKindVariable,
},
Expand Down
32 changes: 16 additions & 16 deletions server/lsp/language_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestLanguage_FindHoverInformation(t *testing.T) {
language := NewLanguage()
parser := createParser()

doc := NewDocumentFromString("x", `
doc := NewDocumentFromString("x", "", `
int value = 1;
fn void main() {
char value = 3;
Expand Down Expand Up @@ -46,14 +46,14 @@ func TestLanguage_FindHoverInformationFromDifferentFile(t *testing.T) {
language := NewLanguage()
parser := createParser()

doc := NewDocumentFromString("x", `
doc := NewDocumentFromString("x", "x", `
fn void main() {
importedMethod();
}
`)
language.RefreshDocumentIdentifiers(&doc, &parser)

doc2 := NewDocumentFromString("y", `
doc2 := NewDocumentFromString("y", "x", `
fn void importedMethod() {}
`)
language.RefreshDocumentIdentifiers(&doc2, &parser)
Expand Down Expand Up @@ -87,6 +87,7 @@ func newDeclarationParams(docId string, line protocol.UInteger, char protocol.UI
}
}
func TestLanguage_FindSymbolDeclarationInWorkspace_symbol_same_scope(t *testing.T) {
module := "mod"
cases := []struct {
name string
sourceCode string
Expand All @@ -99,7 +100,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_symbol_same_scope(t *testing.
`int value=1;value=3;`,
"value",
0, 13,
idx.NewVariableBuilder("value", "int", "x").
idx.NewVariableBuilder("value", "int", module, "x").
WithIdentifierRange(0, 4, 0, 9).
WithDocumentRange(0, 0, 0, 12).
Build()},
Expand All @@ -108,7 +109,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_symbol_same_scope(t *testing.
`enum Colors = { RED, BLUE, GREEN };Colors foo = RED;`,
"Colors",
0, 36,
idx.NewEnumBuilder("Colors", "", "x").
idx.NewEnumBuilder("Colors", "", module, "x").
WithIdentifierRange(0, 5, 0, 11).
WithDocumentRange(0, 0, 0, 34).
WithEnumerator(
Expand Down Expand Up @@ -142,11 +143,10 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_symbol_same_scope(t *testing.
`struct MyStructure {bool enabled; char key;} MyStructure value;`,
"MyStructure",
0, 47,
createStruct("x", "MyStructure", []idx.StructMember{
createStruct("x", module, "MyStructure", []idx.StructMember{
idx.NewStructMember("enabled", "bool", idx.NewRange(0, 20, 0, 33)),
idx.NewStructMember("key", "char", idx.NewRange(0, 34, 0, 43)),
},
idx.NewRange(0, 7, 0, 18)),
}, idx.NewRange(0, 7, 0, 18)),
},
{
"def",
Expand All @@ -163,7 +163,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_symbol_same_scope(t *testing.

for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
doc := NewDocumentFromString("x", tt.sourceCode)
doc := NewDocumentFromString("x", module, tt.sourceCode)
language := NewLanguage()
parser := createParser()
language.RefreshDocumentIdentifiers(&doc, &parser)
Expand All @@ -180,7 +180,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_symbol_same_scope(t *testing.
func TestLanguage_FindSymbolDeclarationInWorkspace_variable_same_scope(t *testing.T) {
language := NewLanguage()
parser := createParser()
doc := NewDocumentFromString("x", `
doc := NewDocumentFromString("x", "mod", `
int value = 1;
value = 3;
`)
Expand All @@ -196,7 +196,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_same_scope(t *testin

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

expectedSymbol := idx.NewVariableBuilder("value", "int", "x").
expectedSymbol := idx.NewVariableBuilder("value", "int", "mod", "x").
WithIdentifierRange(1, 6, 1, 11).
WithDocumentRange(1, 2, 1, 16).
Build()
Expand All @@ -207,7 +207,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_same_scope(t *testin
func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_function(t *testing.T) {
language := NewLanguage()
parser := createParser()
doc := NewDocumentFromString("x", `
doc := NewDocumentFromString("x", "mod", `
int value = 1;
fn void main() {
value = 3;
Expand All @@ -225,7 +225,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_func

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

expectedSymbol := idx.NewVariableBuilder("value", "int", "x").
expectedSymbol := idx.NewVariableBuilder("value", "int", "mod", "x").
WithIdentifierRange(1, 6, 1, 11).
WithDocumentRange(1, 2, 1, 16).
Build()
Expand All @@ -236,13 +236,13 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_func
func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_file(t *testing.T) {
language := NewLanguage()
parser := createParser()
doc := NewDocumentFromString("x", `
doc := NewDocumentFromString("x", "mod", `
fn void main() {
value = 3;
}
`)
language.RefreshDocumentIdentifiers(&doc, &parser)
doc2 := NewDocumentFromString("y", `int value = 1;`)
doc2 := NewDocumentFromString("y", "mod", `int value = 1;`)
language.RefreshDocumentIdentifiers(&doc2, &parser)

params := protocol.DeclarationParams{
Expand All @@ -255,7 +255,7 @@ func TestLanguage_FindSymbolDeclarationInWorkspace_variable_outside_current_file

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

expectedSymbol := idx.NewVariableBuilder("value", "int", "y").
expectedSymbol := idx.NewVariableBuilder("value", "int", "mod", "y").
WithIdentifierRange(0, 4, 0, 9).
WithDocumentRange(0, 0, 0, 14).
Build()
Expand Down
52 changes: 44 additions & 8 deletions server/lsp/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import (
sitter "github.com/smacker/go-tree-sitter"
"github.com/tliron/commonlog"
protocol "github.com/tliron/glsp/protocol_3_16"
"path/filepath"
"regexp"
"strings"
"unsafe"
)

const ModuleQuery = `(source_file (module_declaration) @module)`
const VarDeclarationQuery = `(var_declaration
name: (identifier) @variable_name
)`
Expand Down Expand Up @@ -66,8 +70,7 @@ func (p *Parser) ExtractSymbols(doc *Document) idx.Function {
qc.Exec(q, doc.parsedTree.RootNode())
sourceCode := []byte(doc.Content)

//functionsMap := make(map[string]*idx.Function)
scopeTree := idx.NewAnonymousScopeFunction("main", "", doc.URI, idx.NewRangeFromSitterPositions(doc.parsedTree.RootNode().StartPoint(), doc.parsedTree.RootNode().EndPoint()), protocol.CompletionItemKindModule)
scopeTree := idx.NewAnonymousScopeFunction("main", doc.ModuleName, doc.URI, idx.NewRangeFromSitterPositions(doc.parsedTree.RootNode().StartPoint(), doc.parsedTree.RootNode().EndPoint()), protocol.CompletionItemKindModule)

for {
m, ok := qc.NextMatch()
Expand Down Expand Up @@ -108,7 +111,7 @@ func (p *Parser) ExtractSymbols(doc *Document) idx.Function {
func (p *Parser) nodeToVariable(doc *Document, variableNode *sitter.Node, 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(identifierNode.StartPoint(), identifierNode.EndPoint()), idx.NewRangeFromSitterPositions(variableNode.StartPoint(), variableNode.EndPoint()))
variable := idx.NewVariable(content, typeNodeContent, doc.ModuleName, doc.URI, idx.NewRangeFromSitterPositions(identifierNode.StartPoint(), identifierNode.EndPoint()), idx.NewRangeFromSitterPositions(variableNode.StartPoint(), variableNode.EndPoint()))

return variable
}
Expand All @@ -133,7 +136,7 @@ func (p *Parser) nodeToFunction(doc *Document, node *sitter.Node, sourceCode []b
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)
symbol := idx.NewFunction(nameNode.Content(sourceCode), node.ChildByFieldName("return_type").Content(sourceCode), argumentIds, doc.ModuleName, 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...)
Expand Down Expand Up @@ -170,7 +173,7 @@ func (p *Parser) nodeToArgument(doc *Document, argNode *sitter.Node, sourceCode
idRange = idx.NewRangeFromSitterPositions(idNode.StartPoint(), idNode.EndPoint())
}

variable := idx.NewVariable(identifier, argType, "", doc.URI, idRange, idx.NewRangeFromSitterPositions(argNode.StartPoint(), argNode.EndPoint()))
variable := idx.NewVariable(identifier, argType, doc.ModuleName, doc.URI, idRange, idx.NewRangeFromSitterPositions(argNode.StartPoint(), argNode.EndPoint()))

return variable
}
Expand All @@ -196,7 +199,7 @@ func (p *Parser) nodeToStruct(doc *Document, node *sitter.Node, sourceCode []byt
}
}

_struct := idx.NewStruct(name, fields, "", doc.URI, idx.NewRangeFromSitterPositions(nameNode.StartPoint(), nameNode.EndPoint()))
_struct := idx.NewStruct(name, fields, doc.ModuleName, doc.URI, idx.NewRangeFromSitterPositions(nameNode.StartPoint(), nameNode.EndPoint()))

return _struct
}
Expand All @@ -209,7 +212,7 @@ func (p *Parser) nodeToEnum(doc *Document, node *sitter.Node, sourceCode []byte)
baseType := ""
bodyIndex := int(nodesCount - 1)

enum := idx.NewEnum(nameNode.Content(sourceCode), baseType, []idx.Enumerator{}, "", doc.URI, idx.NewRangeFromSitterPositions(nameNode.StartPoint(), nameNode.EndPoint()), idx.NewRangeFromSitterPositions(node.StartPoint(), node.EndPoint()))
enum := idx.NewEnum(nameNode.Content(sourceCode), baseType, []idx.Enumerator{}, doc.ModuleName, doc.URI, idx.NewRangeFromSitterPositions(nameNode.StartPoint(), nameNode.EndPoint()), idx.NewRangeFromSitterPositions(node.StartPoint(), node.EndPoint()))

enumeratorsNode := node.Child(bodyIndex)

Expand Down Expand Up @@ -297,7 +300,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, "", []string{}, "", 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.ModuleName, 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 All @@ -306,3 +309,36 @@ func (p *Parser) FindFunctionDeclarations(doc *Document) []idx.Indexable {

return identifiers
}

func (p *Parser) ExtractModuleName(doc *Document) string {

q, err := sitter.NewQuery([]byte(ModuleQuery), getLanguage())
if err != nil {
panic(err)
}
qc := sitter.NewQueryCursor()
qc.Exec(q, doc.parsedTree.RootNode())
sourceCode := []byte(doc.Content)

var moduleName string
for {
m, ok := qc.NextMatch()
if !ok {
break
}

for _, c := range m.Captures {
moduleName = c.Node.Content(sourceCode)
moduleName = moduleName
}
}

if moduleName == "" {
moduleName = filepath.Base(doc.URI)
moduleName = strings.TrimSuffix(moduleName, filepath.Ext(moduleName))
regexpPattern := regexp.MustCompile(`[^_0-9a-z]`)
moduleName = regexpPattern.ReplaceAllString(moduleName, "_")
}

return moduleName
}
Loading

0 comments on commit 8622d8c

Please sign in to comment.