|
21 | 21 | import org.eclipse.emf.common.util.URI; |
22 | 22 | import org.eclipse.emf.common.util.WrappedException; |
23 | 23 | import org.eclipse.emf.ecore.EObject; |
| 24 | +import org.eclipse.emf.ecore.EStructuralFeature; |
24 | 25 | import org.eclipse.emf.ecore.InternalEObject; |
25 | 26 | import org.eclipse.emf.ecore.resource.Resource; |
26 | 27 | import org.eclipse.emf.ecore.util.EcoreUtil; |
| 28 | +import org.eclipse.xtext.ParserRule; |
27 | 29 | import org.eclipse.xtext.nodemodel.BidiIterable; |
28 | 30 | import org.eclipse.xtext.nodemodel.BidiTreeIterable; |
29 | 31 | import org.eclipse.xtext.nodemodel.BidiTreeIterator; |
|
42 | 44 | import org.eclipse.xtext.resource.persistence.StorageAwareResource; |
43 | 45 | import org.eclipse.xtext.util.ITextRegion; |
44 | 46 | import org.eclipse.xtext.util.ITextRegionWithLineInformation; |
| 47 | +import org.eclipse.xtext.util.LineAndColumn; |
45 | 48 |
|
46 | 49 | import com.avaloq.tools.ddk.annotations.SuppressFBWarnings; |
47 | 50 |
|
@@ -405,7 +408,59 @@ public void setTarget(final Notifier newTarget) { |
405 | 408 |
|
406 | 409 | @Override |
407 | 410 | 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 element, final INode node, final EStructuralFeature structuralFeature) { |
| 436 | + return loadedNode.utils().findNodesForFeature(element, 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 | + }; |
409 | 464 | } |
410 | 465 | } |
411 | 466 |
|
|
0 commit comments