Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Encountering EProxies after building projects in new workspace
Encountering EProxies after building projects in new workspace [message #1859681] Thu, 22 June 2023 09:33 Go to next message
Lars Fritsche is currently offline Lars FritscheFriend
Messages: 10
Registered: April 2017
Junior Member
Hi,

I have a rather peculiar problem with my Xtext project, which works most of the times.

However, I encounter some errors when creating a new workspace, importing my projects from git and then building them.
This only happens for new workspaces or when I create some sort of dirty state by forcefully closing the runtime workspace from my developer workspace and then building the projects anew.

In both cases, I find that the resources given to me via the doGenerate method contain eproxies that I cannot resolve.
Yet, building a second time somehow solves these issues and the resources are intact.

Here is a small snippet of my grammar:

@Override
SlimRuleNodeContext: {SlimRuleNodeContext}
	'[=]' (local?='local')? context = SlimRuleNode
;

@Override
SlimRuleNodeCreation: {SlimRuleNodeCreation}
	'[+]' creation = SlimRuleNode
;

@Override
SlimRuleNode: {SlimRuleNode}
	name = ID ':' type=[ecore::EClass | QualifiedName] ('{'
		(contextEdges += SlimRuleEdgeContext |
		createdEdges += SlimRuleEdgeCreation)*
	'}')?

SlimRuleEdgeContext:
	'[=]' context = SlimRuleSimpleEdge
;

SlimRuleEdgeCreation:
	'[+]' creation = SlimRuleSimpleEdge
;

SlimRuleSimpleEdge returns SlimRuleEdge: {SlimRuleSimpleEdge}
	'-' type=[ecore::EReference|ValidID] '->' target=[SlimRuleNode|ID]
;

;


I simplified it a bit and omitted some parts but the Overrides come from another common language of ours.
Now, I want to define two nodes with one edge edge between them just as in the following example:
[=] p : J.Package {
	[+] -clazzes->c
}
[+] c : J.Clazz


What happens is that the first time doGenerate is called, I would get p and c as well as the SlimRuleEdgeCreation for the edge between p and c.
However, both the type of the edge (Packages and Clazzes are connected via a clazzes reference) and the target, which should by a crossreference to the element c are eproxies:

SlimRuleNodeContext: org.emoflon.ibex.tgg.tggl.tGGL.impl.SlimRuleNodeContextImpl@17a32f28 (local: false) (refining: false)
SlimRuleNodeContext.context: org.emoflon.ibex.tgg.tggl.tGGL.impl.SlimRuleNodeImpl@253e9c2d (name: p)
SlimRuleNode.context.createdEdges: org.emoflon.ibex.common.slimgt.slimGT.impl.SlimRuleEdgeCreationImpl@5722a66b
SlimRuleNode.context.createdEdges.creation: org.emoflon.ibex.common.slimgt.slimGT.impl.SlimRuleSimpleEdgeImpl@2e4ee9e0
SlimRuleNode.context.createdEdges.creation.target: org.emoflon.ibex.common.slimgt.slimGT.impl.SlimRuleNodeImpl@54c2fe94 (eProxyURI: platform:/resource/Java2Doc/src/org/emoflon/ibex/tgg/rules/Class2Doc.tggl#|2)
SlimRuleNode.context.createdEdges.creation.type: org.eclipse.emf.ecore.impl.EReferenceImpl@29dd10d2 (eProxyURI: platform:/resource/Java2Doc/src/org/emoflon/ibex/tgg/rules/Class2Doc.tggl#|1)


Did anyone encounter a similar problem and was able to solve it somehow?
As it stands, I am quite confused and not sure how to debug this.
I figured that the Scoper might not be robust enough for this startup problem and that there is some corner case that I didn't anticipate.
But it isn't called before doGenerate here.

Thanks in advance for any help!

Cheers
Lars

[Updated on: Thu, 22 June 2023 09:34]

Report message to a moderator

Re: Encountering EProxies after building projects in new workspace [message #1859682 is a reply to message #1859681] Thu, 22 June 2023 09:35 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14735
Registered: July 2009
Senior Member
i propose to debug indexing (ClusteringBuilderState.writeNew....) and linking (DefaultLinkingService)
do you have any special stuff implemented in name providers, scoping, ....


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
Re: Encountering EProxies after building projects in new workspace [message #1859683 is a reply to message #1859682] Thu, 22 June 2023 10:23 Go to previous messageGo to next message
Lars Fritsche is currently offline Lars FritscheFriend
Messages: 10
Registered: April 2017
Junior Member
Hi,

thanks for the fast reply.
I'll try to debug both.
Regarding our features, there are indeed some special things happening.

These nodes from my last post are part of rules and these rules can extend each other.
Hence, an edge may reference a node from an entirely different rule, which may live in another file.

Not sure if this is related but one thing that we have to solve are naming collisions to make these references unambiguous.
In our language, a rule can extend from multiple rules, which means that we need aliases to distinguish between them, e.g., rule X refines Y as A, Y as B for cases where you want to extend your rule twice with structures from one the same rule.
However, importing nodes from another rule or in this case extending the same rule twice can lead to naming collisions (which we catch and highlight via the validator).
You can resolve these cases by overriding nodes and giving them a new name like "node x refines A.y, B.y" (because "node x refines Y.y, Y.y" would be ambiguous), which would basically merge them and solve the naming collision.
Yet, this means that we need QualifiedNames to identify where a node stems from and thus a special scope with two NameProviders (once with Alias (A.y,B.y) and once without (Y.y)).
But when it comes to creating Edges between elements, we rely on simple IDs as these collision must be resolved.

Hence, the scoper has to (transitively) search for nodes in other rules omitting those that have been overridden in the current rule.

Just in case that this scope and name provider is of interest I add it here:
public class TGGLAliasedRuleScope extends SimpleScope {

	public TGGLAliasedRuleScope(Collection<TGGLRuleRefinementAliased> ruleRefinementAliases, Map<TGGRule, Collection<EObject>> rule2refinedNodes) {
		super(calculcateScopes(ruleRefinementAliases, rule2refinedNodes));
	}
	
        // Collect all rule refinements and then create FQ scopes for each node
	private static Iterable<IEObjectDescription> calculcateScopes(Collection<TGGLRuleRefinementAliased> ruleRefinementAliases, Map<TGGRule, Collection<EObject>> rule2refinedNodes) {
		Map<String, String> ruleName2alias = new HashMap<>();

		for(var alias : ruleRefinementAliases) {
			ruleName2alias.put(alias.getSuperRule().getName(), alias.getName());
		}
		
		Collection<IEObjectDescription> scopes = new LinkedList<>();
		for(var rule : rule2refinedNodes.keySet()) {
			if(ruleName2alias.containsKey(rule.getName())) {
				var aliasName = ruleName2alias.get(rule.getName());
				var iterable = Scopes.scopedElementsFor(rule2refinedNodes.get(rule), new RuleAliasedNamedProvider(aliasName));
				iterable.forEach(scopes::add);
			}
			var iterable = Scopes.scopedElementsFor(rule2refinedNodes.get(rule), new RuleAwareQualifiedNamedProvider(rule));
			iterable.forEach(scopes::add);
			
		}
		return scopes;
	}
	
	@Override
	public Iterable<IEObjectDescription> getElements(final EObject object) {
		Iterable<IEObjectDescription> defaultImpl = super.getElements(object);
		if (defaultImpl.iterator().hasNext())
			return defaultImpl;

		// If default does not work, try using the exact URI of object (no normalization etc)
		Iterable<IEObjectDescription> localElements = getLocalElementsByEObject(object, EcoreUtil.getURI(object));
		Iterable<IEObjectDescription> parentElements = getParentElements(new Provider<Iterable<IEObjectDescription>>() {
			@Override
			public Iterable<IEObjectDescription> get() {
				return getParent().getElements(object);
			}
		});
		Iterable<IEObjectDescription> result = Iterables.concat(localElements, parentElements);
		return result;
	}

}

class RuleAliasedNamedProvider extends DefaultDeclarativeQualifiedNameProvider {
	
	private String aliasName;
	
	public RuleAliasedNamedProvider(String aliasName) {
		this.aliasName = aliasName;
	}
	
	@Override
	public QualifiedName getFullyQualifiedName(EObject obj) {
		
		if(obj instanceof SlimRuleNode node) {
			var tggRule = SlimGTModelUtil.getContainer(obj, TGGRule.class);
			if(tggRule == null)
				return super.getFullyQualifiedName(obj);
			
			IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
			return converter.toQualifiedName(aliasName + "." + node.getName());
		}
		
		return super.getFullyQualifiedName(obj);
	}
}

class RuleAwareQualifiedNamedProvider extends DefaultDeclarativeQualifiedNameProvider {

	private TGGRule rule;
	
	public RuleAwareQualifiedNamedProvider(TGGRule rule) {
		this.rule = rule;
	}
	
	@Override
	public QualifiedName getFullyQualifiedName(EObject obj) {
		var tggRule = rule;
		if(obj instanceof SlimRuleNode node) {
			if(tggRule == null)
				tggRule = SlimGTModelUtil.getContainer(obj, TGGRule.class);
			if(tggRule == null)
				return super.getFullyQualifiedName(obj);
			
			IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
			return converter.toQualifiedName(tggRule.getName() + "." + node.getName());
		}
		
		return super.getFullyQualifiedName(obj);
	}
}
Re: Encountering EProxies after building projects in new workspace [message #1859684 is a reply to message #1859683] Thu, 22 June 2023 10:35 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14735
Registered: July 2009
Senior Member
calculating one scope on another reference should per se work. ususally this is not done in the scope impl itself but in the scope provider
=> you need to debug / log what is seen and what is not.
and if the parents you look at are themselves proxies and if yes why.

maybe you can do the calculation purely based on the index.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com

[Updated on: Thu, 22 June 2023 10:40]

Report message to a moderator

Previous Topic:Generate Xtext grammar from Ecore file without the project wizard
Next Topic:Custom scope provider
Goto Forum:
  


Current Time: Thu Dec 05 20:34:24 GMT 2024

Powered by FUDForum. Page generated in 0.03635 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top