1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
package javassist;
import junit.framework.TestCase;
public class LineNumberTest extends TestCase {
private final ClassPool loader = ClassPool.getDefault();
private static int classNumber = 0;
public void testComma() {
doTestCompile(String.join("\n",
"public void run() {",
" return",
"}"), "line 3: syntax error near \" return\n}\"");
}
public void testUndevField() {
doTestCompile(String.join("\n",
"public void run() {",
" foo = 5;",
"}"), "line 2: no such field: foo");
}
public void testUndevMethod() {
doTestCompile(String.join("\n",
"public void run() {",
" foo();",
"}"), "line 2: foo() not found in javassist.LineNumberCompileTest2");
}
public void testException() {
doTestRuntime(String.join("\n",
"public void run() {",
" throw new java.lang.RuntimeException();",
"}"), 0, 5);
}
public void testIf() {
doTestRuntime(String.join("\n",
"public void run() {",
" if (throwException()) {",
" }",
"}"), 1, 5);
}
public void testWhile() {
doTestRuntime(String.join("\n",
"public void run() {",
" while (throwException()) {",
" }",
"}"), 1, 5);
}
public void testFor() {
doTestRuntime(String.join("\n",
"public void run() {",
" for (; throwException(); ) {",
" ",
" }",
"}"), 1, 5);
}
public void test16Line() {
doTestRuntime(String.join("\n",
"public void run() {",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"throwException();",
"}"), 1, 16);
}
private void doTestCompile(String src, String msg) {
CtClass testClass = loader.makeClass("javassist.LineNumberCompileTest" + classNumber++);
try {
testClass.addMethod(CtMethod.make(src, testClass));
} catch (CannotCompileException e) {
assertEquals(msg, e.getCause().getMessage());
return;
}
fail("should not happen");
}
private void doTestRuntime(String src, int stackOffset, int lineNumber) {
CtClass testClass = loader.makeClass("javassist.LineNumberRuntimeTest" + classNumber++);
String test = String.join("\n",
"private boolean throwException() {",
" throw new java.lang.RuntimeException();",
"}");
try {
testClass.addInterface(loader.get("java.lang.Runnable"));
testClass.addMethod(CtMethod.make(test, testClass));
testClass.addMethod(CtMethod.make(src, testClass));
Class cls = testClass.toClass(LineNumberTest.class);
var runnable = (Runnable) cls.getConstructor().newInstance();
runnable.run();
} catch (Exception e) {
var lineNum = e.getStackTrace()[stackOffset].getLineNumber();
assertEquals("Line number should be right", lineNumber, lineNum);
return;
}
fail("should not happen");
}
}
|