Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Wagelaar2017-10-16 05:51:03 -0400
committerDennis Wagelaar2017-10-16 05:51:03 -0400
commit96d0fdba1deb380cff0b8a3ec18b9fb1120400e7 (patch)
treef008eaf0c092762e4dbbc718981254ac821188d9 /plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse
parent2dab64d71d280c455351336d31ffe89650271d29 (diff)
parentc45d6245e94da56678194e6b053f2978dcdcc50b (diff)
downloadorg.eclipse.atl-96d0fdba1deb380cff0b8a3ec18b9fb1120400e7.tar.gz
org.eclipse.atl-96d0fdba1deb380cff0b8a3ec18b9fb1120400e7.tar.xz
org.eclipse.atl-96d0fdba1deb380cff0b8a3ec18b9fb1120400e7.zip
Merge remote-tracking branch 'origin/master' into
bugs/415863-multiple_dispatch Conflicts: plugins/org.eclipse.m2m.atl.emftvm/META-INF/MANIFEST.MF
Diffstat (limited to 'plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse')
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Messages.java67
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/ExecEnvImpl.java2
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/FieldImpl.java10
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java2
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java70
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java28
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/launcher/compat/EMFTVMLauncher.java347
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/messages.properties12
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/EMFTVMUtil.java961
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyBag.java26
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyCollection.java108
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyList.java65
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyOrderedSet.java28
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazySet.java24
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java142
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java676
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/StackFrame.java12
-rwxr-xr-xplugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/Tuple.java34
18 files changed, 1719 insertions, 895 deletions
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Messages.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Messages.java
new file mode 100644
index 00000000..3143042f
--- /dev/null
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/Messages.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Dennis Wagelaar.
+ * 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
+ *
+ * Contributors:
+ * Dennis Wagelaar
+ *******************************************************************************/
+package org.eclipse.m2m.atl.emftvm;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class to access externalized Strings for EMFTVM.
+ *
+ * @author <a href="mailto:dwagelaar@gmail.com">Dennis Wagelaar</a>
+ */
+public final class Messages {
+
+ /** Full qualified path to the properties file in which to seek the keys. */
+ private static final String BUNDLE_NAME = "org.eclipse.m2m.atl.emftvm.messages"; //$NON-NLS-1$
+
+ /** Contains the locale specific {@link String}s needed by this plug-in. */
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ /**
+ * Utility classes don't need to (and shouldn't) be instantiated.
+ */
+ private Messages() {
+ }
+
+ /**
+ * Returns a specified {@link String} from the resource bundle.
+ *
+ * @param key
+ * Key of the String we seek.
+ * @return The String from the resource bundle associated with <code>key</code>.
+ */
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Returns a String from the resource bundle binded with the given arguments.
+ *
+ * @param key
+ * Key of the String we seek.
+ * @param arguments
+ * Arguments for the String formatting.
+ * @return formatted {@link String}.
+ * @see MessageFormat#format(String, Object...)
+ */
+ public static String getString(String key, Object... arguments) {
+ if (arguments == null) {
+ return getString(key);
+ }
+ return MessageFormat.format(getString(key), arguments);
+ }
+}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/ExecEnvImpl.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/ExecEnvImpl.java
index eff95be5..d0cb408a 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/ExecEnvImpl.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/ExecEnvImpl.java
@@ -1610,7 +1610,7 @@ public class ExecEnvImpl extends EObjectImpl implements ExecEnv {
for (String modelName : re.getModels()) {
final Model model = models.get(modelName);
if (model == null) {
- throw new IllegalArgumentException(String.format("Model %s not found", modelName));
+ throw new IllegalArgumentException(String.format("Model %s not found for %s", modelName, re));
}
eModels.add(model);
}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/FieldImpl.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/FieldImpl.java
index 502cf0d9..5fefa045 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/FieldImpl.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/FieldImpl.java
@@ -563,15 +563,7 @@ public class FieldImpl extends FeatureImpl implements Field {
*/
@Override
public String toString() {
- if (eIsProxy()) return super.toString();
-
- StringBuffer result = new StringBuffer(super.toString());
- if (isStatic()) {
- result.append(" (staticValue: ");
- result.append(staticValue);
- result.append(')');
- }
- return result.toString();
+ return super.toString();
}
/**
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java
index 48679aab..6f921d74 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/RuleImpl.java
@@ -3468,7 +3468,7 @@ public class RuleImpl extends NamedElementImpl implements Rule {
*/
private Map<String, Object> createValuesMap(final Object[] values) {
final EList<InputRuleElement> allInput = getInputElements();
- final Map<String, Object> valuesMap = new HashMap<String, Object>(allInput.size());
+ final Map<String, Object> valuesMap = new LinkedHashMap<String, Object>(allInput.size());
assert allInput.size() == values.length;
int i = 0;
for (RuleElement re : allInput) {
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java
index 1ad77166..a8ca44a2 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java
@@ -11,13 +11,11 @@
package org.eclipse.m2m.atl.emftvm.jit;
import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -664,7 +662,7 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
localVariable("body", CodeBlock.class, bodyStart, ifOpNull, bodyIdx);
}
// Generate native method invocation code here
- final Method method = findRootMethod(object.getNativeMethod());
+ final Method method = EMFTVMUtil.findRootMethod(object.getNativeMethod());
if (method != null) { // native method recorded - try first
// Labels
final Label subframeStart = new Label();
@@ -711,7 +709,8 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
mv.visitMethodInsn(opcode, // self.<method>(): [..., ?]
Type.getInternalName(dc),
method.getName(),
- Type.getMethodDescriptor(method));
+ Type.getMethodDescriptor(method),
+ dc.isInterface());
// Check if method returned anything
final Class<?> rt = method.getReturnType();
// Box primitive return values
@@ -849,7 +848,7 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
localVariable("body", CodeBlock.class, bodyStart, ifOpNull, bodyIdx);
}
// Generate native method invocation code here
- final Method method = findRootMethod(object.getNativeMethod());
+ final Method method = EMFTVMUtil.findRootMethod(object.getNativeMethod());
if (method != null) { // native method recorded - try first
// Labels
final Label subframeStart = new Label();
@@ -915,7 +914,8 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
mv.visitMethodInsn(opcode, // self.<method>(arg): [..., ?]
Type.getInternalName(dc),
method.getName(),
- Type.getMethodDescriptor(method));
+ Type.getMethodDescriptor(method),
+ dc.isInterface());
// Check if method returned anything
final Class<?> rt = method.getReturnType();
// Box primitive return values
@@ -1085,61 +1085,6 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
}
/**
- * Finds the root {@link Class} in which <code>method</code> was declared.
- * @param method the method for which to find the root {@link Class}
- * @return the root {@link Class} in which <code>method</code> was declared
- */
- private Method findRootMethod(Method method) {
- if (method == null) {
- return null;
- }
- final int methodModifiers = getRelevantModifiers(method);
- Class<?> dc = method.getDeclaringClass();
- java.util.Set<Class<?>> dis = new LinkedHashSet<Class<?>>(
- Arrays.asList(dc.getInterfaces()));
- while ((dc = dc.getSuperclass()) != null) {
- try {
- Method superMethod = dc.getDeclaredMethod(method.getName(), method.getParameterTypes());
- if (getRelevantModifiers(superMethod) == methodModifiers) {
- method = superMethod;
- } else {
- break;
- }
- } catch (SecurityException e) {
- } catch (NoSuchMethodException e) {
- }
- dis.addAll(Arrays.asList(dc.getInterfaces()));
- }
- while (!dis.isEmpty()) {
- java.util.Set<Class<?>> newDis = new LinkedHashSet<Class<?>>();
- for (Class<?> di : dis) {
- try {
- // Only replace by method declared in a super-interface
- if (di.isAssignableFrom(method.getDeclaringClass())) {
- method = di.getDeclaredMethod(method.getName(), method.getParameterTypes());
- }
- } catch (SecurityException e) {
- } catch (NoSuchMethodException e) {
- }
- newDis.addAll(Arrays.asList(di.getInterfaces()));
- }
- newDis.removeAll(dis);
- dis = newDis;
- }
- return method;
- }
-
- /**
- * Returns the relevant modifiers (visibility and static) for the given method.
- * @param method the method for which to return the modifiers
- * @return the relevant modifiers (visibility and static) for the given method
- */
- private int getRelevantModifiers(final Method method) {
- final int methodModifiers = method.getModifiers();
- return methodModifiers & (Modifier.PRIVATE + Modifier.PROTECTED + Modifier.PUBLIC + Modifier.STATIC);
- }
-
- /**
* {@inheritDoc}
*/
@Override
@@ -2336,7 +2281,8 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
name,
Type.getMethodDescriptor(
retType instanceof Type ? (Type)retType : Type.getType((Class<?>)retType),
- ats));
+ ats),
+ owner.isInterface());
}
protected void invokeIface(final Class<?> owner, final String name,
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java
index 2bae9060..a0afebc3 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java
@@ -184,7 +184,8 @@ public class CodeBlockJIT implements Opcodes {
init.visitMethodInsn(INVOKESPECIAL, // super(cb)
Type.getInternalName(JITCodeBlock.class),
"<init>",
- Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(CodeBlock.class)}));
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(CodeBlock.class)}),
+ false);
init.visitInsn(RETURN);
init.visitLabel(end);
// Create local variable table
@@ -221,10 +222,10 @@ public class CodeBlockJIT implements Opcodes {
// Generate bytecode
execute.visitLabel(start);
execute.visitVarInsn(ALOAD, 1); // frame
- execute.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(StackFrame.class), "getEnv", Type.getMethodDescriptor(Type.getType(ExecEnv.class), new Type[0]));
+ execute.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(StackFrame.class), "getEnv", Type.getMethodDescriptor(Type.getType(ExecEnv.class), new Type[0]), false);
execute.visitVarInsn(ASTORE, 2);
execute.visitVarInsn(ALOAD, 2); // env
- execute.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ExecEnv.class), "getMonitor", Type.getMethodDescriptor(Type.getType(VMMonitor.class), new Type[0]));
+ execute.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ExecEnv.class), "getMonitor", Type.getMethodDescriptor(Type.getType(VMMonitor.class), new Type[0]), true);
execute.visitVarInsn(ASTORE, 3); // monitor
final boolean hasMonitor = getEnv().getMonitor() != null;
if (hasMonitor) {
@@ -235,7 +236,8 @@ public class CodeBlockJIT implements Opcodes {
"enter",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{
Type.getType(StackFrame.class)
- }));
+ }),
+ true);
}
execute.visitLabel(tryStart);
final ByteCodeSwitch bs = new ByteCodeSwitch(this, execute, ls);
@@ -267,7 +269,8 @@ public class CodeBlockJIT implements Opcodes {
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{
Type.getType(StackFrame.class),
Type.getType(Throwable.class)
- }));
+ }),
+ false);
execute.visitInsn(ATHROW); // throw vme
// Regular method return
execute.visitLabel(catchEnd);
@@ -279,7 +282,8 @@ public class CodeBlockJIT implements Opcodes {
"leave",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{
Type.getType(StackFrame.class)
- }));
+ }),
+ true);
}
if (cb.getStackLevel() == 0) {
execute.visitInsn(ACONST_NULL); // push null
@@ -311,7 +315,8 @@ public class CodeBlockJIT implements Opcodes {
mv.visitMethodInsn(INVOKEINTERFACE, // monitor.isTerminated(): [..., boolean]
Type.getInternalName(VMMonitor.class),
"isTerminated",
- Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[0]));
+ Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[0]),
+ true);
mv.visitJumpInsn(IFEQ, notTerminated); // jump if isTerminated == false: [...]
mv.visitTypeInsn(NEW, Type.getInternalName(VMException.class)); // new VMException: [..., vme]
mv.visitInsn(DUP); // [..., vme, vme]
@@ -323,7 +328,8 @@ public class CodeBlockJIT implements Opcodes {
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{
Type.getType(StackFrame.class),
Type.getType(String.class)
- }));
+ }),
+ false);
mv.visitInsn(ATHROW); // throw vme: [...]
mv.visitLabel(notTerminated);
mv.visitVarInsn(ALOAD, 1); // frame: [..., frame]
@@ -333,7 +339,8 @@ public class CodeBlockJIT implements Opcodes {
"setPc",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{
Type.INT_TYPE
- }));
+ }),
+ false);
mv.visitVarInsn(ALOAD, 3); // monitor: [..., monitor]
mv.visitVarInsn(ALOAD, 1); // frame: [..., monitor, frame]
mv.visitMethodInsn(INVOKEINTERFACE, // monitor.step(frame): [...]
@@ -341,7 +348,8 @@ public class CodeBlockJIT implements Opcodes {
"step",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{
Type.getType(StackFrame.class)
- }));
+ }),
+ true);
}
/**
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/launcher/compat/EMFTVMLauncher.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/launcher/compat/EMFTVMLauncher.java
new file mode 100644
index 00000000..aba3b72a
--- /dev/null
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/launcher/compat/EMFTVMLauncher.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Dennis Wagelaar.
+ * 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
+ *
+ * Contributors:
+ * Dennis Wagelaar - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2m.atl.emftvm.launcher.compat;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.regex.Matcher;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.m2m.atl.common.ATLLaunchConstants;
+import org.eclipse.m2m.atl.common.ATLLogger;
+import org.eclipse.m2m.atl.core.ATLCoreException;
+import org.eclipse.m2m.atl.core.IModel;
+import org.eclipse.m2m.atl.core.emf.EMFInjector;
+import org.eclipse.m2m.atl.core.emf.EMFModel;
+import org.eclipse.m2m.atl.core.emf.EMFReferenceModel;
+import org.eclipse.m2m.atl.core.launch.ILauncher;
+import org.eclipse.m2m.atl.core.service.CoreService;
+import org.eclipse.m2m.atl.core.service.LauncherService;
+import org.eclipse.m2m.atl.emftvm.EmftvmFactory;
+import org.eclipse.m2m.atl.emftvm.ExecEnv;
+import org.eclipse.m2m.atl.emftvm.Messages;
+import org.eclipse.m2m.atl.emftvm.Metamodel;
+import org.eclipse.m2m.atl.emftvm.Model;
+import org.eclipse.m2m.atl.emftvm.Module;
+import org.eclipse.m2m.atl.emftvm.util.DefaultModuleResolver;
+import org.eclipse.m2m.atl.emftvm.util.EMFTVMUtil;
+import org.eclipse.m2m.atl.emftvm.util.LazyCollections;
+import org.eclipse.m2m.atl.emftvm.util.ModuleNotFoundException;
+import org.eclipse.m2m.atl.emftvm.util.ModuleResolver;
+import org.eclipse.m2m.atl.emftvm.util.TimingData;
+import org.eclipse.m2m.atl.emftvm.util.VMException;
+import org.eclipse.m2m.atl.emftvm.util.VMMonitor;
+
+/**
+ * The EMFVM implementation of the {@link ILauncher} interface.
+ *
+ * @author <a href="mailto:dwagelaar@gmail.com">Dennis Wagelaar</a>
+ */
+public class EMFTVMLauncher implements ILauncher {
+
+ /** The Default model factory name to use. */
+ public static final String MODEL_FACTORY_NAME = "EMF"; //$NON-NLS-1$
+
+ private static final String EMF_URI_PREFIX = "emftvm://"; //$NON-NLS-1$
+
+ protected Map<String, IModel> models;
+
+ protected Map<String, Module> libraries;
+
+ protected ResourceSet moduleResourceSet;
+
+ protected ModuleResolver moduleResolver;
+
+ protected ExecEnv execEnv;
+
+ protected ResourceSet outputResourceSet;
+
+ protected TimingData timingData;
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return ATLLaunchConstants.EMFTVM_NAME;
+ }
+
+ /**
+ * Adds any model to the local map.
+ *
+ * @param model
+ * the {@link IModel}
+ * @param name
+ * the model name
+ * @param referenceModelName
+ * the model reference model name
+ * @return the EMFTVM {@link Model}
+ */
+ protected Model addModel(IModel model, String name, String referenceModelName) {
+ final Model emftvmModel;
+ if (models.containsKey(name)) {
+ ATLLogger.warning(Messages.getString("EMFTVMLauncher.MODEL_REGISTERED", name)); //$NON-NLS-1$
+ emftvmModel = null;
+ } else {
+ models.put(name, model);
+ final EMFModel emfModel = (EMFModel) model;
+ final Resource resource = emfModel.getResource();
+ if (resource == null) {
+ final EMFInjector emfInjector;
+ try {
+ emfInjector = (EMFInjector) CoreService.getInjector(MODEL_FACTORY_NAME);
+ } catch (ATLCoreException e) {
+ throw new VMException(null, e.getLocalizedMessage(), e);
+ }
+ emfInjector.inject(emfModel, outputResourceSet.createResource(URI.createURI(name + ".xmi"))); //$NON-NLS-1$
+ }
+ emftvmModel = EmftvmFactory.eINSTANCE.createModel();
+ emftvmModel.setResource(emfModel.getResource());
+ }
+ if (!models.containsKey(referenceModelName)) {
+ models.put(referenceModelName, model.getReferenceModel());
+ final Metamodel metamodel = EmftvmFactory.eINSTANCE.createMetamodel();
+ metamodel.setResource(((EMFReferenceModel) model.getReferenceModel()).getResource());
+ execEnv.registerMetaModel(referenceModelName, metamodel);
+ }
+ return emftvmModel;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#addInModel(org.eclipse.m2m.atl.core.IModel,
+ * java.lang.String, java.lang.String)
+ */
+ public void addInModel(IModel model, String name, String referenceModelName) {
+ model.setIsTarget(false);
+ final Model emftvmModel = addModel(model, name, referenceModelName);
+ if (emftvmModel != null) {
+ execEnv.registerInputModel(name, emftvmModel);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#addInOutModel(org.eclipse.m2m.atl.core.IModel,
+ * java.lang.String, java.lang.String)
+ */
+ public void addInOutModel(IModel model, String name, String referenceModelName) {
+ model.setIsTarget(true);
+ final Model emftvmModel = addModel(model, name, referenceModelName);
+ if (emftvmModel != null) {
+ execEnv.registerInOutModel(name, emftvmModel);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#addOutModel(org.eclipse.m2m.atl.core.IModel,
+ * java.lang.String, java.lang.String)
+ */
+ public void addOutModel(IModel model, String name, String referenceModelName) {
+ model.setIsTarget(true);
+ final Model emftvmModel = addModel(model, name, referenceModelName);
+ if (emftvmModel != null) {
+ execEnv.registerOutputModel(name, emftvmModel);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#addLibrary(java.lang.String,
+ * java.lang.Object)
+ */
+ public void addLibrary(String name, Object library) {
+ if (libraries.containsKey(name)) {
+ ATLLogger.warning(Messages.getString("EMFTVMLauncher.LIBRARY_REGISTERED", name)); //$NON-NLS-1$
+ } else {
+ libraries.put(name, getModuleFromObject(library));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#initialize(java.util.Map)
+ */
+ public void initialize(Map<String, Object> parameters) {
+ models = new HashMap<String, IModel>();
+ libraries = new HashMap<String, Module>();
+ moduleResourceSet = new ResourceSetImpl();
+ moduleResolver = new DefaultModuleResolver(EMF_URI_PREFIX, moduleResourceSet);
+ execEnv = EmftvmFactory.eINSTANCE.createExecEnv();
+ outputResourceSet = new ResourceSetImpl();
+ timingData = new TimingData();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#launch(java.lang.String,
+ * org.eclipse.core.runtime.IProgressMonitor, java.util.Map,
+ * java.lang.Object[])
+ */
+ public Object launch(final String mode, final IProgressMonitor monitor, final Map<String, Object> options,
+ final Object... modules) {
+ return internalLaunch(null, monitor, options, modules);
+ }
+
+ /**
+ * Launches the transformation with preloaded modules.
+ *
+ * @param tool
+ * the execution tool
+ * @param monitor
+ * the progression monitor
+ * @param options
+ * the launching options
+ * @param modules
+ * the transformation modules
+ * @return the execution result
+ */
+ protected Object internalLaunch(final VMMonitor tool, final IProgressMonitor monitor,
+ final Map<String, Object> options, Object... modules) {
+ getModuleFromObject(modules[0]);
+ for (int i = 1; i < modules.length; i++) {
+ getModuleFromObject(modules[i]);
+ }
+
+ for (Model model : LazyCollections.asLazySet(execEnv.getInoutModels().values())
+ .union(LazyCollections.asLazySet(execEnv.getOutputModels().values()))) {
+ model.setAllowInterModelReferences(
+ LauncherService.getBooleanOption(options.get("allowInterModelReferences"), false)); //$NON-NLS-1$
+ }
+
+ execEnv.setMonitor(tool);
+ execEnv.setJitDisabled(LauncherService.getBooleanOption(options.get("jitDisabled"), false)); //$NON-NLS-1$
+ timingData.finishLoading();
+
+ final Object result = execEnv.run(timingData);
+
+ timingData.finish();
+ if (LauncherService.getBooleanOption(options.get("printExecutionTime"), false)) { //$NON-NLS-1$
+ ATLLogger.info(timingData.toString());
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#loadModule(java.io.InputStream)
+ */
+ public Module loadModule(final InputStream inputStream) {
+ final Resource resource = moduleResourceSet
+ .createResource(URI.createURI(UUID.randomUUID().toString() + DefaultModuleResolver.FILE_EXT));
+ try {
+ resource.load(inputStream, Collections.emptyMap());
+ final Module module = findModule(resource);
+ final Matcher matcher = EMFTVMUtil.DELIM_PATTERN.matcher(module.getName());
+ final String path = matcher.replaceAll("/");
+ resource.setURI(URI.createURI(EMF_URI_PREFIX + path + DefaultModuleResolver.FILE_EXT));
+ execEnv.loadModule(moduleResolver, module.getName());
+ return module;
+ } catch (IOException e) {
+ throw new VMException(null, e.getLocalizedMessage(), e);
+ }
+ }
+
+ /**
+ * Load a module if necessary.
+ *
+ * @param module
+ * the given {@link Module} or {@link InputStream}.
+ * @return the {@link Module}
+ */
+ protected Module getModuleFromObject(Object module) {
+ if (module instanceof InputStream) {
+ return loadModule((InputStream) module);
+ } else if (module instanceof Module) {
+ return (Module) module;
+ }
+ return null;
+ }
+
+ /**
+ * Finds the first module in {@link Resource}
+ *
+ * <pre>
+ * r
+ * </pre>
+ *
+ * .
+ *
+ * @param r
+ * @return the module with the given name inside
+ *
+ * <pre>
+ * r
+ * </pre>
+ *
+ * , or <code>null</code>
+ */
+ private Module findModule(final Resource r) throws ModuleNotFoundException {
+ for (EObject o : r.getContents()) {
+ if (o instanceof Module) {
+ return (Module) o;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#getModel(java.lang.String)
+ */
+ public IModel getModel(String modelName) {
+ return models.get(modelName);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#getLibrary(java.lang.String)
+ */
+ public Object getLibrary(String libraryName) {
+ return libraries.get(libraryName);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#getDefaultModelFactoryName()
+ */
+ public String getDefaultModelFactoryName() {
+ return MODEL_FACTORY_NAME;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.m2m.atl.core.launch.ILauncher#getModes()
+ */
+ public String[] getModes() {
+ return new String[] { RUN_MODE };
+ }
+}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/messages.properties b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/messages.properties
new file mode 100644
index 00000000..5eef175f
--- /dev/null
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/messages.properties
@@ -0,0 +1,12 @@
+################################################################################
+# Copyright (c) 2017 Dennis Wagelaar.
+# 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
+#
+# Contributors:
+# Dennis Wagelaar
+################################################################################
+EMFTVMLauncher.LIBRARY_REGISTERED=Library {0} has already been registered
+EMFTVMLauncher.MODEL_REGISTERED=Model {0} has already been registered
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 d7a9164e..80468cc2 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011-2013 Dennis Wagelaar, Vrije Universiteit Brussel.
+ * Copyright (c) 2011-2017 Dennis Wagelaar, Vrije Universiteit Brussel.
* 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
@@ -17,6 +17,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -24,7 +25,7 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@@ -33,12 +34,15 @@ import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
@@ -64,7 +68,7 @@ import org.eclipse.m2m.atl.emftvm.trace.TracePackage;
/**
* EMFTVM static utility methods.
- *
+ *
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
*/
@@ -72,7 +76,7 @@ public final class EMFTVMUtil {
/**
* Returns the registry type of the switched object.
- *
+ *
* @author <a href="dwagelaar@gmail.com">Dennis Wagelaar</a>
*/
public static class RegistryTypeSwitch extends EcoreSwitch<Object> {
@@ -127,7 +131,7 @@ public final class EMFTVMUtil {
/**
* Type namespace matching pattern.
- *
+ *
* @see #NS_DELIM
*/
public static final Pattern DELIM_PATTERN = Pattern.compile(NS_DELIM);
@@ -149,23 +153,49 @@ public final class EMFTVMUtil {
/**
* Cache used to store native Java methods.
- *
+ *
* @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static final Map<Class<?>, Map<Integer, Method>> METHOD_CACHE = new WeakHashMap<Class<?>, Map<Integer, Method>>();
+ private static final ConcurrentMap<MethodSignature, WeakReference<Method>> METHOD_CACHE = new ConcurrentHashMap<MethodSignature, WeakReference<Method>>();
+
+ /**
+ * Represents the <code>null</code> method reference for the {@link #METHOD_CACHE}.
+ */
+ private static final WeakReference<Method> NULL_METHOD_REFERENCE = new WeakReference<Method>(null);
+
+ /**
+ * Cache used to store the found root methods for native Java methods.
+ *
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
+ */
+ private static final Map<Method, WeakReference<Method>> ROOT_METHOD_CACHE = Collections
+ .synchronizedMap(new WeakHashMap<Method, WeakReference<Method>>());
/**
* Singleton {@link RegistryTypeSwitch} instance.
*/
private static final RegistryTypeSwitch REGISTRY_TYPE_SWITCH = new RegistryTypeSwitch();
+ /**
+ * {@link Map#toString()} evaluation cut-off number.
+ */
+ private static final int CUT_OFF = 31;
+
private static Metamodel ecoreMetamodel;
private static Metamodel emfTvmMetamodel;
private static Metamodel traceMetamodel;
+ private static volatile int MethodCacheAccesses;
+ private static volatile int MethodCacheHits;
+ private static volatile int RootMethodCacheAccesses;
+ private static volatile int RootMethodCacheHits;
+
/**
* Not used.
*/
@@ -174,7 +204,7 @@ public final class EMFTVMUtil {
/**
* Returns the name of <code>type</code>, for printing.
- *
+ *
* @param env
* the current {@link ExecEnv}
* @param type
@@ -190,7 +220,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();
}
@@ -198,7 +230,7 @@ public final class EMFTVMUtil {
/**
* Returns the names of <code>types</code>, for printing.
- *
+ *
* @param env
* the current {@link ExecEnv}.
* @param types
@@ -208,7 +240,7 @@ public final class EMFTVMUtil {
public static String getTypeNames(final ExecEnv env, final Object[] types) {
final StringBuffer names = new StringBuffer();
boolean notFirst = false;
- for (Object type : types) {
+ for (final Object type : types) {
if (notFirst) {
names.append(", ");
}
@@ -220,7 +252,7 @@ public final class EMFTVMUtil {
/**
* Returns the type object to use for the registry.
- *
+ *
* @param type
* the type object
* @return the type object to use for the registry
@@ -236,10 +268,10 @@ public final class EMFTVMUtil {
/**
* Returns the singleton instance of the Ecore metamodel.
- *
+ *
* @return the singleton instance of the Ecore metamodel
*/
- public static Metamodel getEcoreMetamodel() {
+ public static synchronized Metamodel getEcoreMetamodel() {
if (ecoreMetamodel == null) {
ecoreMetamodel = EmftvmFactory.eINSTANCE.createMetamodel();
ecoreMetamodel.setResource(EcorePackage.eINSTANCE.eResource());
@@ -249,10 +281,10 @@ public final class EMFTVMUtil {
/**
* Returns the singleton instance of the EMFTVM metamodel.
- *
+ *
* @return the singleton instance of the EMFTVM metamodel
*/
- public static Metamodel getEmfTvmMetamodel() {
+ public static synchronized Metamodel getEmfTvmMetamodel() {
if (emfTvmMetamodel == null) {
emfTvmMetamodel = EmftvmFactory.eINSTANCE.createMetamodel();
emfTvmMetamodel.setResource(EmftvmPackage.eINSTANCE.eResource());
@@ -262,10 +294,10 @@ public final class EMFTVMUtil {
/**
* Returns the singleton instance of the Trace metamodel.
- *
+ *
* @return the singleton instance of the Trace metamodel
*/
- public static Metamodel getTraceMetamodel() {
+ public static synchronized Metamodel getTraceMetamodel() {
if (traceMetamodel == null) {
traceMetamodel = EmftvmFactory.eINSTANCE.createMetamodel();
traceMetamodel.setResource(TracePackage.eINSTANCE.eResource());
@@ -275,7 +307,7 @@ public final class EMFTVMUtil {
/**
* Finds all instances of type in the registered input/inout models.
- *
+ *
* @param type
* the type
* @param env
@@ -284,10 +316,10 @@ public final class EMFTVMUtil {
*/
public static LazyList<EObject> findAllInstances(final EClass type, final ExecEnv env) {
LazyList<EObject> allInst = new LazyList<EObject>();
- for (Model model : env.getInputModels().values()) {
+ for (final Model model : env.getInputModels().values()) {
allInst = allInst.union(model.allInstancesOf(type));
}
- for (Model model : env.getInoutModels().values()) {
+ for (final Model model : env.getInoutModels().values()) {
allInst = allInst.union(model.allInstancesOf(type));
}
return allInst;
@@ -295,7 +327,7 @@ public final class EMFTVMUtil {
/**
* Finds all instances of type in the given model.
- *
+ *
* @param modelname
* the model name
* @param type
@@ -318,7 +350,7 @@ public final class EMFTVMUtil {
/**
* Offers an alternative to the default <code>toString()</code> method. Uses <code>env</code> to determine the containing model of
* types. Compensates for {@link EObject}'s notoriously bad <code>toString()</code>.
- *
+ *
* @param object
* @param env
* @return the string representation of <code>object</code>.
@@ -356,6 +388,18 @@ public final class EMFTVMUtil {
return new StringBuffer().append('\'').append(object.toString()).append('\'').toString();
} else if (object instanceof LazyCollection<?>) {
return ((LazyCollection<?>) object).asString(env);
+ } else if (object instanceof Map<?,?>) {
+ final Map<?, ?> map = (Map<?, ?>) object;
+ final StringBuilder buf = new StringBuilder("Map{");
+ appendMapEntries(env, map, buf);
+ buf.append('}');
+ return buf.toString();
+ } else if (object instanceof Tuple) {
+ final Tuple tuple = (Tuple) object;
+ final StringBuilder buf = new StringBuilder("Tuple{");
+ appendMapEntries(env, tuple.asMap(), buf);
+ buf.append('}');
+ return buf.toString();
} else if (object != null) {
return object.toString();
} else {
@@ -364,9 +408,35 @@ public final class EMFTVMUtil {
}
/**
+ * Appends the map entries to the string builder.
+ *
+ * @param env
+ * the current {@link ExecEnv}
+ * @param map
+ * the {@link Map} for which to append the entries
+ * @param buf
+ * the {@link StringBuilder} to append to
+ */
+ private static void appendMapEntries(final ExecEnv env, final Map<?, ?> map, final StringBuilder buf) {
+ int index = 0;
+ for (final Map.Entry<?, ?> entry : map.entrySet()) {
+ if (index > CUT_OFF) {
+ buf.append(", ...");
+ break;
+ }
+ if (index++ > 0) {
+ buf.append(", ");
+ }
+ buf.append(EMFTVMUtil.toPrettyString(entry.getKey(), env));
+ buf.append('=');
+ buf.append(EMFTVMUtil.toPrettyString(entry.getValue(), env));
+ }
+ }
+
+ /**
* Offers an alternative to the default <code>toString()</code> method. Uses <code>env</code> to determine the containing model of
* types. Compensates for {@link EObject}'s notoriously bad <code>toString()</code>.
- *
+ *
* @param coll
* @param env
* @return the string representation of <code>coll</code>.
@@ -375,7 +445,7 @@ public final class EMFTVMUtil {
final StringBuffer sb = new StringBuffer();
sb.append('[');
boolean first = true;
- for (Object object : coll) {
+ for (final Object object : coll) {
if (!first) {
sb.append(", ");
}
@@ -389,7 +459,7 @@ public final class EMFTVMUtil {
/**
* Offers an alternative to the default <code>toString()</code> method. Uses <code>env</code> to determine the containing model of
* types. Compensates for {@link EObject}'s notoriously bad <code>toString()</code>.
- *
+ *
* @param array
* @param env
* @return the string representation of <code>coll</code>.
@@ -398,7 +468,7 @@ public final class EMFTVMUtil {
final StringBuffer sb = new StringBuffer();
sb.append('[');
boolean first = true;
- for (Object object : array) {
+ for (final Object object : array) {
if (!first) {
sb.append(", ");
}
@@ -411,7 +481,7 @@ public final class EMFTVMUtil {
/**
* Retrieves the value of <code>eo.sf</code>. Checks that <code>eo</code> is not in an output model.
- *
+ *
* @param env
* the current {@link ExecEnv}
* @param eo
@@ -430,7 +500,7 @@ public final class EMFTVMUtil {
/**
* Retrieves the value of <code>eo.sf</code>.
- *
+ *
* @param env
* the current {@link ExecEnv}
* @param eo
@@ -477,7 +547,7 @@ public final class EMFTVMUtil {
/**
* Converts <code>value</code> to an EMFTVM value.
- *
+ *
* @param env
* the current {@link ExecEnv}
* @param eo
@@ -529,7 +599,7 @@ public final class EMFTVMUtil {
/**
* Sets the <code>value</code> of <code>eo.sf</code>.
- *
+ *
* @param env
* the current {@link ExecEnv}
* @param eo
@@ -550,8 +620,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 {
@@ -562,7 +632,7 @@ public final class EMFTVMUtil {
/**
* Adds the <code>value</code> of <code>eo.sf</code>.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -597,7 +667,7 @@ public final class EMFTVMUtil {
/**
* Removes the <code>value</code> from <code>eo.sf</code>.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -637,7 +707,7 @@ public final class EMFTVMUtil {
/**
* Sets the <code>value</code> of <code>eo.sf</code>. Assumes <code>sf</code> has a multiplicity &lt;= 1.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -658,11 +728,13 @@ public final class EMFTVMUtil {
assert value == null || ((EObject) value).eResource() != null;
assert oldValue == null || oldValue.eResource() != null;
eo.eSet(sf, value);
- if (value != null) {
- updateResource(eo, (EObject) value);
- }
- if (oldValue != null) {
- updateResource(eo, oldValue);
+ if (ref.isContainment() || ref.isContainer()) {
+ if (value != null) {
+ updateResource(eo, (EObject) value);
+ }
+ if (oldValue != null) {
+ updateResource(eo, oldValue);
+ }
}
assert eo.eResource() != null;
assert value == null || ((EObject) value).eResource() != null;
@@ -685,7 +757,7 @@ public final class EMFTVMUtil {
/**
* Sets the <code>value</code> of <code>eo.sf</code>. Assumes <code>sf</code> has a multiplicity &gt; 1.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -698,7 +770,7 @@ public final class EMFTVMUtil {
if (!values.isEmpty()) {
if (sf instanceof EReference) {
final List<Object> vCopy = new ArrayList<Object>(values);
- for (EObject v : (List<? extends EObject>) vCopy) {
+ for (final EObject v : (List<? extends EObject>) vCopy) {
removeRefValue((EReference) sf, eo, values, v);
}
} else {
@@ -710,7 +782,7 @@ public final class EMFTVMUtil {
/**
* Adds <code>value</code> to <code>eo.sf</code>. Assumes <code>sf</code> has a multiplicity &gt; 1.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -739,7 +811,7 @@ public final class EMFTVMUtil {
/**
* Adds all <code>value</code> elements to <code>eo.sf</code>. Assumes <code>sf</code> has a multiplicity &gt; 1.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -757,11 +829,13 @@ public final class EMFTVMUtil {
final Collection<?> srcValues = ref.isContainment() ? new ArrayList<Object>(value) : value;
if (index > -1) {
int currentIndex = index;
- for (Object v : srcValues) {
+ for (final Object v : srcValues) {
+ checkValueTypeIsEObject(env, ref, v);
addRefValue(env, ref, eo, values, (EObject) v, currentIndex++, allowInterModelReferences);
}
} else {
- for (Object v : srcValues) {
+ for (final Object v : srcValues) {
+ checkValueTypeIsEObject(env, ref, v);
addRefValue(env, ref, eo, values, (EObject) v, -1, allowInterModelReferences);
}
}
@@ -771,11 +845,11 @@ public final class EMFTVMUtil {
final EEnum eEnum = (EEnum) sfType;
if (index > -1) {
int currentIndex = index;
- for (Object v : value) {
+ for (final Object v : value) {
addEnumValue(eEnum, values, v, currentIndex++);
}
} else {
- for (Object v : value) {
+ for (final Object v : value) {
addEnumValue(eEnum, values, v, -1);
}
}
@@ -788,8 +862,26 @@ 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 &gt; 1.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -815,7 +907,7 @@ public final class EMFTVMUtil {
/**
* Removes all elements of <code>value</code> from <code>eo.sf</code>. Assumes <code>sf</code> has a multiplicity &gt; 1.
- *
+ *
* @param env
* @param eo
* @param sf
@@ -828,14 +920,15 @@ public final class EMFTVMUtil {
if (sf instanceof EReference) {
final EReference ref = (EReference) sf;
final Collection<?> srcValues = ref.isContainment() ? new ArrayList<Object>(value) : value;
- for (Object v : srcValues) {
+ for (final Object v : srcValues) {
+ checkValueTypeIsEObject(env, ref, v);
removeRefValue(ref, eo, values, (EObject) v);
}
} else {
final EClassifier sfType = sf.getEType();
if (sfType instanceof EEnum) {
final EEnum eEnum = (EEnum) sfType;
- for (Object v : value) {
+ for (final Object v : value) {
removeEnumValue(eEnum, values, v);
}
} else {
@@ -846,7 +939,7 @@ public final class EMFTVMUtil {
/**
* Adds <code>v</code> to <code>values</code>. Performs enumerator conversion.
- *
+ *
* @param eEnum
* The enumeration type
* @param values
@@ -870,7 +963,7 @@ public final class EMFTVMUtil {
/**
* Removes <code>v</code> from <code>values</code>. Performs enumerator conversion.
- *
+ *
* @param eEnum
* The enumeration type
* @param values
@@ -886,7 +979,7 @@ public final class EMFTVMUtil {
/**
* Adds <code>v</code> to <code>values</code>. Performs constraint checking on <code>v</code>.
- *
+ *
* @param env
* @param ref
* The reference type
@@ -908,7 +1001,9 @@ public final class EMFTVMUtil {
} else {
values.add(v);
}
- updateResource(eo, v);
+ if (ref.isContainment() || ref.isContainer()) {
+ updateResource(eo, v);
+ }
}
assert eo.eResource() != null;
assert v.eResource() != null;
@@ -916,7 +1011,7 @@ public final class EMFTVMUtil {
/**
* Removes <code>v</code> from <code>values</code>. Performs constraint checking on <code>v</code>.
- *
+ *
* @param ref
* The reference type
* @param eo
@@ -927,7 +1022,7 @@ public final class EMFTVMUtil {
private static void removeRefValue(final EReference ref, final EObject eo, final Collection<Object> values, final EObject v) {
assert eo.eResource() != null;
assert v.eResource() != null;
- if (values.remove(v)) {
+ if (values.remove(v) && (ref.isContainment() || ref.isContainer())) {
updateResource(eo, v);
}
assert eo.eResource() != null;
@@ -936,7 +1031,7 @@ public final class EMFTVMUtil {
/**
* Updates the eResource() for <code>eo</code> and <code>v</code> where necessary
- *
+ *
* @param eo
* the {@link EObject} for which an {@link EReference} has just been modified
* @param v
@@ -960,7 +1055,7 @@ public final class EMFTVMUtil {
/**
* Checks whether the model containing <code>eo</code> allows inter-model references.
- *
+ *
* @param env
* the {@link ExecEnv} in which to find the model.
* @param eo
@@ -978,7 +1073,7 @@ public final class EMFTVMUtil {
/**
* Checks whether <code>value</code> may be assigned to <code>eo.ref</code>.
- *
+ *
* @param env
* the current {@link ExecEnv}
* @param eo
@@ -1002,16 +1097,16 @@ public final class EMFTVMUtil {
assert ev.eResource() != null;
if (!allowInterModelReferences) {
ATLLogger
- .warning(String.format("Cannot set %s::%s to %s for %s: inter-model references are not allowed for this model",
- toPrettyString(ref.getEContainingClass(), env), ref.getName(), toPrettyString(value, env),
- toPrettyString(eo, env)));
+ .warning(String.format("Cannot set %s::%s to %s for %s: inter-model references are not allowed for this model",
+ toPrettyString(ref.getEContainingClass(), env), ref.getName(), toPrettyString(value, env),
+ toPrettyString(eo, env)));
return false;
}
if (ref.isContainer() || ref.isContainment()) {
ATLLogger
- .warning(String.format("Cannot set %s::%s to %s for %s: containment references cannot span across models",
- toPrettyString(ref.getEContainingClass(), env), ref.getName(), toPrettyString(value, env),
- toPrettyString(eo, env)));
+ .warning(String.format("Cannot set %s::%s to %s for %s: containment references cannot span across models",
+ toPrettyString(ref.getEContainingClass(), env), ref.getName(), toPrettyString(value, env),
+ toPrettyString(eo, env)));
return false;
}
final EReference opposite = ref.getEOpposite();
@@ -1030,10 +1125,10 @@ public final class EMFTVMUtil {
final Model oppositeModel = env.getInputModelOf((EObject) ev.eGet(opposite));
if (oppositeModel != null) {
ATLLogger
- .warning(String
- .format("Cannot set %s::%s to %s for %s: inter-model reference with single-valued opposite causes changes in input model %s",
- toPrettyString(ref.getEContainingClass(), env), ref.getName(), toPrettyString(value, env),
- toPrettyString(eo, env), env.getModelID(oppositeModel)));
+ .warning(String
+ .format("Cannot set %s::%s to %s for %s: inter-model reference with single-valued opposite causes changes in input model %s",
+ toPrettyString(ref.getEContainingClass(), env), ref.getName(), toPrettyString(value, env),
+ toPrettyString(eo, env), env.getModelID(oppositeModel)));
return false;
}
}
@@ -1044,7 +1139,7 @@ public final class EMFTVMUtil {
/**
* Retrieves the types of <code>args</code>.
- *
+ *
* @param args
* @return the types of <code>args</code>
*/
@@ -1059,7 +1154,7 @@ public final class EMFTVMUtil {
/**
* Retrieves the type of <code>arg</code>.
- *
+ *
* @param arg
* @return the type of <code>arg</code>
*/
@@ -1075,7 +1170,7 @@ public final class EMFTVMUtil {
/**
* Invokes native Java method <code>opname</code> on <code>self</code> with arguments <code>args</code>.
- *
+ *
* @param frame
* the current stack frame
* @param self
@@ -1098,7 +1193,7 @@ public final class EMFTVMUtil {
/**
* Invokes native Java <code>method</code> on <code>self</code> with arguments <code>args</code>.
- *
+ *
* @param frame
* the current stack frame
* @param self
@@ -1109,27 +1204,29 @@ public final class EMFTVMUtil {
* the method arguments
* @return the method result
*/
- public static Object invokeNative(final StackFrame frame, final Object self, final Method method, final Object[] args) {
+ public static Object invokeNative(final StackFrame frame, final Object self, Method method, final Object[] args) {
+ // Fix for Bug # 461445: EMFTVM cannot invoke Java methods on instances of private classes:
+ method = findRootMethod(method);
final StackFrame subFrame = frame.prepareNativeArgs(method, self, args);
try {
return emf2vm(frame.getEnv(), self instanceof EObject ? (EObject) self : null, method.invoke(self, args));
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
final Throwable target = e.getTargetException();
if (target instanceof VMException) {
throw (VMException) target;
} else {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, target);
}
- } catch (VMException e) {
+ } catch (final VMException e) {
throw e;
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, e);
}
}
/**
* Invokes native Java method <code>opname</code> on <code>self</code> with argument <code>arg</code>.
- *
+ *
* @param frame
* the current stack frame
* @param self
@@ -1152,7 +1249,7 @@ public final class EMFTVMUtil {
/**
* Invokes native Java <code>method</code> on <code>self</code> with argument <code>arg</code>.
- *
+ *
* @param frame
* the current stack frame
* @param self
@@ -1163,7 +1260,9 @@ public final class EMFTVMUtil {
* the method argument
* @return the method result
*/
- public static Object invokeNative(final StackFrame frame, final Object self, final Method method, Object arg) {
+ public static Object invokeNative(final StackFrame frame, final Object self, Method method, Object arg) {
+ // Fix for Bug # 461445: EMFTVM cannot invoke Java methods on instances of private classes:
+ method = findRootMethod(method);
StackFrame subFrame = frame.prepareNativeContext(method, self);
if (arg instanceof CodeBlock) {
if (subFrame == null) {
@@ -1175,23 +1274,23 @@ public final class EMFTVMUtil {
}
try {
return emf2vm(frame.getEnv(), self instanceof EObject ? (EObject) self : null, method.invoke(self, arg));
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
final Throwable target = e.getTargetException();
if (target instanceof VMException) {
throw (VMException) target;
} else {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, target);
}
- } catch (VMException e) {
+ } catch (final VMException e) {
throw e;
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, e);
}
}
/**
* Invokes native Java method <code>opname</code> on <code>self</code> without arguments.
- *
+ *
* @param frame
* the current stack frame
* @param self
@@ -1211,7 +1310,7 @@ public final class EMFTVMUtil {
/**
* Invokes native Java <code>method</code> on <code>self</code> without arguments.
- *
+ *
* @param frame
* the current stack frame
* @param self
@@ -1220,27 +1319,29 @@ public final class EMFTVMUtil {
* the method
* @return the method result
*/
- public static Object invokeNative(final StackFrame frame, final Object self, final Method method) {
+ public static Object invokeNative(final StackFrame frame, final Object self, Method method) {
+ // Fix for Bug # 461445: EMFTVM cannot invoke Java methods on instances of private classes:
+ method = findRootMethod(method);
final StackFrame subFrame = frame.prepareNativeContext(method, self);
try {
return emf2vm(frame.getEnv(), self instanceof EObject ? (EObject) self : null, method.invoke(self));
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
final Throwable target = e.getTargetException();
if (target instanceof VMException) {
throw (VMException) target;
} else {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, target);
}
- } catch (VMException e) {
+ } catch (final VMException e) {
throw e;
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, e);
}
}
/**
* Invokes static native Java method <code>opname</code> with arguments <code>args</code>.
- *
+ *
* @param frame
* the current stack frame
* @param type
@@ -1257,16 +1358,16 @@ public final class EMFTVMUtil {
final StackFrame subFrame = frame.prepareNativeArgs(method, args);
try {
return emf2vm(frame.getEnv(), null, method.invoke(type, args));
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
final Throwable target = e.getTargetException();
if (target instanceof VMException) {
throw (VMException) target;
} else {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, target);
}
- } catch (VMException e) {
+ } catch (final VMException e) {
throw e;
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, e);
}
}
@@ -1276,7 +1377,7 @@ public final class EMFTVMUtil {
/**
* Invokes static native Java method <code>opname</code> with argument <code>arg</code>.
- *
+ *
* @param frame
* the current stack frame
* @param type
@@ -1299,16 +1400,16 @@ public final class EMFTVMUtil {
}
try {
return emf2vm(frame.getEnv(), null, method.invoke(type, arg));
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
final Throwable target = e.getTargetException();
if (target instanceof VMException) {
throw (VMException) target;
} else {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, target);
}
- } catch (VMException e) {
+ } catch (final VMException e) {
throw e;
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new VMException(subFrame == null ? new StackFrame(frame, method) : subFrame, e);
}
}
@@ -1318,7 +1419,7 @@ public final class EMFTVMUtil {
/**
* Invokes static native Java method <code>opname</code> without arguments.
- *
+ *
* @param frame
* the current stack frame
* @param type
@@ -1332,16 +1433,16 @@ public final class EMFTVMUtil {
if (method != null) {
try {
return emf2vm(frame.getEnv(), null, method.invoke(type));
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
final Throwable target = e.getTargetException();
if (target instanceof VMException) {
throw (VMException) target;
} else {
throw new VMException(new StackFrame(frame, method), target);
}
- } catch (VMException e) {
+ } catch (final VMException e) {
throw e;
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new VMException(new StackFrame(frame, method), e);
}
}
@@ -1350,12 +1451,12 @@ public final class EMFTVMUtil {
/**
* Looks for a native Java method.
- *
+ *
* @param context
* The class of the method
* @param opname
* The method name
- * @param argumentTypes
+ * @param argTypes
* The types of all arguments
* @param isStatic
* Whether to look for a static method or not
@@ -1365,44 +1466,119 @@ public final class EMFTVMUtil {
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- // TODO implement multi-methods in ExecEnv
public static Method findNativeMethod(final Class<?> context, final String opname, final Class<?>[] argTypes, final boolean isStatic) {
if (context == Void.TYPE) {
return null; // Java methods cannot be invoked on null, or defined on Void
}
- final Integer sig = getMethodSignature(opname, argTypes, isStatic);
- Method ret = findCachedMethod(context, sig);
- if (ret != null || hasCachedMethod(context, sig)) {
+ final MethodSignature sig = getMethodSignature(context, opname, argTypes, isStatic);
+ MethodCacheAccesses++;
+ final WeakReference<Method> methodRef = METHOD_CACHE.get(sig);
+ final Method ret = methodRef != null ? methodRef.get() : null;
+ if (ret != null || methodRef == NULL_METHOD_REFERENCE) {
+ MethodCacheHits++;
+ return methodRef.get();
+ }
+
+ return findNativeMethodInternal(context, opname, argTypes, isStatic, sig);
+ }
+
+ /**
+ * Looks for a native Java method.
+ *
+ * @param context
+ * The class of the method
+ * @param opname
+ * The method name
+ * @param argumentType
+ * The type of the argument
+ * @param isStatic
+ * Whether to look for a static method or not
+ * @return the method if found, null otherwise
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
+ */
+ public static Method findNativeMethod(final Class<?> context, final String opname, final Class<?> argType, final boolean isStatic) {
+ if (context == Void.TYPE) {
+ return null; // Java methods cannot be invoked on null, or defined on Void
+ }
+
+ final MethodSignature sig = getMethodSignature(context, opname, argType, isStatic);
+ MethodCacheAccesses++;
+ final WeakReference<Method> methodRef = METHOD_CACHE.get(sig);
+ final Method ret = methodRef != null ? methodRef.get() : null;
+ if (ret != null || methodRef == NULL_METHOD_REFERENCE) {
+ MethodCacheHits++;
return ret;
}
+ return findNativeMethodInternal(context, opname, argType, isStatic, sig);
+ }
+
+ /**
+ * Looks for a native Java method without arguments.
+ *
+ * @param context
+ * The class of the method
+ * @param opname
+ * The method name
+ * @param isStatic
+ * Whether to look for a static method or not
+ * @return the method if found, null otherwise
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
+ */
+ public static Method findNativeMethod(final Class<?> context, final String opname, final boolean isStatic) {
+ if (context == Void.TYPE) {
+ return null; // Java methods cannot be invoked on null, or defined on Void
+ }
+
+ final MethodSignature sig = getMethodSignature(context, opname, isStatic);
+ MethodCacheAccesses++;
+ final WeakReference<Method> methodRef = METHOD_CACHE.get(sig);
+ final Method ret = methodRef != null ? methodRef.get() : null;
+ if (ret != null || methodRef == NULL_METHOD_REFERENCE) {
+ MethodCacheHits++;
+ return ret;
+ }
+
+ return findNativeMethodInternal(context, opname, isStatic, sig);
+ }
+
+ /**
+ * Looks for a native Java method.
+ *
+ * @param context
+ * The class of the method
+ * @param opname
+ * The method name
+ * @param argTypes
+ * The types of all arguments
+ * @param isStatic
+ * Whether to look for a static method or not
+ * @param sig
+ * the method signature
+ * @return the method if found, null otherwise
+ */
+ private static Method findNativeMethodInternal(final Class<?> context, final String opname,
+ final Class<?>[] argTypes, final boolean isStatic, final MethodSignature sig) {
+ Method ret = null;
+
final Method[] methods = context.getDeclaredMethods();
METHODS: for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
+ final Method method = methods[i];
if ((Modifier.isStatic(method.getModifiers()) == isStatic) && method.getName().equals(opname)) {
- Class<?>[] pts = method.getParameterTypes();
+ final Class<?>[] pts = method.getParameterTypes();
if (pts.length == argTypes.length) {
boolean ok = true;
for (int j = 0; (j < pts.length) && ok; j++) {
- if (argTypes[j] == EnumLiteral.class && Enumerator.class.isAssignableFrom(pts[j])) {
- continue;
- }
- if (!pts[j].isAssignableFrom(argTypes[j])) {
- if (pts[j] == boolean.class)
- ok = argTypes[j] == Boolean.class;
- else if (pts[j] == int.class)
- ok = argTypes[j] == Integer.class;
- else if (pts[j] == char.class)
- ok = argTypes[j] == Character.class;
- else if (pts[j] == long.class)
- ok = argTypes[j] == Long.class;
- else if (pts[j] == float.class)
- ok = argTypes[j] == Float.class;
- else if (pts[j] == double.class)
- ok = argTypes[j] == Double.class;
- else
- ok = argTypes[j] == Void.TYPE; // any type
+ if (!checkParameterType(argTypes[j], pts[j])) {
+ ok = false;
+ break;
}
}
if (ok) {
@@ -1414,72 +1590,40 @@ public final class EMFTVMUtil {
}
if ((ret == null) && !isStatic && (context.getSuperclass() != null)) {
- ret = findNativeMethod(context.getSuperclass(), opname, argTypes, isStatic);
+ ret = findNativeMethodInternal(context.getSuperclass(), opname, argTypes, isStatic, sig);
+ } else {
+ METHOD_CACHE.put(sig, ret != null ? new WeakReference<Method>(ret) : NULL_METHOD_REFERENCE);
}
- cacheMethod(context, sig, ret);
-
return ret;
}
/**
* Looks for a native Java method.
- *
+ *
* @param context
* The class of the method
* @param opname
* The method name
- * @param argumentType
+ * @param argType
* The type of the argument
* @param isStatic
* Whether to look for a static method or not
+ * @param sig
+ * the method signature
* @return the method if found, null otherwise
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- // TODO implement multi-methods in ExecEnv
- public static Method findNativeMethod(final Class<?> context, final String opname, final Class<?> argType, final boolean isStatic) {
- if (context == Void.TYPE) {
- return null; // Java methods cannot be invoked on null, or defined on Void
- }
-
- final Integer sig = getMethodSignature(opname, argType, isStatic);
- Method ret = findCachedMethod(context, sig);
- if (ret != null || hasCachedMethod(context, sig)) {
- return ret;
- }
+ private static Method findNativeMethodInternal(final Class<?> context, final String opname, final Class<?> argType,
+ final boolean isStatic, final MethodSignature sig) {
+ Method ret = null;
final Method[] methods = context.getDeclaredMethods();
METHODS: for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
+ final Method method = methods[i];
if ((Modifier.isStatic(method.getModifiers()) == isStatic) && method.getName().equals(opname)) {
- Class<?>[] pts = method.getParameterTypes();
+ final Class<?>[] pts = method.getParameterTypes();
if (pts.length == 1) {
- Class<?> pt = pts[0];
- if (argType == EnumLiteral.class && Enumerator.class.isAssignableFrom(pt)) {
- ret = method;
- break METHODS;
- }
- boolean ok = true;
- if (!pt.isAssignableFrom(argType)) {
- if (pt == boolean.class)
- ok = argType == Boolean.class;
- else if (pt == int.class)
- ok = argType == Integer.class;
- else if (pt == char.class)
- ok = argType == Character.class;
- else if (pt == long.class)
- ok = argType == Long.class;
- else if (pt == float.class)
- ok = argType == Float.class;
- else if (pt == double.class)
- ok = argType == Double.class;
- else
- ok = argType == Void.TYPE; // any type
- }
- if (ok) {
+ if (checkParameterType(argType, pts[0])) {
ret = method;
break METHODS;
}
@@ -1488,43 +1632,34 @@ public final class EMFTVMUtil {
}
if ((ret == null) && !isStatic && (context.getSuperclass() != null)) {
- ret = findNativeMethod(context.getSuperclass(), opname, argType, isStatic);
+ ret = findNativeMethodInternal(context.getSuperclass(), opname, argType, isStatic, sig);
+ } else {
+ METHOD_CACHE.put(sig, ret != null ? new WeakReference<Method>(ret) : NULL_METHOD_REFERENCE);
}
- cacheMethod(context, sig, ret);
-
return ret;
}
/**
* Looks for a native Java method without arguments.
- *
+ *
* @param context
* The class of the method
* @param opname
* The method name
* @param isStatic
* Whether to look for a static method or not
+ * @param sig
+ * the method signature
* @return the method if found, null otherwise
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- public static Method findNativeMethod(final Class<?> context, final String opname, final boolean isStatic) {
- if (context == Void.TYPE) {
- return null; // Java methods cannot be invoked on null, or defined on Void
- }
-
- final Integer sig = getMethodSignature(opname, isStatic);
- Method ret = findCachedMethod(context, sig);
- if (ret != null || hasCachedMethod(context, sig)) {
- return ret;
- }
+ private static Method findNativeMethodInternal(final Class<?> context, final String opname, final boolean isStatic,
+ final MethodSignature sig) {
+ Method ret = null;
final Method[] methods = context.getDeclaredMethods();
METHODS: for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
+ final Method method = methods[i];
if ((Modifier.isStatic(method.getModifiers()) == isStatic) && method.getName().equals(opname)) {
if (method.getParameterTypes().length == 0) {
ret = method;
@@ -1534,17 +1669,55 @@ public final class EMFTVMUtil {
}
if ((ret == null) && !isStatic && (context.getSuperclass() != null)) {
- ret = findNativeMethod(context.getSuperclass(), opname, isStatic);
+ ret = findNativeMethodInternal(context.getSuperclass(), opname, isStatic, sig);
+ } else {
+ METHOD_CACHE.put(sig, ret != null ? new WeakReference<Method>(ret) : NULL_METHOD_REFERENCE);
}
- cacheMethod(context, sig, ret);
-
return ret;
}
/**
+ * Checks whether the parameter type is compatible with the argument type
+ *
+ * @param argType
+ * the invocation argument type
+ * @param pt
+ * the method parameter type
+ * @return <code>true</code> if the parameter type is compatible,
+ * <code>false</code> otherwise
+ */
+ private static boolean checkParameterType(final Class<?> argType, final Class<?> pt) {
+ if (argType == EnumLiteral.class && Enumerator.class.isAssignableFrom(pt)) {
+ return true;
+ }
+ if (pt.isAssignableFrom(argType)) {
+ return true;
+ }
+ if (pt == boolean.class){
+ return argType == Boolean.class;
+ }
+ if (pt == int.class) {
+ return argType == Integer.class;
+ }
+ if (pt == char.class) {
+ return argType == Character.class;
+ }
+ if (pt == long.class) {
+ return argType == Long.class;
+ }
+ if (pt == float.class) {
+ return argType == Float.class;
+ }
+ if (pt == double.class) {
+ return argType == Double.class;
+ }
+ return argType == Void.TYPE; // any type
+ }
+
+ /**
* Compares 0-parameter <code>op</code> to <code>method</code>.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param method
@@ -1564,7 +1737,7 @@ public final class EMFTVMUtil {
/**
* Compares 1-parameter <code>op</code> to <code>method</code>.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param method
@@ -1594,7 +1767,7 @@ public final class EMFTVMUtil {
/**
* Compares N-parameter <code>op</code> to <code>method</code>.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param method
@@ -1629,7 +1802,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native Java method without arguments.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param self
@@ -1644,7 +1817,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native Java method with one argument.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param self
@@ -1662,7 +1835,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native Java method with multiple arguments.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param self
@@ -1680,7 +1853,7 @@ public final class EMFTVMUtil {
/**
* Returns the superclass as well as super-interfaces for <code>type</code>.
- *
+ *
* @param type
* the type for which to return supertypes
* @return the superclass as well as super-interfaces for <code>type</code>
@@ -1705,7 +1878,7 @@ public final class EMFTVMUtil {
/**
* Compares 0-parameter <code>method1</code> to <code>method2</code>.
- *
+ *
* @param method1
* the previously found method
* @param method2
@@ -1728,7 +1901,7 @@ public final class EMFTVMUtil {
/**
* Compares 1-parameter <code>method1</code> to <code>method2</code>.
- *
+ *
* @param method1
* the previously found method
* @param method2
@@ -1758,7 +1931,7 @@ public final class EMFTVMUtil {
/**
* Compares N-parameter <code>op</code> to <code>method</code>.
- *
+ *
* @param method1
* the previously found EMFTVM {@link Operation}
* @param method2
@@ -1790,7 +1963,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native superclass Java method without arguments.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param context
@@ -1801,7 +1974,7 @@ public final class EMFTVMUtil {
*/
public static Method findNativeSuperMethod(final Operation op, final Class<?> context, final String opname) {
Method method = null;
- for (Class<?> superCtx : getSuperTypes(context)) {
+ for (final Class<?> superCtx : getSuperTypes(context)) {
method = compareNativeMethod0(method, findNativeMethod(superCtx, opname, false));
}
return compareNativeMethod0(op, method);
@@ -1809,7 +1982,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native superclass Java method with one argument.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param context
@@ -1823,7 +1996,7 @@ public final class EMFTVMUtil {
public static Method findNativeSuperMethod(final Operation op, final Class<?> context, final String opname, final Object arg) {
final Class<?> argType = arg == null ? Void.TYPE : arg.getClass();
Method method = null;
- for (Class<?> superCtx : getSuperTypes(context)) {
+ for (final Class<?> superCtx : getSuperTypes(context)) {
method = compareNativeMethod1(method, findNativeMethod(superCtx, opname, argType, false));
}
return compareNativeMethod1(op, method);
@@ -1831,7 +2004,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native superclass Java method with multiple arguments.
- *
+ *
* @param op
* the previously found EMFTVM {@link Operation}
* @param context
@@ -1845,7 +2018,7 @@ public final class EMFTVMUtil {
public static Method findNativeSuperMethod(final Operation op, final Class<?> context, final String opname, final Object[] args) {
final Class<?>[] argTypes = getArgumentClasses(args);
Method method = null;
- for (Class<?> superCtx : getSuperTypes(context)) {
+ for (final Class<?> superCtx : getSuperTypes(context)) {
method = compareNativeMethodN(method, findNativeMethod(superCtx, opname, argTypes, false));
}
return compareNativeMethodN(op, method);
@@ -1853,7 +2026,7 @@ public final class EMFTVMUtil {
/**
* Looks for a native Java constructor.
- *
+ *
* @param context
* The class of the method
* @param argumentTypes
@@ -1870,8 +2043,8 @@ public final class EMFTVMUtil {
final Constructor<?>[] constructors = context.getConstructors();
CONSTRUCTOR: for (int i = 0; i < constructors.length; i++) {
- Constructor<?> constructor = constructors[i];
- Class<?>[] pts = constructor.getParameterTypes();
+ final Constructor<?> constructor = constructors[i];
+ final Class<?>[] pts = constructor.getParameterTypes();
if (pts.length == argTypes.length) {
boolean ok = true;
for (int j = 0; (j < pts.length) && ok; j++) {
@@ -1906,116 +2079,76 @@ public final class EMFTVMUtil {
}
/**
- * Returns <code>true</code> if the method cache contains the given caller and signature.
- *
- * @param caller
- * The class of the method
- * @param signature
- * The method signature
- * @return <code>true</code> if the method cache contains the given caller and signature
- */
- private static boolean hasCachedMethod(final Class<?> caller, final Integer signature) {
- final Map<Integer, Method> sigMap = METHOD_CACHE.get(caller);
- return (sigMap != null) && sigMap.containsKey(signature);
- }
-
- /**
- * Find a method in the cache.
- *
- * @param caller
- * The class of the method
- * @param signature
- * The method signature
- * @return the method
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
- */
- private static Method findCachedMethod(final Class<?> caller, final Integer signature) {
- final Map<Integer, Method> sigMap = METHOD_CACHE.get(caller);
- return (sigMap != null) ? sigMap.get(signature) : null;
- }
-
- /**
- * Stores a method in a cache.
- *
- * @param caller
- * The class of the method
- * @param signature
- * The method signature
- * @param method
- * The method to store
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
- * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- * @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
- */
- private static void cacheMethod(final Class<?> caller, final Integer signature, final Method method) {
- synchronized (METHOD_CACHE) {
- Map<Integer, Method> sigMap = METHOD_CACHE.get(caller);
- if (sigMap == null) {
- sigMap = new HashMap<Integer, Method>();
- METHOD_CACHE.put(caller, sigMap);
- }
- sigMap.put(signature, method);
- }
- }
-
- /**
- * Generates an int signature to store methods.
- *
+ * Generates a signature to store methods.
+ *
+ * @param context
+ * the method declaring class
* @param name
+ * the method name
* @param argumentTypes
+ * the argument types
* @param isStatic
+ * whether the method is static
* @return The method signature
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic
+ * Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static int getMethodSignature(final String name, final Class<?>[] argumentTypes, final boolean isStatic) {
- int sig = (isStatic ? 31 : 0) + name.hashCode();
- for (int i = 0; i < argumentTypes.length; i++) {
- sig = sig * 31 + argumentTypes[i].hashCode();
- }
- return sig;
+ private static MethodSignature getMethodSignature(final Class<?> context, final String name,
+ final Class<?>[] argumentTypes, final boolean isStatic) {
+ return new MethodSignature(context, name, argumentTypes, isStatic);
}
/**
- * Generates an int signature to store methods.
- *
+ * Generates a signature to store methods.
+ *
+ * @param context
+ * the method declaring class
* @param name
+ * the method name
* @param argumentType
+ * the (single) argument type
+ * @param isStatic
+ * whether the method is static
* @param isStatic
* @return The method signature
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic
+ * Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static int getMethodSignature(final String name, final Class<?> argumentType, final boolean isStatic) {
- return ((isStatic ? 31 : 0) + name.hashCode()) * 31 + argumentType.hashCode();
+ private static MethodSignature getMethodSignature(final Class<?> context, final String name,
+ final Class<?> argumentType, final boolean isStatic) {
+ return new MethodSignature(context, name, new Class<?>[] { argumentType }, isStatic);
}
/**
- * Generates an int signature to store methods.
- *
+ * Generates a signature to store methods.
+ *
+ * @param context
+ * the method declaring class
* @param name
+ * the method name
* @param isStatic
+ * whether the method is static
* @return The method signature
- * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
+ * @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic
+ * Jouault</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
- private static int getMethodSignature(final String name, final boolean isStatic) {
- return (isStatic ? 31 : 0) + name.hashCode();
+ private static MethodSignature getMethodSignature(final Class<?> context, final String name,
+ final boolean isStatic) {
+ return new MethodSignature(context, name, null, isStatic);
}
/**
* Retrieves the classes of <code>args</code>.
- *
+ *
* @param args
* @return the classes of <code>args</code>
*/
@@ -2030,7 +2163,7 @@ public final class EMFTVMUtil {
/**
* Writes <code>string</code> to <code>path</code> with the given <code>charset</code>.
- *
+ *
* @param string
* the string to write
* @param path
@@ -2061,7 +2194,7 @@ public final class EMFTVMUtil {
/**
* Returns the file with the given <code>path</code> in the workspace, or the file in the filesystem if the workspace is not available.
- *
+ *
* @param path
* the absolute or relative path to a file.
* @return the file in the workspace, or the file in the filesystem if the workspace is not available.
@@ -2075,11 +2208,11 @@ public final class EMFTVMUtil {
if (wsPath != null) {
return new File(wsPath);
}
- } catch (InstantiationException e) {
+ } catch (final InstantiationException e) {
ATLLogger.fine(e.getMessage());
- } catch (IllegalAccessException e) {
+ } catch (final IllegalAccessException e) {
ATLLogger.fine(e.getMessage());
- } catch (ClassNotFoundException e) {
+ } catch (final ClassNotFoundException e) {
ATLLogger.fine(e.getMessage());
}
ATLLogger.info("Could not find workspace root; falling back to native java.io.File path resolution");
@@ -2088,7 +2221,7 @@ public final class EMFTVMUtil {
/**
* Creates a new {@link Operation}.
- *
+ *
* @param isStatic
* whether the created operation is static
* @param name
@@ -2117,19 +2250,19 @@ public final class EMFTVMUtil {
final EList<Parameter> pars = op.getParameters();
final EList<LocalVariable> locals = body.getLocalVariables();
if (!isStatic) {
- LocalVariable self = factory.createLocalVariable();
+ final LocalVariable self = factory.createLocalVariable();
self.setName("self");
self.setTypeModel(context[0]);
self.setType(context[1]);
locals.add(self);
}
- for (String[][] par : parameters) {
- Parameter p = factory.createParameter();
+ for (final String[][] par : parameters) {
+ final Parameter p = factory.createParameter();
p.setName(par[0][0]);
p.setTypeModel(par[1][0]);
p.setType(par[1][1]);
pars.add(p);
- LocalVariable lv = factory.createLocalVariable();
+ final LocalVariable lv = factory.createLocalVariable();
lv.setName(par[0][0]);
lv.setTypeModel(par[1][0]);
lv.setType(par[1][1]);
@@ -2141,7 +2274,7 @@ public final class EMFTVMUtil {
/**
* Creates a new {@link Field}.
- *
+ *
* @param name
* field name
* @param isStatic
@@ -2169,26 +2302,10 @@ public final class EMFTVMUtil {
}
/**
- * Retrieves the transitive closure of
- *
- * <pre>
- * field
- * </pre>
- *
- * on
- *
- * <pre>
- * object
- * </pre>
- *
- * .
- *
+ * Retrieves the transitive closure of <code>field</code> on <code>object</code>.
+ *
* @param object
- * the object on which to retrieve
- *
- * <pre>
- * field
- * </pre>
+ * the object on which to retrieve <code>field</code>
* @param field
* the field for which to retrieve the value
* @param frame
@@ -2204,13 +2321,13 @@ public final class EMFTVMUtil {
if (value instanceof List<?>) {
final List<Object> cvalue = (List<Object>) value;
newResult = newResult.union(new LazyListOnList<Object>(cvalue));
- for (Object v : cvalue) {
+ for (final Object v : cvalue) {
newResult = getTrans(v, field, frame, newResult);
}
} else if (value instanceof Collection<?>) {
final Collection<Object> cvalue = (Collection<Object>) value;
newResult = newResult.union(new LazyListOnCollection<Object>(cvalue));
- for (Object v : cvalue) {
+ for (final Object v : cvalue) {
newResult = getTrans(v, field, frame, newResult);
}
} else if (value != null) {
@@ -2221,26 +2338,10 @@ public final class EMFTVMUtil {
}
/**
- * Retrieves the transitive closure of
- *
- * <pre>
- * sf
- * </pre>
- *
- * on
- *
- * <pre>
- * object
- * </pre>
- *
- * .
- *
+ * Retrieves the transitive closure of <code>sf</code> on <code>object</code>.
+ *
* @param object
- * the object on which to retrieve
- *
- * <pre>
- * sf
- * </pre>
+ * the object on which to retrieve <code>sf</code>
* @param sf
* the structural feature for which to retrieve the value
* @param env
@@ -2260,7 +2361,7 @@ public final class EMFTVMUtil {
if (value instanceof LazyList<?>) {
final LazyList<Object> cvalue = (LazyList<Object>) value;
newResult = newResult.union(cvalue);
- for (Object v : cvalue) {
+ for (final Object v : cvalue) {
if (v instanceof EObject) {
newResult = getTrans((EObject) v, sf, env, newResult);
}
@@ -2280,26 +2381,10 @@ public final class EMFTVMUtil {
}
/**
- * Retrieves the transitive closure of
- *
- * <pre>
- * field
- * </pre>
- *
- * on
- *
- * <pre>
- * object
- * </pre>
- *
- * .
- *
+ * Retrieves the transitive closure of <code>field</code> on <code>object</code>.
+ *
* @param object
- * the object on which to retrieve
- *
- * <pre>
- * field
- * </pre>
+ * the object on which to retrieve <code>field</code>
* @param field
* the field for which to retrieve the value
* @param result
@@ -2319,19 +2404,19 @@ public final class EMFTVMUtil {
if (value instanceof LazyList<?>) {
final LazyList<Object> cvalue = (LazyList<Object>) value;
newResult = newResult.union(cvalue);
- for (Object v : cvalue) {
+ for (final Object v : cvalue) {
newResult = getTrans(v, field, newResult);
}
} else if (value instanceof List<?>) {
final List<Object> cvalue = (List<Object>) value;
newResult = newResult.union(new LazyListOnList<Object>(cvalue));
- for (Object v : cvalue) {
+ for (final Object v : cvalue) {
newResult = getTrans(v, field, newResult);
}
} else if (value instanceof Collection<?>) {
final Collection<Object> cvalue = (Collection<Object>) value;
newResult = newResult.union(new LazyListOnCollection<Object>(cvalue));
- for (Object v : cvalue) {
+ for (final Object v : cvalue) {
newResult = getTrans(v, field, newResult);
}
} else if (value != null) {
@@ -2343,7 +2428,7 @@ public final class EMFTVMUtil {
/**
* Tries to convert literal to an instance of type.
- *
+ *
* @param literal
* the enum literal to convert
* @param type
@@ -2357,7 +2442,7 @@ public final class EMFTVMUtil {
final java.lang.reflect.Field valuesField = type.getDeclaredField("VALUES");
final Object values = valuesField.get(null);
if (values instanceof Collection<?>) {
- for (Object value : (Collection<?>) values) {
+ for (final Object value : (Collection<?>) values) {
if (value instanceof Enumerator) {
if (litName.equals(((Enumerator) value).getName()) || litName.equals(value.toString())) {
return value;
@@ -2366,13 +2451,13 @@ public final class EMFTVMUtil {
}
}
// Ignore exceptions; just don't convert here
- } catch (SecurityException e) {
+ } catch (final SecurityException e) {
// do nothing
- } catch (NoSuchFieldException e) {
+ } catch (final NoSuchFieldException e) {
// do nothing
- } catch (IllegalArgumentException e) {
+ } catch (final IllegalArgumentException e) {
// do nothing
- } catch (IllegalAccessException e) {
+ } catch (final IllegalAccessException e) {
// do nothing
}
}
@@ -2381,7 +2466,7 @@ public final class EMFTVMUtil {
/**
* Returns the {@link Locale} for the given <code>locale</code> string.
- *
+ *
* @param locale
* the locale string (e.g. "nl_BE", "es_ES_Traditional_WIN")
* @return the {@link Locale} for the given <code>locale</code> string
@@ -2403,16 +2488,16 @@ public final class EMFTVMUtil {
/**
* Registers all {@link EPackage} nsURIs in <code>rs</code> in the local <code>rs</code> {@link EPackage.Registry}. Sets the
* {@link EPackage} nsURI to the {@link EPackage} name if not set.
- *
+ *
* @param rs
* the {@link ResourceSet}
*/
public static void registerEPackages(final ResourceSet rs) {
final EPackage.Registry registry = rs.getPackageRegistry();
- for (Iterator<Object> i = EcoreUtil.getAllContents(rs, true); i.hasNext();) {
- Object object = i.next();
+ for (final Iterator<Object> i = EcoreUtil.getAllContents(rs, true); i.hasNext();) {
+ final Object object = i.next();
if (object instanceof EPackage) {
- EPackage p = (EPackage) object;
+ final EPackage p = (EPackage) object;
// force existence of nsURI
String nsURI = p.getNsURI();
if (nsURI == null) {
@@ -2421,8 +2506,128 @@ public final class EMFTVMUtil {
}
// overwrite with current value to prevent aliasing problems
registry.put(nsURI, p);
+ } else if (object instanceof EDataType) {
+ adaptDataType((EDataType) object);
+ }
+ }
+ }
+
+ /**
+ * Adapts the given {@link EDataType} if necessary.
+ * @param dt the {@link EDataType} to adapt
+ */
+ private static void adaptDataType(final EDataType dt) {
+ String icn = dt.getInstanceClassName();
+ if (icn == null) {
+ final String tname = dt.getName();
+ if (tname.equals("Boolean")) { //$NON-NLS-1$
+ icn = "boolean"; //$NON-NLS-1$
+ } else if (tname.equals("Double") || tname.equals("Real")) { //$NON-NLS-1$ //$NON-NLS-2$
+ icn = "java.lang.Double"; //$NON-NLS-1$
+ } else if (tname.equals("Float")) { //$NON-NLS-1$
+ icn = "java.lang.Float"; //$NON-NLS-1$
+ } else if (tname.equals("Integer")) { //$NON-NLS-1$
+ icn = "java.lang.Integer"; //$NON-NLS-1$
+ } else if (tname.equals("String")) { //$NON-NLS-1$
+ icn = "java.lang.String"; //$NON-NLS-1$
+ }
+ if (icn != null) {
+ dt.setInstanceClassName(icn);
}
}
}
+ /**
+ * Finds the root {@link Class} declaration for the given <code>method</code>.
+ * @param method the method for which to find the root declaration
+ * @return the root {@link Method}
+ */
+ public static Method findRootMethod(final Method method) {
+ if (method == null) {
+ return null;
+ }
+ RootMethodCacheAccesses++;
+ final WeakReference<Method> rootMethodReference = ROOT_METHOD_CACHE.get(method);
+ Method rootMethod = rootMethodReference != null ? rootMethodReference.get() : null;
+ if (rootMethod != null) {
+ RootMethodCacheHits++;
+ return rootMethod;
+ }
+ rootMethod = findRootMethodInner(method);
+ ROOT_METHOD_CACHE.put(method, new WeakReference<Method>(rootMethod));
+ return rootMethod;
+ }
+
+ /**
+ * Finds the root {@link Class} declaration for the given <code>method</code>.
+ * @param method the method for which to find the root declaration
+ * @return the root {@link Method}
+ */
+ private static Method findRootMethodInner(Method method) {
+ final int methodModifiers = getRelevantModifiers(method);
+ Class<?> dc = method.getDeclaringClass();
+ java.util.Set<Class<?>> dis = new LinkedHashSet<Class<?>>(
+ Arrays.<Class<?>> asList(dc.getInterfaces()));
+ while ((dc = dc.getSuperclass()) != null) {
+ try {
+ final Method superMethod = dc.getDeclaredMethod(method.getName(), method.getParameterTypes());
+ if (getRelevantModifiers(superMethod) == methodModifiers) {
+ method = superMethod;
+ } else {
+ break;
+ }
+ } catch (final SecurityException e) {
+ } catch (final NoSuchMethodException e) {
+ }
+ dis.addAll(Arrays.<Class<?>> asList(dc.getInterfaces()));
+ }
+ while (!dis.isEmpty()) {
+ final java.util.Set<Class<?>> newDis = new LinkedHashSet<Class<?>>();
+ for (final Class<?> di : dis) {
+ try {
+ // Only replace by method declared in a super-interface
+ if (di.isAssignableFrom(method.getDeclaringClass())) {
+ method = di.getDeclaredMethod(method.getName(), method.getParameterTypes());
+ }
+ } catch (final SecurityException e) {
+ } catch (final NoSuchMethodException e) {
+ }
+ newDis.addAll(Arrays.<Class<?>> asList(di.getInterfaces()));
+ }
+ newDis.removeAll(dis);
+ dis = newDis;
+ }
+ return method;
+ }
+
+ /**
+ * Returns the relevant modifiers (visibility and static) for the given method.
+ * @param method the method for which to return the modifiers
+ * @return the relevant modifiers (visibility and static) for the given method
+ */
+ private static int getRelevantModifiers(final Method method) {
+ final int methodModifiers = method.getModifiers();
+ return methodModifiers & (Modifier.PRIVATE + Modifier.PROTECTED + Modifier.PUBLIC + Modifier.STATIC);
+ }
+
+ /**
+ * Returns the hit rate of the method cache.
+ *
+ * @return the hit rate of the method cache, or <code>-1.0</code> if no hits
+ * were recorded yet
+ */
+ public static double getMethodCacheHitRate() {
+ return MethodCacheAccesses > 0 ? (double) MethodCacheHits / (double) MethodCacheAccesses : -1.0;
+ }
+
+ /**
+ * Returns the hit rate of the root method cache.
+ *
+ * @return the hit rate of the root method cache, or <code>-1.0</code> if no
+ * hits were recorded yet
+ */
+ public static double getRootMethodCacheHitRate() {
+ return RootMethodCacheAccesses > 0 ? (double) RootMethodCacheHits / (double) RootMethodCacheAccesses : -1.0;
+ }
+
}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyBag.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyBag.java
index 09dd2145..926741f4 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyBag.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyBag.java
@@ -62,7 +62,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* {@inheritDoc}
*/
@Override
- public int count(E o) {
+ public int count(Object o) {
return (object == null ? o == null : object.equals(o)) ? 1 : 0 +
((LazyCollection<E>)dataSource).count(o);
}
@@ -98,14 +98,14 @@ public class LazyBag<E> extends LazyCollection<E> {
*/
public static class UnionBag<E> extends LazyBag<E> {
- protected final LazyCollection<E> other;
+ protected final LazyCollection<? extends E> other;
/**
* Creates a new {@link UnionBag}.
* @param other the collection to union with <pre>dataSource</pre>
* @param dataSource the underlying collection
*/
- public UnionBag(final LazyCollection<E> other, final LazyCollection<E> dataSource) {
+ public UnionBag(final LazyCollection<? extends E> other, final LazyCollection<E> dataSource) {
super(dataSource);
this.other = other;
}
@@ -122,7 +122,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* {@inheritDoc}
*/
@Override
- public int count(E object) {
+ public int count(Object object) {
return ((LazyCollection<E>)dataSource).count(object) + other.count(object);
}
@@ -204,7 +204,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* {@inheritDoc}
*/
@Override
- public int count(Integer object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -277,8 +277,8 @@ public class LazyBag<E> extends LazyCollection<E> {
*/
@Override
public boolean contains(Object o) {
- if (o instanceof Integer) {
- final Integer obj = (Integer) o;
+ if (o instanceof Long) {
+ final Long obj = (Long) o;
return (obj >= first && obj <= last);
}
return false;
@@ -288,7 +288,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* {@inheritDoc}
*/
@Override
- public int count(Long object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -488,7 +488,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* @param bag the collection to union with this
* @return The union of self and <code>bag</code>.
*/
- public LazyBag<E> union(final LazyBag<E> bag) {
+ public LazyBag<E> union(final LazyBag<? extends E> bag) {
return new UnionBag<E>(bag, this);
}
@@ -579,7 +579,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* @return The collection containing all elements of self plus <code>coll</code>.
*/
@Override
- public LazyBag<E> includingAll(final Collection<E> coll) {
+ public LazyBag<E> includingAll(final Collection<? extends E> coll) {
return union(LazyCollections.asLazyBag(coll));
}
@@ -597,7 +597,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* @throws UnsupportedOperationException
*/
@Override
- public LazyBag<E> includingAll(final Collection<E> coll, final int index) {
+ public LazyBag<E> includingAll(final Collection<? extends E> coll, final int index) {
throw new UnsupportedOperationException("Cannot specify index for adding values to unordered collections");
}
@@ -611,7 +611,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* the object to exclude
* @return The bag containing all elements of self apart from all occurrences of <code>object</code>.
*/
- public LazyBag<E> excluding(final E object) {
+ public LazyBag<E> excluding(final Object object) {
return new LazyBag<E>(this) {
@Override
public Iterator<E> iterator() {
@@ -634,7 +634,7 @@ public class LazyBag<E> extends LazyCollection<E> {
* @return The collection containing all elements of self minus <code>coll</code>.
*/
@Override
- public LazyBag<E> excludingAll(final Collection<E> coll) {
+ public LazyBag<E> excludingAll(final Collection<?> coll) {
return new LazyBag<E>(this) {
@Override
public Iterator<E> iterator() {
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyCollection.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyCollection.java
index 250c476c..e264b586 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyCollection.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyCollection.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Vrije Universiteit Brussel.
+ * Copyright (c) 2011-2015 Dennis Wagelaar, Vrije Universiteit Brussel.
* 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
@@ -31,7 +31,7 @@ import org.eclipse.m2m.atl.emftvm.ExecEnv;
* Based on the OCL 2.2 specification (formal/2010-02-01).
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*
- * @param <E>
+ * @param <E> the collection element type
*/
public abstract class LazyCollection<E> implements Collection<E> {
@@ -562,7 +562,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
*/
public class ExcludingIterator extends CachingIterator {
- protected final E object;
+ protected final Object object;
protected E next;
protected boolean nextSet;
@@ -570,7 +570,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* Creates a new {@link ExcludingIterator}, which excludes <code>object</code>.
* @param object the object to exclude
*/
- public ExcludingIterator(final E object) {
+ public ExcludingIterator(final Object object) {
super(dataSource.iterator());
this.object = object;
}
@@ -694,7 +694,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
*/
public class SubtractionIterator extends CachingIterator {
- protected final Collection<E> s;
+ protected final Collection<?> s;
protected E next;
protected boolean nextSet;
@@ -702,7 +702,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* Creates a new {@link SubtractionIterator} on this and <code>s</code>.
* @param s the collection to subtract from this
*/
- public SubtractionIterator(final Collection<E> s) {
+ public SubtractionIterator(final Collection<?> s) {
super(dataSource.iterator());
this.s = s;
}
@@ -761,8 +761,8 @@ public abstract class LazyCollection<E> implements Collection<E> {
*/
public class UnionIterator extends WrappedIterator {
- protected final Iterable<E> s;
- protected Iterator<E> added; // lazily instantiate this iterator
+ protected final Iterable<? extends E> s;
+ protected Iterator<? extends E> added; // lazily instantiate this iterator
protected boolean innerNext; // cache last inner.hasNext() invocation
/**
@@ -770,7 +770,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* collection and <code>s</code>.
* @param s the collection to union with this
*/
- public UnionIterator(final Iterable<E> s) {
+ public UnionIterator(final Iterable<? extends E> s) {
super();
this.s = s;
}
@@ -816,8 +816,8 @@ public abstract class LazyCollection<E> implements Collection<E> {
*/
public class UnionSetIterator extends CachingSetIterator {
- protected final Iterable<E> s;
- protected Iterator<E> added; // lazily instantiate this iterator
+ protected final Iterable<? extends E> s;
+ protected Iterator<? extends E> added; // lazily instantiate this iterator
protected boolean innerNext; // cache last inner.hasNext() invocation
/**
@@ -825,7 +825,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* collection and <code>s</code>.
* @param s the collection to union with this
*/
- public UnionSetIterator(final Iterable<E> s) {
+ public UnionSetIterator(final Iterable<? extends E> s) {
super();
this.s = s;
}
@@ -1853,7 +1853,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* @param object the object to check for
* @return <code>true</code> if <code>object</code> is an element of self, <code>false</code> otherwise.
*/
- public boolean includes(final E object) {
+ public boolean includes(final Object object) {
return contains(object);
}
@@ -1862,7 +1862,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* @param object the object to check for
* @return <code>true</code> if <code>object</code> is not an element of self, <code>false</code> otherwise.
*/
- public boolean excludes(final E object) {
+ public boolean excludes(final Object object) {
return !contains(object);
}
@@ -1871,7 +1871,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* @param object the object to check for
* @return The number of times that <code>object</code> occurs in the collection self.
*/
- public synchronized int count(final E object) {
+ public synchronized int count(final Object object) {
if (occurrences == null) {
occurrences = new HashMap<E, Integer>();
for (E e : this) {
@@ -1890,7 +1890,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* @param c2 the collection to check
* @return <code>true</code> iff self contains all elements of <code>c2</code>.
*/
- public boolean includesAll(final Collection<E> c2) {
+ public boolean includesAll(final Collection<?> c2) {
return containsAll(c2);
}
@@ -1899,7 +1899,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* @param c2 the collection to check
* @return <code>true</code> iff self contains no elements of <code>c2</code>.
*/
- public boolean excludesAll(final Collection<E> c2) {
+ public boolean excludesAll(final Collection<?> c2) {
return !containsAny(c2);
}
@@ -2136,7 +2136,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* the collection to include
* @return The collection containing all elements of self plus <code>coll</code>.
*/
- public abstract LazyCollection<E> includingAll(Collection<E> coll);
+ public abstract LazyCollection<E> includingAll(Collection<? extends E> coll);
/**
* Returns the collection containing all elements of self plus <code>coll</code>.
@@ -2150,7 +2150,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* the index at which to insert <code>coll</code> (starting at 1)
* @return The collection containing all elements of self plus <code>coll</code>.
*/
- public abstract LazyCollection<E> includingAll(Collection<E> coll, int index);
+ public abstract LazyCollection<E> includingAll(Collection<? extends E> coll, int index);
/**
* Returns the collection containing all elements of self apart from all occurrences of <code>object</code>.
@@ -2162,7 +2162,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* the object to exclude
* @return The collection containing all elements of self apart from all occurrences of <code>object</code>.
*/
- public abstract LazyCollection<E> excluding(final E object);
+ public abstract LazyCollection<E> excluding(final Object object);
/**
* Returns the collection containing all elements of self minus <code>coll</code>.
@@ -2174,7 +2174,7 @@ public abstract class LazyCollection<E> implements Collection<E> {
* the collection to exclude
* @return The collection containing all elements of self minus <code>coll</code>.
*/
- public abstract LazyCollection<E> excludingAll(Collection<E> coll);
+ public abstract LazyCollection<E> excludingAll(Collection<?> coll);
/**
* Returns the collection containing all elements of self plus the collection of <code>first</code> running to <code>last</code>.
@@ -2366,4 +2366,70 @@ public abstract class LazyCollection<E> implements Collection<E> {
*/
public abstract LazyCollection<E> sortedBy(final CodeBlock body);
+ /**
+ * Returns a Map indexed by the return value(s) <code>x</code> of the
+ * body expression, containing the Set of elements for which the
+ * body expression returns <code>x</code>.
+ * @param body the function to evaluate on each element
+ * @return the Map
+ */
+ public Map<Object, LazySet<E>> mappedBy(final CodeBlock body) {
+ final StackFrame frame = body.getParentFrame();
+ body.setParentFrame(null);
+ final Map<Object, LazySet<E>> result = new HashMap<Object, LazySet<E>>();
+ final Map<Object, HashSet<E>> shadow = new HashMap<Object, HashSet<E>>();
+ for (E e : this) {
+ Object key = body.execute(frame.getSubFrame(body, new Object[] { e }));
+ if (key instanceof Collection<?>) {
+ for (Object k : (Collection<?>) key) {
+ updateMaps(k, e, result, shadow);
+ }
+ } else {
+ updateMaps(key, e, result, shadow);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns a Map indexed by the return value(s) <code>x</code> of the
+ * body expression, containing a single element for which the
+ * body expression returns <code>x</code>.
+ * @param body the function to evaluate on each element
+ * @return the Map
+ */
+ public Map<Object, E> mappedBySingle(final CodeBlock body) {
+ final StackFrame frame = body.getParentFrame();
+ body.setParentFrame(null);
+ final Map<Object, E> result = new HashMap<Object, E>();
+ for (E e : this) {
+ Object key = body.execute(frame.getSubFrame(body, new Object[] { e }));
+ if (key instanceof Collection<?>) {
+ for (Object k : (Collection<?>) key) {
+ result.put(k, e);
+ }
+ } else {
+ result.put(key, e);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Updates the given maps for {@link #mappedBy(CodeBlock)}.
+ * @param key the map key
+ * @param e the map value
+ * @param result the result map
+ * @param shadow the shadow map of mutable sets
+ */
+ private void updateMaps(final Object key, E e, final Map<Object, LazySet<E>> result, final Map<Object, HashSet<E>> shadow) {
+ HashSet<E> values = shadow.get(key);
+ if (values == null) {
+ values = new HashSet<E>();
+ shadow.put(key, values);
+ result.put(key, new LazySetOnSet<E>(values));
+ }
+ values.add(e);
+ }
+
} \ No newline at end of file
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyList.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyList.java
index 91d4a73d..ae2a71b3 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyList.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyList.java
@@ -23,17 +23,18 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.NoSuchElementException;
+import org.eclipse.emf.common.util.EList;
import org.eclipse.m2m.atl.emftvm.CodeBlock;
import org.eclipse.m2m.atl.emftvm.ExecEnv;
/**
- * Immutable {@link List} that supports lazy evaluation.
+ * Immutable {@link EList} that supports lazy evaluation.
* @author <a href="mailto:dwagelaar@gmail.com">Dennis Wagelaar</a>
*
* @param <E> the collection element type
*/
-public class LazyList<E> extends LazyCollection<E> implements List<E> {
+public class LazyList<E> extends LazyCollection<E> implements EList<E> {
/**
* Abstract {@link LazyList} that disables caching of the underlying {@link LazyList}.
@@ -70,14 +71,14 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
*/
public static class UnionList<E> extends NonCachingList<E> {
- protected final LazyList<E> s;
+ protected final LazyList<? extends E> s;
/**
* Creates a new {@link UnionList}.
* @param s the collection to union with the underlying collection
* @param dataSource the underlying collection
*/
- public UnionList(final LazyList<E> s, final LazyList<E> dataSource) {
+ public UnionList(final LazyList<? extends E> s, final LazyList<E> dataSource) {
super(dataSource);
this.s = s;
assert s != null;
@@ -163,7 +164,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* {@inheritDoc}
*/
@Override
- public int count(E object) {
+ public int count(Object object) {
return ((LazyCollection<E>)dataSource).count(object) + s.count(object);
}
@@ -362,7 +363,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* {@inheritDoc}
*/
@Override
- public int count(final E o) {
+ public int count(final Object o) {
return (object == null ? o == null : object.equals(o)) ? 1 : 0 +
((LazyCollection<E>)dataSource).count(o);
}
@@ -1242,7 +1243,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* {@inheritDoc}
*/
@Override
- public int count(Integer object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -1379,8 +1380,8 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
*/
@Override
public boolean contains(Object o) {
- if (o instanceof Integer) {
- final Integer obj = (Integer) o;
+ if (o instanceof Long) {
+ final Long obj = (Long) o;
return (obj >= first && obj <= last);
}
return false;
@@ -1390,7 +1391,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* {@inheritDoc}
*/
@Override
- public int count(Long object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -1429,8 +1430,8 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
*/
public class UnionListIterator extends WrappedListIterator {
- protected final List<E> s;
- protected ListIterator<E> added; // lazily instantiate this iterator
+ protected final List<? extends E> s;
+ protected ListIterator<? extends E> added; // lazily instantiate this iterator
protected boolean innerNext; // cache last inner.hasNext() invocation
protected boolean addedPrev; // cache last added.hasPrevious() invocation
@@ -1439,7 +1440,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* collection and <code>s</code>.
* @param s the collection to union
*/
- public UnionListIterator(final List<E> s) {
+ public UnionListIterator(final List<? extends E> s) {
super();
this.s = s;
}
@@ -1450,7 +1451,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* @param s the collection to union
* @param index the iterator starting index.
*/
- public UnionListIterator(final List<E> s, final int index) {
+ public UnionListIterator(final List<? extends E> s, final int index) {
super(index);
this.s = s;
}
@@ -1736,6 +1737,28 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
/**
* {@inheritDoc}
+ *
+ * Unsupported in this implementation.
+
+ * @throws UnsupportedOperationException
+ */
+ public void move(int newPosition, E object) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Unsupported in this implementation.
+
+ * @throws UnsupportedOperationException
+ */
+ public E move(int newPosition, int oldPosition) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
*/
@Override
public boolean equals(final Object o) {
@@ -1865,7 +1888,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* @param s the list to union with this
* @return The sequence consisting of all elements in self, followed by all elements in <code>s</code>.
*/
- public LazyList<E> union(final LazyList<E> s) {
+ public LazyList<E> union(final LazyList<? extends E> s) {
return new UnionList<E>(s, this);
}
@@ -1881,7 +1904,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* the insertion index (starting at 1)
* @return The sequence consisting of all elements in self, with all elements in <code>s</code> inserted at <code>index</code>
*/
- public LazyList<E> union(final LazyList<E> s, final int index) {
+ public LazyList<E> union(final LazyList<? extends E> s, final int index) {
if (index == 1) {
return union(s);
}
@@ -1998,7 +2021,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* @return The collection containing all elements of self plus <code>coll</code>.
*/
@Override
- public LazyList<E> includingAll(final Collection<E> coll) {
+ public LazyList<E> includingAll(final Collection<? extends E> coll) {
return union(LazyCollections.asLazyList(coll));
}
@@ -2015,7 +2038,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* @return The collection containing all elements of self plus <code>coll</code>.
*/
@Override
- public LazyList<E> includingAll(final Collection<E> coll, final int index) {
+ public LazyList<E> includingAll(final Collection<? extends E> coll, final int index) {
if (index > 0) {
return union(LazyCollections.asLazyList(coll), index);
} else {
@@ -2033,7 +2056,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* the object to exclude
* @return The sequence containing all elements of self apart from all occurrences of <code>object</code>.
*/
- public LazyList<E> excluding(final E object) {
+ public LazyList<E> excluding(final Object object) {
return new LazyList<E>(this) {
@Override
public Iterator<E> iterator() {
@@ -2056,7 +2079,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
* @return The collection containing all elements of self minus <code>coll</code>.
*/
@Override
- public LazyList<E> excludingAll(final Collection<E> coll) {
+ public LazyList<E> excludingAll(final Collection<?> coll) {
return new LazyList<E>(this) {
@Override
public Iterator<E> iterator() {
@@ -2110,7 +2133,7 @@ public class LazyList<E> extends LazyCollection<E> implements List<E> {
return union((LazyList<E>) new IntegerRangeList((Integer) first, (Integer) last));
}
if (first instanceof Long && last instanceof Long) {
- return union((LazyList<E>) new LongRangeList((Integer) first, (Integer) last));
+ return union((LazyList<E>) new LongRangeList((Long) first, (Long) last));
}
throw new IllegalArgumentException(String.format("includingRange() not supported for arguments of type %s and %s", first.getClass()
.getName(), last.getClass().getName()));
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyOrderedSet.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyOrderedSet.java
index b99369db..632ade5d 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyOrderedSet.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazyOrderedSet.java
@@ -373,7 +373,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* {@inheritDoc}
*/
@Override
- public int count(final E o) {
+ public int count(final Object o) {
return (object == null ? o == null : object.equals(o)) ? 1 :
((LazyCollection<E>)dataSource).count(o);
}
@@ -1279,7 +1279,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
}
}
- protected final E object;
+ protected final Object object;
protected int excludedIndex;
protected boolean excludedIndexSet;
@@ -1288,7 +1288,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* @param object the object to exclude
* @param dataSource the underlying collection
*/
- public ExcludingOrderedSet(final E object, final LazyOrderedSet<E> dataSource) {
+ public ExcludingOrderedSet(final Object object, final LazyOrderedSet<E> dataSource) {
super(dataSource);
this.object = object;
}
@@ -1306,7 +1306,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* {@inheritDoc}
*/
@Override
- public int count(final E o) {
+ public int count(final Object o) {
return (object == null ? o == null : object.equals(o)) ? 0 :
((LazyCollection<E>)dataSource).count(o);
}
@@ -1658,7 +1658,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* {@inheritDoc}
*/
@Override
- public int count(Integer object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -1806,7 +1806,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* {@inheritDoc}
*/
@Override
- public int count(Long object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -2048,7 +2048,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* the object to count
* @return The number of occurrences of <code>object</code> in self.
*/
- public int count(final E o) {
+ public int count(final Object o) {
return contains(o) ? 1 : 0;
}
@@ -2142,7 +2142,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* @param s the collection to union with self
* @return The union of self and <code>s</code>.
*/
- public LazyOrderedSet<E> union(final LazyOrderedSet<E> s) {
+ public LazyOrderedSet<E> union(final LazyOrderedSet<? extends E> s) {
return new LazyOrderedSet<E>(this) {
@Override
public Iterator<E> iterator() {
@@ -2166,7 +2166,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* the insertion index (starting at 1)
* @return The ordered set consisting of all elements in self, with all elements in <code>s</code> inserted at <code>index</code>
*/
- public LazyOrderedSet<E> union(final LazyOrderedSet<E> s, final int index) {
+ public LazyOrderedSet<E> union(final LazyOrderedSet<? extends E> s, final int index) {
if (index == 1) {
return union(s);
}
@@ -2337,7 +2337,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* @return The collection containing all elements of self plus <code>coll</code>.
*/
@Override
- public LazyOrderedSet<E> includingAll(final Collection<E> coll) {
+ public LazyOrderedSet<E> includingAll(final Collection<? extends E> coll) {
return union(LazyCollections.asLazyOrderedSet(coll));
}
@@ -2354,7 +2354,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* @return The collection containing all elements of self plus <code>coll</code>.
*/
@Override
- public LazyOrderedSet<E> includingAll(final Collection<E> coll, final int index) {
+ public LazyOrderedSet<E> includingAll(final Collection<? extends E> coll, final int index) {
if (index > 0) {
return union(LazyCollections.asLazyOrderedSet(coll), index);
} else {
@@ -2372,7 +2372,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* the element to exclude
* @return The set containing all elements of self without <code>object</code>.
*/
- public LazyOrderedSet<E> excluding(final E object) {
+ public LazyOrderedSet<E> excluding(final Object object) {
return new ExcludingOrderedSet<E>(object, this);
}
@@ -2387,7 +2387,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
* @return The collection containing all elements of self minus <code>coll</code>.
*/
@Override
- public LazyOrderedSet<E> excludingAll(final Collection<E> coll) {
+ public LazyOrderedSet<E> excludingAll(final Collection<?> coll) {
return new LazyOrderedSet<E>(this) {
@Override
public Iterator<E> iterator() {
@@ -2516,7 +2516,7 @@ public class LazyOrderedSet<E> extends LazyCollection<E> implements Set<E>, List
return union((LazyOrderedSet<E>) new IntegerRangeOrderedSet((Integer) first, (Integer) last));
}
if (first instanceof Long && last instanceof Long) {
- return union((LazyOrderedSet<E>) new LongRangeOrderedSet((Integer) first, (Integer) last));
+ return union((LazyOrderedSet<E>) new LongRangeOrderedSet((Long) first, (Long) last));
}
throw new IllegalArgumentException(String.format("includingRange() not supported for arguments of type %s and %s", first.getClass()
.getName(), last.getClass().getName()));
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazySet.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazySet.java
index 7b1f30f6..52e55237 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazySet.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/LazySet.java
@@ -159,7 +159,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* {@inheritDoc}
*/
@Override
- public int count(final E o) {
+ public int count(final Object o) {
return (object == null ? o == null : object.equals(o)) ? 1 :
((LazyCollection<E>)dataSource).count(o);
}
@@ -269,7 +269,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
}
}
- protected final E object;
+ protected final Object object;
protected boolean containsExcluded;
protected boolean containsExcludedSet;
@@ -278,7 +278,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* @param object the element to exclude
* @param dataSource the underlying collection
*/
- public ExcludingSet(final E object, final LazySet<E> dataSource) {
+ public ExcludingSet(final Object object, final LazySet<E> dataSource) {
super(dataSource);
this.object = object;
}
@@ -296,7 +296,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* {@inheritDoc}
*/
@Override
- public int count(final E o) {
+ public int count(final Object o) {
return (object == null ? o == null : object.equals(o)) ? 0 :
((LazyCollection<E>)dataSource).count(o);
}
@@ -387,7 +387,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* {@inheritDoc}
*/
@Override
- public int count(Integer object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -471,7 +471,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* {@inheritDoc}
*/
@Override
- public int count(Long object) {
+ public int count(Object object) {
// All elements of a range are unique
return contains(object) ? 1 : 0;
}
@@ -595,7 +595,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* @return The number of occurrences of <code>object</code> in self.
*/
@Override
- public int count(final E o) {
+ public int count(final Object o) {
return contains(o) ? 1 : 0;
}
@@ -609,7 +609,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* @param s the collection to union with self
* @return The union of self and <code>s</code>.
*/
- public LazySet<E> union(final LazySet<E> s) {
+ public LazySet<E> union(final LazySet<? extends E> s) {
return new LazySet<E>(this) {
@Override
public Iterator<E> iterator() {
@@ -723,7 +723,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* @return The collection containing all elements of self plus <code>coll</code>.
*/
@Override
- public LazySet<E> includingAll(final Collection<E> coll) {
+ public LazySet<E> includingAll(final Collection<? extends E> coll) {
return union(LazyCollections.asLazySet(coll));
}
@@ -741,7 +741,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* @throws UnsupportedOperationException
*/
@Override
- public LazySet<E> includingAll(final Collection<E> coll, final int index) {
+ public LazySet<E> includingAll(final Collection<? extends E> coll, final int index) {
throw new UnsupportedOperationException("Cannot specify index for adding values to unordered collections");
}
@@ -755,7 +755,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* the object to exclude
* @return The set containing all elements of self without <code>object</code>.
*/
- public LazySet<E> excluding(final E object) {
+ public LazySet<E> excluding(final Object object) {
return new ExcludingSet<E>(object, this);
}
@@ -770,7 +770,7 @@ public class LazySet<E> extends LazyCollection<E> implements Set<E> {
* @return The collection containing all elements of self minus <code>coll</code>.
*/
@Override
- public LazySet<E> excludingAll(final Collection<E> coll) {
+ public LazySet<E> excludingAll(final Collection<?> coll) {
return new LazySet<E>(this) {
@Override
public Iterator<E> iterator() {
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java
new file mode 100644
index 00000000..f150c0fb
--- /dev/null
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/MethodSignature.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2016-2017 Dennis Wagelaar.
+ * 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
+ *
+ * Contributors:
+ * Dennis Wagelaar - initial API and
+ * implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.m2m.atl.emftvm.util;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * {@link Method} signature for EMFTVM method caching.
+ *
+ * @author <a href="mailto:dwagelaar@gmail.com">Dennis Wagelaar</a>
+ */
+public final class MethodSignature {
+
+ private final String context;
+ private final String name;
+ private final String[] argumentTypes;
+ private final boolean isStatic;
+
+ /**
+ * Creates a new {@link MethodSignature}.
+ *
+ * @param name
+ * the method name
+ * @param argumentTypes
+ * the method argument types
+ * @param isStatic
+ * whether the method is static
+ */
+ public MethodSignature(Class<?> context, String name, Class<?>[] argumentTypes, boolean isStatic) {
+ super();
+ this.context = context.getName();
+ this.name = name;
+ if (argumentTypes != null) {
+ this.argumentTypes = new String[argumentTypes.length];
+ for (int i = 0; i < argumentTypes.length; i++) {
+ this.argumentTypes[i] = argumentTypes[i].getName();
+ }
+ } else {
+ this.argumentTypes = null;
+ }
+ this.isStatic = isStatic;
+ }
+
+ /**
+ * Returns the method context (i.e. declaring class).
+ *
+ * @return the context
+ */
+ public String getContext() {
+ return context;
+ }
+
+ /**
+ * Returns the method name.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the method argument types.
+ *
+ * @return the argumentTypes
+ */
+ public String[] getArgumentTypes() {
+ return argumentTypes;
+ }
+
+ /**
+ * Returns whether the method is static.
+ *
+ * @return the isStatic
+ */
+ public boolean isStatic() {
+ return isStatic;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((context == null) ? 0 : context.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + (isStatic ? 1231 : 1237);
+ result = prime * result + Arrays.hashCode(argumentTypes);
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MethodSignature other = (MethodSignature) obj;
+ if (context == null) {
+ if (other.context != null)
+ return false;
+ } else if (!context.equals(other.context))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (isStatic != other.isStatic)
+ return false;
+ if (!Arrays.equals(argumentTypes, other.argumentTypes))
+ return false;
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "MethodSignature [context=" + context + ", name=" + name + ", argumentTypes="
+ + Arrays.toString(argumentTypes) + ", isStatic=" + isStatic + "]";
+ }
+
+}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java
index 085644ce..67dc025d 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/OCLOperations.java
@@ -1,5 +1,6 @@
/*******************************************************************************
* Copyright (c) 2011 Vrije Universiteit Brussel.
+ * Copyright (c) 2017 Dennis Wagelaar.
* 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
@@ -45,7 +46,6 @@ import org.eclipse.m2m.atl.emftvm.trace.TargetElement;
import org.eclipse.m2m.atl.emftvm.trace.TraceLinkSet;
import org.eclipse.m2m.atl.emftvm.trace.TracedRule;
-
/**
* Provides native operations on simple OCL types.
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
@@ -68,7 +68,7 @@ public final class OCLOperations {
public ResolveIterator() {
super(dataSource.iterator());
}
-
+
/**
* {@inheritDoc}
*/
@@ -82,7 +82,7 @@ public final class OCLOperations {
assert seMapsTo.get(0).getObject().eResource() != null;
next = seMapsTo.get(0).getObject();
} else {
- for (TargetElement te : se.getSourceOf().getTargetElements()) {
+ for (final TargetElement te : se.getSourceOf().getTargetElements()) {
if (te.getMapsTo().isEmpty()) { // default mapping
assert te.getObject().eResource() != null;
next = te.getObject();
@@ -107,7 +107,7 @@ public final class OCLOperations {
super(dataSource);
this.tls = frame.getEnv().getTraces();
}
-
+
/**
* {@inheritDoc}
*/
@@ -118,7 +118,7 @@ public final class OCLOperations {
}
return new ResolveIterator(); // extends CachingIterator
}
-
+
/**
* {@inheritDoc}
*/
@@ -129,7 +129,7 @@ public final class OCLOperations {
}
return ((Collection<Object>)dataSource).size();
}
-
+
}
/**
@@ -155,7 +155,7 @@ public final class OCLOperations {
assert seMapsTo.get(0).getObject().eResource() != null;
next = seMapsTo.get(0).getObject();
} else {
- for (TargetElement te : se.getSourceOf().getTargetElements()) {
+ for (final TargetElement te : se.getSourceOf().getTargetElements()) {
if (te.getMapsTo().isEmpty()) { // default mapping
assert te.getObject().eResource() != null;
next = te.getObject();
@@ -197,7 +197,7 @@ public final class OCLOperations {
return new UniqueResolveIterator(); // extends CachingIterator
}
}
-
+
}
private static OCLOperations instance;
@@ -233,7 +233,7 @@ public final class OCLOperations {
// OclAny
/////////////////////////////////////////////////////////////////////
createOperation(false, "debug", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -251,9 +251,9 @@ public final class OCLOperations {
ATLLogger.info(buf.toString());
return object;
}
- });
+ });
createOperation(false, "debug", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"message"}, Types.STRING_TYPE}},
+ new String[][][]{{{"message"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -272,18 +272,18 @@ public final class OCLOperations {
ATLLogger.info(buf.toString());
return object;
}
- });
+ });
createOperation(false, "toString", Types.OCL_ANY_TYPE, Types.STRING_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
final Object object = frame.getLocal(0, 0);
return EMFTVMUtil.toPrettyString(object, frame.getEnv());
}
- });
+ });
createOperation(false, "oclAsType", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"type"}, Types.CLASSIFIER_TYPE}},
+ new String[][][]{{{"type"}, Types.CLASSIFIER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -297,9 +297,9 @@ public final class OCLOperations {
return object;
}
- });
+ });
createOperation(false, "oclAsType", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -313,9 +313,9 @@ public final class OCLOperations {
return object;
}
- });
+ });
createOperation(false, "oclIsTypeOf", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.CLASSIFIER_TYPE}},
+ new String[][][]{{{"type"}, Types.CLASSIFIER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -324,7 +324,7 @@ public final class OCLOperations {
if (type instanceof EClass) {
return o instanceof EObject && ((EObject) o).eClass() == type;
} else if (o != null) {
- final Class<?> ic = ((EClassifier)type).getInstanceClass();
+ final Class<?> ic = type.getInstanceClass();
if (ic == null) {
throw new IllegalArgumentException(String.format("EClassifier %s must have an instance class", type));
}
@@ -333,9 +333,9 @@ public final class OCLOperations {
return false;
}
}
- });
+ });
createOperation(false, "oclIsTypeOf", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -343,9 +343,9 @@ public final class OCLOperations {
final Class<?> type = (Class<?>)frame.getLocal(0, 1);
return o != null ? o.getClass() == type : false;
}
- });
+ });
createOperation(false, "oclIsKindOf", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.CLASSIFIER_TYPE}},
+ new String[][][]{{{"type"}, Types.CLASSIFIER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -353,9 +353,9 @@ public final class OCLOperations {
final EClassifier type = (EClassifier)frame.getLocal(0, 1);
return type.isInstance(o);
}
- });
+ });
createOperation(false, "oclIsKindOf", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -363,9 +363,9 @@ public final class OCLOperations {
final Class<?> type = (Class<?>)frame.getLocal(0, 1);
return type.isInstance(o);
}
- });
+ });
createOperation(false, "oclType", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -378,9 +378,9 @@ public final class OCLOperations {
return Void.TYPE;
}
}
- });
+ });
createOperation(false, "=", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -388,9 +388,9 @@ public final class OCLOperations {
final Object o2 = frame.getLocal(0, 1);
return o == null ? o2 == null : o.equals(o2);
}
- });
+ });
createOperation(false, "=~", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -398,9 +398,9 @@ public final class OCLOperations {
final Object o2 = frame.getLocal(0, 1);
return o == null ? o2 == null : o.equals(o2);
}
- });
+ });
createOperation(false, "=~|", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -408,9 +408,9 @@ public final class OCLOperations {
final Object o2 = frame.getLocal(0, 1);
return o == null ? o2 == null : o.equals(o2);
}
- });
+ });
createOperation(false, "<>", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -418,9 +418,9 @@ public final class OCLOperations {
final Object o2 = frame.getLocal(0, 1);
return !(o == null ? o2 == null : o.equals(o2));
}
- });
+ });
createOperation(false, "isInModel", Types.OCL_ANY_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"model"}, Types.STRING_TYPE}},
+ new String[][][]{{{"model"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -444,9 +444,9 @@ public final class OCLOperations {
return false;
}
}
- });
+ });
createOperation(false, "refImmediateComposite", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -458,9 +458,9 @@ public final class OCLOperations {
"Cannot retrieve immediate composite for regular objects: %s",
object));
}
- });
+ });
createOperation(false, "refGetValue", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"propname"}, Types.STRING_TYPE}},
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -480,9 +480,9 @@ public final class OCLOperations {
"Cannot retrieve properties for regular objects: %s",
object));
}
- });
+ });
createOperation(false, "refSetValue", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"propname"}, Types.STRING_TYPE}, {{"value"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}, {{"value"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -498,15 +498,15 @@ public final class OCLOperations {
"Cannot find property %s::%s", ecls.getName(), propname));
}
((EObject)object).eSet(sf, value);
- return null;
+ return object;
}
throw new VMException(frame, String.format(
"Cannot set properties for regular objects: %s",
object));
}
- });
+ });
createOperation(false, "refUnsetValue", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"propname"}, Types.STRING_TYPE}},
+ new String[][][]{{{"propname"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -521,13 +521,13 @@ public final class OCLOperations {
"Cannot find property %s::%s", ecls.getName(), propname));
}
((EObject)object).eUnset(sf);
- return null;
+ return object;
}
throw new VMException(frame, String.format(
"Cannot unset properties for regular objects: %s",
object));
}
- });
+ });
createOperation(false, "refInvokeOperation", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{{{"opname"}, Types.STRING_TYPE}, {{"arguments"}, Types.SEQUENCE_TYPE}},
new NativeCodeBlock() {
@@ -538,9 +538,9 @@ public final class OCLOperations {
final List<?> args = (List<?>)frame.getLocal(0, 2);
return EMFTVMUtil.invokeNative(frame, object, opname, args.toArray());
}
- });
+ });
createOperation(false, "resolve", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -552,7 +552,7 @@ public final class OCLOperations {
assert seMapsTo.get(0).getObject().eResource() != null;
return seMapsTo.get(0).getObject();
}
- for (TargetElement te : se.getSourceOf().getTargetElements()) {
+ for (final TargetElement te : se.getSourceOf().getTargetElements()) {
if (te.getMapsTo().isEmpty()) { // default mapping
assert te.getObject().eResource() != null;
return te.getObject();
@@ -561,9 +561,9 @@ public final class OCLOperations {
}
return object;
}
- });
+ });
createOperation(false, "resolve", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"rule"}, Types.STRING_TYPE}},
+ new String[][][]{{{"rule"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -578,7 +578,7 @@ public final class OCLOperations {
assert seMapsTo.get(0).getObject().eResource() != null;
return seMapsTo.get(0).getObject();
}
- for (TargetElement te : se.getSourceOf().getTargetElements()) {
+ for (final TargetElement te : se.getSourceOf().getTargetElements()) {
if (te.getMapsTo().isEmpty()) { // default mapping
assert te.getObject().eResource() != null;
return te.getObject();
@@ -588,8 +588,8 @@ public final class OCLOperations {
}
return object;
}
- });
- createOperation(false, "remap", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
+ });
+ createOperation(false, "remap", Types.OCL_ANY_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{{{"to"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
@@ -601,12 +601,12 @@ public final class OCLOperations {
}
return target;
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// Collection
/////////////////////////////////////////////////////////////////////
createOperation(false, "toString", Types.COLLECTION_TYPE, Types.STRING_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@SuppressWarnings("unchecked")
@Override
@@ -614,12 +614,12 @@ public final class OCLOperations {
final LazyCollection<Object> coll = (LazyCollection<Object>)frame.getLocal(0, 0);
return coll.asString(frame.getEnv());
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// JavaCollection
/////////////////////////////////////////////////////////////////////
createOperation(false, "resolve", Types.JAVA_COLLECTION_TYPE, Types.SEQUENCE_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@SuppressWarnings("unchecked")
@Override
@@ -627,9 +627,9 @@ public final class OCLOperations {
final Collection<Object> object = (Collection<Object>)frame.getLocal(0, 0);
return new ResolveList(object, frame);
}
- });
+ });
createOperation(false, "resolve", Types.JAVA_COLLECTION_TYPE, Types.SEQUENCE_TYPE,
- new String[][][]{{{"rule"}, Types.STRING_TYPE}},
+ new String[][][]{{{"rule"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@SuppressWarnings("unchecked")
@Override
@@ -638,9 +638,9 @@ public final class OCLOperations {
final String rule = (String)frame.getLocal(0, 1);
return new UniqueResolveList(object, frame, rule);
}
- });
+ });
createOperation(false, "=~", Types.JAVA_COLLECTION_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -652,9 +652,9 @@ public final class OCLOperations {
return o.contains(o2);
}
}
- });
+ });
createOperation(false, "=~|", Types.JAVA_COLLECTION_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -666,12 +666,12 @@ public final class OCLOperations {
return o.contains(o2);
}
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// JavaList
/////////////////////////////////////////////////////////////////////
createOperation(false, "=~|", Types.JAVA_LIST_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
+ new String[][][]{{{"o"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -692,58 +692,58 @@ public final class OCLOperations {
return false;
}
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// Map
/////////////////////////////////////////////////////////////////////
createOperation(false, "including", Types.MAP_TYPE, Types.SET_TYPE,
new String[][][]{{{"key"}, Types.OCL_ANY_TYPE}, {{"value"}, Types.OCL_ANY_TYPE}},
new NativeCodeBlock() {
- @Override
- public Object execute(final StackFrame frame) {
- final Map<Object, Object> o = new HashMap<Object, Object>((Map<?, ?>)frame.getLocal(0, 0));
- final Object key = frame.getLocal(0, 1);
- final Object value = frame.getLocal(0, 2);
- o.put(key, value);
- return o;
- }
- });
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Map<Object, Object> o = new HashMap<Object, Object>((Map<?, ?>)frame.getLocal(0, 0));
+ final Object key = frame.getLocal(0, 1);
+ final Object value = frame.getLocal(0, 2);
+ o.put(key, value);
+ return o;
+ }
+ });
createOperation(false, "getKeys", Types.MAP_TYPE, Types.SET_TYPE,
new String[][][]{},
new NativeCodeBlock() {
- @SuppressWarnings("unchecked")
- @Override
- public Object execute(final StackFrame frame) {
- final Map<?, ?> o = (Map<?, ?>)frame.getLocal(0, 0);
- return new LazySetOnSet<Object>((Set<Object>)o.keySet());
- }
- });
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Map<?, ?> o = (Map<?, ?>)frame.getLocal(0, 0);
+ return new LazySetOnSet<Object>((Set<Object>)o.keySet());
+ }
+ });
createOperation(false, "getValues", Types.MAP_TYPE, Types.SET_TYPE,
new String[][][]{},
new NativeCodeBlock() {
- @SuppressWarnings("unchecked")
- @Override
- public Object execute(final StackFrame frame) {
- final Map<?, ?> o = (Map<?, ?>)frame.getLocal(0, 0);
- return new LazyBagOnCollection<Object>((Collection<Object>)o.values());
- }
- });
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Map<?, ?> o = (Map<?, ?>)frame.getLocal(0, 0);
+ return new LazyBagOnCollection<Object>((Collection<Object>)o.values());
+ }
+ });
createOperation(false, "union", Types.MAP_TYPE, Types.SET_TYPE,
new String[][][]{{{"m"}, Types.MAP_TYPE}},
new NativeCodeBlock() {
- @Override
- public Object execute(final StackFrame frame) {
- final Map<Object, Object> o = new HashMap<Object, Object>((Map<?, ?>)frame.getLocal(0, 0));
- final Map<?, ?> m = (Map<?, ?>)frame.getLocal(0, 1);
- o.putAll(m);
- return o;
- }
- });
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Map<Object, Object> o = new HashMap<Object, Object>((Map<?, ?>)frame.getLocal(0, 0));
+ final Map<?, ?> m = (Map<?, ?>)frame.getLocal(0, 1);
+ o.putAll(m);
+ return o;
+ }
+ });
/////////////////////////////////////////////////////////////////////
// ExecEnv
/////////////////////////////////////////////////////////////////////
createOperation(true, "resolveTemp", Types.EXEC_ENV_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"var"}, Types.OCL_ANY_TYPE}, {{"target_pattern_name"}, Types.STRING_TYPE}},
+ new String[][][]{{{"var"}, Types.OCL_ANY_TYPE}, {{"target_pattern_name"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -768,63 +768,63 @@ public final class OCLOperations {
}
}
throw new VMException(frame, String.format(
- "Cannot resolve default trace target '%s' for %s",
+ "Cannot resolve default trace target '%s' for %s",
name, EMFTVMUtil.toPrettyString(object, frame.getEnv())));
}
- });
+ });
createOperation(true, "resolveTemp", Types.EXEC_ENV_TYPE, Types.OCL_ANY_TYPE,
- new String[][][]{{{"var"}, Types.OCL_ANY_TYPE},
- {{"rule_name"}, Types.STRING_TYPE},
- {{"target_pattern_name"}, Types.STRING_TYPE}},
- new NativeCodeBlock() {
- @Override
- public Object execute(final StackFrame frame) {
- final Object object = frame.getLocal(0, 0);
- final String rule = (String)frame.getLocal(0, 1);
- final String name = (String)frame.getLocal(0, 2);
- if (object instanceof List<?>) {
- final TracedRule tr = frame.getEnv().getTraces().getLinksByRule(rule, false);
- if (tr != null) {
- final SourceElementList sel = tr.getUniqueSourceElements((List<?>)object);
- if (sel != null) {
- assert !sel.getSourceElements().isEmpty();
- final TargetElement te = sel.getSourceElements().get(0).getSourceOf().getTargetElement(name);
- if (te != null) {
- return te.getObject();
- }
+ new String[][][]{{{"var"}, Types.OCL_ANY_TYPE},
+ {{"rule_name"}, Types.STRING_TYPE},
+ {{"target_pattern_name"}, Types.STRING_TYPE}},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Object object = frame.getLocal(0, 0);
+ final String rule = (String)frame.getLocal(0, 1);
+ final String name = (String)frame.getLocal(0, 2);
+ if (object instanceof List<?>) {
+ final TracedRule tr = frame.getEnv().getTraces().getLinksByRule(rule, false);
+ if (tr != null) {
+ final SourceElementList sel = tr.getUniqueSourceElements((List<?>)object);
+ if (sel != null) {
+ assert !sel.getSourceElements().isEmpty();
+ final TargetElement te = sel.getSourceElements().get(0).getSourceOf().getTargetElement(name);
+ if (te != null) {
+ return te.getObject();
}
}
- } else {
- final TracedRule tr = frame.getEnv().getTraces().getLinksByRule(rule, false);
- if (tr != null) {
- final SourceElement se = tr.getUniqueSourceElement(object);
- if (se != null) {
- final TargetElement te = se.getSourceOf().getTargetElement(name);
- if (te != null) {
- return te.getObject();
- }
+ }
+ } else {
+ final TracedRule tr = frame.getEnv().getTraces().getLinksByRule(rule, false);
+ if (tr != null) {
+ final SourceElement se = tr.getUniqueSourceElement(object);
+ if (se != null) {
+ final TargetElement te = se.getSourceOf().getTargetElement(name);
+ if (te != null) {
+ return te.getObject();
}
}
}
- throw new VMException(frame, String.format(
- "Cannot resolve unique trace target '%s::%s' for %s",
- rule, name, EMFTVMUtil.toPrettyString(object, frame.getEnv())));
}
- });
+ throw new VMException(frame, String.format(
+ "Cannot resolve unique trace target '%s::%s' for %s",
+ rule, name, EMFTVMUtil.toPrettyString(object, frame.getEnv())));
+ }
+ });
/////////////////////////////////////////////////////////////////////
// Class
/////////////////////////////////////////////////////////////////////
createOperation(false, "allInstances", Types.CLASS_TYPE, Types.SEQUENCE_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
final EClass c = (EClass)frame.getLocal(0, 0);
return EMFTVMUtil.findAllInstances(c, frame.getEnv());
}
- });
+ });
createOperation(false, "allInstancesFrom", Types.CLASS_TYPE, Types.SEQUENCE_TYPE,
- new String[][][]{{{"metamodel"}, Types.STRING_TYPE}},
+ new String[][][]{{{"metamodel"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -832,9 +832,9 @@ public final class OCLOperations {
final String mm = (String)frame.getLocal(0, 1);
return EMFTVMUtil.findAllInstIn(mm, c, frame.getEnv());
}
- });
+ });
createOperation(false, "conformsTo", Types.CLASS_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -842,9 +842,9 @@ public final class OCLOperations {
final EClass c2 = (EClass)frame.getLocal(0, 1);
return c2.isSuperTypeOf(c);
}
- });
+ });
createOperation(false, "conformsTo", Types.CLASS_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -857,7 +857,7 @@ public final class OCLOperations {
return c2 == Object.class; // everything is an Object
}
}
- });
+ });
createOperation(false, "newInstance", Types.CLASS_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{},
new NativeCodeBlock() {
@@ -866,7 +866,7 @@ public final class OCLOperations {
final EClass type = (EClass)frame.getLocal(0, 0);
return type.getEPackage().getEFactoryInstance().create(type);
}
- });
+ });
createOperation(false, "newInstanceIn", Types.CLASS_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{{{"modelname"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@@ -884,7 +884,7 @@ public final class OCLOperations {
}
return model.newElement(type);
}
- });
+ });
createOperation(false, "getInstanceById", Types.CLASS_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{{{"id"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@@ -896,7 +896,7 @@ public final class OCLOperations {
final List<Model> models = new LazyListOnCollection<Model>(
env.getInputModels().values()).union(new LazyListOnCollection<Model>(
env.getInoutModels().values()));
- for (Model model : models) {
+ for (final Model model : models) {
final EObject instance = model.getResource().getEObject(id);
if (type.isInstance(instance)) {
return instance;
@@ -904,7 +904,7 @@ public final class OCLOperations {
}
return null;
}
- });
+ });
createOperation(false, "getInstanceById", Types.CLASS_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{{{"modelname"}, Types.STRING_TYPE}, {{"id"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@@ -928,12 +928,12 @@ public final class OCLOperations {
return null;
}
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// JavaClass
/////////////////////////////////////////////////////////////////////
createOperation(false, "conformsTo", Types.JAVA_CLASS_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -946,9 +946,9 @@ public final class OCLOperations {
return false;
}
}
- });
+ });
createOperation(false, "conformsTo", Types.JAVA_CLASS_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
+ new String[][][]{{{"type"}, Types.JAVA_CLASS_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -956,16 +956,16 @@ public final class OCLOperations {
final Class<?> c2 = (Class<?>)frame.getLocal(0, 1);
return c2.isAssignableFrom(c);
}
- });
+ });
createOperation(false, "getName", Types.JAVA_CLASS_TYPE, Types.STRING_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
final Class<?> c = (Class<?>)frame.getLocal(0, 0);
return NativeTypes.typeName(c);
}
- });
+ });
createOperation(false, "refInvokeStaticOperation", Types.JAVA_CLASS_TYPE, Types.OCL_ANY_TYPE,
new String[][][]{{{"opname"}, Types.STRING_TYPE}, {{"arguments"}, Types.SEQUENCE_TYPE}},
new NativeCodeBlock() {
@@ -976,460 +976,476 @@ public final class OCLOperations {
final List<?> args = (List<?>)frame.getLocal(0, 2);
return EMFTVMUtil.invokeNativeStatic(frame, c, opname, args.toArray());
}
- });
+ });
createOperation(false, "refNewInstance", Types.JAVA_CLASS_TYPE, Types.OCL_ANY_TYPE, new String[][][] { { { "arguments" },
- Types.SEQUENCE_TYPE } }, new NativeCodeBlock() {
- @Override
- public Object execute(final StackFrame frame) {
- final Class<?> c = (Class<?>) frame.getLocal(0, 0);
- final Object[] args = ((List<?>) frame.getLocal(0, 1)).toArray();
- final Constructor<?> constructor = EMFTVMUtil.findConstructor(c, EMFTVMUtil.getArgumentClasses(args));
- if (constructor != null) {
- try {
- return EMFTVMUtil.emf2vm(frame.getEnv(), null, constructor.newInstance(args));
- } catch (InvocationTargetException e) {
- final Throwable target = e.getTargetException();
- if (target instanceof VMException) {
- throw (VMException) target;
- } else {
- throw new VMException(frame, target);
+ Types.SEQUENCE_TYPE } }, new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Class<?> c = (Class<?>) frame.getLocal(0, 0);
+ final Object[] args = ((List<?>) frame.getLocal(0, 1)).toArray();
+ final Constructor<?> constructor = EMFTVMUtil.findConstructor(c, EMFTVMUtil.getArgumentClasses(args));
+ if (constructor != null) {
+ try {
+ return EMFTVMUtil.emf2vm(frame.getEnv(), null, constructor.newInstance(args));
+ } catch (final InvocationTargetException e) {
+ final Throwable target = e.getTargetException();
+ if (target instanceof VMException) {
+ throw (VMException) target;
+ } else {
+ throw new VMException(frame, target);
+ }
+ } catch (final VMException e) {
+ throw e;
+ } catch (final Exception e) {
+ throw new VMException(frame, e);
}
- } catch (VMException e) {
- throw e;
- } catch (Exception e) {
- throw new VMException(frame, e);
}
+ throw new UnsupportedOperationException(String.format("%s::<init>(%s)", EMFTVMUtil.getTypeName(frame.getEnv(), c),
+ EMFTVMUtil.getTypeNames(frame.getEnv(), EMFTVMUtil.getArgumentTypes(args))));
}
- throw new UnsupportedOperationException(String.format("%s::<init>(%s)", EMFTVMUtil.getTypeName(frame.getEnv(), c),
- EMFTVMUtil.getTypeNames(frame.getEnv(), EMFTVMUtil.getArgumentTypes(args))));
- }
- });
+ });
/////////////////////////////////////////////////////////////////////
// Real
/////////////////////////////////////////////////////////////////////
createOperation(false, "+", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) + (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "+", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) + (Integer)frame.getLocal(0, 1);
}
- });
+ });
+ createOperation(false, "-", Types.REAL_TYPE, Types.REAL_TYPE,
+ new String[][][]{},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ return -(Double)frame.getLocal(0, 0);
+ }
+ });
createOperation(false, "-", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) - (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "-", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) - (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "*", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) * (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "*", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) * (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "neg", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return -(Double)frame.getLocal(0, 0);
}
- });
+ });
createOperation(false, "/", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) / (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "/", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) / (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "abs", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.abs((Double)frame.getLocal(0, 0));
}
- });
+ });
createOperation(false, "floor", Types.REAL_TYPE, Types.INTEGER_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Double.valueOf(Math.floor((Double)frame.getLocal(0, 0))).intValue();
}
- });
+ });
createOperation(false, "round", Types.REAL_TYPE, Types.INTEGER_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Double.valueOf(Math.round((Double)frame.getLocal(0, 0))).intValue();
}
- });
+ });
createOperation(false, "max", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.max((Double)frame.getLocal(0, 0), (Double)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "max", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.max((Double)frame.getLocal(0, 0), (Integer)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "min", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.min((Double)frame.getLocal(0, 0), (Double)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "min", Types.REAL_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.min((Double)frame.getLocal(0, 0), (Integer)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "<", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) < (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "<", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) < (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) > (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) > (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "<=", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) <= (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "<=", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) <= (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">=", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) >= (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">=", Types.REAL_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Double)frame.getLocal(0, 0) >= (Integer)frame.getLocal(0, 1);
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// Integer
/////////////////////////////////////////////////////////////////////
createOperation(false, "neg", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return -(Integer)frame.getLocal(0, 0);
}
- });
+ });
createOperation(false, "+", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) + (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "+", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) + (Integer)frame.getLocal(0, 1);
}
- });
+ });
+ createOperation(false, "-", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
+ new String[][][]{},
+ new NativeCodeBlock() {
+ @Override
+ public Object execute(final StackFrame frame) {
+ return -(Integer)frame.getLocal(0, 0);
+ }
+ });
createOperation(false, "-", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) - (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "-", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) - (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "*", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) * (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "*", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) * (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "/", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) / (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "/", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return ((Integer)frame.getLocal(0, 0)).doubleValue() / (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "abs", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.abs((Integer)frame.getLocal(0, 0));
}
- });
+ });
createOperation(false, "div", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) / (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "mod", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) % (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "max", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.max((Integer)frame.getLocal(0, 0), (Double)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "max", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.max((Integer)frame.getLocal(0, 0), (Integer)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "min", Types.INTEGER_TYPE, Types.REAL_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.min((Integer)frame.getLocal(0, 0), (Double)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "min", Types.INTEGER_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Math.min((Integer)frame.getLocal(0, 0), (Integer)frame.getLocal(0, 1));
}
- });
+ });
createOperation(false, "<", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) < (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "<", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) < (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) > (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) > (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "<=", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) <= (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "<=", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) <= (Integer)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">=", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"r"}, Types.REAL_TYPE}},
+ new String[][][]{{{"r"}, Types.REAL_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) >= (Double)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, ">=", Types.INTEGER_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (Integer)frame.getLocal(0, 0) >= (Integer)frame.getLocal(0, 1);
}
- });
+ });
/////////////////////////////////////////////////////////////////////
// String
/////////////////////////////////////////////////////////////////////
createOperation(false, "+", Types.STRING_TYPE, Types.STRING_TYPE,
- new String[][][]{{{"s"}, Types.STRING_TYPE}},
+ new String[][][]{{{"s"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return (String)frame.getLocal(0, 0) + (String)frame.getLocal(0, 1);
}
- });
+ });
createOperation(false, "size", Types.STRING_TYPE, Types.INTEGER_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return ((String)frame.getLocal(0, 0)).length();
}
- });
+ });
createOperation(false, "substring", Types.STRING_TYPE, Types.STRING_TYPE,
- new String[][][]{{{"lower"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"lower"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return ((String)frame.getLocal(0, 0)).substring(
(Integer)frame.getLocal(0, 1) - 1);
- } catch (IndexOutOfBoundsException e) {
+ } catch (final IndexOutOfBoundsException e) {
throw new VMException(frame, e);
}
}
- });
+ });
createOperation(false, "substring", Types.STRING_TYPE, Types.STRING_TYPE,
- new String[][][]{{{"lower"}, Types.INTEGER_TYPE}, {{"upper"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"lower"}, Types.INTEGER_TYPE}, {{"upper"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
@@ -1437,145 +1453,145 @@ public final class OCLOperations {
return ((String)frame.getLocal(0, 0)).substring(
(Integer)frame.getLocal(0, 1) - 1,
(Integer)frame.getLocal(0, 2));
- } catch (IndexOutOfBoundsException e) {
+ } catch (final IndexOutOfBoundsException e) {
throw new VMException(frame, e);
}
}
- });
+ });
createOperation(false, "toInteger", Types.STRING_TYPE, Types.INTEGER_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return Integer.parseInt((String)frame.getLocal(0, 0));
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
throw new VMException(frame, e);
}
}
- });
+ });
createOperation(false, "toReal", Types.STRING_TYPE, Types.REAL_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return Double.parseDouble((String)frame.getLocal(0, 0));
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
throw new VMException(frame, e);
}
}
- });
+ });
createOperation(false, "indexOf", Types.STRING_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"s"}, Types.STRING_TYPE}},
+ new String[][][]{{{"s"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return ((String)frame.getLocal(0, 0)).indexOf((String)frame.getLocal(0, 1)) + 1;
}
- });
+ });
createOperation(false, "lastIndexOf", Types.STRING_TYPE, Types.INTEGER_TYPE,
- new String[][][]{{{"s"}, Types.STRING_TYPE}},
+ new String[][][]{{{"s"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return ((String)frame.getLocal(0, 0)).lastIndexOf((String)frame.getLocal(0, 1)) + 1;
}
- });
+ });
createOperation(false, "at", Types.STRING_TYPE, Types.STRING_TYPE,
- new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
+ new String[][][]{{{"i"}, Types.INTEGER_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return String.valueOf(((String)frame.getLocal(0, 0))
.charAt((Integer)frame.getLocal(0, 1) - 1));
- } catch (IndexOutOfBoundsException e) {
+ } catch (final IndexOutOfBoundsException e) {
throw new VMException(frame, e);
}
}
- });
+ });
createOperation(false, "characters", Types.STRING_TYPE, Types.SEQUENCE_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
LazyList<String> seq = new LazyList<String>();
- for (char c : ((String)frame.getLocal(0, 0)).toCharArray()) {
+ for (final char c : ((String)frame.getLocal(0, 0)).toCharArray()) {
seq = seq.append(String.valueOf(c));
}
return seq;
}
- });
+ });
createOperation(false, "toBoolean", Types.STRING_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return Boolean.parseBoolean((String)frame.getLocal(0, 0));
}
- });
+ });
createOperation(false, "toUpper", Types.STRING_TYPE, Types.STRING_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return ((String)frame.getLocal(0, 0)).toUpperCase();
}
- });
+ });
createOperation(false, "toLower", Types.STRING_TYPE, Types.STRING_TYPE,
- new String[][][]{},
+ new String[][][]{},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
return ((String)frame.getLocal(0, 0)).toLowerCase();
}
- });
+ });
createOperation(false, "writeTo", Types.STRING_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"path"}, Types.STRING_TYPE}},
+ new String[][][]{{{"path"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return EMFTVMUtil.writeToWithCharset(
- (String)frame.getLocal(0, 0),
+ (String)frame.getLocal(0, 0),
(String)frame.getLocal(0, 1),
null);
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new VMException(frame, e);
}
}
- });
+ });
createOperation(false, "writeToWithCharset", Types.STRING_TYPE, Types.BOOLEAN_TYPE,
- new String[][][]{{{"path"}, Types.STRING_TYPE}, {{"charset"}, Types.STRING_TYPE}},
+ new String[][][]{{{"path"}, Types.STRING_TYPE}, {{"charset"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return EMFTVMUtil.writeToWithCharset(
- (String)frame.getLocal(0, 0),
+ (String)frame.getLocal(0, 0),
(String)frame.getLocal(0, 1),
(String)frame.getLocal(0, 2));
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new VMException(frame, e);
}
}
- });
- createOperation(false, "toDate", Types.STRING_TYPE, Types.JAVA_DATE_TYPE,
+ });
+ createOperation(false, "toDate", Types.STRING_TYPE, Types.JAVA_DATE_TYPE,
new String[][][]{{{"format"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
public Object execute(final StackFrame frame) {
try {
return new SimpleDateFormat((String) frame.getLocal(1)).parse((String) frame.getLocal(0));
- } catch (ParseException e) {
+ } catch (final ParseException e) {
throw new VMException(frame, e);
}
}
});
- createOperation(false, "toDate", Types.STRING_TYPE, Types.JAVA_DATE_TYPE,
+ createOperation(false, "toDate", Types.STRING_TYPE, Types.JAVA_DATE_TYPE,
new String[][][]{{{"format"}, Types.STRING_TYPE}, {{"locale"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
@@ -1583,7 +1599,7 @@ public final class OCLOperations {
try {
return new SimpleDateFormat((String) frame.getLocal(1), EMFTVMUtil.getLocale((String) frame.getLocal(2)))
.parse((String) frame.getLocal(0));
- } catch (ParseException e) {
+ } catch (final ParseException e) {
throw new VMException(frame, e);
}
}
@@ -1591,7 +1607,7 @@ public final class OCLOperations {
/////////////////////////////////////////////////////////////////////
// Date
/////////////////////////////////////////////////////////////////////
- createOperation(false, "toString", Types.JAVA_DATE_TYPE, Types.STRING_TYPE,
+ createOperation(false, "toString", Types.JAVA_DATE_TYPE, Types.STRING_TYPE,
new String[][][]{{{"format"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
@@ -1599,7 +1615,7 @@ public final class OCLOperations {
return new SimpleDateFormat((String) frame.getLocal(1)).format((Date) frame.getLocal(0));
}
});
- createOperation(false, "toString", Types.JAVA_DATE_TYPE, Types.STRING_TYPE,
+ createOperation(false, "toString", Types.JAVA_DATE_TYPE, Types.STRING_TYPE,
new String[][][]{{{"format"}, Types.STRING_TYPE}, {{"locale"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
@@ -1610,14 +1626,14 @@ public final class OCLOperations {
});
createOperation(false, "toTuple", Types.JAVA_DATE_TYPE, Types.TUPLE_TYPE, new String[][][]{},
new NativeCodeBlock() {
- @Override
- public Object execute(final StackFrame frame) {
- final Calendar cal = Calendar.getInstance();
- cal.setTime((Date) frame.getLocal(0));
- return Tuple.fromCalendar(cal);
- }
- });
- createOperation(false, "toTuple", Types.JAVA_DATE_TYPE, Types.TUPLE_TYPE,
+ @Override
+ public Object execute(final StackFrame frame) {
+ final Calendar cal = Calendar.getInstance();
+ cal.setTime((Date) frame.getLocal(0));
+ return Tuple.fromCalendar(cal);
+ }
+ });
+ createOperation(false, "toTuple", Types.JAVA_DATE_TYPE, Types.TUPLE_TYPE,
new String[][][]{{{"timezone"}, Types.STRING_TYPE}},
new NativeCodeBlock() {
@Override
@@ -1640,7 +1656,7 @@ public final class OCLOperations {
* @return a new {@link Operation}.
* @see Types
*/
- private Operation createOperation(final boolean isStatic, final String name, final String[] context,
+ private Operation createOperation(final boolean isStatic, final String name, final String[] context,
final String[] returnType, final String[][][] parameters, final CodeBlock body) {
final Operation op = EMFTVMUtil.createOperation(isStatic, name, context, returnType, parameters, body);
oclModule.getFeatures().add(op);
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/StackFrame.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/StackFrame.java
index 841ed601..867af7cf 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/StackFrame.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/StackFrame.java
@@ -315,14 +315,22 @@ public final class StackFrame {
if (lv.getSlot() == slot && lv.getStartInstructionIndex() <= loc && lv.getEndInstructionIndex() >= loc) {
sb.append(lv.toString());
sb.append(" = ");
- sb.append(EMFTVMUtil.toPrettyString(locals[slot], getEnv()));
+ try {
+ sb.append(EMFTVMUtil.toPrettyString(locals[slot], getEnv()));
+ } catch (VMException e) {
+ sb.append("<VMException>");
+ }
break;
}
}
}
sb.append(']');
} else {
- sb.append(EMFTVMUtil.toPrettyString(locals, getEnv()));
+ try {
+ sb.append(EMFTVMUtil.toPrettyString(locals, getEnv()));
+ } catch (VMException e) {
+ sb.append("<VMException>");
+ }
}
final StackFrame parent = getParent();
if (parent != null) {
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/Tuple.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/Tuple.java
index d22e1fd9..eb4ebaf6 100755
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/Tuple.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/util/Tuple.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Vrije Universiteit Brussel.
+ * Copyright (c) 2011-2017 Dennis Wagelaar, Vrije Universiteit Brussel.
* 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
@@ -21,26 +21,26 @@ import java.util.TimeZone;
/**
* Reflective, immutable implementation of OCL Tuples.
- *
+ *
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
public final class Tuple {
/**
* Creates a new {@link Tuple} from <code>map</code>.
- *
+ *
* @param map
* the {@link Map} with tuple data
* @return a new {@link Tuple} from <code>map</code>
*/
- public static Tuple fromMap(final Map<String, Object> map) {
+ public static Tuple fromMap(final Map<String, ? extends Object> map) {
return new Tuple(map);
}
/**
* Returns a new {@link Tuple} from <code>cal</code>. Supported fields: timezone, year, month, day_of_month, day_of_week, day_of_week_in_month,
* day_of_year, era, hour, hour_of_day, minute, second, millisecond, am_pm, week_of_month, week_of_year.
- *
+ *
* @param cal
* the input {@link Calendar}
* @return a new {@link Tuple} from <code>cal</code>
@@ -66,7 +66,7 @@ public final class Tuple {
return new Tuple(values);
}
- private final Map<String, Object> values;
+ private final Map<String, ? extends Object> values;
/**
* Creates a new empty {@link Tuple}.
@@ -77,17 +77,17 @@ public final class Tuple {
/**
* Creates a new {@link Tuple} initialized with the given <code>map</code>.
- *
+ *
* @param map
* the map with tuple key-value pairs
*/
- public Tuple(Map<String, Object> map) {
- values = Collections.unmodifiableMap(map);
+ public Tuple(Map<String, ? extends Object> map) {
+ values = map;
}
/**
* Returns the value for <code>name</code>.
- *
+ *
* @param name
* the element name
* @return the value for <code>name</code>
@@ -100,14 +100,6 @@ public final class Tuple {
* {@inheritDoc}
*/
@Override
- public String toString() {
- return "Tuple " + values.toString(); //$NON-NLS-1$
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public boolean equals(Object o) {
return (o instanceof Tuple) ? values.equals(((Tuple) o).values) : false;
}
@@ -122,10 +114,10 @@ public final class Tuple {
/**
* Returns this {@link Tuple}'s value map.
- *
+ *
* @return this {@link Tuple}'s value map
*/
- public Map<String, Object> asMap() {
+ public Map<String, ? extends Object> asMap() {
return values;
}
@@ -133,7 +125,7 @@ public final class Tuple {
* Returns a {@link Date} instance using the fields of this tuple. Supported fields: timezone, locale, year, month,
* day_of_month, day_of_week, day_of_week_in_month, day_of_year, era, hour, hour_of_day, minute, second, millisecond, am_pm,
* week_of_month, week_of_year.
- *
+ *
* @return a {@link Date} instance using the fields of this tuple
* @see Calendar
*/

Back to the top