summaryrefslogtreecommitdiffstats
path: root/dx
diff options
context:
space:
mode:
Diffstat (limited to 'dx')
-rw-r--r--dx/Android.mk1
-rw-r--r--dx/junit-tests/Android.mk10
-rw-r--r--dx/junit-tests/HelloWorldMaker.java86
-rw-r--r--dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java1628
-rw-r--r--dx/junit-tests/com/android/dx/gen/TypeTest.java33
-rw-r--r--dx/junit-tests/com/android/dx/util/BitIntSetTest.java (renamed from dx/src/com/android/dx/util/_tests/_BitIntSet.java)11
-rw-r--r--dx/junit-tests/com/android/dx/util/BitsTest.java (renamed from dx/src/com/android/dx/util/_tests/_Bits.java)10
-rw-r--r--dx/junit-tests/com/android/dx/util/IntListTest.java (renamed from dx/src/com/android/dx/util/_tests/_IntList.java)12
-rw-r--r--dx/junit-tests/com/android/dx/util/ListIntSetTest.java (renamed from dx/src/com/android/dx/util/_tests/_ListIntSet.java)11
-rw-r--r--dx/src/com/android/dx/command/Main.java7
-rw-r--r--dx/src/com/android/dx/dex/DexOptions.java2
-rw-r--r--dx/src/com/android/dx/dex/TableOfContents.java4
-rw-r--r--dx/src/com/android/dx/dex/code/Dops.java276
-rw-r--r--dx/src/com/android/dx/dex/code/InsnFormat.java5
-rw-r--r--dx/src/com/android/dx/dex/code/form/Form32s.java118
-rw-r--r--dx/src/com/android/dx/dex/code/form/Form33x.java101
-rw-r--r--dx/src/com/android/dx/dex/code/form/Form41c.java144
-rw-r--r--dx/src/com/android/dx/dex/code/form/Form52c.java115
-rw-r--r--dx/src/com/android/dx/dex/code/form/Form5rc.java105
-rw-r--r--dx/src/com/android/dx/dex/file/MemberIdsSection.java35
-rw-r--r--dx/src/com/android/dx/gen/BinaryOp.java118
-rw-r--r--dx/src/com/android/dx/gen/Code.java568
-rw-r--r--dx/src/com/android/dx/gen/Comparison.java71
-rw-r--r--dx/src/com/android/dx/gen/Constants.java72
-rw-r--r--dx/src/com/android/dx/gen/DexGenerator.java259
-rw-r--r--dx/src/com/android/dx/gen/FieldId.java71
-rw-r--r--dx/src/com/android/dx/gen/Label.java90
-rw-r--r--dx/src/com/android/dx/gen/Local.java71
-rw-r--r--dx/src/com/android/dx/gen/MethodId.java107
-rw-r--r--dx/src/com/android/dx/gen/Type.java140
-rw-r--r--dx/src/com/android/dx/gen/TypeList.java64
-rw-r--r--dx/src/com/android/dx/io/DexBuffer.java2
-rw-r--r--dx/src/com/android/dx/io/OpcodeInfo.java195
-rw-r--r--dx/src/com/android/dx/io/Opcodes.java39
-rw-r--r--dx/src/com/android/dx/io/instructions/DecodedInstruction.java5
-rw-r--r--dx/src/com/android/dx/io/instructions/InstructionCodec.java133
-rw-r--r--dx/src/com/android/dx/merge/DexMerger.java26
-rw-r--r--dx/src/com/android/dx/merge/IndexMap.java18
-rw-r--r--dx/src/com/android/dx/rop/cst/CstType.java19
-rw-r--r--dx/src/com/android/dx/ssa/_tests/_DomFront.java32
-rw-r--r--dx/src/junit/extensions/ActiveTestSuite.java64
-rw-r--r--dx/src/junit/extensions/ExceptionTestCase.java46
-rw-r--r--dx/src/junit/extensions/RepeatedTest.java31
-rw-r--r--dx/src/junit/extensions/TestDecorator.java38
-rw-r--r--dx/src/junit/extensions/TestSetup.java37
-rw-r--r--dx/src/junit/framework/Assert.java291
-rw-r--r--dx/src/junit/framework/AssertionFailedError.java13
-rw-r--r--dx/src/junit/framework/ComparisonFailure.java68
-rw-r--r--dx/src/junit/framework/Protectable.java14
-rw-r--r--dx/src/junit/framework/Test.java17
-rw-r--r--dx/src/junit/framework/TestCase.java197
-rw-r--r--dx/src/junit/framework/TestFailure.java57
-rw-r--r--dx/src/junit/framework/TestListener.java23
-rw-r--r--dx/src/junit/framework/TestResult.java166
-rw-r--r--dx/src/junit/framework/TestSuite.java265
-rw-r--r--dx/src/junit/runner/BaseTestRunner.java323
-rw-r--r--dx/src/junit/runner/ClassPathTestCollector.java80
-rw-r--r--dx/src/junit/runner/FailureDetailView.java23
-rw-r--r--dx/src/junit/runner/LoadingTestCollector.java69
-rw-r--r--dx/src/junit/runner/ReloadingTestSuiteLoader.java19
-rw-r--r--dx/src/junit/runner/SimpleTestCollector.java20
-rw-r--r--dx/src/junit/runner/Sorter.java38
-rw-r--r--dx/src/junit/runner/StandardTestSuiteLoader.java19
-rw-r--r--dx/src/junit/runner/TestCaseClassLoader.java226
-rw-r--r--dx/src/junit/runner/TestCollector.java16
-rw-r--r--dx/src/junit/runner/TestRunListener.java19
-rw-r--r--dx/src/junit/runner/TestSuiteLoader.java9
-rw-r--r--dx/src/junit/runner/Version.java14
-rw-r--r--dx/src/junit/runner/excluded.properties12
-rw-r--r--dx/src/junit/runner/logo.gifbin964 -> 0 bytes
-rw-r--r--dx/src/junit/runner/smalllogo.gifbin883 -> 0 bytes
-rw-r--r--dx/src/junit/textui/ResultPrinter.java139
-rw-r--r--dx/src/junit/textui/TestRunner.java189
73 files changed, 156 insertions, 7200 deletions
diff --git a/dx/Android.mk b/dx/Android.mk
index 3abf21af8..b31b23b3b 100644
--- a/dx/Android.mk
+++ b/dx/Android.mk
@@ -67,6 +67,7 @@ INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE)
# the other stuff
# ============================================================
subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+ junit-tests \
src \
))
diff --git a/dx/junit-tests/Android.mk b/dx/junit-tests/Android.mk
new file mode 100644
index 000000000..e1f3c4182
--- /dev/null
+++ b/dx/junit-tests/Android.mk
@@ -0,0 +1,10 @@
+# Copyright 2011 The Android Open Source Project
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAVA_LIBRARIES := dx junit
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE:= dx-tests
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/dx/junit-tests/HelloWorldMaker.java b/dx/junit-tests/HelloWorldMaker.java
deleted file mode 100644
index 001f31a90..000000000
--- a/dx/junit-tests/HelloWorldMaker.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import com.android.dx.gen.BinaryOp;
-import com.android.dx.gen.Code;
-import com.android.dx.gen.DexGenerator;
-import com.android.dx.gen.FieldId;
-import com.android.dx.gen.Local;
-import com.android.dx.gen.MethodId;
-import com.android.dx.gen.Type;
-import com.android.dx.rop.code.AccessFlags;
-import java.io.PrintStream;
-
-public class HelloWorldMaker {
- private static final Type<PrintStream> PRINT_STREAM = Type.get(PrintStream.class);
- private static final FieldId<System, PrintStream> SYSTEM_OUT
- = Type.get(System.class).getField(PRINT_STREAM, "out");
- private static final MethodId<Integer, String> TO_HEX_STRING
- = Type.get(Integer.class).getMethod(Type.STRING, "toHexString", Type.INT);
- private static final MethodId<PrintStream, Void> PRINTLN
- = PRINT_STREAM.getMethod(Type.VOID, "println", Type.STRING);
-
- public static void main(String[] args) throws Exception {
-
- /*
- * This code generates Dalvik bytecode equivalent to the following
- * program.
- *
- * public class HelloWorld {
- * public static void hello() {
- * int a = 0xabcd;
- * int b = 0xaaaa;
- * int c = a - b;
- * String s = Integer.toHexString(c);
- * System.out.println(s);
- * }
- * }
- */
-
- DexGenerator generator = new DexGenerator();
-
- // lookup the symbols of interest
- Type<?> helloWorld = Type.get("LHelloWorld;");
- MethodId hello = helloWorld.getMethod(Type.VOID, "hello");
-
- // create some registers
- // (I'd like a better syntax for this)
- Code code = generator.declare(hello, AccessFlags.ACC_STATIC | AccessFlags.ACC_PUBLIC);
- Local<Integer> a = code.newLocal(Type.INT);
- Local<Integer> b = code.newLocal(Type.INT);
- Local<Integer> c = code.newLocal(Type.INT);
- Local<String> s = code.newLocal(Type.STRING);
- Local<PrintStream> localSystemOut = code.newLocal(PRINT_STREAM);
-
- // specify the code instruction-by-instruction (approximately)
- code.loadConstant(a, 0xabcd);
- code.loadConstant(b, 0xaaaa);
- code.op(BinaryOp.SUBTRACT, c, a, b);
- code.invokeStatic(TO_HEX_STRING, s, c);
- code.sget(SYSTEM_OUT, localSystemOut);
- code.invokeVirtual(PRINTLN, null, localSystemOut, s);
- code.returnVoid();
-
- // TODO: create the constructor
-
- generator.declare(helloWorld, "Generated.java", AccessFlags.ACC_PUBLIC, Type.OBJECT);
-
- // load the dex
- ClassLoader loader = generator.load(HelloWorldMaker.class.getClassLoader());
- Class<?> helloWorldClass = loader.loadClass("HelloWorld");
- helloWorldClass.getMethod("hello").invoke(null);
- }
-}
diff --git a/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java b/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
deleted file mode 100644
index 99eea855e..000000000
--- a/dx/junit-tests/com/android/dx/gen/DexGeneratorTest.java
+++ /dev/null
@@ -1,1628 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR;
-import static com.android.dx.rop.code.AccessFlags.ACC_FINAL;
-import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE;
-import static com.android.dx.rop.code.AccessFlags.ACC_PROTECTED;
-import static com.android.dx.rop.code.AccessFlags.ACC_PUBLIC;
-import static com.android.dx.rop.code.AccessFlags.ACC_STATIC;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import junit.framework.TestCase;
-
-/**
- * This generates a class named 'Generated' with one or more generated methods
- * and fields. In loads the generated class into the current VM and uses
- * reflection to invoke its methods.
- *
- * <p>This test must run on a Dalvik VM.
- */
-public final class DexGeneratorTest extends TestCase {
- private DexGenerator generator;
- private static Type<DexGeneratorTest> TEST_TYPE = Type.get(DexGeneratorTest.class);
- private static Type<?> INT_ARRAY = Type.get(int[].class);
- private static Type<boolean[]> BOOLEAN_ARRAY = Type.get(boolean[].class);
- private static Type<long[]> LONG_ARRAY = Type.get(long[].class);
- private static Type<Object[]> OBJECT_ARRAY = Type.get(Object[].class);
- private static Type<long[][]> LONG_2D_ARRAY = Type.get(long[][].class);
- private static Type<?> GENERATED = Type.get("LGenerated;");
- private static Type<Callable> CALLABLE = Type.get(Callable.class);
- private static MethodId<Callable, Object> CALL = CALLABLE.getMethod(Type.OBJECT, "call");
-
- @Override protected void setUp() throws Exception {
- super.setUp();
- reset();
- }
-
- /**
- * The generator is mutable. Calling reset creates a new empty generator.
- * This is necessary to generate multiple classes in the same test method.
- */
- private void reset() {
- generator = new DexGenerator();
- generator.declare(GENERATED, "Generated.java", ACC_PUBLIC, Type.OBJECT);
- }
-
- public void testNewInstance() throws Exception {
- /*
- * public static Constructable call(long a, boolean b) {
- * Constructable result = new Constructable(a, b);
- * return result;
- * }
- */
- Type<Constructable> constructable = Type.get(Constructable.class);
- MethodId<?, Constructable> methodId = GENERATED.getMethod(
- constructable, "call", Type.LONG, Type.BOOLEAN);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Long> localA = code.getParameter(0, Type.LONG);
- Local<Boolean> localB = code.getParameter(1, Type.BOOLEAN);
- MethodId<Constructable, Void> constructor
- = constructable.getConstructor(Type.LONG, Type.BOOLEAN);
- Local<Constructable> localResult = code.newLocal(constructable);
- code.newInstance(localResult, constructor, localA, localB);
- code.returnValue(localResult);
-
- Constructable constructed = (Constructable) getMethod().invoke(null, 5L, false);
- assertEquals(5L, constructed.a);
- assertEquals(false, constructed.b);
- }
-
- public static class Constructable {
- private final long a;
- private final boolean b;
- public Constructable(long a, boolean b) {
- this.a = a;
- this.b = b;
- }
- }
-
- public void testInvokeStatic() throws Exception {
- /*
- * public static int call(int a) {
- * int result = DexGeneratorTest.staticMethod(a);
- * return result;
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localA = code.getParameter(0, Type.INT);
- Local<Integer> localResult = code.newLocal(Type.INT);
- MethodId<?, Integer> staticMethod
- = TEST_TYPE.getMethod(Type.INT, "staticMethod", Type.INT);
- code.invokeStatic(staticMethod, localResult, localA);
- code.returnValue(localResult);
-
- assertEquals(10, getMethod().invoke(null, 4));
- }
-
- @SuppressWarnings("unused") // called by generated code
- public static int staticMethod(int a) {
- return a + 6;
- }
-
- public void testInvokeVirtual() throws Exception {
- /*
- * public static int call(DexGeneratorTest test, int a) {
- * int result = test.virtualMethod(a);
- * return result;
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", TEST_TYPE, Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<DexGeneratorTest> localInstance = code.getParameter(0, TEST_TYPE);
- Local<Integer> localA = code.getParameter(1, Type.INT);
- Local<Integer> localResult = code.newLocal(Type.INT);
- MethodId<DexGeneratorTest, Integer> virtualMethod
- = TEST_TYPE.getMethod(Type.INT, "virtualMethod", Type.INT);
- code.invokeVirtual(virtualMethod, localResult, localInstance, localA);
- code.returnValue(localResult);
-
- assertEquals(9, getMethod().invoke(null, this, 4));
- }
-
- @SuppressWarnings("unused") // called by generated code
- public int virtualMethod(int a) {
- return a + 5;
- }
-
- public <G> void testInvokeDirect() throws Exception {
- /*
- * private int directMethod() {
- * int a = 5;
- * return a;
- * }
- *
- * public static int call(Generated g) {
- * int b = g.directMethod();
- * return b;
- * }
- */
- Type<G> generated = Type.get("LGenerated;");
- MethodId<G, Integer> directMethodId = generated.getMethod(Type.INT, "directMethod");
- Code directCode = generator.declare(directMethodId, ACC_PRIVATE);
- directCode.getThis(generated); // 'this' is unused
- Local<Integer> localA = directCode.newLocal(Type.INT);
- directCode.loadConstant(localA, 5);
- directCode.returnValue(localA);
-
- MethodId<G, Integer> methodId = generated.getMethod(Type.INT, "call", generated);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localB = code.newLocal(Type.INT);
- Local<G> localG = code.getParameter(0, generated);
- code.invokeDirect(directMethodId, localB, localG);
- code.returnValue(localB);
-
- addDefaultConstructor();
-
- Class<?> generatedClass = loadAndGenerate();
- Object instance = generatedClass.newInstance();
- Method method = generatedClass.getMethod("call", generatedClass);
- assertEquals(5, method.invoke(null, instance));
- }
-
- public <G> void testInvokeSuper() throws Exception {
- /*
- * public int superHashCode() {
- * int result = super.hashCode();
- * return result;
- * }
- * public int hashCode() {
- * return 0;
- * }
- */
- Type<G> generated = Type.get("LGenerated;");
- MethodId<Object, Integer> objectHashCode = Type.OBJECT.getMethod(Type.INT, "hashCode");
- Code superHashCode = generator.declare(
- GENERATED.getMethod(Type.INT, "superHashCode"), ACC_PUBLIC);
- Local<Integer> localResult = superHashCode.newLocal(Type.INT);
- Local<G> localThis = superHashCode.getThis(generated);
- superHashCode.invokeSuper(objectHashCode, localResult, localThis);
- superHashCode.returnValue(localResult);
-
- Code generatedHashCode = generator.declare(
- GENERATED.getMethod(Type.INT, "hashCode"), ACC_PUBLIC);
- Local<Integer> localZero = generatedHashCode.newLocal(Type.INT);
- generatedHashCode.loadConstant(localZero, 0);
- generatedHashCode.returnValue(localZero);
-
- addDefaultConstructor();
-
- Class<?> generatedClass = loadAndGenerate();
- Object instance = generatedClass.newInstance();
- Method method = generatedClass.getMethod("superHashCode");
- assertEquals(System.identityHashCode(instance), method.invoke(instance));
- }
-
- @SuppressWarnings("unused") // called by generated code
- public int superMethod(int a) {
- return a + 4;
- }
-
- public void testInvokeInterface() throws Exception {
- /*
- * public static Object call(Callable c) {
- * Object result = c.call();
- * return result;
- * }
- */
- MethodId<?, Object> methodId = GENERATED.getMethod(Type.OBJECT, "call", CALLABLE);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Callable> localC = code.getParameter(0, CALLABLE);
- Local<Object> localResult = code.newLocal(Type.OBJECT);
- code.invokeInterface(CALL, localResult, localC);
- code.returnValue(localResult);
-
- Callable<Object> callable = new Callable<Object>() {
- public Object call() throws Exception {
- return "abc";
- }
- };
- assertEquals("abc", getMethod().invoke(null, callable));
- }
-
- public void testParameterMismatch() throws Exception {
- Type<?>[] argTypes = {
- Type.get(Integer.class), // should fail because the code specifies int
- Type.OBJECT,
- };
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", argTypes);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- try {
- code.getParameter(0, Type.INT);
- } catch (IllegalArgumentException e) {
- }
- try {
- code.getParameter(2, Type.INT);
- } catch (IndexOutOfBoundsException e) {
- }
- }
-
- public void testInvokeTypeSafety() throws Exception {
- /*
- * public static boolean call(DexGeneratorTest test) {
- * CharSequence cs = test.toString();
- * boolean result = cs.equals(test);
- * return result;
- * }
- */
- MethodId<?, Boolean> methodId = GENERATED.getMethod(Type.BOOLEAN, "call", TEST_TYPE);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<DexGeneratorTest> localTest = code.getParameter(0, TEST_TYPE);
- Type<CharSequence> charSequenceType = Type.get(CharSequence.class);
- MethodId<Object, String> objectToString = Type.OBJECT.getMethod(Type.STRING, "toString");
- MethodId<Object, Boolean> objectEquals
- = Type.OBJECT.getMethod(Type.BOOLEAN, "equals", Type.OBJECT);
- Local<CharSequence> localCs = code.newLocal(charSequenceType);
- Local<Boolean> localResult = code.newLocal(Type.BOOLEAN);
- code.invokeVirtual(objectToString, localCs, localTest);
- code.invokeVirtual(objectEquals, localResult, localCs, localTest);
- code.returnValue(localResult);
-
- assertEquals(false, getMethod().invoke(null, this));
- }
-
- public void testReturnTypeMismatch() {
- MethodId<?, String> methodId = GENERATED.getMethod(Type.STRING, "call");
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- try {
- code.returnValue(code.newLocal(Type.BOOLEAN));
- fail();
- } catch (IllegalArgumentException expected) {
- }
- try {
- code.returnVoid();
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testDeclareStaticFields() throws Exception {
- /*
- * class Generated {
- * public static int a;
- * protected static Object b;
- * }
- */
- generator.declare(GENERATED.getField(Type.INT, "a"), ACC_PUBLIC | ACC_STATIC, 3);
- generator.declare(GENERATED.getField(Type.OBJECT, "b"), ACC_PROTECTED | ACC_STATIC, null);
- Class<?> generatedClass = loadAndGenerate();
-
- Field a = generatedClass.getField("a");
- assertEquals(int.class, a.getType());
- assertEquals(3, a.get(null));
-
- Field b = generatedClass.getDeclaredField("b");
- assertEquals(Object.class, b.getType());
- b.setAccessible(true);
- assertEquals(null, b.get(null));
- }
-
- public void testDeclareInstanceFields() throws Exception {
- /*
- * class Generated {
- * public int a;
- * protected Object b;
- * }
- */
- generator.declare(GENERATED.getField(Type.INT, "a"), ACC_PUBLIC, null);
- generator.declare(GENERATED.getField(Type.OBJECT, "b"), ACC_PROTECTED, null);
-
- addDefaultConstructor();
-
- Class<?> generatedClass = loadAndGenerate();
- Object instance = generatedClass.newInstance();
-
- Field a = generatedClass.getField("a");
- assertEquals(int.class, a.getType());
- assertEquals(0, a.get(instance));
-
- Field b = generatedClass.getDeclaredField("b");
- assertEquals(Object.class, b.getType());
- b.setAccessible(true);
- assertEquals(null, b.get(instance));
- }
-
- /**
- * Declare a constructor that takes an int parameter and assigns it to a
- * field.
- */
- public <G> void testDeclareConstructor() throws Exception {
- /*
- * class Generated {
- * public final int a;
- * public Generated(int a) {
- * this.a = a;
- * }
- * }
- */
- Type<G> generated = Type.get("LGenerated;");
- FieldId<G, Integer> fieldId = generated.getField(Type.INT, "a");
- generator.declare(fieldId, ACC_PUBLIC | ACC_FINAL, null);
- MethodId<?, Void> constructor = GENERATED.getConstructor(Type.INT);
- Code code = generator.declare(constructor, ACC_PUBLIC | ACC_CONSTRUCTOR);
- Local<G> thisRef = code.getThis(generated);
- Local<Integer> parameter = code.getParameter(0, Type.INT);
- code.invokeDirect(Type.OBJECT.getConstructor(), null, thisRef);
- code.iput(fieldId, thisRef, parameter);
- code.returnVoid();
-
- Class<?> generatedClass = loadAndGenerate();
- Field a = generatedClass.getField("a");
- Object instance = generatedClass.getConstructor(int.class).newInstance(0xabcd);
- assertEquals(0xabcd, a.get(instance));
- }
-
- public void testReturnBoolean() throws Exception {
- testReturnType(boolean.class, true);
- testReturnType(byte.class, (byte) 5);
- testReturnType(char.class, 'E');
- testReturnType(double.class, 5.0);
- testReturnType(float.class, 5.0f);
- testReturnType(int.class, 5);
- testReturnType(long.class, 5L);
- testReturnType(short.class, (short) 5);
- testReturnType(void.class, null);
- testReturnType(String.class, "foo");
- testReturnType(Class.class, List.class);
- }
-
- private <T> void testReturnType(Class<T> javaType, T value) throws Exception {
- /*
- * public int call() {
- * int a = 5;
- * return a;
- * }
- */
- reset();
- Type<T> returnType = Type.get(javaType);
- Code code = generator.declare(GENERATED.getMethod(returnType, "call"),
- ACC_PUBLIC | ACC_STATIC);
- if (value != null) {
- Local<T> i = code.newLocal(returnType);
- code.loadConstant(i, value);
- code.returnValue(i);
- } else {
- code.returnVoid();
- }
-
- Class<?> generatedClass = loadAndGenerate();
- Method method = generatedClass.getMethod("call");
- assertEquals(javaType, method.getReturnType());
- assertEquals(value, method.invoke(null));
- }
-
- public void testBranching() throws Exception {
- Method lt = branchingMethod(Comparison.LT);
- assertEquals(Boolean.TRUE, lt.invoke(null, 1, 2));
- assertEquals(Boolean.FALSE, lt.invoke(null, 1, 1));
- assertEquals(Boolean.FALSE, lt.invoke(null, 2, 1));
-
- Method le = branchingMethod(Comparison.LE);
- assertEquals(Boolean.TRUE, le.invoke(null, 1, 2));
- assertEquals(Boolean.TRUE, le.invoke(null, 1, 1));
- assertEquals(Boolean.FALSE, le.invoke(null, 2, 1));
-
- Method eq = branchingMethod(Comparison.EQ);
- assertEquals(Boolean.FALSE, eq.invoke(null, 1, 2));
- assertEquals(Boolean.TRUE, eq.invoke(null, 1, 1));
- assertEquals(Boolean.FALSE, eq.invoke(null, 2, 1));
-
- Method ge = branchingMethod(Comparison.GE);
- assertEquals(Boolean.FALSE, ge.invoke(null, 1, 2));
- assertEquals(Boolean.TRUE, ge.invoke(null, 1, 1));
- assertEquals(Boolean.TRUE, ge.invoke(null, 2, 1));
-
- Method gt = branchingMethod(Comparison.GT);
- assertEquals(Boolean.FALSE, gt.invoke(null, 1, 2));
- assertEquals(Boolean.FALSE, gt.invoke(null, 1, 1));
- assertEquals(Boolean.TRUE, gt.invoke(null, 2, 1));
-
- Method ne = branchingMethod(Comparison.NE);
- assertEquals(Boolean.TRUE, ne.invoke(null, 1, 2));
- assertEquals(Boolean.FALSE, ne.invoke(null, 1, 1));
- assertEquals(Boolean.TRUE, ne.invoke(null, 2, 1));
- }
-
- private Method branchingMethod(Comparison comparison) throws Exception {
- /*
- * public static boolean call(int localA, int localB) {
- * if (a comparison b) {
- * return true;
- * }
- * return false;
- * }
- */
- reset();
- MethodId<?, Boolean> methodId = GENERATED.getMethod(
- Type.BOOLEAN, "call", Type.INT, Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localA = code.getParameter(0, Type.INT);
- Local<Integer> localB = code.getParameter(1, Type.INT);
- Local<Boolean> result = code.newLocal(Type.get(boolean.class));
- Label afterIf = code.newLabel();
- Label ifBody = code.newLabel();
- code.compare(comparison, localA, localB, ifBody);
- code.jump(afterIf);
-
- code.mark(ifBody);
- code.loadConstant(result, true);
- code.returnValue(result);
-
- code.mark(afterIf);
- code.loadConstant(result, false);
- code.returnValue(result);
- return getMethod();
- }
-
- public void testCastIntegerToInteger() throws Exception {
- Method intToLong = numericCastingMethod(int.class, long.class);
- assertEquals(0x0000000000000000L, intToLong.invoke(null, 0x00000000));
- assertEquals(0x000000007fffffffL, intToLong.invoke(null, 0x7fffffff));
- assertEquals(0xffffffff80000000L, intToLong.invoke(null, 0x80000000));
- assertEquals(0xffffffffffffffffL, intToLong.invoke(null, 0xffffffff));
-
- Method longToInt = numericCastingMethod(long.class, int.class);
- assertEquals(0x1234abcd, longToInt.invoke(null, 0x000000001234abcdL));
- assertEquals(0x1234abcd, longToInt.invoke(null, 0x123456781234abcdL));
- assertEquals(0x1234abcd, longToInt.invoke(null, 0xffffffff1234abcdL));
-
- Method intToShort = numericCastingMethod(int.class, short.class);
- assertEquals((short) 0x1234, intToShort.invoke(null, 0x00001234));
- assertEquals((short) 0x1234, intToShort.invoke(null, 0xabcd1234));
- assertEquals((short) 0x1234, intToShort.invoke(null, 0xffff1234));
-
- Method intToChar = numericCastingMethod(int.class, char.class);
- assertEquals((char) 0x1234, intToChar.invoke(null, 0x00001234));
- assertEquals((char) 0x1234, intToChar.invoke(null, 0xabcd1234));
- assertEquals((char) 0x1234, intToChar.invoke(null, 0xffff1234));
-
- Method intToByte = numericCastingMethod(int.class, byte.class);
- assertEquals((byte) 0x34, intToByte.invoke(null, 0x00000034));
- assertEquals((byte) 0x34, intToByte.invoke(null, 0xabcd1234));
- assertEquals((byte) 0x34, intToByte.invoke(null, 0xffffff34));
- }
-
- public void testCastIntegerToFloatingPoint() throws Exception {
- Method intToFloat = numericCastingMethod(int.class, float.class);
- assertEquals(0.0f, intToFloat.invoke(null, 0));
- assertEquals(-1.0f, intToFloat.invoke(null, -1));
- assertEquals(16777216f, intToFloat.invoke(null, 16777216));
- assertEquals(16777216f, intToFloat.invoke(null, 16777217)); // precision
-
- Method intToDouble = numericCastingMethod(int.class, double.class);
- assertEquals(0.0, intToDouble.invoke(null, 0));
- assertEquals(-1.0, intToDouble.invoke(null, -1));
- assertEquals(16777216.0, intToDouble.invoke(null, 16777216));
- assertEquals(16777217.0, intToDouble.invoke(null, 16777217));
-
- Method longToFloat = numericCastingMethod(long.class, float.class);
- assertEquals(0.0f, longToFloat.invoke(null, 0L));
- assertEquals(-1.0f, longToFloat.invoke(null, -1L));
- assertEquals(16777216f, longToFloat.invoke(null, 16777216L));
- assertEquals(16777216f, longToFloat.invoke(null, 16777217L));
-
- Method longToDouble = numericCastingMethod(long.class, double.class);
- assertEquals(0.0, longToDouble.invoke(null, 0L));
- assertEquals(-1.0, longToDouble.invoke(null, -1L));
- assertEquals(9007199254740992.0, longToDouble.invoke(null, 9007199254740992L));
- assertEquals(9007199254740992.0, longToDouble.invoke(null, 9007199254740993L)); // precision
- }
-
- public void testCastFloatingPointToInteger() throws Exception {
- Method floatToInt = numericCastingMethod(float.class, int.class);
- assertEquals(0, floatToInt.invoke(null, 0.0f));
- assertEquals(-1, floatToInt.invoke(null, -1.0f));
- assertEquals(Integer.MAX_VALUE, floatToInt.invoke(null, 10e15f));
- assertEquals(0, floatToInt.invoke(null, 0.5f));
- assertEquals(Integer.MIN_VALUE, floatToInt.invoke(null, Float.NEGATIVE_INFINITY));
- assertEquals(0, floatToInt.invoke(null, Float.NaN));
-
- Method floatToLong = numericCastingMethod(float.class, long.class);
- assertEquals(0L, floatToLong.invoke(null, 0.0f));
- assertEquals(-1L, floatToLong.invoke(null, -1.0f));
- assertEquals(10000000272564224L, floatToLong.invoke(null, 10e15f));
- assertEquals(0L, floatToLong.invoke(null, 0.5f));
- assertEquals(Long.MIN_VALUE, floatToLong.invoke(null, Float.NEGATIVE_INFINITY));
- assertEquals(0L, floatToLong.invoke(null, Float.NaN));
-
- Method doubleToInt = numericCastingMethod(double.class, int.class);
- assertEquals(0, doubleToInt.invoke(null, 0.0));
- assertEquals(-1, doubleToInt.invoke(null, -1.0));
- assertEquals(Integer.MAX_VALUE, doubleToInt.invoke(null, 10e15));
- assertEquals(0, doubleToInt.invoke(null, 0.5));
- assertEquals(Integer.MIN_VALUE, doubleToInt.invoke(null, Double.NEGATIVE_INFINITY));
- assertEquals(0, doubleToInt.invoke(null, Double.NaN));
-
- Method doubleToLong = numericCastingMethod(double.class, long.class);
- assertEquals(0L, doubleToLong.invoke(null, 0.0));
- assertEquals(-1L, doubleToLong.invoke(null, -1.0));
- assertEquals(10000000000000000L, doubleToLong.invoke(null, 10e15));
- assertEquals(0L, doubleToLong.invoke(null, 0.5));
- assertEquals(Long.MIN_VALUE, doubleToLong.invoke(null, Double.NEGATIVE_INFINITY));
- assertEquals(0L, doubleToLong.invoke(null, Double.NaN));
- }
-
- public void testCastFloatingPointToFloatingPoint() throws Exception {
- Method floatToDouble = numericCastingMethod(float.class, double.class);
- assertEquals(0.0, floatToDouble.invoke(null, 0.0f));
- assertEquals(-1.0, floatToDouble.invoke(null, -1.0f));
- assertEquals(0.5, floatToDouble.invoke(null, 0.5f));
- assertEquals(Double.NEGATIVE_INFINITY, floatToDouble.invoke(null, Float.NEGATIVE_INFINITY));
- assertEquals(Double.NaN, floatToDouble.invoke(null, Float.NaN));
-
- Method doubleToFloat = numericCastingMethod(double.class, float.class);
- assertEquals(0.0f, doubleToFloat.invoke(null, 0.0));
- assertEquals(-1.0f, doubleToFloat.invoke(null, -1.0));
- assertEquals(0.5f, doubleToFloat.invoke(null, 0.5));
- assertEquals(Float.NEGATIVE_INFINITY, doubleToFloat.invoke(null, Double.NEGATIVE_INFINITY));
- assertEquals(Float.NaN, doubleToFloat.invoke(null, Double.NaN));
- }
-
- private Method numericCastingMethod(Class<?> source, Class<?> target)
- throws Exception {
- /*
- * public static short call(int source) {
- * short casted = (short) source;
- * return casted;
- * }
- */
- reset();
- Type<?> sourceType = Type.get(source);
- Type<?> targetType = Type.get(target);
- MethodId<?, ?> methodId = GENERATED.getMethod(targetType, "call", sourceType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<?> localSource = code.getParameter(0, sourceType);
- Local<?> localCasted = code.newLocal(targetType);
- code.numericCast(localSource, localCasted);
- code.returnValue(localCasted);
- return getMethod();
- }
-
- public void testNot() throws Exception {
- Method notInteger = notMethod(int.class);
- assertEquals(0xffffffff, notInteger.invoke(null, 0x00000000));
- assertEquals(0x00000000, notInteger.invoke(null, 0xffffffff));
- assertEquals(0xedcba987, notInteger.invoke(null, 0x12345678));
-
- Method notLong = notMethod(long.class);
- assertEquals(0xffffffffffffffffL, notLong.invoke(null, 0x0000000000000000L));
- assertEquals(0x0000000000000000L, notLong.invoke(null, 0xffffffffffffffffL));
- assertEquals(0x98765432edcba987L, notLong.invoke(null, 0x6789abcd12345678L));
- }
-
- private <T> Method notMethod(Class<T> source) throws Exception {
- /*
- * public static short call(int source) {
- * source = ~source;
- * return not;
- * }
- */
- reset();
- Type<T> valueType = Type.get(source);
- MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<T> localSource = code.getParameter(0, valueType);
- code.not(localSource, localSource);
- code.returnValue(localSource);
- return getMethod();
- }
-
- public void testNegate() throws Exception {
- Method negateInteger = negateMethod(int.class);
- assertEquals(0, negateInteger.invoke(null, 0));
- assertEquals(-1, negateInteger.invoke(null, 1));
- assertEquals(Integer.MIN_VALUE, negateInteger.invoke(null, Integer.MIN_VALUE));
-
- Method negateLong = negateMethod(long.class);
- assertEquals(0L, negateLong.invoke(null, 0));
- assertEquals(-1L, negateLong.invoke(null, 1));
- assertEquals(Long.MIN_VALUE, negateLong.invoke(null, Long.MIN_VALUE));
-
- Method negateFloat = negateMethod(float.class);
- assertEquals(-0.0f, negateFloat.invoke(null, 0.0f));
- assertEquals(-1.0f, negateFloat.invoke(null, 1.0f));
- assertEquals(Float.NaN, negateFloat.invoke(null, Float.NaN));
- assertEquals(Float.POSITIVE_INFINITY, negateFloat.invoke(null, Float.NEGATIVE_INFINITY));
-
- Method negateDouble = negateMethod(double.class);
- assertEquals(-0.0, negateDouble.invoke(null, 0.0));
- assertEquals(-1.0, negateDouble.invoke(null, 1.0));
- assertEquals(Double.NaN, negateDouble.invoke(null, Double.NaN));
- assertEquals(Double.POSITIVE_INFINITY, negateDouble.invoke(null, Double.NEGATIVE_INFINITY));
- }
-
- private <T> Method negateMethod(Class<T> source) throws Exception {
- /*
- * public static short call(int source) {
- * source = -source;
- * return not;
- * }
- */
- reset();
- Type<T> valueType = Type.get(source);
- MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<T> localSource = code.getParameter(0, valueType);
- code.negate(localSource, localSource);
- code.returnValue(localSource);
- return getMethod();
- }
-
- public void testIntBinaryOps() throws Exception {
- Method add = binaryOpMethod(int.class, BinaryOp.ADD);
- assertEquals(79, add.invoke(null, 75, 4));
-
- Method subtract = binaryOpMethod(int.class, BinaryOp.SUBTRACT);
- assertEquals(71, subtract.invoke(null, 75, 4));
-
- Method multiply = binaryOpMethod(int.class, BinaryOp.MULTIPLY);
- assertEquals(300, multiply.invoke(null, 75, 4));
-
- Method divide = binaryOpMethod(int.class, BinaryOp.DIVIDE);
- assertEquals(18, divide.invoke(null, 75, 4));
- try {
- divide.invoke(null, 75, 0);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(ArithmeticException.class, expected.getCause().getClass());
- }
-
- Method remainder = binaryOpMethod(int.class, BinaryOp.REMAINDER);
- assertEquals(3, remainder.invoke(null, 75, 4));
- try {
- remainder.invoke(null, 75, 0);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(ArithmeticException.class, expected.getCause().getClass());
- }
-
- Method and = binaryOpMethod(int.class, BinaryOp.AND);
- assertEquals(0xff000000, and.invoke(null, 0xff00ff00, 0xffff0000));
-
- Method or = binaryOpMethod(int.class, BinaryOp.OR);
- assertEquals(0xffffff00, or.invoke(null, 0xff00ff00, 0xffff0000));
-
- Method xor = binaryOpMethod(int.class, BinaryOp.XOR);
- assertEquals(0x00ffff00, xor.invoke(null, 0xff00ff00, 0xffff0000));
-
- Method shiftLeft = binaryOpMethod(int.class, BinaryOp.SHIFT_LEFT);
- assertEquals(0xcd123400, shiftLeft.invoke(null, 0xabcd1234, 8));
-
- Method shiftRight = binaryOpMethod(int.class, BinaryOp.SHIFT_RIGHT);
- assertEquals(0xffabcd12, shiftRight.invoke(null, 0xabcd1234, 8));
-
- Method unsignedShiftRight = binaryOpMethod(int.class,
- BinaryOp.UNSIGNED_SHIFT_RIGHT);
- assertEquals(0x00abcd12, unsignedShiftRight.invoke(null, 0xabcd1234, 8));
- }
-
- public void testLongBinaryOps() throws Exception {
- Method add = binaryOpMethod(long.class, BinaryOp.ADD);
- assertEquals(79L, add.invoke(null, 75L, 4L));
-
- Method subtract = binaryOpMethod(long.class, BinaryOp.SUBTRACT);
- assertEquals(71L, subtract.invoke(null, 75L, 4L));
-
- Method multiply = binaryOpMethod(long.class, BinaryOp.MULTIPLY);
- assertEquals(300L, multiply.invoke(null, 75L, 4L));
-
- Method divide = binaryOpMethod(long.class, BinaryOp.DIVIDE);
- assertEquals(18L, divide.invoke(null, 75L, 4L));
- try {
- divide.invoke(null, 75L, 0L);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(ArithmeticException.class, expected.getCause().getClass());
- }
-
- Method remainder = binaryOpMethod(long.class, BinaryOp.REMAINDER);
- assertEquals(3L, remainder.invoke(null, 75L, 4L));
- try {
- remainder.invoke(null, 75L, 0L);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(ArithmeticException.class, expected.getCause().getClass());
- }
-
- Method and = binaryOpMethod(long.class, BinaryOp.AND);
- assertEquals(0xff00ff0000000000L,
- and.invoke(null, 0xff00ff00ff00ff00L, 0xffffffff00000000L));
-
- Method or = binaryOpMethod(long.class, BinaryOp.OR);
- assertEquals(0xffffffffff00ff00L,
- or.invoke(null, 0xff00ff00ff00ff00L, 0xffffffff00000000L));
-
- Method xor = binaryOpMethod(long.class, BinaryOp.XOR);
- assertEquals(0x00ff00ffff00ff00L,
- xor.invoke(null, 0xff00ff00ff00ff00L, 0xffffffff00000000L));
-
- Method shiftLeft = binaryOpMethod(long.class, BinaryOp.SHIFT_LEFT);
- assertEquals(0xcdef012345678900L, shiftLeft.invoke(null, 0xabcdef0123456789L, 8L));
-
- Method shiftRight = binaryOpMethod(long.class, BinaryOp.SHIFT_RIGHT);
- assertEquals(0xffabcdef01234567L, shiftRight.invoke(null, 0xabcdef0123456789L, 8L));
-
- Method unsignedShiftRight = binaryOpMethod(long.class,
- BinaryOp.UNSIGNED_SHIFT_RIGHT);
- assertEquals(0x00abcdef01234567L, unsignedShiftRight.invoke(null, 0xabcdef0123456789L, 8L));
- }
-
- public void testFloatBinaryOps() throws Exception {
- Method add = binaryOpMethod(float.class, BinaryOp.ADD);
- assertEquals(6.75f, add.invoke(null, 5.5f, 1.25f));
-
- Method subtract = binaryOpMethod(float.class, BinaryOp.SUBTRACT);
- assertEquals(4.25f, subtract.invoke(null, 5.5f, 1.25f));
-
- Method multiply = binaryOpMethod(float.class, BinaryOp.MULTIPLY);
- assertEquals(6.875f, multiply.invoke(null, 5.5f, 1.25f));
-
- Method divide = binaryOpMethod(float.class, BinaryOp.DIVIDE);
- assertEquals(4.4f, divide.invoke(null, 5.5f, 1.25f));
- assertEquals(Float.POSITIVE_INFINITY, divide.invoke(null, 5.5f, 0.0f));
-
- Method remainder = binaryOpMethod(float.class, BinaryOp.REMAINDER);
- assertEquals(0.5f, remainder.invoke(null, 5.5f, 1.25f));
- assertEquals(Float.NaN, remainder.invoke(null, 5.5f, 0.0f));
- }
-
- public void testDoubleBinaryOps() throws Exception {
- Method add = binaryOpMethod(double.class, BinaryOp.ADD);
- assertEquals(6.75, add.invoke(null, 5.5, 1.25));
-
- Method subtract = binaryOpMethod(double.class, BinaryOp.SUBTRACT);
- assertEquals(4.25, subtract.invoke(null, 5.5, 1.25));
-
- Method multiply = binaryOpMethod(double.class, BinaryOp.MULTIPLY);
- assertEquals(6.875, multiply.invoke(null, 5.5, 1.25));
-
- Method divide = binaryOpMethod(double.class, BinaryOp.DIVIDE);
- assertEquals(4.4, divide.invoke(null, 5.5, 1.25));
- assertEquals(Double.POSITIVE_INFINITY, divide.invoke(null, 5.5, 0.0));
-
- Method remainder = binaryOpMethod(double.class, BinaryOp.REMAINDER);
- assertEquals(0.5, remainder.invoke(null, 5.5, 1.25));
- assertEquals(Double.NaN, remainder.invoke(null, 5.5, 0.0));
- }
-
- private <T> Method binaryOpMethod(Class<T> valueClass, BinaryOp op)
- throws Exception {
- /*
- * public static int binaryOp(int a, int b) {
- * int result = a + b;
- * return result;
- * }
- */
- reset();
- Type<T> valueType = Type.get(valueClass);
- MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", valueType, valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<T> localA = code.getParameter(0, valueType);
- Local<T> localB = code.getParameter(1, valueType);
- Local<T> localResult = code.newLocal(valueType);
- code.op(op, localResult, localA, localB);
- code.returnValue(localResult);
- return getMethod();
- }
-
- public void testReadAndWriteInstanceFields() throws Exception {
- Instance instance = new Instance();
-
- Method intSwap = instanceSwapMethod(int.class, "intValue");
- instance.intValue = 5;
- assertEquals(5, intSwap.invoke(null, instance, 10));
- assertEquals(10, instance.intValue);
-
- Method longSwap = instanceSwapMethod(long.class, "longValue");
- instance.longValue = 500L;
- assertEquals(500L, longSwap.invoke(null, instance, 1234L));
- assertEquals(1234L, instance.longValue);
-
- Method booleanSwap = instanceSwapMethod(boolean.class, "booleanValue");
- instance.booleanValue = false;
- assertEquals(false, booleanSwap.invoke(null, instance, true));
- assertEquals(true, instance.booleanValue);
-
- Method floatSwap = instanceSwapMethod(float.class, "floatValue");
- instance.floatValue = 1.5f;
- assertEquals(1.5f, floatSwap.invoke(null, instance, 0.5f));
- assertEquals(0.5f, instance.floatValue);
-
- Method doubleSwap = instanceSwapMethod(double.class, "doubleValue");
- instance.doubleValue = 155.5;
- assertEquals(155.5, doubleSwap.invoke(null, instance, 266.6));
- assertEquals(266.6, instance.doubleValue);
-
- Method objectSwap = instanceSwapMethod(Object.class, "objectValue");
- instance.objectValue = "before";
- assertEquals("before", objectSwap.invoke(null, instance, "after"));
- assertEquals("after", instance.objectValue);
-
- Method byteSwap = instanceSwapMethod(byte.class, "byteValue");
- instance.byteValue = 0x35;
- assertEquals((byte) 0x35, byteSwap.invoke(null, instance, (byte) 0x64));
- assertEquals((byte) 0x64, instance.byteValue);
-
- Method charSwap = instanceSwapMethod(char.class, "charValue");
- instance.charValue = 'A';
- assertEquals('A', charSwap.invoke(null, instance, 'B'));
- assertEquals('B', instance.charValue);
-
- Method shortSwap = instanceSwapMethod(short.class, "shortValue");
- instance.shortValue = (short) 0xabcd;
- assertEquals((short) 0xabcd, shortSwap.invoke(null, instance, (short) 0x1234));
- assertEquals((short) 0x1234, instance.shortValue);
- }
-
- public class Instance {
- public int intValue;
- public long longValue;
- public float floatValue;
- public double doubleValue;
- public Object objectValue;
- public boolean booleanValue;
- public byte byteValue;
- public char charValue;
- public short shortValue;
- }
-
- private <V> Method instanceSwapMethod(
- Class<V> valueClass, String fieldName) throws Exception {
- /*
- * public static int call(Instance instance, int newValue) {
- * int oldValue = instance.intValue;
- * instance.intValue = newValue;
- * return oldValue;
- * }
- */
- reset();
- Type<V> valueType = Type.get(valueClass);
- Type<Instance> objectType = Type.get(Instance.class);
- FieldId<Instance, V> fieldId = objectType.getField(valueType, fieldName);
- MethodId<?, V> methodId = GENERATED.getMethod(valueType, "call", objectType, valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Instance> localInstance = code.getParameter(0, objectType);
- Local<V> localNewValue = code.getParameter(1, valueType);
- Local<V> localOldValue = code.newLocal(valueType);
- code.iget(fieldId, localInstance, localOldValue);
- code.iput(fieldId, localInstance, localNewValue);
- code.returnValue(localOldValue);
- return getMethod();
- }
-
- public void testReadAndWriteStaticFields() throws Exception {
- Method intSwap = staticSwapMethod(int.class, "intValue");
- Static.intValue = 5;
- assertEquals(5, intSwap.invoke(null, 10));
- assertEquals(10, Static.intValue);
-
- Method longSwap = staticSwapMethod(long.class, "longValue");
- Static.longValue = 500L;
- assertEquals(500L, longSwap.invoke(null, 1234L));
- assertEquals(1234L, Static.longValue);
-
- Method booleanSwap = staticSwapMethod(boolean.class, "booleanValue");
- Static.booleanValue = false;
- assertEquals(false, booleanSwap.invoke(null, true));
- assertEquals(true, Static.booleanValue);
-
- Method floatSwap = staticSwapMethod(float.class, "floatValue");
- Static.floatValue = 1.5f;
- assertEquals(1.5f, floatSwap.invoke(null, 0.5f));
- assertEquals(0.5f, Static.floatValue);
-
- Method doubleSwap = staticSwapMethod(double.class, "doubleValue");
- Static.doubleValue = 155.5;
- assertEquals(155.5, doubleSwap.invoke(null, 266.6));
- assertEquals(266.6, Static.doubleValue);
-
- Method objectSwap = staticSwapMethod(Object.class, "objectValue");
- Static.objectValue = "before";
- assertEquals("before", objectSwap.invoke(null, "after"));
- assertEquals("after", Static.objectValue);
-
- Method byteSwap = staticSwapMethod(byte.class, "byteValue");
- Static.byteValue = 0x35;
- assertEquals((byte) 0x35, byteSwap.invoke(null, (byte) 0x64));
- assertEquals((byte) 0x64, Static.byteValue);
-
- Method charSwap = staticSwapMethod(char.class, "charValue");
- Static.charValue = 'A';
- assertEquals('A', charSwap.invoke(null, 'B'));
- assertEquals('B', Static.charValue);
-
- Method shortSwap = staticSwapMethod(short.class, "shortValue");
- Static.shortValue = (short) 0xabcd;
- assertEquals((short) 0xabcd, shortSwap.invoke(null, (short) 0x1234));
- assertEquals((short) 0x1234, Static.shortValue);
- }
-
- public static class Static {
- public static int intValue;
- public static long longValue;
- public static float floatValue;
- public static double doubleValue;
- public static Object objectValue;
- public static boolean booleanValue;
- public static byte byteValue;
- public static char charValue;
- public static short shortValue;
- }
-
- private <V> Method staticSwapMethod(Class<V> valueClass, String fieldName)
- throws Exception {
- /*
- * public static int call(int newValue) {
- * int oldValue = Static.intValue;
- * Static.intValue = newValue;
- * return oldValue;
- * }
- */
- reset();
- Type<V> valueType = Type.get(valueClass);
- Type<Static> objectType = Type.get(Static.class);
- FieldId<Static, V> fieldId = objectType.getField(valueType, fieldName);
- MethodId<?, V> methodId = GENERATED.getMethod(valueType, "call", valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<V> localNewValue = code.getParameter(0, valueType);
- Local<V> localOldValue = code.newLocal(valueType);
- code.sget(fieldId, localOldValue);
- code.sput(fieldId, localNewValue);
- code.returnValue(localOldValue);
- return getMethod();
- }
-
- public void testTypeCast() throws Exception {
- /*
- * public static String call(Object o) {
- * String s = (String) o;
- * }
- */
- MethodId<?, String> methodId = GENERATED.getMethod(Type.STRING, "call", Type.OBJECT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Object> localObject = code.getParameter(0, Type.OBJECT);
- Local<String> localString = code.newLocal(Type.STRING);
- code.typeCast(localObject, localString);
- code.returnValue(localString);
-
- Method method = getMethod();
- assertEquals("s", method.invoke(null, "s"));
- assertEquals(null, method.invoke(null, (String) null));
- try {
- method.invoke(null, 5);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(ClassCastException.class, expected.getCause().getClass());
- }
- }
-
- public void testInstanceOf() throws Exception {
- /*
- * public static boolean call(Object o) {
- * boolean result = o instanceof String;
- * return result;
- * }
- */
- MethodId<?, Boolean> methodId = GENERATED.getMethod(Type.BOOLEAN, "call", Type.OBJECT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Object> localObject = code.getParameter(0, Type.OBJECT);
- Local<Boolean> localResult = code.newLocal(Type.BOOLEAN);
- code.instanceOfType(localResult, localObject, Type.STRING);
- code.returnValue(localResult);
-
- Method method = getMethod();
- assertEquals(true, method.invoke(null, "s"));
- assertEquals(false, method.invoke(null, (String) null));
- assertEquals(false, method.invoke(null, 5));
- }
-
- /**
- * Tests that we can construct a for loop.
- */
- public void testForLoop() throws Exception {
- /*
- * public static int call(int count) {
- * int result = 1;
- * for (int i = 0; i < count; i += 1) {
- * result = result * 2;
- * }
- * return result;
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localCount = code.getParameter(0, Type.INT);
- Local<Integer> localResult = code.newLocal(Type.INT);
- Local<Integer> localI = code.newLocal(Type.INT);
- Local<Integer> local1 = code.newLocal(Type.INT);
- Local<Integer> local2 = code.newLocal(Type.INT);
- code.loadConstant(local1, 1);
- code.loadConstant(local2, 2);
- code.loadConstant(localResult, 1);
- code.loadConstant(localI, 0);
- Label loopCondition = code.newLabel();
- Label loopBody = code.newLabel();
- Label afterLoop = code.newLabel();
- code.mark(loopCondition);
- code.compare(Comparison.LT, localI, localCount, loopBody);
- code.jump(afterLoop);
- code.mark(loopBody);
- code.op(BinaryOp.MULTIPLY, localResult, localResult, local2);
- code.op(BinaryOp.ADD, localI, localI, local1);
- code.jump(loopCondition);
- code.mark(afterLoop);
- code.returnValue(localResult);
-
- Method pow2 = getMethod();
- assertEquals(1, pow2.invoke(null, 0));
- assertEquals(2, pow2.invoke(null, 1));
- assertEquals(4, pow2.invoke(null, 2));
- assertEquals(8, pow2.invoke(null, 3));
- assertEquals(16, pow2.invoke(null, 4));
- }
-
- /**
- * Tests that we can construct a while loop.
- */
- public void testWhileLoop() throws Exception {
- /*
- * public static int call(int max) {
- * int result = 1;
- * while (result < max) {
- * result = result * 2;
- * }
- * return result;
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localMax = code.getParameter(0, Type.INT);
- Local<Integer> localResult = code.newLocal(Type.INT);
- Local<Integer> local2 = code.newLocal(Type.INT);
- code.loadConstant(localResult, 1);
- code.loadConstant(local2, 2);
- Label loopCondition = code.newLabel();
- Label loopBody = code.newLabel();
- Label afterLoop = code.newLabel();
- code.mark(loopCondition);
- code.compare(Comparison.LT, localResult, localMax, loopBody);
- code.jump(afterLoop);
- code.mark(loopBody);
- code.op(BinaryOp.MULTIPLY, localResult, localResult, local2);
- code.jump(loopCondition);
- code.mark(afterLoop);
- code.returnValue(localResult);
-
- Method ceilPow2 = getMethod();
- assertEquals(1, ceilPow2.invoke(null, 1));
- assertEquals(2, ceilPow2.invoke(null, 2));
- assertEquals(4, ceilPow2.invoke(null, 3));
- assertEquals(16, ceilPow2.invoke(null, 10));
- assertEquals(128, ceilPow2.invoke(null, 100));
- assertEquals(1024, ceilPow2.invoke(null, 1000));
- }
-
- public void testIfElseBlock() throws Exception {
- /*
- * public static int call(int a, int b, int c) {
- * if (a < b) {
- * if (a < c) {
- * return a;
- * } else {
- * return c;
- * }
- * } else if (b < c) {
- * return b;
- * } else {
- * return c;
- * }
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(
- Type.INT, "call", Type.INT, Type.INT, Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localA = code.getParameter(0, Type.INT);
- Local<Integer> localB = code.getParameter(1, Type.INT);
- Local<Integer> localC = code.getParameter(2, Type.INT);
- Label aLessThanB = code.newLabel();
- Label aLessThanC = code.newLabel();
- Label bLessThanC = code.newLabel();
- code.compare(Comparison.LT, localA, localB, aLessThanB);
- code.compare(Comparison.LT, localB, localC, bLessThanC);
- code.returnValue(localC);
- // (a < b)
- code.mark(aLessThanB);
- code.compare(Comparison.LT, localA, localC, aLessThanC);
- code.returnValue(localC);
- // (a < c)
- code.mark(aLessThanC);
- code.returnValue(localA);
- // (b < c)
- code.mark(bLessThanC);
- code.returnValue(localB);
-
- Method min = getMethod();
- assertEquals(1, min.invoke(null, 1, 2, 3));
- assertEquals(1, min.invoke(null, 2, 3, 1));
- assertEquals(1, min.invoke(null, 2, 1, 3));
- assertEquals(1, min.invoke(null, 3, 2, 1));
- }
-
- public void testRecursion() throws Exception {
- /*
- * public static int call(int a) {
- * if (a < 2) {
- * return a;
- * }
- * a -= 1;
- * int x = call(a)
- * a -= 1;
- * int y = call(a);
- * int result = x + y;
- * return result;
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localA = code.getParameter(0, Type.INT);
- Local<Integer> local1 = code.newLocal(Type.INT);
- Local<Integer> local2 = code.newLocal(Type.INT);
- Local<Integer> localX = code.newLocal(Type.INT);
- Local<Integer> localY = code.newLocal(Type.INT);
- Local<Integer> localResult = code.newLocal(Type.INT);
- Label baseCase = code.newLabel();
- code.loadConstant(local1, 1);
- code.loadConstant(local2, 2);
- code.compare(Comparison.LT, localA, local2, baseCase);
- code.op(BinaryOp.SUBTRACT, localA, localA, local1);
- code.invokeStatic(methodId, localX, localA);
- code.op(BinaryOp.SUBTRACT, localA, localA, local1);
- code.invokeStatic(methodId, localY, localA);
- code.op(BinaryOp.ADD, localResult, localX, localY);
- code.returnValue(localResult);
- code.mark(baseCase);
- code.returnValue(localA);
-
- Method fib = getMethod();
- assertEquals(0, fib.invoke(null, 0));
- assertEquals(1, fib.invoke(null, 1));
- assertEquals(1, fib.invoke(null, 2));
- assertEquals(2, fib.invoke(null, 3));
- assertEquals(3, fib.invoke(null, 4));
- assertEquals(5, fib.invoke(null, 5));
- assertEquals(8, fib.invoke(null, 6));
- }
-
- public void testCatchExceptions() throws Exception {
- /*
- * public static String call(int i) {
- * try {
- * DexGeneratorTest.thrower(i);
- * return "NONE";
- * } catch (IllegalArgumentException e) {
- * return "IAE";
- * } catch (IllegalStateException e) {
- * return "ISE";
- * } catch (RuntimeException e) {
- * return "RE";
- * }
- */
- MethodId<?, String> methodId = GENERATED.getMethod(Type.STRING, "call", Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localI = code.getParameter(0, Type.INT);
- Local<String> result = code.newLocal(Type.STRING);
- Label catchIae = code.newLabel();
- Label catchIse = code.newLabel();
- Label catchRe = code.newLabel();
-
- code.addCatchClause(Type.get(IllegalArgumentException.class), catchIae);
- code.addCatchClause(Type.get(IllegalStateException.class), catchIse);
- code.addCatchClause(Type.get(RuntimeException.class), catchRe);
- MethodId<?, ?> thrower = TEST_TYPE.getMethod(Type.VOID, "thrower", Type.INT);
- code.invokeStatic(thrower, null, localI);
- code.loadConstant(result, "NONE");
- code.returnValue(result);
-
- code.mark(catchIae);
- code.loadConstant(result, "IAE");
- code.returnValue(result);
-
- code.mark(catchIse);
- code.loadConstant(result, "ISE");
- code.returnValue(result);
-
- code.mark(catchRe);
- code.loadConstant(result, "RE");
- code.returnValue(result);
-
- Method method = getMethod();
- assertEquals("NONE", method.invoke(null, 0));
- assertEquals("IAE", method.invoke(null, 1));
- assertEquals("ISE", method.invoke(null, 2));
- assertEquals("RE", method.invoke(null, 3));
- try {
- method.invoke(null, 4);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(IOException.class, expected.getCause().getClass());
- }
- }
-
- @SuppressWarnings("unused") // called by generated code
- public static void thrower(int a) throws Exception {
- switch (a) {
- case 0:
- return;
- case 1:
- throw new IllegalArgumentException();
- case 2:
- throw new IllegalStateException();
- case 3:
- throw new UnsupportedOperationException();
- case 4:
- throw new IOException();
- default:
- throw new AssertionError();
- }
- }
-
- public void testNestedCatchClauses() throws Exception {
- /*
- * public static String call(int a, int b, int c) {
- * try {
- * DexGeneratorTest.thrower(a);
- * try {
- * DexGeneratorTest.thrower(b);
- * } catch (IllegalArgumentException) {
- * return "INNER";
- * }
- * DexGeneratorTest.thrower(c);
- * return "NONE";
- * } catch (IllegalArgumentException e) {
- * return "OUTER";
- * }
- */
- MethodId<?, String> methodId = GENERATED.getMethod(
- Type.STRING, "call", Type.INT, Type.INT, Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localA = code.getParameter(0, Type.INT);
- Local<Integer> localB = code.getParameter(1, Type.INT);
- Local<Integer> localC = code.getParameter(2, Type.INT);
- Local<String> localResult = code.newLocal(Type.STRING);
- Label catchInner = code.newLabel();
- Label catchOuter = code.newLabel();
-
- Type<IllegalArgumentException> iaeType = Type.get(IllegalArgumentException.class);
- code.addCatchClause(iaeType, catchOuter);
-
- MethodId<?, ?> thrower = TEST_TYPE.getMethod(Type.VOID, "thrower", Type.INT);
- code.invokeStatic(thrower, null, localA);
-
- // for the inner catch clause, we stash the old label and put it back afterwards.
- Label previousLabel = code.removeCatchClause(iaeType);
- code.addCatchClause(iaeType, catchInner);
- code.invokeStatic(thrower, null, localB);
- code.removeCatchClause(iaeType);
- code.addCatchClause(iaeType, previousLabel);
- code.invokeStatic(thrower, null, localC);
- code.loadConstant(localResult, "NONE");
- code.returnValue(localResult);
-
- code.mark(catchInner);
- code.loadConstant(localResult, "INNER");
- code.returnValue(localResult);
-
- code.mark(catchOuter);
- code.loadConstant(localResult, "OUTER");
- code.returnValue(localResult);
-
- Method method = getMethod();
- assertEquals("OUTER", method.invoke(null, 1, 0, 0));
- assertEquals("INNER", method.invoke(null, 0, 1, 0));
- assertEquals("OUTER", method.invoke(null, 0, 0, 1));
- assertEquals("NONE", method.invoke(null, 0, 0, 0));
- }
-
- public void testThrow() throws Exception {
- /*
- * public static void call() {
- * throw new IllegalStateException();
- * }
- */
- MethodId<?, Void> methodId = GENERATED.getMethod(Type.VOID, "call");
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Type<IllegalStateException> iseType = Type.get(IllegalStateException.class);
- MethodId<IllegalStateException, Void> iseConstructor = iseType.getConstructor();
- Local<IllegalStateException> localIse = code.newLocal(iseType);
- code.newInstance(localIse, iseConstructor);
- code.throwValue(localIse);
-
- try {
- getMethod().invoke(null);
- fail();
- } catch (InvocationTargetException expected) {
- assertEquals(IllegalStateException.class, expected.getCause().getClass());
- }
- }
-
- public void testUnusedParameters() throws Exception {
- /*
- * public static void call(int unused1, long unused2, long unused3) {}
- */
- MethodId<?, Void> methodId = GENERATED.getMethod(
- Type.VOID, "call", Type.INT, Type.LONG, Type.LONG);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- code.returnVoid();
- getMethod().invoke(null, 1, 2, 3);
- }
-
- public void testFloatingPointCompare() throws Exception {
- Method floatG = floatingPointCompareMethod(Type.FLOAT, 1);
- assertEquals(-1, floatG.invoke(null, 1.0f, Float.POSITIVE_INFINITY));
- assertEquals(-1, floatG.invoke(null, 1.0f, 2.0f));
- assertEquals(0, floatG.invoke(null, 1.0f, 1.0f));
- assertEquals(1, floatG.invoke(null, 2.0f, 1.0f));
- assertEquals(1, floatG.invoke(null, 1.0f, Float.NaN));
- assertEquals(1, floatG.invoke(null, Float.NaN, 1.0f));
- assertEquals(1, floatG.invoke(null, Float.NaN, Float.NaN));
- assertEquals(1, floatG.invoke(null, Float.NaN, Float.POSITIVE_INFINITY));
-
- Method floatL = floatingPointCompareMethod(Type.FLOAT, -1);
- assertEquals(-1, floatG.invoke(null, 1.0f, Float.POSITIVE_INFINITY));
- assertEquals(-1, floatL.invoke(null, 1.0f, 2.0f));
- assertEquals(0, floatL.invoke(null, 1.0f, 1.0f));
- assertEquals(1, floatL.invoke(null, 2.0f, 1.0f));
- assertEquals(-1, floatL.invoke(null, 1.0f, Float.NaN));
- assertEquals(-1, floatL.invoke(null, Float.NaN, 1.0f));
- assertEquals(-1, floatL.invoke(null, Float.NaN, Float.NaN));
- assertEquals(-1, floatL.invoke(null, Float.NaN, Float.POSITIVE_INFINITY));
-
- Method doubleG = floatingPointCompareMethod(Type.DOUBLE, 1);
- assertEquals(-1, doubleG.invoke(null, 1.0, Double.POSITIVE_INFINITY));
- assertEquals(-1, doubleG.invoke(null, 1.0, 2.0));
- assertEquals(0, doubleG.invoke(null, 1.0, 1.0));
- assertEquals(1, doubleG.invoke(null, 2.0, 1.0));
- assertEquals(1, doubleG.invoke(null, 1.0, Double.NaN));
- assertEquals(1, doubleG.invoke(null, Double.NaN, 1.0));
- assertEquals(1, doubleG.invoke(null, Double.NaN, Double.NaN));
- assertEquals(1, doubleG.invoke(null, Double.NaN, Double.POSITIVE_INFINITY));
-
- Method doubleL = floatingPointCompareMethod(Type.DOUBLE, -1);
- assertEquals(-1, doubleL.invoke(null, 1.0, Double.POSITIVE_INFINITY));
- assertEquals(-1, doubleL.invoke(null, 1.0, 2.0));
- assertEquals(0, doubleL.invoke(null, 1.0, 1.0));
- assertEquals(1, doubleL.invoke(null, 2.0, 1.0));
- assertEquals(-1, doubleL.invoke(null, 1.0, Double.NaN));
- assertEquals(-1, doubleL.invoke(null, Double.NaN, 1.0));
- assertEquals(-1, doubleL.invoke(null, Double.NaN, Double.NaN));
- assertEquals(-1, doubleL.invoke(null, Double.NaN, Double.POSITIVE_INFINITY));
- }
-
- private <T extends Number> Method floatingPointCompareMethod(
- Type<T> valueType, int nanValue) throws Exception {
- /*
- * public static int call(float a, float b) {
- * int result = a <=> b;
- * return result;
- * }
- */
- reset();
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", valueType, valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<T> localA = code.getParameter(0, valueType);
- Local<T> localB = code.getParameter(1, valueType);
- Local<Integer> localResult = code.newLocal(Type.INT);
- code.compare(localA, localB, localResult, nanValue);
- code.returnValue(localResult);
- return getMethod();
- }
-
- public void testLongCompare() throws Exception {
- /*
- * public static int call(long a, long b) {
- * int result = a <=> b;
- * return result;
- * }
- */
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", Type.LONG, Type.LONG);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Long> localA = code.getParameter(0, Type.LONG);
- Local<Long> localB = code.getParameter(1, Type.LONG);
- Local<Integer> localResult = code.newLocal(Type.INT);
- code.compare(localA, localB, localResult);
- code.returnValue(localResult);
-
- Method method = getMethod();
- assertEquals(0, method.invoke(null, Long.MIN_VALUE, Long.MIN_VALUE));
- assertEquals(-1, method.invoke(null, Long.MIN_VALUE, 0));
- assertEquals(-1, method.invoke(null, Long.MIN_VALUE, Long.MAX_VALUE));
- assertEquals(1, method.invoke(null, 0, Long.MIN_VALUE));
- assertEquals(0, method.invoke(null, 0, 0));
- assertEquals(-1, method.invoke(null, 0, Long.MAX_VALUE));
- assertEquals(1, method.invoke(null, Long.MAX_VALUE, Long.MIN_VALUE));
- assertEquals(1, method.invoke(null, Long.MAX_VALUE, 0));
- assertEquals(0, method.invoke(null, Long.MAX_VALUE, Long.MAX_VALUE));
- }
-
- public void testArrayLength() throws Exception {
- Method booleanArrayLength = arrayLengthMethod(BOOLEAN_ARRAY);
- assertEquals(0, booleanArrayLength.invoke(null, new Object[] { new boolean[0] }));
- assertEquals(5, booleanArrayLength.invoke(null, new Object[] { new boolean[5] }));
-
- Method intArrayLength = arrayLengthMethod(INT_ARRAY);
- assertEquals(0, intArrayLength.invoke(null, new Object[] { new int[0] }));
- assertEquals(5, intArrayLength.invoke(null, new Object[] { new int[5] }));
-
- Method longArrayLength = arrayLengthMethod(LONG_ARRAY);
- assertEquals(0, longArrayLength.invoke(null, new Object[] { new long[0] }));
- assertEquals(5, longArrayLength.invoke(null, new Object[] { new long[5] }));
-
- Method objectArrayLength = arrayLengthMethod(OBJECT_ARRAY);
- assertEquals(0, objectArrayLength.invoke(null, new Object[] { new Object[0] }));
- assertEquals(5, objectArrayLength.invoke(null, new Object[] { new Object[5] }));
-
- Method long2dArrayLength = arrayLengthMethod(LONG_2D_ARRAY);
- assertEquals(0, long2dArrayLength.invoke(null, new Object[] { new long[0][0] }));
- assertEquals(5, long2dArrayLength.invoke(null, new Object[] { new long[5][10] }));
- }
-
- private <T> Method arrayLengthMethod(Type<T> valueType) throws Exception {
- /*
- * public static int call(long[] array) {
- * int result = array.length;
- * return result;
- * }
- */
- reset();
- MethodId<?, Integer> methodId = GENERATED.getMethod(Type.INT, "call", valueType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<T> localArray = code.getParameter(0, valueType);
- Local<Integer> localResult = code.newLocal(Type.INT);
- code.arrayLength(localArray, localResult);
- code.returnValue(localResult);
- return getMethod();
- }
-
- public void testNewArray() throws Exception {
- Method newBooleanArray = newArrayMethod(BOOLEAN_ARRAY);
- assertEquals("[]", Arrays.toString((boolean[]) newBooleanArray.invoke(null, 0)));
- assertEquals("[false, false, false]",
- Arrays.toString((boolean[]) newBooleanArray.invoke(null, 3)));
-
- Method newIntArray = newArrayMethod(INT_ARRAY);
- assertEquals("[]", Arrays.toString((int[]) newIntArray.invoke(null, 0)));
- assertEquals("[0, 0, 0]", Arrays.toString((int[]) newIntArray.invoke(null, 3)));
-
- Method newLongArray = newArrayMethod(LONG_ARRAY);
- assertEquals("[]", Arrays.toString((long[]) newLongArray.invoke(null, 0)));
- assertEquals("[0, 0, 0]", Arrays.toString((long[]) newLongArray.invoke(null, 3)));
-
- Method newObjectArray = newArrayMethod(OBJECT_ARRAY);
- assertEquals("[]", Arrays.toString((Object[]) newObjectArray.invoke(null, 0)));
- assertEquals("[null, null, null]",
- Arrays.toString((Object[]) newObjectArray.invoke(null, 3)));
-
- Method new2dLongArray = newArrayMethod(LONG_2D_ARRAY);
- assertEquals("[]", Arrays.deepToString((long[][]) new2dLongArray.invoke(null, 0)));
- assertEquals("[null, null, null]",
- Arrays.deepToString((long[][]) new2dLongArray.invoke(null, 3)));
- }
-
- private <T> Method newArrayMethod(Type<T> valueType) throws Exception {
- /*
- * public static long[] call(int length) {
- * long[] result = new long[length];
- * return result;
- * }
- */
- reset();
- MethodId<?, T> methodId = GENERATED.getMethod(valueType, "call", Type.INT);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<Integer> localLength = code.getParameter(0, Type.INT);
- Local<T> localResult = code.newLocal(valueType);
- code.newArray(localLength, localResult);
- code.returnValue(localResult);
- return getMethod();
- }
-
- public void testReadAndWriteArray() throws Exception {
- Method swapBooleanArray = arraySwapMethod(BOOLEAN_ARRAY, Type.BOOLEAN);
- boolean[] booleans = new boolean[3];
- assertEquals(false, swapBooleanArray.invoke(null, booleans, 1, true));
- assertEquals("[false, true, false]", Arrays.toString(booleans));
-
- Method swapIntArray = arraySwapMethod(INT_ARRAY, Type.INT);
- int[] ints = new int[3];
- assertEquals(0, swapIntArray.invoke(null, ints, 1, 5));
- assertEquals("[0, 5, 0]", Arrays.toString(ints));
-
- Method swapLongArray = arraySwapMethod(LONG_ARRAY, Type.LONG);
- long[] longs = new long[3];
- assertEquals(0L, swapLongArray.invoke(null, longs, 1, 6L));
- assertEquals("[0, 6, 0]", Arrays.toString(longs));
-
- Method swapObjectArray = arraySwapMethod(OBJECT_ARRAY, Type.OBJECT);
- Object[] objects = new Object[3];
- assertEquals(null, swapObjectArray.invoke(null, objects, 1, "X"));
- assertEquals("[null, X, null]", Arrays.toString(objects));
-
- Method swapLong2dArray = arraySwapMethod(LONG_2D_ARRAY, LONG_ARRAY);
- long[][] longs2d = new long[3][];
- assertEquals(null, swapLong2dArray.invoke(null, longs2d, 1, new long[] { 7 }));
- assertEquals("[null, [7], null]", Arrays.deepToString(longs2d));
- }
-
- private <A, T> Method arraySwapMethod(Type<A> arrayType, Type<T> singleType)
- throws Exception {
- /*
- * public static long swap(long[] array, int index, long newValue) {
- * long result = array[index];
- * array[index] = newValue;
- * return result;
- * }
- */
- reset();
- MethodId<?, T> methodId = GENERATED.getMethod(
- singleType, "call", arrayType, Type.INT, singleType);
- Code code = generator.declare(methodId, ACC_PUBLIC | ACC_STATIC);
- Local<A> localArray = code.getParameter(0, arrayType);
- Local<Integer> localIndex = code.getParameter(1, Type.INT);
- Local<T> localNewValue = code.getParameter(2, singleType);
- Local<T> localResult = code.newLocal(singleType);
- code.aget(localArray, localIndex, localResult);
- code.aput(localArray, localIndex, localNewValue);
- code.returnValue(localResult);
- return getMethod();
- }
-
- // TODO: fail if a label is unreachable (never navigated to)
-
- // TODO: more strict type parameters: Integer on methods
-
- // TODO: don't generate multiple times (?)
-
- private void addDefaultConstructor() {
- Code code = generator.declare(GENERATED.getConstructor(), ACC_PUBLIC | ACC_CONSTRUCTOR);
- Local<?> thisRef = code.getThis(GENERATED);
- code.invokeDirect(Type.OBJECT.getConstructor(), null, thisRef);
- code.returnVoid();
- }
-
- /**
- * Returns the generated method.
- */
- private Method getMethod() throws Exception {
- Class<?> generated = loadAndGenerate();
- for (Method method : generated.getMethods()) {
- if (method.getName().equals("call")) {
- return method;
- }
- }
- throw new IllegalStateException("no call() method");
- }
-
- private Class<?> loadAndGenerate() throws IOException, ClassNotFoundException {
- return generator.load(DexGeneratorTest.class.getClassLoader()).loadClass("Generated");
- }
-}
diff --git a/dx/junit-tests/com/android/dx/gen/TypeTest.java b/dx/junit-tests/com/android/dx/gen/TypeTest.java
deleted file mode 100644
index c2f4f0438..000000000
--- a/dx/junit-tests/com/android/dx/gen/TypeTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import junit.framework.TestCase;
-
-public final class TypeTest extends TestCase {
-
- private final DexGenerator generator = new DexGenerator();
-
- public void testGetType() {
- assertEquals("Ljava/lang/String;", Type.get(String.class).getName());
- assertEquals("[Ljava/lang/String;", Type.get(String[].class).getName());
- assertEquals("[[Ljava/lang/String;", Type.get(String[][].class).getName());
- assertEquals("I", Type.get(int.class).getName());
- assertEquals("[I", Type.get(int[].class).getName());
- assertEquals("[[I", Type.get(int[][].class).getName());
- }
-}
diff --git a/dx/src/com/android/dx/util/_tests/_BitIntSet.java b/dx/junit-tests/com/android/dx/util/BitIntSetTest.java
index e26d7a4f5..d46d14fe3 100644
--- a/dx/src/com/android/dx/util/_tests/_BitIntSet.java
+++ b/dx/junit-tests/com/android/dx/util/BitIntSetTest.java
@@ -14,17 +14,12 @@
* limitations under the License.
*/
-package com.android.dx.util._tests;
-
-import com.android.dx.util.BitIntSet;
-import com.android.dx.util.IntIterator;
-import com.android.dx.util.ListIntSet;
-
-import junit.framework.TestCase;
+package com.android.dx.util;
import java.util.NoSuchElementException;
+import junit.framework.TestCase;
-public class _BitIntSet extends TestCase {
+public final class BitIntSetTest extends TestCase {
public void test_basic() {
BitIntSet set = new BitIntSet(32);
diff --git a/dx/src/com/android/dx/util/_tests/_Bits.java b/dx/junit-tests/com/android/dx/util/BitsTest.java
index a95fc14d7..e4275132f 100644
--- a/dx/src/com/android/dx/util/_tests/_Bits.java
+++ b/dx/junit-tests/com/android/dx/util/BitsTest.java
@@ -14,17 +14,11 @@
* limitations under the License.
*/
-package com.android.dx.util._tests;
-
-import com.android.dx.util.Bits;
+package com.android.dx.util;
import junit.framework.TestCase;
-/**
- * Test the class {@code com.android.dx.util.Bits}.
- */
-public class _Bits
- extends TestCase {
+public final class BitsTest extends TestCase {
public void test_makeBitSet() {
assertEquals(label(0), 0, Bits.makeBitSet(0).length);
diff --git a/dx/src/com/android/dx/util/_tests/_IntList.java b/dx/junit-tests/com/android/dx/util/IntListTest.java
index dadbd54fb..7a53a67ba 100644
--- a/dx/src/com/android/dx/util/_tests/_IntList.java
+++ b/dx/junit-tests/com/android/dx/util/IntListTest.java
@@ -14,19 +14,11 @@
* limitations under the License.
*/
-package com.android.dx.util._tests;
-
-import com.android.dx.util.IntList;
+package com.android.dx.util;
import junit.framework.TestCase;
-/**
- * Test the class {@code com.android.dx.util.IntList}.
- */
-public class _IntList
- extends TestCase {
- // TODO: Add tests for the rest of the methods.
-
+public final class IntListTest extends TestCase {
public void test_contains() {
for (int sz = 0; sz < 100; sz++) {
IntList list = new IntList(sz);
diff --git a/dx/src/com/android/dx/util/_tests/_ListIntSet.java b/dx/junit-tests/com/android/dx/util/ListIntSetTest.java
index ccd599178..868e630a1 100644
--- a/dx/src/com/android/dx/util/_tests/_ListIntSet.java
+++ b/dx/junit-tests/com/android/dx/util/ListIntSetTest.java
@@ -14,17 +14,12 @@
* limitations under the License.
*/
-package com.android.dx.util._tests;
-
-import com.android.dx.util.BitIntSet;
-import com.android.dx.util.ListIntSet;
-import com.android.dx.util.IntIterator;
-
-import junit.framework.TestCase;
+package com.android.dx.util;
import java.util.NoSuchElementException;
+import junit.framework.TestCase;
-public class _ListIntSet extends TestCase {
+public final class ListIntSetTest extends TestCase {
public void test_basic() {
ListIntSet set = new ListIntSet();
diff --git a/dx/src/com/android/dx/command/Main.java b/dx/src/com/android/dx/command/Main.java
index d0bbbe2c2..10a117929 100644
--- a/dx/src/com/android/dx/command/Main.java
+++ b/dx/src/com/android/dx/command/Main.java
@@ -18,8 +18,6 @@ package com.android.dx.command;
import com.android.dx.Version;
-import junit.textui.TestRunner;
-
/**
* Main class for dx. It recognizes enough options to be able to dispatch
* to the right "actual" main.
@@ -50,8 +48,6 @@ public class Main {
" [--width=<n>] [<file>.class | <file>.txt] ...\n" +
" Dump classfiles, or transformations thereof, in a " +
"human-oriented format.\n" +
- " dx --junit [-wait] <TestClass>\n" +
- " Run the indicated unit test.\n" +
" dx --find-usages <file.dex> <declaring type> <member>\n" +
" Find references and declarations to a field or method.\n" +
" declaring type: a class name in internal form, like " +
@@ -101,9 +97,6 @@ public class Main {
com.android.dx.command.annotool.Main.main(
without(args, i));
break;
- } else if (arg.equals("--junit")) {
- TestRunner.main(without(args, i));
- break;
} else if (arg.equals("--find-usages")) {
com.android.dx.command.findusages.Main.main(without(args, i));
break;
diff --git a/dx/src/com/android/dx/dex/DexOptions.java b/dx/src/com/android/dx/dex/DexOptions.java
index a72532565..03573844e 100644
--- a/dx/src/com/android/dx/dex/DexOptions.java
+++ b/dx/src/com/android/dx/dex/DexOptions.java
@@ -21,7 +21,7 @@ package com.android.dx.dex;
*/
public class DexOptions {
/** target API level */
- public int targetApiLevel = DexFormat.API_CURRENT;
+ public int targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
/**
* Gets the dex file magic number corresponding to this instance.
diff --git a/dx/src/com/android/dx/dex/TableOfContents.java b/dx/src/com/android/dx/dex/TableOfContents.java
index 877dddbeb..fbe46264c 100644
--- a/dx/src/com/android/dx/dex/TableOfContents.java
+++ b/dx/src/com/android/dx/dex/TableOfContents.java
@@ -77,7 +77,7 @@ public final class TableOfContents {
byte[] magic = headerIn.readByteArray(8);
int apiTarget = DexFormat.magicToApi(magic);
- if (apiTarget < 0) {
+ if (apiTarget != DexFormat.API_NO_EXTENDED_OPCODES) {
throw new DexException("Unexpected magic: " + Arrays.toString(magic));
}
@@ -166,7 +166,7 @@ public final class TableOfContents {
}
public void writeHeader(DexBuffer.Section out) throws IOException {
- out.write(DexFormat.apiToMagic(DexFormat.API_CURRENT).getBytes("UTF-8"));
+ out.write(DexFormat.apiToMagic(DexFormat.API_NO_EXTENDED_OPCODES).getBytes("UTF-8"));
out.writeInt(checksum);
out.write(signature);
out.writeInt(fileSize);
diff --git a/dx/src/com/android/dx/dex/code/Dops.java b/dx/src/com/android/dx/dex/code/Dops.java
index c0662527e..cc5c173ed 100644
--- a/dx/src/com/android/dx/dex/code/Dops.java
+++ b/dx/src/com/android/dx/dex/code/Dops.java
@@ -40,10 +40,7 @@ import com.android.dx.dex.code.form.Form31t;
import com.android.dx.dex.code.form.Form32x;
import com.android.dx.dex.code.form.Form35c;
import com.android.dx.dex.code.form.Form3rc;
-import com.android.dx.dex.code.form.Form41c;
import com.android.dx.dex.code.form.Form51l;
-import com.android.dx.dex.code.form.Form52c;
-import com.android.dx.dex.code.form.Form5rc;
import com.android.dx.dex.code.form.SpecialFormat;
import com.android.dx.io.Opcodes;
@@ -180,7 +177,7 @@ public final class Dops {
public static final Dop CONST_CLASS =
new Dop(Opcodes.CONST_CLASS, Opcodes.CONST_CLASS,
- Opcodes.CONST_CLASS_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop MONITOR_ENTER =
new Dop(Opcodes.MONITOR_ENTER, Opcodes.MONITOR_ENTER,
@@ -192,11 +189,11 @@ public final class Dops {
public static final Dop CHECK_CAST =
new Dop(Opcodes.CHECK_CAST, Opcodes.CHECK_CAST,
- Opcodes.CHECK_CAST_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop INSTANCE_OF =
new Dop(Opcodes.INSTANCE_OF, Opcodes.INSTANCE_OF,
- Opcodes.INSTANCE_OF_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop ARRAY_LENGTH =
new Dop(Opcodes.ARRAY_LENGTH, Opcodes.ARRAY_LENGTH,
@@ -204,11 +201,11 @@ public final class Dops {
public static final Dop NEW_INSTANCE =
new Dop(Opcodes.NEW_INSTANCE, Opcodes.NEW_INSTANCE,
- Opcodes.NEW_INSTANCE_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop NEW_ARRAY =
new Dop(Opcodes.NEW_ARRAY, Opcodes.NEW_ARRAY,
- Opcodes.NEW_ARRAY_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop FILLED_NEW_ARRAY =
new Dop(Opcodes.FILLED_NEW_ARRAY, Opcodes.FILLED_NEW_ARRAY,
@@ -216,7 +213,7 @@ public final class Dops {
public static final Dop FILLED_NEW_ARRAY_RANGE =
new Dop(Opcodes.FILLED_NEW_ARRAY_RANGE, Opcodes.FILLED_NEW_ARRAY,
- Opcodes.FILLED_NEW_ARRAY_JUMBO, Form3rc.THE_ONE, false);
+ Opcodes.NO_NEXT, Form3rc.THE_ONE, false);
public static final Dop FILL_ARRAY_DATA =
new Dop(Opcodes.FILL_ARRAY_DATA, Opcodes.FILL_ARRAY_DATA,
@@ -372,115 +369,115 @@ public final class Dops {
public static final Dop IGET =
new Dop(Opcodes.IGET, Opcodes.IGET,
- Opcodes.IGET_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IGET_WIDE =
new Dop(Opcodes.IGET_WIDE, Opcodes.IGET_WIDE,
- Opcodes.IGET_WIDE_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IGET_OBJECT =
new Dop(Opcodes.IGET_OBJECT, Opcodes.IGET_OBJECT,
- Opcodes.IGET_OBJECT_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IGET_BOOLEAN =
new Dop(Opcodes.IGET_BOOLEAN, Opcodes.IGET_BOOLEAN,
- Opcodes.IGET_BOOLEAN_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IGET_BYTE =
new Dop(Opcodes.IGET_BYTE, Opcodes.IGET_BYTE,
- Opcodes.IGET_BYTE_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IGET_CHAR =
new Dop(Opcodes.IGET_CHAR, Opcodes.IGET_CHAR,
- Opcodes.IGET_CHAR_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IGET_SHORT =
new Dop(Opcodes.IGET_SHORT, Opcodes.IGET_SHORT,
- Opcodes.IGET_SHORT_JUMBO, Form22c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, true);
public static final Dop IPUT =
new Dop(Opcodes.IPUT, Opcodes.IPUT,
- Opcodes.IPUT_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop IPUT_WIDE =
new Dop(Opcodes.IPUT_WIDE, Opcodes.IPUT_WIDE,
- Opcodes.IPUT_WIDE_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop IPUT_OBJECT =
new Dop(Opcodes.IPUT_OBJECT, Opcodes.IPUT_OBJECT,
- Opcodes.IPUT_OBJECT_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop IPUT_BOOLEAN =
new Dop(Opcodes.IPUT_BOOLEAN, Opcodes.IPUT_BOOLEAN,
- Opcodes.IPUT_BOOLEAN_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop IPUT_BYTE =
new Dop(Opcodes.IPUT_BYTE, Opcodes.IPUT_BYTE,
- Opcodes.IPUT_BYTE_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop IPUT_CHAR =
new Dop(Opcodes.IPUT_CHAR, Opcodes.IPUT_CHAR,
- Opcodes.IPUT_CHAR_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop IPUT_SHORT =
new Dop(Opcodes.IPUT_SHORT, Opcodes.IPUT_SHORT,
- Opcodes.IPUT_SHORT_JUMBO, Form22c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form22c.THE_ONE, false);
public static final Dop SGET =
new Dop(Opcodes.SGET, Opcodes.SGET,
- Opcodes.SGET_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SGET_WIDE =
new Dop(Opcodes.SGET_WIDE, Opcodes.SGET_WIDE,
- Opcodes.SGET_WIDE_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SGET_OBJECT =
new Dop(Opcodes.SGET_OBJECT, Opcodes.SGET_OBJECT,
- Opcodes.SGET_OBJECT_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SGET_BOOLEAN =
new Dop(Opcodes.SGET_BOOLEAN, Opcodes.SGET_BOOLEAN,
- Opcodes.SGET_BOOLEAN_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SGET_BYTE =
new Dop(Opcodes.SGET_BYTE, Opcodes.SGET_BYTE,
- Opcodes.SGET_BYTE_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SGET_CHAR =
new Dop(Opcodes.SGET_CHAR, Opcodes.SGET_CHAR,
- Opcodes.SGET_CHAR_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SGET_SHORT =
new Dop(Opcodes.SGET_SHORT, Opcodes.SGET_SHORT,
- Opcodes.SGET_SHORT_JUMBO, Form21c.THE_ONE, true);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, true);
public static final Dop SPUT =
new Dop(Opcodes.SPUT, Opcodes.SPUT,
- Opcodes.SPUT_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop SPUT_WIDE =
new Dop(Opcodes.SPUT_WIDE, Opcodes.SPUT_WIDE,
- Opcodes.SPUT_WIDE_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop SPUT_OBJECT =
new Dop(Opcodes.SPUT_OBJECT, Opcodes.SPUT_OBJECT,
- Opcodes.SPUT_OBJECT_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop SPUT_BOOLEAN =
new Dop(Opcodes.SPUT_BOOLEAN, Opcodes.SPUT_BOOLEAN,
- Opcodes.SPUT_BOOLEAN_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop SPUT_BYTE =
new Dop(Opcodes.SPUT_BYTE, Opcodes.SPUT_BYTE,
- Opcodes.SPUT_BYTE_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop SPUT_CHAR =
new Dop(Opcodes.SPUT_CHAR, Opcodes.SPUT_CHAR,
- Opcodes.SPUT_CHAR_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop SPUT_SHORT =
new Dop(Opcodes.SPUT_SHORT, Opcodes.SPUT_SHORT,
- Opcodes.SPUT_SHORT_JUMBO, Form21c.THE_ONE, false);
+ Opcodes.NO_NEXT, Form21c.THE_ONE, false);
public static final Dop INVOKE_VIRTUAL =
new Dop(Opcodes.INVOKE_VIRTUAL, Opcodes.INVOKE_VIRTUAL,
@@ -504,23 +501,23 @@ public final class Dops {
public static final Dop INVOKE_VIRTUAL_RANGE =
new Dop(Opcodes.INVOKE_VIRTUAL_RANGE, Opcodes.INVOKE_VIRTUAL,
- Opcodes.INVOKE_VIRTUAL_JUMBO, Form3rc.THE_ONE, false);
+ Opcodes.NO_NEXT, Form3rc.THE_ONE, false);
public static final Dop INVOKE_SUPER_RANGE =
new Dop(Opcodes.INVOKE_SUPER_RANGE, Opcodes.INVOKE_SUPER,
- Opcodes.INVOKE_SUPER_JUMBO, Form3rc.THE_ONE, false);
+ Opcodes.NO_NEXT, Form3rc.THE_ONE, false);
public static final Dop INVOKE_DIRECT_RANGE =
new Dop(Opcodes.INVOKE_DIRECT_RANGE, Opcodes.INVOKE_DIRECT,
- Opcodes.INVOKE_DIRECT_JUMBO, Form3rc.THE_ONE, false);
+ Opcodes.NO_NEXT, Form3rc.THE_ONE, false);
public static final Dop INVOKE_STATIC_RANGE =
new Dop(Opcodes.INVOKE_STATIC_RANGE, Opcodes.INVOKE_STATIC,
- Opcodes.INVOKE_STATIC_JUMBO, Form3rc.THE_ONE, false);
+ Opcodes.NO_NEXT, Form3rc.THE_ONE, false);
public static final Dop INVOKE_INTERFACE_RANGE =
new Dop(Opcodes.INVOKE_INTERFACE_RANGE, Opcodes.INVOKE_INTERFACE,
- Opcodes.INVOKE_INTERFACE_JUMBO, Form3rc.THE_ONE, false);
+ Opcodes.NO_NEXT, Form3rc.THE_ONE, false);
public static final Dop NEG_INT =
new Dop(Opcodes.NEG_INT, Opcodes.NEG_INT,
@@ -938,162 +935,6 @@ public final class Dops {
new Dop(Opcodes.USHR_INT_LIT8, Opcodes.USHR_INT,
Opcodes.NO_NEXT, Form22b.THE_ONE, true);
- public static final Dop CONST_CLASS_JUMBO =
- new Dop(Opcodes.CONST_CLASS_JUMBO, Opcodes.CONST_CLASS,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop CHECK_CAST_JUMBO =
- new Dop(Opcodes.CHECK_CAST_JUMBO, Opcodes.CHECK_CAST,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop INSTANCE_OF_JUMBO =
- new Dop(Opcodes.INSTANCE_OF_JUMBO, Opcodes.INSTANCE_OF,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop NEW_INSTANCE_JUMBO =
- new Dop(Opcodes.NEW_INSTANCE_JUMBO, Opcodes.NEW_INSTANCE,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop NEW_ARRAY_JUMBO =
- new Dop(Opcodes.NEW_ARRAY_JUMBO, Opcodes.NEW_ARRAY,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop FILLED_NEW_ARRAY_JUMBO =
- new Dop(Opcodes.FILLED_NEW_ARRAY_JUMBO, Opcodes.FILLED_NEW_ARRAY,
- Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
- public static final Dop IGET_JUMBO =
- new Dop(Opcodes.IGET_JUMBO, Opcodes.IGET,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IGET_WIDE_JUMBO =
- new Dop(Opcodes.IGET_WIDE_JUMBO, Opcodes.IGET_WIDE,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IGET_OBJECT_JUMBO =
- new Dop(Opcodes.IGET_OBJECT_JUMBO, Opcodes.IGET_OBJECT,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IGET_BOOLEAN_JUMBO =
- new Dop(Opcodes.IGET_BOOLEAN_JUMBO, Opcodes.IGET_BOOLEAN,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IGET_BYTE_JUMBO =
- new Dop(Opcodes.IGET_BYTE_JUMBO, Opcodes.IGET_BYTE,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IGET_CHAR_JUMBO =
- new Dop(Opcodes.IGET_CHAR_JUMBO, Opcodes.IGET_CHAR,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IGET_SHORT_JUMBO =
- new Dop(Opcodes.IGET_SHORT_JUMBO, Opcodes.IGET_SHORT,
- Opcodes.NO_NEXT, Form52c.THE_ONE, true);
-
- public static final Dop IPUT_JUMBO =
- new Dop(Opcodes.IPUT_JUMBO, Opcodes.IPUT,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop IPUT_WIDE_JUMBO =
- new Dop(Opcodes.IPUT_WIDE_JUMBO, Opcodes.IPUT_WIDE,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop IPUT_OBJECT_JUMBO =
- new Dop(Opcodes.IPUT_OBJECT_JUMBO, Opcodes.IPUT_OBJECT,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop IPUT_BOOLEAN_JUMBO =
- new Dop(Opcodes.IPUT_BOOLEAN_JUMBO, Opcodes.IPUT_BOOLEAN,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop IPUT_BYTE_JUMBO =
- new Dop(Opcodes.IPUT_BYTE_JUMBO, Opcodes.IPUT_BYTE,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop IPUT_CHAR_JUMBO =
- new Dop(Opcodes.IPUT_CHAR_JUMBO, Opcodes.IPUT_CHAR,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop IPUT_SHORT_JUMBO =
- new Dop(Opcodes.IPUT_SHORT_JUMBO, Opcodes.IPUT_SHORT,
- Opcodes.NO_NEXT, Form52c.THE_ONE, false);
-
- public static final Dop SGET_JUMBO =
- new Dop(Opcodes.SGET_JUMBO, Opcodes.SGET,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SGET_WIDE_JUMBO =
- new Dop(Opcodes.SGET_WIDE_JUMBO, Opcodes.SGET_WIDE,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SGET_OBJECT_JUMBO =
- new Dop(Opcodes.SGET_OBJECT_JUMBO, Opcodes.SGET_OBJECT,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SGET_BOOLEAN_JUMBO =
- new Dop(Opcodes.SGET_BOOLEAN_JUMBO, Opcodes.SGET_BOOLEAN,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SGET_BYTE_JUMBO =
- new Dop(Opcodes.SGET_BYTE_JUMBO, Opcodes.SGET_BYTE,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SGET_CHAR_JUMBO =
- new Dop(Opcodes.SGET_CHAR_JUMBO, Opcodes.SGET_CHAR,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SGET_SHORT_JUMBO =
- new Dop(Opcodes.SGET_SHORT_JUMBO, Opcodes.SGET_SHORT,
- Opcodes.NO_NEXT, Form41c.THE_ONE, true);
-
- public static final Dop SPUT_JUMBO =
- new Dop(Opcodes.SPUT_JUMBO, Opcodes.SPUT,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop SPUT_WIDE_JUMBO =
- new Dop(Opcodes.SPUT_WIDE_JUMBO, Opcodes.SPUT_WIDE,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop SPUT_OBJECT_JUMBO =
- new Dop(Opcodes.SPUT_OBJECT_JUMBO, Opcodes.SPUT_OBJECT,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop SPUT_BOOLEAN_JUMBO =
- new Dop(Opcodes.SPUT_BOOLEAN_JUMBO, Opcodes.SPUT_BOOLEAN,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop SPUT_BYTE_JUMBO =
- new Dop(Opcodes.SPUT_BYTE_JUMBO, Opcodes.SPUT_BYTE,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop SPUT_CHAR_JUMBO =
- new Dop(Opcodes.SPUT_CHAR_JUMBO, Opcodes.SPUT_CHAR,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop SPUT_SHORT_JUMBO =
- new Dop(Opcodes.SPUT_SHORT_JUMBO, Opcodes.SPUT_SHORT,
- Opcodes.NO_NEXT, Form41c.THE_ONE, false);
-
- public static final Dop INVOKE_VIRTUAL_JUMBO =
- new Dop(Opcodes.INVOKE_VIRTUAL_JUMBO, Opcodes.INVOKE_VIRTUAL,
- Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
- public static final Dop INVOKE_SUPER_JUMBO =
- new Dop(Opcodes.INVOKE_SUPER_JUMBO, Opcodes.INVOKE_SUPER,
- Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
- public static final Dop INVOKE_DIRECT_JUMBO =
- new Dop(Opcodes.INVOKE_DIRECT_JUMBO, Opcodes.INVOKE_DIRECT,
- Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
- public static final Dop INVOKE_STATIC_JUMBO =
- new Dop(Opcodes.INVOKE_STATIC_JUMBO, Opcodes.INVOKE_STATIC,
- Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
- public static final Dop INVOKE_INTERFACE_JUMBO =
- new Dop(Opcodes.INVOKE_INTERFACE_JUMBO, Opcodes.INVOKE_INTERFACE,
- Opcodes.NO_NEXT, Form5rc.THE_ONE, false);
-
// END(dops)
// Static initialization.
@@ -1321,45 +1162,6 @@ public final class Dops {
set(SHL_INT_LIT8);
set(SHR_INT_LIT8);
set(USHR_INT_LIT8);
- set(CONST_CLASS_JUMBO);
- set(CHECK_CAST_JUMBO);
- set(INSTANCE_OF_JUMBO);
- set(NEW_INSTANCE_JUMBO);
- set(NEW_ARRAY_JUMBO);
- set(FILLED_NEW_ARRAY_JUMBO);
- set(IGET_JUMBO);
- set(IGET_WIDE_JUMBO);
- set(IGET_OBJECT_JUMBO);
- set(IGET_BOOLEAN_JUMBO);
- set(IGET_BYTE_JUMBO);
- set(IGET_CHAR_JUMBO);
- set(IGET_SHORT_JUMBO);
- set(IPUT_JUMBO);
- set(IPUT_WIDE_JUMBO);
- set(IPUT_OBJECT_JUMBO);
- set(IPUT_BOOLEAN_JUMBO);
- set(IPUT_BYTE_JUMBO);
- set(IPUT_CHAR_JUMBO);
- set(IPUT_SHORT_JUMBO);
- set(SGET_JUMBO);
- set(SGET_WIDE_JUMBO);
- set(SGET_OBJECT_JUMBO);
- set(SGET_BOOLEAN_JUMBO);
- set(SGET_BYTE_JUMBO);
- set(SGET_CHAR_JUMBO);
- set(SGET_SHORT_JUMBO);
- set(SPUT_JUMBO);
- set(SPUT_WIDE_JUMBO);
- set(SPUT_OBJECT_JUMBO);
- set(SPUT_BOOLEAN_JUMBO);
- set(SPUT_BYTE_JUMBO);
- set(SPUT_CHAR_JUMBO);
- set(SPUT_SHORT_JUMBO);
- set(INVOKE_VIRTUAL_JUMBO);
- set(INVOKE_SUPER_JUMBO);
- set(INVOKE_DIRECT_JUMBO);
- set(INVOKE_STATIC_JUMBO);
- set(INVOKE_INTERFACE_JUMBO);
// END(dops-init)
}
diff --git a/dx/src/com/android/dx/dex/code/InsnFormat.java b/dx/src/com/android/dx/dex/code/InsnFormat.java
index bf9f08e52..c866fecdc 100644
--- a/dx/src/com/android/dx/dex/code/InsnFormat.java
+++ b/dx/src/com/android/dx/dex/code/InsnFormat.java
@@ -507,9 +507,8 @@ public abstract class InsnFormat {
protected static short opcodeUnit(DalvInsn insn) {
int opcode = insn.getOpcode().getOpcode();
- if ((opcode < 0xff) || (opcode > 0xffff)) {
- throw new IllegalArgumentException(
- "extended opcode out of range 255..65535");
+ if ((opcode < 0x100) || (opcode > 0xffff)) {
+ throw new IllegalArgumentException("opcode out of range 0..65535");
}
return (short) opcode;
diff --git a/dx/src/com/android/dx/dex/code/form/Form32s.java b/dx/src/com/android/dx/dex/code/form/Form32s.java
deleted file mode 100644
index e08147056..000000000
--- a/dx/src/com/android/dx/dex/code/form/Form32s.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstLiteralBits;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 32s}. See the instruction format spec
- * for details.
- */
-public final class Form32s extends InsnFormat {
- /** {@code non-null;} unique instance of this class */
- public static final InsnFormat THE_ONE = new Form32s();
-
- /**
- * Constructs an instance. This class is not publicly
- * instantiable. Use {@link #THE_ONE}.
- */
- private Form32s() {
- // This space intentionally left blank.
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnArgString(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
-
- return regs.get(0).regString() + ", " + regs.get(1).regString()
- + ", " + literalBitsString(value);
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnCommentString(DalvInsn insn, boolean noteIndices) {
- CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
- return literalBitsComment(value, 16);
- }
-
- /** {@inheritDoc} */
- @Override
- public int codeSize() {
- return 3;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isCompatible(DalvInsn insn) {
- if (! ALLOW_EXTENDED_OPCODES) {
- return false;
- }
-
- RegisterSpecList regs = insn.getRegisters();
- if (!((insn instanceof CstInsn) &&
- (regs.size() == 2) &&
- unsignedFitsInByte(regs.get(0).getReg()) &&
- unsignedFitsInByte(regs.get(1).getReg()))) {
- return false;
- }
-
- CstInsn ci = (CstInsn) insn;
- Constant cst = ci.getConstant();
-
- if (!(cst instanceof CstLiteralBits)) {
- return false;
- }
-
- CstLiteralBits cb = (CstLiteralBits) cst;
-
- return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());
- }
-
- /** {@inheritDoc} */
- @Override
- public BitSet compatibleRegs(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- BitSet bits = new BitSet(2);
-
- bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
- bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));
- return bits;
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeTo(AnnotatedOutput out, DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- int value =
- ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
-
- write(out,
- opcodeUnit(insn),
- codeUnit(regs.get(0).getReg(), regs.get(1).getReg()),
- (short) value);
- }
-}
diff --git a/dx/src/com/android/dx/dex/code/form/Form33x.java b/dx/src/com/android/dx/dex/code/form/Form33x.java
deleted file mode 100644
index 9a569a000..000000000
--- a/dx/src/com/android/dx/dex/code/form/Form33x.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.dex.code.form;
-
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.dex.code.SimpleInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 33x}. See the instruction format spec
- * for details.
- */
-public final class Form33x extends InsnFormat {
- /** {@code non-null;} unique instance of this class */
- public static final InsnFormat THE_ONE = new Form33x();
-
- /**
- * Constructs an instance. This class is not publicly
- * instantiable. Use {@link #THE_ONE}.
- */
- private Form33x() {
- // This space intentionally left blank.
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnArgString(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- return regs.get(0).regString() + ", " + regs.get(1).regString() +
- ", " + regs.get(2).regString();
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnCommentString(DalvInsn insn, boolean noteIndices) {
- // This format has no comment.
- return "";
- }
-
- /** {@inheritDoc} */
- @Override
- public int codeSize() {
- return 3;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isCompatible(DalvInsn insn) {
- if (! ALLOW_EXTENDED_OPCODES) {
- return false;
- }
-
- RegisterSpecList regs = insn.getRegisters();
-
- return (insn instanceof SimpleInsn) &&
- (regs.size() == 3) &&
- unsignedFitsInByte(regs.get(0).getReg()) &&
- unsignedFitsInByte(regs.get(1).getReg()) &&
- unsignedFitsInShort(regs.get(2).getReg());
- }
-
- /** {@inheritDoc} */
- @Override
- public BitSet compatibleRegs(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- BitSet bits = new BitSet(3);
-
- bits.set(0, unsignedFitsInByte(regs.get(0).getReg()));
- bits.set(1, unsignedFitsInByte(regs.get(1).getReg()));
- bits.set(2, unsignedFitsInShort(regs.get(2).getReg()));
- return bits;
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeTo(AnnotatedOutput out, DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- write(out,
- opcodeUnit(insn),
- codeUnit(regs.get(0).getReg(), regs.get(1).getReg()),
- (short) regs.get(2).getReg());
- }
-}
diff --git a/dx/src/com/android/dx/dex/code/form/Form41c.java b/dx/src/com/android/dx/dex/code/form/Form41c.java
deleted file mode 100644
index 24067bce4..000000000
--- a/dx/src/com/android/dx/dex/code/form/Form41c.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpec;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 41c}. See the instruction format spec
- * for details.
- */
-public final class Form41c extends InsnFormat {
- /** {@code non-null;} unique instance of this class */
- public static final InsnFormat THE_ONE = new Form41c();
-
- /**
- * Constructs an instance. This class is not publicly
- * instantiable. Use {@link #THE_ONE}.
- */
- private Form41c() {
- // This space intentionally left blank.
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnArgString(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- return regs.get(0).regString() + ", " + cstString(insn);
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnCommentString(DalvInsn insn, boolean noteIndices) {
- if (noteIndices) {
- return cstComment(insn);
- } else {
- return "";
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public int codeSize() {
- return 4;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isCompatible(DalvInsn insn) {
- if (! ALLOW_EXTENDED_OPCODES) {
- return false;
- }
-
- if (!(insn instanceof CstInsn)) {
- return false;
- }
-
- RegisterSpecList regs = insn.getRegisters();
- RegisterSpec reg;
-
- switch (regs.size()) {
- case 1: {
- reg = regs.get(0);
- break;
- }
- case 2: {
- /*
- * This format is allowed for ops that are effectively
- * 2-arg but where the two args are identical.
- */
- reg = regs.get(0);
- if (reg.getReg() != regs.get(1).getReg()) {
- return false;
- }
- break;
- }
- default: {
- return false;
- }
- }
-
- if (!unsignedFitsInShort(reg.getReg())) {
- return false;
- }
-
- CstInsn ci = (CstInsn) insn;
- Constant cst = ci.getConstant();
-
- return (cst instanceof CstType) ||
- (cst instanceof CstFieldRef);
- }
-
- /** {@inheritDoc} */
- @Override
- public BitSet compatibleRegs(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- int sz = regs.size();
- BitSet bits = new BitSet(sz);
- boolean compat = unsignedFitsInByte(regs.get(0).getReg());
-
- if (sz == 1) {
- bits.set(0, compat);
- } else {
- if (regs.get(0).getReg() == regs.get(1).getReg()) {
- bits.set(0, compat);
- bits.set(1, compat);
- }
- }
-
- return bits;
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeTo(AnnotatedOutput out, DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- int cpi = ((CstInsn) insn).getIndex();
-
- write(out, opcodeUnit(insn), cpi, (short) regs.get(0).getReg());
- }
-}
diff --git a/dx/src/com/android/dx/dex/code/form/Form52c.java b/dx/src/com/android/dx/dex/code/form/Form52c.java
deleted file mode 100644
index acd2124d6..000000000
--- a/dx/src/com/android/dx/dex/code/form/Form52c.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-import java.util.BitSet;
-
-/**
- * Instruction format {@code 52c}. See the instruction format spec
- * for details.
- */
-public final class Form52c extends InsnFormat {
- /** {@code non-null;} unique instance of this class */
- public static final InsnFormat THE_ONE = new Form52c();
-
- /**
- * Constructs an instance. This class is not publicly
- * instantiable. Use {@link #THE_ONE}.
- */
- private Form52c() {
- // This space intentionally left blank.
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnArgString(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- return regs.get(0).regString() + ", " + regs.get(1).regString() +
- ", " + cstString(insn);
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnCommentString(DalvInsn insn, boolean noteIndices) {
- if (noteIndices) {
- return cstComment(insn);
- } else {
- return "";
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public int codeSize() {
- return 5;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isCompatible(DalvInsn insn) {
- if (! ALLOW_EXTENDED_OPCODES) {
- return false;
- }
-
- RegisterSpecList regs = insn.getRegisters();
- if (!((insn instanceof CstInsn) &&
- (regs.size() == 2) &&
- unsignedFitsInShort(regs.get(0).getReg()) &&
- unsignedFitsInShort(regs.get(1).getReg()))) {
- return false;
- }
-
- CstInsn ci = (CstInsn) insn;
- Constant cst = ci.getConstant();
-
- return (cst instanceof CstType) ||
- (cst instanceof CstFieldRef);
- }
-
- /** {@inheritDoc} */
- @Override
- public BitSet compatibleRegs(DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- BitSet bits = new BitSet(2);
-
- bits.set(0, unsignedFitsInShort(regs.get(0).getReg()));
- bits.set(1, unsignedFitsInShort(regs.get(1).getReg()));
- return bits;
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeTo(AnnotatedOutput out, DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- int cpi = ((CstInsn) insn).getIndex();
-
- write(out,
- opcodeUnit(insn),
- cpi,
- (short) regs.get(0).getReg(),
- (short) regs.get(1).getReg());
- }
-}
diff --git a/dx/src/com/android/dx/dex/code/form/Form5rc.java b/dx/src/com/android/dx/dex/code/form/Form5rc.java
deleted file mode 100644
index 0c5470252..000000000
--- a/dx/src/com/android/dx/dex/code/form/Form5rc.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.dex.code.form;
-
-import com.android.dx.dex.code.CstInsn;
-import com.android.dx.dex.code.DalvInsn;
-import com.android.dx.dex.code.InsnFormat;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.util.AnnotatedOutput;
-
-/**
- * Instruction format {@code 5rc}. See the instruction format spec
- * for details.
- */
-public final class Form5rc extends InsnFormat {
- /** {@code non-null;} unique instance of this class */
- public static final InsnFormat THE_ONE = new Form5rc();
-
- /**
- * Constructs an instance. This class is not publicly
- * instantiable. Use {@link #THE_ONE}.
- */
- private Form5rc() {
- // This space intentionally left blank.
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnArgString(DalvInsn insn) {
- return regRangeString(insn.getRegisters()) + ", " +
- cstString(insn);
- }
-
- /** {@inheritDoc} */
- @Override
- public String insnCommentString(DalvInsn insn, boolean noteIndices) {
- if (noteIndices) {
- return cstComment(insn);
- } else {
- return "";
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public int codeSize() {
- return 5;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isCompatible(DalvInsn insn) {
- if (! ALLOW_EXTENDED_OPCODES) {
- return false;
- }
-
- if (!(insn instanceof CstInsn)) {
- return false;
- }
-
- CstInsn ci = (CstInsn) insn;
- Constant cst = ci.getConstant();
-
- if (!((cst instanceof CstMethodRef) ||
- (cst instanceof CstType))) {
- return false;
- }
-
- RegisterSpecList regs = ci.getRegisters();
- int sz = regs.size();
-
- return (regs.size() == 0) ||
- (isRegListSequential(regs) &&
- unsignedFitsInShort(regs.get(0).getReg()) &&
- unsignedFitsInShort(regs.getWordCount()));
- }
-
- /** {@inheritDoc} */
- @Override
- public void writeTo(AnnotatedOutput out, DalvInsn insn) {
- RegisterSpecList regs = insn.getRegisters();
- int cpi = ((CstInsn) insn).getIndex();
- int firstReg = (regs.size() == 0) ? 0 : regs.get(0).getReg();
- int count = regs.getWordCount();
-
- write(out, opcodeUnit(insn), cpi, (short) count, (short) firstReg);
- }
-}
diff --git a/dx/src/com/android/dx/dex/file/MemberIdsSection.java b/dx/src/com/android/dx/dex/file/MemberIdsSection.java
index ef0d8cd92..ee844d9de 100644
--- a/dx/src/com/android/dx/dex/file/MemberIdsSection.java
+++ b/dx/src/com/android/dx/dex/file/MemberIdsSection.java
@@ -16,10 +16,19 @@
package com.android.dx.dex.file;
+import com.android.dx.util.DexException;
+import java.util.Formatter;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* Member (field or method) refs list section of a {@code .dex} file.
*/
public abstract class MemberIdsSection extends UniformItemSection {
+ /** The largest addressable member is 0xffff, in the dex spec as field@CCCC or meth@CCCC. */
+ private static final int MAX_MEMBERS = 0x10000;
+
/**
* Constructs an instance. The file offset is initially unknown.
*
@@ -36,9 +45,35 @@ public abstract class MemberIdsSection extends UniformItemSection {
protected void orderItems() {
int idx = 0;
+ if (items().size() > MAX_MEMBERS) {
+ throw new DexException(tooManyMembersMessage());
+ }
+
for (Object i : items()) {
((MemberIdItem) i).setIndex(idx);
idx++;
}
}
+
+ private String tooManyMembersMessage() {
+ Map<String, AtomicInteger> membersByPackage = new TreeMap<String, AtomicInteger>();
+ for (Object member : items()) {
+ String packageName = ((MemberIdItem) member).getDefiningClass().getPackageName();
+ AtomicInteger count = membersByPackage.get(packageName);
+ if (count == null) {
+ count = new AtomicInteger();
+ membersByPackage.put(packageName, count);
+ }
+ count.incrementAndGet();
+ }
+
+ Formatter formatter = new Formatter();
+ String memberType = this instanceof MethodIdsSection ? "methods" : "fields";
+ formatter.format("Too many %s: %d; max is %d. By package:",
+ memberType, items().size(), MAX_MEMBERS);
+ for (Map.Entry<String, AtomicInteger> entry : membersByPackage.entrySet()) {
+ formatter.format("%n%6d %s", entry.getValue().get(), entry.getKey());
+ }
+ return formatter.toString();
+ }
}
diff --git a/dx/src/com/android/dx/gen/BinaryOp.java b/dx/src/com/android/dx/gen/BinaryOp.java
deleted file mode 100644
index 65a29983a..000000000
--- a/dx/src/com/android/dx/gen/BinaryOp.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * An operation on two values of the same type.
- *
- * <p>Math operations ({@link #ADD}, {@link #SUBTRACT}, {@link #MULTIPLY},
- * {@link #DIVIDE}, and {@link #REMAINDER}) support ints, longs, floats and
- * doubles.
- *
- * <p>Bit operations ({@link #AND}, {@link #OR}, {@link #XOR}, {@link
- * #SHIFT_LEFT}, {@link #SHIFT_RIGHT}, {@link #UNSIGNED_SHIFT_RIGHT}) support
- * ints and longs.
- *
- * <p>Division by zero behaves differently depending on the operand type.
- * For int and long operands, {@link #DIVIDE} and {@link #REMAINDER} throw
- * {@link ArithmeticException} if {@code b == 0}. For float and double operands,
- * the operations return {@code NaN}.
- */
-public enum BinaryOp {
- /** {@code a + b} */
- ADD() {
- @Override Rop rop(TypeList types) {
- return Rops.opAdd(types);
- }
- },
-
- /** {@code a - b} */
- SUBTRACT() {
- @Override Rop rop(TypeList types) {
- return Rops.opSub(types);
- }
- },
-
- /** {@code a * b} */
- MULTIPLY() {
- @Override Rop rop(TypeList types) {
- return Rops.opMul(types);
- }
- },
-
- /** {@code a / b} */
- DIVIDE() {
- @Override Rop rop(TypeList types) {
- return Rops.opDiv(types);
- }
- },
-
- /** {@code a % b} */
- REMAINDER() {
- @Override Rop rop(TypeList types) {
- return Rops.opRem(types);
- }
- },
-
- /** {@code a & b} */
- AND() {
- @Override Rop rop(TypeList types) {
- return Rops.opAnd(types);
- }
- },
-
- /** {@code a | b} */
- OR() {
- @Override Rop rop(TypeList types) {
- return Rops.opOr(types);
- }
- },
-
- /** {@code a ^ b} */
- XOR() {
- @Override Rop rop(TypeList types) {
- return Rops.opXor(types);
- }
- },
-
- /** {@code a << b} */
- SHIFT_LEFT() {
- @Override Rop rop(TypeList types) {
- return Rops.opShl(types);
- }
- },
-
- /** {@code a >> b} */
- SHIFT_RIGHT() {
- @Override Rop rop(TypeList types) {
- return Rops.opShr(types);
- }
- },
-
- /** {@code a >>> b} */
- UNSIGNED_SHIFT_RIGHT() {
- @Override Rop rop(TypeList types) {
- return Rops.opUshr(types);
- }
- };
-
- abstract Rop rop(com.android.dx.rop.type.TypeList types);
-}
diff --git a/dx/src/com/android/dx/gen/Code.java b/dx/src/com/android/dx/gen/Code.java
deleted file mode 100644
index b44d01cdd..000000000
--- a/dx/src/com/android/dx/gen/Code.java
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.BasicBlockList;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.PlainCstInsn;
-import com.android.dx.rop.code.PlainInsn;
-import com.android.dx.rop.code.RegisterSpecList;
-import com.android.dx.rop.code.Rop;
-import static com.android.dx.rop.code.Rop.BRANCH_GOTO;
-import static com.android.dx.rop.code.Rop.BRANCH_NONE;
-import static com.android.dx.rop.code.Rop.BRANCH_RETURN;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.code.SourcePosition;
-import com.android.dx.rop.code.ThrowingCstInsn;
-import com.android.dx.rop.code.ThrowingInsn;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.type.StdTypeList;
-import static com.android.dx.rop.type.Type.BT_BYTE;
-import static com.android.dx.rop.type.Type.BT_CHAR;
-import static com.android.dx.rop.type.Type.BT_INT;
-import static com.android.dx.rop.type.Type.BT_SHORT;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Builds a sequence of instructions.
- */
-public final class Code {
- private final MethodId<?, ?> method;
- /**
- * All allocated labels. Although the order of the labels in this list
- * shouldn't impact behavior, it is used to determine basic block indices.
- */
- private final List<Label> labels = new ArrayList<Label>();
-
- /**
- * The label currently receiving instructions. This is null if the most
- * recent instruction was a return or goto.
- */
- private Label currentLabel;
-
- /** true once we've fixed the positions of the parameter registers */
- private boolean localsInitialized;
-
- private final Local<?> thisLocal;
- private final List<Local<?>> parameters = new ArrayList<Local<?>>();
- private final List<Local<?>> locals = new ArrayList<Local<?>>();
- private SourcePosition sourcePosition = SourcePosition.NO_INFO;
- private final List<Type<?>> catchTypes = new ArrayList<Type<?>>();
- private final List<Label> catchLabels = new ArrayList<Label>();
- private StdTypeList catches = StdTypeList.EMPTY;
-
- Code(DexGenerator.MethodDeclaration methodDeclaration) {
- this.method = methodDeclaration.method;
- this.thisLocal = methodDeclaration.isStatic()
- ? null
- : Local.get(this, method.declaringType);
- for (Type<?> parameter : method.parameters.types) {
- parameters.add(Local.get(this, parameter));
- }
- this.currentLabel = newLabel();
- this.currentLabel.marked = true;
- }
-
- public <T> Local<T> newLocal(Type<T> type) {
- if (localsInitialized) {
- throw new IllegalStateException("Cannot allocate locals after adding instructions");
- }
- Local<T> result = Local.get(this, type);
- locals.add(result);
- return result;
- }
-
- public <T> Local<T> getParameter(int index, Type<T> type) {
- return coerce(parameters.get(index), type);
- }
-
- public <T> Local<T> getThis(Type<T> type) {
- if (thisLocal == null) {
- throw new IllegalStateException("static methods cannot access 'this'");
- }
- return coerce(thisLocal, type);
- }
-
- @SuppressWarnings("unchecked") // guarded by an equals check
- private <T> Local<T> coerce(Local<?> local, Type<T> expectedType) {
- if (!local.type.equals(expectedType)) {
- throw new IllegalArgumentException(
- "requested " + expectedType + " but was " + local.type);
- }
- return (Local<T>) local;
- }
-
- /**
- * Assigns registers to locals. From the spec:
- * "the N arguments to a method land in the last N registers of the
- * method's invocation frame, in order. Wide arguments consume two
- * registers. Instance methods are passed a this reference as their
- * first argument."
- *
- * In addition to assigning registers to each of the locals, this creates
- * instructions to move parameters into their initial registers. These
- * instructions are inserted before the code's first real instruction.
- */
- void initializeLocals() {
- if (localsInitialized) {
- throw new AssertionError();
- }
- localsInitialized = true;
-
- int reg = 0;
- for (Local<?> local : locals) {
- reg += local.initialize(reg);
- }
- if (thisLocal != null) {
- reg += thisLocal.initialize(reg);
- }
- int firstParamReg = reg;
-
- List<Insn> moveParameterInstructions = new ArrayList<Insn>();
- for (Local<?> local : parameters) {
- CstInteger paramConstant = CstInteger.make(reg - firstParamReg);
- reg += local.initialize(reg);
- moveParameterInstructions.add(new PlainCstInsn(Rops.opMoveParam(local.type.ropType),
- sourcePosition, local.spec(), RegisterSpecList.EMPTY, paramConstant));
- }
- labels.get(0).instructions.addAll(0, moveParameterInstructions);
- }
-
- int paramSize() {
- int result = 0;
- for (Local<?> local : parameters) {
- result += local.size();
- }
- return result;
- }
-
- // labels
-
- /**
- * Creates a new label for use as a branch target. The new label must have
- * code attached to it later by calling {@link #mark(Label)}.
- */
- public Label newLabel() {
- Label result = new Label();
- labels.add(result);
- return result;
- }
-
- /**
- * Start defining instructions for the named label.
- */
- public void mark(Label label) {
- if (label.marked) {
- throw new IllegalStateException("already marked");
- }
- label.marked = true;
- if (currentLabel != null) {
- jump(label); // blocks must end with a branch, return or throw
- }
- currentLabel = label;
- }
-
- public void jump(Label target) {
- addInstruction(new PlainInsn(Rops.GOTO, sourcePosition, null, RegisterSpecList.EMPTY),
- target);
- }
-
- public void addCatchClause(Type<?> throwable, Label catchClause) {
- if (catchTypes.contains(throwable)) {
- throw new IllegalArgumentException("Already caught: " + throwable);
- }
- catchTypes.add(throwable);
- catches = toTypeList(catchTypes);
- catchLabels.add(catchClause);
- }
-
- public Label removeCatchClause(Type<?> throwable) {
- int index = catchTypes.indexOf(throwable);
- if (index == -1) {
- throw new IllegalArgumentException("No catch clause: " + throwable);
- }
- catchTypes.remove(index);
- catches = toTypeList(catchTypes);
- return catchLabels.remove(index);
- }
-
- public void throwValue(Local<?> throwable) {
- addInstruction(new ThrowingInsn(Rops.THROW, sourcePosition,
- RegisterSpecList.make(throwable.spec()), catches));
- }
-
- private StdTypeList toTypeList(List<Type<?>> types) {
- StdTypeList result = new StdTypeList(types.size());
- for (int i = 0; i < types.size(); i++) {
- result.set(i, types.get(i).ropType);
- }
- return result;
- }
-
- private void addInstruction(Insn insn) {
- addInstruction(insn, null);
- }
-
- /**
- * @param branch the branches to follow; interpretation depends on the
- * instruction's branchingness.
- */
- private void addInstruction(Insn insn, Label branch) {
- if (currentLabel == null || !currentLabel.marked) {
- throw new IllegalStateException("no current label");
- }
- currentLabel.instructions.add(insn);
-
- switch (insn.getOpcode().getBranchingness()) {
- case BRANCH_NONE:
- if (branch != null) {
- throw new IllegalArgumentException("unexpected branch: " + branch);
- }
- return;
-
- case BRANCH_RETURN:
- if (branch != null) {
- throw new IllegalArgumentException("unexpected branch: " + branch);
- }
- currentLabel = null;
- break;
-
- case BRANCH_GOTO:
- if (branch == null) {
- throw new IllegalArgumentException("branch == null");
- }
- currentLabel.primarySuccessor = branch;
- currentLabel = null;
- break;
-
- case Rop.BRANCH_IF:
- if (branch == null) {
- throw new IllegalArgumentException("branch == null");
- }
- splitCurrentLabel(branch, Collections.<Label>emptyList());
- break;
-
- case Rop.BRANCH_THROW:
- if (branch != null) {
- throw new IllegalArgumentException("unexpected branch: " + branch);
- }
- splitCurrentLabel(null, new ArrayList<Label>(catchLabels));
- break;
-
- default:
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * Closes the current label and starts a new one.
- *
- * @param catchLabels an immutable list of catch labels
- */
- private void splitCurrentLabel(Label alternateSuccessor, List<Label> catchLabels) {
- Label newLabel = newLabel();
- currentLabel.primarySuccessor = newLabel;
- currentLabel.alternateSuccessor = alternateSuccessor;
- currentLabel.catchLabels = catchLabels;
- currentLabel = newLabel;
- currentLabel.marked = true;
- }
-
- // instructions: constants
-
- public <T> void loadConstant(Local<T> target, T value) {
- Rop rop = Rops.opConst(target.type.ropType);
- if (rop.getBranchingness() == BRANCH_NONE) {
- addInstruction(new PlainCstInsn(rop, sourcePosition, target.spec(),
- RegisterSpecList.EMPTY, Constants.getConstant(value)));
- } else {
- addInstruction(new ThrowingCstInsn(rop, sourcePosition,
- RegisterSpecList.EMPTY, catches, Constants.getConstant(value)));
- moveResult(target, true);
- }
- }
-
- // instructions: unary
-
- public <T> void negate(Local<T> source, Local<T> target) {
- unary(Rops.opNeg(source.type.ropType), source, target);
- }
-
- public <T> void not(Local<T> source, Local<T> target) {
- unary(Rops.opNot(source.type.ropType), source, target);
- }
-
- public void numericCast(Local<?> source, Local<?> target) {
- unary(getCastRop(source.type.ropType, target.type.ropType), source, target);
- }
-
- private Rop getCastRop(com.android.dx.rop.type.Type sourceType,
- com.android.dx.rop.type.Type targetType) {
- if (sourceType.getBasicType() == BT_INT) {
- switch (targetType.getBasicType()) {
- case BT_SHORT:
- return Rops.TO_SHORT;
- case BT_CHAR:
- return Rops.TO_CHAR;
- case BT_BYTE:
- return Rops.TO_BYTE;
- }
- }
- return Rops.opConv(targetType, sourceType);
- }
-
- private void unary(Rop rop, Local<?> source, Local<?> target) {
- addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), source.spec()));
- }
-
- // instructions: binary
-
- public <T> void op(BinaryOp op, Local<T> target, Local<T> a, Local<T> b) {
- Rop rop = op.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
- RegisterSpecList sources = RegisterSpecList.make(a.spec(), b.spec());
-
- if (rop.getBranchingness() == BRANCH_NONE) {
- addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), sources));
- } else {
- addInstruction(new ThrowingInsn(rop, sourcePosition, sources, catches));
- moveResult(target, true);
- }
- }
-
- // instructions: branches
-
- /**
- * Compare ints. If the comparison is true, execution jumps to {@code
- * trueLabel}. If it is false, execution continues to the next instruction.
- */
- public <T> void compare(Comparison comparison, Local<T> a, Local<T> b, Label trueLabel) {
- if (trueLabel == null) {
- throw new IllegalArgumentException();
- }
- Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
- addInstruction(new PlainInsn(rop, sourcePosition, null,
- RegisterSpecList.make(a.spec(), b.spec())), trueLabel);
- }
-
- /**
- * Compare floats or doubles.
- */
- public <T extends Number> void compare(Local<T> a, Local<T> b, Local<Integer> target,
- int nanValue) {
- Rop rop;
- if (nanValue == 1) {
- rop = Rops.opCmpg(a.type.ropType);
- } else if (nanValue == -1) {
- rop = Rops.opCmpl(a.type.ropType);
- } else {
- throw new IllegalArgumentException("expected 1 or -1 but was " + nanValue);
- }
- addInstruction(new PlainInsn(rop, sourcePosition, target.spec(),
- RegisterSpecList.make(a.spec(), b.spec())));
- }
-
- /**
- * Compare longs.
- */
- public <T> void compare(Local<T> a, Local<T> b, Local<?> target) {
- addInstruction(new PlainInsn(Rops.CMPL_LONG, sourcePosition, target.spec(),
- RegisterSpecList.make(a.spec(), b.spec())));
- }
-
- // instructions: fields
-
- public <D, V> void iget(FieldId<D, V> fieldId, Local<D> instance, Local<V> target) {
- addInstruction(new ThrowingCstInsn(Rops.opGetField(target.type.ropType), sourcePosition,
- RegisterSpecList.make(instance.spec()), catches, fieldId.constant));
- moveResult(target, true);
- }
-
- public <D, V> void iput(FieldId<D, V> fieldId, Local<D> instance, Local<V> source) {
- addInstruction(new ThrowingCstInsn(Rops.opPutField(source.type.ropType), sourcePosition,
- RegisterSpecList.make(source.spec(), instance.spec()), catches, fieldId.constant));
- }
-
- public <V> void sget(FieldId<?, V> fieldId, Local<V> target) {
- addInstruction(new ThrowingCstInsn(Rops.opGetStatic(target.type.ropType), sourcePosition,
- RegisterSpecList.EMPTY, catches, fieldId.constant));
- moveResult(target, true);
- }
-
- public <V> void sput(FieldId<?, V> fieldId, Local<V> source) {
- addInstruction(new ThrowingCstInsn(Rops.opPutStatic(source.type.ropType), sourcePosition,
- RegisterSpecList.make(source.spec()), catches, fieldId.constant));
- }
-
- // instructions: invoke
-
- public <T> void newInstance(Local<T> target, MethodId<T, Void> constructor, Local<?>... args) {
- if (target == null) {
- throw new IllegalArgumentException();
- }
- addInstruction(new ThrowingCstInsn(Rops.NEW_INSTANCE, sourcePosition,
- RegisterSpecList.EMPTY, catches, constructor.declaringType.constant));
- moveResult(target, true);
- invokeDirect(constructor, null, target, args);
- }
-
- public <R> void invokeStatic(MethodId<?, R> method, Local<? super R> target, Local<?>... args) {
- invoke(Rops.opInvokeStatic(method.prototype(true)), method, target, null, args);
- }
-
- public <D, R> void invokeVirtual(MethodId<D, R> method, Local<? super R> target,
- Local<? extends D> object, Local<?>... args) {
- invoke(Rops.opInvokeVirtual(method.prototype(true)), method, target, object, args);
- }
-
- public <D, R> void invokeDirect(MethodId<D, R> method, Local<? super R> target,
- Local<? extends D> object, Local<?>... args) {
- invoke(Rops.opInvokeDirect(method.prototype(true)), method, target, object, args);
- }
-
- public <D, R> void invokeSuper(MethodId<D, R> method, Local<? super R> target,
- Local<? extends D> object, Local<?>... args) {
- invoke(Rops.opInvokeSuper(method.prototype(true)), method, target, object, args);
- }
-
- public <D, R> void invokeInterface(MethodId<D, R> method, Local<? super R> target,
- Local<? extends D> object, Local<?>... args) {
- invoke(Rops.opInvokeInterface(method.prototype(true)), method, target, object, args);
- }
-
- private <D, R> void invoke(Rop rop, MethodId<D, R> method, Local<? super R> target,
- Local<? extends D> object, Local<?>... args) {
- addInstruction(new ThrowingCstInsn(rop, sourcePosition, concatenate(object, args),
- catches, method.constant));
- if (target != null) {
- moveResult(target, false);
- }
- }
-
- // instructions: types
-
- public void instanceOfType(Local<?> target, Local<?> source, Type<?> type) {
- addInstruction(new ThrowingCstInsn(Rops.INSTANCE_OF, sourcePosition,
- RegisterSpecList.make(source.spec()), catches, type.constant));
- moveResult(target, true);
- }
-
- public void typeCast(Local<?> source, Local<?> target) {
- addInstruction(new ThrowingCstInsn(Rops.CHECK_CAST, sourcePosition,
- RegisterSpecList.make(source.spec()), catches, target.type.constant));
- moveResult(target, true);
- }
-
- // instructions: arrays
-
- public <T> void arrayLength(Local<T> array, Local<Integer> target) {
- addInstruction(new ThrowingInsn(Rops.ARRAY_LENGTH, sourcePosition,
- RegisterSpecList.make(array.spec()), catches));
- moveResult(target, true);
- }
-
- public <T> void newArray(Local<Integer> length, Local<T> target) {
- addInstruction(new ThrowingCstInsn(Rops.opNewArray(target.type.ropType), sourcePosition,
- RegisterSpecList.make(length.spec()), catches, target.type.constant));
- moveResult(target, true);
- }
-
- public void aget(Local<?> array, Local<Integer> index, Local<?> target) {
- addInstruction(new ThrowingInsn(Rops.opAget(target.type.ropType), sourcePosition,
- RegisterSpecList.make(array.spec(), index.spec()), catches));
- moveResult(target, true);
- }
-
- public void aput(Local<?> array, Local<Integer> index, Local<?> source) {
- addInstruction(new ThrowingInsn(Rops.opAput(source.type.ropType), sourcePosition,
- RegisterSpecList.make(source.spec(), array.spec(), index.spec()), catches));
- }
-
- // instructions: return
-
- public void returnVoid() {
- if (!method.returnType.equals(Type.VOID)) {
- throw new IllegalArgumentException("declared " + method.returnType
- + " but returned void");
- }
- addInstruction(new PlainInsn(Rops.RETURN_VOID, sourcePosition, null,
- RegisterSpecList.EMPTY));
- }
-
- public void returnValue(Local<?> result) {
- if (!result.type.equals(method.returnType)) {
- // TODO: this is probably too strict.
- throw new IllegalArgumentException("declared " + method.returnType
- + " but returned " + result.type);
- }
- addInstruction(new PlainInsn(Rops.opReturn(result.type.ropType), sourcePosition,
- null, RegisterSpecList.make(result.spec())));
- }
-
- private void moveResult(Local<?> target, boolean afterNonInvokeThrowingInsn) {
- Rop rop = afterNonInvokeThrowingInsn
- ? Rops.opMoveResultPseudo(target.type.ropType)
- : Rops.opMoveResult(target.type.ropType);
- addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), RegisterSpecList.EMPTY));
- }
-
- // produce BasicBlocks for dex
-
- BasicBlockList toBasicBlocks() {
- if (!localsInitialized) {
- initializeLocals();
- }
-
- cleanUpLabels();
-
- BasicBlockList result = new BasicBlockList(labels.size());
- for (int i = 0; i < labels.size(); i++) {
- result.set(i, labels.get(i).toBasicBlock());
- }
- return result;
- }
-
- /**
- * Removes empty labels and assigns IDs to non-empty labels.
- */
- private void cleanUpLabels() {
- int id = 0;
- for (Iterator<Label> i = labels.iterator(); i.hasNext();) {
- Label label = i.next();
- if (label.isEmpty()) {
- i.remove();
- } else {
- label.compact();
- label.id = id++;
- }
- }
- }
-
- private static RegisterSpecList concatenate(Local<?> first, Local<?>[] rest) {
- int offset = (first != null) ? 1 : 0;
- RegisterSpecList result = new RegisterSpecList(offset + rest.length);
- if (first != null) {
- result.set(0, first.spec());
- }
- for (int i = 0; i < rest.length; i++) {
- result.set(i + offset, rest[i].spec());
- }
- return result;
- }
-}
diff --git a/dx/src/com/android/dx/gen/Comparison.java b/dx/src/com/android/dx/gen/Comparison.java
deleted file mode 100644
index 40a6e9724..000000000
--- a/dx/src/com/android/dx/gen/Comparison.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.Rop;
-import com.android.dx.rop.code.Rops;
-import com.android.dx.rop.type.TypeList;
-
-/**
- * A comparison between two values of the same type.
- */
-public enum Comparison {
-
- /** {@code a < b} */
- LT() {
- @Override Rop rop(TypeList types) {
- return Rops.opIfLt(types);
- }
- },
-
- /** {@code a <= b} */
- LE() {
- @Override Rop rop(TypeList types) {
- return Rops.opIfLe(types);
- }
- },
-
- /** {@code a == b} */
- EQ() {
- @Override Rop rop(TypeList types) {
- return Rops.opIfEq(types);
- }
- },
-
- /** {@code a >= b} */
- GE() {
- @Override Rop rop(TypeList types) {
- return Rops.opIfGe(types);
- }
- },
-
- /** {@code a > b} */
- GT() {
- @Override Rop rop(TypeList types) {
- return Rops.opIfGt(types);
- }
- },
-
- /** {@code a != b} */
- NE() {
- @Override Rop rop(TypeList types) {
- return Rops.opIfNe(types);
- }
- };
-
- abstract Rop rop(TypeList types);
-}
diff --git a/dx/src/com/android/dx/gen/Constants.java b/dx/src/com/android/dx/gen/Constants.java
deleted file mode 100644
index 255c2e4ce..000000000
--- a/dx/src/com/android/dx/gen/Constants.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstBoolean;
-import com.android.dx.rop.cst.CstByte;
-import com.android.dx.rop.cst.CstChar;
-import com.android.dx.rop.cst.CstDouble;
-import com.android.dx.rop.cst.CstFloat;
-import com.android.dx.rop.cst.CstInteger;
-import com.android.dx.rop.cst.CstKnownNull;
-import com.android.dx.rop.cst.CstLong;
-import com.android.dx.rop.cst.CstShort;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.cst.TypedConstant;
-
-/**
- * Factory for rop constants.
- */
-final class Constants {
- private Constants() {}
-
- /**
- * Returns a rop constant for the specified value.
- *
- * @param value null, a boxed primitive, String, Class, or Type.
- */
- static TypedConstant getConstant(Object value) {
- if (value == null) {
- return CstKnownNull.THE_ONE;
- } else if (value instanceof Boolean) {
- return CstBoolean.make((Boolean) value);
- } else if (value instanceof Byte) {
- return CstByte.make((Byte) value);
- } else if (value instanceof Character) {
- return CstChar.make((Character) value);
- } else if (value instanceof Double) {
- return CstDouble.make(Double.doubleToLongBits((Double) value));
- } else if (value instanceof Float) {
- return CstFloat.make(Float.floatToIntBits((Float) value));
- } else if (value instanceof Integer) {
- return CstInteger.make((Integer) value);
- } else if (value instanceof Long) {
- return CstLong.make((Long) value);
- } else if (value instanceof Short) {
- return CstShort.make((Short) value);
- } else if (value instanceof String) {
- return new CstString((String) value);
- } else if (value instanceof Class) {
- return new CstType(Type.get((Class<?>) value).ropType);
- } else if (value instanceof Type) {
- return new CstType(((Type) value).ropType);
- } else {
- throw new UnsupportedOperationException("Not a constant: " + value);
- }
- }
-}
diff --git a/dx/src/com/android/dx/gen/DexGenerator.java b/dx/src/com/android/dx/gen/DexGenerator.java
deleted file mode 100644
index 7cde9a93f..000000000
--- a/dx/src/com/android/dx/gen/DexGenerator.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.dex.DexFormat;
-import com.android.dx.dex.DexOptions;
-import com.android.dx.dex.code.DalvCode;
-import com.android.dx.dex.code.PositionList;
-import com.android.dx.dex.code.RopTranslator;
-import com.android.dx.dex.file.ClassDefItem;
-import com.android.dx.dex.file.DexFile;
-import com.android.dx.dex.file.EncodedField;
-import com.android.dx.dex.file.EncodedMethod;
-import com.android.dx.rop.code.AccessFlags;
-import static com.android.dx.rop.code.AccessFlags.*;
-import com.android.dx.rop.code.LocalVariableInfo;
-import com.android.dx.rop.code.RopMethod;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.cst.CstType;
-import com.android.dx.rop.type.StdTypeList;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-
-/**
- * Define types, fields and methods.
- */
-public final class DexGenerator {
- private final Map<Type<?>, TypeDeclaration> types
- = new LinkedHashMap<Type<?>, TypeDeclaration>();
-
- private TypeDeclaration getTypeDeclaration(Type<?> type) {
- TypeDeclaration result = types.get(type);
- if (result == null) {
- result = new TypeDeclaration(type);
- types.put(type, result);
- }
- return result;
- }
-
- /**
- * @param flags any flags masked by {@link com.android.dx.rop.code.AccessFlags#CLASS_FLAGS}.
- */
- public void declare(Type<?> type, String sourceFile, int flags,
- Type<?> supertype, Type<?>... interfaces) {
- TypeDeclaration declaration = getTypeDeclaration(type);
- if (declaration.declared) {
- throw new IllegalStateException("already declared: " + type);
- }
- declaration.declared = true;
- declaration.flags = flags;
- declaration.supertype = supertype;
- declaration.sourceFile = sourceFile;
- declaration.interfaces = new TypeList(interfaces);
- }
-
- /**
- * @param flags any flags masked by {@link com.android.dx.rop.code.AccessFlags#METHOD_FLAGS}.
- */
- public Code declare(MethodId<?, ?> method, int flags) {
- TypeDeclaration typeDeclaration = getTypeDeclaration(method.declaringType);
- if (typeDeclaration.methods.containsKey(method)) {
- throw new IllegalStateException("already declared: " + method);
- }
- MethodDeclaration methodDeclaration = new MethodDeclaration(method, flags);
- typeDeclaration.methods.put(method, methodDeclaration);
- return methodDeclaration.code;
- }
-
- /**
- * @param flags any flags masked by {@link AccessFlags#FIELD_FLAGS}.
- */
- public void declare(FieldId<?, ?> fieldId, int flags, Object staticValue) {
- TypeDeclaration typeDeclaration = getTypeDeclaration(fieldId.declaringType);
- if (typeDeclaration.fields.containsKey(fieldId)) {
- throw new IllegalStateException("already declared: " + fieldId);
- }
- FieldDeclaration fieldDeclaration = new FieldDeclaration(fieldId, flags, staticValue);
- typeDeclaration.fields.put(fieldId, fieldDeclaration);
- }
-
- /**
- * Returns a .dex formatted file.
- */
- public byte[] generate() {
- DexFile outputDex = new DexFile(new DexOptions());
-
- for (TypeDeclaration typeDeclaration : types.values()) {
- outputDex.add(typeDeclaration.toClassDefItem());
- }
-
- try {
- return outputDex.toDex(null, false);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Loads the generated types into the current dalvikvm process.
- */
- public ClassLoader load(ClassLoader parent) throws IOException {
- byte[] dex = generate();
-
- /*
- * This implementation currently dumps the dex to the filesystem. It
- * jars the emitted .dex for the benefit of Gingerbread and earlier
- * devices, which can't load .dex files directly.
- *
- * TODO: load the dex from memory where supported.
- */
- File result = File.createTempFile("Generated", ".jar");
- result.deleteOnExit();
- JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
- jarOut.putNextEntry(new JarEntry(DexFormat.DEX_IN_JAR_NAME));
- jarOut.write(dex);
- jarOut.closeEntry();
- jarOut.close();
- try {
- Class<?> pathClassLoader = Class.forName("dalvik.system.PathClassLoader");
- return (ClassLoader) pathClassLoader.getConstructor(String.class, ClassLoader.class)
- .newInstance(result.getPath(), parent);
- } catch (ClassNotFoundException e) {
- throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e.getCause());
- } catch (InstantiationException e) {
- throw new AssertionError();
- } catch (NoSuchMethodException e) {
- throw new AssertionError();
- } catch (IllegalAccessException e) {
- throw new AssertionError();
- }
- }
-
- private static class TypeDeclaration {
- private final Type<?> type;
-
- /** declared state */
- private boolean declared;
- private int flags;
- private Type<?> supertype;
- private String sourceFile;
- private TypeList interfaces;
-
- private final Map<FieldId, FieldDeclaration> fields
- = new LinkedHashMap<FieldId, FieldDeclaration>();
- private final Map<MethodId, MethodDeclaration> methods
- = new LinkedHashMap<MethodId, MethodDeclaration>();
-
- TypeDeclaration(Type<?> type) {
- this.type = type;
- }
-
- ClassDefItem toClassDefItem() {
- if (!declared) {
- throw new IllegalStateException("Undeclared type " + type + " declares members: "
- + fields.keySet() + " " + methods.keySet());
- }
-
- DexOptions dexOptions = new DexOptions();
- dexOptions.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES;
-
- CstType thisType = type.constant;
-
- ClassDefItem out = new ClassDefItem(thisType, flags, supertype.constant,
- interfaces.ropTypes, new CstString(sourceFile));
-
- for (MethodDeclaration method : methods.values()) {
- EncodedMethod encoded = method.toEncodedMethod(dexOptions);
- if (method.isDirect()) {
- out.addDirectMethod(encoded);
- } else {
- out.addVirtualMethod(encoded);
- }
- }
- for (FieldDeclaration field : fields.values()) {
- EncodedField encoded = field.toEncodedField();
- if (field.isStatic()) {
- out.addStaticField(encoded, Constants.getConstant(field.staticValue));
- } else {
- out.addInstanceField(encoded);
- }
- }
-
- return out;
- }
- }
-
- static class FieldDeclaration {
- final FieldId<?, ?> fieldId;
- private final int accessFlags;
- private final Object staticValue;
-
- FieldDeclaration(FieldId<?, ?> fieldId, int accessFlags, Object staticValue) {
- if ((accessFlags & (AccessFlags.ACC_STATIC)) == 0 && staticValue != null) {
- throw new IllegalArgumentException("instance fields may not have a value");
- }
- this.fieldId = fieldId;
- this.accessFlags = accessFlags;
- this.staticValue = staticValue;
- }
-
- EncodedField toEncodedField() {
- return new EncodedField(fieldId.constant, accessFlags);
- }
-
- public boolean isStatic() {
- return (accessFlags & (AccessFlags.ACC_STATIC)) != 0;
- }
- }
-
- static class MethodDeclaration {
- final MethodId<?, ?> method;
- private final int flags;
- private final Code code;
-
- public MethodDeclaration(MethodId<?, ?> method, int flags) {
- this.method = method;
- this.flags = flags;
- this.code = new Code(this);
- }
-
- boolean isStatic() {
- return (flags & ACC_STATIC) != 0;
- }
-
- boolean isDirect() {
- return (flags & (ACC_STATIC | ACC_PRIVATE | ACC_CONSTRUCTOR)) != 0;
- }
-
- EncodedMethod toEncodedMethod(DexOptions dexOptions) {
- RopMethod ropMethod = new RopMethod(code.toBasicBlocks(), 0);
- LocalVariableInfo locals = null;
- DalvCode dalvCode = RopTranslator.translate(
- ropMethod, PositionList.NONE, locals, code.paramSize(), dexOptions);
- return new EncodedMethod(method.constant, flags, dalvCode, StdTypeList.EMPTY);
- }
- }
-}
diff --git a/dx/src/com/android/dx/gen/FieldId.java b/dx/src/com/android/dx/gen/FieldId.java
deleted file mode 100644
index 62ef73bdd..000000000
--- a/dx/src/com/android/dx/gen/FieldId.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstFieldRef;
-import com.android.dx.rop.cst.CstNat;
-import com.android.dx.rop.cst.CstString;
-
-/**
- * A field.
- */
-public final class FieldId<D, V> {
- final Type<D> declaringType;
- final Type<V> type;
- final String name;
-
- /** cached converted state */
- final CstNat nat;
- final CstFieldRef constant;
-
- FieldId(Type<D> declaringType, Type<V> type, String name) {
- if (declaringType == null || type == null || name == null) {
- throw new NullPointerException();
- }
- this.declaringType = declaringType;
- this.type = type;
- this.name = name;
- this.nat = new CstNat(new CstString(name), new CstString(type.name));
- this.constant = new CstFieldRef(declaringType.constant, nat);
- }
-
- public Type<D> getDeclaringType() {
- return declaringType;
- }
-
- public Type<V> getType() {
- return type;
- }
-
- public String getName() {
- return name;
- }
-
- @Override public boolean equals(Object o) {
- return o instanceof FieldId
- && ((FieldId<?, ?>) o).declaringType.equals(declaringType)
- && ((FieldId<?, ?>) o).name.equals(name);
- }
-
- @Override public int hashCode() {
- return declaringType.hashCode() + 37 * name.hashCode();
- }
-
- @Override public String toString() {
- return declaringType + "." + name;
- }
-}
diff --git a/dx/src/com/android/dx/gen/Label.java b/dx/src/com/android/dx/gen/Label.java
deleted file mode 100644
index 633b5f161..000000000
--- a/dx/src/com/android/dx/gen/Label.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.BasicBlock;
-import com.android.dx.rop.code.Insn;
-import com.android.dx.rop.code.InsnList;
-import com.android.dx.util.IntList;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A branch target in a list of instructions.
- */
-public final class Label {
-
- final List<Insn> instructions = new ArrayList<Insn>();
-
- boolean marked = false;
-
- /** an immutable list of labels corresponding to the types in the catch list */
- List<Label> catchLabels = Collections.emptyList();
-
- /** contains the next instruction if no branch occurs */
- Label primarySuccessor;
-
- /** contains the instruction to jump to if the if is true */
- Label alternateSuccessor;
-
- int id = -1;
-
- Label() {}
-
- boolean isEmpty() {
- return instructions.isEmpty();
- }
-
- void compact() {
- for (int i = 0; i < catchLabels.size(); i++) {
- while (catchLabels.get(i).isEmpty()) {
- catchLabels.set(i, catchLabels.get(i).primarySuccessor);
- }
- }
- while (primarySuccessor != null && primarySuccessor.isEmpty()) {
- primarySuccessor = primarySuccessor.primarySuccessor;
- }
- while (alternateSuccessor != null && alternateSuccessor.isEmpty()) {
- alternateSuccessor = alternateSuccessor.primarySuccessor;
- }
- }
-
- BasicBlock toBasicBlock() {
- InsnList result = new InsnList(instructions.size());
- for (int i = 0; i < instructions.size(); i++) {
- result.set(i, instructions.get(i));
- }
- result.setImmutable();
-
- int primarySuccessorIndex = -1;
- IntList successors = new IntList();
- for (Label catchLabel : catchLabels) {
- successors.add(catchLabel.id);
- }
- if (primarySuccessor != null) {
- primarySuccessorIndex = primarySuccessor.id;
- successors.add(primarySuccessorIndex);
- }
- if (alternateSuccessor != null) {
- successors.add(alternateSuccessor.id);
- }
- successors.setImmutable();
-
- return new BasicBlock(id, result, successors, primarySuccessorIndex);
- }
-}
diff --git a/dx/src/com/android/dx/gen/Local.java b/dx/src/com/android/dx/gen/Local.java
deleted file mode 100644
index b98759c3f..000000000
--- a/dx/src/com/android/dx/gen/Local.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.code.RegisterSpec;
-
-/**
- * A temporary variable that holds a single value.
- */
-public final class Local<T> {
- private final Code code;
- final Type<T> type;
- private int reg = -1;
- private RegisterSpec spec;
-
- private Local(Code code, Type<T> type) {
- this.code = code;
- this.type = type;
- }
-
- static <T> Local<T> get(Code code, Type<T> type) {
- return new Local<T>(code, type);
- }
-
- /**
- * Assigns registers to this local.
- *
- * @return the number of registers required.
- */
- int initialize(int reg) {
- this.reg = reg;
- this.spec = RegisterSpec.make(reg, type.ropType);
- return size();
- }
-
- int size() {
- return type.ropType.getCategory();
- }
-
- RegisterSpec spec() {
- if (spec == null) {
- code.initializeLocals();
- if (spec == null) {
- throw new AssertionError();
- }
- }
- return spec;
- }
-
- public Type getType() {
- return type;
- }
-
- @Override public String toString() {
- return "v" + reg + "(" + type + ")";
- }
-}
diff --git a/dx/src/com/android/dx/gen/MethodId.java b/dx/src/com/android/dx/gen/MethodId.java
deleted file mode 100644
index 29d088ab4..000000000
--- a/dx/src/com/android/dx/gen/MethodId.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstMethodRef;
-import com.android.dx.rop.cst.CstNat;
-import com.android.dx.rop.cst.CstString;
-import com.android.dx.rop.type.Prototype;
-import java.util.List;
-
-/**
- * A method or constructor.
- */
-public final class MethodId<D, R> {
- final Type<D> declaringType;
- final Type<R> returnType;
- final String name;
- final TypeList parameters;
-
- /** cached converted state */
- final CstNat nat;
- final CstMethodRef constant;
-
- MethodId(Type<D> declaringType, Type<R> returnType, String name, TypeList parameters) {
- if (declaringType == null || returnType == null || name == null || parameters == null) {
- throw new NullPointerException();
- }
- this.declaringType = declaringType;
- this.returnType = returnType;
- this.name = name;
- this.parameters = parameters;
- this.nat = new CstNat(new CstString(name), new CstString(descriptor(false)));
- this.constant = new CstMethodRef(declaringType.constant, nat);
- }
-
- public Type<D> getDeclaringType() {
- return declaringType;
- }
-
- public Type<R> getReturnType() {
- return returnType;
- }
-
- public String getName() {
- return name;
- }
-
- public List<Type<?>> getParameters() {
- return parameters.asList();
- }
-
- /**
- * Returns a descriptor like "(Ljava/lang/Class;[I)Ljava/lang/Object;".
- */
- String descriptor(boolean includeThis) {
- StringBuilder result = new StringBuilder();
- result.append("(");
- if (includeThis) {
- result.append(declaringType.name);
- }
- for (Type t : parameters.types) {
- result.append(t.name);
- }
- result.append(")");
- result.append(returnType.name);
- return result.toString();
- }
-
- Prototype prototype(boolean includeThis) {
- return Prototype.intern(descriptor(includeThis));
- }
-
- @Override public boolean equals(Object o) {
- return o instanceof MethodId
- && ((MethodId<?, ?>) o).declaringType.equals(declaringType)
- && ((MethodId<?, ?>) o).name.equals(name)
- && ((MethodId<?, ?>) o).parameters.equals(parameters)
- && ((MethodId<?, ?>) o).returnType.equals(returnType);
- }
-
- @Override public int hashCode() {
- int result = 17;
- result = 31 * result + declaringType.hashCode();
- result = 31 * result + name.hashCode();
- result = 31 * result + parameters.hashCode();
- result = 31 * result + returnType.hashCode();
- return result;
- }
-
- @Override public String toString() {
- return declaringType + "." + name + "(" + parameters + ")";
- }
-}
diff --git a/dx/src/com/android/dx/gen/Type.java b/dx/src/com/android/dx/gen/Type.java
deleted file mode 100644
index 3b81f6d1d..000000000
--- a/dx/src/com/android/dx/gen/Type.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.cst.CstType;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A primitive type, interface or class.
- */
-public final class Type<T> {
- /** The {@code boolean} primitive type. */
- public static final Type<Boolean> BOOLEAN
- = new Type<Boolean>(com.android.dx.rop.type.Type.BOOLEAN);
-
- /** The {@code byte} primitive type. */
- public static final Type<Byte> BYTE = new Type<Byte>(com.android.dx.rop.type.Type.BYTE);
-
- /** The {@code char} primitive type. */
- public static final Type<Character> CHAR
- = new Type<Character>(com.android.dx.rop.type.Type.CHAR);
-
- /** The {@code double} primitive type. */
- public static final Type<Double> DOUBLE = new Type<Double>(com.android.dx.rop.type.Type.DOUBLE);
-
- /** The {@code float} primitive type. */
- public static final Type<Float> FLOAT = new Type<Float>(com.android.dx.rop.type.Type.FLOAT);
-
- /** The {@code int} primitive type. */
- public static final Type<Integer> INT = new Type<Integer>(com.android.dx.rop.type.Type.INT);
-
- /** The {@code long} primitive type. */
- public static final Type<Long> LONG = new Type<Long>(com.android.dx.rop.type.Type.LONG);
-
- /** The {@code short} primitive type. */
- public static final Type<Short> SHORT = new Type<Short>(com.android.dx.rop.type.Type.SHORT);
-
- /** The {@code void} primitive type. Only used as a return type. */
- public static final Type<Void> VOID = new Type<Void>(com.android.dx.rop.type.Type.VOID);
-
- /** The {@code Object} type. */
- public static final Type<Object> OBJECT = new Type<Object>(com.android.dx.rop.type.Type.OBJECT);
-
- /** The {@code String} type. */
- public static final Type<String> STRING = new Type<String>(com.android.dx.rop.type.Type.STRING);
-
- private static final Map<Class<?>, Type<?>> PRIMITIVE_TO_TYPE
- = new HashMap<Class<?>, Type<?>>();
- static {
- PRIMITIVE_TO_TYPE.put(boolean.class, BOOLEAN);
- PRIMITIVE_TO_TYPE.put(byte.class, BYTE);
- PRIMITIVE_TO_TYPE.put(char.class, CHAR);
- PRIMITIVE_TO_TYPE.put(double.class, DOUBLE);
- PRIMITIVE_TO_TYPE.put(float.class, FLOAT);
- PRIMITIVE_TO_TYPE.put(int.class, INT);
- PRIMITIVE_TO_TYPE.put(long.class, LONG);
- PRIMITIVE_TO_TYPE.put(short.class, SHORT);
- PRIMITIVE_TO_TYPE.put(void.class, VOID);
- }
-
- final String name;
-
- /** cached converted values */
- final com.android.dx.rop.type.Type ropType;
- final CstType constant;
-
- Type(com.android.dx.rop.type.Type ropType) {
- this(ropType.getDescriptor(), ropType);
- }
-
- Type(String name, com.android.dx.rop.type.Type ropType) {
- if (name == null || ropType == null) {
- throw new NullPointerException();
- }
- this.name = name;
- this.ropType = ropType;
- this.constant = CstType.intern(ropType);
- }
-
- /**
- * @param name a descriptor like "Ljava/lang/Class;".
- */
- public static <T> Type<T> get(String name) {
- return new Type<T>(name, com.android.dx.rop.type.Type.internReturnType(name));
- }
-
- public static <T> Type<T> get(Class<T> type) {
- if (type.isPrimitive()) {
- @SuppressWarnings("unchecked") // guarded by equals
- Type<T> result = (Type<T>) PRIMITIVE_TO_TYPE.get(type);
- return result;
- }
- String name = type.getName().replace('.', '/');
- return get(type.isArray() ? name : 'L' + name + ';');
- }
-
- public <V> FieldId<T, V> getField(Type<V> type, String name) {
- return new FieldId<T, V>(this, type, name);
- }
-
- public MethodId<T, Void> getConstructor(Type<?>... parameters) {
- return new MethodId<T, Void>(this, VOID, "<init>", new TypeList(parameters));
- }
-
- public <R> MethodId<T, R> getMethod(Type<R> returnType, String name, Type<?>... parameters) {
- return new MethodId<T, R>(this, returnType, name, new TypeList(parameters));
- }
-
- public String getName() {
- return name;
- }
-
- @Override public boolean equals(Object o) {
- return o instanceof Type
- && ((Type) o).name.equals(name);
- }
-
- @Override public int hashCode() {
- return name.hashCode();
- }
-
- @Override public String toString() {
- return name;
- }
-}
diff --git a/dx/src/com/android/dx/gen/TypeList.java b/dx/src/com/android/dx/gen/TypeList.java
deleted file mode 100644
index e18ed4a28..000000000
--- a/dx/src/com/android/dx/gen/TypeList.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.gen;
-
-import com.android.dx.rop.type.StdTypeList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * An immutable of types.
- */
-final class TypeList {
- final Type<?>[] types;
- final StdTypeList ropTypes;
-
- TypeList(Type<?>[] types) {
- this.types = types.clone();
- this.ropTypes = new StdTypeList(types.length);
- for (int i = 0; i < types.length; i++) {
- ropTypes.set(i, types[i].ropType);
- }
- }
-
- /**
- * Returns an immutable list.
- */
- public List<Type<?>> asList() {
- return Collections.unmodifiableList(Arrays.asList(types));
- }
-
- @Override public boolean equals(Object o) {
- return o instanceof TypeList && Arrays.equals(((TypeList) o).types, types);
- }
-
- @Override public int hashCode() {
- return Arrays.hashCode(types);
- }
-
- @Override public String toString() {
- StringBuilder result = new StringBuilder();
- for (int i = 0; i < types.length; i++) {
- if (i > 0) {
- result.append(", ");
- }
- result.append(types[i]);
- }
- return result.toString();
- }
-}
diff --git a/dx/src/com/android/dx/io/DexBuffer.java b/dx/src/com/android/dx/io/DexBuffer.java
index e6f908bfa..39e5858e6 100644
--- a/dx/src/com/android/dx/io/DexBuffer.java
+++ b/dx/src/com/android/dx/io/DexBuffer.java
@@ -217,7 +217,7 @@ public final class DexBuffer {
return length;
}
- private static int fourByteAlign(int position) {
+ public static int fourByteAlign(int position) {
return (position + 3) & ~3;
}
diff --git a/dx/src/com/android/dx/io/OpcodeInfo.java b/dx/src/com/android/dx/io/OpcodeInfo.java
index c8fcf25d5..2040d352c 100644
--- a/dx/src/com/android/dx/io/OpcodeInfo.java
+++ b/dx/src/com/android/dx/io/OpcodeInfo.java
@@ -931,162 +931,6 @@ public final class OpcodeInfo {
new Info(Opcodes.USHR_INT_LIT8, "ushr-int/lit8",
InstructionCodec.FORMAT_22B, IndexType.NONE);
- public static final Info CONST_CLASS_JUMBO =
- new Info(Opcodes.CONST_CLASS_JUMBO, "const-class/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.TYPE_REF);
-
- public static final Info CHECK_CAST_JUMBO =
- new Info(Opcodes.CHECK_CAST_JUMBO, "check-cast/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.TYPE_REF);
-
- public static final Info INSTANCE_OF_JUMBO =
- new Info(Opcodes.INSTANCE_OF_JUMBO, "instance-of/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.TYPE_REF);
-
- public static final Info NEW_INSTANCE_JUMBO =
- new Info(Opcodes.NEW_INSTANCE_JUMBO, "new-instance/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.TYPE_REF);
-
- public static final Info NEW_ARRAY_JUMBO =
- new Info(Opcodes.NEW_ARRAY_JUMBO, "new-array/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.TYPE_REF);
-
- public static final Info FILLED_NEW_ARRAY_JUMBO =
- new Info(Opcodes.FILLED_NEW_ARRAY_JUMBO, "filled-new-array/jumbo",
- InstructionCodec.FORMAT_5RC, IndexType.TYPE_REF);
-
- public static final Info IGET_JUMBO =
- new Info(Opcodes.IGET_JUMBO, "iget/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IGET_WIDE_JUMBO =
- new Info(Opcodes.IGET_WIDE_JUMBO, "iget-wide/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IGET_OBJECT_JUMBO =
- new Info(Opcodes.IGET_OBJECT_JUMBO, "iget-object/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IGET_BOOLEAN_JUMBO =
- new Info(Opcodes.IGET_BOOLEAN_JUMBO, "iget-boolean/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IGET_BYTE_JUMBO =
- new Info(Opcodes.IGET_BYTE_JUMBO, "iget-byte/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IGET_CHAR_JUMBO =
- new Info(Opcodes.IGET_CHAR_JUMBO, "iget-char/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IGET_SHORT_JUMBO =
- new Info(Opcodes.IGET_SHORT_JUMBO, "iget-short/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_JUMBO =
- new Info(Opcodes.IPUT_JUMBO, "iput/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_WIDE_JUMBO =
- new Info(Opcodes.IPUT_WIDE_JUMBO, "iput-wide/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_OBJECT_JUMBO =
- new Info(Opcodes.IPUT_OBJECT_JUMBO, "iput-object/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_BOOLEAN_JUMBO =
- new Info(Opcodes.IPUT_BOOLEAN_JUMBO, "iput-boolean/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_BYTE_JUMBO =
- new Info(Opcodes.IPUT_BYTE_JUMBO, "iput-byte/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_CHAR_JUMBO =
- new Info(Opcodes.IPUT_CHAR_JUMBO, "iput-char/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info IPUT_SHORT_JUMBO =
- new Info(Opcodes.IPUT_SHORT_JUMBO, "iput-short/jumbo",
- InstructionCodec.FORMAT_52C, IndexType.FIELD_REF);
-
- public static final Info SGET_JUMBO =
- new Info(Opcodes.SGET_JUMBO, "sget/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SGET_WIDE_JUMBO =
- new Info(Opcodes.SGET_WIDE_JUMBO, "sget-wide/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SGET_OBJECT_JUMBO =
- new Info(Opcodes.SGET_OBJECT_JUMBO, "sget-object/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SGET_BOOLEAN_JUMBO =
- new Info(Opcodes.SGET_BOOLEAN_JUMBO, "sget-boolean/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SGET_BYTE_JUMBO =
- new Info(Opcodes.SGET_BYTE_JUMBO, "sget-byte/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SGET_CHAR_JUMBO =
- new Info(Opcodes.SGET_CHAR_JUMBO, "sget-char/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SGET_SHORT_JUMBO =
- new Info(Opcodes.SGET_SHORT_JUMBO, "sget-short/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_JUMBO =
- new Info(Opcodes.SPUT_JUMBO, "sput/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_WIDE_JUMBO =
- new Info(Opcodes.SPUT_WIDE_JUMBO, "sput-wide/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_OBJECT_JUMBO =
- new Info(Opcodes.SPUT_OBJECT_JUMBO, "sput-object/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_BOOLEAN_JUMBO =
- new Info(Opcodes.SPUT_BOOLEAN_JUMBO, "sput-boolean/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_BYTE_JUMBO =
- new Info(Opcodes.SPUT_BYTE_JUMBO, "sput-byte/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_CHAR_JUMBO =
- new Info(Opcodes.SPUT_CHAR_JUMBO, "sput-char/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info SPUT_SHORT_JUMBO =
- new Info(Opcodes.SPUT_SHORT_JUMBO, "sput-short/jumbo",
- InstructionCodec.FORMAT_41C, IndexType.FIELD_REF);
-
- public static final Info INVOKE_VIRTUAL_JUMBO =
- new Info(Opcodes.INVOKE_VIRTUAL_JUMBO, "invoke-virtual/jumbo",
- InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
- public static final Info INVOKE_SUPER_JUMBO =
- new Info(Opcodes.INVOKE_SUPER_JUMBO, "invoke-super/jumbo",
- InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
- public static final Info INVOKE_DIRECT_JUMBO =
- new Info(Opcodes.INVOKE_DIRECT_JUMBO, "invoke-direct/jumbo",
- InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
- public static final Info INVOKE_STATIC_JUMBO =
- new Info(Opcodes.INVOKE_STATIC_JUMBO, "invoke-static/jumbo",
- InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
- public static final Info INVOKE_INTERFACE_JUMBO =
- new Info(Opcodes.INVOKE_INTERFACE_JUMBO, "invoke-interface/jumbo",
- InstructionCodec.FORMAT_5RC, IndexType.METHOD_REF);
-
// END(opcode-info-defs)
// Static initialization.
@@ -1320,45 +1164,6 @@ public final class OpcodeInfo {
set(SHL_INT_LIT8);
set(SHR_INT_LIT8);
set(USHR_INT_LIT8);
- set(CONST_CLASS_JUMBO);
- set(CHECK_CAST_JUMBO);
- set(INSTANCE_OF_JUMBO);
- set(NEW_INSTANCE_JUMBO);
- set(NEW_ARRAY_JUMBO);
- set(FILLED_NEW_ARRAY_JUMBO);
- set(IGET_JUMBO);
- set(IGET_WIDE_JUMBO);
- set(IGET_OBJECT_JUMBO);
- set(IGET_BOOLEAN_JUMBO);
- set(IGET_BYTE_JUMBO);
- set(IGET_CHAR_JUMBO);
- set(IGET_SHORT_JUMBO);
- set(IPUT_JUMBO);
- set(IPUT_WIDE_JUMBO);
- set(IPUT_OBJECT_JUMBO);
- set(IPUT_BOOLEAN_JUMBO);
- set(IPUT_BYTE_JUMBO);
- set(IPUT_CHAR_JUMBO);
- set(IPUT_SHORT_JUMBO);
- set(SGET_JUMBO);
- set(SGET_WIDE_JUMBO);
- set(SGET_OBJECT_JUMBO);
- set(SGET_BOOLEAN_JUMBO);
- set(SGET_BYTE_JUMBO);
- set(SGET_CHAR_JUMBO);
- set(SGET_SHORT_JUMBO);
- set(SPUT_JUMBO);
- set(SPUT_WIDE_JUMBO);
- set(SPUT_OBJECT_JUMBO);
- set(SPUT_BOOLEAN_JUMBO);
- set(SPUT_BYTE_JUMBO);
- set(SPUT_CHAR_JUMBO);
- set(SPUT_SHORT_JUMBO);
- set(INVOKE_VIRTUAL_JUMBO);
- set(INVOKE_SUPER_JUMBO);
- set(INVOKE_DIRECT_JUMBO);
- set(INVOKE_STATIC_JUMBO);
- set(INVOKE_INTERFACE_JUMBO);
// END(opcode-info-init)
}
diff --git a/dx/src/com/android/dx/io/Opcodes.java b/dx/src/com/android/dx/io/Opcodes.java
index 4a255f7d4..6dba49d9e 100644
--- a/dx/src/com/android/dx/io/Opcodes.java
+++ b/dx/src/com/android/dx/io/Opcodes.java
@@ -259,45 +259,6 @@ public final class Opcodes {
public static final int SHL_INT_LIT8 = 0xe0;
public static final int SHR_INT_LIT8 = 0xe1;
public static final int USHR_INT_LIT8 = 0xe2;
- public static final int CONST_CLASS_JUMBO = 0x00ff;
- public static final int CHECK_CAST_JUMBO = 0x01ff;
- public static final int INSTANCE_OF_JUMBO = 0x02ff;
- public static final int NEW_INSTANCE_JUMBO = 0x03ff;
- public static final int NEW_ARRAY_JUMBO = 0x04ff;
- public static final int FILLED_NEW_ARRAY_JUMBO = 0x05ff;
- public static final int IGET_JUMBO = 0x06ff;
- public static final int IGET_WIDE_JUMBO = 0x07ff;
- public static final int IGET_OBJECT_JUMBO = 0x08ff;
- public static final int IGET_BOOLEAN_JUMBO = 0x09ff;
- public static final int IGET_BYTE_JUMBO = 0x0aff;
- public static final int IGET_CHAR_JUMBO = 0x0bff;
- public static final int IGET_SHORT_JUMBO = 0x0cff;
- public static final int IPUT_JUMBO = 0x0dff;
- public static final int IPUT_WIDE_JUMBO = 0x0eff;
- public static final int IPUT_OBJECT_JUMBO = 0x0fff;
- public static final int IPUT_BOOLEAN_JUMBO = 0x10ff;
- public static final int IPUT_BYTE_JUMBO = 0x11ff;
- public static final int IPUT_CHAR_JUMBO = 0x12ff;
- public static final int IPUT_SHORT_JUMBO = 0x13ff;
- public static final int SGET_JUMBO = 0x14ff;
- public static final int SGET_WIDE_JUMBO = 0x15ff;
- public static final int SGET_OBJECT_JUMBO = 0x16ff;
- public static final int SGET_BOOLEAN_JUMBO = 0x17ff;
- public static final int SGET_BYTE_JUMBO = 0x18ff;
- public static final int SGET_CHAR_JUMBO = 0x19ff;
- public static final int SGET_SHORT_JUMBO = 0x1aff;
- public static final int SPUT_JUMBO = 0x1bff;
- public static final int SPUT_WIDE_JUMBO = 0x1cff;
- public static final int SPUT_OBJECT_JUMBO = 0x1dff;
- public static final int SPUT_BOOLEAN_JUMBO = 0x1eff;
- public static final int SPUT_BYTE_JUMBO = 0x1fff;
- public static final int SPUT_CHAR_JUMBO = 0x20ff;
- public static final int SPUT_SHORT_JUMBO = 0x21ff;
- public static final int INVOKE_VIRTUAL_JUMBO = 0x22ff;
- public static final int INVOKE_SUPER_JUMBO = 0x23ff;
- public static final int INVOKE_DIRECT_JUMBO = 0x24ff;
- public static final int INVOKE_STATIC_JUMBO = 0x25ff;
- public static final int INVOKE_INTERFACE_JUMBO = 0x26ff;
// END(opcodes)
// TODO: Generate these payload opcodes with opcode-gen.
diff --git a/dx/src/com/android/dx/io/instructions/DecodedInstruction.java b/dx/src/com/android/dx/io/instructions/DecodedInstruction.java
index e418a1c0b..a8bc8592e 100644
--- a/dx/src/com/android/dx/io/instructions/DecodedInstruction.java
+++ b/dx/src/com/android/dx/io/instructions/DecodedInstruction.java
@@ -21,7 +21,6 @@ import com.android.dx.io.OpcodeInfo;
import com.android.dx.io.Opcodes;
import com.android.dx.util.DexException;
import com.android.dx.util.Hex;
-
import java.io.EOFException;
/**
@@ -59,7 +58,7 @@ public abstract class DecodedInstruction {
/**
* literal value argument; also used for special verification error
- * constants (formats 20bc and 40sc) as well as should-be-zero values
+ * constants (format 20bc) as well as should-be-zero values
* (formats 10x, 20t, 30t, and 32x)
*/
private final long literal;
@@ -90,7 +89,7 @@ public abstract class DecodedInstruction {
decoded[in.cursor()] = DecodedInstruction.decode(in);
}
} catch (EOFException ex) {
- throw new AssertionError("shouldn't happen");
+ throw new DexException(ex);
}
return decoded;
diff --git a/dx/src/com/android/dx/io/instructions/InstructionCodec.java b/dx/src/com/android/dx/io/instructions/InstructionCodec.java
index b864b8365..2e803ed6b 100644
--- a/dx/src/com/android/dx/io/instructions/InstructionCodec.java
+++ b/dx/src/com/android/dx/io/instructions/InstructionCodec.java
@@ -605,139 +605,6 @@ public enum InstructionCodec {
}
},
- FORMAT_33X() {
- @Override public DecodedInstruction decode(int opcodeUnit,
- CodeInput in) throws EOFException {
- int ab = in.read();
- int a = byte0(ab);
- int b = byte1(ab);
- int c = in.read();
- return new ThreeRegisterDecodedInstruction(
- this, opcodeUnit, 0, null,
- 0, 0L,
- a, b, c);
- }
-
- @Override public void encode(DecodedInstruction insn, CodeOutput out) {
- out.write(
- insn.getOpcodeUnit(),
- codeUnit(insn.getA(), insn.getB()),
- insn.getCUnit());
- }
- },
-
- FORMAT_32S() {
- @Override public DecodedInstruction decode(int opcodeUnit,
- CodeInput in) throws EOFException {
- int ab = in.read();
- int a = byte0(ab);
- int b = byte1(ab);
- int literal = (short) in.read(); // sign-extend
- return new TwoRegisterDecodedInstruction(
- this, opcodeUnit, 0, null,
- 0, literal,
- a, b);
- }
-
- @Override public void encode(DecodedInstruction insn, CodeOutput out) {
- out.write(
- insn.getOpcodeUnit(),
- codeUnit(insn.getA(), insn.getB()),
- insn.getLiteralUnit());
- }
- },
-
- FORMAT_40SC() {
- @Override public DecodedInstruction decode(int opcodeUnit,
- CodeInput in) throws EOFException {
- // Note: We use the literal field to hold the decoded AA value.
- int index = in.readInt();
- int literal = in.read();
- return new ZeroRegisterDecodedInstruction(
- this, opcodeUnit, index, IndexType.VARIES,
- 0, literal);
- }
-
- @Override public void encode(DecodedInstruction insn, CodeOutput out) {
- int index = insn.getIndex();
- out.write(
- insn.getOpcodeUnit(),
- unit0(index),
- unit1(index),
- insn.getLiteralUnit());
- }
- },
-
- FORMAT_41C() {
- @Override public DecodedInstruction decode(int opcodeUnit,
- CodeInput in) throws EOFException {
- int index = in.readInt();
- int a = in.read();
- IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
- return new OneRegisterDecodedInstruction(
- this, opcodeUnit, index, indexType,
- 0, 0L,
- a);
- }
-
- @Override public void encode(DecodedInstruction insn, CodeOutput out) {
- int index = insn.getIndex();
- out.write(
- insn.getOpcodeUnit(),
- unit0(index),
- unit1(index),
- insn.getAUnit());
- }
- },
-
- FORMAT_52C() {
- @Override public DecodedInstruction decode(int opcodeUnit,
- CodeInput in) throws EOFException {
- int index = in.readInt();
- int a = in.read();
- int b = in.read();
- IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
- return new TwoRegisterDecodedInstruction(
- this, opcodeUnit, index, indexType,
- 0, 0L,
- a, b);
- }
-
- @Override public void encode(DecodedInstruction insn, CodeOutput out) {
- int index = insn.getIndex();
- out.write(
- insn.getOpcodeUnit(),
- unit0(index),
- unit1(index),
- insn.getAUnit(),
- insn.getBUnit());
- }
- },
-
- FORMAT_5RC() {
- @Override public DecodedInstruction decode(int opcodeUnit,
- CodeInput in) throws EOFException {
- int index = in.readInt();
- int registerCount = in.read();
- int a = in.read();
- IndexType indexType = OpcodeInfo.getIndexType(opcodeUnit);
- return new RegisterRangeDecodedInstruction(
- this, opcodeUnit, index, indexType,
- 0, 0L,
- a, registerCount);
- }
-
- @Override public void encode(DecodedInstruction insn, CodeOutput out) {
- int index = insn.getIndex();
- out.write(
- insn.getOpcodeUnit(),
- unit0(index),
- unit1(index),
- insn.getRegisterCountUnit(),
- insn.getAUnit());
- }
- },
-
FORMAT_PACKED_SWITCH_PAYLOAD() {
@Override public DecodedInstruction decode(int opcodeUnit,
CodeInput in) throws EOFException {
diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java
index 8078f640e..a6f413a5d 100644
--- a/dx/src/com/android/dx/merge/DexMerger.java
+++ b/dx/src/com/android/dx/merge/DexMerger.java
@@ -33,7 +33,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Combine two dex files into one.
@@ -594,6 +596,8 @@ public final class DexMerger {
transformAnnotationSets(dexB, bIndexMap);
transformAnnotationDirectories(dexA, aIndexMap);
transformAnnotationDirectories(dexB, bIndexMap);
+ transformStaticValues(dexA, aIndexMap);
+ transformStaticValues(dexB, bIndexMap);
}
private void transformAnnotationSets(DexBuffer in, IndexMap indexMap) {
@@ -616,6 +620,16 @@ public final class DexMerger {
}
}
+ private void transformStaticValues(DexBuffer in, IndexMap indexMap) {
+ TableOfContents.Section section = in.getTableOfContents().encodedArrays;
+ if (section.exists()) {
+ DexBuffer.Section staticValuesIn = in.open(section.off);
+ for (int i = 0; i < section.size; i++) {
+ transformStaticValues(staticValuesIn, indexMap);
+ }
+ }
+ }
+
/**
* Reads a class_def_item beginning at {@code in} and writes the index and
* data.
@@ -643,13 +657,7 @@ public final class DexMerger {
}
int staticValuesOff = classDef.getStaticValuesOffset();
- if (staticValuesOff == 0) {
- idsDefsOut.writeInt(0);
- } else {
- DexBuffer.Section staticValuesIn = in.open(staticValuesOff);
- idsDefsOut.writeInt(encodedArrayOut.getPosition());
- transformStaticValues(staticValuesIn, indexMap);
- }
+ idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));
}
/**
@@ -923,6 +931,7 @@ public final class DexMerger {
private void transformStaticValues(DexBuffer.Section in, IndexMap indexMap) {
contentsOut.encodedArrays.size++;
+ indexMap.putStaticValuesOffset(in.getPosition(), encodedArrayOut.getPosition());
indexMap.adjustEncodedArray(in.readEncodedArray()).writeTo(encodedArrayOut);
}
@@ -1008,6 +1017,9 @@ public final class DexMerger {
// all of the bytes in a debug info section may be uleb/sleb
debugInfo += contents.debugInfos.byteCount * 2;
}
+
+ typeList = DexBuffer.fourByteAlign(typeList);
+ code = DexBuffer.fourByteAlign(code);
}
public int size() {
diff --git a/dx/src/com/android/dx/merge/IndexMap.java b/dx/src/com/android/dx/merge/IndexMap.java
index a7b20bede..a5c9584dc 100644
--- a/dx/src/com/android/dx/merge/IndexMap.java
+++ b/dx/src/com/android/dx/merge/IndexMap.java
@@ -48,6 +48,7 @@ public final class IndexMap {
private final HashMap<Integer, Integer> annotationOffsets;
private final HashMap<Integer, Integer> annotationSetOffsets;
private final HashMap<Integer, Integer> annotationDirectoryOffsets;
+ private final HashMap<Integer, Integer> staticValuesOffsets;
public IndexMap(DexBuffer target, TableOfContents tableOfContents) {
this.target = target;
@@ -60,14 +61,16 @@ public final class IndexMap {
this.annotationOffsets = new HashMap<Integer, Integer>();
this.annotationSetOffsets = new HashMap<Integer, Integer>();
this.annotationDirectoryOffsets = new HashMap<Integer, Integer>();
+ this.staticValuesOffsets = new HashMap<Integer, Integer>();
/*
- * A type list, annotation set, or annotation directory at offset 0 is
- * always empty. Always map offset 0 to 0.
+ * A type list, annotation set, annotation directory, or static value at
+ * offset 0 is always empty. Always map offset 0 to 0.
*/
this.typeListOffsets.put(0, 0);
this.annotationSetOffsets.put(0, 0);
this.annotationDirectoryOffsets.put(0, 0);
+ this.staticValuesOffsets.put(0, 0);
}
public void putTypeListOffset(int oldOffset, int newOffset) {
@@ -98,6 +101,13 @@ public final class IndexMap {
annotationDirectoryOffsets.put(oldOffset, newOffset);
}
+ public void putStaticValuesOffset(int oldOffset, int newOffset) {
+ if (oldOffset <= 0 || newOffset <= 0) {
+ throw new IllegalArgumentException();
+ }
+ staticValuesOffsets.put(oldOffset, newOffset);
+ }
+
public int adjustString(int stringIndex) {
return stringIndex == ClassDef.NO_INDEX ? ClassDef.NO_INDEX : stringIds[stringIndex];
}
@@ -145,6 +155,10 @@ public final class IndexMap {
return annotationDirectoryOffsets.get(annotationDirectoryOffset);
}
+ public int adjustStaticValues(int staticValuesOffset) {
+ return staticValuesOffsets.get(staticValuesOffset);
+ }
+
public MethodId adjust(MethodId methodId) {
return new MethodId(target,
adjustType(methodId.getDeclaringClassIndex()),
diff --git a/dx/src/com/android/dx/rop/cst/CstType.java b/dx/src/com/android/dx/rop/cst/CstType.java
index 8624028aa..870fcb480 100644
--- a/dx/src/com/android/dx/rop/cst/CstType.java
+++ b/dx/src/com/android/dx/rop/cst/CstType.java
@@ -17,7 +17,6 @@
package com.android.dx.rop.cst;
import com.android.dx.rop.type.Type;
-
import java.util.HashMap;
/**
@@ -229,4 +228,22 @@ public final class CstType extends TypedConstant {
return descriptor;
}
+
+ /**
+ * Returns a human readable package name for this type, like "java.util".
+ * If this is an array type, this returns the package name of the array's
+ * component type. If this is a primitive type, this returns "default".
+ */
+ public String getPackageName() {
+ // descriptor is a string like "[[Ljava/util/String;"
+ String descriptor = getDescriptor().getString();
+ int lastSlash = descriptor.lastIndexOf('/');
+ int lastLeftSquare = descriptor.lastIndexOf('['); // -1 unless this is an array
+ if (lastSlash == -1) {
+ return "default";
+ } else {
+ // +2 to skip the '[' and the 'L' prefix
+ return descriptor.substring(lastLeftSquare + 2, lastSlash).replace('/', '.');
+ }
+ }
}
diff --git a/dx/src/com/android/dx/ssa/_tests/_DomFront.java b/dx/src/com/android/dx/ssa/_tests/_DomFront.java
deleted file mode 100644
index 3d891c9bb..000000000
--- a/dx/src/com/android/dx/ssa/_tests/_DomFront.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dx.ssa._tests;
-
-import junit.framework.TestCase;
-
-/**
- * Test the class {@code com.android.dx.ssa.DomFront}.
- */
-public class _DomFront
- extends TestCase {
-
- public void test_one() {
-
- }
-
-
-}
diff --git a/dx/src/junit/extensions/ActiveTestSuite.java b/dx/src/junit/extensions/ActiveTestSuite.java
deleted file mode 100644
index 1a3f163ec..000000000
--- a/dx/src/junit/extensions/ActiveTestSuite.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package junit.extensions;
-
-import junit.framework.*;
-
-/**
- * A TestSuite for active Tests. It runs each
- * test in a separate thread and waits until all
- * threads have terminated.
- * -- Aarhus Radisson Scandinavian Center 11th floor
- */
-public class ActiveTestSuite extends TestSuite {
- private volatile int fActiveTestDeathCount;
-
- public ActiveTestSuite() {
- }
-
- public ActiveTestSuite(Class theClass) {
- super(theClass);
- }
-
- public ActiveTestSuite(String name) {
- super (name);
- }
-
- public ActiveTestSuite(Class theClass, String name) {
- super(theClass, name);
- }
-
- public void run(TestResult result) {
- fActiveTestDeathCount= 0;
- super.run(result);
- waitUntilFinished();
- }
-
- public void runTest(final Test test, final TestResult result) {
- Thread t= new Thread() {
- public void run() {
- try {
- // inlined due to limitation in VA/Java
- //ActiveTestSuite.super.runTest(test, result);
- test.run(result);
- } finally {
- ActiveTestSuite.this.runFinished(test);
- }
- }
- };
- t.start();
- }
-
- synchronized void waitUntilFinished() {
- while (fActiveTestDeathCount < testCount()) {
- try {
- wait();
- } catch (InterruptedException e) {
- return; // ignore
- }
- }
- }
-
- synchronized public void runFinished(Test test) {
- fActiveTestDeathCount++;
- notifyAll();
- }
-}
diff --git a/dx/src/junit/extensions/ExceptionTestCase.java b/dx/src/junit/extensions/ExceptionTestCase.java
deleted file mode 100644
index fae574625..000000000
--- a/dx/src/junit/extensions/ExceptionTestCase.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package junit.extensions;
-
-import junit.framework.*;
-
-/**
- * A TestCase that expects an Exception of class fExpected to be thrown.
- * The other way to check that an expected exception is thrown is:
- * <pre>
- * try {
- * shouldThrow();
- * }
- * catch (SpecialException e) {
- * return;
- * }
- * fail("Expected SpecialException");
- * </pre>
- *
- * To use ExceptionTestCase, create a TestCase like:
- * <pre>
- * new ExceptionTestCase("testShouldThrow", SpecialException.class);
- * </pre>
- */
-public class ExceptionTestCase extends TestCase {
- Class<?> fExpected;
-
- public ExceptionTestCase(String name, Class exception) {
- super(name);
- fExpected= exception;
- }
- /**
- * Execute the test method expecting that an Exception of
- * class fExpected or one of its subclasses will be thrown
- */
- protected void runTest() throws Throwable {
- try {
- super.runTest();
- }
- catch (Exception e) {
- if (fExpected.isAssignableFrom(e.getClass()))
- return;
- else
- throw e;
- }
- fail("Expected exception " + fExpected);
- }
-}
diff --git a/dx/src/junit/extensions/RepeatedTest.java b/dx/src/junit/extensions/RepeatedTest.java
deleted file mode 100644
index ebce77547..000000000
--- a/dx/src/junit/extensions/RepeatedTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package junit.extensions;
-
-import junit.framework.*;
-
-/**
- * A Decorator that runs a test repeatedly.
- *
- */
-public class RepeatedTest extends TestDecorator {
- private int fTimesRepeat;
-
- public RepeatedTest(Test test, int repeat) {
- super(test);
- if (repeat < 0)
- throw new IllegalArgumentException("Repetition count must be > 0");
- fTimesRepeat= repeat;
- }
- public int countTestCases() {
- return super.countTestCases()*fTimesRepeat;
- }
- public void run(TestResult result) {
- for (int i= 0; i < fTimesRepeat; i++) {
- if (result.shouldStop())
- break;
- super.run(result);
- }
- }
- public String toString() {
- return super.toString()+"(repeated)";
- }
-}
diff --git a/dx/src/junit/extensions/TestDecorator.java b/dx/src/junit/extensions/TestDecorator.java
deleted file mode 100644
index a8e9e7d46..000000000
--- a/dx/src/junit/extensions/TestDecorator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package junit.extensions;
-
-import junit.framework.*;
-
-/**
- * A Decorator for Tests. Use TestDecorator as the base class
- * for defining new test decorators. Test decorator subclasses
- * can be introduced to add behaviour before or after a test
- * is run.
- *
- */
-public class TestDecorator extends Assert implements Test {
- protected Test fTest;
-
- public TestDecorator(Test test) {
- fTest= test;
- }
- /**
- * The basic run behaviour.
- */
- public void basicRun(TestResult result) {
- fTest.run(result);
- }
- public int countTestCases() {
- return fTest.countTestCases();
- }
- public void run(TestResult result) {
- basicRun(result);
- }
-
- public String toString() {
- return fTest.toString();
- }
-
- public Test getTest() {
- return fTest;
- }
-}
diff --git a/dx/src/junit/extensions/TestSetup.java b/dx/src/junit/extensions/TestSetup.java
deleted file mode 100644
index f1c25face..000000000
--- a/dx/src/junit/extensions/TestSetup.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package junit.extensions;
-
-import junit.framework.*;
-
-/**
- * A Decorator to set up and tear down additional fixture state.
- * Subclass TestSetup and insert it into your tests when you want
- * to set up additional state once before the tests are run.
- */
-public class TestSetup extends TestDecorator {
-
- public TestSetup(Test test) {
- super(test);
- }
- public void run(final TestResult result) {
- Protectable p= new Protectable() {
- public void protect() throws Exception {
- setUp();
- basicRun(result);
- tearDown();
- }
- };
- result.runProtected(this, p);
- }
- /**
- * Sets up the fixture. Override to set up additional fixture
- * state.
- */
- protected void setUp() throws Exception {
- }
- /**
- * Tears down the fixture. Override to tear down the additional
- * fixture state.
- */
- protected void tearDown() throws Exception {
- }
-}
diff --git a/dx/src/junit/framework/Assert.java b/dx/src/junit/framework/Assert.java
deleted file mode 100644
index eb5d96042..000000000
--- a/dx/src/junit/framework/Assert.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package junit.framework;
-
-/**
- * A set of assert methods. Messages are only displayed when an assert fails.
- */
-
-public class Assert {
- /**
- * Protect constructor since it is a static only class
- */
- protected Assert() {
- }
-
- /**
- * Asserts that a condition is true. If it isn't it throws
- * an AssertionFailedError with the given message.
- */
- static public void assertTrue(String message, boolean condition) {
- if (!condition)
- fail(message);
- }
- /**
- * Asserts that a condition is true. If it isn't it throws
- * an AssertionFailedError.
- */
- static public void assertTrue(boolean condition) {
- assertTrue(null, condition);
- }
- /**
- * Asserts that a condition is false. If it isn't it throws
- * an AssertionFailedError with the given message.
- */
- static public void assertFalse(String message, boolean condition) {
- assertTrue(message, !condition);
- }
- /**
- * Asserts that a condition is false. If it isn't it throws
- * an AssertionFailedError.
- */
- static public void assertFalse(boolean condition) {
- assertFalse(null, condition);
- }
- /**
- * Fails a test with the given message.
- */
- static public void fail(String message) {
- throw new AssertionFailedError(message);
- }
- /**
- * Fails a test with no message.
- */
- static public void fail() {
- fail(null);
- }
- /**
- * Asserts that two objects are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, Object expected, Object actual) {
- if (expected == null && actual == null)
- return;
- if (expected != null && expected.equals(actual))
- return;
- failNotEquals(message, expected, actual);
- }
- /**
- * Asserts that two objects are equal. If they are not
- * an AssertionFailedError is thrown.
- */
- static public void assertEquals(Object expected, Object actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two Strings are equal.
- */
- static public void assertEquals(String message, String expected, String actual) {
- if (expected == null && actual == null)
- return;
- if (expected != null && expected.equals(actual))
- return;
- throw new ComparisonFailure(message, expected, actual);
- }
- /**
- * Asserts that two Strings are equal.
- */
- static public void assertEquals(String expected, String actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two doubles are equal concerning a delta. If they are not
- * an AssertionFailedError is thrown with the given message. If the expected
- * value is infinity then the delta value is ignored.
- */
- static public void assertEquals(String message, double expected, double actual, double delta) {
- // handle infinity specially since subtracting to infinite values gives NaN and the
- // the following test fails
- if (Double.isInfinite(expected)) {
- if (!(expected == actual))
- failNotEquals(message, new Double(expected), new Double(actual));
- } else if (!(Math.abs(expected-actual) <= delta)) // Because comparison with NaN always returns false
- failNotEquals(message, new Double(expected), new Double(actual));
- }
- /**
- * Asserts that two doubles are equal concerning a delta. If the expected
- * value is infinity then the delta value is ignored.
- */
- static public void assertEquals(double expected, double actual, double delta) {
- assertEquals(null, expected, actual, delta);
- }
- /**
- * Asserts that two floats are equal concerning a delta. If they are not
- * an AssertionFailedError is thrown with the given message. If the expected
- * value is infinity then the delta value is ignored.
- */
- static public void assertEquals(String message, float expected, float actual, float delta) {
- // handle infinity specially since subtracting to infinite values gives NaN and the
- // the following test fails
- if (Float.isInfinite(expected)) {
- if (!(expected == actual))
- failNotEquals(message, new Float(expected), new Float(actual));
- } else if (!(Math.abs(expected-actual) <= delta))
- failNotEquals(message, new Float(expected), new Float(actual));
- }
- /**
- * Asserts that two floats are equal concerning a delta. If the expected
- * value is infinity then the delta value is ignored.
- */
- static public void assertEquals(float expected, float actual, float delta) {
- assertEquals(null, expected, actual, delta);
- }
- /**
- * Asserts that two longs are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, long expected, long actual) {
- assertEquals(message, new Long(expected), new Long(actual));
- }
- /**
- * Asserts that two longs are equal.
- */
- static public void assertEquals(long expected, long actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two booleans are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, boolean expected, boolean actual) {
- assertEquals(message, new Boolean(expected), new Boolean(actual));
- }
- /**
- * Asserts that two booleans are equal.
- */
- static public void assertEquals(boolean expected, boolean actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two bytes are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, byte expected, byte actual) {
- assertEquals(message, new Byte(expected), new Byte(actual));
- }
- /**
- * Asserts that two bytes are equal.
- */
- static public void assertEquals(byte expected, byte actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two chars are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, char expected, char actual) {
- assertEquals(message, new Character(expected), new Character(actual));
- }
- /**
- * Asserts that two chars are equal.
- */
- static public void assertEquals(char expected, char actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two shorts are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, short expected, short actual) {
- assertEquals(message, new Short(expected), new Short(actual));
- }
- /**
- * Asserts that two shorts are equal.
- */
- static public void assertEquals(short expected, short actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that two ints are equal. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertEquals(String message, int expected, int actual) {
- assertEquals(message, new Integer(expected), new Integer(actual));
- }
- /**
- * Asserts that two ints are equal.
- */
- static public void assertEquals(int expected, int actual) {
- assertEquals(null, expected, actual);
- }
- /**
- * Asserts that an object isn't null.
- */
- static public void assertNotNull(Object object) {
- assertNotNull(null, object);
- }
- /**
- * Asserts that an object isn't null. If it is
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertNotNull(String message, Object object) {
- assertTrue(message, object != null);
- }
- /**
- * Asserts that an object is null.
- */
- static public void assertNull(Object object) {
- assertNull(null, object);
- }
- /**
- * Asserts that an object is null. If it is not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertNull(String message, Object object) {
- assertTrue(message, object == null);
- }
- /**
- * Asserts that two objects refer to the same object. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertSame(String message, Object expected, Object actual) {
- if (expected == actual)
- return;
- failNotSame(message, expected, actual);
- }
- /**
- * Asserts that two objects refer to the same object. If they are not
- * the same an AssertionFailedError is thrown.
- */
- static public void assertSame(Object expected, Object actual) {
- assertSame(null, expected, actual);
- }
- /**
- * Asserts that two objects refer to the same object. If they are not
- * an AssertionFailedError is thrown with the given message.
- */
- static public void assertNotSame(String message, Object expected, Object actual) {
- if (expected == actual)
- failSame(message);
- }
- /**
- * Asserts that two objects refer to the same object. If they are not
- * the same an AssertionFailedError is thrown.
- */
- static public void assertNotSame(Object expected, Object actual) {
- assertNotSame(null, expected, actual);
- }
-
- static private void failSame(String message) {
- String formatted= "";
- if (message != null)
- formatted= message+" ";
- fail(formatted+"expected not same");
- }
-
- static private void failNotSame(String message, Object expected, Object actual) {
- String formatted= "";
- if (message != null)
- formatted= message+" ";
- fail(formatted+"expected same:<"+expected+"> was not:<"+actual+">");
- }
-
- static private void failNotEquals(String message, Object expected, Object actual) {
- fail(format(message, expected, actual));
- }
-
- static String format(String message, Object expected, Object actual) {
- String formatted= "";
- if (message != null)
- formatted= message+" ";
- return formatted+"expected:<"+expected+"> but was:<"+actual+">";
- }
-}
diff --git a/dx/src/junit/framework/AssertionFailedError.java b/dx/src/junit/framework/AssertionFailedError.java
deleted file mode 100644
index 9aee0018f..000000000
--- a/dx/src/junit/framework/AssertionFailedError.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package junit.framework;
-
-/**
- * Thrown when an assertion failed.
- */
-public class AssertionFailedError extends Error {
-
- public AssertionFailedError () {
- }
- public AssertionFailedError (String message) {
- super (message);
- }
-}
diff --git a/dx/src/junit/framework/ComparisonFailure.java b/dx/src/junit/framework/ComparisonFailure.java
deleted file mode 100644
index 1bfe591c5..000000000
--- a/dx/src/junit/framework/ComparisonFailure.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package junit.framework;
-
-/**
- * Thrown when an assert equals for Strings failed.
- *
- * Inspired by a patch from Alex Chaffee mailto:alex@purpletech.com
- */
-public class ComparisonFailure extends AssertionFailedError {
- private String fExpected;
- private String fActual;
-
- /**
- * Constructs a comparison failure.
- * @param message the identifying message or null
- * @param expected the expected string value
- * @param actual the actual string value
- */
- public ComparisonFailure (String message, String expected, String actual) {
- super (message);
- fExpected= expected;
- fActual= actual;
- }
-
- /**
- * Returns "..." in place of common prefix and "..." in
- * place of common suffix between expected and actual.
- *
- * @see java.lang.Throwable#getMessage()
- */
- public String getMessage() {
- if (fExpected == null || fActual == null)
- return Assert.format(super.getMessage(), fExpected, fActual);
-
- int end= Math.min(fExpected.length(), fActual.length());
-
- int i= 0;
- for(; i < end; i++) {
- if (fExpected.charAt(i) != fActual.charAt(i))
- break;
- }
- int j= fExpected.length()-1;
- int k= fActual.length()-1;
- for (; k >= i && j >= i; k--,j--) {
- if (fExpected.charAt(j) != fActual.charAt(k))
- break;
- }
- String actual, expected;
-
- // equal strings
- if (j < i && k < i) {
- expected= fExpected;
- actual= fActual;
- } else {
- expected= fExpected.substring(i, j+1);
- actual= fActual.substring(i, k+1);
- if (i <= end && i > 0) {
- expected= "..."+expected;
- actual= "..."+actual;
- }
-
- if (j < fExpected.length()-1)
- expected= expected+"...";
- if (k < fActual.length()-1)
- actual= actual+"...";
- }
- return Assert.format(super.getMessage(), expected, actual);
- }
-}
diff --git a/dx/src/junit/framework/Protectable.java b/dx/src/junit/framework/Protectable.java
deleted file mode 100644
index 8243555a1..000000000
--- a/dx/src/junit/framework/Protectable.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package junit.framework;
-
-/**
- * A <em>Protectable</em> can be run and can throw a Throwable.
- *
- * @see TestResult
- */
-public interface Protectable {
-
- /**
- * Run the the following method protected.
- */
- public abstract void protect() throws Throwable;
-}
diff --git a/dx/src/junit/framework/Test.java b/dx/src/junit/framework/Test.java
deleted file mode 100644
index 1c6d57b36..000000000
--- a/dx/src/junit/framework/Test.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package junit.framework;
-
-/**
- * A <em>Test</em> can be run and collect its results.
- *
- * @see TestResult
- */
-public interface Test {
- /**
- * Counts the number of test cases that will be run by this test.
- */
- public abstract int countTestCases();
- /**
- * Runs a test and collects its result in a TestResult instance.
- */
- public abstract void run(TestResult result);
-}
diff --git a/dx/src/junit/framework/TestCase.java b/dx/src/junit/framework/TestCase.java
deleted file mode 100644
index 8988c45ef..000000000
--- a/dx/src/junit/framework/TestCase.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package junit.framework;
-
-import java.lang.reflect.*;
-
-/**
- * A test case defines the fixture to run multiple tests. To define a test case<br>
- * 1) implement a subclass of TestCase<br>
- * 2) define instance variables that store the state of the fixture<br>
- * 3) initialize the fixture state by overriding <code>setUp</code><br>
- * 4) clean-up after a test by overriding <code>tearDown</code>.<br>
- * Each test runs in its own fixture so there
- * can be no side effects among test runs.
- * Here is an example:
- * <pre>
- * public class MathTest extends TestCase {
- * protected double fValue1;
- * protected double fValue2;
- *
- * protected void setUp() {
- * fValue1= 2.0;
- * fValue2= 3.0;
- * }
- * }
- * </pre>
- *
- * For each test implement a method which interacts
- * with the fixture. Verify the expected results with assertions specified
- * by calling <code>assertTrue</code> with a boolean.
- * <pre>
- * public void testAdd() {
- * double result= fValue1 + fValue2;
- * assertTrue(result == 5.0);
- * }
- * </pre>
- * Once the methods are defined you can run them. The framework supports
- * both a static type safe and more dynamic way to run a test.
- * In the static way you override the runTest method and define the method to
- * be invoked. A convenient way to do so is with an anonymous inner class.
- * <pre>
- * TestCase test= new MathTest("add") {
- * public void runTest() {
- * testAdd();
- * }
- * };
- * test.run();
- * </pre>
- * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds
- * and invokes a method.
- * In this case the name of the test case has to correspond to the test method
- * to be run.
- * <pre>
- * TestCase= new MathTest("testAdd");
- * test.run();
- * </pre>
- * The tests to be run can be collected into a TestSuite. JUnit provides
- * different <i>test runners</i> which can run a test suite and collect the results.
- * A test runner either expects a static method <code>suite</code> as the entry
- * point to get a test to run or it will extract the suite automatically.
- * <pre>
- * public static Test suite() {
- * suite.addTest(new MathTest("testAdd"));
- * suite.addTest(new MathTest("testDivideByZero"));
- * return suite;
- * }
- * </pre>
- * @see TestResult
- * @see TestSuite
- */
-
-public abstract class TestCase extends Assert implements Test {
- /**
- * the name of the test case
- */
- private String fName;
-
- /**
- * No-arg constructor to enable serialization. This method
- * is not intended to be used by mere mortals without calling setName().
- */
- public TestCase() {
- fName= null;
- }
- /**
- * Constructs a test case with the given name.
- */
- public TestCase(String name) {
- fName= name;
- }
- /**
- * Counts the number of test cases executed by run(TestResult result).
- */
- public int countTestCases() {
- return 1;
- }
- /**
- * Creates a default TestResult object
- *
- * @see TestResult
- */
- protected TestResult createResult() {
- return new TestResult();
- }
- /**
- * A convenience method to run this test, collecting the results with a
- * default TestResult object.
- *
- * @see TestResult
- */
- public TestResult run() {
- TestResult result= createResult();
- run(result);
- return result;
- }
- /**
- * Runs the test case and collects the results in TestResult.
- */
- public void run(TestResult result) {
- result.run(this);
- }
- /**
- * Runs the bare test sequence.
- * @exception Throwable if any exception is thrown
- */
- public void runBare() throws Throwable {
- setUp();
- try {
- runTest();
- }
- finally {
- tearDown();
- }
- }
- /**
- * Override to run the test and assert its state.
- * @exception Throwable if any exception is thrown
- */
- protected void runTest() throws Throwable {
- assertNotNull(fName);
- Method runMethod= null;
- try {
- // use getMethod to get all public inherited
- // methods. getDeclaredMethods returns all
- // methods of this class but excludes the
- // inherited ones.
- runMethod= getClass().getMethod(fName, (Class[]) null);
- } catch (NoSuchMethodException e) {
- fail("Method \""+fName+"\" not found");
- }
- if (!Modifier.isPublic(runMethod.getModifiers())) {
- fail("Method \""+fName+"\" should be public");
- }
-
- try {
- runMethod.invoke(this, (Object[]) new Class[0]);
- }
- catch (InvocationTargetException e) {
- e.fillInStackTrace();
- throw e.getTargetException();
- }
- catch (IllegalAccessException e) {
- e.fillInStackTrace();
- throw e;
- }
- }
- /**
- * Sets up the fixture, for example, open a network connection.
- * This method is called before a test is executed.
- */
- protected void setUp() throws Exception {
- }
- /**
- * Tears down the fixture, for example, close a network connection.
- * This method is called after a test is executed.
- */
- protected void tearDown() throws Exception {
- }
- /**
- * Returns a string representation of the test case
- */
- public String toString() {
- return getName() + "(" + getClass().getName() + ")";
- }
- /**
- * Gets the name of a TestCase
- * @return returns a String
- */
- public String getName() {
- return fName;
- }
- /**
- * Sets the name of a TestCase
- * @param name The name to set
- */
- public void setName(String name) {
- fName= name;
- }
-}
diff --git a/dx/src/junit/framework/TestFailure.java b/dx/src/junit/framework/TestFailure.java
deleted file mode 100644
index 664747d81..000000000
--- a/dx/src/junit/framework/TestFailure.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package junit.framework;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-
-/**
- * A <code>TestFailure</code> collects a failed test together with
- * the caught exception.
- * @see TestResult
- */
-public class TestFailure extends Object {
- protected Test fFailedTest;
- protected Throwable fThrownException;
-
-
- /**
- * Constructs a TestFailure with the given test and exception.
- */
- public TestFailure(Test failedTest, Throwable thrownException) {
- fFailedTest= failedTest;
- fThrownException= thrownException;
- }
- /**
- * Gets the failed test.
- */
- public Test failedTest() {
- return fFailedTest;
- }
- /**
- * Gets the thrown exception.
- */
- public Throwable thrownException() {
- return fThrownException;
- }
- /**
- * Returns a short description of the failure.
- */
- public String toString() {
- StringBuffer buffer= new StringBuffer();
- buffer.append(fFailedTest+": "+fThrownException.getMessage());
- return buffer.toString();
- }
- public String trace() {
- StringWriter stringWriter= new StringWriter();
- PrintWriter writer= new PrintWriter(stringWriter);
- thrownException().printStackTrace(writer);
- StringBuffer buffer= stringWriter.getBuffer();
- return buffer.toString();
- }
- public String exceptionMessage() {
- return thrownException().getMessage();
- }
- public boolean isFailure() {
- return thrownException() instanceof AssertionFailedError;
- }
-}
diff --git a/dx/src/junit/framework/TestListener.java b/dx/src/junit/framework/TestListener.java
deleted file mode 100644
index 755818752..000000000
--- a/dx/src/junit/framework/TestListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package junit.framework;
-
-/**
- * A Listener for test progress
- */
-public interface TestListener {
- /**
- * An error occurred.
- */
- public void addError(Test test, Throwable t);
- /**
- * A failure occurred.
- */
- public void addFailure(Test test, AssertionFailedError t);
- /**
- * A test ended.
- */
- public void endTest(Test test);
- /**
- * A test started.
- */
- public void startTest(Test test);
-}
diff --git a/dx/src/junit/framework/TestResult.java b/dx/src/junit/framework/TestResult.java
deleted file mode 100644
index 4b1a7e2ed..000000000
--- a/dx/src/junit/framework/TestResult.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package junit.framework;
-
-import java.util.Vector;
-import java.util.Enumeration;
-
-/**
- * A <code>TestResult</code> collects the results of executing
- * a test case. It is an instance of the Collecting Parameter pattern.
- * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
- * A failure is anticipated and checked for with assertions. Errors are
- * unanticipated problems like an <code>ArrayIndexOutOfBoundsException</code>.
- *
- * @see Test
- */
-public class TestResult extends Object {
- protected Vector<TestFailure> fFailures;
- protected Vector<TestFailure> fErrors;
- protected Vector<TestListener> fListeners;
- protected int fRunTests;
- private boolean fStop;
-
- public TestResult() {
- fFailures= new Vector<TestFailure>();
- fErrors= new Vector<TestFailure>();
- fListeners= new Vector<TestListener>();
- fRunTests= 0;
- fStop= false;
- }
- /**
- * Adds an error to the list of errors. The passed in exception
- * caused the error.
- */
- public synchronized void addError(Test test, Throwable t) {
- fErrors.addElement(new TestFailure(test, t));
- for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
- ((TestListener)e.nextElement()).addError(test, t);
- }
- }
- /**
- * Adds a failure to the list of failures. The passed in exception
- * caused the failure.
- */
- public synchronized void addFailure(Test test, AssertionFailedError t) {
- fFailures.addElement(new TestFailure(test, t));
- for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
- ((TestListener)e.nextElement()).addFailure(test, t);
- }
- }
- /**
- * Registers a TestListener
- */
- public synchronized void addListener(TestListener listener) {
- fListeners.addElement(listener);
- }
- /**
- * Unregisters a TestListener
- */
- public synchronized void removeListener(TestListener listener) {
- fListeners.removeElement(listener);
- }
- /**
- * Returns a copy of the listeners.
- */
- private synchronized Vector cloneListeners() {
- return (Vector)fListeners.clone();
- }
- /**
- * Informs the result that a test was completed.
- */
- public void endTest(Test test) {
- for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
- ((TestListener)e.nextElement()).endTest(test);
- }
- }
- /**
- * Gets the number of detected errors.
- */
- public synchronized int errorCount() {
- return fErrors.size();
- }
- /**
- * Returns an Enumeration for the errors
- */
- public synchronized Enumeration errors() {
- return fErrors.elements();
- }
- /**
- * Gets the number of detected failures.
- */
- public synchronized int failureCount() {
- return fFailures.size();
- }
- /**
- * Returns an Enumeration for the failures
- */
- public synchronized Enumeration failures() {
- return fFailures.elements();
- }
- /**
- * Runs a TestCase.
- */
- protected void run(final TestCase test) {
- startTest(test);
- Protectable p= new Protectable() {
- public void protect() throws Throwable {
- test.runBare();
- }
- };
- runProtected(test, p);
-
- endTest(test);
- }
- /**
- * Gets the number of run tests.
- */
- public synchronized int runCount() {
- return fRunTests;
- }
- /**
- * Runs a TestCase.
- */
- public void runProtected(final Test test, Protectable p) {
- try {
- p.protect();
- }
- catch (AssertionFailedError e) {
- addFailure(test, e);
- }
- catch (ThreadDeath e) { // don't catch ThreadDeath by accident
- throw e;
- }
- catch (Throwable e) {
- addError(test, e);
- }
- }
- /**
- * Checks whether the test run should stop
- */
- public synchronized boolean shouldStop() {
- return fStop;
- }
- /**
- * Informs the result that a test will be started.
- */
- public void startTest(Test test) {
- final int count= test.countTestCases();
- synchronized(this) {
- fRunTests+= count;
- }
- for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
- ((TestListener)e.nextElement()).startTest(test);
- }
- }
- /**
- * Marks that the test run should stop.
- */
- public synchronized void stop() {
- fStop= true;
- }
- /**
- * Returns whether the entire test was successful or not.
- */
- public synchronized boolean wasSuccessful() {
- return failureCount() == 0 && errorCount() == 0;
- }
-}
diff --git a/dx/src/junit/framework/TestSuite.java b/dx/src/junit/framework/TestSuite.java
deleted file mode 100644
index 2987ad12c..000000000
--- a/dx/src/junit/framework/TestSuite.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package junit.framework;
-
-import java.util.Vector;
-import java.util.Enumeration;
-import java.io.PrintWriter;import java.io.StringWriter;import java.lang.reflect.*;
-import java.lang.reflect.Constructor;
-
-/**
- * A <code>TestSuite</code> is a <code>Composite</code> of Tests.
- * It runs a collection of test cases. Here is an example using
- * the dynamic test definition.
- * <pre>
- * TestSuite suite= new TestSuite();
- * suite.addTest(new MathTest("testAdd"));
- * suite.addTest(new MathTest("testDivideByZero"));
- * </pre>
- * Alternatively, a TestSuite can extract the tests to be run automatically.
- * To do so you pass the class of your TestCase class to the
- * TestSuite constructor.
- * <pre>
- * TestSuite suite= new TestSuite(MathTest.class);
- * </pre>
- * This constructor creates a suite with all the methods
- * starting with "test" that take no arguments.
- *
- * @see Test
- */
-public class TestSuite implements Test {
-
- private Vector<Test> fTests= new Vector<Test>(10);
- private String fName;
-
- /**
- * Constructs an empty TestSuite.
- */
- public TestSuite() {
- }
-
- /**
- * Constructs a TestSuite from the given class with the given name.
- * @see TestSuite#TestSuite(Class)
- */
- public TestSuite(Class theClass, String name) {
- this(theClass);
- setName(name);
- }
-
- /**
- * Constructs a TestSuite from the given class. Adds all the methods
- * starting with "test" as test cases to the suite.
- * Parts of this method was written at 2337 meters in the Huffihutte,
- * Kanton Uri
- */
- public TestSuite(final Class theClass) {
- fName= theClass.getName();
- try {
- getTestConstructor(theClass); // Avoid generating multiple error messages
- } catch (NoSuchMethodException e) {
- addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
- return;
- }
-
- if (!Modifier.isPublic(theClass.getModifiers())) {
- addTest(warning("Class "+theClass.getName()+" is not public"));
- return;
- }
-
- Class superClass= theClass;
- Vector<String> names= new Vector<String>();
- while (Test.class.isAssignableFrom(superClass)) {
- Method[] methods= superClass.getDeclaredMethods();
- for (int i= 0; i < methods.length; i++) {
- addTestMethod(methods[i], names, theClass);
- }
- superClass= superClass.getSuperclass();
- }
- if (fTests.size() == 0)
- addTest(warning("No tests found in "+theClass.getName()));
- }
-
- /**
- * Constructs an empty TestSuite.
- */
- public TestSuite(String name) {
- setName(name);
- }
-
- /**
- * Adds a test to the suite.
- */
- public void addTest(Test test) {
- fTests.addElement(test);
- }
-
- /**
- * Adds the tests from the given class to the suite
- */
- public void addTestSuite(Class testClass) {
- addTest(new TestSuite(testClass));
- }
-
- private void addTestMethod(Method m, Vector<String> names, Class theClass) {
- String name= m.getName();
- if (names.contains(name))
- return;
- if (! isPublicTestMethod(m)) {
- if (isTestMethod(m))
- addTest(warning("Test method isn't public: "+m.getName()));
- return;
- }
- names.addElement(name);
- addTest(createTest(theClass, name));
- }
-
- /**
- * ...as the moon sets over the early morning Merlin, Oregon
- * mountains, our intrepid adventurers type...
- */
- static public Test createTest(Class theClass, String name) {
- Constructor constructor;
- try {
- constructor= getTestConstructor(theClass);
- } catch (NoSuchMethodException e) {
- return warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()");
- }
- Object test;
- try {
- if (constructor.getParameterTypes().length == 0) {
- test= constructor.newInstance(new Object[0]);
- if (test instanceof TestCase)
- ((TestCase) test).setName(name);
- } else {
- test= constructor.newInstance(new Object[]{name});
- }
- } catch (InstantiationException e) {
- return(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
- } catch (InvocationTargetException e) {
- return(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
- } catch (IllegalAccessException e) {
- return(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
- }
- return (Test) test;
- }
-
- /**
- * Converts the stack trace into a string
- */
- private static String exceptionToString(Throwable t) {
- StringWriter stringWriter= new StringWriter();
- PrintWriter writer= new PrintWriter(stringWriter);
- t.printStackTrace(writer);
- return stringWriter.toString();
-
- }
-
- /**
- * Counts the number of test cases that will be run by this test.
- */
- public int countTestCases() {
- int count= 0;
- for (Enumeration e= tests(); e.hasMoreElements(); ) {
- Test test= (Test)e.nextElement();
- count= count + test.countTestCases();
- }
- return count;
- }
-
- /**
- * Gets a constructor which takes a single String as
- * its argument or a no arg constructor.
- */
- public static Constructor getTestConstructor(Class theClass) throws NoSuchMethodException {
- Class[] args= { String.class };
- try {
- return theClass.getConstructor(args);
- } catch (NoSuchMethodException e) {
- // fall through
- }
- return theClass.getConstructor(new Class[0]);
- }
-
- private boolean isPublicTestMethod(Method m) {
- return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
- }
-
- private boolean isTestMethod(Method m) {
- String name= m.getName();
- Class[] parameters= m.getParameterTypes();
- Class returnType= m.getReturnType();
- return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
- }
-
- /**
- * Runs the tests and collects their result in a TestResult.
- */
- public void run(TestResult result) {
- for (Enumeration e= tests(); e.hasMoreElements(); ) {
- if (result.shouldStop() )
- break;
- Test test= (Test)e.nextElement();
- runTest(test, result);
- }
- }
-
- public void runTest(Test test, TestResult result) {
- test.run(result);
- }
-
- /**
- * Returns the test at the given index
- */
- public Test testAt(int index) {
- return (Test)fTests.elementAt(index);
- }
-
- /**
- * Returns the number of tests in this suite
- */
- public int testCount() {
- return fTests.size();
- }
-
- /**
- * Returns the tests as an enumeration
- */
- public Enumeration tests() {
- return fTests.elements();
- }
-
- /**
- */
- public String toString() {
- if (getName() != null)
- return getName();
- return super.toString();
- }
-
- /**
- * Sets the name of the suite.
- * @param name The name to set
- */
- public void setName(String name) {
- fName= name;
- }
-
- /**
- * Returns the name of the suite. Not all
- * test suites have a name and this method
- * can return null.
- */
- public String getName() {
- return fName;
- }
-
- /**
- * Returns a test which will fail and log a warning message.
- */
- private static Test warning(final String message) {
- return new TestCase("warning") {
- protected void runTest() {
- fail(message);
- }
- };
- }
-}
diff --git a/dx/src/junit/runner/BaseTestRunner.java b/dx/src/junit/runner/BaseTestRunner.java
deleted file mode 100644
index 39c8c2f98..000000000
--- a/dx/src/junit/runner/BaseTestRunner.java
+++ /dev/null
@@ -1,323 +0,0 @@
-package junit.runner;
-
-import junit.framework.*;
-import java.lang.reflect.*;
-import java.text.NumberFormat;
-import java.io.*;
-import java.util.*;
-
-/**
- * Base class for all test runners.
- * This class was born live on stage in Sardinia during XP2000.
- */
-public abstract class BaseTestRunner implements TestListener {
- public static final String SUITE_METHODNAME= "suite";
-
- private static Properties fPreferences;
- static int fgMaxMessageLength= 500;
- static boolean fgFilterStack= true;
- boolean fLoading= true;
-
- /*
- * Implementation of TestListener
- */
- public synchronized void startTest(Test test) {
- testStarted(test.toString());
- }
-
- protected static void setPreferences(Properties preferences) {
- fPreferences= preferences;
- }
-
- protected static Properties getPreferences() {
- if (fPreferences == null) {
- fPreferences= new Properties();
- fPreferences.put("loading", "true");
- fPreferences.put("filterstack", "true");
- readPreferences();
- }
- return fPreferences;
- }
-
- public static void savePreferences() throws IOException {
- FileOutputStream fos= new FileOutputStream(getPreferencesFile());
- try {
- getPreferences().store(fos, "");
- } finally {
- fos.close();
- }
- }
-
- public void setPreference(String key, String value) {
- getPreferences().setProperty(key, value);
- }
-
- public synchronized void endTest(Test test) {
- testEnded(test.toString());
- }
-
- public synchronized void addError(final Test test, final Throwable t) {
- testFailed(TestRunListener.STATUS_ERROR, test, t);
- }
-
- public synchronized void addFailure(final Test test, final AssertionFailedError t) {
- testFailed(TestRunListener.STATUS_FAILURE, test, t);
- }
-
- // TestRunListener implementation
-
- public abstract void testStarted(String testName);
-
- public abstract void testEnded(String testName);
-
- public abstract void testFailed(int status, Test test, Throwable t);
-
- /**
- * Returns the Test corresponding to the given suite. This is
- * a template method, subclasses override runFailed(), clearStatus().
- */
- public Test getTest(String suiteClassName) {
- if (suiteClassName.length() <= 0) {
- clearStatus();
- return null;
- }
- Class testClass= null;
- try {
- testClass= loadSuiteClass(suiteClassName);
- } catch (ClassNotFoundException e) {
- String clazz= e.getMessage();
- if (clazz == null)
- clazz= suiteClassName;
- runFailed("Class not found \""+clazz+"\"");
- return null;
- } catch(Exception e) {
- runFailed("Error: "+e.toString());
- return null;
- }
- Method suiteMethod= null;
- try {
- suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
- } catch(Exception e) {
- // try to extract a test suite automatically
- clearStatus();
- return new TestSuite(testClass);
- }
- if (! Modifier.isStatic(suiteMethod.getModifiers())) {
- runFailed("Suite() method must be static");
- return null;
- }
- Test test= null;
- try {
- test= (Test)suiteMethod.invoke(null, (Object[]) new Class[0]); // static method
- if (test == null)
- return test;
- }
- catch (InvocationTargetException e) {
- runFailed("Failed to invoke suite():" + e.getTargetException().toString());
- return null;
- }
- catch (IllegalAccessException e) {
- runFailed("Failed to invoke suite():" + e.toString());
- return null;
- }
-
- clearStatus();
- return test;
- }
-
- /**
- * Returns the formatted string of the elapsed time.
- */
- public String elapsedTimeAsString(long runTime) {
- return NumberFormat.getInstance().format((double)runTime/1000);
- }
-
- /**
- * Processes the command line arguments and
- * returns the name of the suite class to run or null
- */
- protected String processArguments(String[] args) {
- String suiteName= null;
- for (int i= 0; i < args.length; i++) {
- if (args[i].equals("-noloading")) {
- setLoading(false);
- } else if (args[i].equals("-nofilterstack")) {
- fgFilterStack= false;
- } else if (args[i].equals("-c")) {
- if (args.length > i+1)
- suiteName= extractClassName(args[i+1]);
- else
- System.out.println("Missing Test class name");
- i++;
- } else {
- suiteName= args[i];
- }
- }
- return suiteName;
- }
-
- /**
- * Sets the loading behaviour of the test runner
- */
- public void setLoading(boolean enable) {
- fLoading= enable;
- }
- /**
- * Extract the class name from a String in VA/Java style
- */
- public String extractClassName(String className) {
- if(className.startsWith("Default package for"))
- return className.substring(className.lastIndexOf(".")+1);
- return className;
- }
-
- /**
- * Truncates a String to the maximum length.
- */
- public static String truncate(String s) {
- if (fgMaxMessageLength != -1 && s.length() > fgMaxMessageLength)
- s= s.substring(0, fgMaxMessageLength)+"...";
- return s;
- }
-
- /**
- * Override to define how to handle a failed loading of
- * a test suite.
- */
- protected abstract void runFailed(String message);
-
- /**
- * Returns the loaded Class for a suite name.
- */
- protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
- return getLoader().load(suiteClassName);
- }
-
- /**
- * Clears the status message.
- */
- protected void clearStatus() { // Belongs in the GUI TestRunner class
- }
-
- /**
- * Returns the loader to be used.
- */
- public TestSuiteLoader getLoader() {
- if (useReloadingTestSuiteLoader())
- return new ReloadingTestSuiteLoader();
- return new StandardTestSuiteLoader();
- }
-
- protected boolean useReloadingTestSuiteLoader() {
- return getPreference("loading").equals("true") && !inVAJava() && fLoading;
- }
-
- private static File getPreferencesFile() {
- String home= System.getProperty("user.home");
- return new File(home, "junit.properties");
- }
-
- private static void readPreferences() {
- InputStream is= null;
- try {
- is= new FileInputStream(getPreferencesFile());
- setPreferences(new Properties(getPreferences()));
- getPreferences().load(is);
- } catch (IOException e) {
- try {
- if (is != null)
- is.close();
- } catch (IOException e1) {
- }
- }
- }
-
- public static String getPreference(String key) {
- return getPreferences().getProperty(key);
- }
-
- public static int getPreference(String key, int dflt) {
- String value= getPreference(key);
- int intValue= dflt;
- if (value == null)
- return intValue;
- try {
- intValue= Integer.parseInt(value);
- } catch (NumberFormatException ne) {
- }
- return intValue;
- }
-
- public static boolean inVAJava() {
- try {
- Class.forName("com.ibm.uvm.tools.DebugSupport");
- }
- catch (Exception e) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns a filtered stack trace
- */
- public static String getFilteredTrace(Throwable t) {
- StringWriter stringWriter= new StringWriter();
- PrintWriter writer= new PrintWriter(stringWriter);
- t.printStackTrace(writer);
- StringBuffer buffer= stringWriter.getBuffer();
- String trace= buffer.toString();
- return BaseTestRunner.getFilteredTrace(trace);
- }
-
- /**
- * Filters stack frames from internal JUnit classes
- */
- public static String getFilteredTrace(String stack) {
- if (showStackRaw())
- return stack;
-
- StringWriter sw= new StringWriter();
- PrintWriter pw= new PrintWriter(sw);
- StringReader sr= new StringReader(stack);
- BufferedReader br= new BufferedReader(sr);
-
- String line;
- try {
- while ((line= br.readLine()) != null) {
- if (!filterLine(line))
- pw.println(line);
- }
- } catch (Exception IOException) {
- return stack; // return the stack unfiltered
- }
- return sw.toString();
- }
-
- protected static boolean showStackRaw() {
- return !getPreference("filterstack").equals("true") || fgFilterStack == false;
- }
-
- static boolean filterLine(String line) {
- String[] patterns= new String[] {
- "junit.framework.TestCase",
- "junit.framework.TestResult",
- "junit.framework.TestSuite",
- "junit.framework.Assert.", // don't filter AssertionFailure
- "junit.swingui.TestRunner",
- "junit.awtui.TestRunner",
- "junit.textui.TestRunner",
- "java.lang.reflect.Method.invoke("
- };
- for (int i= 0; i < patterns.length; i++) {
- if (line.indexOf(patterns[i]) > 0)
- return true;
- }
- return false;
- }
-
- static {
- fgMaxMessageLength= getPreference("maxmessage", fgMaxMessageLength);
- }
-
-}
diff --git a/dx/src/junit/runner/ClassPathTestCollector.java b/dx/src/junit/runner/ClassPathTestCollector.java
deleted file mode 100644
index 24bf1e998..000000000
--- a/dx/src/junit/runner/ClassPathTestCollector.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package junit.runner;
-
-import java.util.*;
-import java.io.*;
-
-/**
- * An implementation of a TestCollector that consults the
- * class path. It considers all classes on the class path
- * excluding classes in JARs. It leaves it up to subclasses
- * to decide whether a class is a runnable Test.
- *
- * @see TestCollector
- */
-public abstract class ClassPathTestCollector implements TestCollector {
-
- static final int SUFFIX_LENGTH= ".class".length();
-
- public ClassPathTestCollector() {
- }
-
- public Enumeration collectTests() {
- String classPath= System.getProperty("java.class.path");
- Hashtable result = collectFilesInPath(classPath);
- return result.elements();
- }
-
- public Hashtable collectFilesInPath(String classPath) {
- Hashtable result= collectFilesInRoots(splitClassPath(classPath));
- return result;
- }
-
- Hashtable collectFilesInRoots(Vector roots) {
- Hashtable<String,String> result= new Hashtable<String,String>(100);
- Enumeration e= roots.elements();
- while (e.hasMoreElements())
- gatherFiles(new File((String)e.nextElement()), "", result);
- return result;
- }
-
- void gatherFiles(File classRoot, String classFileName, Hashtable<String,String> result) {
- File thisRoot= new File(classRoot, classFileName);
- if (thisRoot.isFile()) {
- if (isTestClass(classFileName)) {
- String className= classNameFromFile(classFileName);
- result.put(className, className);
- }
- return;
- }
- String[] contents= thisRoot.list();
- if (contents != null) {
- for (int i= 0; i < contents.length; i++)
- gatherFiles(classRoot, classFileName+File.separatorChar+contents[i], result);
- }
- }
-
- Vector splitClassPath(String classPath) {
- Vector<String> result= new Vector<String>();
- String separator= System.getProperty("path.separator");
- StringTokenizer tokenizer= new StringTokenizer(classPath, separator);
- while (tokenizer.hasMoreTokens())
- result.addElement(tokenizer.nextToken());
- return result;
- }
-
- protected boolean isTestClass(String classFileName) {
- return
- classFileName.endsWith(".class") &&
- classFileName.indexOf('$') < 0 &&
- classFileName.indexOf("Test") > 0;
- }
-
- protected String classNameFromFile(String classFileName) {
- // convert /a/b.class to a.b
- String s= classFileName.substring(0, classFileName.length()-SUFFIX_LENGTH);
- String s2= s.replace(File.separatorChar, '.');
- if (s2.startsWith("."))
- return s2.substring(1);
- return s2;
- }
-}
diff --git a/dx/src/junit/runner/FailureDetailView.java b/dx/src/junit/runner/FailureDetailView.java
deleted file mode 100644
index 762326b3f..000000000
--- a/dx/src/junit/runner/FailureDetailView.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package junit.runner;
-
-import java.awt.Component;
-
-import junit.framework.*;
-
-/**
- * A view to show a details about a failure
- */
-public interface FailureDetailView {
- /**
- * Returns the component used to present the TraceView
- */
- public Component getComponent();
- /**
- * Shows details of a TestFailure
- */
- public void showFailure(TestFailure failure);
- /**
- * Clears the view
- */
- public void clear();
-}
diff --git a/dx/src/junit/runner/LoadingTestCollector.java b/dx/src/junit/runner/LoadingTestCollector.java
deleted file mode 100644
index b13835930..000000000
--- a/dx/src/junit/runner/LoadingTestCollector.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package junit.runner;
-
-import java.lang.reflect.*;
-import junit.runner.*;
-import junit.framework.*;
-
-/**
- * An implementation of a TestCollector that loads
- * all classes on the class path and tests whether
- * it is assignable from Test or provides a static suite method.
- * @see TestCollector
- */
-public class LoadingTestCollector extends ClassPathTestCollector {
-
- TestCaseClassLoader fLoader;
-
- public LoadingTestCollector() {
- fLoader= new TestCaseClassLoader();
- }
-
- protected boolean isTestClass(String classFileName) {
- try {
- if (classFileName.endsWith(".class")) {
- Class testClass= classFromFile(classFileName);
- return (testClass != null) && isTestClass(testClass);
- }
- }
- catch (ClassNotFoundException expected) {
- }
- catch (NoClassDefFoundError notFatal) {
- }
- return false;
- }
-
- Class classFromFile(String classFileName) throws ClassNotFoundException {
- String className= classNameFromFile(classFileName);
- if (!fLoader.isExcluded(className))
- return fLoader.loadClass(className, false);
- return null;
- }
-
- boolean isTestClass(Class testClass) {
- if (hasSuiteMethod(testClass))
- return true;
- if (Test.class.isAssignableFrom(testClass) &&
- Modifier.isPublic(testClass.getModifiers()) &&
- hasPublicConstructor(testClass))
- return true;
- return false;
- }
-
- boolean hasSuiteMethod(Class testClass) {
- try {
- testClass.getMethod(BaseTestRunner.SUITE_METHODNAME, new Class[0]);
- } catch(Exception e) {
- return false;
- }
- return true;
- }
-
- boolean hasPublicConstructor(Class testClass) {
- try {
- TestSuite.getTestConstructor(testClass);
- } catch(NoSuchMethodException e) {
- return false;
- }
- return true;
- }
-}
diff --git a/dx/src/junit/runner/ReloadingTestSuiteLoader.java b/dx/src/junit/runner/ReloadingTestSuiteLoader.java
deleted file mode 100644
index f7ef919cc..000000000
--- a/dx/src/junit/runner/ReloadingTestSuiteLoader.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package junit.runner;
-
-/**
- * A TestSuite loader that can reload classes.
- */
-public class ReloadingTestSuiteLoader implements TestSuiteLoader {
-
- public Class load(String suiteClassName) throws ClassNotFoundException {
- return createLoader().loadClass(suiteClassName, true);
- }
-
- public Class reload(Class aClass) throws ClassNotFoundException {
- return createLoader().loadClass(aClass.getName(), true);
- }
-
- protected TestCaseClassLoader createLoader() {
- return new TestCaseClassLoader();
- }
-}
diff --git a/dx/src/junit/runner/SimpleTestCollector.java b/dx/src/junit/runner/SimpleTestCollector.java
deleted file mode 100644
index 9d1956ad2..000000000
--- a/dx/src/junit/runner/SimpleTestCollector.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package junit.runner;
-
-/**
- * An implementation of a TestCollector that considers
- * a class to be a test class when it contains the
- * pattern "Test" in its name
- * @see TestCollector
- */
-public class SimpleTestCollector extends ClassPathTestCollector {
-
- public SimpleTestCollector() {
- }
-
- protected boolean isTestClass(String classFileName) {
- return
- classFileName.endsWith(".class") &&
- classFileName.indexOf('$') < 0 &&
- classFileName.indexOf("Test") > 0;
- }
-}
diff --git a/dx/src/junit/runner/Sorter.java b/dx/src/junit/runner/Sorter.java
deleted file mode 100644
index e614ab47e..000000000
--- a/dx/src/junit/runner/Sorter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package junit.runner;
-
-import java.util.*;
-
-import junit.runner.*;
-
-/**
- * A custom quick sort with support to customize the swap behaviour.
- * NOTICE: We can't use the the sorting support from the JDK 1.2 collection
- * classes because of the JDK 1.1.7 compatibility.
- */
-public class Sorter {
- public static interface Swapper {
- public void swap(Vector values, int left, int right);
- }
-
- public static void sortStrings(Vector values , int left, int right, Swapper swapper) {
- int oleft= left;
- int oright= right;
- String mid= (String)values.elementAt((left + right) / 2);
- do {
- while (((String)(values.elementAt(left))).compareTo(mid) < 0)
- left++;
- while (mid.compareTo((String)(values.elementAt(right))) < 0)
- right--;
- if (left <= right) {
- swapper.swap(values, left, right);
- left++;
- right--;
- }
- } while (left <= right);
-
- if (oleft < right)
- sortStrings(values, oleft, right, swapper);
- if (left < oright)
- sortStrings(values, left, oright, swapper);
- }
-}
diff --git a/dx/src/junit/runner/StandardTestSuiteLoader.java b/dx/src/junit/runner/StandardTestSuiteLoader.java
deleted file mode 100644
index e2bd765ee..000000000
--- a/dx/src/junit/runner/StandardTestSuiteLoader.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package junit.runner;
-
-/**
- * The standard test suite loader. It can only load the same class once.
- */
-public class StandardTestSuiteLoader implements TestSuiteLoader {
- /**
- * Uses the system class loader to load the test class
- */
- public Class load(String suiteClassName) throws ClassNotFoundException {
- return Class.forName(suiteClassName);
- }
- /**
- * Uses the system class loader to load the test class
- */
- public Class reload(Class aClass) throws ClassNotFoundException {
- return aClass;
- }
-}
diff --git a/dx/src/junit/runner/TestCaseClassLoader.java b/dx/src/junit/runner/TestCaseClassLoader.java
deleted file mode 100644
index 543641a85..000000000
--- a/dx/src/junit/runner/TestCaseClassLoader.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package junit.runner;
-
-import java.util.*;
-import java.io.*;
-import java.net.URL;
-import java.util.zip.*;
-
-/**
- * A custom class loader which enables the reloading
- * of classes for each test run. The class loader
- * can be configured with a list of package paths that
- * should be excluded from loading. The loading
- * of these packages is delegated to the system class
- * loader. They will be shared across test runs.
- * <p>
- * The list of excluded package paths is specified in
- * a properties file "excluded.properties" that is located in
- * the same place as the TestCaseClassLoader class.
- * <p>
- * <b>Known limitation:</b> the TestCaseClassLoader cannot load classes
- * from jar files.
- */
-
-
-public class TestCaseClassLoader extends ClassLoader {
- /** scanned class path */
- private Vector<String> fPathItems;
- /** default excluded paths */
- private String[] defaultExclusions= {
- "junit.framework.",
- "junit.extensions.",
- "junit.runner."
- };
- /** name of excluded properties file */
- static final String EXCLUDED_FILE= "excluded.properties";
- /** excluded paths */
- private Vector<String> fExcluded;
-
- /**
- * Constructs a TestCaseLoader. It scans the class path
- * and the excluded package paths
- */
- public TestCaseClassLoader() {
- this(System.getProperty("java.class.path"));
- }
-
- /**
- * Constructs a TestCaseLoader. It scans the class path
- * and the excluded package paths
- */
- public TestCaseClassLoader(String classPath) {
- scanPath(classPath);
- readExcludedPackages();
- }
-
- private void scanPath(String classPath) {
- String separator= System.getProperty("path.separator");
- fPathItems= new Vector<String>(10);
- StringTokenizer st= new StringTokenizer(classPath, separator);
- while (st.hasMoreTokens()) {
- fPathItems.addElement(st.nextToken());
- }
- }
-
- public URL getResource(String name) {
- return ClassLoader.getSystemResource(name);
- }
-
- public InputStream getResourceAsStream(String name) {
- return ClassLoader.getSystemResourceAsStream(name);
- }
-
- public boolean isExcluded(String name) {
- for (int i= 0; i < fExcluded.size(); i++) {
- if (name.startsWith((String) fExcluded.elementAt(i))) {
- return true;
- }
- }
- return false;
- }
-
- public synchronized Class loadClass(String name, boolean resolve)
- throws ClassNotFoundException {
-
- Class c= findLoadedClass(name);
- if (c != null)
- return c;
- //
- // Delegate the loading of excluded classes to the
- // standard class loader.
- //
- if (isExcluded(name)) {
- try {
- c= findSystemClass(name);
- return c;
- } catch (ClassNotFoundException e) {
- // keep searching
- }
- }
- if (c == null) {
- byte[] data= lookupClassData(name);
- if (data == null)
- throw new ClassNotFoundException();
- c= defineClass(name, data, 0, data.length);
- }
- if (resolve)
- resolveClass(c);
- return c;
- }
-
- private byte[] lookupClassData(String className) throws ClassNotFoundException {
- byte[] data= null;
- for (int i= 0; i < fPathItems.size(); i++) {
- String path= (String) fPathItems.elementAt(i);
- String fileName= className.replace('.', '/')+".class";
- if (isJar(path)) {
- data= loadJarData(path, fileName);
- } else {
- data= loadFileData(path, fileName);
- }
- if (data != null)
- return data;
- }
- throw new ClassNotFoundException(className);
- }
-
- boolean isJar(String pathEntry) {
- return pathEntry.endsWith(".jar") ||
- pathEntry.endsWith(".zip") ||
- pathEntry.endsWith(".apk");
- }
-
- private byte[] loadFileData(String path, String fileName) {
- File file= new File(path, fileName);
- if (file.exists()) {
- return getClassData(file);
- }
- return null;
- }
-
- private byte[] getClassData(File f) {
- try {
- FileInputStream stream= new FileInputStream(f);
- ByteArrayOutputStream out= new ByteArrayOutputStream(1000);
- byte[] b= new byte[1000];
- int n;
- while ((n= stream.read(b)) != -1)
- out.write(b, 0, n);
- stream.close();
- out.close();
- return out.toByteArray();
-
- } catch (IOException e) {
- }
- return null;
- }
-
- private byte[] loadJarData(String path, String fileName) {
- ZipFile zipFile= null;
- InputStream stream= null;
- File archive= new File(path);
- if (!archive.exists())
- return null;
- try {
- zipFile= new ZipFile(archive);
- } catch(IOException io) {
- return null;
- }
- ZipEntry entry= zipFile.getEntry(fileName);
- if (entry == null)
- return null;
- int size= (int) entry.getSize();
- try {
- stream= zipFile.getInputStream(entry);
- byte[] data= new byte[size];
- int pos= 0;
- while (pos < size) {
- int n= stream.read(data, pos, data.length - pos);
- pos += n;
- }
- zipFile.close();
- return data;
- } catch (IOException e) {
- } finally {
- try {
- if (stream != null)
- stream.close();
- } catch (IOException e) {
- }
- }
- return null;
- }
-
- private void readExcludedPackages() {
- fExcluded= new Vector<String>(10);
- for (int i= 0; i < defaultExclusions.length; i++)
- fExcluded.addElement(defaultExclusions[i]);
-
- InputStream is= getClass().getResourceAsStream(EXCLUDED_FILE);
- if (is == null)
- return;
- Properties p= new Properties();
- try {
- p.load(is);
- }
- catch (IOException e) {
- return;
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- }
- }
- for (Enumeration e= p.propertyNames(); e.hasMoreElements(); ) {
- String key= (String)e.nextElement();
- if (key.startsWith("excluded.")) {
- String path= p.getProperty(key);
- path= path.trim();
- if (path.endsWith("*"))
- path= path.substring(0, path.length()-1);
- if (path.length() > 0)
- fExcluded.addElement(path);
- }
- }
- }
-}
diff --git a/dx/src/junit/runner/TestCollector.java b/dx/src/junit/runner/TestCollector.java
deleted file mode 100644
index 73efb4e39..000000000
--- a/dx/src/junit/runner/TestCollector.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package junit.runner;
-
-import java.util.*;
-
-
-/**
- * Collects Test class names to be presented
- * by the TestSelector.
- * @see TestSelector
- */
-public interface TestCollector {
- /**
- * Returns an enumeration of Strings with qualified class names
- */
- public Enumeration collectTests();
-}
diff --git a/dx/src/junit/runner/TestRunListener.java b/dx/src/junit/runner/TestRunListener.java
deleted file mode 100644
index b11ef0744..000000000
--- a/dx/src/junit/runner/TestRunListener.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package junit.runner;
-/**
- * A listener interface for observing the
- * execution of a test run. Unlike TestListener,
- * this interface using only primitive objects,
- * making it suitable for remote test execution.
- */
- public interface TestRunListener {
- /* test status constants*/
- public static final int STATUS_ERROR= 1;
- public static final int STATUS_FAILURE= 2;
-
- public void testRunStarted(String testSuiteName, int testCount);
- public void testRunEnded(long elapsedTime);
- public void testRunStopped(long elapsedTime);
- public void testStarted(String testName);
- public void testEnded(String testName);
- public void testFailed(int status, String testName, String trace);
-}
diff --git a/dx/src/junit/runner/TestSuiteLoader.java b/dx/src/junit/runner/TestSuiteLoader.java
deleted file mode 100644
index 39a4cf79a..000000000
--- a/dx/src/junit/runner/TestSuiteLoader.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package junit.runner;
-
-/**
- * An interface to define how a test suite should be loaded.
- */
-public interface TestSuiteLoader {
- abstract public Class load(String suiteClassName) throws ClassNotFoundException;
- abstract public Class reload(Class aClass) throws ClassNotFoundException;
-}
diff --git a/dx/src/junit/runner/Version.java b/dx/src/junit/runner/Version.java
deleted file mode 100644
index b4541abde..000000000
--- a/dx/src/junit/runner/Version.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package junit.runner;
-
-/**
- * This class defines the current version of JUnit
- */
-public class Version {
- private Version() {
- // don't instantiate
- }
-
- public static String id() {
- return "3.8.1";
- }
-}
diff --git a/dx/src/junit/runner/excluded.properties b/dx/src/junit/runner/excluded.properties
deleted file mode 100644
index 32846283e..000000000
--- a/dx/src/junit/runner/excluded.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# The list of excluded package paths for the TestCaseClassLoader
-#
-excluded.0=sun.*
-excluded.1=com.sun.*
-excluded.2=org.omg.*
-excluded.3=javax.*
-excluded.4=sunw.*
-excluded.5=java.*
-excluded.6=org.w3c.dom.*
-excluded.7=org.xml.sax.*
-excluded.8=net.jini.*
diff --git a/dx/src/junit/runner/logo.gif b/dx/src/junit/runner/logo.gif
deleted file mode 100644
index d0e154738..000000000
--- a/dx/src/junit/runner/logo.gif
+++ /dev/null
Binary files differ
diff --git a/dx/src/junit/runner/smalllogo.gif b/dx/src/junit/runner/smalllogo.gif
deleted file mode 100644
index 7b25eaf6a..000000000
--- a/dx/src/junit/runner/smalllogo.gif
+++ /dev/null
Binary files differ
diff --git a/dx/src/junit/textui/ResultPrinter.java b/dx/src/junit/textui/ResultPrinter.java
deleted file mode 100644
index 1ebb7a178..000000000
--- a/dx/src/junit/textui/ResultPrinter.java
+++ /dev/null
@@ -1,139 +0,0 @@
-
-package junit.textui;
-
-import java.io.PrintStream;
-import java.text.NumberFormat;
-import java.util.Enumeration;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-import junit.framework.TestFailure;
-import junit.framework.TestListener;
-import junit.framework.TestResult;
-import junit.runner.BaseTestRunner;
-
-public class ResultPrinter implements TestListener {
- PrintStream fWriter;
- int fColumn= 0;
-
- public ResultPrinter(PrintStream writer) {
- fWriter= writer;
- }
-
- /* API for use by textui.TestRunner
- */
-
- synchronized void print(TestResult result, long runTime) {
- printHeader(runTime);
- printErrors(result);
- printFailures(result);
- printFooter(result);
- }
-
- void printWaitPrompt() {
- getWriter().println();
- getWriter().println("<RETURN> to continue");
- }
-
- /* Internal methods
- */
-
- protected void printHeader(long runTime) {
- getWriter().println();
- getWriter().println("Time: "+elapsedTimeAsString(runTime));
- }
-
- protected void printErrors(TestResult result) {
- printDefects(result.errors(), result.errorCount(), "error");
- }
-
- protected void printFailures(TestResult result) {
- printDefects(result.failures(), result.failureCount(), "failure");
- }
-
- protected void printDefects(Enumeration booBoos, int count, String type) {
- if (count == 0) return;
- if (count == 1)
- getWriter().println("There was " + count + " " + type + ":");
- else
- getWriter().println("There were " + count + " " + type + "s:");
- for (int i= 1; booBoos.hasMoreElements(); i++) {
- printDefect((TestFailure) booBoos.nextElement(), i);
- }
- }
-
- public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
- printDefectHeader(booBoo, count);
- printDefectTrace(booBoo);
- }
-
- protected void printDefectHeader(TestFailure booBoo, int count) {
- // I feel like making this a println, then adding a line giving the throwable a chance to print something
- // before we get to the stack trace.
- getWriter().print(count + ") " + booBoo.failedTest());
- }
-
- protected void printDefectTrace(TestFailure booBoo) {
- getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
- }
-
- protected void printFooter(TestResult result) {
- if (result.wasSuccessful()) {
- getWriter().println();
- getWriter().print("OK");
- getWriter().println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")");
-
- } else {
- getWriter().println();
- getWriter().println("FAILURES!!!");
- getWriter().println("Tests run: "+result.runCount()+
- ", Failures: "+result.failureCount()+
- ", Errors: "+result.errorCount());
- }
- getWriter().println();
- }
-
-
- /**
- * Returns the formatted string of the elapsed time.
- * Duplicated from BaseTestRunner. Fix it.
- */
- protected String elapsedTimeAsString(long runTime) {
- return NumberFormat.getInstance().format((double)runTime/1000);
- }
-
- public PrintStream getWriter() {
- return fWriter;
- }
- /**
- * @see junit.framework.TestListener#addError(Test, Throwable)
- */
- public void addError(Test test, Throwable t) {
- getWriter().print("E");
- }
-
- /**
- * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
- */
- public void addFailure(Test test, AssertionFailedError t) {
- getWriter().print("F");
- }
-
- /**
- * @see junit.framework.TestListener#endTest(Test)
- */
- public void endTest(Test test) {
- }
-
- /**
- * @see junit.framework.TestListener#startTest(Test)
- */
- public void startTest(Test test) {
- getWriter().print(".");
- if (fColumn++ >= 40) {
- getWriter().println();
- fColumn= 0;
- }
- }
-
-}
diff --git a/dx/src/junit/textui/TestRunner.java b/dx/src/junit/textui/TestRunner.java
deleted file mode 100644
index 8bdc3258a..000000000
--- a/dx/src/junit/textui/TestRunner.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package junit.textui;
-
-
-import java.io.PrintStream;
-
-import junit.framework.*;
-import junit.runner.*;
-
-/**
- * A command line based tool to run tests.
- * <pre>
- * java junit.textui.TestRunner [-wait] TestCaseClass
- * </pre>
- * TestRunner expects the name of a TestCase class as argument.
- * If this class defines a static <code>suite</code> method it
- * will be invoked and the returned test is run. Otherwise all
- * the methods starting with "test" having no arguments are run.
- * <p>
- * When the wait command line argument is given TestRunner
- * waits until the users types RETURN.
- * <p>
- * TestRunner prints a trace as the tests are executed followed by a
- * summary at the end.
- */
-public class TestRunner extends BaseTestRunner {
- private ResultPrinter fPrinter;
-
- public static final int SUCCESS_EXIT= 0;
- public static final int FAILURE_EXIT= 1;
- public static final int EXCEPTION_EXIT= 2;
-
- /**
- * Constructs a TestRunner.
- */
- public TestRunner() {
- this(System.out);
- }
-
- /**
- * Constructs a TestRunner using the given stream for all the output
- */
- public TestRunner(PrintStream writer) {
- this(new ResultPrinter(writer));
- }
-
- /**
- * Constructs a TestRunner using the given ResultPrinter all the output
- */
- public TestRunner(ResultPrinter printer) {
- fPrinter= printer;
- }
-
- /**
- * Runs a suite extracted from a TestCase subclass.
- */
- static public void run(Class testClass) {
- run(new TestSuite(testClass));
- }
-
- /**
- * Runs a single test and collects its results.
- * This method can be used to start a test run
- * from your program.
- * <pre>
- * public static void main (String[] args) {
- * test.textui.TestRunner.run(suite());
- * }
- * </pre>
- */
- static public TestResult run(Test test) {
- TestRunner runner= new TestRunner();
- return runner.doRun(test);
- }
-
- /**
- * Runs a single test and waits until the user
- * types RETURN.
- */
- static public void runAndWait(Test suite) {
- TestRunner aTestRunner= new TestRunner();
- aTestRunner.doRun(suite, true);
- }
-
- /**
- * Always use the StandardTestSuiteLoader. Overridden from
- * BaseTestRunner.
- */
- public TestSuiteLoader getLoader() {
- return new StandardTestSuiteLoader();
- }
-
- public void testFailed(int status, Test test, Throwable t) {
- }
-
- public void testStarted(String testName) {
- }
-
- public void testEnded(String testName) {
- }
-
- /**
- * Creates the TestResult to be used for the test run.
- */
- protected TestResult createTestResult() {
- return new TestResult();
- }
-
- public TestResult doRun(Test test) {
- return doRun(test, false);
- }
-
- public TestResult doRun(Test suite, boolean wait) {
- TestResult result= createTestResult();
- result.addListener(fPrinter);
- long startTime= System.currentTimeMillis();
- suite.run(result);
- long endTime= System.currentTimeMillis();
- long runTime= endTime-startTime;
- fPrinter.print(result, runTime);
-
- pause(wait);
- return result;
- }
-
- protected void pause(boolean wait) {
- if (!wait) return;
- fPrinter.printWaitPrompt();
- try {
- System.in.read();
- }
- catch(Exception e) {
- }
- }
-
- public static void main(String args[]) {
- TestRunner aTestRunner= new TestRunner();
- try {
- TestResult r= aTestRunner.start(args);
- if (!r.wasSuccessful())
- System.exit(FAILURE_EXIT);
- System.exit(SUCCESS_EXIT);
- } catch(Exception e) {
- System.err.println(e.getMessage());
- System.exit(EXCEPTION_EXIT);
- }
- }
-
- /**
- * Starts a test run. Analyzes the command line arguments
- * and runs the given test suite.
- */
- protected TestResult start(String args[]) throws Exception {
- String testCase= "";
- boolean wait= false;
-
- for (int i= 0; i < args.length; i++) {
- if (args[i].equals("-wait"))
- wait= true;
- else if (args[i].equals("-c"))
- testCase= extractClassName(args[++i]);
- else if (args[i].equals("-v"))
- System.err.println("JUnit "+Version.id()+" by Kent Beck and Erich Gamma");
- else
- testCase= args[i];
- }
-
- if (testCase.equals(""))
- throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
-
- try {
- Test suite= getTest(testCase);
- return doRun(suite, wait);
- }
- catch(Exception e) {
- throw new Exception("Could not create and run test suite: "+e);
- }
- }
-
- protected void runFailed(String message) {
- System.err.println(message);
- System.exit(FAILURE_EXIT);
- }
-
- public void setPrinter(ResultPrinter printer) {
- fPrinter= printer;
- }
-
-
-}