diff options
author | ahaase | 2008-01-31 21:03:09 +0000 |
---|---|---|
committer | ahaase | 2008-01-31 21:03:09 +0000 |
commit | a343b56857b67317dced1afc2100ded643a7bb75 (patch) | |
tree | 4de7d48c7edfb770308ffe5889428efe0f6015c6 | |
parent | bcc5d9362ddc447234a3f485f7a899703aaf8cee (diff) | |
download | org.eclipse.xpand-a343b56857b67317dced1afc2100ded643a7bb75.tar.gz org.eclipse.xpand-a343b56857b67317dced1afc2100ded643a7bb75.tar.xz org.eclipse.xpand-a343b56857b67317dced1afc2100ded643a7bb75.zip |
added tests for the expression implementations
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... + + |