Files
marte_dev_tools/internal/index/index.go
Martino Ferrari 69d3360289 Working
2026-01-19 23:10:09 +01:00

125 lines
2.6 KiB
Go

package index
import (
"github.com/marte-dev/marte-dev-tools/internal/parser"
)
type SymbolType int
const (
SymbolObject SymbolType = iota
SymbolSignal
SymbolDataSource
SymbolGAM
)
type Symbol struct {
Name string
Type SymbolType
Position parser.Position
File string
Doc string
Class string
Parent *Symbol
}
type Reference struct {
Name string
Position parser.Position
File string
Target *Symbol
}
type Index struct {
Symbols map[string]*Symbol
References []Reference
Packages map[string][]string // pkgURI -> list of files
}
func NewIndex() *Index {
return &Index{
Symbols: make(map[string]*Symbol),
Packages: make(map[string][]string),
}
}
func (idx *Index) IndexConfig(file string, config *parser.Configuration) {
pkgURI := ""
if config.Package != nil {
pkgURI = config.Package.URI
}
idx.Packages[pkgURI] = append(idx.Packages[pkgURI], file)
for _, def := range config.Definitions {
idx.indexDefinition(file, "", nil, def)
}
}
func (idx *Index) indexDefinition(file string, path string, parent *Symbol, def parser.Definition) {
switch d := def.(type) {
case *parser.ObjectNode:
name := d.Name
fullPath := name
if path != "" {
fullPath = path + "." + name
}
class := ""
for _, subDef := range d.Subnode.Definitions {
if f, ok := subDef.(*parser.Field); ok && f.Name == "Class" {
if s, ok := f.Value.(*parser.StringValue); ok {
class = s.Value
} else if r, ok := f.Value.(*parser.ReferenceValue); ok {
class = r.Value
}
}
}
symType := SymbolObject
// Simple heuristic for GAM or DataSource if class name matches or node name starts with +/$
// In a real implementation we would check the class against known MARTe classes
sym := &Symbol{
Name: fullPath,
Type: symType,
Position: d.Position,
File: file,
Class: class,
Parent: parent,
}
idx.Symbols[fullPath] = sym
for _, subDef := range d.Subnode.Definitions {
idx.indexDefinition(file, fullPath, sym, subDef)
}
case *parser.Field:
idx.indexValue(file, d.Value)
}
}
func (idx *Index) indexValue(file string, val parser.Value) {
switch v := val.(type) {
case *parser.ReferenceValue:
idx.References = append(idx.References, Reference{
Name: v.Value,
Position: v.Position,
File: file,
})
case *parser.ArrayValue:
for _, elem := range v.Elements {
idx.indexValue(file, elem)
}
}
}
func (idx *Index) ResolveReferences() {
for i := range idx.References {
ref := &idx.References[i]
if sym, ok := idx.Symbols[ref.Name]; ok {
ref.Target = sym
} else {
// Try relative resolution?
}
}
}