aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/javassist/LineNumberTest.java
blob: 4ab2580c7a526f37a43545129e19d80865e6d70f (plain)
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");
    }
}