Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -379,7 +370,6 @@ private Deque<EObject> 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();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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<INode>, Adapter {
public class ProxyCompositeNode implements ICompositeNode, BidiTreeIterable<INode>, 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<EObject> idToEObjectMap;
Expand All @@ -69,48 +68,34 @@ class ProxyCompositeNode implements ICompositeNode, BidiTreeIterable<INode>, 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<EObject> map) {
map.add(eObject);

FeatureIterator<EObject> iterator = (FeatureIterator<EObject>) eObject.eContents().iterator();
if (iterator instanceof Filterable filterable) {
filterable.filter(f -> !f.isTransient());
for (FeatureIterator<EObject> it = iterator; it.hasNext();) {
fillIdToEObjectMap(it.next(), map);
}
} else {
// post-filter the iterator, which is extra work
for (FeatureIterator<EObject> 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);
}
}

Expand Down