summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author Elliott Hughes <enh@google.com> 2012-03-22 18:06:48 -0700
committer Elliott Hughes <enh@google.com> 2012-03-22 18:06:48 -0700
commit9058f2bf308871bd43c194c6a771587ecf79740d (patch)
tree256f51b2af0977f65d0ab18de72fad16e8d850fe /src
parent634eb2eb14f87753519d0ef2c5f256e55888f378 (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.cc46
-rw-r--r--src/utils_test.cc83
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) {