Skip to content

Commit c715423

Browse files
committed
fix: utils on ProxyCompositeNode to adapt node arguments.
NodeModelUtils typically calls Node.utils() and passes the node to the implementation method. ProxyCompositeNode is now fixed so that the loaded node rather than the proxy is passed to the implementation method.
1 parent 44bf4dd commit c715423

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/ProxyCompositeNode.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import org.eclipse.emf.common.util.URI;
2222
import org.eclipse.emf.common.util.WrappedException;
2323
import org.eclipse.emf.ecore.EObject;
24+
import org.eclipse.emf.ecore.EStructuralFeature;
2425
import org.eclipse.emf.ecore.InternalEObject;
2526
import org.eclipse.emf.ecore.resource.Resource;
2627
import org.eclipse.emf.ecore.util.EcoreUtil;
28+
import org.eclipse.xtext.ParserRule;
2729
import org.eclipse.xtext.nodemodel.BidiIterable;
2830
import org.eclipse.xtext.nodemodel.BidiTreeIterable;
2931
import org.eclipse.xtext.nodemodel.BidiTreeIterator;
@@ -42,6 +44,7 @@
4244
import org.eclipse.xtext.resource.persistence.StorageAwareResource;
4345
import org.eclipse.xtext.util.ITextRegion;
4446
import org.eclipse.xtext.util.ITextRegionWithLineInformation;
47+
import org.eclipse.xtext.util.LineAndColumn;
4548

4649
import com.avaloq.tools.ddk.annotations.SuppressFBWarnings;
4750

@@ -405,7 +408,59 @@ public void setTarget(final Notifier newTarget) {
405408

406409
@Override
407410
public NodeModelUtils.Implementation utils() {
408-
return delegate().utils();
411+
// return an implementation that adapts the proxy node to the delegate on each Node parameter
412+
return new NodeModelUtils.Implementation() {
413+
private final ICompositeNode loadedNode = delegate();
414+
415+
@SuppressWarnings("unchecked")
416+
private <N extends INode> N adapt(final N node) {
417+
if (node == ProxyCompositeNode.this) {
418+
// adapt() is only ever called with INodes and ICompositeNodes, so it is safe to cast to N here.
419+
return (N) loadedNode;
420+
}
421+
return node;
422+
}
423+
424+
@Override
425+
public ILeafNode findLeafNodeAtOffset(final INode node, final int leafNodeOffset) {
426+
return loadedNode.utils().findLeafNodeAtOffset(adapt(node), leafNodeOffset);
427+
}
428+
429+
@Override
430+
public LineAndColumn getLineAndColumn(final INode anyNode, final int documentOffset) {
431+
return loadedNode.utils().getLineAndColumn(adapt(anyNode), documentOffset);
432+
}
433+
434+
@Override
435+
public List<INode> findNodesForFeature(final EObject semanticElement, final INode node, final EStructuralFeature structuralFeature) {
436+
return loadedNode.utils().findNodesForFeature(semanticElement, adapt(node), structuralFeature);
437+
}
438+
439+
@Override
440+
public ICompositeNode findActualNodeEnclosing(final ICompositeNode node) {
441+
return loadedNode.utils().findActualNodeEnclosing(adapt(node));
442+
}
443+
444+
@Override
445+
public EObject findActualSemanticObjectFor(final INode node) {
446+
return loadedNode.utils().findActualSemanticObjectFor(adapt(node));
447+
}
448+
449+
@Override
450+
public String compactDump(final INode node, final boolean showHidden) {
451+
return loadedNode.utils().compactDump(adapt(node), showHidden);
452+
}
453+
454+
@Override
455+
public String getTokenText(final INode node) {
456+
return loadedNode.utils().getTokenText(adapt(node));
457+
}
458+
459+
@Override
460+
public ParserRule getEntryParserRule(final INode node) {
461+
return loadedNode.utils().getEntryParserRule(adapt(node));
462+
}
463+
};
409464
}
410465
}
411466

0 commit comments

Comments
 (0)