├── lib ├── guava.jar ├── junit4.jar ├── jarjar-1.0.jar └── ant-contrib.jar ├── .gitignore ├── docs ├── logo │ ├── ductile-bw-hires.png │ ├── ductile-bw-single.png │ ├── ductile-color-logo.pdf │ ├── ductile-color-tile.pdf │ ├── ductile-color-tile.png │ ├── ductile-color-logo-large.png │ ├── ductile-color-logo-small.png │ └── ductile-color-tile-square.png ├── poster.graffle │ └── image1.gif └── wasp-2010-2-22-src │ ├── hole.png │ ├── except.java │ ├── collide.java │ ├── namemangle.java │ ├── xcollide.java │ ├── xexceptbad.java │ ├── xnamemangle.java │ ├── foreach.java │ ├── switch.java │ ├── unop.java │ ├── libsuper.java │ ├── combine.java │ ├── arrays.java │ ├── assop.java │ ├── boolean.java │ ├── assign.java │ ├── nomangctors.java │ ├── sigmangle.java │ ├── basic.java │ ├── xnorefsuper.java │ ├── xforeach.java │ ├── defassign.java │ ├── libcode.java │ ├── xnomangctors.java │ ├── sigmangsuper.java │ ├── xswitch.java │ ├── xsigmangle.java │ ├── xunop.java │ ├── nocombsuper.java │ ├── xassign.java │ ├── xbasic.java │ ├── xarrays.java │ ├── xassop.java │ ├── xdefassign.java │ ├── xsigmangsuper.java │ ├── norefsuper.java │ ├── xboolean.java │ ├── xlibcode.java │ ├── xexcept.java │ ├── xlibsuper.java │ ├── xcombine.java │ ├── xnocombsuper.java │ └── bggen.java ├── src ├── test │ └── java │ │ └── org │ │ └── ductilej │ │ ├── tests │ │ ├── helper │ │ │ ├── HelperEnum.java │ │ │ ├── two │ │ │ │ └── MyInterfaceTest.java │ │ │ ├── one │ │ │ │ └── MyInterfaceTest.java │ │ │ ├── ConstructorPackageTestClass.java │ │ │ ├── HelperUtil.java │ │ │ ├── ProtectedHelper.java │ │ │ ├── SelectSuperHelper.java │ │ │ └── StaticMethodResolutionTestPackage.java │ │ ├── CloneTest.java │ │ ├── AssignExprTest.java │ │ ├── ProtectedConstructorTest.java │ │ ├── OuterInnerTest.java │ │ ├── StaticImportTest.java │ │ ├── ConstructorPackageTest.java │ │ ├── StaticHelper.java │ │ ├── StaticBlockTest.java │ │ ├── RawTypesTest.java │ │ ├── OldJUnitTest.java │ │ ├── ArgVisibilityTest.java │ │ ├── SelectSuperTest.java │ │ ├── ArrayCloneTest.java │ │ ├── IterableTest.java │ │ ├── SuperTypeVarTest.java │ │ ├── QualifiedNameTest.java │ │ ├── ConstTest.java │ │ ├── ShadowedFinalArgTest.java │ │ ├── InnerFieldTest.java │ │ ├── InitOrderTest.java │ │ ├── BridgeMethodTest.java │ │ ├── VarTypedExpTest.java │ │ ├── VAEnumTest.java │ │ ├── PackageAccessTest.java │ │ ├── CtorTest.java │ │ ├── RetTypeVarTest.java │ │ ├── FieldInitTest.java │ │ ├── ArrayAccessTest.java │ │ ├── NameCollideTest.java │ │ ├── StaticMethodAmbiguousInterfaceTest.java │ │ ├── QualifiedThisTest.java │ │ ├── NestedTypeVarTest.java │ │ ├── StaticMethodResolutionTest.java │ │ ├── ArrayCreateTest.java │ │ ├── ReflectiveInvokeTest.java │ │ ├── ArrayTypeTest.java │ │ ├── ConversionTest.java │ │ ├── ChainedConsTest.java │ │ ├── HashCodeTest.java │ │ ├── ParamVarArgsTest.java │ │ ├── LibraryFieldAssignTest.java │ │ ├── ParameterizedThisTest.java │ │ ├── RawVarArgsTest.java │ │ ├── EnumTest.java │ │ ├── ArrayStoreTest.java │ │ ├── BasicAssignTest.java │ │ ├── InvokeNonStaticTest.java │ │ ├── SuperSuperTest.java │ │ ├── PromoteTest.java │ │ ├── SelectTest.java │ │ ├── ConditionalTest.java │ │ ├── SneakyThrowTest.java │ │ ├── ThrowsTest.java │ │ ├── NullVarArgsTest.java │ │ ├── CoerceTest.java │ │ ├── ImplInheritTest.java │ │ ├── InfTypeVarTest.java │ │ ├── OverloadTest.java │ │ ├── OverVarArgsTest.java │ │ ├── ForeachTest.java │ │ ├── OverCtorTest.java │ │ ├── DefApplyTest.java │ │ ├── OuterThisTest.java │ │ ├── SuperCallTest.java │ │ ├── WildcardTest.java │ │ ├── InvokeStaticTest.java │ │ ├── TypeVarTest.java │ │ └── LibInterfaceTest.java │ │ └── dtests │ │ ├── UncheckedExceptionTest.java │ │ ├── ConstructorArgsTest.java │ │ ├── MissingMethodTest.java │ │ ├── DuckTypingTest.java │ │ ├── IterableTest.java │ │ ├── InferredReceiverTest.java │ │ ├── NullPointerExceptionTest.java │ │ └── FindStaticMethodTest.java └── main │ └── java │ └── org │ └── ductilej │ ├── runtime │ ├── WrappedException.java │ ├── AmbiguousMethodError.java │ ├── Transformed.java │ ├── UnOps.java │ ├── ops │ │ ├── ByteOps.java │ │ ├── LongOps.java │ │ ├── IntegerOps.java │ │ ├── ShortOps.java │ │ ├── IntegralUnOps.tmpl │ │ ├── CharacterOps.java │ │ ├── FloatOps.java │ │ ├── FloatingUnOps.tmpl │ │ ├── DoubleOps.java │ │ ├── BooleanOps.java │ │ ├── ByteByteOps.java │ │ ├── ByteLongOps.java │ │ ├── LongByteOps.java │ │ ├── LongLongOps.java │ │ ├── ByteShortOps.java │ │ ├── LongShortOps.java │ │ ├── ShortByteOps.java │ │ ├── ShortLongOps.java │ │ ├── ByteIntegerOps.java │ │ ├── IntegerByteOps.java │ │ ├── IntegerLongOps.java │ │ ├── LongIntegerOps.java │ │ ├── ByteFloatOps.java │ │ ├── FloatByteOps.java │ │ ├── FloatLongOps.java │ │ ├── LongFloatOps.java │ │ ├── ShortShortOps.java │ │ ├── IntegerShortOps.java │ │ ├── ShortIntegerOps.java │ │ ├── IntegerIntegerOps.java │ │ ├── ByteCharacterOps.java │ │ ├── ByteDoubleOps.java │ │ ├── CharacterByteOps.java │ │ ├── CharacterLongOps.java │ │ ├── DoubleByteOps.java │ │ ├── DoubleLongOps.java │ │ ├── FloatFloatOps.java │ │ ├── FloatShortOps.java │ │ └── LongCharacterOps.java │ └── BinOps.java │ └── detyper │ └── DetypeContext.java └── bin └── genops /lib/guava.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/lib/guava.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build.properties 2 | dist 3 | docs/proposal 4 | docs/oopsla-2010 5 | -------------------------------------------------------------------------------- /lib/junit4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/lib/junit4.jar -------------------------------------------------------------------------------- /lib/jarjar-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/lib/jarjar-1.0.jar -------------------------------------------------------------------------------- /lib/ant-contrib.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/lib/ant-contrib.jar -------------------------------------------------------------------------------- /docs/logo/ductile-bw-hires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-bw-hires.png -------------------------------------------------------------------------------- /docs/logo/ductile-bw-single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-bw-single.png -------------------------------------------------------------------------------- /docs/poster.graffle/image1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/poster.graffle/image1.gif -------------------------------------------------------------------------------- /docs/logo/ductile-color-logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-color-logo.pdf -------------------------------------------------------------------------------- /docs/logo/ductile-color-tile.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-color-tile.pdf -------------------------------------------------------------------------------- /docs/logo/ductile-color-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-color-tile.png -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/wasp-2010-2-22-src/hole.png -------------------------------------------------------------------------------- /docs/logo/ductile-color-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-color-logo-large.png -------------------------------------------------------------------------------- /docs/logo/ductile-color-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-color-logo-small.png -------------------------------------------------------------------------------- /docs/logo/ductile-color-tile-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mernst/ductilej/HEAD/docs/logo/ductile-color-tile-square.png -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/except.java: -------------------------------------------------------------------------------- 1 | InputStream in = ...; 2 | try { 3 | int c = in.read(); 4 | ... 5 | } catch (IOException e) { 6 | ... 7 | } 8 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/collide.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void bar (String arg) { 3 | ... 4 | } 5 | void bar (int arg) { 6 | ... 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/namemangle.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void bar (String arg) { 3 | ... 4 | } 5 | void bar (int arg) { 6 | ... 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xcollide.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void bar (Object arg) { 3 | ... 4 | } 5 | void bar (Object arg) { 6 | ... 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xexceptbad.java: -------------------------------------------------------------------------------- 1 | Object in = ...; 2 | try { 3 | Object c = RT.invoke("read", in); 4 | // ... 5 | } catch (IOException e) { 6 | ... 7 | } 8 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xnamemangle.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | void bar$String (Object arg) { 3 | ... 4 | } 5 | void bar$int (Object arg) { 6 | ... 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/foreach.java: -------------------------------------------------------------------------------- 1 | int[] array = ...; 2 | for (int i : array) { 3 | ... 4 | } 5 | 6 | List list = ...; 7 | for (Integer i : list) { 8 | ... 9 | } 10 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/switch.java: -------------------------------------------------------------------------------- 1 | // some field 2 | static final int CONSTANT = 1; 3 | 4 | int value = ...; 5 | switch (value) { 6 | case CONSTANT: 7 | ... 8 | } 9 | 10 | MyEnum value = ...; 11 | switch (value) { 12 | ... 13 | } 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/unop.java: -------------------------------------------------------------------------------- 1 | int foo = 0, bar = 0; 2 | 3 | // non-side-effecting op 4 | foo = -foo; 5 | 6 | // prefix increment 7 | foo = ++bar; 8 | 9 | // postfix increment 10 | foo = bar++; 11 | 12 | 13 | 14 | // same for decrement 15 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/HelperEnum.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper; 5 | 6 | /** 7 | * Used to test fully qualifying type names. 8 | */ 9 | public enum HelperEnum 10 | { 11 | A, B, C; 12 | } 13 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/libsuper.java: -------------------------------------------------------------------------------- 1 | class MyList 2 | extends ArrayList { 3 | 4 | public E at (int i) { 5 | return super.get(i); 6 | } 7 | 8 | public void append (E elem) { 9 | super.add(elem); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/two/MyInterfaceTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper.two; 5 | 6 | /** 7 | * Used by StaticMethodAmbiguousInterfaceTest. 8 | */ 9 | public interface MyInterfaceTest 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/combine.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo (String arg) { 3 | ... 4 | } 5 | Foo (int arg) { 6 | ... 7 | } 8 | } 9 | 10 | String sarg = "Hello"; 11 | new Foo(sarg); 12 | 13 | int iarg = 5; 14 | new Foo(iarg); 15 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/one/MyInterfaceTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper.one; 5 | 6 | /** 7 | * Used by StaticMethodAmbiguousInterfaceTest. 8 | */ 9 | public interface MyInterfaceTest 10 | { 11 | } 12 | 13 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/arrays.java: -------------------------------------------------------------------------------- 1 | int length = ...; 2 | String[] strings = 3 | new String[length]; 4 | 5 | String[] bar = new String[] { 6 | "a", "b", "c" } 7 | 8 | int[][] foo = { 9 | { 1, 2, }, { 3, 4 } }; 10 | 11 | 12 | 13 | String elem = bar[2]; 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/assop.java: -------------------------------------------------------------------------------- 1 | // simple assignment 2 | int foo = 0; 3 | foo += 5; 4 | 5 | // array assignment 6 | int[] vec = { 5 }; 7 | vec[0] *= 5; 8 | 9 | // field assignment 10 | foo.bar -= 5; 11 | 12 | // side-effecting lhs 13 | naughty().bar /= 5; 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/boolean.java: -------------------------------------------------------------------------------- 1 | boolean expr = ...; 2 | 3 | if (expr) { ... } 4 | 5 | for ( ; expr; ) { .. } 6 | 7 | while (expr) { ... } 8 | 9 | do { ... } while (expr); 10 | 11 | int i = expr ? 1 : 0; 12 | 13 | assert expr; 14 | assert expr : message; 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/assign.java: -------------------------------------------------------------------------------- 1 | // simple assignment 2 | int foo = 3; 3 | 4 | // array element assignment 5 | int[] vec = new int[3]; 6 | vec[1] = 42; 7 | 8 | // field assignment 9 | bar.baz = foo; 10 | 11 | // static field assignment 12 | SomeClass.baz = foo; 13 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/ConstructorPackageTestClass.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper; 5 | 6 | public final class ConstructorPackageTestClass { 7 | 8 | public ConstructorPackageTestClass(int arg0) { 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/nomangctors.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo (String arg) { 3 | ... 4 | } 5 | Foo (int arg) { 6 | ... 7 | } 8 | void bar (String arg) { 9 | ... 10 | } 11 | void bar (int arg) { 12 | ... 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/sigmangle.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo (String arg) { 3 | ... 4 | } 5 | Foo (int arg) { 6 | ... 7 | } 8 | void bar (String arg) { 9 | ... 10 | } 11 | void bar (int arg) { 12 | ... 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/basic.java: -------------------------------------------------------------------------------- 1 | int intval = 1; 2 | String strval = "Hello"; 3 | 4 | class Foo { 5 | int value; 6 | int add (int a, int b) { 7 | return a + b; 8 | } 9 | } 10 | 11 | Foo foo = new Foo(); 12 | int sum = foo.add(2, 3); 13 | int fval = foo.value; 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xnorefsuper.java: -------------------------------------------------------------------------------- 1 | class Adder { 2 | int sum (int a, int b) { 3 | return a + b; 4 | } 5 | } 6 | 7 | class Badder extends Adder { 8 | int sum (int a, int b) { 9 | int s = super.sum(a, b); 10 | return s + 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xforeach.java: -------------------------------------------------------------------------------- 1 | Object array = ...; 2 | for (Object i : RT.asIterable(array)) { 3 | ... 4 | } 5 | 6 | Object list = ...; 7 | for (Object i : RT.asIterable(list)) { 8 | ... 9 | } 10 | 11 | // RT.asIterable: Object -> Iterable 12 | // wraps arrays with Arrays.asList() 13 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/defassign.java: -------------------------------------------------------------------------------- 1 | // locals 2 | int foo; 3 | if (4 > 2) { 4 | foo = 0; 5 | } 6 | System.out.println(foo); 7 | 8 | // final fields 9 | class Foo { 10 | final int value; 11 | Foo () { 12 | if (4 > 2) { 13 | value = 0; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/libcode.java: -------------------------------------------------------------------------------- 1 | class MyInt { 2 | final int v; 3 | MyInt (int value) { 4 | v = value; 5 | } 6 | 7 | public boolean equals (Object o) { 8 | return v == ((MyInt)o).v; 9 | } 10 | 11 | public int hashCode () { 12 | return v; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xnomangctors.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo$String (Object arg) { 3 | ... 4 | } 5 | Foo$int (Object arg) { 6 | ... 7 | } 8 | void bar$String (Object arg) { 9 | ... 10 | } 11 | void bar$int (Object arg) { 12 | ... 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/sigmangsuper.java: -------------------------------------------------------------------------------- 1 | class LibBase { 2 | LibBase (String arg) { 3 | } 4 | LibBase (int arg) { 5 | } 6 | } 7 | 8 | class Foo extends LibBase { 9 | Foo (String arg) { 10 | super(arg); 11 | } 12 | Foo (int arg) { 13 | super(arg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/HelperUtil.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper; 5 | 6 | /** 7 | * Helps out with more inter-package bits. 8 | */ 9 | public class HelperUtil 10 | { 11 | public static HelperEnum getA () { 12 | return HelperEnum.A; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xswitch.java: -------------------------------------------------------------------------------- 1 | // not detyped 2 | static final int CONSTANT = 1; 3 | 4 | Object value = ...; 5 | switch (RT.asInt(value)) { 6 | case CONSTANT: 7 | ... 8 | } 9 | 10 | Object value = ...; 11 | switch (RT.asEnum(MyEnum.class, value)) { 12 | ... 13 | } 14 | 15 | // RT.asEnum: Class -> Object -> E 16 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xsigmangle.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | Foo (Object arg, String arg$T) { 3 | ... 4 | } 5 | Foo (Object arg, int arg$T) { 6 | ... 7 | } 8 | void bar (Object arg, String arg$T) { 9 | ... 10 | } 11 | void bar (Object arg, int arg$T) { 12 | ... 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xunop.java: -------------------------------------------------------------------------------- 1 | Object foo = 0, bar = 0; 2 | 3 | // non-side-effecting op 4 | foo = RT.unop("-", foo); 5 | 6 | // prefix increment 7 | foo = (bar = RT.binop("+", bar, 1)); 8 | 9 | // postfix increment 10 | foo = RT.binop( 11 | "-", 12 | (bar = RT.binop("+", bar, 1)), 1); 13 | 14 | // same for decrement 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/nocombsuper.java: -------------------------------------------------------------------------------- 1 | class LibBase { 2 | LibBase (String arg) { 3 | ... 4 | } 5 | LibBase (int arg) { 6 | ... 7 | } 8 | } 9 | 10 | class Foo extends LibBase { 11 | Foo (String arg) { 12 | super(arg); 13 | } 14 | Foo (int arg) { 15 | super(arg); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xassign.java: -------------------------------------------------------------------------------- 1 | // simple assignment 2 | Object foo = 3; 3 | 4 | // array element assignment 5 | Object vec = new int[RT.asInt(3)]; 6 | RT.assignAt(vec, 1, 42); 7 | 8 | // field assignment 9 | RT.assign(bar, "baz", foo); 10 | 11 | // static field assignment 12 | RT.assignStatic(SomeClass.class, 13 | "baz", foo); 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xbasic.java: -------------------------------------------------------------------------------- 1 | Object intval = 1; 2 | Object strval = "Hello"; 3 | 4 | class Foo { 5 | Object value; 6 | Object add (Object a, Object b) { 7 | return RT.binop("+", a, b); 8 | } 9 | } 10 | 11 | Object foo = RT.newInstance(Foo.class); 12 | Object sum = RT.invoke("add", foo, 2, 3); 13 | Object fval = RT.select("value", foo) 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xarrays.java: -------------------------------------------------------------------------------- 1 | Object length = ...; 2 | Object strings = 3 | new String[RT.asInt(length)]; 4 | 5 | Object bar = RT.newArrayOf( 6 | String.class, "a", "b", "c"); 7 | 8 | Object foo = 9 | RT.newArrayOf(int[].class, 10 | RT.newArrayOf(int.class, 1, 2), 11 | RT.newArrayOf(int.class, 3, 4)); 12 | 13 | Object elem = RT.atIndex(bar, 2); 14 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xassop.java: -------------------------------------------------------------------------------- 1 | // simple assignment 2 | Object foo = 0; 3 | foo = RT.binop("+", foo, 5); 4 | 5 | // array assignment 6 | Object vec = RT.newArrayOf(int.class, 5); 7 | RT.assignOpAt(vec, 0, "+", 5); 8 | 9 | // field assignment 10 | RT.assignOp(foo, "bar", "-", 5); 11 | 12 | // side-effecting lhs 13 | RT.assignOp( 14 | RT.invoke(this, "foo"), "bar", "/", 5) 15 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/ProtectedHelper.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper; 5 | 6 | /** 7 | * Used to test access to a protected constructor. 8 | */ 9 | public class ProtectedHelper 10 | { 11 | public final String value; 12 | 13 | protected ProtectedHelper (String value) { 14 | this.value = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xdefassign.java: -------------------------------------------------------------------------------- 1 | // locals 2 | Object foo = null; // added initializer 3 | if (RT.binop(">", 4, 2)) { 4 | foo = 0; 5 | } 6 | RT.invoke("println", System.out, foo); 7 | 8 | // final fields 9 | class Foo { 10 | Object value; // final removed 11 | Foo () { 12 | if (RT.binop(">", 4, 2) { 13 | value = 0; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xsigmangsuper.java: -------------------------------------------------------------------------------- 1 | class LibBase { 2 | LibBase (String arg) { 3 | } 4 | LibBase (int arg) { 5 | } 6 | } 7 | 8 | class Foo extends LibBase { 9 | Foo (Object arg, String arg$T) { 10 | super(RT.cast(String.class, arg)); 11 | } 12 | Foo (Object arg, int arg$T) { 13 | super(RT.cast(Integer.TYPE, arg)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/norefsuper.java: -------------------------------------------------------------------------------- 1 | class Adder { 2 | Object sum (Object a, Object b, 3 | int a$T, int b$T) { 4 | return RT.binop("+", a, b); 5 | } 6 | } 7 | 8 | class Badder extends Adder { 9 | Object sum (Object a, Object b, 10 | int a$T, int b$T) { 11 | Object s = super.sum(a, b, 0, 0); 12 | return RT.binop("+", s, 1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xboolean.java: -------------------------------------------------------------------------------- 1 | Object expr = ...; 2 | 3 | if (RT.asBoolean(expr)) { ... } 4 | 5 | for ( ; RT.asBoolean(expr); ) { .. } 6 | 7 | while (RT.asBoolean(expr)) { ... } 8 | 9 | do { ... } while (RT.asBoolean(expr)); 10 | 11 | Object i = RT.asBoolean(expr) ? 1 : 0; 12 | 13 | assert RT.asBoolean(expr); 14 | assert RT.asBoolean(expr) : message; 15 | 16 | // RT.asBoolean: Object -> boolean 17 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xlibcode.java: -------------------------------------------------------------------------------- 1 | class MyInt { 2 | Object v; 3 | MyInt (Object value) { 4 | v = value; 5 | } 6 | 7 | public boolean equals (Object o) { 8 | return RT.cast(Boolean.class, 9 | RT.binop("==", v, 10 | RT.select("v", o))); 11 | } 12 | 13 | public int hashCode () { 14 | return RT.cast(Integer.class, v); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xexcept.java: -------------------------------------------------------------------------------- 1 | Object in = ...; 2 | try { 3 | try { 4 | Object c = RT.invoke("read", in); 5 | // ... 6 | } catch (WrappedException _w_e) { 7 | if (_w_e.getCause() instanceof IOException) { 8 | throw (IOException)_w_e.getCause(); 9 | } else { 10 | throw _w_e; 11 | } 12 | } 13 | } catch (IOException e) { 14 | ... 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/WrappedException.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime; 5 | 6 | /** 7 | * Used to note checked exceptions wrapped during reflective invocation so that they can be 8 | * unwrapped in the appropriate places. 9 | */ 10 | public class WrappedException extends RuntimeException 11 | { 12 | public WrappedException (Throwable cause) { 13 | super(cause); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/AmbiguousMethodError.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime; 5 | 6 | /** 7 | * Thrown when two or more methods match the arguments provided to a runtime method call that was 8 | * not resolvable at compile time. 9 | */ 10 | public class AmbiguousMethodError extends RuntimeException 11 | { 12 | public AmbiguousMethodError (String error) 13 | { 14 | super(error); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/CloneTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests detection of clone methods. 11 | */ 12 | public class CloneTest 13 | { 14 | @Test public void testArrayClone () 15 | { 16 | int[] vals = { 1, 2, 3, 4 }; 17 | int[] cvals = vals.clone(); 18 | assertEquals(vals[1], cvals[1]); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xlibsuper.java: -------------------------------------------------------------------------------- 1 | class MyList extends ArrayList { 2 | 3 | public Object at (Object i) { 4 | return super.get(RT.cast(int.class, i)); 5 | } 6 | 7 | public void append (Object elem) { 8 | super.add( 9 | (E)RT.cast(Object.class, elem)); 10 | } 11 | 12 | public void append (Object elem) { 13 | super.add( 14 | RT.typeVarCast( 15 | Object.class, elem)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/Transformed.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * An annotation that identifies a class that has been transformed. 13 | */ 14 | @Target({ElementType.TYPE}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface Transformed 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xcombine.java: -------------------------------------------------------------------------------- 1 | class Foo { 2 | static Class[][] Foo$SIGS = { 3 | { String.class }, { Integer.TYPE }}; 4 | Foo (Object arg, Class arg$T) { 5 | switch (RT.resolve(Foo$SIGS, arg$T)) { 6 | case 0: { ...String... } 7 | case 1: { ...int... } 8 | } 9 | } 10 | } 11 | 12 | Object sarg = "Hello"; 13 | RT.newInstance( 14 | Foo.class, sarg, String.class); 15 | 16 | Object iarg = 5; 17 | RT.newInstance( 18 | Foo.class, iarg, Integer.TYPE); 19 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/SelectSuperHelper.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper; 5 | 6 | /** 7 | * Defines a class outside the tests package for testing cross package bits. 8 | */ 9 | public class SelectSuperHelper 10 | { 11 | public static class A { 12 | protected A (String foo) { 13 | _foo = foo; 14 | } 15 | protected String getFoo () { 16 | return _foo; 17 | } 18 | protected String _foo; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/xnocombsuper.java: -------------------------------------------------------------------------------- 1 | class LibBase { 2 | LibBase (String arg) { 3 | ... 4 | } 5 | LibBase (int arg) { 6 | ... 7 | } 8 | } 9 | 10 | class Foo extends LibBase { 11 | static Class[][] Foo$SIGS = { 12 | { String.class }, { Integer.TYPE }}; 13 | Foo (Object arg, Class arg$T) { 14 | switch (RT.resolve(Foo$SIGS, arg$T)) { 15 | case 0: { super(RT.cast(String.class, arg)); } 16 | case 1: { super(RT.cast(Integer.TYPE, arg)); } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/helper/StaticMethodResolutionTestPackage.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests.helper; 5 | 6 | /** 7 | * Tests that static methods are correctly resolved when a class with the same simple name as the 8 | * current package is imported. The simple name of this class "StaticMethodResolutionTestPackage" 9 | * must be identical to the name of the package containing "StaticMethodResolutionTest". 10 | */ 11 | public class StaticMethodResolutionTestPackage 12 | { 13 | // this space intentionally left blank 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/UncheckedExceptionTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Should compile under DuctileJ but not javac due to lack of check 11 | * exception annotation ("throws") on Foo's constructor. 12 | */ 13 | public class UncheckedExceptionTest 14 | { 15 | class Foo { 16 | public Foo() { 17 | throw new java.lang.Exception(); 18 | } 19 | } 20 | 21 | public UncheckedExceptionTest() { 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/AssignExprTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | public class AssignExprTest 10 | { 11 | @Test public void testAssignExpr () 12 | { 13 | int value = 5; 14 | // we're mainly testing that 'msg' is registered in the symbol table at the time that we 15 | // process msg's initializer expression 16 | String msg = (value == 5) ? msg = "Redundant" : null; 17 | assertEquals("Redundant", msg); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ProtectedConstructorTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | import org.ductilej.tests.helper.ProtectedHelper; 10 | 11 | /** 12 | * Tests proper resolution of protected constructor when used by an anonymous inner class. 13 | */ 14 | public class ProtectedConstructorTest 15 | { 16 | @Test public void testPC () { 17 | ProtectedHelper a = new ProtectedHelper("test") { 18 | }; 19 | assertEquals("test", a.value); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/OuterInnerTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | public class OuterInnerTest 10 | { 11 | public class Outer { 12 | public class Inner { 13 | public final int value; 14 | public Inner (int value) { 15 | this.value = value; 16 | } 17 | } 18 | } 19 | 20 | @Test public void test () { 21 | Outer o = new Outer(); 22 | Outer.Inner i = o.new Inner(10); 23 | assertEquals(10, i.value); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/ConstructorArgsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import java.util.Date; 7 | import org.junit.Test; 8 | import static org.junit.Assert.*; 9 | 10 | /** 11 | * Tests that we can pass non-matching arguments to constructor. 12 | */ 13 | public class ConstructorArgsTest 14 | { 15 | static class Foo { 16 | public Foo(String arg0, String arg1, String arg2, Date arg3) { 17 | } 18 | } 19 | 20 | @Test(expected=NoSuchMethodError.class) 21 | public void testNonmatchingArgs() { 22 | Foo f = new Foo("", "", "", ""); 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/StaticImportTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | import static org.ductilej.tests.StaticHelper.inner; 10 | import static org.ductilej.tests.StaticHelper.Inner.innerHelp; 11 | 12 | /** 13 | * Tests static imports. 14 | */ 15 | public class StaticImportTest 16 | { 17 | @Test public void testImportedField () 18 | { 19 | assertTrue(inner.triple(5) == 15); 20 | } 21 | 22 | @Test public void testImportedMethod () 23 | { 24 | assertTrue(innerHelp(5) == 29); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/UnOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime; 5 | 6 | /** 7 | * Encapsulates unary operations on primitive types. Specialized instances of this class are 8 | * automatically generated for all primitive types for reasonably fast dispatch of ad-hoc 9 | * polymorphic unary operators. 10 | */ 11 | public interface UnOps 12 | { 13 | public Object plus (Object arg); 14 | public Object minus (Object arg); 15 | public Object increment (Object arg); 16 | public Object decrement (Object arg); 17 | public Object bitComp (Object arg); 18 | public Object logicalComp (Object arg); 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ConstructorPackageTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package OtherPackage; 5 | 6 | import org.junit.Test; 7 | 8 | public final class ConstructorPackageTest { 9 | 10 | private static final class Tester { 11 | } 12 | 13 | public ConstructorPackageTest() { 14 | } 15 | 16 | @Test 17 | public void testConstructor() { 18 | // The following line results in the compiler error "constructor 19 | // ConstructorPackageTestClass in class ConstructorPackageTestClass 20 | // cannot be applied to given types". 21 | new org.ductilej.tests.helper.ConstructorPackageTestClass(0); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/MissingMethodTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests that we can compile code with a missing method and that we throw a NoSuchMethodError at 11 | * runtime. 12 | */ 13 | public class MissingMethodTest 14 | { 15 | static class Bar { 16 | } 17 | 18 | static class Foo { 19 | public Bar firstMethod() { return new Bar(); } 20 | } 21 | 22 | @Test(expected=NoSuchMethodError.class) 23 | public void testUndefinedMethod() { 24 | Foo f = new Foo(); 25 | f.firstMethod().secondMethod(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/StaticHelper.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | /** 7 | * Used to test locating classes in one's same package. 8 | */ 9 | public class StaticHelper 10 | { 11 | public static final int HELPFUL = 42; 12 | 13 | public static class Inner { 14 | public static int innerHelp (int value) { 15 | return value + 24; 16 | } 17 | 18 | public int triple (int value) { 19 | return value * 3; 20 | } 21 | } 22 | 23 | public static final Inner inner = new Inner(); 24 | 25 | public static int help (int value) 26 | { 27 | return value + 42; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/StaticBlockTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests handling of static blocks. 14 | */ 15 | public class StaticBlockTest 16 | { 17 | @Test public void testImportedField () 18 | { 19 | assertEquals(2, _classes.size()); 20 | } 21 | 22 | protected static Set> _classes; 23 | static { 24 | Set> set = new HashSet>(); 25 | set.add(Byte.TYPE); 26 | set.add(Short.TYPE); 27 | _classes = set; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/RawTypesTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests handling of raw types. 14 | */ 15 | public class RawTypesTest 16 | { 17 | @Test @SuppressWarnings({"unchecked", "rawtypes"}) 18 | public void testRawTypes () { 19 | Map map = new HashMap(); 20 | map.put("one", "two"); 21 | Map.Entry entry1 = (Map.Entry) map.entrySet().iterator().next(); 22 | entry1.setValue("XYZ"); 23 | assertEquals("XYZ", map.get("one")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/OldJUnitTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import junit.framework.TestCase; 7 | import junit.framework.TestSuite; 8 | 9 | /** 10 | * Tests special handling for JUnit 3 test cases. 11 | */ 12 | public class OldJUnitTest extends TestCase 13 | { 14 | public static TestSuite suite () { 15 | return new TestSuite(OldJUnitTest.class); 16 | } 17 | 18 | // we need to make sure that this ctor is not detyped 19 | public OldJUnitTest (String name) { 20 | super(name); 21 | } 22 | 23 | // if this method gets called at all, things are working 24 | public void testTest () { 25 | assertEquals(1+1, 2); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ArgVisibilityTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests handling of methods with inaccessible argument types. 11 | */ 12 | public class ArgVisibilityTest 13 | { 14 | public static class B { 15 | public int callFoo (A a) { 16 | return a.foo(null); 17 | } 18 | } 19 | 20 | @Test public void testCall () { 21 | B b = new B(); 22 | assertEquals(1, b.callFoo(new A())); 23 | } 24 | } 25 | 26 | class A { 27 | public int foo (Private p) { 28 | return 1; 29 | } 30 | private static class Private { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/SelectSuperTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.ductilej.tests.helper.SelectSuperHelper; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests configuring the selectSuper bit in AttrContext. 13 | */ 14 | public class SelectSuperTest 15 | { 16 | public class B extends SelectSuperHelper.A { 17 | public B (String foo) { 18 | super(foo); 19 | } 20 | 21 | public String get () { 22 | return super.getFoo(); 23 | } 24 | } 25 | 26 | @Test public void testSelectSuper () 27 | { 28 | B b = new B("Foo"); 29 | assertEquals("Foo", b.get()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ArrayCloneTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests handling typing of cloned arrays. 14 | */ 15 | public class ArrayCloneTest 16 | { 17 | @Test public void testClonedArray () 18 | { 19 | String[] array = { "one", "two", "three" }; 20 | // make sure the type of array.clone() is being resolved as String[] rather than Object 21 | // (which is what is declared and what would be correct in the absence of special cases) 22 | List list = Arrays.asList(array.clone()); 23 | assertEquals(3, list.size()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/IterableTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Iterator; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests our handling of iterables. 14 | */ 15 | public class IterableTest 16 | { 17 | @Test public void testList () { 18 | ArrayList list = new ArrayList(); 19 | list.add("One"); 20 | for (String item : list) { 21 | assertEquals("One", item); 22 | } 23 | } 24 | 25 | @Test public void testArray () { 26 | String[] array = new String[] { "One" }; 27 | for (String item : array) { 28 | assertEquals("One", item); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/SuperTypeVarTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests type variables accessed through a super member. 14 | */ 15 | public class SuperTypeVarTest 16 | { 17 | public class A { 18 | public List list = new ArrayList(); 19 | } 20 | 21 | public class B extends A { 22 | public void add (T elem) { 23 | list.add(elem); 24 | } 25 | } 26 | 27 | @Test public void testSuperTypeVar () 28 | { 29 | B b = new B(); 30 | b.add("Hello"); 31 | assertEquals("Hello", b.list.get(0)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/QualifiedNameTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests resolution of fully-qualified class names. 11 | */ 12 | public class QualifiedNameTest 13 | { 14 | public static boolean test = false; 15 | 16 | @Test public void testConstant () 17 | { 18 | assertEquals("Center", java.awt.BorderLayout.CENTER); 19 | } 20 | 21 | @Test public void testClassLiteral () 22 | { 23 | assertEquals("[Ljava.lang.String;", String[].class.getName()); 24 | } 25 | 26 | @Test public void testSameClassStaticField () 27 | { 28 | QualifiedNameTest.test = true; 29 | assertEquals(true, QualifiedNameTest.test); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ConstTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests detection of constants. 11 | */ 12 | public class ConstTest 13 | { 14 | public static final int ONE = 1; 15 | public static final int TWO = ONE+1; 16 | public static final int THREE = 2*ONE+1; 17 | 18 | @Test public void testConst () 19 | { 20 | int one = ONE; 21 | final int two = TWO; 22 | final int three = one + two; 23 | final int four = TWO + TWO; 24 | switch (one) { 25 | case ONE: break; 26 | case two: fail(); break; 27 | case THREE: fail(); break; 28 | case four: fail(); break; 29 | } 30 | assertEquals(3, three); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ShadowedFinalArgTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import javax.swing.JLabel; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests handling of shadowed final arguments. 13 | */ 14 | public class ShadowedFinalArgTest 15 | { 16 | public static class MyLabel extends JLabel { 17 | @Override public void setText (final String text) { 18 | super.setText(text); 19 | new Runnable() { 20 | public void run () { 21 | String val = text; 22 | } 23 | }.run(); 24 | } 25 | } 26 | 27 | @Test public void testShadowedFinal () 28 | { 29 | // we have nothing to test here, if the above code compiles, then we're fine 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/InnerFieldTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Ensures correct types are assigned to inner field members. 14 | */ 15 | public class InnerFieldTest 16 | { 17 | @Test public void testInnerField () 18 | { 19 | Runnable r = new Runnable() { 20 | String hello = "Hello"; 21 | public void run () { 22 | add(hello); 23 | } 24 | }; 25 | r.run(); 26 | assertEquals("Hello", _list.get(0)); 27 | } 28 | 29 | protected void add (String elem) { 30 | _list.add(elem); 31 | } 32 | 33 | protected List _list = new ArrayList(); 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/InitOrderTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Points out an edge case with finals that we can't help. 11 | */ 12 | public class InitOrderTest 13 | { 14 | public static abstract class A { 15 | public int fooVal = foo(); 16 | protected abstract int foo (); 17 | } 18 | 19 | public static class B extends A { 20 | public final int bar; 21 | public B () { 22 | bar = 5; 23 | } 24 | protected int foo () { 25 | return bar; 26 | } 27 | } 28 | 29 | @Test public void testInitOrder() { 30 | B b = new B(); 31 | // assertEquals(0, b.fooVal); // will be 'null' in detyped code 32 | assertEquals(5, b.bar); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/BridgeMethodTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests our handling of situations which normally require bridge methods. 11 | */ 12 | public class BridgeMethodTest 13 | { 14 | public static interface Function { 15 | public R apply (A arg); 16 | } 17 | 18 | public static R applyFunc (Function func, A arg) { 19 | return func.apply(arg); 20 | } 21 | 22 | @Test public void testBridgedApply () { 23 | Function lower = new Function() { 24 | public String apply (String arg) { 25 | return arg.toLowerCase(); 26 | } 27 | }; 28 | assertEquals("hello", applyFunc(lower, "Hello")); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/VarTypedExpTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | public class VarTypedExpTest 10 | { 11 | public class Foo { 12 | } 13 | 14 | public class Bar extends Foo 15 | { 16 | public Bar (Class clazz) { 17 | } 18 | } 19 | 20 | @Test public void testInstantiate () 21 | { 22 | // we're going to resolve the type of this constructor and then insert type carrying 23 | // arguments into the AST; this tests that the necessary constructor resolution properly 24 | // instantiates type variables, so we get "new Bar" rather than "new Bar" 25 | foo(new Bar(Runnable.class) { 26 | // magical inner class juice! 27 | }); 28 | } 29 | 30 | protected void foo (Foo foo) { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/VAEnumTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests special handling for enums with varargs constructors. 11 | */ 12 | public class VAEnumTest 13 | { 14 | public static enum Letter { 15 | A, B, C("one", "two"), D("three"); 16 | 17 | public String getArgs () { 18 | return _args; 19 | } 20 | 21 | Letter (String... args) { 22 | for (String arg : args) { 23 | _args += arg; 24 | } 25 | } 26 | protected String _args = ""; 27 | } 28 | 29 | @Test public void testVAE () { 30 | assertEquals("", Letter.A.getArgs()); 31 | assertEquals("", Letter.B.getArgs()); 32 | assertEquals("onetwo", Letter.C.getArgs()); 33 | assertEquals("three", Letter.D.getArgs()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/PackageAccessTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests package visibility through type parameters. 14 | */ 15 | public class PackageAccessTest 16 | { 17 | public static class Larry { 18 | public E bob; 19 | 20 | public Larry (E bob) { 21 | this.bob = bob; 22 | } 23 | 24 | public String getBobName () { 25 | return bob.getName(); 26 | } 27 | } 28 | 29 | public static class Bob { 30 | String getName () { 31 | return "Bob"; 32 | } 33 | } 34 | 35 | @Test public void testPackageAccess () 36 | { 37 | Larry larry = new Larry(new Bob()); 38 | assertEquals("Bob", larry.getBobName()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Byte. 10 | */ 11 | public class ByteOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Byte)arg).byteValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Byte)arg).byteValue(); 18 | } 19 | public Object increment (Object arg) { 20 | byte tmp = ((Byte)arg).byteValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | byte tmp = ((Byte)arg).byteValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | return ~((Byte)arg).byteValue(); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on byte"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Long. 10 | */ 11 | public class LongOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Long)arg).longValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Long)arg).longValue(); 18 | } 19 | public Object increment (Object arg) { 20 | long tmp = ((Long)arg).longValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | long tmp = ((Long)arg).longValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | return ~((Long)arg).longValue(); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on long"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/IntegerOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Integer. 10 | */ 11 | public class IntegerOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Integer)arg).intValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Integer)arg).intValue(); 18 | } 19 | public Object increment (Object arg) { 20 | int tmp = ((Integer)arg).intValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | int tmp = ((Integer)arg).intValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | return ~((Integer)arg).intValue(); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on int"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ShortOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Short. 10 | */ 11 | public class ShortOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Short)arg).shortValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Short)arg).shortValue(); 18 | } 19 | public Object increment (Object arg) { 20 | short tmp = ((Short)arg).shortValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | short tmp = ((Short)arg).shortValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | return ~((Short)arg).shortValue(); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on short"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/IntegralUnOps.tmpl: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for {ARG}. 10 | */ 11 | public class {ARG}Ops implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +(({ARG})arg).{arg}Value(); 15 | } 16 | public Object minus (Object arg) { 17 | return -(({ARG})arg).{arg}Value(); 18 | } 19 | public Object increment (Object arg) { 20 | {arg} tmp = (({ARG})arg).{arg}Value(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | {arg} tmp = (({ARG})arg).{arg}Value(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | return ~(({ARG})arg).{arg}Value(); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on {arg}"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/CtorTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests various constructor related bits. 11 | */ 12 | public class CtorTest 13 | { 14 | public class Wrapper { 15 | public final String value; 16 | public Wrapper (String value) { 17 | this.value = value; 18 | } 19 | } 20 | 21 | public class VarWrapper { 22 | public final String[] values; 23 | public VarWrapper (String... values) { 24 | this.values = values; 25 | } 26 | } 27 | 28 | @Test public void testNullArg () { 29 | Wrapper w = new Wrapper(null); 30 | assertTrue(null == w.value); 31 | 32 | VarWrapper vw = new VarWrapper((String[])null); 33 | assertTrue(null == vw.values); 34 | 35 | vw = new VarWrapper((String)null); 36 | assertTrue(1 == vw.values.length); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/CharacterOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Character. 10 | */ 11 | public class CharacterOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Character)arg).charValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Character)arg).charValue(); 18 | } 19 | public Object increment (Object arg) { 20 | char tmp = ((Character)arg).charValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | char tmp = ((Character)arg).charValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | return ~((Character)arg).charValue(); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on char"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/FloatOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Float. 10 | */ 11 | public class FloatOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Float)arg).floatValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Float)arg).floatValue(); 18 | } 19 | public Object increment (Object arg) { 20 | float tmp = ((Float)arg).floatValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | float tmp = ((Float)arg).floatValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | throw new IllegalArgumentException("Bitwise complement illegal on float"); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on float"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/RetTypeVarTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.ArrayList; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | public class RetTypeVarTest 12 | { 13 | public static class MyList extends ArrayList { 14 | @Override public T get (int index) { 15 | T val = super.get(index); 16 | return val; 17 | } 18 | } 19 | 20 | public static class MyIntList extends ArrayList { 21 | @Override public Integer get (int index) { 22 | Integer val = super.get(index); 23 | return val; 24 | } 25 | } 26 | 27 | @Test public void test () 28 | { 29 | MyList list = new MyList(); 30 | list.add(5); 31 | assertEquals(Integer.valueOf(5), list.get(0)); 32 | 33 | MyIntList ilist = new MyIntList(); 34 | ilist.add(5); 35 | assertEquals(Integer.valueOf(5), ilist.get(0)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/FloatingUnOps.tmpl: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for {ARG}. 10 | */ 11 | public class {ARG}Ops implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +(({ARG})arg).{arg}Value(); 15 | } 16 | public Object minus (Object arg) { 17 | return -(({ARG})arg).{arg}Value(); 18 | } 19 | public Object increment (Object arg) { 20 | {arg} tmp = (({ARG})arg).{arg}Value(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | {arg} tmp = (({ARG})arg).{arg}Value(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | throw new IllegalArgumentException("Bitwise complement illegal on {arg}"); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on {arg}"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/DoubleOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Double. 10 | */ 11 | public class DoubleOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | return +((Double)arg).doubleValue(); 15 | } 16 | public Object minus (Object arg) { 17 | return -((Double)arg).doubleValue(); 18 | } 19 | public Object increment (Object arg) { 20 | double tmp = ((Double)arg).doubleValue(); 21 | return ++tmp; 22 | } 23 | public Object decrement (Object arg) { 24 | double tmp = ((Double)arg).doubleValue(); 25 | return --tmp; 26 | } 27 | public Object bitComp (Object arg) { 28 | throw new IllegalArgumentException("Bitwise complement illegal on double"); 29 | } 30 | public Object logicalComp (Object arg) { 31 | throw new IllegalArgumentException("Logical complement illegal on double"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/DuckTypingTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import java.util.Collections; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests proxying of library interfaces to classes that don't declare that they implement those 13 | * interfaces but do implement the necessary methods. 14 | */ 15 | public class DuckTypingTest 16 | { 17 | public class Adder { 18 | public int value; 19 | 20 | public boolean add (Integer value) { 21 | this.value += value; 22 | return true; 23 | } 24 | } 25 | 26 | @Test public void testAddAll () { 27 | Adder a = new Adder(); 28 | Collections.addAll(a, 1, 2, 3, 4, 5); 29 | assertEquals(15, a.value); 30 | } 31 | 32 | @Test(expected=NoSuchMethodError.class) 33 | public void testMissingMethods () { 34 | Adder a = new Adder(); 35 | Collections.max(a); // will throw NSME when looking for iterator() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/BooleanOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.UnOps; 7 | 8 | /** 9 | * Implements unary operations for Boolean. 10 | */ 11 | public class BooleanOps implements UnOps 12 | { 13 | public Object plus (Object arg) { 14 | throw new IllegalArgumentException("Plus illegal on boolean"); 15 | } 16 | public Object minus (Object arg) { 17 | throw new IllegalArgumentException("Minus illegal on boolean"); 18 | } 19 | public Object increment (Object arg) { 20 | throw new IllegalArgumentException("Increment illegal on boolean"); 21 | } 22 | public Object decrement (Object arg) { 23 | throw new IllegalArgumentException("Decrement illegal on boolean"); 24 | } 25 | public Object bitComp (Object arg) { 26 | throw new IllegalArgumentException("Bitwise complement illegal on boolean"); 27 | } 28 | public Object logicalComp (Object arg) { 29 | return !((Boolean)arg).booleanValue(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/FieldInitTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests initialization of transformed primitive fields. 11 | */ 12 | public class FieldInitTest 13 | { 14 | @Test public void testInit () 15 | { 16 | assertEquals(false, boolField); 17 | assertEquals((byte)0, byteField); 18 | assertEquals((char)0, charField); 19 | assertEquals(0, intField); 20 | assertEquals(0L, longField); 21 | assertEquals(0f, floatField, 0); // third arg is allowable error 22 | assertEquals(0d, doubleField, 0); // third arg is allowable error 23 | assertEquals(null, objectField); 24 | } 25 | 26 | protected boolean boolField; 27 | protected byte byteField; 28 | protected char charField; 29 | protected int intField; 30 | protected long longField; 31 | protected float floatField; 32 | protected double doubleField; 33 | protected Object objectField; 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ArrayAccessTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests array access. 11 | */ 12 | public class ArrayAccessTest 13 | { 14 | @Test public void testArrayAccess () 15 | { 16 | String[] args = new String[] { "one", "two", "three" }; 17 | String text = ""; 18 | for (String arg : args) { 19 | text = text + arg; 20 | } 21 | assertEquals(text, "onetwothree"); 22 | text = ""; 23 | for (int ii = 0; ii < args.length; ii++) { 24 | text = text + args[ii]; 25 | } 26 | assertEquals(text, "onetwothree"); 27 | } 28 | 29 | @Test public void testArrayIndexedMethodCall () 30 | { 31 | String[] args = new String[] { "one", "two", "three" }; 32 | int length = 0; 33 | for (int ii = 0; ii < args.length; ii++) { 34 | length += args[ii].length(); 35 | } 36 | assertEquals(length, 11); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/NameCollideTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.awt.event.*; 7 | import javax.swing.JButton; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests some annoying name collision behavior caused by TreeMaker.Type(). 14 | */ 15 | public class NameCollideTest 16 | { 17 | public static class MouseListener extends MouseAdapter { 18 | public void mouseClicked (MouseEvent e) { /* yay! */ } 19 | } 20 | 21 | @Test public void testShadowedName () { 22 | JButton button = new JButton(); 23 | // ensure that this gets transformed into: 24 | // RT.invoke("addMouseListener", new Class{ java.awt.event.MouseListener.class }, ...) 25 | // rather than 26 | // RT.invoke("addMouseListener", new Class{ MouseListener.class }, ...) 27 | // which will cause badness due to the shadowing MouseListener above. 28 | button.addMouseListener(new MouseListener()); 29 | assertTrue(1 == 1); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/StaticMethodAmbiguousInterfaceTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package MyInterfaceTest; 5 | 6 | import org.junit.Test; 7 | 8 | import org.ductilej.tests.helper.one.*; 9 | import org.ductilej.tests.helper.two.*; 10 | 11 | /** 12 | * Demonstrates similar compiler bug as StaticMethodResolutionTest.java: this 13 | * time the ambiguity results from the two identically named interfaces (from 14 | * different packages) being imported. 15 | */ 16 | public class StaticMethodAmbiguousInterfaceTest 17 | implements org.ductilej.tests.helper.one.MyInterfaceTest 18 | { 19 | @Test public void testInvokeFoo () { 20 | // The following line results in the following compiler error: 21 | // "reference to MyInterfaceTest is ambiguous, both interface 22 | // org.ductilej.tests.helper.two.MyInterfaceTest in 23 | // org.ductilej.tests.helper.two and interface 24 | // org.ductilej.tests.helper.one.MyInterfaceTest in 25 | // org.ductilej.tests.helper.one match". 26 | foo(); 27 | } 28 | 29 | private static void foo () { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/QualifiedThisTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | public class QualifiedThisTest 10 | { 11 | public static class A { 12 | public String foo () { 13 | return "foo"; 14 | } 15 | } 16 | 17 | public static class B extends A { 18 | public class C { 19 | public String bar () { 20 | return foo(); // --> RT.invoke("foo", B.this); not A.this 21 | } 22 | } 23 | } 24 | 25 | @Test public void testQualifiedThis () 26 | { 27 | B b = new B(); 28 | B.C c = b.new C(); 29 | assertEquals("foo", c.bar()); 30 | 31 | // if we are creating an anonymous inner class, we need to be sure that we cast the 32 | // enclosing class reference back to its static type 33 | B.C c2 = b.new C() { 34 | public String bar () { 35 | return "overridden"; 36 | } 37 | }; 38 | assertEquals("overridden", c2.bar()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/NestedTypeVarTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.AbstractMap; 7 | 8 | import org.junit.Test; 9 | 10 | /** 11 | * Tests type resolution of some complex nested type variables. 12 | */ 13 | public class NestedTypeVarTest 14 | { 15 | static abstract class Impl extends AbstractMap 16 | { 17 | final class Segment { 18 | public E getEntry (Object key) { 19 | return null; 20 | } 21 | public boolean removeEntry(E entry) { 22 | return false; 23 | } 24 | } 25 | } 26 | 27 | static abstract class ComputingImpl extends Impl { 28 | public void test (Object k) { 29 | @SuppressWarnings("unchecked") K key = (K) k; 30 | Segment segment = null; // TODO 31 | E entry = segment.getEntry(key); 32 | segment.removeEntry(entry); 33 | } 34 | } 35 | 36 | @Test public void testNoop () 37 | { 38 | // nothing to test here, we just want to resolve types above 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/StaticMethodResolutionTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | // This package name "StaticMethodResolutionTestPackage" must be identical to the simple name of 5 | // the class defined in the source file StaticMethodResolutionTestPackage.java. 6 | package StaticMethodResolutionTestPackage; 7 | 8 | import org.junit.Test; 9 | 10 | // Import is required to demonstrate bug: importing a class with the same name 11 | // as the current package breaks static method resolution at compile time 12 | // presumably due to name ambiguities which Ductile attempts to resolve 13 | // differently from regular Java compilation. 14 | import org.ductilej.tests.helper.StaticMethodResolutionTestPackage; 15 | 16 | /** 17 | * Tests that static methods are correctly resolved when a class with the same 18 | * simple name as the current package is imported. 19 | */ 20 | public class StaticMethodResolutionTest 21 | { 22 | public static void someStaticMethod () { 23 | // noop 24 | } 25 | 26 | @Test public void testDummy () { 27 | // Ductile generates erroneous "cannot find symbol" on the following line. 28 | someStaticMethod(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ArrayCreateTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests array creation and assignment. 11 | */ 12 | public class ArrayCreateTest 13 | { 14 | @Test public void testArrayCreate () 15 | { 16 | Integer foo = new Integer(5); 17 | Number[][] nums = new Number[][] { { foo, 5f, 5 } }; 18 | assertEquals(nums[0][0], foo); 19 | assertEquals(nums[0][1], 5f); 20 | assertEquals(nums[0][2], 5); 21 | } 22 | 23 | @Test public void testArrayCreateDimsCast () 24 | { 25 | int dim1 = 3, dim2 = 5; 26 | Number[][] nums2 = new Number[dim1][dim2]; 27 | assertTrue(nums2.length == dim1); 28 | if (dim1 > 0) { 29 | assertTrue(nums2[0].length == dim2); 30 | } 31 | } 32 | 33 | @Test public void testArrayInitializer () 34 | { 35 | int[] data = { 1, 2, 3, 4 }; 36 | assertTrue(data[0] == 1); 37 | } 38 | 39 | @Test public void testByteArrayInit () 40 | { 41 | byte[] b1 = { 0, 1, -128, 44, 12 }; 42 | assertEquals(-128, b1[2]); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ReflectiveInvokeTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.lang.reflect.Method; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests the wrapping and unwrapping of arguments that takes place when we issue reflective calls 13 | * through yet another layer of reflection. 14 | */ 15 | public class ReflectiveInvokeTest 16 | { 17 | @Test public void testReflectiveInvoke () throws Exception { 18 | int ran = 0; 19 | for (Method m : ReflectiveInvokeTest.class.getDeclaredMethods()) { 20 | if (m.getName().startsWith("testMethod")) { 21 | Object[] args = new Object[m.getParameterTypes().length]; 22 | assertEquals("ran", invoke(m, null, args)); 23 | ran += 1; 24 | } 25 | } 26 | assertEquals(1, ran); 27 | } 28 | 29 | protected static Object invoke (Method m, Object instance, Object[] params) throws Exception { 30 | m.setAccessible(true); 31 | return m.invoke(instance, params); 32 | } 33 | 34 | protected static String testMethod (String arg) { 35 | return "ran"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ArrayTypeTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.io.OutputStream; 7 | import java.io.PrintWriter; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests array related type resolution. 14 | */ 15 | public class ArrayTypeTest 16 | { 17 | @Test public void testResolveArrayLengthType () 18 | { 19 | char[] foo = "one".toCharArray(); 20 | assertEquals(1, noop(foo.length)); 21 | } 22 | 23 | @Test public void testResolveArrayType () 24 | { 25 | assertEquals(2, noop(new Integer[] { 1, 2, 3 })); 26 | } 27 | 28 | protected static void noop (Object value) { 29 | // noop! 30 | } 31 | 32 | protected static int noop (int value) { 33 | return 1; 34 | } 35 | 36 | protected static int noop (Integer[] values) { 37 | return 2; 38 | } 39 | 40 | protected class MyPrintWriter extends PrintWriter { 41 | public MyPrintWriter (OutputStream out) { 42 | super(out); 43 | } 44 | 45 | public void println (char[] data) { 46 | super.println(data); // checks typeToTree for array types 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/IterableTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Iterator; 8 | 9 | import org.junit.Test; 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Tests handling of duck-typed iterables. 14 | */ 15 | public class IterableTest 16 | { 17 | @Test public void testDuckTypedIterable () { 18 | Object foo = new Object() { 19 | public Iterator iterator () { 20 | return _list.iterator(); 21 | } 22 | protected ArrayList _list = new ArrayList(); { 23 | _list.add("One"); 24 | } 25 | }; 26 | for (String item : foo) { 27 | assertEquals("One", item); 28 | } 29 | } 30 | 31 | @Test(expected=ClassCastException.class) 32 | public void testDuckTypedNonIterable () { 33 | Object foo = new Object() { 34 | public String iterator () { 35 | return "Ohai!"; 36 | } 37 | }; 38 | // will throw CCE, because iterator() returns non-Iterator 39 | for (String item : foo) { 40 | assertEquals("One", item); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ConversionTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests various places where implicit widening conversion must be performed. 11 | */ 12 | public class ConversionTest 13 | { 14 | @Test public void testInitializerConversion () { 15 | long value = VALUE; 16 | assertEquals(RESULT, A + B * value); 17 | } 18 | 19 | @Test public void testAssignmentConversion () { 20 | long value = 0L; 21 | value = VALUE; 22 | assertEquals(RESULT, A + B * value); 23 | } 24 | 25 | @Test public void testReturnValueConversion () { 26 | assertEquals(RESULT, A + B * getValue()); 27 | } 28 | 29 | @Test public void testArgumentConversion () { 30 | assertEquals(469230040, compute(VALUE)); 31 | } 32 | 33 | protected static long compute (long value) { 34 | return A + B * value; 35 | } 36 | 37 | protected static long getValue () { 38 | return VALUE; 39 | } 40 | 41 | protected static final long A = 13774830040L; 42 | protected static final int B = -154; 43 | protected static final int VALUE = 86400000; 44 | protected static final int RESULT = 469230040; 45 | } 46 | -------------------------------------------------------------------------------- /docs/wasp-2010-2-22-src/bggen.java: -------------------------------------------------------------------------------- 1 | import java.awt.Color; 2 | import java.awt.Graphics2D; 3 | import java.io.File; 4 | import javax.imageio.ImageIO; 5 | import java.awt.image.BufferedImage; 6 | 7 | public class bggen 8 | { 9 | public static final int WIDTH = 824; 10 | public static final int ROW_HEIGHT = 25; 11 | public static final int ROWS = 24; 12 | public static final int GAP = 4; 13 | 14 | public static void main (String[] args) 15 | throws Exception 16 | { 17 | BufferedImage hole = ImageIO.read(new File("hole.png")); 18 | 19 | BufferedImage image = new BufferedImage( 20 | WIDTH+2*hole.getWidth(), ROW_HEIGHT*ROWS+2*GAP, BufferedImage.TYPE_INT_ARGB); 21 | Graphics2D gfx = image.createGraphics(); 22 | gfx.setColor(new Color(0xD0, 0xF0, 0xD0, 0x99)); 23 | for (int rr = 0; rr < ROWS; rr += 6) { 24 | gfx.fillRect(hole.getWidth(), GAP+rr*ROW_HEIGHT, WIDTH, 3*ROW_HEIGHT); 25 | } 26 | for (int rr = 0; rr < ROWS; rr += 2) { 27 | gfx.drawImage(hole, 0, GAP+rr*ROW_HEIGHT, null); 28 | gfx.drawImage(hole, WIDTH+hole.getWidth(), GAP+rr*ROW_HEIGHT, null); 29 | } 30 | gfx.dispose(); 31 | ImageIO.write(image, "png", new File("background.png")); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/InferredReceiverTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import org.junit.Test; 7 | import org.junit.Assert; 8 | import static org.junit.Assert.*; 9 | 10 | /** 11 | * Tests various circumstances in which we must use heuristics to determine whether a receiver is 12 | * static. 13 | */ 14 | public class InferredReceiverTest 15 | { 16 | public static class Tester { 17 | public static String staticTest (String arg) { 18 | return "static:" + arg; 19 | } 20 | 21 | public String test (String arg) { 22 | return "non-static:" + arg; 23 | } 24 | } 25 | 26 | @Test public void testSimpleStatic () { 27 | assertEquals("static:foo", Tester.staticTest("foo")); 28 | } 29 | 30 | @Test public void testSimpleNonStatic () { 31 | Object t = new Tester(); 32 | // TODO: we fail to resolve assertEquals() because t.test cannot be resolved 33 | assertEquals("non-static:foo", t.test("foo")); 34 | } 35 | 36 | @Test public void testArrayReceiver () { 37 | Object[] ts = { new Tester() }; 38 | // TODO: we fail to resolve assertEquals() because ts[0].test cannot be resolved 39 | assertEquals("non-static:foo", ts[0].test("foo")); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ChainedConsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests the handling of chained constructors. 11 | */ 12 | public class ChainedConsTest 13 | { 14 | public static class A { 15 | public final int foo; 16 | 17 | public A (int foo) { 18 | this.foo = foo; 19 | } 20 | 21 | public A (String foo) { 22 | this.foo = Integer.valueOf(foo); 23 | } 24 | } 25 | 26 | public static class B extends A { 27 | public B (int foo, int bar) { 28 | super(foo); 29 | } 30 | } 31 | 32 | public static class C extends A { 33 | public C (int foo) { 34 | super(foo); 35 | } 36 | 37 | public C (String foo) { 38 | super(foo); 39 | } 40 | 41 | public C (int foo, int bar) { 42 | this(""+foo); 43 | } 44 | } 45 | 46 | @Test public void testChainedCons () 47 | { 48 | A ab = new B(42, 42); 49 | assertEquals(ab.foo, 42); 50 | 51 | A ac1 = new C(42); 52 | assertEquals(ac1.foo, 42); 53 | 54 | A ac2 = new C(42, 42); 55 | assertEquals(ac2.foo, 42); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/HashCodeTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests (non-)transformation of hashcode signature. 11 | */ 12 | public class HashCodeTest 13 | { 14 | public class Key 15 | { 16 | public /* final TODO: this hoses the constructor */ int one, two; 17 | 18 | public Key (int one, int two) { 19 | this.one = one; 20 | this.two = two; 21 | } 22 | 23 | @Override 24 | public boolean equals (Object other) { 25 | return (other instanceof Key) && 26 | ((Key)other).one == this.one && 27 | ((Key)other).two == this.two; 28 | } 29 | 30 | @Override 31 | public int hashCode () { 32 | return 37 * this.one + this.two; 33 | } 34 | 35 | @Override 36 | public String toString () { 37 | return "[" + this.one + ", " + this.two + "]"; 38 | } 39 | } 40 | 41 | @Test 42 | public void hashCodeTest () 43 | { 44 | Key key = new Key(42, -24); 45 | org.junit.Assert.assertTrue(key.hashCode() == (-24 + 37 * 42)); 46 | assertTrue(key.hashCode() == (37 * 42 + -24)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ParamVarArgsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests handling of varags with parameterized variable argument. Edge case extraordinaire! 11 | */ 12 | public class ParamVarArgsTest 13 | { 14 | public static interface Predicate { 15 | boolean apply (T arg); 16 | } 17 | 18 | public static Predicate or (final Predicate... preds) { 19 | return new Predicate() { 20 | public boolean apply (T arg) { 21 | for (Predicate pred : preds) { 22 | if (pred.apply(arg)) { 23 | return true; 24 | } 25 | } 26 | return false; 27 | } 28 | }; 29 | } 30 | 31 | @SuppressWarnings("unchecked") // this use of parameterized varargs is safe 32 | @Test public void testParamVarArgs () { 33 | Predicate test = or(FALSE); 34 | assertEquals(false, test.apply(1)); 35 | } 36 | 37 | protected static final Predicate FALSE = new Predicate() { 38 | public boolean apply (Integer arg) { 39 | return false; 40 | } 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/LibraryFieldAssignTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.awt.Component; 7 | import javax.swing.JTree; 8 | import javax.swing.tree.DefaultTreeCellRenderer; 9 | 10 | import org.junit.Test; 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Does something extraordinary. 15 | */ 16 | public class LibraryFieldAssignTest 17 | { 18 | public static class TestRenderer extends DefaultTreeCellRenderer { 19 | @Override 20 | public Component getTreeCellRendererComponent ( 21 | JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, 22 | boolean hasFocus) { 23 | // assigning to a field in our superclass which will not have been detyped 24 | selected = sel; 25 | // also assigning to field in super class, this time via explicit this 26 | this.hasFocus = hasFocus; 27 | return null; 28 | } 29 | 30 | public boolean getSelected () { 31 | return selected; 32 | } 33 | } 34 | 35 | @Test public void testFieldAssign () 36 | { 37 | TestRenderer t = new TestRenderer(); 38 | t.getTreeCellRendererComponent(null, null, true, true, true, 0, true); 39 | assertEquals(true, t.getSelected()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/BinOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime; 5 | 6 | /** 7 | * Encapsulates binary operations on primitive types. Specialized instances of this class are 8 | * automatically generated for the cartesian product of all compatible primitive types for 9 | * reasonably fast dispatch of ad-hoc polymorphic binary operators. 10 | */ 11 | public interface BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs); 14 | public Object minus (Object lhs, Object rhs); 15 | public Object multiply (Object lhs, Object rhs); 16 | public Object divide (Object lhs, Object rhs); 17 | public Object remainder (Object lhs, Object rhs); 18 | 19 | public Object bitOr (Object lhs, Object rhs); 20 | public Object bitAnd (Object lhs, Object rhs); 21 | public Object bitXor (Object lhs, Object rhs); 22 | 23 | public Object leftShift (Object lhs, Object rhs); 24 | public Object rightShift (Object lhs, Object rhs); 25 | public Object unsignedRightShift (Object lhs, Object rhs); 26 | 27 | public boolean equalTo (Object lhs, Object rhs); 28 | public boolean lessThan (Object lhs, Object rhs); 29 | public boolean lessThanEq (Object lhs, Object rhs); 30 | public boolean greaterThan (Object lhs, Object rhs); 31 | public boolean greaterThanEq (Object lhs, Object rhs); 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ParameterizedThisTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.concurrent.Callable; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests handling of a parameterized 'this' reference. 13 | */ 14 | public class ParameterizedThisTest 15 | { 16 | public static abstract class A { 17 | public abstract E getElement (); 18 | } 19 | 20 | public static abstract class B extends A> { 21 | public V getValue () throws Exception { 22 | // we're testing the resolution of the 'this' expression which should have type B 23 | // rather than just a bare B, if it has the latter, then getElement() will have a 24 | // return type of Object rather than V 25 | return this.getElement().call(); 26 | } 27 | } 28 | 29 | @Test public void testPT () throws Exception 30 | { 31 | B b = new B() { 32 | public Callable getElement () { 33 | return new Callable() { 34 | public String call () { 35 | return "Yay!"; 36 | } 37 | }; 38 | } 39 | }; 40 | assertEquals("Yay!", b.getValue()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/RawVarArgsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests our varargs machinations in the presence of raw types (which people unfortunately use, so 11 | * we have to handle them reasonably). 12 | */ 13 | public class RawVarArgsTest 14 | { 15 | public static interface Predicate { 16 | boolean apply (T arg); 17 | } 18 | 19 | public static Predicate and (final Predicate... preds) { 20 | return new Predicate() { 21 | public boolean apply (T arg) { 22 | for (Predicate pred : preds) { 23 | if (!pred.apply(arg)) { 24 | return false; 25 | } 26 | } 27 | return true; 28 | } 29 | }; 30 | } 31 | 32 | @Test @SuppressWarnings({"unchecked", "rawtypes"}) 33 | public void testRawVarArgs () { 34 | Predicate[] array = { FALSE }; 35 | Predicate predicate = and(array); 36 | assertFalse(predicate.apply(1)); 37 | } 38 | 39 | protected static final Predicate FALSE = new Predicate() { 40 | public boolean apply (Object arg) { 41 | return false; 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/EnumTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | public class EnumTest 10 | { 11 | public enum TestEnum { A, B, C, D }; 12 | 13 | // tests restoring static type in Enum constructors 14 | public enum StringEnum { 15 | A(get("A")), 16 | B(get("B")), 17 | C(get("C")) { 18 | // this constant declaration is legal, even though static declarations in general are 19 | // not legal in inner classes (of which a "customized" enum value is one) 20 | private static final String testConstant = "some value"; 21 | }; 22 | 23 | StringEnum (String string) { 24 | _string = string; 25 | } 26 | 27 | public String toString () { 28 | return _string; 29 | } 30 | 31 | protected String _string; 32 | } 33 | 34 | @Test public void testValueOf () 35 | { 36 | Class base_type = TestEnum.class; 37 | @SuppressWarnings({"unchecked","rawness","rawtypes"}) 38 | Object eval = Enum.valueOf((Class)base_type, "B"); 39 | assertEquals(TestEnum.B, eval); 40 | 41 | assertEquals("Bgot", StringEnum.B.toString()); 42 | } 43 | 44 | protected static String get (String value) 45 | { 46 | return value + "got"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ArrayStoreTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests array store. 11 | */ 12 | public class ArrayStoreTest 13 | { 14 | @Test public void testArrayStore () 15 | { 16 | String[] test1 = new String[] { "zero", "one", "two" }; 17 | assertEquals(test1[0] + " " + test1[1] + " " + test1[2], "zero one two"); 18 | String[] test2 = new String[3]; 19 | assertTrue(test2[0] == null); 20 | assertTrue(test2[1] == null); 21 | assertTrue(test2[2] == null); 22 | test2[0] = "0"; 23 | test2[1] = "1"; 24 | test2[2] = "2"; 25 | assertEquals(test2[0], "0"); 26 | assertEquals(test2[1], "1"); 27 | assertEquals(test2[2], "2"); 28 | } 29 | 30 | @Test public void testPrimitiveArrayStore () 31 | { 32 | int[] ints = new int[4]; 33 | ints[0] = 1; 34 | ints[1] = 2; 35 | for (int ii = 2; ii < ints.length; ii++) { 36 | ints[ii] = ii; 37 | } 38 | } 39 | 40 | @Test public void testIllegalArrayStore () 41 | { 42 | try { 43 | Object[] foo = new String[1]; 44 | foo[0] = 5; 45 | fail("Should have failed with ASE"); 46 | } catch (ArrayStoreException ase) { 47 | // expected 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/BasicAssignTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests various assignment transformations. 11 | */ 12 | public class BasicAssignTest 13 | { 14 | // make sure the type of this initializer expression gets cast back to the declared type as we 15 | // don't detype static final fields 16 | public static final Boolean debug = Boolean.getBoolean("debug"); 17 | 18 | public class MutableInt { 19 | public int value; 20 | public MutableInt (int value) { 21 | this.value = value; 22 | } 23 | } 24 | 25 | @Test public void assignTest () 26 | { 27 | int ivalue = 42; 28 | assertTrue(ivalue == 42); 29 | String svalue = "hello"; 30 | assertEquals(svalue, "hello"); 31 | int[] iarray = new int[1]; 32 | iarray[0] = 42; 33 | assertEquals(iarray[0], 42); 34 | MutableInt iobj = new MutableInt(42); 35 | iobj.value = -24; 36 | assertEquals(iobj.value, -24); 37 | } 38 | 39 | @Test public void testDefiniteAssign () 40 | { 41 | String a = "Hello!", b; 42 | boolean cond = true; 43 | if (cond && (b = next()) != null) { 44 | a = b; 45 | } 46 | assertEquals("Hello!", a); 47 | } 48 | 49 | protected static String next() { 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/InvokeNonStaticTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests the detection and invocation of non-static methods. 11 | */ 12 | public class InvokeNonStaticTest 13 | { 14 | public class Foo 15 | { 16 | public int triple (int value) { 17 | return value * 3; 18 | } 19 | 20 | public int something (int value) { 21 | return triple(value); 22 | } 23 | 24 | public String noop (String value) { 25 | return value; 26 | } 27 | } 28 | 29 | public Foo bar = new Foo(); 30 | 31 | @Test public void testInvokeNonStatic () 32 | { 33 | Foo test = new Foo(); 34 | int value = test.triple(25); 35 | assertTrue(value == 75); 36 | int val2 = bar.triple(3); 37 | assertTrue(val2 == 9); 38 | assertEquals(9, test.something(3)); 39 | 40 | Foo bar = new Foo() { 41 | @Override public int something (int value) { 42 | return 2 * triple(value); 43 | } 44 | }; 45 | assertEquals(18, bar.something(3)); 46 | 47 | // make sure we generate: RT.invoke(foo, "noop", (Object)null) 48 | assertTrue(test.noop(null) == null); 49 | } 50 | 51 | @Test public void testStringLitReceiver () 52 | { 53 | assertEquals("foo".length(), 3); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/SuperSuperTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests detecting as library method a method overridden in a non-library super class. 11 | */ 12 | public class SuperSuperTest 13 | { 14 | public static class A implements Comparable 15 | { 16 | public final String value; 17 | public A (String value) { 18 | this.value = value; 19 | } 20 | 21 | public int compareTo (A other) { 22 | return value.compareTo(other.value); 23 | } 24 | 25 | public int foo (A other) { 26 | return value.compareTo(other.value); 27 | } 28 | 29 | public String toString () { 30 | return value; 31 | } 32 | } 33 | 34 | public static class B extends A 35 | { 36 | public B (String value) { 37 | super(value); 38 | } 39 | 40 | @Override public int compareTo (A other) { 41 | return super.compareTo(other); 42 | } 43 | 44 | @Override public int foo (A other) { 45 | return super.foo(other); 46 | } 47 | 48 | @Override public String toString () { 49 | return "b:" + value; 50 | } 51 | } 52 | 53 | @Test public void testSuperSuper () 54 | { 55 | B b1 = new B("one"); 56 | B b2 = new B("two"); 57 | assertTrue(b1.compareTo(b2) < 0); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/PromoteTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests fiddly bits related to primitive type promotion. 11 | */ 12 | public class PromoteTest 13 | { 14 | @Test public void testNarrow () 15 | { 16 | short value = 1; // int literal narrowed to short 17 | assertEquals((short)1, value); 18 | 19 | value = FIVE; 20 | assertEquals((short)5, value); 21 | } 22 | 23 | @Test public void testShortPromote () 24 | { 25 | short val1 = 1, val2 = 2; 26 | Object val = val1 + val2; // + result is numeric promoted to int 27 | assertEquals(Integer.class, val.getClass()); 28 | } 29 | 30 | @Test public void testLongNonPromote () 31 | { 32 | long val1 = 1, val2 = 2; 33 | Object val = val1 + val2; // + result remains long 34 | assertEquals(Long.class, val.getClass()); 35 | } 36 | 37 | @Test public void testTypingAndRuntimeNonPromote () 38 | { 39 | // ensure that during detyping the type of _nextInternCode++ resolves to short not int, and 40 | // ensures that at runtime we also don't inadvertently promote the short to an int 41 | short value = box(_counter++); 42 | assertEquals(1, value); 43 | } 44 | 45 | protected Short box (short code) 46 | { 47 | return code; 48 | } 49 | 50 | protected short _counter = 1; 51 | protected static final int FIVE = 5; 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/SelectTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests select transformation and non-transformation. 11 | */ 12 | public class SelectTest 13 | { 14 | public static final Value twofour = new Value(24); 15 | 16 | @Test public void testSelect () 17 | { 18 | Value five = new Value(5); 19 | assertTrue(five.value == 5); 20 | assertTrue(toValue(19).value == 19); 21 | assertTrue(five.someText.length() == 10); 22 | assertTrue(five.moreText().length() == 10); 23 | // SelectTest.Value shouldn't be transformed, expr.value should 24 | assertTrue(new SelectTest.Value(180).value == 180); 25 | // since SelectTest.Value is a class name, expr.theAnswer is not xformed 26 | assertTrue(SelectTest.Value.theAnswer == 42); 27 | // SelectTest.twofour should not be transformed, expr.value should 28 | assertTrue(SelectTest.twofour.value == 24); 29 | } 30 | 31 | protected Value toValue (int value) 32 | { 33 | return new Value(value); 34 | } 35 | 36 | protected static class Value 37 | { 38 | public static int theAnswer = 42; 39 | 40 | public int value; 41 | 42 | public String someText = "Some text!"; 43 | 44 | public Value (int value) { 45 | this.value = value; 46 | } 47 | 48 | public String moreText () { 49 | return "More text!"; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ConditionalTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests handling of various conditional statements. 11 | */ 12 | public class ConditionalTest 13 | { 14 | @Test public void whileTest () 15 | { 16 | int ii = 0; 17 | while (ii < 5) { 18 | ii += 1; 19 | } 20 | assertEquals(ii, 5); 21 | } 22 | 23 | @Test public void doTest () 24 | { 25 | int ii = 0; 26 | do { 27 | ii += 1; 28 | } while (ii < 5); 29 | assertEquals(ii, 5); 30 | } 31 | 32 | @Test public void ifTest () 33 | { 34 | int ii = 0; 35 | if (ii < 0) { 36 | ii = 5; 37 | } 38 | assertEquals(ii, 0); 39 | } 40 | 41 | @Test public void forTest () 42 | { 43 | int count = 0; 44 | for (int ii = 0; ii < 5; ii++) { 45 | count = count + 1; 46 | } 47 | assertEquals(count, 5); 48 | } 49 | 50 | @Test public void condExprTypeTest () 51 | { 52 | // ensure that resolveType() on a conditional expression with a null in one or the other 53 | // position properly returns the type of the non-null expression 54 | int a = 0; 55 | foo(a < 2 ? "bar" : null); 56 | foo(a < 2 ? null : "bar"); 57 | } 58 | 59 | protected void foo (String value) 60 | { 61 | } 62 | 63 | protected void foo (Integer value) 64 | { 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/SneakyThrowTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests the sneaky throwing of checked exceptions. 11 | */ 12 | public class SneakyThrowTest 13 | { 14 | @Test public void testSneakyThrow () throws Exception { 15 | try { 16 | SneakyThrower.sneakyThrow(); 17 | fail("No exception thrown"); 18 | } catch (Exception e) { 19 | if (!(e instanceof SomeCheckedException)) { 20 | throw e; 21 | } 22 | } 23 | } 24 | 25 | @Test public void testClassForName () throws Exception { 26 | // tests that we properly insert a cast to Class around this Class.forName expr 27 | Object o = Class.forName("java.lang.Thread").newInstance(); 28 | assertEquals(Thread.class, o.getClass()); 29 | } 30 | 31 | protected static class SneakyThrower { 32 | public static void sneakyThrow() { 33 | try { 34 | SneakyThrower.class.newInstance(); 35 | } catch (IllegalAccessException e) { 36 | fail("Illegal access: " + e); 37 | } catch (InstantiationException e) { 38 | fail("Instantiation exception: " + e); 39 | } 40 | } 41 | SneakyThrower() throws SomeCheckedException { 42 | throw new SomeCheckedException(); 43 | } 44 | } 45 | 46 | protected static class SomeCheckedException extends Exception { 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/detyper/DetypeContext.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.detyper; 5 | 6 | import com.sun.tools.javac.code.Lint; 7 | import com.sun.tools.javac.code.Scope; 8 | import com.sun.tools.javac.code.Symbol; 9 | import com.sun.tools.javac.tree.JCTree.JCExpression; 10 | 11 | /** 12 | * Used to compute scopes during the detyping process. 13 | */ 14 | public class DetypeContext 15 | { 16 | /** The symbols in scope in this context. */ 17 | public Scope scope = null; 18 | 19 | /** The parent of the anonymous inner class currently being created, if any. */ 20 | public Symbol anonParent; 21 | 22 | /** The type of the current array initializer element type, if any. */ 23 | public JCExpression arrayElemType; 24 | 25 | /** True if we're in the middle of processing a call to this() or super(). */ 26 | public boolean inChainedCons; 27 | 28 | /** A record of the lint/SuppressWarnings currently in effect. */ 29 | public Lint lint; 30 | 31 | /** 32 | * Duplicates this context with the specified new scope. 33 | */ 34 | public DetypeContext dup (Scope scope) 35 | { 36 | DetypeContext ctx = new DetypeContext(); 37 | ctx.scope = scope; 38 | ctx.anonParent = anonParent; 39 | ctx.arrayElemType = arrayElemType; 40 | ctx.inChainedCons = inChainedCons; 41 | return ctx; 42 | } 43 | 44 | /** 45 | * Duplicates this context with the same scope. 46 | */ 47 | public DetypeContext dup () 48 | { 49 | return dup(this.scope); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ThrowsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.io.IOException; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests checked exception throwing and catching. 13 | */ 14 | public class ThrowsTest 15 | { 16 | @Test public void testThrows () throws IOException 17 | { 18 | try { 19 | thrower(); 20 | } catch (java.io.FileNotFoundException fnfe) { 21 | return; 22 | } catch (IOException ioe) { 23 | // test detyping of vars inside catch block; we detype inside, we don't detype vars in 24 | // the actual catch clause (ioe above) 25 | int pos = ioe.getMessage().indexOf('.'); 26 | return; 27 | } catch (NullPointerException npe) { 28 | return; 29 | } 30 | fail("Should not be reached."); 31 | } 32 | 33 | protected void thrower () throws IOException 34 | { 35 | throw new IOException("Oh noez!"); 36 | } 37 | 38 | protected void castingThrower () throws IOException 39 | { 40 | Throwable ioe = new IOException(); 41 | throw (IOException) ioe; 42 | } 43 | 44 | protected void nonCastingThrower () throws IOException 45 | { 46 | IOException ioe = new IOException(); 47 | throw ioe; 48 | } 49 | 50 | protected void callingThrower () throws IOException 51 | { 52 | throw error(); 53 | } 54 | 55 | protected static IOException error () 56 | { 57 | return new IOException(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/NullVarArgsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.lang.reflect.Constructor; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | import org.junit.Test; 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Tests varargs handling involving nulls. 15 | */ 16 | public class NullVarArgsTest 17 | { 18 | @Test public void testNullDisambig () 19 | { 20 | assertEquals(-1, varargs((Object[])null)); 21 | assertEquals(0, varargs()); 22 | assertEquals(1, varargs(1)); 23 | // this should get wrapped into a one element array containing null 24 | assertEquals(1, varargs((Object)null)); 25 | } 26 | 27 | @Test public void testVarArgsArrayType () 28 | { 29 | List list = Arrays.asList((Integer) null); 30 | Object[] array = list.toArray(); 31 | assertEquals(array.getClass(), Integer[].class); 32 | } 33 | 34 | @Test public void testLibraryNullVarArray () 35 | throws NoSuchMethodException 36 | { 37 | Constructor ctor = getClass().getDeclaredConstructor((Class[]) null); 38 | assertTrue(ctor != null); 39 | } 40 | 41 | @Test public void testNonVarArgsToVarArgs () 42 | { 43 | assertEquals("[null]", toString(new Object[] { null })); 44 | } 45 | 46 | protected static int varargs (Object... args) 47 | { 48 | return (args == null) ? -1 : args.length; 49 | } 50 | 51 | protected static String toString (Object[] elems) { 52 | return Arrays.asList(elems).toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/NullPointerExceptionTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | /* 7 | * Demonstrates an uncaught exception in Detyper. 8 | * Compilation with Detyper leads to a call stack like the following: 9 | * !!! Symbol resolution failed [expr=Foo, sym=symbol not found error] 10 | * !!! Unable to resolve type [expr=Foo, pkind=2] 11 | * !!! Symbol resolution failed [expr=Foo, sym=symbol not found error] 12 | * !!! Unable to resolve type [expr=Foo, pkind=2] 13 | * !!! Fatal error [file=RegularFileObject[/home/rcook/src/ductilej/src/org/ductilej/dtests/NullPointerExceptionTest.java]] 14 | * 15 | * 16 | * An annotation processor threw an uncaught exception. 17 | * Consult the following stack trace for details. 18 | * java.lang.NullPointerException 19 | * at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:3404) 20 | * at com.sun.tools.javac.code.Types.isSameType(Types.java:575) 21 | * at org.ductilej.detyper.Detype.isConstDecl(Detype.java:1173) 22 | * at org.ductilej.detyper.Detype.visitVarDef(Detype.java:345) 23 | * at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:712) 24 | * at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) 25 | * at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70) 26 | * at org.ductilej.util.PathedTreeTranslator.visitBlock(PathedTreeTranslator.java:105) 27 | * at org.ductilej.detyper.Detype.visitBlock(Detype.java:1098) 28 | */ 29 | public final class NullPointerExceptionTest { 30 | 31 | public NullPointerExceptionTest() { 32 | Foo[] foos; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/CoerceTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Date; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests coercions. 13 | */ 14 | public class CoerceTest 15 | { 16 | @Test public void testCastCoerce () 17 | { 18 | int a = 0; 19 | a = (int) (3 * 4.5f); 20 | assertEquals(13, a); 21 | } 22 | 23 | @Test public void testImplictEqualityCoercion () 24 | { 25 | short value = (short)0x42F0; 26 | assertTrue(value == 0x42F0); 27 | } 28 | 29 | @Test public void testCompareCoercion () 30 | { 31 | byte bvalue = (byte)0; 32 | char cvalue = (char)0; 33 | short svalue = (char)0; 34 | 35 | assertTrue(bvalue < 100); 36 | assertTrue(bvalue <= 0); 37 | assertTrue(100 > bvalue); 38 | assertTrue(0 >= bvalue); 39 | 40 | assertTrue(cvalue < 100); 41 | assertTrue(cvalue <= 0); 42 | assertTrue(100 > cvalue); 43 | assertTrue(0 >= cvalue); 44 | 45 | assertTrue(svalue < 100); 46 | assertTrue(svalue <= 0); 47 | assertTrue(100 > svalue); 48 | assertTrue(0 >= svalue); 49 | } 50 | 51 | @Test public void testCoerceReturnValue () 52 | { 53 | assertEquals(0L, new MyDate().getTime()); 54 | } 55 | 56 | protected static class MyDate extends Date { 57 | // since this overrides a library method, its signature will not be detyped 58 | @Override public long getTime () { 59 | return 0; // javac will normally coerce this int to a long, we must do so as well 60 | } 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/dtests/FindStaticMethodTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.dtests; 5 | 6 | import static java.lang.Integer.valueOf; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests the fallback method resolution code which must determine whether to call a static or 13 | * non-static method with invalid arguments. 14 | */ 15 | public class FindStaticMethodTest 16 | { 17 | public interface Database { 18 | } 19 | 20 | public static class TestDatabase { 21 | public String get (String key) { 22 | return key + "!"; 23 | } 24 | } 25 | 26 | public static String dbGet (Database db, String key) 27 | { 28 | return db.get(key); 29 | } 30 | 31 | public static void callStaticTests () 32 | { 33 | // we're in a static context here, so Ductile must be sure not to emit a non-static call 34 | String rv = dbGet(new TestDatabase(), "test"); 35 | assertEquals("test!", rv); 36 | // TODO: the following breaks because dbGet() fails to resolve, and thus we fail to resolve 37 | // the correct assertEquals() 38 | assertEquals("test!", dbGet(new TestDatabase(), "test")); 39 | } 40 | 41 | @Test public void testStaticFinding () 42 | { 43 | callStaticTests(); 44 | } 45 | 46 | @Test public void testNamedImportFinding () 47 | { 48 | Object number = "FFCC"; 49 | // valueOf takes a string (and has two single argument overloaded variants), but we should 50 | // find the two argument variant even though one of its argument types is invalid 51 | assertEquals(0xFFCC, valueOf(number, 16)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ImplInheritTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Arrays; 7 | import java.util.Comparator; 8 | import java.util.HashMap; 9 | import java.util.zip.Deflater; 10 | 11 | import org.junit.Test; 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Tests removal of "implements" declarations for application interfaces, thereby avoiding a 16 | * problem where a class that implements an application interface but inherits the implementation 17 | * of one or more methods from a library parent class ends up no longer correctly implementing the 18 | * interface because the interface was detyped but the inherited library methods were not. 19 | */ 20 | public class ImplInheritTest 21 | { 22 | public interface HasEnding { 23 | public boolean finished (); 24 | public int progress (); 25 | } 26 | 27 | public class TestImpl extends Deflater implements HasEnding { 28 | // boolean finished() is inherited from Deflater 29 | 30 | @Override // @Override will need to be stripped away 31 | public int progress () { 32 | return 0; 33 | } 34 | } 35 | 36 | public interface Cache { 37 | public int size (); 38 | } 39 | 40 | public class MyCache extends HashMap implements Cache { 41 | // this will not be detyped because it overrides an implementation in Map, but it needs to 42 | // be detyped because it's supposed to implement Cache.size, which has itself been detyped 43 | @Override public int size () { 44 | return super.size(); 45 | } 46 | } 47 | 48 | @Test public void testNoop () { 49 | HasEnding obj = new TestImpl(); 50 | assertEquals(0, obj.progress()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/InfTypeVarTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.lang.reflect.Constructor; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import com.google.common.base.Function; 11 | import com.google.common.collect.Lists; 12 | import com.google.common.collect.MapMaker; 13 | import com.google.common.collect.Maps; 14 | 15 | import org.junit.Test; 16 | import static org.junit.Assert.*; 17 | 18 | /** 19 | * Tests related to type variable inference. 20 | */ 21 | public class InfTypeVarTest 22 | { 23 | public static class Value 24 | { 25 | } 26 | 27 | public static Function newInstanceCreator (Class clazz) 28 | { 29 | final Constructor ctor; 30 | try { 31 | ctor = clazz.getConstructor(); 32 | } catch (NoSuchMethodException nsme) { 33 | throw new IllegalArgumentException(clazz + " must have a no-args constructor."); 34 | } 35 | return new Function() { 36 | public V apply (K key) { 37 | try { 38 | return ctor.newInstance(); 39 | } catch (Exception e) { 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | }; 44 | } 45 | 46 | @Test public void testTVI () 47 | { 48 | // this triggers some complex type inference, which is what we're testing 49 | Map test = new MapMaker().makeComputingMap(newInstanceCreator(Value.class)); 50 | Value v = test.get("test"); 51 | assertTrue(v == test.get("test")); 52 | } 53 | 54 | @Test public void testPut () 55 | { 56 | Map> m = Maps.newHashMap(); 57 | Value v = new Value(); 58 | m.put("Hello", Lists.newArrayList(v)); 59 | assertTrue(m.get("Hello").get(0) == v); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/OverloadTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.io.StringWriter; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import org.junit.Test; 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Tests the resolution of static method overloads. 15 | */ 16 | public class OverloadTest 17 | { 18 | public static enum Ord { ONE, TWO, THREE }; 19 | 20 | public static class Overloaded { 21 | public Ord toOrd (String value) { 22 | return OverloadTest.toOrd(value); 23 | } 24 | 25 | public Ord toOrd (int value) { 26 | return OverloadTest.toOrd(value); 27 | } 28 | } 29 | 30 | @Test public void testSwitchExprOverload () 31 | { 32 | Overloaded o = new Overloaded(); 33 | switch (o.toOrd(2)) { 34 | case ONE: assertTrue(false); break; 35 | case TWO: assertTrue(true); break; 36 | case THREE: assertTrue(false); break; 37 | } 38 | } 39 | 40 | @Test public void testTypeParamToConcrete () 41 | { 42 | StringWriter out = new StringWriter(); 43 | List strs = new ArrayList(); 44 | strs.add("one"); 45 | strs.add("two"); 46 | strs.add("three"); 47 | for (int ii = 0, ll = strs.size(); ii < ll; ii++) { 48 | out.write(strs.get(ii)); // A get() -> String get() 49 | } 50 | assertEquals(out.toString(), "onetwothree"); 51 | } 52 | 53 | protected static Ord toOrd (String value) 54 | { 55 | return Enum.valueOf(Ord.class, value); 56 | } 57 | 58 | protected static Ord toOrd (int value) 59 | { 60 | switch (value) { 61 | case 1: return Ord.ONE; 62 | case 2: return Ord.TWO; 63 | case 3: return Ord.THREE; 64 | default: throw new IllegalArgumentException(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/OverVarArgsTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Date; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests method selection of overloaded varargs methods. 13 | */ 14 | public class OverVarArgsTest 15 | { 16 | public class Varrgh { 17 | public final String name; 18 | public final int[] values; 19 | 20 | public Varrgh (String name, int... values) { 21 | this.name = name; 22 | this.values = values; 23 | } 24 | 25 | public Varrgh (int number, int... values) { 26 | this(String.valueOf(number), values); 27 | } 28 | 29 | public Varrgh (Date one, int two) { 30 | this(one.toString(), two); 31 | } 32 | 33 | public Varrgh (boolean one) { 34 | this(String.valueOf(one)); 35 | } 36 | } 37 | 38 | @Test public void testRuntimeSelect () 39 | { 40 | assertEquals(foo("one", "two", "three"), "foo(String,String...)"); 41 | assertEquals(foo("one", 2, 3), "foo(String,Integer...)"); 42 | } 43 | 44 | @Test public void testVarArgs () 45 | { 46 | // make sure none of the following throw MethodNotFoundError 47 | log("one"); 48 | log("one", (Object)new String[] { "two", "three" }); 49 | log("one", "two", "three"); 50 | } 51 | 52 | @Test public void testGroupVarArgs () 53 | { 54 | Varrgh v = new Varrgh(true); 55 | assertEquals("true", v.name); 56 | } 57 | 58 | protected static String foo (String one, String... two) 59 | { 60 | return "foo(String,String...)"; 61 | } 62 | 63 | protected static String foo (String one, Integer... two) 64 | { 65 | return "foo(String,Integer...)"; 66 | } 67 | 68 | protected static void log (String message, Object... args) 69 | { 70 | // System.out.println(message + " " + args); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /bin/genops: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | # 3 | # $Id$ 4 | # 5 | # Generates our myriad binary operator classes from a single template file. 6 | 7 | use Cwd 'realpath'; 8 | 9 | my $root = `dirname $0`; 10 | chomp($root); 11 | $root = realpath("$root/.."); 12 | my $opsdir = "$root/src/org/ductilej/runtime/ops"; 13 | 14 | my %types = ( "byte" => "Byte", 15 | "short" => "Short", 16 | "char" => "Character", 17 | "int" => "Integer", 18 | "long" => "Long", 19 | "float" => "Float", 20 | "double" => "Double" ); 21 | 22 | # First do the binops 23 | my $idata = `cat $opsdir/IntegralBinOps.tmpl`; 24 | my $fdata = `cat $opsdir/FloatingBinOps.tmpl`; 25 | 26 | foreach $left (keys %types) { 27 | foreach $right (keys %types) { 28 | my $lclass = $types{$left}; 29 | my $rclass = $types{$right}; 30 | my $xdata; 31 | if ($left eq "float" || $right eq "float" || $left eq "double" || $right eq "double") { 32 | $xdata = $fdata; 33 | } else { 34 | $xdata = $idata; 35 | } 36 | $xdata =~ s/\{left\}/$left/g; 37 | $xdata =~ s/\{right\}/$right/g; 38 | $xdata =~ s/\{LEFT\}/$lclass/g; 39 | $xdata =~ s/\{RIGHT\}/$rclass/g; 40 | my $xfile = "$opsdir/" . $lclass . $rclass . "Ops.java"; 41 | open(OUT, ">$xfile") or die "Can't write to $xfile: $!\n"; 42 | print OUT $xdata; 43 | close(OUT); 44 | } 45 | } 46 | 47 | # Then do the unops 48 | $idata = `cat $opsdir/IntegralUnOps.tmpl`; 49 | $fdata = `cat $opsdir/FloatingUnOps.tmpl`; 50 | 51 | foreach $arg (keys %types) { 52 | my $aclass = $types{$arg}; 53 | my $xdata; 54 | if ($arg eq "float" || $arg eq "double") { 55 | $xdata = $fdata; 56 | } else { 57 | $xdata = $idata; 58 | } 59 | $xdata =~ s/\{arg\}/$arg/g; 60 | $xdata =~ s/\{ARG\}/$aclass/g; 61 | my $xfile = "$opsdir/" . $aclass . "Ops.java"; 62 | open(OUT, ">$xfile") or die "Can't write to $xfile: $!\n"; 63 | print OUT $xdata; 64 | close(OUT); 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/ForeachTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Arrays; 7 | 8 | import org.junit.Test; 9 | import static org.junit.Assert.*; 10 | 11 | /** 12 | * Tests handling of various foreach expressions. 13 | */ 14 | public class ForeachTest 15 | { 16 | @Test public void testBoolean () { 17 | for (boolean v : new boolean[] { false, false }) { 18 | assertTrue(!v); 19 | } 20 | } 21 | 22 | @Test public void testByte () { 23 | for (byte v : new byte[] { 0, 0 }) { 24 | assertTrue(v == 0); 25 | } 26 | } 27 | 28 | @Test public void testShort () { 29 | for (short v : new short[] { 0, 0 }) { 30 | assertTrue(v == 0); 31 | } 32 | } 33 | 34 | @Test public void testChar () { 35 | for (char v : new char[] { 0, 0 }) { 36 | assertTrue(v == 0); 37 | } 38 | } 39 | 40 | @Test public void testInt () { 41 | for (int v : new int[] { 0, 0 }) { 42 | assertTrue(v == 0); 43 | } 44 | } 45 | 46 | @Test public void testLong () { 47 | for (long v : new long[] { 0, 0 }) { 48 | assertTrue(v == 0); 49 | } 50 | } 51 | 52 | @Test public void testFloat () { 53 | for (float v : new float[] { 0, 0 }) { 54 | assertTrue(v == 0); 55 | } 56 | } 57 | 58 | @Test public void testDouble () { 59 | for (double v : new double[] { 0, 0 }) { 60 | assertTrue(v == 0); 61 | } 62 | } 63 | 64 | @Test public void testInteger () { 65 | for (Integer v : new Integer[] { 0, 0 }) { 66 | assertTrue(v == 0); 67 | } 68 | } 69 | 70 | @Test public void testList () { 71 | for (int v : Arrays.asList(new Integer[] { 0, 0 })) { 72 | assertTrue(v == 0); 73 | } 74 | } 75 | 76 | @Test public void testUnboxedInteger () { 77 | for (int v : new Integer[] { 0, 0 }) { 78 | assertTrue(v == 0); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/OverCtorTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests handling of overloaded constructors. 11 | */ 12 | public class OverCtorTest 13 | { 14 | public static class Foo { 15 | public final String value; 16 | 17 | public Foo (Integer value) { 18 | this.value = String.valueOf(value); 19 | } 20 | 21 | // in cases of ambiguity, RT.newInstance currently chooses the last matching ctor, which in 22 | // this case will be the wrong one 23 | public Foo (String value) { 24 | this.value = value; 25 | } 26 | } 27 | 28 | @Test public void testOverCtor () { 29 | // at runtime, we won't know which constructor was desired 30 | Foo foo = new Foo((Integer)null); 31 | assertEquals("null", foo.value); 32 | } 33 | 34 | public static class A { 35 | public final String data; 36 | 37 | public A (long arg) { // detypes to A(Object,long) 38 | this.data = String.valueOf(arg); 39 | } 40 | public A (Object arg) { // detypes to A(Object,Object) 41 | this.data = String.valueOf(arg); 42 | } 43 | } 44 | 45 | public static class B extends A { 46 | public B () { 47 | super(0L); // detypes to super(0L,0L) 48 | 49 | // prior to detyping, A(long) matches during the subtyping phase and A(Object) matches 50 | // only during the method invocation conversion phase (which is never entered because a 51 | // match existed during the subtyping phase) 52 | 53 | // after detyping A(Object,long) and A(Object,Object) both match during the method 54 | // invocation conversion phase, but there's no subtype relationship between long and 55 | // Object, so neither is more specific and they are thus ambiguous 56 | } 57 | } 58 | 59 | @Test public void testAmbiguousSuperCons () { 60 | B b = new B(); 61 | assertEquals("0", b.data); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/DefApplyTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.awt.BorderLayout; 7 | import java.awt.Dimension; 8 | import java.util.Date; 9 | import javax.swing.JLabel; 10 | import javax.swing.JPanel; 11 | 12 | import org.junit.Test; 13 | import static org.junit.Assert.*; 14 | 15 | /** 16 | * Tests untyping of method defs and applications. 17 | */ 18 | public class DefApplyTest 19 | { 20 | public class Person { 21 | public Person (String name, int age) { 22 | _name = name; 23 | _age = age; 24 | } 25 | 26 | public String getName () { 27 | return _name; 28 | } 29 | 30 | public int getAge () { 31 | return _age; 32 | } 33 | 34 | public Person reproduce (String name) { 35 | return new Person(name, 0); 36 | } 37 | 38 | protected String _name; 39 | protected int _age; 40 | } 41 | 42 | public class DatePerson extends Person { 43 | public DatePerson (int age) { 44 | // ensures that RT.newInstance(Date.class, ...) detects that the arguments to super() 45 | // are in a "static" context (i.e. they cannot reference "this") 46 | super(new Date().toString(), age); 47 | } 48 | } 49 | 50 | public class MyPanel extends JPanel 51 | { 52 | public MyPanel () { 53 | setLayout(new BorderLayout()); 54 | JLabel label = new JLabel("Testing"); 55 | add(label, BorderLayout.CENTER); 56 | } 57 | 58 | public Dimension getPreferredSize () { 59 | Dimension d = super.getPreferredSize(); 60 | d.height = 50; 61 | return d; 62 | } 63 | } 64 | 65 | @Test public void testDefApply () 66 | { 67 | Person p = new Person("Theodor Geisel", 62); 68 | assertEquals(p.getName(), "Theodor Geisel"); 69 | assertEquals(p.getAge(), 62); 70 | Person p2 = p.reproduce("Sneetch"); 71 | assertEquals(p2.getName(), "Sneetch"); 72 | assertEquals(p2.getAge(), 0); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/OuterThisTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests resolution of which outer-this to use in a constructor. 11 | */ 12 | public class OuterThisTest 13 | { 14 | public class B { 15 | } 16 | 17 | public class C { 18 | public B newB () { 19 | return new B(); 20 | } 21 | public D newD () { 22 | return new D(); 23 | } 24 | } 25 | 26 | public static class D { 27 | } 28 | 29 | public class InnerA { 30 | public final String arg; 31 | public InnerA (String arg) { 32 | this.arg = arg; 33 | } 34 | } 35 | 36 | public class InnerB extends InnerA { 37 | public InnerB () { 38 | super(getOuterString()); 39 | } 40 | } 41 | 42 | public class ParentOuter { 43 | public class Inner1 { 44 | } 45 | } 46 | 47 | public class ChildOuter extends ParentOuter { 48 | public class Inner2 { 49 | public Inner1 newOne () { 50 | // this needs to xform to: RT.newInstance(Inner1.class, ChildOuter.this) not 51 | // RT.newInstance(Inner1.class, ParentOuter.this) which would naturally happen if 52 | // we just used the owner of the to be instantiated inner class 53 | return new Inner1(); 54 | } 55 | } 56 | } 57 | 58 | @Test public void testThisResolve () 59 | { 60 | C c = new C(); 61 | assertTrue(c.newB() != null); 62 | } 63 | 64 | @Test public void testNoThis () 65 | { 66 | C c = new C(); 67 | assertTrue(c.newD() != null); 68 | } 69 | 70 | @Test public void testOuterThisInSuper () 71 | { 72 | InnerB b = new InnerB(); 73 | assertEquals("Outer", b.arg); 74 | } 75 | 76 | @Test public void testParentInner1FromChildInner2 () 77 | { 78 | ChildOuter outer = new ChildOuter(); 79 | ChildOuter.Inner2 inner = outer.new Inner2(); 80 | assertTrue(inner.newOne() != null); 81 | } 82 | 83 | protected String getOuterString () 84 | { 85 | return "Outer"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/SuperCallTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.awt.Button; 7 | import java.util.ArrayList; 8 | import java.util.Collection; 9 | import java.util.Collections; 10 | 11 | import org.junit.Test; 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Tests handling of super constructors and super method calls. 16 | */ 17 | public class SuperCallTest 18 | { 19 | public static class A { 20 | public final int value; 21 | public final String text; 22 | 23 | public A (int value, String text) { 24 | this.value = value; 25 | this.text = text; 26 | } 27 | 28 | public String who () { 29 | return "A"; 30 | } 31 | 32 | public String why (String reason) { 33 | return reason; 34 | } 35 | } 36 | 37 | public static class B extends A { 38 | public B (int value) { 39 | super(value, "text"); 40 | } 41 | 42 | @Override public String who () { 43 | return "B"; 44 | } 45 | 46 | public String superwho () { 47 | return super.who(); 48 | } 49 | 50 | public String why (String reason) { 51 | return "Because " + super.why(reason); 52 | } 53 | } 54 | 55 | public static class StringList extends ArrayList 56 | { 57 | public StringList (Collection values) { 58 | super(values); 59 | } 60 | } 61 | 62 | public static class TestButton extends Button 63 | { 64 | public TestButton (String text) { 65 | super(text); 66 | } 67 | 68 | public void updateLabel (String text) { 69 | super.setLabel(text); 70 | } 71 | } 72 | 73 | @Test public void testSuperConstructor () 74 | { 75 | B b = new B(5); 76 | assertEquals(5, b.value); 77 | assertEquals("text", b.text); 78 | 79 | assertEquals("B", b.who()); 80 | assertEquals("A", b.superwho()); 81 | 82 | assertEquals("Because me", b.why("me")); 83 | 84 | StringList slist = new StringList(Collections.singleton("Hello")); 85 | assertEquals(slist.get(0), "Hello"); 86 | 87 | TestButton button = new TestButton("test"); 88 | assertEquals(button.getLabel(), "test"); 89 | button.updateLabel("newtest"); 90 | assertEquals(button.getLabel(), "newtest"); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/WildcardTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Collection; 7 | import java.util.Enumeration; 8 | import java.util.HashMap; 9 | import java.util.Iterator; 10 | import java.util.Map; 11 | 12 | import org.junit.Test; 13 | import static org.junit.Assert.*; 14 | 15 | /** 16 | * Tests wildcard types. 17 | */ 18 | public class WildcardTest 19 | { 20 | public static class A { 21 | public A (Class[] types) { 22 | } 23 | } 24 | 25 | public static class B extends A { 26 | public B () { 27 | super(TYPES); // this becomes: super(TYPES, (Class)null); 28 | // we generate the Class for the cast expression using TreeMaker.Type(), which has a 29 | // bug, which causes javac to choke way later in the Flow or Check phases, so this code 30 | // tests that our workaround for that bug is operational 31 | } 32 | 33 | protected static final Class[] TYPES = { B.class }; 34 | } 35 | 36 | @Test public void testWildcard () { 37 | Class clazz = WildcardTest.class; 38 | assertEquals("WildcardTest", clazz.getSimpleName()); 39 | 40 | Map, Integer> foo = new HashMap, Integer>(); 41 | foo.put(WildcardTest.class, 5); 42 | assertEquals(Integer.valueOf(5), foo.get(WildcardTest.class)); 43 | 44 | // iter.next() will resolve to type ? which we need to promote to Object before trying to 45 | // resolve the type of String.valueOf(); this tests that rigamarole 46 | for (Iterator iter = foo.values().iterator(); iter.hasNext(); ) { 47 | assertEquals("5", String.valueOf(iter.next())); 48 | } 49 | } 50 | 51 | public static > C addAll (C col, Enumeration enm) { 52 | while (enm.hasMoreElements()) { 53 | col.add(enm.nextElement()); 54 | } 55 | return col; 56 | } 57 | 58 | @Test public void testGetClassType () { 59 | // resolveType() on Runnable.class should yield Class 60 | takeRunnableClass(Runnable.class); 61 | 62 | // resolveType() on r.getClass() should yield Class 63 | Runnable r = new Runnable() { 64 | public void run () {} 65 | }; 66 | takeRunnableClass(r.getClass()); 67 | } 68 | 69 | protected void takeRunnableClass (Class rclass) { 70 | // nada 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Byte. 10 | */ 11 | public class ByteByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Byte)lhs).byteValue() | ((Byte)rhs).byteValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Byte)lhs).byteValue() & ((Byte)rhs).byteValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Byte)lhs).byteValue() ^ ((Byte)rhs).byteValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Byte)lhs).byteValue() << ((Byte)rhs).byteValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Byte)lhs).byteValue() >> ((Byte)rhs).byteValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Byte)lhs).byteValue() >>> ((Byte)rhs).byteValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Long. 10 | */ 11 | public class ByteLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Byte)lhs).byteValue() | ((Long)rhs).longValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Byte)lhs).byteValue() & ((Long)rhs).longValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Byte)lhs).byteValue() ^ ((Long)rhs).longValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Byte)lhs).byteValue() << ((Long)rhs).longValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Byte)lhs).byteValue() >> ((Long)rhs).longValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Byte)lhs).byteValue() >>> ((Long)rhs).longValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Long and rhs of Byte. 10 | */ 11 | public class LongByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Long)lhs).longValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Long)lhs).longValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Long)lhs).longValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Long)lhs).longValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Long)lhs).longValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Long)lhs).longValue() | ((Byte)rhs).byteValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Long)lhs).longValue() & ((Byte)rhs).byteValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Long)lhs).longValue() ^ ((Byte)rhs).byteValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Long)lhs).longValue() << ((Byte)rhs).byteValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Long)lhs).longValue() >> ((Byte)rhs).byteValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Long)lhs).longValue() >>> ((Byte)rhs).byteValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Long)lhs).longValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Long)lhs).longValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Long)lhs).longValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Long)lhs).longValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Long)lhs).longValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Long and rhs of Long. 10 | */ 11 | public class LongLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Long)lhs).longValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Long)lhs).longValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Long)lhs).longValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Long)lhs).longValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Long)lhs).longValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Long)lhs).longValue() | ((Long)rhs).longValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Long)lhs).longValue() & ((Long)rhs).longValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Long)lhs).longValue() ^ ((Long)rhs).longValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Long)lhs).longValue() << ((Long)rhs).longValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Long)lhs).longValue() >> ((Long)rhs).longValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Long)lhs).longValue() >>> ((Long)rhs).longValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Long)lhs).longValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Long)lhs).longValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Long)lhs).longValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Long)lhs).longValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Long)lhs).longValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteShortOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Short. 10 | */ 11 | public class ByteShortOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Short)rhs).shortValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Short)rhs).shortValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Short)rhs).shortValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Short)rhs).shortValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Short)rhs).shortValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Byte)lhs).byteValue() | ((Short)rhs).shortValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Byte)lhs).byteValue() & ((Short)rhs).shortValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Byte)lhs).byteValue() ^ ((Short)rhs).shortValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Byte)lhs).byteValue() << ((Short)rhs).shortValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Byte)lhs).byteValue() >> ((Short)rhs).shortValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Byte)lhs).byteValue() >>> ((Short)rhs).shortValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Short)rhs).shortValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Short)rhs).shortValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Short)rhs).shortValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Short)rhs).shortValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Short)rhs).shortValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongShortOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Long and rhs of Short. 10 | */ 11 | public class LongShortOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Long)lhs).longValue() + ((Short)rhs).shortValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Long)lhs).longValue() - ((Short)rhs).shortValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Long)lhs).longValue() * ((Short)rhs).shortValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Long)lhs).longValue() / ((Short)rhs).shortValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Long)lhs).longValue() % ((Short)rhs).shortValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Long)lhs).longValue() | ((Short)rhs).shortValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Long)lhs).longValue() & ((Short)rhs).shortValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Long)lhs).longValue() ^ ((Short)rhs).shortValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Long)lhs).longValue() << ((Short)rhs).shortValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Long)lhs).longValue() >> ((Short)rhs).shortValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Long)lhs).longValue() >>> ((Short)rhs).shortValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Long)lhs).longValue() == ((Short)rhs).shortValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Long)lhs).longValue() < ((Short)rhs).shortValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Long)lhs).longValue() <= ((Short)rhs).shortValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Long)lhs).longValue() > ((Short)rhs).shortValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Long)lhs).longValue() >= ((Short)rhs).shortValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ShortByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Short and rhs of Byte. 10 | */ 11 | public class ShortByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Short)lhs).shortValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Short)lhs).shortValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Short)lhs).shortValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Short)lhs).shortValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Short)lhs).shortValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Short)lhs).shortValue() | ((Byte)rhs).byteValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Short)lhs).shortValue() & ((Byte)rhs).byteValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Short)lhs).shortValue() ^ ((Byte)rhs).byteValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Short)lhs).shortValue() << ((Byte)rhs).byteValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Short)lhs).shortValue() >> ((Byte)rhs).byteValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Short)lhs).shortValue() >>> ((Byte)rhs).byteValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Short)lhs).shortValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Short)lhs).shortValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Short)lhs).shortValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Short)lhs).shortValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Short)lhs).shortValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ShortLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Short and rhs of Long. 10 | */ 11 | public class ShortLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Short)lhs).shortValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Short)lhs).shortValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Short)lhs).shortValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Short)lhs).shortValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Short)lhs).shortValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Short)lhs).shortValue() | ((Long)rhs).longValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Short)lhs).shortValue() & ((Long)rhs).longValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Short)lhs).shortValue() ^ ((Long)rhs).longValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Short)lhs).shortValue() << ((Long)rhs).longValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Short)lhs).shortValue() >> ((Long)rhs).longValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Short)lhs).shortValue() >>> ((Long)rhs).longValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Short)lhs).shortValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Short)lhs).shortValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Short)lhs).shortValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Short)lhs).shortValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Short)lhs).shortValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteIntegerOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Integer. 10 | */ 11 | public class ByteIntegerOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Integer)rhs).intValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Integer)rhs).intValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Integer)rhs).intValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Integer)rhs).intValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Integer)rhs).intValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Byte)lhs).byteValue() | ((Integer)rhs).intValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Byte)lhs).byteValue() & ((Integer)rhs).intValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Byte)lhs).byteValue() ^ ((Integer)rhs).intValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Byte)lhs).byteValue() << ((Integer)rhs).intValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Byte)lhs).byteValue() >> ((Integer)rhs).intValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Byte)lhs).byteValue() >>> ((Integer)rhs).intValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Integer)rhs).intValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Integer)rhs).intValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Integer)rhs).intValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Integer)rhs).intValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Integer)rhs).intValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/IntegerByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Integer and rhs of Byte. 10 | */ 11 | public class IntegerByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Integer)lhs).intValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Integer)lhs).intValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Integer)lhs).intValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Integer)lhs).intValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Integer)lhs).intValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Integer)lhs).intValue() | ((Byte)rhs).byteValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Integer)lhs).intValue() & ((Byte)rhs).byteValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Integer)lhs).intValue() ^ ((Byte)rhs).byteValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Integer)lhs).intValue() << ((Byte)rhs).byteValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Integer)lhs).intValue() >> ((Byte)rhs).byteValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Integer)lhs).intValue() >>> ((Byte)rhs).byteValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Integer)lhs).intValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Integer)lhs).intValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Integer)lhs).intValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Integer)lhs).intValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Integer)lhs).intValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/IntegerLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Integer and rhs of Long. 10 | */ 11 | public class IntegerLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Integer)lhs).intValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Integer)lhs).intValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Integer)lhs).intValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Integer)lhs).intValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Integer)lhs).intValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Integer)lhs).intValue() | ((Long)rhs).longValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Integer)lhs).intValue() & ((Long)rhs).longValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Integer)lhs).intValue() ^ ((Long)rhs).longValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Integer)lhs).intValue() << ((Long)rhs).longValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Integer)lhs).intValue() >> ((Long)rhs).longValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Integer)lhs).intValue() >>> ((Long)rhs).longValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Integer)lhs).intValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Integer)lhs).intValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Integer)lhs).intValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Integer)lhs).intValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Integer)lhs).intValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongIntegerOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Long and rhs of Integer. 10 | */ 11 | public class LongIntegerOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Long)lhs).longValue() + ((Integer)rhs).intValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Long)lhs).longValue() - ((Integer)rhs).intValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Long)lhs).longValue() * ((Integer)rhs).intValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Long)lhs).longValue() / ((Integer)rhs).intValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Long)lhs).longValue() % ((Integer)rhs).intValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Long)lhs).longValue() | ((Integer)rhs).intValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Long)lhs).longValue() & ((Integer)rhs).intValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Long)lhs).longValue() ^ ((Integer)rhs).intValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Long)lhs).longValue() << ((Integer)rhs).intValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Long)lhs).longValue() >> ((Integer)rhs).intValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Long)lhs).longValue() >>> ((Integer)rhs).intValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Long)lhs).longValue() == ((Integer)rhs).intValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Long)lhs).longValue() < ((Integer)rhs).intValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Long)lhs).longValue() <= ((Integer)rhs).intValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Long)lhs).longValue() > ((Integer)rhs).intValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Long)lhs).longValue() >= ((Integer)rhs).intValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/InvokeStaticTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import org.junit.Test; 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * Tests the detection and invocation of static methods. 11 | */ 12 | public class InvokeStaticTest 13 | { 14 | @Test public void testInvokeStatic () 15 | { 16 | java.util.Calendar cal = java.util.Calendar.getInstance(); 17 | 18 | // a static method defined on an inner class 19 | int value = Tester.half(25); 20 | assertEquals(12, value); 21 | 22 | // a static method defined on an implicit Java class 23 | Integer foo = Integer.valueOf(25); 24 | assertEquals((Integer)25, foo); // this cast needed for normal compilation 25 | 26 | // a static method defined on this class 27 | value = triple(42); 28 | assertEquals(126, value); 29 | 30 | // a static method of an inner class calling one in neighboring scope 31 | value = MoreTester.threeHalves(42); 32 | assertEquals(63, value); 33 | 34 | // a static method of an inner class calling one from broader scope 35 | value = InvokeStaticTest.Tester.tripleDouble(42); 36 | assertEquals(252, value); 37 | 38 | // test finding a qualified inner inner class 39 | value = MoreTester.InnerTester.oneFourth(42); 40 | assertEquals(10, value); 41 | 42 | // test a static method of another class in this package 43 | value = StaticHelper.help(1); 44 | assertEquals(43, value); 45 | 46 | // test a static method of another class in this package 47 | value = StaticHelper.Inner.innerHelp(1); 48 | assertEquals(25, value); 49 | 50 | // TODO: test statically imported method (or just use assertTrue()); 51 | } 52 | 53 | protected static int triple (int value) 54 | { 55 | return value * 3; 56 | } 57 | 58 | protected static class Tester 59 | { 60 | public static int half (int value) { 61 | return value / 2; 62 | } 63 | 64 | public static int tripleDouble (int value) { 65 | return triple(value) * 2; 66 | } 67 | } 68 | 69 | protected static class MoreTester 70 | { 71 | public static int threeHalves (int value) { 72 | return Tester.half(3 * value); 73 | } 74 | 75 | protected static class InnerTester { 76 | public static int oneFourth (int value) { 77 | return value/4; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/TypeVarTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import org.junit.Test; 13 | import static org.junit.Assert.*; 14 | 15 | /** 16 | * Tests the handling of type variables. 17 | */ 18 | public class TypeVarTest 19 | { 20 | public static class MyList extends ArrayList 21 | { 22 | public void wibble (A value) { 23 | super.add(value); 24 | } 25 | 26 | @Override 27 | public boolean add (A element) 28 | { 29 | // test whether we correctly determine that the below add() is a method defined by our 30 | // supertype (which involves some annoying manual type variable translation) 31 | add(size(), element); 32 | return true; 33 | } 34 | } 35 | 36 | public class Tuple { 37 | public final L left; 38 | public final R right; 39 | public Tuple (L left, R right) { 40 | this.left = left; 41 | this.right = right; 42 | } 43 | } 44 | 45 | @Test public void testSuperCast () { 46 | MyList list = new MyList(); 47 | list.add(5); 48 | assertEquals(Integer.valueOf(5), list.get(0)); 49 | } 50 | 51 | @Test public void testTVarInstantiate () { 52 | List intlist = new ArrayList(); 53 | Integer[] intvec = new Integer[] { 1, 2, 3, 4 }; 54 | intlist.addAll(Arrays.asList(intvec)); 55 | assertEquals(Integer.valueOf(1), intlist.get(0)); 56 | } 57 | 58 | @Test public void testTypeVar () { 59 | Tuple tup = new Tuple(5, 5); 60 | assertEquals(5, tup.left.intValue()); 61 | } 62 | 63 | @Test public void testQuantifiedPrimitive () { 64 | assertEquals(5, noop(5)); 65 | } 66 | 67 | protected static int countKeyLengths (Map map) 68 | { 69 | int length = 0; 70 | for (Map.Entry entry : map.entrySet()) { 71 | // tests having a receiver with type 'K' 72 | K key = entry.getKey(); 73 | length = length + key.toString().length(); 74 | } 75 | return length; 76 | } 77 | 78 | // tests having a quantified primitive as a return type (Resolve has to handle such types 79 | // specially) 80 | protected static int noop (int arg) 81 | { 82 | return arg; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteFloatOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Float. 10 | */ 11 | public class ByteFloatOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Float)rhs).floatValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Float)rhs).floatValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Float)rhs).floatValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Float)rhs).floatValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Float)rhs).floatValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Float)rhs).floatValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Float)rhs).floatValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Float)rhs).floatValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Float)rhs).floatValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Float)rhs).floatValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/FloatByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Float and rhs of Byte. 10 | */ 11 | public class FloatByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Float)lhs).floatValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Float)lhs).floatValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Float)lhs).floatValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Float)lhs).floatValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Float)lhs).floatValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Float)lhs).floatValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Float)lhs).floatValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Float)lhs).floatValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Float)lhs).floatValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Float)lhs).floatValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/FloatLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Float and rhs of Long. 10 | */ 11 | public class FloatLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Float)lhs).floatValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Float)lhs).floatValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Float)lhs).floatValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Float)lhs).floatValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Float)lhs).floatValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Float)lhs).floatValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Float)lhs).floatValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Float)lhs).floatValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Float)lhs).floatValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Float)lhs).floatValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongFloatOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Long and rhs of Float. 10 | */ 11 | public class LongFloatOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Long)lhs).longValue() + ((Float)rhs).floatValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Long)lhs).longValue() - ((Float)rhs).floatValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Long)lhs).longValue() * ((Float)rhs).floatValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Long)lhs).longValue() / ((Float)rhs).floatValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Long)lhs).longValue() % ((Float)rhs).floatValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Long)lhs).longValue() == ((Float)rhs).floatValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Long)lhs).longValue() < ((Float)rhs).floatValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Long)lhs).longValue() <= ((Float)rhs).floatValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Long)lhs).longValue() > ((Float)rhs).floatValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Long)lhs).longValue() >= ((Float)rhs).floatValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ShortShortOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Short and rhs of Short. 10 | */ 11 | public class ShortShortOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Short)lhs).shortValue() + ((Short)rhs).shortValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Short)lhs).shortValue() - ((Short)rhs).shortValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Short)lhs).shortValue() * ((Short)rhs).shortValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Short)lhs).shortValue() / ((Short)rhs).shortValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Short)lhs).shortValue() % ((Short)rhs).shortValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Short)lhs).shortValue() | ((Short)rhs).shortValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Short)lhs).shortValue() & ((Short)rhs).shortValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Short)lhs).shortValue() ^ ((Short)rhs).shortValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Short)lhs).shortValue() << ((Short)rhs).shortValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Short)lhs).shortValue() >> ((Short)rhs).shortValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Short)lhs).shortValue() >>> ((Short)rhs).shortValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Short)lhs).shortValue() == ((Short)rhs).shortValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Short)lhs).shortValue() < ((Short)rhs).shortValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Short)lhs).shortValue() <= ((Short)rhs).shortValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Short)lhs).shortValue() > ((Short)rhs).shortValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Short)lhs).shortValue() >= ((Short)rhs).shortValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/org/ductilej/tests/LibInterfaceTest.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.tests; 5 | 6 | import java.util.Arrays; 7 | import java.util.Comparator; 8 | import java.util.concurrent.Callable; 9 | 10 | import org.junit.Test; 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Tests preservation of library interface implementation signature, in this case compareTo(). 15 | */ 16 | public class LibInterfaceTest 17 | { 18 | public static class Value implements Comparable 19 | { 20 | public int value; 21 | 22 | public Value (int value) { 23 | this.value = value; 24 | } 25 | 26 | public int compareTo (Value o) { 27 | return (value == o.value) ? 0 : ((value > o.value) ? 1 : -1); 28 | } 29 | } 30 | 31 | @Test public void testLibInterface () 32 | { 33 | Value[] values = new Value[] { new Value(3), new Value(1), new Value(99) }; 34 | Arrays.sort(values); 35 | assertTrue(values[0].value == 1); 36 | assertTrue(values[1].value == 3); 37 | assertTrue(values[2].value == 99); 38 | 39 | Comparator icomp = new Comparator() { 40 | public int compare (Integer one, Integer two) { 41 | return one.compareTo(two); 42 | } 43 | }; 44 | // if I use ClassLiteral where Detype turns this into invokeStatic(), then mysteriously 45 | // *this* assertion starts failing with "unrecognized symbol org (in the 46 | // org.junit.Assert.class tree), but the assertTrue transformations *above* the Comparator 47 | // instantion are fine, and if I comment out Comparator, this one also becomes fine (or 48 | // rather one that doesn't refer to the comparator is fine); whiskey tango foxtrot? 49 | assertTrue(icomp.compare(0, 5) < 0); 50 | } 51 | 52 | @Test public void testOverride () 53 | { 54 | Value v = new Value(15) { 55 | @Override public String toString() { 56 | return String.valueOf(value); 57 | } 58 | }; 59 | assertEquals("15", v.toString()); 60 | } 61 | 62 | protected static void testForall (final V dummy) 63 | { 64 | Comparator icomp = new Comparator() { 65 | public int compare (V one, V two) { 66 | return 0; 67 | } 68 | }; 69 | Callable c = new Callable() { 70 | public V call () { 71 | // V foo = null; 72 | return null; 73 | } 74 | }; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/IntegerShortOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Integer and rhs of Short. 10 | */ 11 | public class IntegerShortOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Integer)lhs).intValue() + ((Short)rhs).shortValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Integer)lhs).intValue() - ((Short)rhs).shortValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Integer)lhs).intValue() * ((Short)rhs).shortValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Integer)lhs).intValue() / ((Short)rhs).shortValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Integer)lhs).intValue() % ((Short)rhs).shortValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Integer)lhs).intValue() | ((Short)rhs).shortValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Integer)lhs).intValue() & ((Short)rhs).shortValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Integer)lhs).intValue() ^ ((Short)rhs).shortValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Integer)lhs).intValue() << ((Short)rhs).shortValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Integer)lhs).intValue() >> ((Short)rhs).shortValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Integer)lhs).intValue() >>> ((Short)rhs).shortValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Integer)lhs).intValue() == ((Short)rhs).shortValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Integer)lhs).intValue() < ((Short)rhs).shortValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Integer)lhs).intValue() <= ((Short)rhs).shortValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Integer)lhs).intValue() > ((Short)rhs).shortValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Integer)lhs).intValue() >= ((Short)rhs).shortValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ShortIntegerOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Short and rhs of Integer. 10 | */ 11 | public class ShortIntegerOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Short)lhs).shortValue() + ((Integer)rhs).intValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Short)lhs).shortValue() - ((Integer)rhs).intValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Short)lhs).shortValue() * ((Integer)rhs).intValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Short)lhs).shortValue() / ((Integer)rhs).intValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Short)lhs).shortValue() % ((Integer)rhs).intValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Short)lhs).shortValue() | ((Integer)rhs).intValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Short)lhs).shortValue() & ((Integer)rhs).intValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Short)lhs).shortValue() ^ ((Integer)rhs).intValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Short)lhs).shortValue() << ((Integer)rhs).intValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Short)lhs).shortValue() >> ((Integer)rhs).intValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Short)lhs).shortValue() >>> ((Integer)rhs).intValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Short)lhs).shortValue() == ((Integer)rhs).intValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Short)lhs).shortValue() < ((Integer)rhs).intValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Short)lhs).shortValue() <= ((Integer)rhs).intValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Short)lhs).shortValue() > ((Integer)rhs).intValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Short)lhs).shortValue() >= ((Integer)rhs).intValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/IntegerIntegerOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Integer and rhs of Integer. 10 | */ 11 | public class IntegerIntegerOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Integer)lhs).intValue() + ((Integer)rhs).intValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Integer)lhs).intValue() - ((Integer)rhs).intValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Integer)lhs).intValue() * ((Integer)rhs).intValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Integer)lhs).intValue() / ((Integer)rhs).intValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Integer)lhs).intValue() % ((Integer)rhs).intValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Integer)lhs).intValue() | ((Integer)rhs).intValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Integer)lhs).intValue() & ((Integer)rhs).intValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Integer)lhs).intValue() ^ ((Integer)rhs).intValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Integer)lhs).intValue() << ((Integer)rhs).intValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Integer)lhs).intValue() >> ((Integer)rhs).intValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Integer)lhs).intValue() >>> ((Integer)rhs).intValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Integer)lhs).intValue() == ((Integer)rhs).intValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Integer)lhs).intValue() < ((Integer)rhs).intValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Integer)lhs).intValue() <= ((Integer)rhs).intValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Integer)lhs).intValue() > ((Integer)rhs).intValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Integer)lhs).intValue() >= ((Integer)rhs).intValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteCharacterOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Character. 10 | */ 11 | public class ByteCharacterOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Character)rhs).charValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Character)rhs).charValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Character)rhs).charValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Character)rhs).charValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Character)rhs).charValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Byte)lhs).byteValue() | ((Character)rhs).charValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Byte)lhs).byteValue() & ((Character)rhs).charValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Byte)lhs).byteValue() ^ ((Character)rhs).charValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Byte)lhs).byteValue() << ((Character)rhs).charValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Byte)lhs).byteValue() >> ((Character)rhs).charValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Byte)lhs).byteValue() >>> ((Character)rhs).charValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Character)rhs).charValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Character)rhs).charValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Character)rhs).charValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Character)rhs).charValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Character)rhs).charValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/ByteDoubleOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Byte and rhs of Double. 10 | */ 11 | public class ByteDoubleOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Byte)lhs).byteValue() + ((Double)rhs).doubleValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Byte)lhs).byteValue() - ((Double)rhs).doubleValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Byte)lhs).byteValue() * ((Double)rhs).doubleValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Byte)lhs).byteValue() / ((Double)rhs).doubleValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Byte)lhs).byteValue() % ((Double)rhs).doubleValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Byte)lhs).byteValue() == ((Double)rhs).doubleValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Byte)lhs).byteValue() < ((Double)rhs).doubleValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Byte)lhs).byteValue() <= ((Double)rhs).doubleValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Byte)lhs).byteValue() > ((Double)rhs).doubleValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Byte)lhs).byteValue() >= ((Double)rhs).doubleValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/CharacterByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Character and rhs of Byte. 10 | */ 11 | public class CharacterByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Character)lhs).charValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Character)lhs).charValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Character)lhs).charValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Character)lhs).charValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Character)lhs).charValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Character)lhs).charValue() | ((Byte)rhs).byteValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Character)lhs).charValue() & ((Byte)rhs).byteValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Character)lhs).charValue() ^ ((Byte)rhs).byteValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Character)lhs).charValue() << ((Byte)rhs).byteValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Character)lhs).charValue() >> ((Byte)rhs).byteValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Character)lhs).charValue() >>> ((Byte)rhs).byteValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Character)lhs).charValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Character)lhs).charValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Character)lhs).charValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Character)lhs).charValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Character)lhs).charValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/CharacterLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Character and rhs of Long. 10 | */ 11 | public class CharacterLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Character)lhs).charValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Character)lhs).charValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Character)lhs).charValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Character)lhs).charValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Character)lhs).charValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Character)lhs).charValue() | ((Long)rhs).longValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Character)lhs).charValue() & ((Long)rhs).longValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Character)lhs).charValue() ^ ((Long)rhs).longValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Character)lhs).charValue() << ((Long)rhs).longValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Character)lhs).charValue() >> ((Long)rhs).longValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Character)lhs).charValue() >>> ((Long)rhs).longValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Character)lhs).charValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Character)lhs).charValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Character)lhs).charValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Character)lhs).charValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Character)lhs).charValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/DoubleByteOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Double and rhs of Byte. 10 | */ 11 | public class DoubleByteOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Double)lhs).doubleValue() + ((Byte)rhs).byteValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Double)lhs).doubleValue() - ((Byte)rhs).byteValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Double)lhs).doubleValue() * ((Byte)rhs).byteValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Double)lhs).doubleValue() / ((Byte)rhs).byteValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Double)lhs).doubleValue() % ((Byte)rhs).byteValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Double)lhs).doubleValue() == ((Byte)rhs).byteValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Double)lhs).doubleValue() < ((Byte)rhs).byteValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Double)lhs).doubleValue() <= ((Byte)rhs).byteValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Double)lhs).doubleValue() > ((Byte)rhs).byteValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Double)lhs).doubleValue() >= ((Byte)rhs).byteValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/DoubleLongOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Double and rhs of Long. 10 | */ 11 | public class DoubleLongOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Double)lhs).doubleValue() + ((Long)rhs).longValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Double)lhs).doubleValue() - ((Long)rhs).longValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Double)lhs).doubleValue() * ((Long)rhs).longValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Double)lhs).doubleValue() / ((Long)rhs).longValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Double)lhs).doubleValue() % ((Long)rhs).longValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Double)lhs).doubleValue() == ((Long)rhs).longValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Double)lhs).doubleValue() < ((Long)rhs).longValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Double)lhs).doubleValue() <= ((Long)rhs).longValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Double)lhs).doubleValue() > ((Long)rhs).longValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Double)lhs).doubleValue() >= ((Long)rhs).longValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/FloatFloatOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Float and rhs of Float. 10 | */ 11 | public class FloatFloatOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Float)lhs).floatValue() + ((Float)rhs).floatValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Float)lhs).floatValue() - ((Float)rhs).floatValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Float)lhs).floatValue() * ((Float)rhs).floatValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Float)lhs).floatValue() / ((Float)rhs).floatValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Float)lhs).floatValue() % ((Float)rhs).floatValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Float)lhs).floatValue() == ((Float)rhs).floatValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Float)lhs).floatValue() < ((Float)rhs).floatValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Float)lhs).floatValue() <= ((Float)rhs).floatValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Float)lhs).floatValue() > ((Float)rhs).floatValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Float)lhs).floatValue() >= ((Float)rhs).floatValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/FloatShortOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Float and rhs of Short. 10 | */ 11 | public class FloatShortOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Float)lhs).floatValue() + ((Short)rhs).shortValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Float)lhs).floatValue() - ((Short)rhs).shortValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Float)lhs).floatValue() * ((Short)rhs).shortValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Float)lhs).floatValue() / ((Short)rhs).shortValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Float)lhs).floatValue() % ((Short)rhs).shortValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | throw new RuntimeException("Cannot bitwise-or LEFT and RIGHT"); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | throw new RuntimeException("Cannot bitwise-and LEFT and RIGHT"); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | throw new RuntimeException("Cannot bitwise-xor LEFT and RIGHT"); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | throw new RuntimeException("Cannot left-shift LEFT and RIGHT"); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | throw new RuntimeException("Cannot right-shift LEFT and RIGHT"); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | throw new RuntimeException("Cannot unsigned right-shift LEFT and RIGHT"); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Float)lhs).floatValue() == ((Short)rhs).shortValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Float)lhs).floatValue() < ((Short)rhs).shortValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Float)lhs).floatValue() <= ((Short)rhs).shortValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Float)lhs).floatValue() > ((Short)rhs).shortValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Float)lhs).floatValue() >= ((Short)rhs).shortValue(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/ductilej/runtime/ops/LongCharacterOps.java: -------------------------------------------------------------------------------- 1 | // 2 | // $Id$ 3 | 4 | package org.ductilej.runtime.ops; 5 | 6 | import org.ductilej.runtime.BinOps; 7 | 8 | /** 9 | * Implements binary operations for lhs of Long and rhs of Character. 10 | */ 11 | public class LongCharacterOps implements BinOps 12 | { 13 | public Object plus (Object lhs, Object rhs) { 14 | return ((Long)lhs).longValue() + ((Character)rhs).charValue(); 15 | } 16 | public Object minus (Object lhs, Object rhs) { 17 | return ((Long)lhs).longValue() - ((Character)rhs).charValue(); 18 | } 19 | public Object multiply (Object lhs, Object rhs) { 20 | return ((Long)lhs).longValue() * ((Character)rhs).charValue(); 21 | } 22 | public Object divide (Object lhs, Object rhs) { 23 | return ((Long)lhs).longValue() / ((Character)rhs).charValue(); 24 | } 25 | public Object remainder (Object lhs, Object rhs) { 26 | return ((Long)lhs).longValue() % ((Character)rhs).charValue(); 27 | } 28 | 29 | public Object bitOr (Object lhs, Object rhs) { 30 | return ((Long)lhs).longValue() | ((Character)rhs).charValue(); 31 | } 32 | public Object bitAnd (Object lhs, Object rhs) { 33 | return ((Long)lhs).longValue() & ((Character)rhs).charValue(); 34 | } 35 | public Object bitXor (Object lhs, Object rhs) { 36 | return ((Long)lhs).longValue() ^ ((Character)rhs).charValue(); 37 | } 38 | 39 | public Object leftShift (Object lhs, Object rhs) { 40 | return ((Long)lhs).longValue() << ((Character)rhs).charValue(); 41 | } 42 | public Object rightShift (Object lhs, Object rhs) { 43 | return ((Long)lhs).longValue() >> ((Character)rhs).charValue(); 44 | } 45 | public Object unsignedRightShift (Object lhs, Object rhs) { 46 | return ((Long)lhs).longValue() >>> ((Character)rhs).charValue(); 47 | } 48 | 49 | public boolean equalTo (Object lhs, Object rhs) { 50 | return ((Long)lhs).longValue() == ((Character)rhs).charValue(); 51 | } 52 | public boolean lessThan (Object lhs, Object rhs) { 53 | return ((Long)lhs).longValue() < ((Character)rhs).charValue(); 54 | } 55 | public boolean lessThanEq (Object lhs, Object rhs) { 56 | return ((Long)lhs).longValue() <= ((Character)rhs).charValue(); 57 | } 58 | public boolean greaterThan (Object lhs, Object rhs) { 59 | return ((Long)lhs).longValue() > ((Character)rhs).charValue(); 60 | } 61 | public boolean greaterThanEq (Object lhs, Object rhs) { 62 | return ((Long)lhs).longValue() >= ((Character)rhs).charValue(); 63 | } 64 | } 65 | --------------------------------------------------------------------------------