diff --git a/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/DirectLinkingResourceStorageLoadable.java b/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/DirectLinkingResourceStorageLoadable.java index 313de97589..2c7ef9f77d 100644 --- a/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/DirectLinkingResourceStorageLoadable.java +++ b/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/DirectLinkingResourceStorageLoadable.java @@ -65,16 +65,10 @@ public class DirectLinkingResourceStorageLoadable extends ResourceStorageLoadabl * - count the number of EObjects added to the Resource */ private final class EObjectInputStreamExtension extends BinaryResourceImpl.EObjectInputStream { - private int objectCount; - private EObjectInputStreamExtension(final InputStream inputStream, final Map options) throws IOException { super(inputStream, options); } - public int eObjectCount() { - return objectCount; - } - @Override public int readCompressedInt() throws IOException { // HACK! null resource set, to avoid usage of resourceSet's package registry @@ -86,7 +80,6 @@ public int readCompressedInt() throws IOException { public InternalEObject loadEObject() throws IOException { final InternalEObject result = super.loadEObject(); handleLoadEObject(result, this); - objectCount++; return result; } @@ -146,8 +139,6 @@ public void loadResource(final Resource resource) throws IOException { private ResourceLoadMode mode; - private int eObjectCount; - public DirectLinkingResourceStorageLoadable(final InputStream in, final boolean loadNodeModel, final boolean splitContents, final ITraceSet traceSet) { super(in, loadNodeModel); this.loadNodeModel = loadNodeModel; @@ -271,7 +262,7 @@ protected void loadEntries(final StorageAwareResource resource, final ZipInputSt case SKIP: break; case PROXY: - ProxyCompositeNode.installProxyNodeModel(resource, eObjectCount); + ProxyCompositeNode.installProxyNodeModel(resource); break; case LOAD: readNodeModel(resource, new NonLockingBufferInputStream(zipIn), content); @@ -379,7 +370,6 @@ private Deque readMappedEObjects(final DirectLinkingEObjectInputStream protected void readContents(final StorageAwareResource resource, final InputStream inputStream) throws IOException { final EObjectInputStreamExtension in = new EObjectInputStreamExtension(inputStream, Collections.emptyMap()); in.loadResource(resource); - eObjectCount = in.eObjectCount(); } } diff --git a/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/ProxyCompositeNode.java b/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/ProxyCompositeNode.java index 229e821039..4329809e99 100644 --- a/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/ProxyCompositeNode.java +++ b/com.avaloq.tools.ddk.xtext/src/com/avaloq/tools/ddk/xtext/resource/persistence/ProxyCompositeNode.java @@ -23,8 +23,6 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EContentsEList.FeatureIterator; -import org.eclipse.emf.ecore.util.EContentsEList.Filterable; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.nodemodel.BidiIterable; import org.eclipse.xtext.nodemodel.BidiTreeIterable; @@ -37,6 +35,7 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.eclipse.xtext.nodemodel.util.NodeTreeIterator; import org.eclipse.xtext.nodemodel.util.ReversedBidiTreeIterable; +import org.eclipse.xtext.parser.IParseResult; import org.eclipse.xtext.parser.ParseResult; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.persistence.IResourceStorageFacade; @@ -53,7 +52,7 @@ * To conserve memory this class implements the primary interfaces rather than extending an implementation like * {@link org.eclipse.xtext.nodemodel.impl.CompositeNodeWithSemanticElement}. */ -class ProxyCompositeNode implements ICompositeNode, BidiTreeIterable, Adapter { +public class ProxyCompositeNode implements ICompositeNode, BidiTreeIterable, Adapter { /** The root node proxy stores the original EObject ID map so that it can be used when installing the real node model. */ private List idToEObjectMap; @@ -69,48 +68,34 @@ class ProxyCompositeNode implements ICompositeNode, BidiTreeIterable, Ada * * @param resource * resource, must not be {@code null} - * @param expectedEObjectCount - * the expected EObject count of the resource */ - static void installProxyNodeModel(final Resource resource, final int expectedEObjectCount) { + static void installProxyNodeModel(final Resource resource) { if (resource.getContents().isEmpty()) { return; } - EObject root = resource.getContents().get(0); - - ProxyCompositeNode rootNode = installProxyNodeModel(root); - rootNode.idToEObjectMap = new ArrayList<>(expectedEObjectCount); - fillIdToEObjectMap(root, rootNode.idToEObjectMap); - - if (resource instanceof XtextResource) { - ((XtextResource) resource).setParseResult(new ParseResult(root, rootNode, false)); + if (resource instanceof XtextResource xtextResource) { + EObject root = resource.getContents().get(0); + xtextResource.setParseResult(new ParseResult(root, createRootNode(root), false)); } } - private static ProxyCompositeNode installProxyNodeModel(final EObject eObject) { + private static ProxyCompositeNode createRootNode(final EObject eObject) { ProxyCompositeNode result = new ProxyCompositeNode(); eObject.eAdapters().add(result); return result; } - private static void fillIdToEObjectMap(final EObject eObject, final List map) { - map.add(eObject); - - FeatureIterator iterator = (FeatureIterator) eObject.eContents().iterator(); - if (iterator instanceof Filterable filterable) { - filterable.filter(f -> !f.isTransient()); - for (FeatureIterator it = iterator; it.hasNext();) { - fillIdToEObjectMap(it.next(), map); - } - } else { - // post-filter the iterator, which is extra work - for (FeatureIterator it = iterator; it.hasNext();) { - EObject child = it.next(); - if (!it.feature().isTransient()) { - fillIdToEObjectMap(child, map); - } - } + /** + * Fill id to EOject map. + * + * @param parseResult + * the {@link IParseResult} + */ + public static void fillIdToEObjectMap(final IParseResult parseResult) { + if (parseResult.getRootNode() instanceof ProxyCompositeNode rootNode && rootNode.idToEObjectMap == null) { + rootNode.idToEObjectMap = new ArrayList<>(); + ProxyAwareSerializationConversionContext.fillIdToEObjectMap(parseResult.getRootASTElement(), rootNode.idToEObjectMap); } }