Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahaase2008-01-31 21:03:09 +0000
committerahaase2008-01-31 21:03:09 +0000
commita343b56857b67317dced1afc2100ded643a7bb75 (patch)
tree4de7d48c7edfb770308ffe5889428efe0f6015c6
parentbcc5d9362ddc447234a3f485f7a899703aaf8cee (diff)
downloadorg.eclipse.xpand-a343b56857b67317dced1afc2100ded643a7bb75.tar.gz
org.eclipse.xpand-a343b56857b67317dced1afc2100ded643a7bb75.tar.xz
org.eclipse.xpand-a343b56857b67317dced1afc2100ded643a7bb75.zip
added tests for the expression implementations
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Helpers.java12
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java3
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpression.java13
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java13
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpression.java2
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SequenceExpression.java4
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SwitchExpression.java13
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/DuplicateAwareNamedFunctionCollection.java5
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/FunctionDefContextImpl.java4
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/PolymorphicResolver.java43
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/TypesComparator.java49
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractProperty.java5
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractType.java14
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/BuiltinProperty.java1
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/CollectionType.java4
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/DoubleType.java2
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/LongType.java7
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/ObjectType.java45
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/StringType.java2
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/java/JavaBeansType.java5
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java24
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java28
-rw-r--r--tests/org.eclipse.xtend.backend.test/META-INF/MANIFEST.MF5
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/AndExpressionTest.java45
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ConcatExpressionTest.java42
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateCachedExpressionTest.java79
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateUncachedExpressionTest.java46
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpressionTest.java44
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/IfExpressionTest.java44
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InitClosureExpressionTest.java114
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnCollectionExpressionTest.java32
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpressionTest.java42
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpressionTest.java60
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ListLiteralExpressionTest.java35
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LiteralExpressionTest.java31
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LocalVarEvalExpressionTest.java35
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/NewLocalVarDefExpressionTest.java43
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/OrExpressionTest.java45
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnCollectionExpressionTest.java33
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpressionTest.java37
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpressionTest.java40
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SequenceExpressionTest.java41
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SetPropertyExpressionTest.java52
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SwitchExpressionTest.java143
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BackendTestHelper.java47
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BeanWithSizeProperty.java33
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/CheckEvaluationExpression.java39
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/ExceptionThrowingExpression.java30
-rw-r--r--tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/MutableLiteralExpression.java38
-rw-r--r--tests/org.eclipse.xtend.backend.test/todo.txt23
50 files changed, 1488 insertions, 108 deletions
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 96705935..475de8b3 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
@@ -10,15 +10,18 @@ Contributors:
*/
package org.eclipse.xtend.backend.common;
+import java.util.Arrays;
import java.util.Collections;
/**
+ * This class contains commonly used helper operations.
*
* @author Arno Haase (http://www.haase-consulting.com)
*/
public class Helpers {
public static String TO_STRING_METHOD_NAME = "toString";
+ public static String EQUALS_NAME = "operatorEquals";
/**
* This method is public static so as to be available as a helper method for all code that needs to call "toString".
@@ -38,4 +41,13 @@ public class Helpers {
return String.valueOf (resultRaw);
}
+ public static boolean nullSafeEquals (ExecutionContext ctx, Object o1, Object o2) {
+ if (o1 == o2)
+ return true;
+
+ if (o1 == null || o2 == null)
+ return false;
+
+ return (Boolean) ctx.getFunctionDefContext().invoke (ctx, EQUALS_NAME, Arrays.asList (o1, o2));
+ }
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java
index 7df57056..0f81237b 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java
@@ -24,8 +24,7 @@ public final class HidingLocalVarDefExpression extends ExpressionBase {
private final ExpressionBase _defExpression;
private final ExpressionBase _inner;
- public HidingLocalVarDefExpression (String localVarName, ExpressionBase defExpression, ExpressionBase inner,
- SourcePos sourcePos) {
+ public HidingLocalVarDefExpression (String localVarName, ExpressionBase defExpression, ExpressionBase inner, SourcePos sourcePos) {
super (sourcePos);
_localVarName = localVarName;
_defExpression = defExpression;
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpression.java
index a701b522..97b51338 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpression.java
@@ -25,12 +25,14 @@ import org.eclipse.xtend.backend.common.SourcePos;
public final class InvocationOnObjectExpression extends ExpressionBase {
private final String _functionName;
private final List<? extends ExpressionBase> _params;
+ private final boolean _nullIfFirstParamIsNull;
- public InvocationOnObjectExpression (String functionName, List<? extends ExpressionBase> params, SourcePos sourcePos) {
+ public InvocationOnObjectExpression (String functionName, List<? extends ExpressionBase> params, boolean nullIfFirstParamIsNull, SourcePos sourcePos) {
super (sourcePos);
_functionName = functionName;
_params = params;
+ _nullIfFirstParamIsNull = nullIfFirstParamIsNull;
}
@Override
@@ -39,6 +41,15 @@ public final class InvocationOnObjectExpression extends ExpressionBase {
for (ExpressionBase expr: _params)
params.add (expr.evaluate(ctx));
+ // this is for "method-style" invocations: if the first parameter (i.e. the one "before the dot") is null,
+ // shortcut the evaluation and return null
+ //
+ // CAUTION - without this shortcut, the polymorphic resolution may be ambiguous in unexpected ways
+ if (_nullIfFirstParamIsNull && params.get(0) == null) {
+ ctx.logNullDeRef (getPos());
+ return null;
+ }
+
return ctx.getFunctionDefContext().invoke (ctx, _functionName, params);
}
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java
index 1260016b..2912f5c1 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java
@@ -27,12 +27,14 @@ import org.eclipse.xtend.backend.common.SourcePos;
public final class InvocationOnWhateverExpression extends ExpressionBase {
private final String _functionName;
private final List<? extends ExpressionBase> _params;
+ private final boolean _nullIfFirstParamIsNull;
- public InvocationOnWhateverExpression (String functionName, List<? extends ExpressionBase> params, SourcePos sourcePos) {
+ public InvocationOnWhateverExpression (String functionName, List<? extends ExpressionBase> params, boolean nullIfFirstParamIsNull, SourcePos sourcePos) {
super (sourcePos);
_functionName = functionName;
_params = params;
+ _nullIfFirstParamIsNull = nullIfFirstParamIsNull;
}
@Override
@@ -41,10 +43,15 @@ public final class InvocationOnWhateverExpression extends ExpressionBase {
for (ExpressionBase expr: _params)
params.add (expr.evaluate(ctx));
+ if (_nullIfFirstParamIsNull && params.get(0) == null) {
+ ctx.logNullDeRef (getPos());
+ return null;
+ }
+
if (params.get (0) instanceof Collection<?>) {
// check if this is a function on Collection itself
- if (ctx.getFunctionDefContext().hasMatch(ctx, _functionName, params))
- return ctx.getFunctionDefContext().invoke(ctx, _functionName, params);
+ if (ctx.getFunctionDefContext().hasMatch (ctx, _functionName, params))
+ return ctx.getFunctionDefContext().invoke (ctx, _functionName, params);
final Collection<?> coll = (Collection<?>) params.get (0);
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpression.java
index 5bcceeea..883b1c8f 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpression.java
@@ -38,6 +38,6 @@ public final class PropertyOnObjectExpression extends ExpressionBase {
return null;
}
- return ctx.getTypesystem().findType(o).getProperty(ctx, o, _propertyName);
+ return ctx.getTypesystem().findType (o).getProperty (ctx, o, _propertyName);
}
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SequenceExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SequenceExpression.java
index 81a31ade..6e641322 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SequenceExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SequenceExpression.java
@@ -22,9 +22,9 @@ import org.eclipse.xtend.backend.common.SourcePos;
* @author Arno Haase (http://www.haase-consulting.com)
*/
public final class SequenceExpression extends ExpressionBase {
- private final List<ExpressionBase> _inner;
+ private final List<? extends ExpressionBase> _inner;
- public SequenceExpression (List<ExpressionBase> inner, SourcePos sourcePos) {
+ public SequenceExpression (List<? extends ExpressionBase> inner, SourcePos sourcePos) {
super (sourcePos);
_inner = inner;
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SwitchExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SwitchExpression.java
index e71b8fea..1584f2aa 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SwitchExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/SwitchExpression.java
@@ -14,6 +14,7 @@ import java.util.List;
import org.eclipse.xtend.backend.common.ExecutionContext;
import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.common.Helpers;
import org.eclipse.xtend.backend.common.SourcePos;
import org.eclipse.xtend.backend.util.Pair;
@@ -45,21 +46,11 @@ public final class SwitchExpression extends ExpressionBase {
for (Pair<ExpressionBase, ExpressionBase> curCase: _cases) {
final Object curVal = curCase.getFirst().evaluate(ctx);
- if (nullSafeEquals (switchVal, curVal))
+ if (Helpers.nullSafeEquals (ctx, switchVal, curVal))
return curCase.getSecond().evaluate(ctx);
}
return _defaultExpr.evaluate(ctx);
}
-
- private static boolean nullSafeEquals (Object o1, Object o2) {
- if (o1 == o2)
- return true;
-
- if (o1 == null || o2 == null)
- return false;
-
- return o1.equals (o2);
- }
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/DuplicateAwareNamedFunctionCollection.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/DuplicateAwareNamedFunctionCollection.java
index 7e287e72..63a633c9 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/DuplicateAwareNamedFunctionCollection.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/DuplicateAwareNamedFunctionCollection.java
@@ -85,5 +85,10 @@ public final class DuplicateAwareNamedFunctionCollection {
return f1.getFunction().getParameterTypes().equals (f2.getFunction().getParameterTypes());
}
+
+ @Override
+ public String toString () {
+ return _allFunctions.toString();
+ }
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/FunctionDefContextImpl.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/FunctionDefContextImpl.java
index 887227e1..4c23bbae 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/FunctionDefContextImpl.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/FunctionDefContextImpl.java
@@ -49,7 +49,7 @@ public final class FunctionDefContextImpl implements FunctionDefContext {
@Override
protected Collection<Function> create (String functionName, List<BackendType> paramTypes) {
- return new PolymorphicResolver(functionName).getBestFitCandidates (findCandidates (functionName, paramTypes));
+ return new PolymorphicResolver(functionName).getBestFitCandidates (findCandidates (functionName, paramTypes)); // TODO go around this cache if there is a dynamically provided function
}
private Collection<Function> findCandidates (String functionName, List<BackendType> paramTypes) {
@@ -143,7 +143,7 @@ public final class FunctionDefContextImpl implements FunctionDefContext {
}
public boolean hasMatch (ExecutionContext ctx, String functionName, List<? extends Object> params) {
- return findFunctionCandidates(ctx, functionName, params).size() > 0;
+ return findFunctionCandidates (ctx, functionName, params).size() > 0;
}
@Override
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/PolymorphicResolver.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/PolymorphicResolver.java
index f1b78fec..a1ea46b4 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/PolymorphicResolver.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/PolymorphicResolver.java
@@ -12,8 +12,8 @@ package org.eclipse.xtend.backend.functions;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
-import java.util.Iterator;
import java.util.List;
import org.eclipse.xtend.backend.common.ExecutionContext;
@@ -40,32 +40,23 @@ final class PolymorphicResolver {
*/
public Collection<Function> getBestFitCandidates (Collection<Function> functions) {
// shortcut for a common case
- if (functions.size() == 1)
+ if (functions.size() <= 1)
return functions;
- if (functions.isEmpty())
- throw new IllegalArgumentException ("no matches found");
-
- Iterator<Function> iter = functions.iterator();
+// if (functions.isEmpty())
+// throw new IllegalArgumentException ("no matches found");
- Function firstBestMatch = iter.next();
- List<Function> bestMatches2 = new ArrayList<Function> ();
- bestMatches2.add (firstBestMatch);
+ final List<Function> sorted = new ArrayList<Function> (functions);
+ Collections.sort (sorted, _paramTypeComparator);
- while (iter.hasNext()) {
- final Function candidate = iter.next();
- final int compResult = _paramTypeComparator.compare (candidate, firstBestMatch);
-
- if (compResult < 0) {
- firstBestMatch = candidate;
- bestMatches2 = new ArrayList<Function>();
- bestMatches2.add (candidate);
- }
- else if (compResult == 0) {
- bestMatches2.add (candidate);
- }
+ final List<Function> result = new ArrayList<Function> ();
+ for (Function f: sorted) {
+ if (_paramTypeComparator.compare (f, sorted.get(0)) == 0)
+ result.add (f);
+ else
+ break;
}
- return bestMatches2;
+ return result;
}
private Function evaluateGuards (ExecutionContext ctx, Function function) {
@@ -103,10 +94,12 @@ final class PolymorphicResolver {
if (passedInspection != null)
return passedInspection;
- if (unguarded.size() > 0)
- return unguarded.get (unguarded.size() - 1); // this is where the overwriting of extensions is implemented
+ if (unguarded.size() == 1)
+ return unguarded.get (0); // TODO implement the overwriting of extensions
+ if (unguarded.isEmpty())
+ throw new IllegalArgumentException ("call to " + _name + " could not be resolved - no guard allowed passage, and there are no unguarded implementations.");
- throw new IllegalArgumentException ("call to " + _name + " could not be resolved - no guard allowed passage, and there are no unguarded implementations.");
+ throw new IllegalArgumentException ("call to " + _name + " could not be resolved - ambiuity between " + unguarded);
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/TypesComparator.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/TypesComparator.java
index 15c35958..8e000c7f 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/TypesComparator.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/TypesComparator.java
@@ -17,37 +17,50 @@ import org.eclipse.xtend.backend.common.BackendType;
/**
+ * This comparator defines a partial order on lists of types by assignability, i.e. l1 <= l2 iff
+ * all types in l2 are assignable from their respective counterparts in l1. It treats all lists of
+ * types as "equal" if neither is fully assignable from the other.
*
* @author Arno Haase (http://www.haase-consulting.com)
*/
final class TypesComparator implements Comparator<List<? extends BackendType>> {
- /**
- *
- * returns -1 if the second list of types is not assignable to the first
- * list of types returns 0 if the second list of types exactly matches the
- * first list of types returns 1 if the second list of types is assignable
- * to the first list of types
- */
+
public int compare(final List<? extends BackendType> types1, final List<? extends BackendType> types2) {
if (types1 == null || types2 == null)
throw new NullPointerException ();
if (types1.size() != types2.size ())
- return -1;
- boolean directMatch = true;
+ throw new IllegalArgumentException ("can not compare type lists of different sizes");
+
+ boolean less = false;
+ boolean greater = false;
+
for (int i = 0, x = types1.size (); i < x; i++) {
final BackendType type1 = types1.get (i);
final BackendType type2 = types2.get (i);
- if (type1.isAssignableFrom (type2)) {
- if (!type1.equals (type2)) {
- directMatch = false;
- }
- } else
- return -1;
+
+ if (type1.equals (type2))
+ continue;
+
+ if (type2.isAssignableFrom (type1)) {
+ if (greater)
+ return 0;
+
+ less = true;
+ }
+ else if (type1.isAssignableFrom (type2)) {
+ if (less)
+ return 0;
+
+ greater = true;
+ }
}
- if (directMatch)
- return 0;
- else
+
+ if (greater)
return 1;
+ if (less)
+ return -1;
+
+ return 0;
}
} \ No newline at end of file
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractProperty.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractProperty.java
index 1b1b9602..a155e2c0 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractProperty.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractProperty.java
@@ -25,6 +25,11 @@ public abstract class AbstractProperty implements Property {
protected final String _name;
public AbstractProperty (BackendType owner, BackendType type, String name) {
+ if (owner == null)
+ throw new IllegalArgumentException ();
+ if (type == null)
+ throw new IllegalArgumentException ();
+
_owner = owner;
_type = type;
_name = name;
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractType.java
index 9b7b67ab..979d35f7 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractType.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/AbstractType.java
@@ -75,7 +75,7 @@ public abstract class AbstractType implements BackendType {
}
public final Object getProperty (ExecutionContext ctx, Object o, String name) {
- final Property p = _properties.get (name);
+ final Property p = getProperties().get (name);
if (p == null)
throw new IllegalArgumentException ("no property " + name + " in type " + getName());
@@ -83,7 +83,7 @@ public abstract class AbstractType implements BackendType {
}
public final void setProperty (ExecutionContext ctx, Object o, String name, Object value) {
- final Property p = _properties.get (name);
+ final Property p = getProperties().get (name);
if (p == null)
throw new IllegalArgumentException ("no property " + name + " in type " + getName());
@@ -100,7 +100,15 @@ public abstract class AbstractType implements BackendType {
}
public final Map<String, ? extends Property> getProperties () {
- return _properties;
+ //this could be statically initialized in the constructor, but is intentionally done dynamically to prepare for
+ // "dynamic properties" that are attached at runtime
+ final Map<String, Property> result = new HashMap<String, Property> ();
+
+ for (BackendType t: _superTypes)
+ result.putAll (t.getProperties());
+
+ result.putAll (_properties);
+ return result;
}
public final Map<String, ? extends StaticProperty> getStaticProperties () {
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/BuiltinProperty.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/BuiltinProperty.java
index 47f5612f..733d1ec9 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/BuiltinProperty.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/BuiltinProperty.java
@@ -32,6 +32,7 @@ public final class BuiltinProperty extends AbstractProperty {
public BuiltinProperty (BackendType owner, BackendType type, String name, Method getter, Method setter) {
super (owner, type, name);
+
_getter = getter;
_setter = setter;
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/CollectionType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/CollectionType.java
index aaf09007..095a86a6 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/CollectionType.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/CollectionType.java
@@ -27,8 +27,8 @@ public final class CollectionType extends AbstractType {
private CollectionType() {
super ("Collection");
- register (new BuiltinProperty (CollectionType.INSTANCE, LongType.INSTANCE, "size", ReflectionHelper.getKnownMethod(Collection.class, "size"), null));
- register (new BuiltinProperty (CollectionType.INSTANCE, BooleanType.INSTANCE, "isEmpty", ReflectionHelper.getKnownMethod(Collection.class, "isEmpty"), null));
+ register (new BuiltinProperty (this, LongType.INSTANCE, "size", ReflectionHelper.getKnownMethod(Collection.class, "size"), null));
+ register (new BuiltinProperty (this, BooleanType.INSTANCE, "isEmpty", ReflectionHelper.getKnownMethod(Collection.class, "isEmpty"), null));
}
public boolean isAssignableFrom (BackendType other) {
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/DoubleType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/DoubleType.java
index 4754f7ee..3e033dde 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/DoubleType.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/DoubleType.java
@@ -21,7 +21,7 @@ import org.eclipse.xtend.backend.types.AbstractType;
public final class DoubleType extends AbstractType {
public static final DoubleType INSTANCE = new DoubleType();
- private DoubleType () {super ("double"); }
+ private DoubleType () {super ("Double"); }
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/builtin/LongType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/LongType.java
index edceee5b..6b0021fa 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/LongType.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/LongType.java
@@ -21,12 +21,7 @@ import org.eclipse.xtend.backend.types.AbstractType;
public final class LongType extends AbstractType {
public static final LongType INSTANCE = new LongType();
- private LongType () {super ("Int"); }
-
- @Override
- public Object create() {
- throw new UnsupportedOperationException ();
- }
+ private LongType () {super ("Long"); }
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/builtin/ObjectType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/ObjectType.java
index 7a57fd4e..06925e2c 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/ObjectType.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/types/builtin/ObjectType.java
@@ -10,20 +10,59 @@ Contributors:
*/
package org.eclipse.xtend.backend.types.builtin;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
import org.eclipse.xtend.backend.common.BackendType;
-import org.eclipse.xtend.backend.types.AbstractType;
+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;
/**
*
* @author Arno Haase (http://www.haase-consulting.com)
*/
-public final class ObjectType extends AbstractType {
- private ObjectType() {super ("Object"); }
+public final class ObjectType implements BackendType {
+ private ObjectType() {}
public static ObjectType INSTANCE = new ObjectType();
public boolean isAssignableFrom (BackendType other) {
return true;
}
+
+ public Object create () {
+ throw new UnsupportedOperationException ("ObjectType can not be instantiated");
+ }
+
+ public Collection<? extends NamedFunction> getBuiltinOperations () {
+ return Collections.emptyList();
+ }
+
+ public String getName () {
+ return "Object";
+ }
+
+ public Map<String, ? extends Property> getProperties () {
+ return Collections.emptyMap();
+ }
+
+ public Object getProperty (ExecutionContext ctx, Object o, String name) {
+ throw new IllegalArgumentException ("ObjectType has no properties");
+ }
+
+ public Map<String, ? extends StaticProperty> getStaticProperties () {
+ throw new IllegalArgumentException ("ObjectType has no static properties");
+ }
+
+ public Collection<? extends BackendType> getSuperTypes () {
+ return Collections.emptyList();
+ }
+
+ public void setProperty (ExecutionContext ctx, Object o, String name, Object value) {
+ throw new IllegalArgumentException ("ObjectType has no properties");
+ }
}
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 61954022..b3234dfb 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
@@ -31,7 +31,7 @@ public final class StringType extends AbstractType {
private StringType () {
super ("String");
- register (new BuiltinProperty (this, StringType.INSTANCE, "length", ReflectionHelper.getKnownMethod (CharSequence.class, "length"), null));
+ register (new BuiltinProperty (this, this, "length", ReflectionHelper.getKnownMethod (CharSequence.class, "length"), null));
}
public boolean isAssignableFrom (BackendType other) {
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
index 72bda900..30f9b463 100644
--- 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
@@ -155,6 +155,11 @@ final class JavaBeansType implements BackendType {
public Collection<BackendType> getSuperTypes () {
return _superTypes;
}
+
+ @Override
+ public String toString () {
+ return "JavaBeansType[" + _javaClass.getName() + "]";
+ }
}
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 937cccf8..0de92105 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
@@ -202,13 +202,13 @@ final class OldDefinitionConverter {
referencedDefinitions.add (called);
- final ExpressionBase invocationExpression = new InvocationOnObjectExpression (called.getCanonicalDefinitionName(), params, getSourcePos(stmt));
+ final ExpressionBase invocationExpression = new InvocationOnObjectExpression (called.getCanonicalDefinitionName(), params, false, getSourcePos(stmt));
final ExpressionBase loopBody = new InitClosureExpression (Arrays.asList(closureParamName), Arrays.asList(ObjectType.INSTANCE), invocationExpression, getSourcePos(stmt));
if (separator == null)
- return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody), true, getSourcePos (stmt));
else
- return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody, separator), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody, separator), true, getSourcePos (stmt));
}
else {
final List<ExpressionBase> params = new ArrayList<ExpressionBase>();
@@ -222,7 +222,7 @@ final class OldDefinitionConverter {
final XpandDefinitionName called = new XpandDefinitionName (stmt.getDefinition().getValue(), stmt.getTarget(), stmt.getParametersAsList(), _ctx);
referencedDefinitions.add (called);
- return new InvocationOnObjectExpression (called.getCanonicalDefinitionName(), params, getSourcePos(stmt));
+ return new InvocationOnObjectExpression (called.getCanonicalDefinitionName(), params, true, getSourcePos(stmt));
}
}
@@ -260,9 +260,9 @@ final class OldDefinitionConverter {
final ExpressionBase closureCreation = new InitClosureExpression (Arrays.asList (varName), Arrays.asList (_typeConverter.convertToBackendType(eleType)), body, getSourcePos (stmt));
if (separator == null)
- return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation), true, getSourcePos (stmt));
else
- return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation, separator), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation, separator), true, getSourcePos (stmt));
}
else {
// forEach with an iterator
@@ -281,9 +281,9 @@ final class OldDefinitionConverter {
final ExpressionBase closureCreation = new InitClosureExpression (paramNames, paramTypes, body, getSourcePos (stmt));
if (separator == null)
- return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation), true, getSourcePos (stmt));
else
- return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation, separator), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation, separator), true, getSourcePos (stmt));
}
}
@@ -341,10 +341,10 @@ final class OldDefinitionConverter {
//TODO register the outlets
final List<ExpressionBase> emptyParamList = Collections.emptyList();
- final ExpressionBase initIsDeleteLineExpression = new InvocationOnObjectExpression (XtendLibNames.DELETE_LINE_INIT, emptyParamList, getSourcePos (stmt));
+ final ExpressionBase initIsDeleteLineExpression = new InvocationOnObjectExpression (XtendLibNames.DELETE_LINE_INIT, emptyParamList, false, getSourcePos (stmt));
- final ExpressionBase postprocessIsDeleteLineExpression = new InvocationOnObjectExpression (XtendLibNames.DELETE_LINE_POSTPROCESS, Arrays.asList(body), getSourcePos (stmt));
- final ExpressionBase writeToFileExpression = new InvocationOnObjectExpression (SysLibNames.WRITE_TO_FILE, Arrays.asList(outletName, filename, append, postprocessIsDeleteLineExpression), getSourcePos (stmt));
+ final ExpressionBase postprocessIsDeleteLineExpression = new InvocationOnObjectExpression (XtendLibNames.DELETE_LINE_POSTPROCESS, Arrays.asList(body), false, getSourcePos (stmt));
+ final ExpressionBase writeToFileExpression = new InvocationOnObjectExpression (SysLibNames.WRITE_TO_FILE, Arrays.asList(outletName, filename, append, postprocessIsDeleteLineExpression), false, getSourcePos (stmt));
return new SequenceExpression (Arrays.asList (initIsDeleteLineExpression, writeToFileExpression), getSourcePos (stmt));
}
@@ -356,7 +356,7 @@ final class OldDefinitionConverter {
private ExpressionBase convertTextStatement (TextStatement stmt) {
if (stmt.isDeleteLine()) {
final List<ExpressionBase> emptyParamList = Collections.emptyList();
- final ExpressionBase registerExpression = new InvocationOnObjectExpression (XtendLibNames.DELETE_LINE_REGISTER, emptyParamList, getSourcePos(stmt));
+ final ExpressionBase registerExpression = new InvocationOnObjectExpression (XtendLibNames.DELETE_LINE_REGISTER, emptyParamList, false, getSourcePos(stmt));
final ExpressionBase markerExpression = new LiteralExpression (XpandIsDeleteLine.MARKER_FOR_IS_DELETE_LINE, getSourcePos(stmt));
final ExpressionBase contentExpression = new LiteralExpression (stmt.getValue(), getSourcePos (stmt));
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java
index 2a0ccc1d..a20a9ed1 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java
@@ -148,18 +148,18 @@ final class OldExpressionConverter {
// if a function matches directly (i.e. without implicitly passing 'this' as a first parameter), that
// has precedence in matching
if (_ctx.getExtensionForTypes (functionName, paramTypes.toArray (new Type[0])) != null)
- return new InvocationOnObjectExpression (functionName, params, sourcePos);
+ return new InvocationOnObjectExpression (functionName, params, false, sourcePos);
else {
final ExpressionBase thisExpression = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
final Type thisType = (Type) _ctx.getVariable (ExecutionContext.IMPLICIT_VARIABLE).getValue();
- return createInvocationOnTargetExpression(functionName, thisExpression, thisType, params, paramTypes, sourcePos);
+ return createInvocationOnTargetExpression (functionName, thisExpression, thisType, params, paramTypes, true, sourcePos);
}
}
else
- return new InvocationOnObjectExpression (functionName, params, sourcePos);
+ return new InvocationOnObjectExpression (functionName, params, false, sourcePos);
}
else
- return createInvocationOnTargetExpression(functionName, convert (expr.getTarget()), expr.getTarget ().analyze (_ctx, new HashSet<AnalysationIssue> ()), params, paramTypes, sourcePos);
+ return createInvocationOnTargetExpression(functionName, convert (expr.getTarget()), expr.getTarget ().analyze (_ctx, new HashSet<AnalysationIssue> ()), params, paramTypes, true, sourcePos);
}
/**
@@ -196,7 +196,7 @@ final class OldExpressionConverter {
return functionName;
}
- private ExpressionBase createInvocationOnTargetExpression (String functionName, ExpressionBase targetExpression, Type targetType, List<ExpressionBase> params, List<Type> paramTypes, SourcePos sourcePos) {
+ private ExpressionBase createInvocationOnTargetExpression (String functionName, ExpressionBase targetExpression, Type targetType, List<ExpressionBase> params, List<Type> paramTypes, boolean isMethodStyle, SourcePos sourcePos) {
final List<ExpressionBase> paramsWithoutFirst = params;
final List<ExpressionBase> allParams = new ArrayList<ExpressionBase> ();
allParams.add (targetExpression);
@@ -208,7 +208,7 @@ final class OldExpressionConverter {
if (_ctx.getExtensionForTypes (functionName, paramTypeArray) != null)
// check if there is a function that directly matches the collection
- return new InvocationOnObjectExpression (functionName, allParams, sourcePos);
+ return new InvocationOnObjectExpression (functionName, allParams, true, sourcePos);
else
// otherwise, do a 'collect' and call the function on all elements of the collection
return new InvocationOnCollectionExpression (targetExpression, functionName, paramsWithoutFirst, sourcePos);
@@ -216,10 +216,10 @@ final class OldExpressionConverter {
if (isObjectType (targetType))
// if the static type is "Object", we do not know if it is a collection, so we do the logic at runtime
- return new InvocationOnWhateverExpression (functionName, allParams, sourcePos);
+ return new InvocationOnWhateverExpression (functionName, allParams, isMethodStyle, sourcePos);
// otherwise we know that it is not a collection and can avoid repeating this logic at runtime
- return new InvocationOnObjectExpression (functionName, allParams, sourcePos);
+ return new InvocationOnObjectExpression (functionName, allParams, true, sourcePos);
}
private ExpressionBase convertTypeSelectExpression (TypeSelectExpression expr) {
@@ -233,10 +233,10 @@ final class OldExpressionConverter {
throw new IllegalStateException ("typeSelect with neither a target nor an implicit 'this'");
final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
- return new InvocationOnObjectExpression ("typeSelect", Arrays.asList (thisExpr, typeExpr), sourcePos);
+ return new InvocationOnObjectExpression (SysLibNames.TYPE_SELECT, Arrays.asList (thisExpr, typeExpr), true, sourcePos);
}
else
- return new InvocationOnObjectExpression ("typeSelect", Arrays.asList(convert (expr.getTarget()), typeExpr), sourcePos);
+ return new InvocationOnObjectExpression (SysLibNames.TYPE_SELECT, Arrays.asList(convert (expr.getTarget()), typeExpr), false, sourcePos);
}
private ExpressionBase convertSwitchExpression (SwitchExpression expr) {
@@ -318,7 +318,7 @@ final class OldExpressionConverter {
private ExpressionBase createPropertyExpression (ExpressionBase target, Type type, String varName, SourcePos sourcePos) {
if (isCollectionType (type)) {
- if ("size".equals (varName) || "isEmpty".equals (varName))
+ if ("size".equals (varName) || "isEmpty".equals (varName)) //TODO reference the type system for this
return new PropertyOnObjectExpression (target, varName, sourcePos);
else
return new PropertyOnCollectionExpression (target, varName, sourcePos);
@@ -352,10 +352,10 @@ final class OldExpressionConverter {
throw new IllegalStateException (functionName + " with neither a target nor an implicit 'this'");
final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
- return new InvocationOnObjectExpression (functionName, Arrays.asList (thisExpr, closureExpr), sourcePos);
+ return new InvocationOnObjectExpression (functionName, Arrays.asList (thisExpr, closureExpr), true, sourcePos);
}
else
- return new InvocationOnObjectExpression (functionName, Arrays.asList(convert (expr.getTarget()), closureExpr), sourcePos);
+ return new InvocationOnObjectExpression (functionName, Arrays.asList(convert (expr.getTarget()), closureExpr), true, sourcePos);
}
private ExpressionBase convertChainExpression (ChainExpression expr) {
@@ -391,7 +391,7 @@ final class OldExpressionConverter {
if ("||".equals (expr.getOperator().getValue()))
return new OrExpression (left, right, getSourcePos(expr));
if ("implies".equals (expr.getOperator().getValue()))
- return new InvocationOnObjectExpression ("implies", Arrays.asList(left, right), getSourcePos(expr));
+ return new InvocationOnObjectExpression (SysLibNames.IMPLIES, Arrays.asList(left, right), true, getSourcePos(expr));
throw new IllegalArgumentException ("unknown boolean operator " + expr.getOperator().getValue());
}
diff --git a/tests/org.eclipse.xtend.backend.test/META-INF/MANIFEST.MF b/tests/org.eclipse.xtend.backend.test/META-INF/MANIFEST.MF
index ce19846f..014bd593 100644
--- a/tests/org.eclipse.xtend.backend.test/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.xtend.backend.test/META-INF/MANIFEST.MF
@@ -3,4 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: Test Plug-in
Bundle-SymbolicName: org.eclipse.xtend.backend.test
Bundle-Version: 1.0.0
-Require-Bundle: org.eclipse.xtend.backend
+Require-Bundle: org.eclipse.xtend.backend,
+ org.junit4,
+ org.eclipse.xtend.backend.syslib,
+ org.eclipse.xtend.middleend
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/AndExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/AndExpressionTest.java
new file mode 100644
index 00000000..dfaa164a
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/AndExpressionTest.java
@@ -0,0 +1,45 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.*;
+import static org.junit.Assert.*;
+
+import org.eclipse.xtend.backend.helpers.ExceptionThrowingExpression;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class AndExpressionTest {
+ @Test public void testLogic () {
+ assertEquals (true, eval (true, true));
+ assertEquals (false, eval (true, false));
+ assertEquals (false, eval (false, true));
+ assertEquals (false, eval (false, false));
+
+ assertEquals (null, eval (null, false));
+ assertEquals (null, eval (null, true));
+ assertEquals (false, eval (false, null));
+ assertEquals (null, eval (true, null));
+ assertEquals (null, eval (null, null));
+ }
+
+ private Object eval (Boolean b1, Boolean b2) {
+ return new AndExpression (createLiteral (b1), createLiteral (b2), SOURCE_POS).evaluate (createEmptyExecutionContext());
+ }
+
+ @Test public void testShortcutEvaluation () {
+ assertEquals (false, new AndExpression (createLiteral (false), new ExceptionThrowingExpression(), SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ConcatExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ConcatExpressionTest.java
new file mode 100644
index 00000000..52ed5fe5
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ConcatExpressionTest.java
@@ -0,0 +1,42 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class ConcatExpressionTest {
+ @Test public void testLogic () {
+ assertEquals ("", eval ());
+ assertEquals ("abc", eval (createLiteral ("abc")));
+ assertEquals ("abc", eval (createLiteral ("a"), createLiteral ("b"), createLiteral ("c")));
+ assertEquals ("123", eval (createLiteral (1), createLiteral (2), createLiteral (3)));
+ assertEquals ("123", eval (createLiteral (1), createLiteral ("2"), createLiteral (3)));
+ assertEquals ("", eval (createLiteral (null)));
+ assertEquals ("a", eval (createLiteral (null), createLiteral ("a")));
+ }
+
+ private Object eval (ExpressionBase... parts) {
+ return new ConcatExpression (Arrays.asList(parts), SOURCE_POS).evaluate (createEmptyExecutionContext()).toString();
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateCachedExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateCachedExpressionTest.java
new file mode 100644
index 00000000..7444dc2e
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateCachedExpressionTest.java
@@ -0,0 +1,79 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.types.builtin.ListType;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class CreateCachedExpressionTest {
+ private ExecutionContext _ctx = null;
+
+ @Test public void testLogic () {
+ _ctx = createEmptyExecutionContext();
+
+ final List<Object> listNoKey = eval ();
+ final List<Object> listA = eval ("a");
+ final List<Object> listB = eval ("b");
+ final List<Object> listAB = eval ("a", "b");
+
+ listNoKey.add ("no key");
+ listA.add ("Aa");
+ listB.add ("Bb");
+ listAB.add ("AaBb");
+
+ assertSame (listNoKey, eval ());
+ assertSame (listA, eval ("a"));
+ assertSame (listB, eval ("b"));
+ assertSame (listAB, eval ("a", "b"));
+
+ assertEquals (1, eval().size());
+ assertEquals (1, eval("a").size());
+ assertEquals (1, eval("b").size());
+ assertEquals (1, eval("a", "b").size());
+
+ assertEquals ("no key", eval().get(0));
+ assertEquals ("Aa", eval("a").get(0));
+ assertEquals ("Bb", eval("b").get(0));
+ assertEquals ("AaBb", eval("a", "b").get(0));
+
+ _ctx = createEmptyExecutionContext();
+ assertNotSame (listNoKey, eval());
+ assertTrue (eval().isEmpty());
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Object> eval (Object... keys) {
+ final List<ExpressionBase> keyExpr = new ArrayList<ExpressionBase> ();
+ for (Object o: keys)
+ keyExpr.add (createLiteral (o));
+
+ return (List<Object>) new CreateCachedExpression (ListType.INSTANCE, keyExpr, SOURCE_POS).evaluate (_ctx);
+
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateUncachedExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateUncachedExpressionTest.java
new file mode 100644
index 00000000..a97629e1
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/CreateUncachedExpressionTest.java
@@ -0,0 +1,46 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.types.builtin.ListType;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class CreateUncachedExpressionTest {
+ private ExecutionContext _ctx = null;
+
+ @Test public void testLogic () {
+ _ctx = createEmptyExecutionContext();
+
+ final List<Object> l1 = eval ();
+ l1.add ("a");
+
+ assertNotSame (l1, eval());
+ assertTrue (eval ().isEmpty());
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Object> eval () {
+ return (List<Object>) new CreateUncachedExpression (ListType.INSTANCE, SOURCE_POS).evaluate (_ctx);
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpressionTest.java
new file mode 100644
index 00000000..b38c7ff8
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpressionTest.java
@@ -0,0 +1,44 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class HidingLocalVarDefExpressionTest {
+
+ @Test public void testLocalVar () {
+ final ExecutionContext outerCtx = createEmptyExecutionContext();
+ outerCtx.getLocalVarContext().getLocalVars().put ("a", "aValue");
+
+ final ExpressionBase expr = new HidingLocalVarDefExpression ("a", createLiteral("bValue"), new ExpressionBase (SOURCE_POS) {
+ @Override
+ protected Object evaluateInternal (ExecutionContext innerCtx) {
+ assertEquals ("bValue", innerCtx.getLocalVarContext().getLocalVars().get ("a"));
+ return "xyz";
+ }
+ }, SOURCE_POS);
+
+ assertEquals ("xyz", expr.evaluate (outerCtx));
+ assertEquals ("aValue", outerCtx.getLocalVarContext().getLocalVars().get ("a"));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/IfExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/IfExpressionTest.java
new file mode 100644
index 00000000..12a8e4cd
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/IfExpressionTest.java
@@ -0,0 +1,44 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.helpers.MutableLiteralExpression;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class IfExpressionTest {
+
+ @Test public void testLogic () {
+ final MutableLiteralExpression condExpression = new MutableLiteralExpression (true);
+ final ExpressionBase ifExpr = createLiteral ("ifBranch");
+ final ExpressionBase elseExpr = createLiteral ("elseBranch");
+
+ final IfExpression expr = new IfExpression (condExpression, ifExpr, elseExpr, SOURCE_POS);
+
+ assertEquals ("ifBranch", expr.evaluate (createEmptyExecutionContext()));
+
+ condExpression.setValue (false);
+ assertEquals ("elseBranch", expr.evaluate (createEmptyExecutionContext()));
+
+ condExpression.setValue (null);
+ assertEquals (null, expr.evaluate (createEmptyExecutionContext()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InitClosureExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InitClosureExpressionTest.java
new file mode 100644
index 00000000..64160b74
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InitClosureExpressionTest.java
@@ -0,0 +1,114 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipose.xtend.middleend.FunctionDefContextFactory;
+import org.eclipse.xtend.backend.BackendFacade;
+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.ExpressionBase;
+import org.eclipse.xtend.backend.common.Function;
+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.types.builtin.StringType;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class InitClosureExpressionTest {
+
+ /**
+ * test that the newly initialized closure actually has the correct number and type of parameters, and correctly binds the values to the right
+ * local variables in its body.
+ */
+ @Test public void testParameterBinding () {
+ final List<String> paramNames = Arrays.asList("a");
+ final List<StringType> paramTypes = Arrays.asList(StringType.INSTANCE);
+ final LocalVarEvalExpression body = new LocalVarEvalExpression ("a", SOURCE_POS);
+
+ final Function closure = (Function) new InitClosureExpression (paramNames, paramTypes, body, SOURCE_POS).evaluate (createEmptyExecutionContext());
+ assertEquals (1, closure.getParameterTypes().size());
+ assertEquals (StringType.INSTANCE, closure.getParameterTypes().get(0));
+
+ assertEquals ("xyz", closure.invoke(createEmptyExecutionContext(), new Object[] {"xyz"}));
+ assertEquals ("abc", closure.invoke(createEmptyExecutionContext(), new Object[] {"abc"}));
+ }
+
+
+ /**
+ * test that local variables that were in scope during the initialization of a closure are visible during its execution, even if that is in an
+ * entirely different scope.
+ */
+ @Test public void testLocalVariableBinding () {
+ final ExecutionContext initContext = createEmptyExecutionContext();
+ initContext.getLocalVarContext().getLocalVars().put ("a", "aValue");
+
+ final LocalVarEvalExpression body = new LocalVarEvalExpression ("a", SOURCE_POS);
+
+ final Function closure = (Function) new InitClosureExpression (new ArrayList<String>(), new ArrayList<BackendType>(), body, SOURCE_POS).evaluate (initContext);
+
+ assertEquals ("aValue", closure.invoke (createEmptyExecutionContext(), new Object[] {}));
+ }
+
+
+ /**
+ * test that functions visible during the initialization of a closure are callable in a different context where they are no longer in scope.
+ */
+ @Test public void testFdcPropagation () {
+ final BackendTypesystem ts = new CompositeTypesystem ();
+
+ final FunctionDefContextImpl fdc = new FunctionDefContextFactory (ts).create();
+ fdc.register (new NamedFunction ("myFunction", new Function () {
+
+ public ExpressionBase getGuard () {
+ return null;
+ }
+
+ public List<? extends BackendType> getParameterTypes () {
+ return new ArrayList<BackendType>();
+ }
+
+ public Object invoke (ExecutionContext ctx, Object[] params) {
+ return "myResult";
+ }
+
+ public boolean isCached () {
+ return false;
+ }
+
+ }));
+
+ final ExecutionContext initCtx = BackendFacade.createExecutionContext (fdc, ts);
+ final ExpressionBase body = new InvocationOnObjectExpression ("myFunction", new ArrayList<ExpressionBase> (), false, SOURCE_POS);
+ final Function closure = (Function) new InitClosureExpression (new ArrayList<String>(), new ArrayList<BackendType>(), body, SOURCE_POS).evaluate (initCtx);
+
+ assertEquals ("myResult", closure.invoke(createEmptyExecutionContext(), new Object[]{}));
+ }
+}
+
+
+
+
+
+
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnCollectionExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnCollectionExpressionTest.java
new file mode 100644
index 00000000..3cc2d3d6
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnCollectionExpressionTest.java
@@ -0,0 +1,32 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class InvocationOnCollectionExpressionTest {
+ @Test public void testInvocation () {
+ assertEquals (Arrays.asList (3L, 4L, 5L), new InvocationOnCollectionExpression (createLiteral (Arrays.asList(1L, 2L, 3L)), "operatorPlus", Arrays.asList (createLiteral (2L)), SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ assertEquals (null, new InvocationOnCollectionExpression (createLiteral (null), "operatorPlus", Arrays.asList (createLiteral (2L)), SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpressionTest.java
new file mode 100644
index 00000000..8a32985d
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnObjectExpressionTest.java
@@ -0,0 +1,42 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.*;
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class InvocationOnObjectExpressionTest {
+ @Test public void testInvocation () {
+ assertEquals (3L, new InvocationOnObjectExpression ("operatorPlus", Arrays.asList (createLiteral (1L), createLiteral (2L)), false, SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ assertEquals (3L, new InvocationOnObjectExpression ("operatorPlus", Arrays.asList (createLiteral (1L), createLiteral (2L)), true, SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ assertEquals (Arrays.asList (1L), new InvocationOnObjectExpression ("asList", Arrays.asList (createLiteral (Arrays.asList(1L))), false, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (Arrays.asList (1L), new InvocationOnObjectExpression ("asList", Arrays.asList (createLiteral (Arrays.asList(1L))), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+
+ assertEquals (null, new InvocationOnObjectExpression ("asList", Arrays.asList (createLiteral (null)), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (null, new InvocationOnObjectExpression ("operatorPlus", Arrays.asList (createLiteral (null), createLiteral (2L)), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+
+ try {
+ new InvocationOnObjectExpression ("operatorPlus", Arrays.asList (createLiteral (null), createLiteral (2L)), false, SOURCE_POS).evaluate (createEmptyExecutionContext());
+ fail ("exception expected");
+ }
+ catch (Exception exc) {
+ }
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpressionTest.java
new file mode 100644
index 00000000..4b118b61
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpressionTest.java
@@ -0,0 +1,60 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.Test;
+
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class InvocationOnWhateverExpressionTest {
+ @Test public void testInvocationOnObject () {
+ assertEquals (3L, new InvocationOnWhateverExpression ("operatorPlus", Arrays.asList (createLiteral (1L), createLiteral (2L)), false, SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ assertEquals (3L, new InvocationOnWhateverExpression ("operatorPlus", Arrays.asList (createLiteral (1L), createLiteral (2L)), true, SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ assertEquals (Arrays.asList (1L), new InvocationOnWhateverExpression ("asList", Arrays.asList (createLiteral (Arrays.asList(1L))), false, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (Arrays.asList (1L), new InvocationOnWhateverExpression ("asList", Arrays.asList (createLiteral (Arrays.asList(1L))), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+
+ assertEquals (Arrays.asList (Collections.singleton (1L)), new InvocationOnWhateverExpression ("asList", Arrays.asList (createLiteral (Collections.singleton (Collections.singleton (1L)))), false, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (Arrays.asList (Collections.singleton (1L)), new InvocationOnWhateverExpression ("asList", Arrays.asList (createLiteral (Collections.singleton (Collections.singleton (1L)))), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+
+ assertEquals (null, new InvocationOnWhateverExpression ("asList", Arrays.asList (createLiteral (null)), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (null, new InvocationOnWhateverExpression ("operatorPlus", Arrays.asList (createLiteral (null), createLiteral (2L)), true, SOURCE_POS).evaluate (createEmptyExecutionContext()));
+
+ try {
+ new InvocationOnWhateverExpression ("operatorPlus", Arrays.asList (createLiteral (null), createLiteral (2L)), false, SOURCE_POS).evaluate (createEmptyExecutionContext());
+ fail ("exception expected");
+ }
+ catch (Exception exc) {
+ }
+ }
+
+ @Test public void testPrecedenceOfCollectionOperation () {
+ assertEquals ("[1, 2, 3]4", new InvocationOnWhateverExpression ("operatorPlus", Arrays.asList (createLiteral (Arrays.asList (1L, 2L, 3L)), createLiteral (4L)), true, SOURCE_POS).evaluate (createEmptyExecutionContext ()).toString());
+ assertEquals ("[1, 2, 3]4", new InvocationOnWhateverExpression ("operatorPlus", Arrays.asList (createLiteral (Arrays.asList (1L, 2L, 3L)), createLiteral (4L)), false, SOURCE_POS).evaluate (createEmptyExecutionContext ()).toString());
+ }
+
+ @Test public void testInvocationOnCollection () {
+ assertEquals (Arrays.asList (1L, 2L, 3L), new InvocationOnWhateverExpression ("operatorMinus", Arrays.asList (createLiteral (Arrays.asList (3L, 4L, 5L)), createLiteral (2L)), true, SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ assertEquals (Arrays.asList (1L, 2L, 3L), new InvocationOnWhateverExpression ("operatorMinus", Arrays.asList (createLiteral (Arrays.asList (3L, 4L, 5L)), createLiteral (2L)), false, SOURCE_POS).evaluate (createEmptyExecutionContext ()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ListLiteralExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ListLiteralExpressionTest.java
new file mode 100644
index 00000000..67e54017
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/ListLiteralExpressionTest.java
@@ -0,0 +1,35 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class ListLiteralExpressionTest {
+
+ @Test public void testLogic () {
+ assertEquals (Arrays.asList (1L, 2L), new ListLiteralExpression (Arrays.asList (createLiteral (1L), createLiteral (2L)), SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (new ArrayList<Object>(), new ListLiteralExpression (new ArrayList<ExpressionBase> (), SOURCE_POS).evaluate(createEmptyExecutionContext()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LiteralExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LiteralExpressionTest.java
new file mode 100644
index 00000000..f6ab2fd2
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LiteralExpressionTest.java
@@ -0,0 +1,31 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class LiteralExpressionTest {
+
+ @Test public void testLogic () {
+ assertEquals (null, new LiteralExpression (null, SOURCE_POS).evaluate(createEmptyExecutionContext()));
+ assertEquals ("abc", new LiteralExpression ("abc", SOURCE_POS).evaluate(createEmptyExecutionContext()));
+ assertEquals (1L, new LiteralExpression (1L, SOURCE_POS).evaluate(createEmptyExecutionContext()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LocalVarEvalExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LocalVarEvalExpressionTest.java
new file mode 100644
index 00000000..5d66d582
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/LocalVarEvalExpressionTest.java
@@ -0,0 +1,35 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.junit.Test;
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class LocalVarEvalExpressionTest {
+
+ @Test public void testLogic () {
+ final ExecutionContext ctx = createEmptyExecutionContext();
+ ctx.getLocalVarContext().getLocalVars().put ("a", "aValue");
+ ctx.getLocalVarContext().getLocalVars().put ("b", "bValue");
+
+ assertEquals ("aValue", new LocalVarEvalExpression ("a", SOURCE_POS).evaluate (ctx));
+ assertEquals ("bValue", new LocalVarEvalExpression ("b", SOURCE_POS).evaluate (ctx));
+ assertEquals (null, new LocalVarEvalExpression ("c", SOURCE_POS).evaluate (ctx));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/NewLocalVarDefExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/NewLocalVarDefExpressionTest.java
new file mode 100644
index 00000000..ef136f36
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/NewLocalVarDefExpressionTest.java
@@ -0,0 +1,43 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.*;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class NewLocalVarDefExpressionTest {
+
+ @Test public void testLocalVar () {
+ final ExecutionContext outerCtx = createEmptyExecutionContext();
+
+ final ExpressionBase expr = new NewLocalVarDefExpression ("a", createLiteral("bValue"), new ExpressionBase (SOURCE_POS) {
+ @Override
+ protected Object evaluateInternal (ExecutionContext innerCtx) {
+ assertEquals ("bValue", innerCtx.getLocalVarContext().getLocalVars().get ("a"));
+ return "xyz";
+ }
+ }, SOURCE_POS);
+
+ assertEquals ("xyz", expr.evaluate (outerCtx));
+ assertFalse (outerCtx.getLocalVarContext().getLocalVars().containsKey ("a"));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/OrExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/OrExpressionTest.java
new file mode 100644
index 00000000..a5988c7c
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/OrExpressionTest.java
@@ -0,0 +1,45 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.*;
+import static org.junit.Assert.*;
+
+import org.eclipse.xtend.backend.helpers.ExceptionThrowingExpression;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class OrExpressionTest {
+ @Test public void testLogic () {
+ assertEquals (true, eval (true, true));
+ assertEquals (true, eval (true, false));
+ assertEquals (true, eval (false, true));
+ assertEquals (false, eval (false, false));
+
+ assertEquals (null, eval (null, false));
+ assertEquals (null, eval (null, true));
+ assertEquals (null, eval (false, null));
+ assertEquals (true, eval (true, null));
+ assertEquals (null, eval (null, null));
+ }
+
+ private Object eval (Boolean b1, Boolean b2) {
+ return new OrExpression (new LiteralExpression (b1, SOURCE_POS), new LiteralExpression (b2, SOURCE_POS), SOURCE_POS).evaluate (createEmptyExecutionContext());
+ }
+
+ @Test public void testShortcutEvaluation () {
+ assertEquals (true, new OrExpression (new LiteralExpression (true, SOURCE_POS), new ExceptionThrowingExpression(), SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnCollectionExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnCollectionExpressionTest.java
new file mode 100644
index 00000000..8365bed3
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnCollectionExpressionTest.java
@@ -0,0 +1,33 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.eclipse.xtend.backend.helpers.BeanWithSizeProperty;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class PropertyOnCollectionExpressionTest {
+ @Test public void testLogic () {
+ assertEquals (Arrays.asList (1L, 2L, 3L), new PropertyOnCollectionExpression (createLiteral (Arrays.asList ("a", "ab", "abc")), "length", SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ assertEquals (Arrays.asList (7L, 12L), new PropertyOnCollectionExpression (createLiteral (Arrays.asList (new BeanWithSizeProperty (7), new BeanWithSizeProperty (12))), "size", SOURCE_POS).evaluate (createEmptyExecutionContext()));
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpressionTest.java
new file mode 100644
index 00000000..7ce530fb
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnObjectExpressionTest.java
@@ -0,0 +1,37 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.eclipse.xtend.backend.helpers.BeanWithSizeProperty;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class PropertyOnObjectExpressionTest {
+ @Test public void testLogic () {
+ assertEquals (6L, eval (new BeanWithSizeProperty (6), "size"));
+ assertEquals (2L, eval (Arrays.asList (new BeanWithSizeProperty (7), new BeanWithSizeProperty (12)), "size"));
+ }
+
+ private Object eval (Object param, String propertyName) {
+ return new PropertyOnObjectExpression (createLiteral (param), propertyName, SOURCE_POS).evaluate (createEmptyExecutionContext());
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpressionTest.java
new file mode 100644
index 00000000..e8632654
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpressionTest.java
@@ -0,0 +1,40 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.eclipse.xtend.backend.helpers.BeanWithSizeProperty;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class PropertyOnWhateverExpressionTest {
+ @Test public void testLogic () {
+ assertEquals (6L, eval (new BeanWithSizeProperty (6), "size"));
+ assertEquals (2L, eval (Arrays.asList (new BeanWithSizeProperty (7), new BeanWithSizeProperty (12)), "size"));
+
+ assertEquals (Arrays.asList (1L, 2L, 3L), eval (Arrays.asList ("a", "ab", "abc"), "length"));
+ assertEquals (2L, eval (Arrays.asList (new BeanWithSizeProperty (7), new BeanWithSizeProperty (12)), "size"));
+ }
+
+ private Object eval (Object param, String propertyName) {
+ return new PropertyOnWhateverExpression (createLiteral (param), propertyName, SOURCE_POS).evaluate (createEmptyExecutionContext());
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SequenceExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SequenceExpressionTest.java
new file mode 100644
index 00000000..7f35df7b
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SequenceExpressionTest.java
@@ -0,0 +1,41 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.eclipse.xtend.backend.helpers.CheckEvaluationExpression;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class SequenceExpressionTest {
+ @Test public void testLogic () {
+ final CheckEvaluationExpression first = new CheckEvaluationExpression ("a");
+ final CheckEvaluationExpression second = new CheckEvaluationExpression ("b");
+ final CheckEvaluationExpression third = new CheckEvaluationExpression ("c");
+
+ final SequenceExpression se = new SequenceExpression (Arrays.asList(first, second, third), SOURCE_POS);
+
+ assertEquals ("c", se.evaluate (createEmptyExecutionContext()));
+ assertEquals (1, first._evalCounter);
+ assertEquals (1, second._evalCounter);
+ assertEquals (1, third._evalCounter);
+ }
+
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SetPropertyExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SetPropertyExpressionTest.java
new file mode 100644
index 00000000..578388d5
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SetPropertyExpressionTest.java
@@ -0,0 +1,52 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createLiteral;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+
+import org.eclipse.xtend.backend.common.ExecutionException;
+import org.eclipse.xtend.backend.helpers.BeanWithSizeProperty;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class SetPropertyExpressionTest {
+ @Test public void testReadWrite () {
+ final BeanWithSizeProperty bwsp = new BeanWithSizeProperty (5);
+
+ assertSame (bwsp, eval (bwsp, "size", 9L));
+ assertEquals (9L, bwsp.getSize());
+
+ assertSame (bwsp, eval (bwsp, "size", 3L));
+ assertEquals (3L, bwsp.getSize());
+
+ assertNull (eval (null, "abc", "newValue"));
+
+ try {
+ eval (new ArrayList<Object>(), "size", 9L);
+ fail ("exception expected");
+ }
+ catch (ExecutionException e) {
+ }
+ }
+
+ private Object eval (Object target, String propName, Object newValue) {
+ return new SetPropertyExpression (createLiteral (target), propName, createLiteral(newValue), SOURCE_POS).evaluate (createEmptyExecutionContext());
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SwitchExpressionTest.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SwitchExpressionTest.java
new file mode 100644
index 00000000..39fa9d67
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/expr/SwitchExpressionTest.java
@@ -0,0 +1,143 @@
+/*
+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.expr;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.SOURCE_POS;
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.createEmptyExecutionContext;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipose.xtend.middleend.FunctionDefContextFactory;
+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.common.NamedFunction;
+import org.eclipse.xtend.backend.functions.FunctionDefContextImpl;
+import org.eclipse.xtend.backend.helpers.CheckEvaluationExpression;
+import org.eclipse.xtend.backend.types.CompositeTypesystem;
+import org.eclipse.xtend.backend.types.builtin.StringType;
+import org.eclipse.xtend.backend.util.Pair;
+import org.junit.Test;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class SwitchExpressionTest {
+
+ @Test public void testLogic () {
+ final CheckEvaluationExpression switchExpr = new CheckEvaluationExpression ("a");
+
+ final CheckEvaluationExpression caseAExpr = new CheckEvaluationExpression ("a");
+ final CheckEvaluationExpression valueAExpr = new CheckEvaluationExpression ("aValue");
+
+ final CheckEvaluationExpression caseBExpr = new CheckEvaluationExpression ("b");
+ final CheckEvaluationExpression valueBExpr = new CheckEvaluationExpression ("bValue");
+
+ final CheckEvaluationExpression defaultExpr = new CheckEvaluationExpression ("defaultValue");
+
+ final List<Pair<ExpressionBase, ExpressionBase>> cases = new ArrayList<Pair<ExpressionBase,ExpressionBase>> ();
+ cases.add (new Pair<ExpressionBase, ExpressionBase> (caseAExpr, valueAExpr));
+ cases.add (new Pair<ExpressionBase, ExpressionBase> (caseBExpr, valueBExpr));
+
+ final SwitchExpression expr = new SwitchExpression (switchExpr, cases, defaultExpr, SOURCE_POS);
+
+ assertEquals ("aValue", expr.evaluate (createEmptyExecutionContext()));
+ assertEquals (1, switchExpr._evalCounter);
+ assertEquals (1, caseAExpr._evalCounter);
+ assertEquals (1, valueAExpr._evalCounter);
+ assertEquals (0, caseBExpr._evalCounter);
+ assertEquals (0, valueBExpr._evalCounter);
+ assertEquals (0, defaultExpr._evalCounter);
+
+ switchExpr._value = "b";
+ assertEquals ("bValue", expr.evaluate (createEmptyExecutionContext()));
+ assertEquals (2, switchExpr._evalCounter);
+ assertEquals (2, caseAExpr._evalCounter);
+ assertEquals (1, valueAExpr._evalCounter);
+ assertEquals (1, caseBExpr._evalCounter);
+ assertEquals (1, valueBExpr._evalCounter);
+ assertEquals (0, defaultExpr._evalCounter);
+
+ switchExpr._value = "c";
+ assertEquals ("defaultValue", expr.evaluate (createEmptyExecutionContext()));
+ assertEquals (3, switchExpr._evalCounter);
+ assertEquals (3, caseAExpr._evalCounter);
+ assertEquals (1, valueAExpr._evalCounter);
+ assertEquals (2, caseBExpr._evalCounter);
+ assertEquals (1, valueBExpr._evalCounter);
+ assertEquals (1, defaultExpr._evalCounter);
+
+ switchExpr._value = null;
+ assertEquals ("defaultValue", expr.evaluate (createEmptyExecutionContext()));
+ assertEquals (4, switchExpr._evalCounter);
+ assertEquals (4, caseAExpr._evalCounter);
+ assertEquals (1, valueAExpr._evalCounter);
+ assertEquals (3, caseBExpr._evalCounter);
+ assertEquals (1, valueBExpr._evalCounter);
+ assertEquals (2, defaultExpr._evalCounter);
+ }
+
+ @Test public void testUsesOperatorEquals () {
+ final CheckEvaluationExpression switchExpr = new CheckEvaluationExpression ("xyz");
+
+ final CheckEvaluationExpression caseAExpr = new CheckEvaluationExpression ("a");
+ final CheckEvaluationExpression valueAExpr = new CheckEvaluationExpression ("aValue");
+
+ final CheckEvaluationExpression defaultExpr = new CheckEvaluationExpression ("defaultValue");
+
+ final List<Pair<ExpressionBase, ExpressionBase>> cases = new ArrayList<Pair<ExpressionBase,ExpressionBase>> ();
+ cases.add (new Pair<ExpressionBase, ExpressionBase> (caseAExpr, valueAExpr));
+
+ final SwitchExpression expr = new SwitchExpression (switchExpr, cases, defaultExpr, SOURCE_POS);
+
+
+ // register an equals function that returns "true" for any two strings
+ final NamedFunction myStringEquals = new NamedFunction ("operatorEquals", new Function () {
+
+ public ExpressionBase getGuard () {
+ return null;
+ }
+
+ public List<? extends BackendType> getParameterTypes () {
+ return Arrays.asList(StringType.INSTANCE, StringType.INSTANCE);
+ }
+
+ public Object invoke (ExecutionContext ctx, Object[] params) {
+ System.err.println ("!!!");
+ return true;
+ }
+
+ public boolean isCached () {
+ return false;
+ }
+ });
+
+ final FunctionDefContextImpl fdc = new FunctionDefContextFactory (new CompositeTypesystem ()).create();
+ fdc.register (myStringEquals);
+
+ final ExecutionContext ctx = createEmptyExecutionContext();
+ assertEquals ("defaultValue", expr.evaluate (ctx));
+
+ ctx.setFunctionDefContext(fdc);
+ assertEquals ("aValue", expr.evaluate (ctx));
+ }
+}
+
+
+
+
+
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BackendTestHelper.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BackendTestHelper.java
new file mode 100644
index 00000000..1c928629
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BackendTestHelper.java
@@ -0,0 +1,47 @@
+/*
+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.helpers;
+
+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.SourcePos;
+import org.eclipse.xtend.backend.expr.LiteralExpression;
+import org.eclipse.xtend.backend.functions.FunctionDefContextImpl;
+import org.eclipse.xtend.backend.syslib.SyslibContributor;
+import org.eclipse.xtend.backend.types.CompositeTypesystem;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class BackendTestHelper {
+ public static final SourcePos SOURCE_POS = createSourcePos();
+
+ /**
+ * This method returns an ExecutionContext that is basically empty - no registered functions, and
+ * only the JavaBeansTypeSystem. It is useful for simple tests.
+ */
+ public static ExecutionContext createEmptyExecutionContext () {
+ final BackendTypesystem ts = new CompositeTypesystem ();
+ return BackendFacade.createExecutionContext (new FunctionDefContextImpl (new SyslibContributor (ts)), ts);
+ }
+
+ public static ExpressionBase createLiteral (Object literal) {
+ return new LiteralExpression (literal, SOURCE_POS);
+ }
+
+ public static SourcePos createSourcePos () {
+ return new SourcePos ("<no file>", "<no callable>", 0);
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BeanWithSizeProperty.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BeanWithSizeProperty.java
new file mode 100644
index 00000000..597c652a
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/BeanWithSizeProperty.java
@@ -0,0 +1,33 @@
+/*
+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.helpers;
+
+
+/**
+ * This bean class serves as support for the PropertyOn* tests.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class BeanWithSizeProperty {
+ private long _size;
+
+ public BeanWithSizeProperty (long size) {
+ _size = size;
+ }
+
+ public long getSize () {
+ return _size;
+ }
+
+ public void setSize (long size) {
+ _size = size;
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/CheckEvaluationExpression.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/CheckEvaluationExpression.java
new file mode 100644
index 00000000..aaf830e4
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/CheckEvaluationExpression.java
@@ -0,0 +1,39 @@
+/*
+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.helpers;
+
+import static org.eclipse.xtend.backend.helpers.BackendTestHelper.*;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+
+
+/**
+ * This expression class serves as a mock implementation to test that an
+ * expression was actually evaluated.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class CheckEvaluationExpression extends ExpressionBase{
+ public Object _value;
+ public int _evalCounter = 0;
+
+ public CheckEvaluationExpression (Object value) {
+ super (SOURCE_POS);
+ _value = value;
+ }
+
+ @Override
+ protected Object evaluateInternal (ExecutionContext ctx) {
+ _evalCounter++;
+ return _value;
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/ExceptionThrowingExpression.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/ExceptionThrowingExpression.java
new file mode 100644
index 00000000..5cb6ae8c
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/ExceptionThrowingExpression.java
@@ -0,0 +1,30 @@
+/*
+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.helpers;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class ExceptionThrowingExpression extends ExpressionBase {
+ public ExceptionThrowingExpression () {
+ super (BackendTestHelper.SOURCE_POS);
+ }
+
+ @Override
+ protected Object evaluateInternal (ExecutionContext ctx) {
+ throw new UnsupportedOperationException ("this expression can not be evaluated");
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/MutableLiteralExpression.java b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/MutableLiteralExpression.java
new file mode 100644
index 00000000..cd4ad5cf
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/src/org/eclipse/xtend/backend/helpers/MutableLiteralExpression.java
@@ -0,0 +1,38 @@
+/*
+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.helpers;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public class MutableLiteralExpression extends ExpressionBase {
+ private Object _value;
+
+ public MutableLiteralExpression (Object value) {
+ super (BackendTestHelper.SOURCE_POS);
+
+ _value = value;
+ }
+
+ public void setValue (Object value) {
+ _value = value;
+ }
+
+ @Override
+ protected Object evaluateInternal (ExecutionContext ctx) {
+ return _value;
+ }
+}
diff --git a/tests/org.eclipse.xtend.backend.test/todo.txt b/tests/org.eclipse.xtend.backend.test/todo.txt
new file mode 100644
index 00000000..ce1bffa2
--- /dev/null
+++ b/tests/org.eclipse.xtend.backend.test/todo.txt
@@ -0,0 +1,23 @@
+todo
+----
+properties are inherited (--> List.size)
+overwriting of extensions, e.g. syslib
+eine Instanz je JavaDefinedFunction-Klasse
+creation cache
+immutable auf cached-ergebnis
+polymorphic resolver
+efficientLazyString: streaming
+Java-Type <--> Cacnonical type
+expression-Implementierungen
+Aufruf der Listener
+CurriedFunction, CurryingExpression
+GlobalParamExpression
+Verwendung von syslib für toString: ConcatExpression, operatorPlus,
+
+
+syslib-Implementierungen
+Schreiben in Files
+
+Xpand und Xtend: Middleends...
+
+

Back to the top