mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 00:38:56 +00:00
[ChangeSerializer] support modifications applied to non-xtext-resources
Signed-off-by: Moritz Eysholdt <moritz.eysholdt@typefox.io>
This commit is contained in:
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
|
@ -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" -> '''
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue