diff options
| author | 2012-03-22 18:06:48 -0700 | |
|---|---|---|
| committer | 2012-03-22 18:06:48 -0700 | |
| commit | 9058f2bf308871bd43c194c6a771587ecf79740d (patch) | |
| tree | 256f51b2af0977f65d0ab18de72fad16e8d850fe /src | |
| parent | 634eb2eb14f87753519d0ef2c5f256e55888f378 (diff) | |
Make our new NullPointerException detail messages more readable to Java programmers.
Two to-dos to-done.
Change-Id: I0276dd8b9c062e8e9523cb51defed2c3eda77e2b
Diffstat (limited to 'src')
| -rw-r--r-- | src/utils.cc | 46 | ||||
| -rw-r--r-- | src/utils_test.cc | 83 |
2 files changed, 88 insertions, 41 deletions
diff --git a/src/utils.cc b/src/utils.cc index c9a6e7e752..389c280ed3 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -184,6 +184,7 @@ std::string PrettyDescriptor(const std::string& descriptor) { case 'J': c = "long;"; break; case 'S': c = "short;"; break; case 'Z': c = "boolean;"; break; + case 'V': c = "void;"; break; // Used when decoding return types. default: return descriptor; } } @@ -227,6 +228,41 @@ std::string PrettyField(const Field* f, bool with_type) { return result; } +std::string PrettyArguments(const char* signature) { + std::string result; + result += '('; + CHECK_EQ(*signature, '('); + ++signature; // Skip the '('. + while (*signature != ')') { + size_t argument_length = 0; + while (signature[argument_length] == '[') { + ++argument_length; + } + if (signature[argument_length] == 'L') { + argument_length = (strchr(signature, ';') - signature + 1); + } else { + ++argument_length; + } + std::string argument_descriptor(signature, argument_length); + result += PrettyDescriptor(argument_descriptor); + if (signature[argument_length] != ')') { + result += ", "; + } + signature += argument_length; + } + CHECK_EQ(*signature, ')'); + ++signature; // Skip the ')'. + result += ')'; + return result; +} + +std::string PrettyReturnType(const char* signature) { + const char* return_type = strchr(signature, ')'); + CHECK(return_type != NULL); + ++return_type; // Skip ')'. + return PrettyDescriptor(return_type); +} + std::string PrettyMethod(const Method* m, bool with_signature) { if (m == NULL) { return "null"; @@ -236,9 +272,8 @@ std::string PrettyMethod(const Method* m, bool with_signature) { result += '.'; result += mh.GetName(); if (with_signature) { - // TODO: iterate over the signature's elements and pass them all to - // PrettyDescriptor? We'd need to pull out the return type specially, too. - result += mh.GetSignature(); + std::string signature(mh.GetSignature()); + result = PrettyReturnType(signature.c_str()) + " " + result + PrettyArguments(signature.c_str()); } return result; } @@ -249,9 +284,8 @@ std::string PrettyMethod(uint32_t method_idx, const DexFile& dex_file, bool with result += '.'; result += dex_file.GetMethodName(method_id); if (with_signature) { - // TODO: iterate over the signature's elements and pass them all to - // PrettyDescriptor? We'd need to pull out the return type specially, too. - result += dex_file.GetMethodSignature(method_id); + std::string signature(dex_file.GetMethodSignature(method_id)); + result = PrettyReturnType(signature.c_str()) + " " + result + PrettyArguments(signature.c_str()); } return result; } diff --git a/src/utils_test.cc b/src/utils_test.cc index 31fccc506d..3228bb6d12 100644 --- a/src/utils_test.cc +++ b/src/utils_test.cc @@ -20,54 +20,67 @@ namespace art { +std::string PrettyArguments(const char* signature); +std::string PrettyReturnType(const char* signature); + class UtilsTest : public CommonTest { }; -#define EXPECT_DESCRIPTOR(pretty_descriptor, descriptor) \ - do { \ - SirtRef<String> s(String::AllocFromModifiedUtf8(descriptor)); \ - std::string result(PrettyDescriptor(s.get())); \ - EXPECT_EQ(pretty_descriptor, result); \ - } while (false) - TEST_F(UtilsTest, PrettyDescriptor_ArrayReferences) { - EXPECT_DESCRIPTOR("java.lang.Class[]", "[Ljava/lang/Class;"); - EXPECT_DESCRIPTOR("java.lang.Class[][]", "[[Ljava/lang/Class;"); + EXPECT_EQ("java.lang.Class[]", PrettyDescriptor("[Ljava/lang/Class;")); + EXPECT_EQ("java.lang.Class[][]", PrettyDescriptor("[[Ljava/lang/Class;")); } TEST_F(UtilsTest, PrettyDescriptor_ScalarReferences) { - EXPECT_DESCRIPTOR("java.lang.String", "Ljava.lang.String;"); - EXPECT_DESCRIPTOR("java.lang.String", "Ljava/lang/String;"); + EXPECT_EQ("java.lang.String", PrettyDescriptor("Ljava.lang.String;")); + EXPECT_EQ("java.lang.String", PrettyDescriptor("Ljava/lang/String;")); } TEST_F(UtilsTest, PrettyDescriptor_PrimitiveArrays) { - EXPECT_DESCRIPTOR("boolean[]", "[Z"); - EXPECT_DESCRIPTOR("boolean[][]", "[[Z"); - EXPECT_DESCRIPTOR("byte[]", "[B"); - EXPECT_DESCRIPTOR("byte[][]", "[[B"); - EXPECT_DESCRIPTOR("char[]", "[C"); - EXPECT_DESCRIPTOR("char[][]", "[[C"); - EXPECT_DESCRIPTOR("double[]", "[D"); - EXPECT_DESCRIPTOR("double[][]", "[[D"); - EXPECT_DESCRIPTOR("float[]", "[F"); - EXPECT_DESCRIPTOR("float[][]", "[[F"); - EXPECT_DESCRIPTOR("int[]", "[I"); - EXPECT_DESCRIPTOR("int[][]", "[[I"); - EXPECT_DESCRIPTOR("long[]", "[J"); - EXPECT_DESCRIPTOR("long[][]", "[[J"); - EXPECT_DESCRIPTOR("short[]", "[S"); - EXPECT_DESCRIPTOR("short[][]", "[[S"); + EXPECT_EQ("boolean[]", PrettyDescriptor("[Z")); + EXPECT_EQ("boolean[][]", PrettyDescriptor("[[Z")); + EXPECT_EQ("byte[]", PrettyDescriptor("[B")); + EXPECT_EQ("byte[][]", PrettyDescriptor("[[B")); + EXPECT_EQ("char[]", PrettyDescriptor("[C")); + EXPECT_EQ("char[][]", PrettyDescriptor("[[C")); + EXPECT_EQ("double[]", PrettyDescriptor("[D")); + EXPECT_EQ("double[][]", PrettyDescriptor("[[D")); + EXPECT_EQ("float[]", PrettyDescriptor("[F")); + EXPECT_EQ("float[][]", PrettyDescriptor("[[F")); + EXPECT_EQ("int[]", PrettyDescriptor("[I")); + EXPECT_EQ("int[][]", PrettyDescriptor("[[I")); + EXPECT_EQ("long[]", PrettyDescriptor("[J")); + EXPECT_EQ("long[][]", PrettyDescriptor("[[J")); + EXPECT_EQ("short[]", PrettyDescriptor("[S")); + EXPECT_EQ("short[][]", PrettyDescriptor("[[S")); } TEST_F(UtilsTest, PrettyDescriptor_PrimitiveScalars) { - EXPECT_DESCRIPTOR("boolean", "Z"); - EXPECT_DESCRIPTOR("byte", "B"); - EXPECT_DESCRIPTOR("char", "C"); - EXPECT_DESCRIPTOR("double", "D"); - EXPECT_DESCRIPTOR("float", "F"); - EXPECT_DESCRIPTOR("int", "I"); - EXPECT_DESCRIPTOR("long", "J"); - EXPECT_DESCRIPTOR("short", "S"); + EXPECT_EQ("boolean", PrettyDescriptor("Z")); + EXPECT_EQ("byte", PrettyDescriptor("B")); + EXPECT_EQ("char", PrettyDescriptor("C")); + EXPECT_EQ("double", PrettyDescriptor("D")); + EXPECT_EQ("float", PrettyDescriptor("F")); + EXPECT_EQ("int", PrettyDescriptor("I")); + EXPECT_EQ("long", PrettyDescriptor("J")); + EXPECT_EQ("short", PrettyDescriptor("S")); +} + +TEST_F(UtilsTest, PrettyArguments) { + EXPECT_EQ("()", PrettyArguments("()V")); + EXPECT_EQ("(int)", PrettyArguments("(I)V")); + EXPECT_EQ("(int, int)", PrettyArguments("(II)V")); + EXPECT_EQ("(int, int, int[][])", PrettyArguments("(II[[I)V")); + EXPECT_EQ("(int, int, int[][], java.lang.Poop)", PrettyArguments("(II[[ILjava/lang/Poop;)V")); + EXPECT_EQ("(int, int, int[][], java.lang.Poop, java.lang.Poop[][])", PrettyArguments("(II[[ILjava/lang/Poop;[[Ljava/lang/Poop;)V")); +} + +TEST_F(UtilsTest, PrettyReturnType) { + EXPECT_EQ("void", PrettyReturnType("()V")); + EXPECT_EQ("int", PrettyReturnType("()I")); + EXPECT_EQ("int[][]", PrettyReturnType("()[[I")); + EXPECT_EQ("java.lang.Poop", PrettyReturnType("()Ljava/lang/Poop;")); + EXPECT_EQ("java.lang.Poop[][]", PrettyReturnType("()[[Ljava/lang/Poop;")); } TEST_F(UtilsTest, PrettyTypeOf) { |