diff options
2 files changed, 93 insertions, 3 deletions
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java index b17436a0..a624e43b 100644 --- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java +++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java @@ -202,7 +202,9 @@ public final class EMFTVMUtil { } return eCls.getName(); } else if (type instanceof Class<?>) { - return NATIVE + '!' + ((Class<?>) type).getName(); + final Class<?> cls = (Class<?>) type; + final String nativeTypeName = NativeTypes.typeName(cls); + return cls.getName().equals(nativeTypeName) ? NATIVE + '!' + nativeTypeName : nativeTypeName; } else { return type.toString(); } @@ -562,8 +564,8 @@ public final class EMFTVMUtil { } if (sf.isMany()) { if (!(value instanceof Collection<?>)) { - throw new IllegalArgumentException(String.format("Cannot assign %s to multi-valued field %s::%s", value, sf - .getEContainingClass().getName(), sf.getName())); + throw new IllegalArgumentException(String.format("Cannot assign %s to multi-valued field %s::%s", + toPrettyString(value, env), sf.getEContainingClass().getName(), sf.getName())); } setMany(env, eo, sf, (Collection<?>) value); } else { @@ -772,10 +774,12 @@ public final class EMFTVMUtil { if (index > -1) { int currentIndex = index; for (Object v : srcValues) { + checkValueTypeIsEObject(env, ref, v); addRefValue(env, ref, eo, values, (EObject) v, currentIndex++, allowInterModelReferences); } } else { for (Object v : srcValues) { + checkValueTypeIsEObject(env, ref, v); addRefValue(env, ref, eo, values, (EObject) v, -1, allowInterModelReferences); } } @@ -802,6 +806,24 @@ public final class EMFTVMUtil { } /** + * Checks that the value is an instance of {@link EObject}. + * + * @param env + * the current {@link ExecEnv} + * @param ref + * the {@link EReference} to assign to + * @param v + * the value to check + */ + private static void checkValueTypeIsEObject(final ExecEnv env, final EReference ref, final Object v) { + if (!(v instanceof EObject)) { + throw new IllegalArgumentException(String.format( + "Cannot add/remove values of type %s to/from multi-valued field %s::%s", + getTypeName(env, v.getClass()), ref.getEContainingClass().getName(), ref.getName())); + } + } + + /** * Removes the <code>value</code> from <code>eo.sf</code>. Assumes <code>sf</code> has a multiplicity > 1. * * @param env @@ -843,6 +865,7 @@ public final class EMFTVMUtil { final EReference ref = (EReference) sf; final Collection<?> srcValues = ref.isContainment() ? new ArrayList<Object>(value) : value; for (Object v : srcValues) { + checkValueTypeIsEObject(env, ref, v); removeRefValue(ref, eo, values, (EObject) v); } } else { diff --git a/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/util/tests/EMFTVMUtilTest.java b/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/util/tests/EMFTVMUtilTest.java index 7b50b969..abbe5751 100644 --- a/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/util/tests/EMFTVMUtilTest.java +++ b/tests/org.eclipse.m2m.atl.emftvm.tests/src/org/eclipse/m2m/atl/emftvm/util/tests/EMFTVMUtilTest.java @@ -15,7 +15,13 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.m2m.atl.emftvm.CodeBlock; +import org.eclipse.m2m.atl.emftvm.EmftvmFactory; +import org.eclipse.m2m.atl.emftvm.EmftvmPackage; +import org.eclipse.m2m.atl.emftvm.ExecEnv; +import org.eclipse.m2m.atl.emftvm.Instruction; import org.eclipse.m2m.atl.emftvm.util.EMFTVMUtil; import org.eclipse.m2m.atl.emftvm.util.LazyCollection; import org.eclipse.m2m.atl.emftvm.util.LazyList; @@ -111,4 +117,65 @@ public class EMFTVMUtilTest extends TestCase { assertEquals(int.class, method.getReturnType()); } + /** + * Test method for + * {@link EMFTVMUtil#set(ExecEnv, org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature, Object)}. + */ + public void testSet_Bug496434() { + final ExecEnv env = EmftvmFactory.eINSTANCE.createExecEnv(); + final CodeBlock eo = EmftvmFactory.eINSTANCE.createCodeBlock(); + final EReference sf = EmftvmPackage.eINSTANCE.getCodeBlock_Code(); + final LazyList<Instruction> element = new LazyList<Instruction>().append(EmftvmFactory.eINSTANCE.createPusht()); + final LazyList<LazyList<Instruction>> value = new LazyList<LazyList<Instruction>>().append(element); + + try { + EMFTVMUtil.set(env, eo, sf, value); + fail("Expected VMException"); + } catch (IllegalArgumentException e) { + assertEquals("Cannot add/remove values of type Sequence to/from multi-valued field CodeBlock::code", + e.getMessage()); + } + } + + /** + * Test method for {@link EMFTVMUtil#add(ExecEnv, + * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature, + * Object, int). + */ + public void testAdd_Bug496434() { + final ExecEnv env = EmftvmFactory.eINSTANCE.createExecEnv(); + final CodeBlock eo = EmftvmFactory.eINSTANCE.createCodeBlock(); + final EReference sf = EmftvmPackage.eINSTANCE.getCodeBlock_Code(); + final LazyList<Instruction> element = new LazyList<Instruction>().append(EmftvmFactory.eINSTANCE.createPusht()); + final LazyList<LazyList<Instruction>> value = new LazyList<LazyList<Instruction>>().append(element); + + try { + EMFTVMUtil.add(env, eo, sf, value, 0); + fail("Expected VMException"); + } catch (IllegalArgumentException e) { + assertEquals("Cannot add/remove values of type Sequence to/from multi-valued field CodeBlock::code", + e.getMessage()); + } + } + + /** + * Test method for + * {@link EMFTVMUtil#remove(ExecEnv, org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature, Object)}. + */ + public void testRemove_Bug496434() { + final ExecEnv env = EmftvmFactory.eINSTANCE.createExecEnv(); + final CodeBlock eo = EmftvmFactory.eINSTANCE.createCodeBlock(); + final EReference sf = EmftvmPackage.eINSTANCE.getCodeBlock_Code(); + final LazyList<Instruction> element = new LazyList<Instruction>().append(EmftvmFactory.eINSTANCE.createPusht()); + final LazyList<LazyList<Instruction>> value = new LazyList<LazyList<Instruction>>().append(element); + + try { + EMFTVMUtil.remove(env, eo, sf, value); + fail("Expected VMException"); + } catch (IllegalArgumentException e) { + assertEquals("Cannot add/remove values of type Sequence to/from multi-valued field CodeBlock::code", + e.getMessage()); + } + } + } |