Preserve Gotlin semantics across packages

This commit is contained in:
pavel 2026-08-27 22:18:45 +02:00
commit acb42a5702
10 changed files with 525 additions and 34 deletions

View file

@ -326,27 +326,43 @@ func (s *server) buildDocumentState(uri, text string) documentState {
return state
}
state.program = program
programs, symbols := s.packageContext(uri, program.PackagePath, text)
_, semanticDiagnostics := lang.AnalyzeWithContext(program, programs)
programs, symbols, metadata := s.packageContext(uri, program.PackagePath, text)
_, semanticDiagnostics := lang.AnalyzeWithContextAndMetadata(program, programs, metadata)
state.symbols = indexSymbols(text, program)
state.packageSymbols = symbols
state.diagnostics = diagnosticsFromSemantic(text, semanticDiagnostics)
return state
}
func (s *server) packageContext(currentURI, packagePath, currentText string) ([]*lang.Program, []symbol) {
func (s *server) packageContext(currentURI, packagePath, currentText string) ([]*lang.Program, []symbol, []*lang.PackageMetadata) {
path, ok := filePathFromURI(currentURI)
if !ok {
return nil, nil
return nil, nil, nil
}
root := nearestWorkspaceRoot(filepath.Dir(path))
if root == "" {
root = nearestModuleRoot(filepath.Dir(path))
}
root := nearestModuleRoot(filepath.Dir(path))
if root == "" {
root = filepath.Dir(path)
}
var programs []*lang.Program
var symbols []symbol
var metadata []*lang.PackageMetadata
_ = filepath.WalkDir(root, func(candidate string, entry os.DirEntry, err error) error {
if err != nil || entry.IsDir() || filepath.Ext(candidate) != ".gt" {
if err != nil || entry.IsDir() {
return nil
}
if strings.HasSuffix(candidate, ".gti.json") {
if body, readErr := os.ReadFile(candidate); readErr == nil {
var item lang.PackageMetadata
if json.Unmarshal(body, &item) == nil && item.Version == lang.PackageMetadataVersion {
metadata = append(metadata, &item)
}
}
return nil
}
if filepath.Ext(candidate) != ".gt" {
return nil
}
candidateURI := fileURI(candidate)
@ -374,7 +390,20 @@ func (s *server) packageContext(currentURI, packagePath, currentText string) ([]
}
return nil
})
return programs, symbols
return programs, symbols, metadata
}
func nearestWorkspaceRoot(directory string) string {
for {
if _, err := os.Stat(filepath.Join(directory, "go.work")); err == nil {
return directory
}
parent := filepath.Dir(directory)
if parent == directory {
return ""
}
directory = parent
}
}
func nearestModuleRoot(directory string) string {