From 49b9ff4e55c19d432b1f774e6766d107e72ba5ff Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Tue, 2 Aug 2016 18:03:35 +0200 Subject: [PATCH] Do not collect EObjects in transient Features when calculating IdToEObjectMap for Serialization. Fixes #65 Signed-off-by: Christian Dietrich --- .../serialization/SerializationUtilTest.java | 58 ++++++++++++++++++- .../serialization/SerializationUtil.java | 11 ++-- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtilTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtilTest.java index aa9cc1421..6240ba5db 100644 --- a/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtilTest.java +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtilTest.java @@ -12,15 +12,71 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.xtext.nodemodel.SyntaxErrorMessage; import org.junit.Assert; import org.junit.Test; -/** @author Mark Christiaens */ +/** + * @author Mark Christiaens + * @author Christian Dietrich + */ public class SerializationUtilTest extends Assert { + @Test + public void testFillIdToEObjectMap() { + EPackage pack = EcoreFactory.eINSTANCE.createEPackage(); + EClass root = createEClass(pack, "Root"); + EClass someType = createEClass(pack, "SomeType"); + + EReference ref1 = addEReference(root, someType, "ref1", false); + EReference ref2 = addEReference(root, someType, "ref2", true); + + EFactory factory = pack.getEFactoryInstance(); + EObject rootObject = factory.create(root); + EObject someTypeObject1 = factory.create(someType); + EObject someTypeObject2 = factory.create(someType); + rootObject.eSet(ref1, someTypeObject1); + rootObject.eSet(ref2, someTypeObject2); + + List map = new ArrayList<>(); + SerializationUtil.fillIdToEObjectMap(rootObject, map); + assertTrue(map.contains(rootObject)); + assertTrue(map.contains(someTypeObject1)); + assertFalse(map.contains(someTypeObject2)); + assertEquals(2, map.size()); + } + + private EClass createEClass(EPackage pack, String name) { + EClass clazz = EcoreFactory.eINSTANCE.createEClass(); + clazz.setName(name); + pack.getEClassifiers().add(clazz); + return clazz; + } + + private EReference addEReference(EClass from, EClass to, String name, boolean isTransient) { + EReference ref = EcoreFactory.eINSTANCE.createEReference(); + ref.setName("ref2"); + ref.setEType(to); + ref.setContainment(true); + if (isTransient) { + ref.setTransient(true); + ref.setDerived(true); + } + ref.setChangeable(true); + from.getEStructuralFeatures().add(ref); + return ref; + } + @Test public void testSyntaxErrorMessage() throws IOException { final String message = "hi"; diff --git a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtil.java b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtil.java index bd40cefc4..577fcc1f7 100644 --- a/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtil.java +++ b/org.eclipse.xtext/src/org/eclipse/xtext/nodemodel/serialization/SerializationUtil.java @@ -48,12 +48,13 @@ public class SerializationUtil { } public static void fillIdToEObjectMap(EObject eObject, List map) { - map.add(eObject); + if (eObject.eContainingFeature() == null || !eObject.eContainingFeature().isTransient()) { + map.add(eObject); + EList eContents = eObject.eContents(); - EList eContents = eObject.eContents(); - - for (EObject child : eContents) { - fillIdToEObjectMap(child, map); + for (EObject child : eContents) { + fillIdToEObjectMap(child, map); + } } }