[ChangeSerializer] support modifications applied to non-xtext-resources

Signed-off-by: Moritz Eysholdt <moritz.eysholdt@typefox.io>
This commit is contained in:
Moritz Eysholdt 2018-03-02 16:25:36 +01:00 committed by Moritz Eysholdt
parent 860bf74ab5
commit 9885cc4323
5 changed files with 202 additions and 9 deletions
org.eclipse.xtext.ide.tests
src/org/eclipse/xtext/ide/tests/serializer
xtend-gen/org/eclipse/xtext/ide/tests/serializer
org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/serializer/impl
org.eclipse.xtext.testlanguages/src/org/eclipse/xtext/testlanguages/ecore

View file

@ -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" -> '''
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="MyPackage">
<eClassifiers xsi:type="ecore:EClass" name="MyClass1"/>
</ecore:EPackage>
'''
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 -----------------------------
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="MyPackage">
<eClassifiers xsi:type="ecore:EClass" name="NewClass"/>
</ecore:EPackage>
--------------------------------------------------------------------------------
----------------- inmemory:/file1.pstl (syntax: <offset|text>) -----------------
#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" -> '''

View file

@ -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<String, String> _mappedTo = Pair.<String, String>of("inmemory:/file1.pstl", _builder.toString());
this._changeSerializerTestHelper.operator_add(fs, _mappedTo);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
_builder_1.newLine();
_builder_1.append("<ecore:EPackage xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("xmlns:ecore=\"http://www.eclipse.org/emf/2002/Ecore\" name=\"MyPackage\">");
_builder_1.newLine();
_builder_1.append(" ");
_builder_1.append("<eClassifiers xsi:type=\"ecore:EClass\" name=\"MyClass1\"/>");
_builder_1.newLine();
_builder_1.append("</ecore:EPackage>");
_builder_1.newLine();
Pair<String, String> _mappedTo_1 = Pair.<String, String>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.<EPackage>contents(rs, "inmemory:/file2.ecore", EPackage.class);
final ChangeSerializer serializer = this.serializerProvider.get();
final IChangeSerializer.IModification<EPackage> _function = (EPackage it) -> {
EClassifier _head = IterableExtensions.<EClassifier>head(model.getEClassifiers());
((EClass) _head).setName("NewClass");
};
serializer.<EPackage>addModification(model, _function);
Collection<IEmfResourceChange> _endRecordChangesToTextDocuments = this._changeSerializerTestHelper.endRecordChangesToTextDocuments(serializer);
StringConcatenation _builder_2 = new StringConcatenation();
_builder_2.append("---------------------------- inmemory:/file2.ecore -----------------------------");
_builder_2.newLine();
_builder_2.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
_builder_2.newLine();
_builder_2.append("<ecore:EPackage xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
_builder_2.newLine();
_builder_2.append(" ");
_builder_2.append("xmlns:ecore=\"http://www.eclipse.org/emf/2002/Ecore\" name=\"MyPackage\">");
_builder_2.newLine();
_builder_2.append(" ");
_builder_2.append("<eClassifiers xsi:type=\"ecore:EClass\" name=\"NewClass\"/>");
_builder_2.newLine();
_builder_2.append("</ecore:EPackage>");
_builder_2.newLine();
_builder_2.append("--------------------------------------------------------------------------------");
_builder_2.newLine();
_builder_2.append("----------------- inmemory:/file1.pstl (syntax: <offset|text>) -----------------");
_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");

View file

@ -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;
}
}

View file

@ -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<IEmfResourceChange> 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() {
}
}

View file

@ -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<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
return EcoreResourceDescriptionStrategy.class;
}
@Override
public Class<? extends IQualifiedNameProvider> 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);
}
}