From 9885cc432303462c783163e453bdeb9f0bf0b4bc Mon Sep 17 00:00:00 2001 From: Moritz Eysholdt Date: Fri, 2 Mar 2018 16:25:36 +0100 Subject: [PATCH] [ChangeSerializer] support modifications applied to non-xtext-resources Signed-off-by: Moritz Eysholdt --- .../ChangeSerializerWithEmfTest.xtend | 40 +++++++++- .../ChangeSerializerWithEmfTest.java | 65 +++++++++++++++- .../ide/serializer/impl/ChangeSerializer.java | 4 +- .../impl/RecordingEmfResourceUpdater.java | 78 +++++++++++++++++++ .../ecore/EcoreRuntimeModule.java | 24 +++++- 5 files changed, 202 insertions(+), 9 deletions(-) create mode 100644 org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/RecordingEmfResourceUpdater.java diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.xtend b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.xtend index 7224f35c3..4e3e8a0ac 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.xtend +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.xtend @@ -22,6 +22,7 @@ import org.eclipse.xtext.testlanguages.ecore.EcoreSupport import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith +import org.eclipse.emf.ecore.EPackage /** * @author Moritz Eysholdt - Initial contribution and API @@ -34,7 +35,7 @@ class ChangeSerializerWithEmfTest { @Inject extension ChangeSerializerTestHelper @Test - def void testRefToXML() { + def void testChangeRefToXML() { val fs = new InMemoryURIHandler() fs += "inmemory:/file1.pstl" -> '''#21 MyPackage.MyClass1''' fs += "inmemory:/file2.ecore" -> ''' @@ -60,9 +61,44 @@ class ChangeSerializerWithEmfTest { 4 18 "MyPackage.MyClass1" -> "MyPackage.MyClass2" ''' } + + @Test + def void testChangeInXML() { + val fs = new InMemoryURIHandler() + fs += "inmemory:/file1.pstl" -> '''#21 MyPackage.MyClass1''' + fs += "inmemory:/file2.ecore" -> ''' + + + + + ''' + + val rs = fs.createResourceSet + val model = rs.contents("inmemory:/file2.ecore", EPackage) + + val serializer = serializerProvider.get() + serializer.addModification(model) [ + (model.EClassifiers.head as EClass).name = "NewClass" + ] + serializer.endRecordChangesToTextDocuments === ''' + ---------------------------- inmemory:/file2.ecore ----------------------------- + + + + + -------------------------------------------------------------------------------- + ----------------- inmemory:/file1.pstl (syntax: ) ----------------- + #21 <4:18|MyPackage.NewClass> + -------------------------------------------------------------------------------- + 4 18 "MyPackage.MyClass1" -> "MyPackage.NewClass" + ''' + } + @Test - def void testRefFromXML() { + def void testChangeInDSL() { val fs = new InMemoryURIHandler() fs += "inmemory:/file1.pstl" -> '''#20 DslEClass''' fs += "inmemory:/file2.ecore" -> ''' diff --git a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.java b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.java index bfab5fe57..8f917d92d 100644 --- a/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.java +++ b/org.eclipse.xtext.ide.tests/xtend-gen/org/eclipse/xtext/ide/tests/serializer/ChangeSerializerWithEmfTest.java @@ -13,6 +13,7 @@ import java.util.Collection; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; @@ -28,6 +29,7 @@ import org.eclipse.xtext.testing.InjectWith; import org.eclipse.xtext.testing.XtextRunner; import org.eclipse.xtext.testing.util.InMemoryURIHandler; import org.eclipse.xtext.xbase.lib.Extension; +import org.eclipse.xtext.xbase.lib.IterableExtensions; import org.eclipse.xtext.xbase.lib.ObjectExtensions; import org.eclipse.xtext.xbase.lib.Pair; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; @@ -50,7 +52,7 @@ public class ChangeSerializerWithEmfTest { private ChangeSerializerTestHelper _changeSerializerTestHelper; @Test - public void testRefToXML() { + public void testChangeRefToXML() { final InMemoryURIHandler fs = new InMemoryURIHandler(); StringConcatenation _builder = new StringConcatenation(); _builder.append("#21 MyPackage.MyClass1"); @@ -96,7 +98,66 @@ public class ChangeSerializerWithEmfTest { } @Test - public void testRefFromXML() { + public void testChangeInXML() { + final InMemoryURIHandler fs = new InMemoryURIHandler(); + StringConcatenation _builder = new StringConcatenation(); + _builder.append("#21 MyPackage.MyClass1"); + Pair _mappedTo = Pair.of("inmemory:/file1.pstl", _builder.toString()); + this._changeSerializerTestHelper.operator_add(fs, _mappedTo); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append(""); + _builder_1.newLine(); + _builder_1.append(""); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append(""); + _builder_1.newLine(); + _builder_1.append(""); + _builder_1.newLine(); + Pair _mappedTo_1 = Pair.of("inmemory:/file2.ecore", _builder_1.toString()); + this._changeSerializerTestHelper.operator_add(fs, _mappedTo_1); + final ResourceSet rs = this._changeSerializerTestHelper.createResourceSet(fs); + final EPackage model = this._changeSerializerTestHelper.contents(rs, "inmemory:/file2.ecore", EPackage.class); + final ChangeSerializer serializer = this.serializerProvider.get(); + final IChangeSerializer.IModification _function = (EPackage it) -> { + EClassifier _head = IterableExtensions.head(model.getEClassifiers()); + ((EClass) _head).setName("NewClass"); + }; + serializer.addModification(model, _function); + Collection _endRecordChangesToTextDocuments = this._changeSerializerTestHelper.endRecordChangesToTextDocuments(serializer); + StringConcatenation _builder_2 = new StringConcatenation(); + _builder_2.append("---------------------------- inmemory:/file2.ecore -----------------------------"); + _builder_2.newLine(); + _builder_2.append(""); + _builder_2.newLine(); + _builder_2.append(""); + _builder_2.newLine(); + _builder_2.append(" "); + _builder_2.append(""); + _builder_2.newLine(); + _builder_2.append(""); + _builder_2.newLine(); + _builder_2.append("--------------------------------------------------------------------------------"); + _builder_2.newLine(); + _builder_2.append("----------------- inmemory:/file1.pstl (syntax: ) -----------------"); + _builder_2.newLine(); + _builder_2.append("#21 <4:18|MyPackage.NewClass>"); + _builder_2.newLine(); + _builder_2.append("--------------------------------------------------------------------------------"); + _builder_2.newLine(); + _builder_2.append("4 18 \"MyPackage.MyClass1\" -> \"MyPackage.NewClass\""); + _builder_2.newLine(); + this._changeSerializerTestHelper.operator_tripleEquals(_endRecordChangesToTextDocuments, _builder_2); + } + + @Test + public void testChangeInDSL() { final InMemoryURIHandler fs = new InMemoryURIHandler(); StringConcatenation _builder = new StringConcatenation(); _builder.append("#20 DslEClass"); diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/ChangeSerializer.java b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/ChangeSerializer.java index 2375d6e2a..956390e9e 100644 --- a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/ChangeSerializer.java +++ b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/ChangeSerializer.java @@ -139,7 +139,9 @@ public class ChangeSerializer implements IChangeSerializer { updater.beginRecording(this, (XtextResource) resource); return updater; } else { - throw new UnsupportedOperationException(); + RecordingEmfResourceUpdater updater = getService(resource, RecordingEmfResourceUpdater.class); + updater.beginRecording(this, resource); + return updater; } } diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/RecordingEmfResourceUpdater.java b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/RecordingEmfResourceUpdater.java new file mode 100644 index 000000000..9e0168415 --- /dev/null +++ b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl/RecordingEmfResourceUpdater.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2018 TypeFox GmbH (http://www.typefox.io) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.xtext.ide.serializer.impl; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtext.ide.serializer.IChangeSerializer; +import org.eclipse.xtext.ide.serializer.IEmfResourceChange; +import org.eclipse.xtext.ide.serializer.hooks.IResourceSnapshot; +import org.eclipse.xtext.ide.serializer.impl.EObjectDescriptionDeltaProvider.Deltas; +import org.eclipse.xtext.util.IAcceptor; + +import com.google.inject.Inject; + +/** + * @since 2.14 + * + * @author Moritz Eysholdt - Initial contribution and API + */ +public class RecordingEmfResourceUpdater extends RecordingResourceUpdater { + + private IChangeSerializer serializer; + + private IResourceSnapshot snapshot; + + @Inject + private EObjectSnapshotProvider snapshotProvider; + + @Override + public void applyChange(Deltas deltas, IAcceptor changeAcceptor) { + EmfResourceChange change = new EmfResourceChange(snapshot.getResource(), snapshot.getURI()); + changeAcceptor.accept(change); + } + + public void beginRecording(IChangeSerializer serializer, Resource resource) { + this.serializer = serializer; + this.snapshot = snapshotProvider.createResourceSnapshot(resource); + EcoreUtil.resolveAll(resource); + } + + @Override + public Resource getResource() { + return snapshot.getResource(); + } + + public IChangeSerializer getSerializer() { + return serializer; + } + + @Override + public IResourceSnapshot getSnapshot() { + return snapshot; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(getClass().getSimpleName()); + URI oldURI = getSnapshot().getURI(); + URI newURI = getResource().getURI(); + if (oldURI.equals(newURI)) { + result.append(" " + oldURI); + } else { + result.append(" " + oldURI + " -> " + newURI); + } + return result.toString(); + } + + @Override + public void unload() { + } + +} diff --git a/org.eclipse.xtext.testlanguages/src/org/eclipse/xtext/testlanguages/ecore/EcoreRuntimeModule.java b/org.eclipse.xtext.testlanguages/src/org/eclipse/xtext/testlanguages/ecore/EcoreRuntimeModule.java index fbd795596..bd06de8fc 100644 --- a/org.eclipse.xtext.testlanguages/src/org/eclipse/xtext/testlanguages/ecore/EcoreRuntimeModule.java +++ b/org.eclipse.xtext.testlanguages/src/org/eclipse/xtext/testlanguages/ecore/EcoreRuntimeModule.java @@ -9,11 +9,18 @@ package org.eclipse.xtext.testlanguages.ecore; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; +import org.eclipse.xtext.resource.IResourceDescriptions; import org.eclipse.xtext.resource.generic.AbstractGenericResourceRuntimeModule; +import org.eclipse.xtext.resource.impl.LiveShadowedResourceDescriptions; +import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider; +import org.eclipse.xtext.resource.impl.ResourceSetBasedResourceDescriptions; + +import com.google.inject.Binder; +import com.google.inject.name.Names; /** * Default Guice bindings for managing Ecore resources in the context of Xtext. - * + * * @author Jan Koehnlein - Initial contribution and API */ public class EcoreRuntimeModule extends AbstractGenericResourceRuntimeModule { @@ -27,14 +34,23 @@ public class EcoreRuntimeModule extends AbstractGenericResourceRuntimeModule { protected String getFileExtensions() { return "ecore"; } - + public Class bindIDefaultResourceDescriptionStrategy() { return EcoreResourceDescriptionStrategy.class; } - + @Override public Class bindIQualifiedNameProvider() { return EcoreQualifiedNameProvider.class; } - + + public void configureIResourceDescriptions(Binder binder) { + binder.bind(IResourceDescriptions.class).to(ResourceSetBasedResourceDescriptions.class); + } + + public void configureIResourceDescriptionsLiveScope(Binder binder) { + binder.bind(IResourceDescriptions.class).annotatedWith(Names.named(ResourceDescriptionsProvider.LIVE_SCOPE)) + .to(LiveShadowedResourceDescriptions.class); + } + }