0

I have the following Xtext grammar part:

AssignmentStatement: (variable=[SymbolicVariable] | array=ArrayVariable) ':=' value=Expression;
ArrayVariable: varName=[SymbolicVariable] '[' index=Expression ']';
SymbolicVariable: name=ID;

and a test where id1 and id2 are SymbolicVariable, moreover SymbolicVariable can be part of Expression:

id1 := 0 < id2 [ 0 ]

In the test, id1 and id2 are not defined before since I am generating inputs as tests by the grammar and do not care on semantics. I want to create objects for them dynamically to get rid of:

ERROR:Couldn't resolve reference to SymbolicVariable 'id1'.

ERROR:Couldn't resolve reference to SymbolicVariable 'id2'.

while validation.

Following the ideas from post XText cross-reference to an non-DSL resource, I was able to create a ScopeProvider impl as well as a Scope impl:

class MyScope extends AbstractPoSTScopeProvider {
    
    override getScope(EObject context, EReference reference) {
        val res = context.eResource
        var uri = res.URI       
        val rs = res.resourceSet
        val scope = super.getScope(context, reference)
        if (context instanceof ArrayVariableImpl) new ScopeWrapper(scope, res) else scope
    }
}

class ScopeWrapper implements IScope {
    
    IScope scope;
    Resource resource;
    
    protected new(IScope w, Resource res) {
        scope = w
        resource = res
    }
    override getSingleElement(QualifiedName name) {
        println("[scope]getSingleElement " + name.toString())
        val r = scope.getSingleElement(name)
        if (r === null) {
            val fac = PoSTPackage.eINSTANCE.getPoSTFactory()
            var s = fac.createSymbolicVariable()
            s.name = name.toString()
            println("[!!!!! ] creation")
            Main.isChanged = true //to rerun in cause of modification 
            val ret = new MyDescr(s, name) //just a wrap
            resource.contents += s
            ret
        } else
        r
    }
    
}

After this injection, id2 is appeared and I can generate a code with it, but I still get

ERROR:Couldn't resolve reference to SymbolicVariable 'id1'.

and I do not see id1 anywhere during the debug.

Seems, for attributes we need some other magic. Which pattern should I follow?

SeregASM
  • 75
  • 12

1 Answers1

1

In the test, id1 and id2 are not defined before since I am generating inputs as tests by the grammar and do not care on semantics.

If you are generating your textual model id1 := 0 < id2 [ 0 ], I am not sure why you could not generate it as id1; id2; id1 := 0 < id2 [ 0 ] which would probably resolve OK.

If you really want to "create id1 and id2 dynamically", I think you need to customize your IScopeProvider implementation such that when computing the scopes for both references AssignmentStatement.variable and ArrayVariable.varName, if the parent implementation returns an empty scope, then you simply create a SymbolicVariable in memory and provide it in the returned scope.

user1292456
  • 778
  • 4
  • 12