better multi file variable support
This commit is contained in:
@@ -182,13 +182,7 @@ func (pt *ProjectTree) AddFile(file string, config *parser.Configuration) {
|
||||
}
|
||||
|
||||
if config.Package == nil {
|
||||
node := &ProjectNode{
|
||||
Children: make(map[string]*ProjectNode),
|
||||
Metadata: make(map[string]string),
|
||||
Variables: make(map[string]VariableInfo),
|
||||
}
|
||||
pt.IsolatedFiles[file] = node
|
||||
pt.populateNode(node, file, config)
|
||||
pt.populateNode(pt.Root, file, config)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -399,8 +393,9 @@ func (pt *ProjectTree) indexValue(file string, val parser.Value) {
|
||||
File: file,
|
||||
})
|
||||
case *parser.VariableReferenceValue:
|
||||
name := strings.TrimPrefix(v.Name, "@")
|
||||
pt.References = append(pt.References, Reference{
|
||||
Name: strings.TrimPrefix(v.Name, "@"),
|
||||
Name: name,
|
||||
Position: v.Position,
|
||||
File: file,
|
||||
IsVariable: true,
|
||||
|
||||
@@ -193,8 +193,8 @@ $App = {
|
||||
}
|
||||
}
|
||||
}
|
||||
if foundProjectDS {
|
||||
t.Error("Did not expect ProjectDS in isolated file suggestions")
|
||||
if !foundProjectDS {
|
||||
t.Error("Expected ProjectDS in isolated file suggestions (now shared root)")
|
||||
}
|
||||
|
||||
// Completion in a project file
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestLSPSignalReferences(t *testing.T) {
|
||||
v.ValidateProject()
|
||||
|
||||
// Find definition of MySig in MyDS
|
||||
root := idx.IsolatedFiles["signal_refs.marte"]
|
||||
root := idx.Root
|
||||
if root == nil {
|
||||
t.Fatal("Root node not found")
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ func TestIsolatedFileValidation(t *testing.T) {
|
||||
t.Fatal("Reference SharedObj not found in index")
|
||||
}
|
||||
|
||||
if ref.Target != nil {
|
||||
t.Errorf("Expected reference in isolated file to be unresolved, but got target in %s", ref.Target.Fragments[0].File)
|
||||
if ref.Target == nil {
|
||||
t.Errorf("Expected reference in root file (iso.marte) to resolve to global SharedObj")
|
||||
}
|
||||
}
|
||||
|
||||
87
test/variable_multifile_test.go
Normal file
87
test/variable_multifile_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/marte-community/marte-dev-tools/internal/index"
|
||||
"github.com/marte-community/marte-dev-tools/internal/parser"
|
||||
"github.com/marte-community/marte-dev-tools/internal/validator"
|
||||
)
|
||||
|
||||
func TestMultiFileVariableResolution(t *testing.T) {
|
||||
// File 1: Defines a variable in the root scope (no package)
|
||||
file1Content := `#package Test
|
||||
#var GlobalVal: int = 42`
|
||||
|
||||
// File 2: Uses the variable (no package)
|
||||
file2Content := `
|
||||
#package Test
|
||||
+App = {
|
||||
Class = RealTimeApplication
|
||||
Field = @GlobalVal
|
||||
}
|
||||
`
|
||||
|
||||
pt := index.NewProjectTree()
|
||||
|
||||
// Parse and add File 1
|
||||
p1 := parser.NewParser(file1Content)
|
||||
cfg1, err := p1.Parse()
|
||||
if err != nil {
|
||||
t.Fatalf("Parse file1 error: %v", err)
|
||||
}
|
||||
pt.AddFile("vars.marte", cfg1)
|
||||
|
||||
// Parse and add File 2
|
||||
p2 := parser.NewParser(file2Content)
|
||||
cfg2, err := p2.Parse()
|
||||
if err != nil {
|
||||
t.Fatalf("Parse file2 error: %v", err)
|
||||
}
|
||||
pt.AddFile("main.marte", cfg2)
|
||||
|
||||
pt.ResolveReferences()
|
||||
|
||||
// Validate
|
||||
// We need a dummy schema for CheckVariables to work, or we check References directly.
|
||||
// CheckVariables validates types. CheckUnresolvedVariables validates existence.
|
||||
// We want to check if $GlobalVal is resolved.
|
||||
|
||||
t.Logf("Root Variables keys: %v", getKeys(pt.Root.Variables))
|
||||
|
||||
v := validator.NewValidator(pt, ".")
|
||||
v.CheckUnresolvedVariables()
|
||||
|
||||
for _, d := range v.Diagnostics {
|
||||
if strings.Contains(d.Message, "Unresolved variable") {
|
||||
t.Errorf("Unexpected unresolved variable error: %s", d.Message)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify reference target directly
|
||||
found := false
|
||||
for _, ref := range pt.References {
|
||||
if ref.Name == "GlobalVal" {
|
||||
found = true
|
||||
if ref.TargetVariable == nil {
|
||||
t.Error("Reference 'GlobalVal' TargetVariable is nil (not resolved)")
|
||||
} else {
|
||||
if ref.TargetVariable.Name != "GlobalVal" {
|
||||
t.Errorf("Reference resolved to wrong variable: %s", ref.TargetVariable.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Error("Reference 'GlobalVal' not found in index")
|
||||
}
|
||||
}
|
||||
|
||||
func getKeys(m map[string]index.VariableInfo) []string {
|
||||
keys := []string{}
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
Reference in New Issue
Block a user