summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahaase2008-01-28 10:27:01 (EST)
committer ahaase2008-01-28 10:27:01 (EST)
commit3ec540ff60d95bb981a2d5cecd44869aa7be2477 (patch)
treeaeb4802ba69aae1f6d8e1a38ecd12f6150831d7c
parentab36f6fbf15428d6282007038d165343762a4792 (diff)
downloadorg.eclipse.xpand-3ec540ff60d95bb981a2d5cecd44869aa7be2477.zip
org.eclipse.xpand-3ec540ff60d95bb981a2d5cecd44869aa7be2477.tar.gz
org.eclipse.xpand-3ec540ff60d95bb981a2d5cecd44869aa7be2477.tar.bz2
added XpandWorkflowComponent and completed support for FILE statements
-rw-r--r--plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Helpers.java4
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/CompositeTypesystem.java27
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/StringType.java7
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/AbstractJavaBeansTypesystem.java78
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/GlobalJavaBeansTypesystem.java24
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansProperty.java72
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansStaticProperty.java58
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansType.java160
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaOperation.java94
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java9
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java13
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendRegistry.java6
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/TypeToBackendType.java6
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendContributor.java75
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java190
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java2
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java215
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java1
-rw-r--r--plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java1
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/.cvsignore1
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/META-INF/MANIFEST.MF3
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java18
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/WithFileOutput.xpt6
25 files changed, 969 insertions, 105 deletions
diff --git a/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF
index 7b87b10..e4ce600 100644
--- a/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF
@@ -11,5 +11,6 @@ Export-Package: org.eclipse.xtend.backend,
org.eclipse.xtend.backend.iface,
org.eclipse.xtend.backend.types,
org.eclipse.xtend.backend.types.builtin,
+ org.eclipse.xtend.backend.types.java,
org.eclipse.xtend.backend.util
Require-Bundle: org.apache.commons.logging
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Helpers.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Helpers.java
index 50b92a8..9670593 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Helpers.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Helpers.java
@@ -18,6 +18,8 @@ import java.util.Collections;
* @author Arno Haase (http://www.haase-consulting.com)
*/
public class Helpers {
+ public static String TO_STRING_METHOD_NAME = "toString";
+
/**
* This method is public static so as to be available as a helper method for all code that needs to call "toString".
* It calls "toString" on an object, taking into account all potential overriding extensions.<br>
@@ -29,7 +31,7 @@ public class Helpers {
if (o instanceof EfficientLazyString)
return (CharSequence) o;
- final Object resultRaw = ctx.getFunctionDefContext().invoke (ctx, "toString", Collections.singletonList (o));
+ final Object resultRaw = ctx.getFunctionDefContext().invoke (ctx, TO_STRING_METHOD_NAME, Collections.singletonList (o));
if (resultRaw instanceof CharSequence)
return (CharSequence) resultRaw;
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/CompositeTypesystem.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/CompositeTypesystem.java
index 4686a35..37db3ff 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/CompositeTypesystem.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/CompositeTypesystem.java
@@ -35,6 +35,7 @@ import org.eclipse.xtend.backend.types.builtin.StaticPropertyType;
import org.eclipse.xtend.backend.types.builtin.StringType;
import org.eclipse.xtend.backend.types.builtin.TypeType;
import org.eclipse.xtend.backend.types.builtin.VoidType;
+import org.eclipse.xtend.backend.types.java.GlobalJavaBeansTypesystem;
import org.eclipse.xtend.backend.util.Cache;
@@ -48,6 +49,12 @@ public final class CompositeTypesystem implements BackendTypesystem {
private BackendTypesystem _rootTypesystem = this;
private final List<BackendTypesystem> _inner = new ArrayList<BackendTypesystem>();
+ private final BackendTypesystem _javaBeansTypesystem = new GlobalJavaBeansTypesystem ();
+ {
+ _javaBeansTypesystem.setRootTypesystem (_rootTypesystem);
+ }
+
+
private final Cache<Class<?>, BackendType> _cache = new Cache<Class<?>, BackendType>() {
@Override
protected BackendType create (Class<?> key) {
@@ -61,19 +68,26 @@ public final class CompositeTypesystem implements BackendTypesystem {
return result;
}
+ final BackendType jbResult = _javaBeansTypesystem.findType(key);
+ if (jbResult != null)
+ return jbResult;
+
return ObjectType.INSTANCE;
}
};
+ //TODO remove this - add "asBackendType" to frontend type instead
+ public Collection<BackendTypesystem> getInner () {
+ final Collection<BackendTypesystem> result = new ArrayList<BackendTypesystem> (_inner);
+ result.add (_javaBeansTypesystem);
+ return result;
+ }
+
public void register (BackendTypesystem ts) {
_inner.add(ts);
ts.setRootTypesystem (getRootTypesystem());
}
- public List<BackendTypesystem> getInner () {
- return _inner;
- }
-
public BackendType findType (Object o) {
if (o == null)
return VoidType.INSTANCE;
@@ -93,6 +107,8 @@ public final class CompositeTypesystem implements BackendTypesystem {
_rootTypesystem = ts;
for (BackendTypesystem child : _inner)
child.setRootTypesystem(ts);
+
+ _javaBeansTypesystem.setRootTypesystem (ts);
}
private BackendType findSimpleBuiltinType (Class<?> cls) {
@@ -135,5 +151,6 @@ public final class CompositeTypesystem implements BackendTypesystem {
return null;
}
-
}
+
+
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/StringType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/StringType.java
index 82fc063..9c9a2ed 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/StringType.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/StringType.java
@@ -12,6 +12,7 @@ package org.eclipse.xtend.backend.types.builtin;
import org.eclipse.xtend.backend.common.BackendType;
import org.eclipse.xtend.backend.types.AbstractType;
+import org.eclipse.xtend.backend.util.ReflectionHelper;
/**
@@ -27,7 +28,11 @@ import org.eclipse.xtend.backend.types.AbstractType;
public final class StringType extends AbstractType {
public static final StringType INSTANCE = new StringType();
- private StringType () {super ("String"); }
+ private StringType () {
+ super ("String");
+
+ register (new BuiltinProperty (this, StringType.INSTANCE, "length", ReflectionHelper.getKnownMethod(CharSequence.class, "length"), null));
+ }
public boolean isAssignableFrom (BackendType other) {
return other == this || other == VoidType.INSTANCE;
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/AbstractJavaBeansTypesystem.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/AbstractJavaBeansTypesystem.java
new file mode 100644
index 0000000..0cc720d
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/AbstractJavaBeansTypesystem.java
@@ -0,0 +1,78 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.backend.types.java;
+
+import java.beans.IntrospectionException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
+import org.eclipse.xtend.backend.functions.java.JavaBuiltinConverterFactory;
+import org.eclipse.xtend.backend.util.ErrorHandler;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public abstract class AbstractJavaBeansTypesystem implements BackendTypesystem {
+ private BackendTypesystem _rootTypesystem = null;
+ private Map<Class<?>, JavaBeansType> _cache = new HashMap<Class<?>, JavaBeansType>(); // this is necessary to avoid endless recursion!
+
+ public BackendType findType (Class<?> cls) {
+ if (cls == Object.class)
+ return null;
+
+ final BackendType nonstandardBuiltin = JavaBuiltinConverterFactory.getTypeForAdditionalBuiltin (cls);
+ if (nonstandardBuiltin != null)
+ return nonstandardBuiltin;
+
+ if (! matchesScope (cls))
+ return null;
+
+ JavaBeansType result = _cache.get (cls);
+ if (result != null)
+ return result;
+
+ result = new JavaBeansType (cls);
+ _cache.put (cls, result);
+
+ try {
+ result.init (this);
+ } catch (IntrospectionException e) {
+ ErrorHandler.handle(e);
+ }
+ return result;
+ }
+
+ public BackendType findType (Object o) {
+ if (o == null)
+ return null;
+
+ return findType (o.getClass());
+ }
+
+ /**
+ * This operation allows support for type system instances that are selective, e.g. by package, as
+ * to which classes they feel responsible for.
+ */
+ public abstract boolean matchesScope (Class<?> cls);
+
+
+ public BackendTypesystem getRootTypesystem () {
+ return _rootTypesystem;
+ }
+
+ public void setRootTypesystem (BackendTypesystem ts) {
+ _rootTypesystem = ts;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/GlobalJavaBeansTypesystem.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/GlobalJavaBeansTypesystem.java
new file mode 100644
index 0000000..89e6751
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/GlobalJavaBeansTypesystem.java
@@ -0,0 +1,24 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.backend.types.java;
+
+
+/**
+ * This type system feels responsible for any Java class and treats it as a Java bean.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class GlobalJavaBeansTypesystem extends AbstractJavaBeansTypesystem {
+ @Override
+ public boolean matchesScope (Class<?> cls) {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansProperty.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansProperty.java
new file mode 100644
index 0000000..275d165
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansProperty.java
@@ -0,0 +1,72 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.backend.types.java;
+
+import java.beans.PropertyDescriptor;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.Property;
+import org.eclipse.xtend.backend.functions.java.JavaBuiltinConverter;
+import org.eclipse.xtend.backend.util.ErrorHandler;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+final class JavaBeansProperty implements Property {
+ private final PropertyDescriptor _pd;
+ private final BackendType _owner;
+ private final BackendType _type;
+ private final JavaBuiltinConverter _converter;
+
+
+ public JavaBeansProperty (PropertyDescriptor pd, BackendType owner, BackendType type, JavaBuiltinConverter converter) {
+ _pd = pd;
+ _owner = owner;
+ _type = type;
+ _converter = converter;
+ }
+
+ public String getName () {
+ return _pd.getName();
+ }
+
+ public BackendType getOwner () {
+ return _owner;
+ }
+
+ public BackendType getType () {
+ return _type;
+ }
+
+ public Object get (ExecutionContext ctx, Object o) {
+ try {
+ if (_pd.getReadMethod() == null)
+ throw new IllegalArgumentException ("no readable property " + _pd.getName() + " for type " + _owner.getName());
+ return _converter.javaToBackend (_pd.getReadMethod().invoke (o));
+ } catch (Exception e) {
+ ErrorHandler.handle(e);
+ return null; // to make the compiler happy - this is never executed
+ }
+ }
+
+ public void set (ExecutionContext ctx, Object o, Object newValue) {
+ try {
+ if (_pd.getWriteMethod() == null)
+ throw new IllegalArgumentException ("no writeable property " + _pd.getName() + " for type " + _owner.getName());
+ _pd.getWriteMethod().invoke (o, _converter.backendToJava (newValue));
+ } catch (Exception e) {
+ ErrorHandler.handle (e);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansStaticProperty.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansStaticProperty.java
new file mode 100644
index 0000000..03280e8
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansStaticProperty.java
@@ -0,0 +1,58 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.backend.types.java;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.StaticProperty;
+import org.eclipse.xtend.backend.functions.java.JavaBuiltinConverter;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+final class JavaBeansStaticProperty implements StaticProperty {
+ private final String _name;
+ private final Object _value;
+ private final BackendType _owner;
+ private final BackendType _type;
+
+
+ public JavaBeansStaticProperty (Field field, BackendType owner, BackendType type, JavaBuiltinConverter converter) throws IllegalArgumentException, IllegalAccessException {
+ this (owner, type, field.getName(), converter.javaToBackend (field.get (null)));
+ }
+
+ public JavaBeansStaticProperty (BackendType owner, BackendType type, String name, Object value) {
+ _name = name;
+ _owner = owner;
+ _type = type;
+ _value = value;
+ }
+
+
+ public String getName () {
+ return _name;
+ }
+
+ public BackendType getOwner () {
+ return _owner;
+ }
+
+ public BackendType getType () {
+ return _type;
+ }
+
+ public Object get () {
+ return _value;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansType.java
new file mode 100644
index 0000000..72bda90
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansType.java
@@ -0,0 +1,160 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.backend.types.java;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.NamedFunction;
+import org.eclipse.xtend.backend.common.Property;
+import org.eclipse.xtend.backend.common.StaticProperty;
+import org.eclipse.xtend.backend.functions.java.JavaBuiltinConverterFactory;
+import org.eclipse.xtend.backend.types.builtin.VoidType;
+import org.eclipse.xtend.backend.util.ErrorHandler;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+final class JavaBeansType implements BackendType {
+ private final Class<?> _javaClass;
+ private final List<NamedFunction> _operations = new ArrayList<NamedFunction>();
+ private final Map<String, JavaBeansProperty> _properties = new HashMap<String, JavaBeansProperty> ();
+ private final Map<String, StaticProperty> _staticProperties = new HashMap<String, StaticProperty> ();
+
+ private Collection<BackendType> _superTypes;
+
+ public JavaBeansType (Class<?> cls) {
+ _javaClass = cls;
+ }
+
+ /**
+ * the actual initialization is separated to deal with circular dependencies of operations and/or
+ * properties referring to this very same type.
+ */
+ void init (BackendTypesystem ts) throws IntrospectionException {
+ _superTypes = Collections.singleton (ts.getRootTypesystem().findType (_javaClass.getSuperclass()));
+
+ for (Method mtd: _javaClass.getMethods()) {
+ if (mtd.getDeclaringClass() == Object.class) // toString is added as a syslib function
+ continue;
+
+ final List<BackendType> paramTypes = new ArrayList<BackendType> ();
+
+ paramTypes.add (this); // first parameter is the object on which the method is called
+ for (Class<?> cls: mtd.getParameterTypes()) {
+ paramTypes.add (ts.getRootTypesystem().findType(cls));
+ }
+
+ _operations.add (new NamedFunction (mtd.getName(), new JavaOperation (mtd, paramTypes, null)));
+ }
+
+ for (PropertyDescriptor pd: Introspector.getBeanInfo(_javaClass).getPropertyDescriptors()) {
+ if (pd.getReadMethod().getDeclaringClass() == Object.class)
+ continue;
+
+ _properties.put (pd.getName(), new JavaBeansProperty (pd, this, ts.getRootTypesystem().findType (pd.getPropertyType()), JavaBuiltinConverterFactory.getConverter (pd.getPropertyType ())));
+ }
+
+ // static properties
+ for (Field field: _javaClass.getFields()) {
+ final int mod = field.getModifiers();
+ if (Modifier.isPublic(mod) && Modifier.isStatic(mod) && Modifier.isFinal(mod)) {
+ try {
+ _staticProperties.put (field.getName(), new JavaBeansStaticProperty (field, this, ts.getRootTypesystem().findType (field.getType()), JavaBuiltinConverterFactory.getConverter (field.getType())));
+ } catch (Exception e) {
+ ErrorHandler.handle (e);
+ }
+ }
+ }
+
+ // Java 5 enums
+ final Object[] enumValues = _javaClass.getEnumConstants();
+ if (enumValues != null) {
+ for (Object o : enumValues) {
+ final Enum<?> curEnum = (Enum<?>) o;
+ _staticProperties.put (curEnum.name(), new JavaBeansStaticProperty (this, ts.getRootTypesystem().findType(curEnum), curEnum.name(), curEnum));
+ }
+ }
+ }
+
+ public Object create () {
+ try {
+ return _javaClass.newInstance();
+ } catch (Exception e) {
+ ErrorHandler.handle (e);
+ return null; // to make the compiler happy - this is never executed
+ }
+ }
+
+ public List<NamedFunction> getBuiltinOperations () {
+ return _operations;
+ }
+
+ public Object getProperty (ExecutionContext ctx, Object o, String name) {
+ return findProperty(name).get (ctx, o);
+ }
+
+ private Property findProperty (String name) {
+ final Property result = _properties.get (name);
+ if (result == null)
+ throw new IllegalArgumentException (" no property " + name + " for type " + getName());
+
+ return result;
+ }
+
+ public void setProperty (ExecutionContext ctx, Object o, String name, Object value) {
+ findProperty(name).set (ctx, o, value);
+ }
+
+ public boolean isAssignableFrom (BackendType other) {
+ if (other == VoidType.INSTANCE)
+ return true;
+
+ if (! (other instanceof JavaBeansType))
+ return false;
+
+ final JavaBeansType jbt = (JavaBeansType) other;
+ return _javaClass.isAssignableFrom(jbt._javaClass);
+ }
+
+ public String getName () {
+ return _javaClass.getCanonicalName().replace(".", "::");
+ }
+
+ public Map<String, ? extends Property> getProperties () {
+ return _properties;
+ }
+
+ public Map<String, ? extends StaticProperty> getStaticProperties () {
+ return _staticProperties;
+ }
+
+ public Collection<BackendType> getSuperTypes () {
+ return _superTypes;
+ }
+}
+
+
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaOperation.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaOperation.java
new file mode 100644
index 0000000..c71fd86
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaOperation.java
@@ -0,0 +1,94 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.backend.types.java;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.functions.java.JavaBuiltinConverter;
+import org.eclipse.xtend.backend.functions.java.JavaBuiltinConverterFactory;
+import org.eclipse.xtend.backend.functions.java.ParameterConverter;
+import org.eclipse.xtend.backend.util.CollectionHelper;
+import org.eclipse.xtend.backend.util.ErrorHandler;
+
+
+
+/**
+ * This class defines an operation defined as a method of a Java class, Java Beans style. The
+ * object on which the method is called is passed in as the first parameter of the function.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class JavaOperation implements Function {
+ private final Method _mtd;
+ private final List<BackendType> _parameterTypes;
+ private final ExpressionBase _guard;
+
+ private final List<ParameterConverter> _parameterConverters = new ArrayList<ParameterConverter>();
+ private final JavaBuiltinConverter _returnValueConverter;
+
+ public JavaOperation (Method mtd, List<BackendType> parameterTypes, ExpressionBase guard) {
+ _mtd = mtd;
+ _parameterTypes = parameterTypes;
+ _guard = guard;
+
+ for (int i=0; i<mtd.getParameterTypes().length; i++) {
+ final ParameterConverter pc = JavaBuiltinConverterFactory.getParameterConverter (mtd.getParameterTypes()[i], i);
+ if (pc != null)
+ _parameterConverters.add(pc);
+ }
+
+ _returnValueConverter = JavaBuiltinConverterFactory.getConverter (mtd.getReturnType());
+ }
+
+ public boolean isCached () {
+ return false;
+ }
+
+ public List<BackendType> getParameterTypes() {
+ return _parameterTypes;
+ }
+
+ public Object invoke (ExecutionContext ctx, Object[] params) {
+ for (ParameterConverter pc: _parameterConverters)
+ pc.convert(params);
+
+ try {
+ final Object resultRaw = _mtd.invoke (params[0], CollectionHelper.withoutFirst (params));
+ return _returnValueConverter.javaToBackend (resultRaw);
+ } catch (Exception e) {
+ ErrorHandler.handle (e);
+ return null; // just for the compiler - this is never executed
+ }
+ }
+
+ public ExpressionBase getGuard () {
+ return _guard;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF
index 19ccfaa..e18fe25 100644
--- a/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF
@@ -12,5 +12,6 @@ Require-Bundle: org.eclipse.xtend.backend,
org.eclipse.xpand,
org.eclipse.xtend.typesystem.emf,
org.eclipse.emf.mwe.core,
- org.eclipse.xtend.backend.xtendlib
+ org.eclipse.xtend.backend.xtendlib,
+ org.apache.commons.logging
Export-Package: org.eclipse.xtend.middleend.old
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java
index dd06ecc..937cccf 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java
@@ -132,17 +132,20 @@ final class OldDefinitionConverter {
}
}
- private ExpressionBase convertStatementSequence (Statement[] statements, SyntaxElement oldPos, Set<XpandDefinitionName> referencedDefinitions) {
+ public ExpressionBase convertStatementSequence (Statement[] statements, SyntaxElement oldPos, Set<XpandDefinitionName> referencedDefinitions) {
final List<ExpressionBase> parts = new ArrayList<ExpressionBase> ();
for (Statement stmt: statements)
parts.add (convertStatement (stmt, referencedDefinitions));
- return new ConcatExpression (parts, getSourcePos(oldPos));
+ if (parts.size() == 1)
+ return parts.get (0);
+ else
+ return new ConcatExpression (parts, getSourcePos(oldPos));
}
- private ExpressionBase convertStatement (Statement stmt, Set<XpandDefinitionName> referencedDefinitions) {
+ public ExpressionBase convertStatement (Statement stmt, Set<XpandDefinitionName> referencedDefinitions) {
if (stmt instanceof ErrorStatement)
return convertErrorStatement((ErrorStatement) stmt);
if (stmt instanceof ExpandStatement)
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java
index b42623f..319930b 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java
@@ -23,9 +23,9 @@ import org.eclipse.internal.xpand2.ast.Template;
import org.eclipse.internal.xpand2.model.XpandDefinition;
import org.eclipse.xpand2.XpandExecutionContext;
import org.eclipse.xpand2.XpandUtil;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
import org.eclipse.xtend.backend.common.NamedFunction;
import org.eclipse.xtend.backend.functions.FunctionDefContextImpl;
-import org.eclipse.xtend.backend.types.CompositeTypesystem;
import org.eclipse.xtend.backend.util.Cache;
import org.eclipse.xtend.backend.xtendlib.XtendLibContributor;
@@ -37,7 +37,7 @@ import org.eclipse.xtend.backend.xtendlib.XtendLibContributor;
*/
final class OldXpandRegistry {
private final XpandExecutionContext _ctx;
- private final CompositeTypesystem _ts;
+ private final BackendTypesystem _ts;
private final OldXtendRegistry _extensions;
private final Cache<String, FunctionDefContextImpl> _functionDefContexts = new Cache<String, FunctionDefContextImpl> () {
@@ -53,7 +53,7 @@ final class OldXpandRegistry {
private final Map<String, List<NamedFunction>> _functionsByResource = new HashMap <String, List<NamedFunction>>();
- public OldXpandRegistry (XpandExecutionContext ctx, CompositeTypesystem ts, OldXtendRegistry extensions) {
+ public OldXpandRegistry (XpandExecutionContext ctx, BackendTypesystem ts, OldXtendRegistry extensions) {
_ctx = ctx;
_ts = ts;
_extensions = extensions;
@@ -101,15 +101,12 @@ final class OldXpandRegistry {
_functionsByResource.put (xpandFile, defined);
// make sure all imported resources are registered as well
- for (String imported: file.getImportedExtensions())
- _extensions.registerExtension (imported);
-
- // make all imported extensions visible for the scope of this compilation unit
for (String imported: file.getImportedExtensions()) {
+ _extensions.registerExtension (imported);
for (NamedFunction f: _extensions.getContributedFunctions(imported))
fdc.register (f);
}
-
+
// read all referenced template files...
final Set<String> xpandFileNames = new HashSet<String> ();
for (XpandDefinitionName n: referenced)
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendRegistry.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendRegistry.java
index fee268a..7bc3112 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendRegistry.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendRegistry.java
@@ -23,9 +23,9 @@ import org.eclipse.internal.xtend.xtend.XtendFile;
import org.eclipse.internal.xtend.xtend.ast.Extension;
import org.eclipse.internal.xtend.xtend.ast.ExtensionFile;
import org.eclipse.internal.xtend.xtend.ast.ImportStatement;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
import org.eclipse.xtend.backend.common.NamedFunction;
import org.eclipse.xtend.backend.functions.FunctionDefContextImpl;
-import org.eclipse.xtend.backend.types.CompositeTypesystem;
import org.eclipse.xtend.backend.util.Cache;
import org.eclipse.xtend.backend.xtendlib.XtendLibContributor;
import org.eclipse.xtend.expression.ExecutionContext;
@@ -38,7 +38,7 @@ import org.eclipse.xtend.expression.ExecutionContext;
*/
final class OldXtendRegistry {
private final ExecutionContext _ctx;
- private final CompositeTypesystem _ts;
+ private final BackendTypesystem _ts;
private final Cache<String, FunctionDefContextImpl> _functionDefContexts = new Cache<String, FunctionDefContextImpl> () {
@Override
@@ -65,7 +65,7 @@ final class OldXtendRegistry {
private final Map<String, List<NamedFunction>> _locallyExportedFunctionsByResource = new HashMap <String, List<NamedFunction>>();
- public OldXtendRegistry (ExecutionContext ctx, CompositeTypesystem ts) {
+ public OldXtendRegistry (ExecutionContext ctx, BackendTypesystem ts) {
_ctx = ctx;
_ts = ts;
}
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/TypeToBackendType.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/TypeToBackendType.java
index ed37d3f..3c172b1 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/TypeToBackendType.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/TypeToBackendType.java
@@ -60,16 +60,16 @@ import org.eclipse.xtend.typesystem.emf.EObjectType;
* @author Arno Haase (http://www.haase-consulting.com)
*/
final class TypeToBackendType {
- private final CompositeTypesystem _backendTypes;
+ private final BackendTypesystem _backendTypes;
private final EmfTypesystem _emfTypes;
private final ExecutionContext _ctx;
- public TypeToBackendType (CompositeTypesystem backendTypes, ExecutionContext ctx) {
+ public TypeToBackendType (BackendTypesystem backendTypes, ExecutionContext ctx) {
_backendTypes = backendTypes;
_ctx = ctx;
EmfTypesystem ets = null;
- for (BackendTypesystem bts: _backendTypes.getInner()) {
+ for (BackendTypesystem bts: ((CompositeTypesystem) _backendTypes).getInner()) {
if (bts instanceof EmfTypesystem)
ets = (EmfTypesystem) bts;
}
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendContributor.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendContributor.java
deleted file mode 100644
index c4bd41f..0000000
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendContributor.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-Copyright (c) 2008 Arno Haase.
-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:
- Arno Haase - initial API and implementation
- */
-package org.eclipse.xtend.middleend.old;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipose.xtend.middleend.FunctionDefContextFactory;
-import org.eclipse.xpand2.XpandExecutionContextImpl;
-import org.eclipse.xpand2.output.Outlet;
-import org.eclipse.xpand2.output.Output;
-import org.eclipse.xpand2.output.OutputImpl;
-import org.eclipse.xtend.backend.common.BackendType;
-import org.eclipse.xtend.backend.common.BackendTypesystem;
-import org.eclipse.xtend.backend.common.FunctionDefContext;
-import org.eclipse.xtend.backend.common.NamedFunction;
-import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
-import org.eclipse.xtend.backend.iface.BackendContributor;
-import org.eclipse.xtend.backend.types.CompositeTypesystem;
-import org.eclipse.xtend.typesystem.MetaModel;
-
-
-/**
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public final class XpandBackendContributor implements BackendContributor {
- private final OldXtendRegistry _extensions;
- private final OldXpandRegistry _registry;
- private final String _xpandFile;
- private final BackendTypesystem _ts;
-
- public XpandBackendContributor (String xpandFile, Collection<MetaModel> mms, CompositeTypesystem ts, Collection <Outlet> outlets) {
- _xpandFile = OldXtendHelper.normalizeXpandResourceName (xpandFile);
- _ts = ts;
-
- final Output output = new OutputImpl ();
- for (Outlet outlet: outlets)
- output.addOutlet (outlet);
- //TODO ProtectedRegionResolver
- final XpandExecutionContextImpl ctx = new XpandExecutionContextImpl (output, null);
- for (MetaModel mm: mms)
- ctx.registerMetaModel (mm);
- ctx.setFileEncoding("iso-8859-1"); //TODO really set the encoding
-
- _extensions = new OldXtendRegistry (ctx, ts);
- _registry = new OldXpandRegistry (ctx, ts, _extensions);
- _registry.registerXpandFile (xpandFile);
- }
-
- public BackendType convertToType (List<String> segments) {
- return null;
- }
-
- public Collection<NamedFunction> getContributedFunctions () {
- return _registry.getContributedFunctions (_xpandFile);
- }
-
- public FunctionDefContext getFunctionDefContext () {
- if (getContributedFunctions().isEmpty())
- return new FunctionDefContextFactory(_ts).create();
-
- return ((SourceDefinedFunction) getContributedFunctions().iterator().next().getFunction()).getFunctionDefContext();
- }
-}
-
-
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java
new file mode 100644
index 0000000..d9f66fa
--- /dev/null
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandBackendFacade.java
@@ -0,0 +1,190 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.middleend.old;
+
+import java.io.File;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipose.xtend.middleend.FunctionDefContextFactory;
+import org.eclipse.internal.xpand2.ast.Definition;
+import org.eclipse.internal.xpand2.ast.Statement;
+import org.eclipse.internal.xpand2.ast.Template;
+import org.eclipse.internal.xpand2.codeassist.XpandTokens;
+import org.eclipse.internal.xpand2.parser.XpandParseFacade;
+import org.eclipse.xpand2.XpandExecutionContext;
+import org.eclipse.xpand2.XpandExecutionContextImpl;
+import org.eclipse.xpand2.output.Outlet;
+import org.eclipse.xpand2.output.Output;
+import org.eclipse.xpand2.output.OutputImpl;
+import org.eclipse.xtend.backend.BackendFacade;
+import org.eclipse.xtend.backend.common.BackendTypesystem;
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.common.FunctionDefContext;
+import org.eclipse.xtend.backend.common.NamedFunction;
+import org.eclipse.xtend.backend.functions.FunctionDefContextImpl;
+import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
+import org.eclipse.xtend.backend.syslib.FileIoOperations;
+import org.eclipse.xtend.backend.syslib.FileOutlet;
+import org.eclipse.xtend.backend.syslib.SysLibNames;
+import org.eclipse.xtend.backend.types.CompositeTypesystem;
+import org.eclipse.xtend.backend.types.emf.EmfTypesystem;
+import org.eclipse.xtend.expression.Variable;
+import org.eclipse.xtend.typesystem.MetaModel;
+import org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class XpandBackendFacade {
+ private final OldXtendRegistry _extensions;
+ private final OldXpandRegistry _registry;
+ private final String _xpandFile;
+ private final BackendTypesystem _ts;
+
+
+ /**
+ * This method executes Xpand code that is passed in as a string, script language style.<br>
+ *
+ * There are two restrictions. Firstly, no DEFINEs are allowed - the string that is passed in must be a valid body for a DEFINE. Never
+ * mind the "parameters" - the "variables" parameter defines all variables that will be defined during execution. Use "this" as a
+ * variable name to specify the variable that is implicitly bound as the "special" parameter passed to a definition.<br>
+ *
+ * Secondly, no IMPORT or EXTENSION statements are possible. So types must be referenced by their fully qualified names, and no calls
+ * to extensions are possible. Calls to other templates that are available as files are possible, just as you would expect.<br>
+ *
+ * Both the "variables" and "outlets" parameter may be null.
+ */
+ public static Object executeStatement (String code, Collection<MetaModel> mms, Map<String, Object> variables, Collection <Outlet> outlets) {
+ final BackendTypesystem ts = guessTypesystem(mms);
+
+ if (variables == null)
+ variables = new HashMap<String, Object> ();
+ if (outlets == null)
+ outlets = new ArrayList<Outlet> ();
+
+ final Template tpl = XpandParseFacade.file (new StringReader (XpandTokens.LT + "DEFINE dUmMy FOR dUmMy" + XpandTokens.RT + code + XpandTokens.RT + XpandTokens.LT + "ENDDEFINE" + XpandTokens.RT), null);
+ final Statement[] statements = ((Definition) tpl.getDefinitions()[0]).getBody();
+
+
+ XpandExecutionContext ctx = createOldExecutionContext (null, mms, outlets); // TODO fileEncoding
+ for (String varName: variables.keySet())
+ ctx = (XpandExecutionContext) ctx.cloneWithVariable (new Variable (varName, ctx.getType (variables.get (varName))));
+
+ final Set<XpandDefinitionName> referenced = new HashSet<XpandDefinitionName>();
+ final OldDefinitionConverter defConverter = new OldDefinitionConverter (ctx, new TypeToBackendType (ts, ctx));
+ final ExpressionBase converted = defConverter.convertStatementSequence (statements, tpl, referenced);
+
+
+ final FunctionDefContextImpl fdc = new FunctionDefContextFactory (ts).create();
+
+ //TODO refactor this to extract common code - both from here and from OldXpandRegistry
+ final OldXpandRegistry oxr = new OldXpandRegistry (ctx, ts, new OldXtendRegistry (ctx, ts));
+ for (XpandDefinitionName xdn: referenced) {
+ oxr.registerXpandFile (xdn.getCanonicalTemplateFileName());
+
+ for (NamedFunction f: oxr.getContributedFunctions (xdn.getCanonicalTemplateFileName()))
+ fdc.register (f);
+ }
+
+ final ExecutionContext backendCtx = BackendFacade.createExecutionContext (fdc, ts);
+ backendCtx.getLocalVarContext().getLocalVars().putAll (variables);
+ registerOutlets (backendCtx, outlets);
+
+ return converted.evaluate (backendCtx);
+ }
+
+ public static BackendTypesystem guessTypesystem (Collection<MetaModel> mms) {
+ boolean hasEmf = false;
+
+ for (MetaModel mm: mms) {
+ if (mm instanceof EmfRegistryMetaModel)
+ hasEmf = true;
+ }
+
+ final CompositeTypesystem result = new CompositeTypesystem ();
+ if (hasEmf)
+ result.register (new EmfTypesystem ());
+ //TODO register uml mm
+ //TODO replace this by adding "asBackendType" to the frontend types
+
+ return result;
+ }
+
+ public static void registerOutlets (ExecutionContext ctx, Collection<Outlet> outlets) {
+ for (Outlet oldOutlet: outlets) {
+ final FileOutlet newOutlet = new FileOutlet ();
+ newOutlet.setAppend (oldOutlet.isAppend());
+ newOutlet.setBaseDir (new File (oldOutlet.getPath()));
+ if (oldOutlet.getFileEncoding() != null)
+ newOutlet.setFileEncoding (oldOutlet.getFileEncoding());
+ newOutlet.setOverwrite (oldOutlet.isOverwrite());
+
+ final String outletName = (oldOutlet.getName() != null) ? oldOutlet.getName() : FileIoOperations.DEFAULT_OUTLET_NAME;
+ ctx.getFunctionDefContext ().invoke (ctx, SysLibNames.REGISTER_OUTLET, Arrays.asList (outletName, newOutlet));
+ }
+ }
+
+ public static XpandBackendFacade createForFile (String xpandFilename, Collection<MetaModel> mms, Collection <Outlet> outlets) {
+ return new XpandBackendFacade (xpandFilename, mms, outlets);
+ }
+
+
+ private static XpandExecutionContext createOldExecutionContext (String fileEncoding, Collection<MetaModel> mms, Collection<Outlet> outlets) {
+ if (fileEncoding == null)
+ fileEncoding = System.getProperty ("file.encoding");
+
+ final Output output = new OutputImpl ();
+ for (Outlet outlet: outlets)
+ output.addOutlet (outlet);
+ //TODO ProtectedRegionResolver
+
+ final XpandExecutionContextImpl ctx = new XpandExecutionContextImpl (output, null);
+ for (MetaModel mm: mms)
+ ctx.registerMetaModel (mm);
+ ctx.setFileEncoding (fileEncoding);
+
+ return ctx;
+ }
+
+ private XpandBackendFacade (String xpandFilename, Collection<MetaModel> mms, Collection <Outlet> outlets) {
+ _xpandFile = OldXtendHelper.normalizeXpandResourceName (xpandFilename);
+ _ts = guessTypesystem(mms);
+
+ final XpandExecutionContext ctx = createOldExecutionContext (null, mms, outlets);
+
+ _extensions = new OldXtendRegistry (ctx, _ts);
+ _registry = new OldXpandRegistry (ctx, _ts, _extensions);
+ _registry.registerXpandFile (xpandFilename);
+ }
+
+ public Collection<NamedFunction> getContributedFunctions () {
+ return _registry.getContributedFunctions (_xpandFile);
+ }
+
+ public FunctionDefContext getFunctionDefContext () {
+ if (getContributedFunctions().isEmpty())
+ return new FunctionDefContextFactory(_ts).create();
+
+ return ((SourceDefinedFunction) getContributedFunctions().iterator().next().getFunction()).getFunctionDefContext();
+ }
+}
+
+
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java
index 48497b7..25af7df 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java
@@ -38,7 +38,7 @@ final class XpandDefinitionName {
public XpandDefinitionName (XpandDefinition def) {
_canonicalTemplateFileName = def.getFileName();
- _canonicalDefinitionName = _canonicalTemplateFileName.substring (0, _canonicalTemplateFileName.length() - 4) + "/" + def.getName();
+ _canonicalDefinitionName = _canonicalTemplateFileName.substring (0, _canonicalTemplateFileName.length() - 4) + "/" + def.getName();
}
/**
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java
new file mode 100644
index 0000000..ff6fb18
--- /dev/null
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandWorkflowComponent.java
@@ -0,0 +1,215 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+ */
+package org.eclipse.xtend.middleend.old;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.mwe.core.WorkflowContext;
+import org.eclipse.emf.mwe.core.issues.Issues;
+import org.eclipse.emf.mwe.core.monitor.ProgressMonitor;
+import org.eclipse.internal.xpand2.ast.Definition;
+import org.eclipse.internal.xpand2.ast.ExpandStatement;
+import org.eclipse.internal.xpand2.ast.Template;
+import org.eclipse.internal.xpand2.codeassist.XpandTokens;
+import org.eclipse.internal.xpand2.parser.XpandParseFacade;
+import org.eclipse.internal.xtend.xtend.parser.ParseException;
+import org.eclipse.xpand2.XpandExecutionContextImpl;
+import org.eclipse.xpand2.output.Outlet;
+import org.eclipse.xpand2.output.Output;
+import org.eclipse.xpand2.output.OutputImpl;
+import org.eclipse.xtend.expression.AbstractExpressionsUsingWorkflowComponent;
+
+
+/**
+ * This workflow component executes an Xpand template based on the new backend implementation. It
+ * combines the steps of parsing and transforming the source files, and of invoking the script.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class XpandWorkflowComponent extends AbstractExpressionsUsingWorkflowComponent {
+ //TODO genPath, srcPath
+ //TODO profiler
+ //TODO beautifier
+ //TODO advice / AOP
+
+ private String _genPath = null;
+ private String _srcPath = null;
+
+ private String _expand = null;
+ private String _fileEncoding = null;
+ private boolean _automaticHyphens = false;
+ private Output _output = null;
+ private List<Outlet> _initializedOutlets = new ArrayList<Outlet> ();
+
+
+ public void setAutomaticHyphens(boolean automaticHyphens) {
+ this._automaticHyphens = automaticHyphens;
+ }
+
+ @Override
+ public String getLogMessage() {
+ return "generating '" + _expand + "' => directory '" + _genPath + "'";
+ }
+
+ public void setFileEncoding(final String fileEncoding) {
+ _fileEncoding = fileEncoding;
+ }
+
+ public String getFileEncoding() {
+ return _fileEncoding;
+ }
+
+ public void setExpand (String invoke) {
+ _expand = invoke;
+ }
+
+ /**
+ * @deprecated use outlets instead
+ */
+ @Deprecated
+ public void setGenPath(final String genPath) {
+ _genPath = fixPath(genPath);
+ }
+
+ /**
+ *
+ * @deprecated use outlets instead
+ */
+ @Deprecated
+ public void setSrcPath(final String srcPath) {
+ _srcPath = fixPath(srcPath);
+ }
+
+
+ private String fixPath(final String p) {
+ if (p.endsWith("\\"))
+ return p.replace('\\', '/');
+ if (p.endsWith("/"))
+ return p;
+ return p + "/";
+ }
+
+
+ @Override
+ protected void invokeInternal2 (WorkflowContext wfContext, ProgressMonitor monitor, Issues issues) {
+
+ // set up the execution context
+ XpandExecutionContextImpl executionContext = new XpandExecutionContextImpl (getOutput(), null, getGlobalVars (wfContext), null, getNullEvaluationHandler());
+
+ if (_fileEncoding != null)
+ executionContext.setFileEncoding (_fileEncoding);
+
+ final String code = XpandTokens.LT + "EXPAND " + _expand + XpandTokens.RT;
+
+ final Map<String, Object> variables = new HashMap<String, Object> ();
+ for (String name: wfContext.getSlotNames())
+ variables.put (name, wfContext.get (name));
+
+ XpandBackendFacade.executeStatement (code, metaModels, variables, outlets);
+ }
+
+ private final List<Outlet> outlets = new ArrayList<Outlet>();
+
+ public void addOutlet (Outlet outlet) {
+ outlets.add(outlet);
+ }
+
+ public void setOutput (Output output) {
+ _output = output;
+ }
+
+ private Output getOutput () {
+ if (_output == null) {
+ // lazy initialization
+ OutputImpl out = new OutputImpl();
+ out.setAutomaticHyphens (_automaticHyphens);
+ _output = out;
+ }
+
+ return _output;
+ }
+
+
+ private List<Outlet> getInitializedOutlets() {
+ if (_initializedOutlets.isEmpty()) {
+ final List<Outlet> result = new ArrayList<Outlet> (outlets);
+ if (result.isEmpty()) {
+ if (_genPath != null) { // backward compatibility
+ result.add (new Outlet (false, _fileEncoding, null, true, _genPath));
+ result.add (new Outlet (true, _fileEncoding, "APPEND", true, _genPath));
+ }
+
+ if (_srcPath != null)
+ result.add (new Outlet (false, _fileEncoding, "ONCE", false, _srcPath));
+ }
+
+ for (Outlet o: result)
+ if (o.hasDefaultEncoding() && _fileEncoding!=null)
+ o.setFileEncoding(_fileEncoding);
+ }
+
+ return _initializedOutlets;
+ }
+
+
+ private ExpandStatement getStatement() {
+ Template tpl = XpandParseFacade.file (new StringReader(XpandTokens.LT + "DEFINE test FOR test" + XpandTokens.RT + XpandTokens.LT + "EXPAND " + _expand + XpandTokens.RT + XpandTokens.LT + "ENDDEFINE" + XpandTokens.RT), null);
+ ExpandStatement es = null;
+ try {
+ es = (ExpandStatement) ((Definition) tpl.getDefinitions()[0]).getBody()[1];
+ } catch (final Exception e) {
+ log.error(e);
+ }
+ return es;
+ }
+
+ @Override
+ public void checkConfiguration(final Issues issues) {
+ super.checkConfiguration(issues);
+ if (_genPath == null && getInitializedOutlets().isEmpty())
+ issues.addError(this, "You need to configure at least one outlet!");
+
+ if ((_genPath != null || _srcPath != null) && !outlets.isEmpty())
+ issues.addWarning(this, "'genPath' is ignored since you have specified outlets!");
+
+ int defaultOutlets = 0;
+ for (final Iterator<Outlet> iter = getInitializedOutlets().iterator(); iter.hasNext();) {
+ final Outlet o = iter.next();
+ if (o.getName() == null)
+ defaultOutlets++;
+ }
+
+ if (defaultOutlets > 1)
+ issues.addError(this, "Only one outlet can be the default outlet. Please specifiy a name for the other outlets!");
+ else if (defaultOutlets == 0)
+ issues.addWarning(this, "No default outlet configured!");
+
+ if (_expand == null)
+ issues.addError(this, "property 'expand' not configured!");
+ else {
+ try {
+ final ExpandStatement es = getStatement();
+ if (es == null) {
+ issues.addError(this, "property 'expand' has wrong syntax!");
+ }
+ } catch (ParseException e) {
+ issues.addError(this, "property 'expand' has wrong syntax : "+e.getMessage());
+ }
+ }
+ }
+}
+
+
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java
index 2048a5c..8db461f 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XtendBackendContributor.java
@@ -30,6 +30,7 @@ import org.eclipse.xtend.typesystem.MetaModel;
* @author Arno Haase (http://www.haase-consulting.com)
*/
public final class XtendBackendContributor implements BackendContributor {
+ //TODO merge with XpandBackendFacade
private final OldXtendRegistry _registry;
private final String _xtendFile;
private final BackendTypesystem _ts;
diff --git a/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java b/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java
index b1f2128..032e7f3 100644
--- a/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java
+++ b/plugins/org.eclipse.xtend.middleend/src/org/eclipose/xtend/middleend/BackendTypesystemFactory.java
@@ -47,7 +47,6 @@ public final class BackendTypesystemFactory {
final CompositeTypesystem result = new CompositeTypesystem ();
result.register (new EmfTypesystem ());
- result.register (new GlobalJavaBeansTypesystem ());
return result;
}
diff --git a/tests/org.eclipse.xtend.middleend.old.test/.cvsignore b/tests/org.eclipse.xtend.middleend.old.test/.cvsignore
index ba077a4..4cbbaf5 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/.cvsignore
+++ b/tests/org.eclipse.xtend.middleend.old.test/.cvsignore
@@ -1 +1,2 @@
bin
+src-gen
diff --git a/tests/org.eclipse.xtend.middleend.old.test/META-INF/MANIFEST.MF b/tests/org.eclipse.xtend.middleend.old.test/META-INF/MANIFEST.MF
index 453102d..e0f20f2 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.xtend.middleend.old.test/META-INF/MANIFEST.MF
@@ -7,4 +7,5 @@ Require-Bundle: org.eclipse.xtend.backend,
org.eclipse.xtend.middleend.old,
org.eclipse.xtend.middleend,
org.eclipse.xtend,
- org.eclipse.xpand
+ org.eclipse.xpand,
+ org.eclipse.emf.mwe.core
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
index 26ab737..9f5005c 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
@@ -15,12 +15,16 @@ import java.util.Arrays;
import java.util.List;
import org.eclipose.xtend.middleend.BackendTypesystemFactory;
+import org.eclipse.emf.mwe.core.WorkflowContext;
+import org.eclipse.emf.mwe.core.issues.IssuesImpl;
+import org.eclipse.emf.mwe.internal.core.WorkflowContextDefaultImpl;
import org.eclipse.internal.xtend.type.impl.java.JavaBeansMetaModel;
import org.eclipse.xpand2.output.Outlet;
import org.eclipse.xtend.backend.BackendFacade;
import org.eclipse.xtend.backend.common.ExecutionContext;
import org.eclipse.xtend.backend.types.CompositeTypesystem;
-import org.eclipse.xtend.middleend.old.XpandBackendContributor;
+import org.eclipse.xtend.middleend.old.XpandBackendFacade;
+import org.eclipse.xtend.middleend.old.XpandWorkflowComponent;
import org.eclipse.xtend.middleend.old.XtendBackendContributor;
import org.eclipse.xtend.typesystem.MetaModel;
@@ -33,13 +37,23 @@ public class FirstAttempt {
final CompositeTypesystem ts = BackendTypesystemFactory.createWithoutUml();
{
- final XpandBackendContributor xp = new XpandBackendContributor ("org::eclipse::xtend::middleend::old::first::aTemplate", mms, ts, new ArrayList<Outlet>());
+ final XpandBackendFacade xp = XpandBackendFacade.createForFile ("org::eclipse::xtend::middleend::old::first::aTemplate", mms, new ArrayList<Outlet>());
final ExecutionContext ctx = BackendFacade.createExecutionContext (xp.getFunctionDefContext(), ts);
System.err.println (BackendFacade.invoke (ctx, "org/eclipse/xtend/middleend/old/first/aTemplate/greeting", Arrays.asList("Arno")));
}
{
+ final XpandWorkflowComponent xwc = new XpandWorkflowComponent ();
+ xwc.setExpand ("org::eclipse::xtend::middleend::old::first::WithFileOutput::WithFileOutput FOR toBeGreeted");
+ xwc.addOutlet (new Outlet (false, "iso-8859-1", null, true, "src-gen"));
+
+ final WorkflowContext wfContext = new WorkflowContextDefaultImpl ();
+ wfContext.set ("toBeGreeted", "Arno");
+ xwc.invoke (wfContext, null, new IssuesImpl ());
+ }
+
+ {
final XtendBackendContributor bc = new XtendBackendContributor ("org::eclipse::xtend::middleend::old::first::first", mms, ts);
final ExecutionContext ctx = BackendFacade.createExecutionContext (bc.getFunctionDefContext(), ts);
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/WithFileOutput.xpt b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/WithFileOutput.xpt
new file mode 100644
index 0000000..c9b4514
--- /dev/null
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/WithFileOutput.xpt
@@ -0,0 +1,6 @@
+
+«DEFINE WithFileOutput FOR String»
+ «FILE "dummy.txt"»
+ Hello «this»: «this.length»!
+ «ENDFILE»
+«ENDDEFINE»