From 635ee810675b8950d11f6518179e26595d62800d Mon Sep 17 00:00:00 2001 From: jkohnlein Date: Thu, 12 Feb 2009 10:26:53 +0000 Subject: patch applied https://bugs.eclipse.org/bugs/show_bug.cgi?id=264564 --- .../src/org/eclipse/xtend/AllTests.java | 1 + .../org/eclipse/xtend/ExtensionEvaluationTest.java | 11 +- .../xtend/JavaExtensionTypeConversionTest.java | 179 +++++++++++++++++++++ .../xtend/expression/ast/EvaluationTest.java | 17 +- .../xtend/typesystem/baseimpl/types/AllTests.java | 1 + .../baseimpl/types/CollectionTypeTest.java | 25 +-- .../typesystem/baseimpl/types/IntegerTypeTest.java | 130 ++++++++++++++- .../baseimpl/types/RealAndIntegerTeamplayTest.java | 108 +++++++++++++ .../typesystem/baseimpl/types/StringTypeTest.java | 4 +- .../xtend/expression/ast/IntegerLiteral.java | 6 +- .../xtend/type/baseimpl/types/IntegerTypeImpl.java | 141 ++++++++-------- .../xtend/type/baseimpl/types/StringTypeImpl.java | 5 +- .../xtend/xtend/ast/JavaExtensionStatement.java | 18 ++- 13 files changed, 537 insertions(+), 109 deletions(-) create mode 100644 plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/JavaExtensionTypeConversionTest.java create mode 100644 plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/RealAndIntegerTeamplayTest.java diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/AllTests.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/AllTests.java index 77949265..185b841b 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/AllTests.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/AllTests.java @@ -20,6 +20,7 @@ public class AllTests { suite.addTestSuite(XtendFacadeTest.class); suite.addTestSuite(XtendComponentTest.class); suite.addTestSuite(ExtensionEvaluationTest.class); + suite.addTestSuite(JavaExtensionTypeConversionTest.class); //$JUnit-END$ return suite; } diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/ExtensionEvaluationTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/ExtensionEvaluationTest.java index f8f0a76d..d5c67cff 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/ExtensionEvaluationTest.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/ExtensionEvaluationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -12,6 +12,7 @@ package org.eclipse.xtend; import java.io.StringReader; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -96,12 +97,12 @@ public class ExtensionEvaluationTest extends TestCase { ec = (ExecutionContextImpl) ec.cloneWithResource(file); - final Extension ext = ec.getExtension("recExtension", new Object[] { new Long(5), new Long(10) }); - final List expected = new ArrayList(); + final Extension ext = ec.getExtension("recExtension", new Object[] { new BigInteger("5"), new BigInteger("10") }); + final List expected = new ArrayList(); for (int i = 5; i <= 10; i++) { - expected.add(new Long(i)); + expected.add(new BigInteger(""+i)); } - final Object evalResult = ext.evaluate(new Object[] { new Long(5), new Long(10) }, ec); + final Object evalResult = ext.evaluate(new Object[] { new BigInteger("5"), new BigInteger("10") }, ec); assertEquals(expected, evalResult); } diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/JavaExtensionTypeConversionTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/JavaExtensionTypeConversionTest.java new file mode 100644 index 00000000..692deb2f --- /dev/null +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/JavaExtensionTypeConversionTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others. + * 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 + *******************************************************************************/ +package org.eclipse.xtend; + +import java.io.StringReader; +import java.math.BigDecimal; +import java.math.BigInteger; + +import junit.framework.TestCase; + +import org.eclipse.internal.xtend.type.impl.java.JavaMetaModel; +import org.eclipse.internal.xtend.type.impl.java.beans.JavaBeansStrategy; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.parser.ParseFacade; +import org.eclipse.xtend.expression.EvaluationException; +import org.eclipse.xtend.expression.ExecutionContextImpl; +import org.eclipse.xtend.expression.ExpressionFacade; + +/** + * @author Heiko Behrens - Initial contribution and API + */ +public class JavaExtensionTypeConversionTest extends TestCase { + + ExecutionContextImpl ec; + + private ExpressionFacade ef; + + @Override + protected void setUp() throws Exception { + ec = new ExecutionContextImpl(); + ec.registerMetaModel(new JavaMetaModel("asdf", new JavaBeansStrategy())); + ef = new ExpressionFacade(ec); + } + + protected void registerExtensions(String extensions) { + final ExtensionFile file = ParseFacade.file(new StringReader( + extensions + ), "nofile"); + ec = (ExecutionContextImpl) ec.cloneWithResource(file); + ef = new ExpressionFacade(ec); + } + + protected void assertExpressionValue(String expected, String expression) { + Object actual = ef.evaluate(expression); + assertEquals(expected, actual.toString()); + } + + public static String staticTestInteger(Byte param) { + return "Byte " + param; + } + + public static String staticTestInteger(Short param) { + return "Short " + param; + } + + public static String staticTestInteger(Integer param) { + return "Integer " + param; + } + + public static String staticTestInteger(Long param) { + return "Long " + param; + } + + public static String staticTestInteger(BigInteger param) { + return "BigInteger " + param; + } + + public void testInteger() { + registerExtensions( + "String testByte(Integer param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestInteger(java.lang.Byte) ; \n" + + "String testShort(Integer param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestInteger(java.lang.Short) ; \n" + + "String testInteger(Integer param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestInteger(java.lang.Integer) ; \n" + + "String testLong(Integer param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestInteger(java.lang.Long) ; \n" + + "String testBigInteger(Integer param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestInteger(java.math.BigInteger) ; \n" + ); + + // since the implementation of IntegerTypeImpl is based on BigDecimal + // the implicit type conversion greatly illustrates how the significant + // bits are cut off + assertExpressionValue("Byte 42", "testByte(42)"); + assertExpressionValue("Byte 0", "testByte(256)"); + assertExpressionValue("Short 256", "testShort(256)"); + assertExpressionValue("Short 0", "testShort(65536)"); + assertExpressionValue("Integer 65536", "testInteger(65536)"); + assertExpressionValue("Integer 0", "testInteger(4294967296)"); + assertExpressionValue("Long 4294967296", "testLong(4294967296)"); + assertExpressionValue("Long 0", "testLong(18446744073709551616)"); + assertExpressionValue("BigInteger 18446744073709551616", "testBigInteger(18446744073709551616)"); + } + + public static String staticTestReal(Float param) { + return "Float " + param; + } + + public static String staticTestReal(Double param) { + return "Double " + param; + } + + public static String staticTestReal(BigDecimal param) { + return "BigDecimal " + param; + } + + public void testReal() { + registerExtensions( + "String testFloat(Real param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestReal(java.lang.Float) ; \n" + + "String testDouble(Real param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestReal(java.lang.Double) ; \n" + + "String testBigDecimal(Real param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestReal(java.math.BigDecimal) ; \n" + ); + + assertExpressionValue("Float 137.0", "testFloat(137.0)"); + assertExpressionValue("Double 137.0", "testDouble(137.0)"); + assertExpressionValue("BigDecimal 137", "testBigDecimal(137.0)"); + } + + public static String staticTestString(Character param) { + return "Char " + param; + } + + public static String staticTestString(String param) { + return "String " + param; + } + + public static String staticTestString(StringBuffer param) { + return "StringBuffer " + param; + } + + public void testString() { + registerExtensions( + "String testCharacter(String param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestString(java.lang.Character) ; \n" + + "String testString(String param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestString(java.lang.String) ; \n" + + "String testStringBuffer(String param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestString(java.lang.StringBuffer) ; \n" + ); + + assertExpressionValue("Char A", "testCharacter('A')"); + try { + assertExpressionValue("Char A", "testCharacter('AB')"); + fail("Implicit String conversion to Character should not be allows for Strings with length different from 1"); + } catch (EvaluationException e){ + // expected + } + assertExpressionValue("String AB", "testString('AB')"); + assertExpressionValue("StringBuffer ABC", "testStringBuffer('ABC')"); + } + + public static String staticTestMultipleParams(Byte b, Float f, Character c) { + return "" + b + " " + f + " " + c; + } + + public void testMultipleParams() { + registerExtensions( + "String testMultipleParams(Integer i, Real r, String s) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticTestMultipleParams(java.lang.Byte, java.lang.Float, java.lang.Character) ; \n" + ); + assertExpressionValue("1 2.0 A", "testMultipleParams(1, 2.0, 'A')"); + } + + public static Long staticReturnLong(Long param) { + return param; + } + + public static Character staticReturnCharacter(String param) { + return param.charAt(0); + } + + public void testReturnType() { + registerExtensions( + "Integer returnLong(Integer param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticReturnLong(java.lang.Long) ; \n" + + "String returnCharacter(String param) : JAVA org.eclipse.xtend.JavaExtensionTypeConversionTest.staticReturnCharacter(java.lang.String) ; \n" + ); + + assertExpressionValue("42", "returnLong(42 - 1) + 1"); + assertExpressionValue("AB", "returnCharacter('AB'.subString(0,1)) + 'B' "); + } + +} diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/expression/ast/EvaluationTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/expression/ast/EvaluationTest.java index 78f0efed..5be3cd8e 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/expression/ast/EvaluationTest.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/expression/ast/EvaluationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -11,6 +11,7 @@ package org.eclipse.xtend.expression.ast; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -115,8 +116,8 @@ public class EvaluationTest extends TestCase { @SuppressWarnings("unchecked") public final void testCollectionLiteral1() { assertEquals(Arrays.asList("hallo"), eval ("{\"hallo\"}")); - assertEquals(Arrays.asList(3L), eval ("{3}")); - assertEquals (Arrays.asList("hallo", 3L), eval ("{\"hallo\",3}")); + assertEquals(Arrays.asList(new BigInteger("3")), eval ("{3}")); + assertEquals (Arrays.asList("hallo", new BigInteger("3")), eval ("{\"hallo\",3}")); } public final void testFeatureCall() { @@ -150,16 +151,16 @@ public class EvaluationTest extends TestCase { } public final void testArithmetic() { - assertEquals(new Long(11), eval ("4 * 2 + 3")); - assertEquals(new Long(11), eval ("3 + 4 * 2")); - assertEquals(new Long(9), eval ("4 * 2 + 3 / 3")); - assertEquals(new Long(4), eval ("4 * 2 - (9 / 2)")); + assertEquals(new BigInteger("11"), eval ("4 * 2 + 3")); + assertEquals(new BigInteger("11"), eval ("3 + 4 * 2")); + assertEquals(new BigInteger("9"), eval ("4 * 2 + 3 / 3")); + assertEquals(new BigInteger("4"), eval ("4 * 2 - (9 / 2)")); assertEquals(new Double(11), eval ("3 + 4.0 * 2")); assertEquals(new Double(11), eval ("4.0 * 2 + 3")); assertEquals(new Double(9), eval ("4 * 2 + 3 / 3.0")); - assertEquals(new Long(2), eval ("5 / 2")); + assertEquals(new BigInteger("2"), eval ("5 / 2")); assertEquals(new Double(2.5), eval ("5 / 2.0")); } diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/AllTests.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/AllTests.java index 3be695f8..b5be6260 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/AllTests.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/AllTests.java @@ -17,6 +17,7 @@ public class AllTests { suite.addTestSuite(StringTypeTest.class); suite.addTestSuite(EnumTest.class); suite.addTestSuite(BooleanTypeTest.class); + suite.addTestSuite(RealAndIntegerTeamplayTest.class); //$JUnit-END$ return suite; } diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/CollectionTypeTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/CollectionTypeTest.java index 6d3cd424..4ae3f89d 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/CollectionTypeTest.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/CollectionTypeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.xtend.typesystem.baseimpl.types; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -67,7 +68,7 @@ public class CollectionTypeTest extends TestCase { public final void testToSet() { final Set result = (Set) ef.evaluate("{1,2,3}.toSet()"); assertEquals(3, result.size()); - assertTrue(result.contains(new Long(2))); + assertTrue(result.contains(new BigInteger("2"))); } public final void testSize() { @@ -93,28 +94,28 @@ public class CollectionTypeTest extends TestCase { } public final void testFirst() { - assertEquals(1l, ef.evaluate("{1,2,3}.first()")); + assertEquals(BigInteger.ONE, ef.evaluate("{1,2,3}.first()")); assertEquals(null, ef.evaluate("{}.first()")); assertEquals(null, ef.evaluate("null.first()")); } public final void testLast() { - assertEquals(3l, ef.evaluate("{1,2,3}.last()")); + assertEquals(new BigInteger("3"), ef.evaluate("{1,2,3}.last()")); assertNull(ef.evaluate("{}.last()")); assertNull(ef.evaluate("null.last()")); } public final void testReverse() { - assertEquals(3l, ef.evaluate("{1,2,3}.reverse().first()")); - assertEquals(1l, ef.evaluate("{1,2,3}.reverse().reverse().first()")); + assertEquals(new BigInteger("3"), ef.evaluate("{1,2,3}.reverse().first()")); + assertEquals(BigInteger.ONE, ef.evaluate("{1,2,3}.reverse().reverse().first()")); assertTrue(((List) ef.evaluate("{}.reverse()")).isEmpty()); assertNull(ef.evaluate("null.reverse()")); } public final void testWithoutFirst() { - List l = new ArrayList(); - l.add(2l); - l.add(3l); + List l = new ArrayList(); + l.add(new BigInteger("2")); + l.add(new BigInteger("3")); assertEquals(l, ef.evaluate("{1,2,3}.withoutFirst()")); assertEquals(Collections.EMPTY_LIST, ef.evaluate("{1}.withoutFirst()")); assertEquals(Collections.EMPTY_LIST, ef.evaluate("{}.withoutFirst()")); @@ -122,9 +123,9 @@ public class CollectionTypeTest extends TestCase { } public final void testWithoutLast() { - List l = new ArrayList(); - l.add(1l); - l.add(2l); + List l = new ArrayList(); + l.add(BigInteger.ONE); + l.add(new BigInteger("2")); assertEquals(l, ef.evaluate("{1,2,3}.withoutLast()")); assertEquals(Collections.EMPTY_LIST, ef.evaluate("{1}.withoutLast()")); assertEquals(Collections.EMPTY_LIST, ef.evaluate("{}.withoutLast()")); diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/IntegerTypeTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/IntegerTypeTest.java index 73d9056e..bec38c12 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/IntegerTypeTest.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/IntegerTypeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.xtend.typesystem.baseimpl.types; +import java.io.StringReader; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -18,9 +20,16 @@ import junit.framework.TestCase; import org.eclipse.internal.xtend.type.impl.java.JavaMetaModel; import org.eclipse.internal.xtend.type.impl.java.beans.JavaBeansStrategy; +import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; +import org.eclipse.internal.xtend.xtend.parser.ParseFacade; import org.eclipse.xtend.expression.ExecutionContextImpl; import org.eclipse.xtend.expression.ExpressionFacade; +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Heiko Behrens + */ public class IntegerTypeTest extends TestCase { ExecutionContextImpl ec; @@ -34,15 +43,33 @@ public class IntegerTypeTest extends TestCase { ef = new ExpressionFacade(ec); } - public final void testUpTo1() { + protected void assertExpressionValue(String expected, String expression) { + Object actual = ef.evaluate(expression); + assertEquals(expected, actual.toString()); + } + + @SuppressWarnings("unchecked") + public final void testUpTo1() { final List r = (List) ef.evaluate("1.upTo(5)", Collections.EMPTY_MAP); - final List c = new ArrayList(); + final List c = new ArrayList(); for (int i = 1; i <= 5; i++) { - c.add(new Long(i)); + c.add(new BigInteger("" + i)); } assertEquals(c, r); } + @SuppressWarnings("unchecked") + public final void testUpToWithStepping() { + final List r = (List) ef.evaluate("1.upTo(10, 2)", Collections.EMPTY_MAP); + final List c = new ArrayList(); + c.add(new BigInteger("1")); + c.add(new BigInteger("3")); + c.add(new BigInteger("5")); + c.add(new BigInteger("7")); + c.add(new BigInteger("9")); + assertEquals(c, r); + } + public void testBug172154Equals() { Boolean result = (Boolean) ef.evaluate("1==null"); assertNotNull(result); @@ -54,4 +81,99 @@ public class IntegerTypeTest extends TestCase { assertNotNull(result); assertTrue(result.booleanValue()); } + + public void testLiteral() { + assertExpressionValue("1", "1"); + assertExpressionValue("9223372036854775807", "9223372036854775807"); + assertExpressionValue("9223372036854775808", "9223372036854775808"); + assertIsBigInt("1"); + } + + public void testNegate() { + assertExpressionValue("-1", "-1"); + assertExpressionValue("1", "-(-1)"); + assertExpressionValue("-9223372036854775808", "-9223372036854775808"); + assertExpressionValue("-9223372036854775809", "-9223372036854775809"); + assertIsBigInt("-1"); + } + + private void assertIsBigInt(String expression) { + Object result = ef.evaluate(expression); + assertEquals(BigInteger.class.getName(), result.getClass().getName()); + } + + public void testAdd() { + assertExpressionValue("2", "1 + 1"); + assertExpressionValue("9223372036854775808", "9223372036854775807 + 1"); + assertIsBigInt("1 + 1"); + } + + public void testSubtract() { + assertExpressionValue("-1", "1 - 2"); + assertExpressionValue("-9223372036854775809", "-9223372036854775808 - 1"); + assertIsBigInt("1 - 2"); + } + final static String TWO_POW_64 = "18446744073709551616"; + final static String TWO_POW_128 = "340282366920938463463374607431768211456"; + + public void testMultiply() { + assertExpressionValue("0", "42 * 0"); + assertExpressionValue("42", "42 * 1"); + assertExpressionValue(TWO_POW_128, TWO_POW_64 + " * " + TWO_POW_64); + assertIsBigInt("1 * 1"); + } + + public void testDivide() { + assertExpressionValue("0", "0 / 42"); + assertExpressionValue("1", "42 / 42"); + assertExpressionValue(TWO_POW_64, TWO_POW_128 + " / " + TWO_POW_64); + assertIsBigInt("1 / 1"); + } + + public void testEquals() { + assertExpressionValue("true", "1 == 1"); + assertExpressionValue("false", "1 == 0"); + assertExpressionValue("false", "9223372036854775808 == -9223372036854775808"); + assertExpressionValue("true", "9223372036854775808 == 9223372036854775808"); + } + + public void testNotEquals() { + assertExpressionValue("false", "1 != 1"); + assertExpressionValue("true", "1 != 0"); + assertExpressionValue("true", "9223372036854775808 != -9223372036854775808"); + assertExpressionValue("false", "9223372036854775808 != 9223372036854775808"); + } + + public void testGreaterThan() { + assertExpressionValue("true", "1 > 0"); + assertExpressionValue("false", "0 > 0"); + assertExpressionValue("false", "0 > 1"); + assertExpressionValue("true", "9223372036854775808 > 0"); + } + + public void testGreaterThanOrEqual() { + assertExpressionValue("true", "1 >= 0"); + assertExpressionValue("true", "1 >= 1"); + assertExpressionValue("true", "0 >= 0"); + assertExpressionValue("false", "0 >= 1"); + assertExpressionValue("true", "9223372036854775808 >= 0"); + assertExpressionValue("true", "9223372036854775808 >= 9223372036854775808"); + } + + public void testLessThan() { + assertExpressionValue("true", "0 < 1"); + assertExpressionValue("false", "0 < 0"); + assertExpressionValue("false", "1 < 0"); + assertExpressionValue("true", "0 < 9223372036854775808"); + } + + public void testLessThanOrEqual() { + assertExpressionValue("true", "0 <= 1"); + assertExpressionValue("true", "1 <= 1"); + assertExpressionValue("true", "0 <= 0"); + assertExpressionValue("false", "1 <= 0"); + assertExpressionValue("true", "0 <= 9223372036854775808"); + assertExpressionValue("true", "9223372036854775808 <= 9223372036854775808"); + } + } diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/RealAndIntegerTeamplayTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/RealAndIntegerTeamplayTest.java new file mode 100644 index 00000000..04e91b29 --- /dev/null +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/RealAndIntegerTeamplayTest.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others. + * 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 + *******************************************************************************/ +package org.eclipse.xtend.typesystem.baseimpl.types; + +import org.eclipse.internal.xtend.type.impl.java.JavaMetaModel; +import org.eclipse.internal.xtend.type.impl.java.beans.JavaBeansStrategy; +import org.eclipse.xtend.expression.ExecutionContextImpl; +import org.eclipse.xtend.expression.ExpressionFacade; + +import junit.framework.TestCase; + +/** + * @author Heiko Behrens - Initial contribution and API + */ +public class RealAndIntegerTeamplayTest extends TestCase { + + ExecutionContextImpl ec; + + private ExpressionFacade ef; + + @Override + protected void setUp() throws Exception { + ec = new ExecutionContextImpl(); + ec.registerMetaModel(new JavaMetaModel("asdf", new JavaBeansStrategy())); + ef = new ExpressionFacade(ec); + } + + protected void assertExpressionValue(String expected, String expression) { + Object actual = ef.evaluate(expression); + assertEquals(expected, actual.toString()); + } + + public void testAdd() throws Exception { + assertExpressionValue("3.0", "1 + 2.0"); + assertExpressionValue("3.0", "2.0 + 1"); + } + + public void testSubtract() throws Exception { + assertExpressionValue("1.0", "2 - 1.0"); + assertExpressionValue("1.0", "2.0 - 1"); + } + + public void testMultiply() throws Exception { + assertExpressionValue("2.0", "1 * 2.0"); + assertExpressionValue("2.0", "2.0 * 1"); + } + + public void testDivide() throws Exception { + assertExpressionValue("2.0", "4 / 2.0"); + assertExpressionValue("2.0", "4.0 / 2"); + } + + public void testEquals() throws Exception { + assertExpressionValue("true", "1 == 1.0"); + assertExpressionValue("false", "1 == 2.0"); + assertExpressionValue("true", "1.0 == 1"); + assertExpressionValue("false", "1.0 == 2"); + } + + public void testNotEquals() throws Exception { + assertExpressionValue("false", "1 != 1.0"); + assertExpressionValue("true", "1 != 2.0"); + assertExpressionValue("false", "1.0 != 1"); + assertExpressionValue("true", "1.0 != 2"); + } + + public void testGreaterThan() throws Exception { + assertExpressionValue("true", "2 > 1.0"); + assertExpressionValue("false", "2 > 2.0"); + assertExpressionValue("false", "2 > 3.0"); + assertExpressionValue("true", "2.0 > 1"); + assertExpressionValue("false", "2.0 > 2"); + assertExpressionValue("false", "2.0 > 3"); + } + + public void testGreaterThanOrEqual() throws Exception { + assertExpressionValue("true", "2 >= 1.0"); + assertExpressionValue("true", "2 >= 2.0"); + assertExpressionValue("false", "2 >= 3.0"); + assertExpressionValue("true", "2.0 >= 1"); + assertExpressionValue("true", "2.0 >= 2"); + assertExpressionValue("false", "2.0 >= 3"); + } + + public void testLessThan() throws Exception { + assertExpressionValue("true", "1 < 2.0"); + assertExpressionValue("false", "2 < 2.0"); + assertExpressionValue("false", "3 < 2.0"); + assertExpressionValue("true", "1.0 < 2"); + assertExpressionValue("false", "2.0 < 2"); + assertExpressionValue("false", "3.0 < 2"); + } + + public void testLessOrEqual() throws Exception { + assertExpressionValue("true", "1 <= 2.0"); + assertExpressionValue("true", "2 <= 2.0"); + assertExpressionValue("false", "3 <= 2.0"); + assertExpressionValue("true", "1.0 <= 2"); + assertExpressionValue("true", "2.0 <= 2"); + assertExpressionValue("false", "3.0 <= 2"); + } + +} diff --git a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/StringTypeTest.java b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/StringTypeTest.java index d3f4743c..e638403c 100644 --- a/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/StringTypeTest.java +++ b/plugins/org.eclipse.xtend.tests/src/org/eclipse/xtend/typesystem/baseimpl/types/StringTypeTest.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.xtend.typesystem.baseimpl.types; +import java.math.BigInteger; + import junit.framework.TestCase; import org.eclipse.xtend.expression.ExecutionContextImpl; @@ -33,7 +35,7 @@ public class StringTypeTest extends TestCase { } public final void testAsInteger() { - assertEquals(new Integer(42),ef.evaluate("'42'.asInteger()")); + assertEquals(new BigInteger("42"),ef.evaluate("'42'.asInteger()")); } public final void testSplit() { diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java index 9e39efe0..00ff9323 100644 --- a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/expression/ast/IntegerLiteral.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -11,6 +11,7 @@ package org.eclipse.internal.xtend.expression.ast; +import java.math.BigInteger; import java.util.Set; import org.eclipse.xtend.expression.AnalysationIssue; @@ -20,6 +21,7 @@ import org.eclipse.xtend.typesystem.Type; /** * @author Sven Efftinge (http://www.efftinge.de) * @author Arno Haase + * @author Heiko Behrens */ public class IntegerLiteral extends Literal { @@ -29,7 +31,7 @@ public class IntegerLiteral extends Literal { @Override public Object evaluateInternal(final ExecutionContext ctx) { - return new Long(getLiteralValue().getValue()); + return new BigInteger(getLiteralValue().getValue()); } public Type analyzeInternal(final ExecutionContext ctx, final Set issues) { diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java index abe66283..538b590a 100644 --- a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/IntegerTypeImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -22,6 +22,11 @@ import org.eclipse.xtend.expression.TypeSystem; import org.eclipse.xtend.typesystem.Feature; import org.eclipse.xtend.typesystem.Type; +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Heiko Behrens + */ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { public IntegerTypeImpl(final TypeSystem ts, final String name) { @@ -29,12 +34,12 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { } public boolean isInstance(final Object o) { - return o instanceof Integer || o instanceof BigInteger || o instanceof Byte || o instanceof Long + return o instanceof BigInteger || o instanceof Integer || o instanceof Byte || o instanceof Long || o instanceof Short; } public Object newInstance() { - return new Long(-1); + return new BigInteger("-1"); } @Override @@ -45,7 +50,7 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { public Object evaluateInternal(final Object target, final Object[] params) { if (params[0] == null) return null; - return new Long(((Number) target).longValue() + ((Number) params[0]).longValue()); + return toInt(target).add(toInt(params[0])); } }, new OperationImpl(this, "-", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { @@ -53,13 +58,13 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { public Object evaluateInternal(final Object target, final Object[] params) { if (params[0] == null) return null; - return new Long(((Number) target).longValue() - ((Number) params[0]).longValue()); + return toInt(target).subtract(toInt(params[0])); } }, new OperationImpl(this, "-", IntegerTypeImpl.this, new Type[] {}) { @Override public Object evaluateInternal(final Object target, final Object[] params) { - return new Long(((Number) target).longValue() * -1l); + return toInt(target).negate(); } }, new OperationImpl(this, "*", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { @@ -68,7 +73,7 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { if (params[0] == null) return null; - return new Long(((Number) target).longValue() * ((Number) params[0]).longValue()); + return toInt(target).multiply(toInt(params[0])); } }, new OperationImpl(this, "/", IntegerTypeImpl.this, new Type[] { IntegerTypeImpl.this }) { @@ -77,48 +82,38 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { if (params[0] == null) return null; - return new Long(((Number) target).longValue() / ((Number) params[0]).longValue()); + return toInt(target).divide(toInt(params[0])); } }, - new OperationImpl(this, "==", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() - .getObjectType() }) { + new OperationImpl(this, "==", getTypeSystem().getBooleanType(), new Type[] { IntegerTypeImpl.this }) { @Override public Object evaluateInternal(final Object target, final Object[] params) { if (target == null) return new Boolean(target == params[0]); - try { - return toLong(target).equals(toLong(params[0])); + return toInt(target).equals(toInt(params[0])); } catch (Exception exc) { - if (target instanceof Number && params[0] instanceof Number) - return ((Number) target).doubleValue() == ((Number) params[0]).doubleValue(); - return false; } } }, - new OperationImpl(this, "!=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() - .getObjectType() }) { + new OperationImpl(this, "!=", getTypeSystem().getBooleanType(), new Type[] { IntegerTypeImpl.this }) { @Override public Object evaluateInternal(final Object target, final Object[] params) { if (target == null) return params[0] != null; try { - return ! toLong(target).equals(toLong(params[0])); + return ! toInt(target).equals(toInt(params[0])); } catch (Exception exc) { - if (target instanceof Number && params[0] instanceof Number) - return ((Number) target).doubleValue() != ((Number) params[0]).doubleValue(); - return true; } } }, - new OperationImpl(this, ">", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() - .getObjectType() }) { + new OperationImpl(this, ">", getTypeSystem().getBooleanType(), new Type[] { IntegerTypeImpl.this }) { @Override public Object evaluateInternal(final Object target, final Object[] params) { if (target == null) @@ -127,15 +122,14 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { return Boolean.FALSE; try { - return ((Comparable) toLong(target)).compareTo(toLong(params[0])) > 0; + return toInt(target).compareTo(toInt(params[0])) > 0; } catch (Exception exc) { - return ((Number) target).doubleValue() > ((Number) params[0]).doubleValue(); + return Boolean.FALSE; } } }, - new OperationImpl(this, ">=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() - .getObjectType() }) { + new OperationImpl(this, ">=", getTypeSystem().getBooleanType(), new Type[] { IntegerTypeImpl.this }) { @Override public Object evaluateInternal(final Object target, final Object[] params) { if (target == null) @@ -144,15 +138,14 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { return Boolean.FALSE; try { - return ((Comparable) toLong(target)).compareTo(toLong(params[0])) >= 0; + return toInt(target).compareTo(toInt(params[0])) >= 0; } catch (Exception exc) { - return ((Number) target).doubleValue() >= ((Number) params[0]).doubleValue(); + return Boolean.FALSE; } } }, - new OperationImpl(this, "<", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() - .getObjectType() }) { + new OperationImpl(this, "<", getTypeSystem().getBooleanType(), new Type[] { IntegerTypeImpl.this }) { @Override public Object evaluateInternal(final Object target, final Object[] params) { if (target == null) @@ -161,15 +154,14 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { return Boolean.FALSE; try { - return ((Comparable) toLong(target)).compareTo(toLong(params[0])) < 0; + return toInt(target).compareTo(toInt(params[0])) < 0; } catch (Exception exc) { - return ((Number) target).doubleValue() < ((Number) params[0]).doubleValue(); + return Boolean.FALSE; } } }, - new OperationImpl(this, "<=", getTypeSystem().getBooleanType(), new Type[] { getTypeSystem() - .getObjectType() }) { + new OperationImpl(this, "<=", getTypeSystem().getBooleanType(), new Type[] { IntegerTypeImpl.this }) { @Override public Object evaluateInternal(final Object target, final Object[] params) { if (target == null) @@ -178,10 +170,10 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { return Boolean.FALSE; try { - return ((Comparable) toLong(target)).compareTo(toLong(params[0])) <= 0; + return toInt(target).compareTo(toInt(params[0])) <= 0; } catch (Exception exc) { - return ((Number) target).doubleValue() <= ((Number) params[0]).doubleValue(); + return Boolean.FALSE; } } }, new OperationImpl(this, "upTo", getTypeSystem().getListType(this), new Type[] { this }) { @@ -195,13 +187,13 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { @Override public Object evaluateInternal(final Object target, final Object[] params) { - final List result = new ArrayList(); - long l1 = toLong(target).longValue(); - final long l2 = toLong(params[0]).longValue(); + final List result = new ArrayList(); + BigInteger l1 = toInt(target); + final BigInteger l2 = toInt(params[0]); - while (l1 <= l2) { - result.add(new Long(l1)); - l1++; + while (l1.compareTo(l2) <= 0) { + result.add(l1); + l1 = l1.add(BigInteger.ONE); } return result; } @@ -216,55 +208,58 @@ public final class IntegerTypeImpl extends BuiltinBaseType implements Type { @Override public Object evaluateInternal(final Object target, final Object[] params) { - final List result = new ArrayList(); - long l1 = toLong(target).longValue(); - final long l2 = toLong(params[0]).longValue(); - final long l3 = toLong(params[1]).longValue(); + final List result = new ArrayList(); + BigInteger l1 = toInt(target); + final BigInteger l2 = toInt(params[0]); + final BigInteger l3 = toInt(params[1]); - while (l1 <= l2) { - result.add(new Long(l1)); - l1 = l1 + l3; + while (l1.compareTo(l2) <= 0) { + result.add(l1); + l1 = l1.add(l3); } return result; } } }; } - @Override + @Override public Set getSuperTypes() { return Collections.singleton(getTypeSystem().getRealType()); } - Long toLong(final Object o) { - if (o == null) - return null; - + protected BigInteger toInt(final Object o) { + if(o == null) + return null; + + if (o instanceof BigInteger) + return (BigInteger) o; + if (o instanceof Integer) - return new Long(((Integer) o).longValue()); - else if (o instanceof BigInteger) - return new Long(((BigInteger) o).longValue()); + return BigInteger.valueOf(((Integer)o).longValue()); else if (o instanceof Byte) - return new Long(((Byte) o).longValue()); + return BigInteger.valueOf(((Byte)o).longValue()); else if (o instanceof Long) - return (Long) o; + return BigInteger.valueOf((Long)o); else if (o instanceof Short) - return new Long(((Short) o).longValue()); - throw new IllegalArgumentException(o.getClass().getName() + " not supported"); - } - + return BigInteger.valueOf(((Short) o).longValue()); + + throw new IllegalArgumentException(o.getClass().getName() + " not supported"); + } + @Override public Object convert(final Object src, final Class targetType) { - final Long l = toLong(src); - if (targetType.isAssignableFrom(Integer.class) || targetType.isAssignableFrom(Integer.TYPE)) - return new Integer(l.intValue()); - else if (targetType.isAssignableFrom(BigInteger.class)) - return BigInteger.valueOf(l.longValue()); - else if (targetType.isAssignableFrom(Byte.class) || targetType.isAssignableFrom(Byte.TYPE)) - return new Byte(l.byteValue()); + final BigInteger value = toInt(src); + + if (targetType.isAssignableFrom(BigInteger.class)) + return value; else if (targetType.isAssignableFrom(Long.class) || targetType.isAssignableFrom(Long.TYPE)) - return src; + return value.longValue(); + else if (targetType.isAssignableFrom(Integer.class) || targetType.isAssignableFrom(Integer.TYPE)) + return value.intValue(); + else if (targetType.isAssignableFrom(Byte.class) || targetType.isAssignableFrom(Byte.TYPE)) + return value.byteValue(); else if (targetType.isAssignableFrom(Short.class) || targetType.isAssignableFrom(Short.TYPE)) - return new Short(l.shortValue()); + return value.shortValue(); return super.convert(src, targetType); } diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java index d451fdbf..b363bdce 100644 --- a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/type/baseimpl/types/StringTypeImpl.java @@ -11,6 +11,7 @@ package org.eclipse.internal.xtend.type.baseimpl.types; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -122,7 +123,7 @@ public class StringTypeImpl extends BuiltinBaseType implements Type { @Override public String getDocumentation() { - return "Tests if this string ends with the specified prefix."; + return "Returns a new string that is a substring of this string."; } @Override @@ -291,7 +292,7 @@ public class StringTypeImpl extends BuiltinBaseType implements Type { @Override public Object evaluateInternal(final Object target, final Object[] params) { try { - return Integer.valueOf((String) target); + return new BigInteger((String) target); } catch (NumberFormatException nfe) { log.error("'asInteger' on '"+target+"' returned null!"); return null; diff --git a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java index 0812da62..30dc5d8b 100644 --- a/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java +++ b/plugins/org.eclipse.xtend/src/org/eclipse/internal/xtend/xtend/ast/JavaExtensionStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 committers of openArchitectureWare and others. + * Copyright (c) 2005, 2009 committers of openArchitectureWare and others. * 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 @@ -27,6 +27,11 @@ import org.eclipse.xtend.expression.EvaluationException; import org.eclipse.xtend.expression.ExecutionContext; import org.eclipse.xtend.typesystem.Type; +/** + * @author Sven Efftinge (http://www.efftinge.de) + * @author Arno Haase + * @author Heiko Behrens + */ public class JavaExtensionStatement extends AbstractExtension { protected Identifier javaType; @@ -65,6 +70,7 @@ public class JavaExtensionStatement extends AbstractExtension { } throw new EvaluationException(javaMethodToString() + " not found, problems were: \n" + b, this, ctx); } + convertTypesToMethodSignature(ctx, method, parameters); return method.invoke(null, parameters); } catch (final InvocationTargetException ite) { throw new RuntimeException(ite.getCause()); @@ -73,7 +79,15 @@ public class JavaExtensionStatement extends AbstractExtension { } } - private String javaMethodToString() { + private void convertTypesToMethodSignature(ExecutionContext ctx, Method method, Object[] parameters) { + Class[] paramTypes = method.getParameterTypes(); + for(int i = 0; i < parameters.length; i++) { + Object param = parameters[i]; + parameters[i] = ctx.getType(param).convert(param, paramTypes[i]); + } + } + + private String javaMethodToString() { final StringBuffer buff = new StringBuffer(); for (final Iterator iter = javaParamTypes.iterator(); iter.hasNext();) { buff.append(iter.next()); -- cgit v1.2.3