Skip to content

Commit

Permalink
Reorganize server to keep a symbol table.
Browse files Browse the repository at this point in the history
  • Loading branch information
pherrymason committed Jan 17, 2025
1 parent 2374317 commit e946556
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 21 deletions.
6 changes: 3 additions & 3 deletions server/internal/lsp/analysis/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func getPositionContext(document *document.Document, pos lsp.Position) PositionC
return posContext
}

func FindSymbolAtPosition(pos lsp.Position, fileName string, symbolTable SymbolTable, tree ast.Node) option.Option[*Symbol] {
func FindSymbolAtPosition(pos lsp.Position, fileName string, symbolTable *SymbolTable, tree ast.Node) option.Option[*Symbol] {
nodeAtPosition, path := FindNode(tree, pos)

var name string
Expand Down Expand Up @@ -128,7 +128,7 @@ func FindSymbolAtPosition(pos lsp.Position, fileName string, symbolTable SymbolT
}

// solveSelAtSelectorExpr resolves Sel Ident symbol.
func solveSelAtSelectorExpr(selectorExpr *ast.SelectorExpr, pos lsp.Position, fileName string, moduleName ModuleName, symbolTable SymbolTable, deepLevel uint) *Symbol {
func solveSelAtSelectorExpr(selectorExpr *ast.SelectorExpr, pos lsp.Position, fileName string, moduleName ModuleName, symbolTable *SymbolTable, deepLevel uint) *Symbol {
// To be able to resolve selectorExpr.Sel, we need to know first what is selectorExpr.X is or what does it return.
var parentSymbol *Symbol
switch base := selectorExpr.X.(type) {
Expand Down Expand Up @@ -172,7 +172,7 @@ func solveSelAtSelectorExpr(selectorExpr *ast.SelectorExpr, pos lsp.Position, fi
if deepLevel == 0 {
solveElementType = false
}
return resolveChildSymbol(parentSymbol, selectorExpr.Sel.Name, moduleName, fileName, &symbolTable, solveElementType)
return resolveChildSymbol(parentSymbol, selectorExpr.Sel.Name, moduleName, fileName, symbolTable, solveElementType)
}

func resolveChildSymbol(symbol *Symbol, nextIdent string, moduleName ModuleName, fileName string, symbolTable *SymbolTable, solveType bool) *Symbol {
Expand Down
4 changes: 3 additions & 1 deletion server/internal/lsp/analysis/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
protocol "github.com/tliron/glsp/protocol_3_16"
)

func GetDefinitionLocation(document *document.Document, pos lsp.Position, storage *document.Storage) []protocol.Location {
func GetDefinitionLocation(document *document.Document, pos lsp.Position, storage *document.Storage, symbolTable *SymbolTable) []protocol.Location {

posContext := getPositionContext(document, pos)

Expand All @@ -20,6 +20,8 @@ func GetDefinitionLocation(document *document.Document, pos lsp.Position, storag
}
}

FindSymbolAtPosition(pos, document.FullPath, symbolTable, document.Ast)

return []protocol.Location{}
}

Expand Down
20 changes: 15 additions & 5 deletions server/internal/lsp/analysis/symbol_table_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import (
"github.com/pherrymason/c3-lsp/internal/lsp/ast/walk"
)

func BuildSymbolTable(astTree ast.Node, fileName string) SymbolTable {
visitor := newSymbolTableVisitor()
func BuildSymbolTable(astTree ast.Node, fileName string) *SymbolTable {
visitor := newSymbolTableVisitor(nil)
walk.Walk(&visitor, astTree, "")

return visitor.table
}
func UpdateSymbolTable(symbolTable *SymbolTable, astTree ast.Node, fileName string) {
visitor := newSymbolTableVisitor(symbolTable)
walk.Walk(&visitor, astTree, "")
}

type symbolTableGenerator struct {
table SymbolTable
table *SymbolTable

// State properties to keep track
currentModule ast.Module
Expand All @@ -22,9 +26,15 @@ type symbolTableGenerator struct {
scopePushed uint
}

func newSymbolTableVisitor() symbolTableGenerator {
func newSymbolTableVisitor(symbolTable *SymbolTable) symbolTableGenerator {
if symbolTable == nil {
return symbolTableGenerator{
table: NewSymbolTable(),
}
}

return symbolTableGenerator{
table: *NewSymbolTable(),
table: symbolTable,
}
}

Expand Down
6 changes: 3 additions & 3 deletions server/internal/lsp/document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ func NewStore() *Storage {
}
}

func (pd *Storage) OpenDocument(uri string, text string, version uint) {
converter := factory.NewASTConverter()
func (pd *Storage) OpenDocument(uri string, text string, version uint) *Document {
document := &Document{
Uri: uri,
FullPath: utils.NormalizePath(uri),
Text: text,
Owned: true,
Version: version,
Ast: converter.ConvertToAST(factory.GetCST(text), text, uri),
}

pd.Documents[uri] = document

return document
}

func (pd *Storage) OpenDocumentFromPath(path string, text string, version uint) {
Expand Down
2 changes: 1 addition & 1 deletion server/internal/lsp/server/TextDocumentDefinition.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func (srv *Server) TextDocumentDefinition(context *glsp.Context, params *protocol.DefinitionParams) (any, error) {
if featureflags.IsActive(featureflags.UseGeneratedAST) {
doc, _ := srv.documents.GetDocument(params.TextDocument.URI)
locations := analysis.GetDefinitionLocation(doc, lsp.NewLSPPosition(params.Position), srv.documents)
locations := analysis.GetDefinitionLocation(doc, lsp.NewLSPPosition(params.Position), srv.documents, srv.symbolTable)
return locations, nil
}

Expand Down
10 changes: 9 additions & 1 deletion server/internal/lsp/server/TextDocumentDidOpen.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package server

import (
"github.com/pherrymason/c3-lsp/internal/lsp/analysis"
"github.com/pherrymason/c3-lsp/internal/lsp/ast/factory"
"github.com/pherrymason/c3-lsp/pkg/document"
"github.com/pherrymason/c3-lsp/pkg/featureflags"
"github.com/tliron/glsp"
Expand All @@ -14,7 +16,13 @@ func (srv *Server) TextDocumentDidOpen(context *glsp.Context, params *protocol.D
}

if featureflags.IsActive(featureflags.UseGeneratedAST) {
srv.documents.OpenDocument(params.TextDocument.URI, params.TextDocument.Text, uint(params.TextDocument.Version))
doc := srv.documents.OpenDocument(params.TextDocument.URI, params.TextDocument.Text, uint(params.TextDocument.Version))

// Build AST tree node
doc.Ast = srv.astConverter.ConvertToAST(factory.GetCST(doc.Text), doc.Text, doc.Uri)
// Extract Symbols
analysis.UpdateSymbolTable(srv.symbolTable, &doc.Ast, "")

} else {
doc := document.NewDocumentFromDocURI(params.TextDocument.URI, params.TextDocument.Text, params.TextDocument.Version)
srv.state.RefreshDocumentIdentifiers(doc, srv.parser)
Expand Down
21 changes: 14 additions & 7 deletions server/internal/lsp/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package server

import (
"fmt"
"github.com/pherrymason/c3-lsp/internal/lsp/analysis"
"github.com/pherrymason/c3-lsp/internal/lsp/ast/factory"
"github.com/pherrymason/c3-lsp/internal/lsp/document"
"log"
"time"
Expand All @@ -26,11 +28,13 @@ type Server struct {
options ServerOpts
version string

documents *document.Storage
documents *document.Storage
astConverter *factory.ASTConverter
symbolTable *analysis.SymbolTable

state *ps.ProjectState
state *ps.ProjectState // To remove on 0.4 release
parser *p.Parser
search search.Search
search search.Search // To remove on 0.4 release

diagnosticDebounced func(func())
}
Expand Down Expand Up @@ -70,10 +74,13 @@ func NewServer(opts ServerOpts, appName string, version string) *Server {
options: opts,
version: version,

documents: document.NewStore(),
state: &state,
parser: &parser,
search: search,
documents: document.NewStore(),
astConverter: factory.NewASTConverter(),
symbolTable: analysis.NewSymbolTable(),

state: &state,
parser: &parser,
search: search,

diagnosticDebounced: debounce.New(opts.Diagnostics.Delay * time.Millisecond),
}
Expand Down

0 comments on commit e946556

Please sign in to comment.