Skip to content

Commit c582b1d

Browse files
author
Michael Bogdanov
committed
Generate linenumber if needed after inlining
1 parent 8cd4965 commit c582b1d

File tree

12 files changed

+399
-2
lines changed

12 files changed

+399
-2
lines changed

compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,21 @@ public void markLineNumber(@NotNull JetElement statement, boolean markEndOffset)
17171717
v.visitLineNumber(lineNumber, label);
17181718
}
17191719

1720+
//we should generate additional linenumber info after inline call only if it used as argument
1721+
public void markLineNumberAfterInlineIfNeeded() {
1722+
if (!shouldMarkLineNumbers) {
1723+
//if it used as general argument
1724+
if (myLastLineNumber > -1) {
1725+
Label label = new Label();
1726+
v.visitLabel(label);
1727+
v.visitLineNumber(myLastLineNumber, label);
1728+
}
1729+
} else {
1730+
//if it used as argument of infix call (in this case lineNumber for simple inlineCall also would be reset)
1731+
myLastLineNumber = -1;
1732+
}
1733+
}
1734+
17201735
private void doFinallyOnReturn() {
17211736
if(!blockStackElements.isEmpty()) {
17221737
BlockStackElement stackElement = blockStackElements.peek();

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ private void endCall(@NotNull InlineResult result) {
154154
codegen.propagateChildReifiedTypeParametersUsages(result.getReifiedTypeParametersUsages());
155155

156156
state.getFactory().removeInlinedClasses(result.getClassesToRemove());
157+
158+
codegen.markLineNumberAfterInlineIfNeeded();
157159
}
158160

159161
@NotNull

compiler/testData/codegen/boxInline/smap/smap.2.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ inline fun initTag2(init: () -> Unit) {
88
val p = 1;
99
init()
1010
}
11-
12-
inline fun head(init: () -> Unit) = initTag2(init)
11+
//{val p = initTag2(init); return p} to remove difference in linenumber processing through MethodNode and MethodVisitor should be: = initTag2(init)
12+
inline fun head(init: () -> Unit) {val p = initTag2(init); return p}
1313

1414

1515
inline fun html(init: () -> Unit) {
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
fun testProperLineNumber(): String {
2+
var exceptionCount = 0;
3+
try {
4+
test().
5+
test().
6+
fail()
7+
8+
}
9+
catch(e: AssertionError) {
10+
val entry = (e as java.lang.Throwable).getStackTrace()!!.get(1)
11+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
12+
if ("chainCalls.kt:6" != actual) {
13+
return "fail 1: ${actual}"
14+
}
15+
exceptionCount++
16+
}
17+
18+
try {
19+
call().
20+
test().
21+
fail()
22+
}
23+
catch(e: AssertionError) {
24+
val entry = e.getStackTrace()!![1]
25+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
26+
if ("chainCalls.kt:21" != actual) {
27+
return "fail 2: ${actual}"
28+
}
29+
exceptionCount++
30+
}
31+
32+
try {
33+
test().
34+
fail()
35+
}
36+
catch(e: AssertionError) {
37+
val entry = e.getStackTrace()!![1]
38+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
39+
if ("chainCalls.kt:34" != actual) {
40+
return "fail 3: ${actual}"
41+
}
42+
exceptionCount++
43+
}
44+
45+
try {
46+
test().fail()
47+
}
48+
catch(e: AssertionError) {
49+
val entry = e.getStackTrace()!![1]
50+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
51+
if ("chainCalls.kt:46" != actual) {
52+
return "fail 4: ${actual}"
53+
}
54+
exceptionCount++
55+
}
56+
57+
return if (exceptionCount == 4) "OK" else "fail"
58+
}
59+
60+
fun box(): String {
61+
return testProperLineNumber()
62+
}
63+
64+
public fun checkEquals(p1: String, p2: String) {
65+
throw AssertionError("fail")
66+
}
67+
68+
inline fun test(): String {
69+
return "123"
70+
}
71+
72+
inline fun String.test(): String {
73+
return "123"
74+
}
75+
76+
fun String.fail(): String {
77+
throw AssertionError("fail")
78+
}
79+
80+
fun call(): String {
81+
return "xxx"
82+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
fun testProperLineNumber(): String {
2+
var exceptionCount = 0;
3+
try {
4+
test() fail
5+
call()
6+
}
7+
catch(e: AssertionError) {
8+
val entry = (e as java.lang.Throwable).getStackTrace()!!.get(1)
9+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
10+
if ("infixCalls.kt:4" != actual) {
11+
return "fail 1: ${actual}"
12+
}
13+
exceptionCount++
14+
}
15+
16+
try {
17+
call() fail
18+
test()
19+
}
20+
catch(e: AssertionError) {
21+
val entry = e.getStackTrace()!![1]
22+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
23+
if ("infixCalls.kt:17" != actual) {
24+
return "fail 1: ${actual}"
25+
}
26+
exceptionCount++
27+
}
28+
29+
try {
30+
call() fail test()
31+
}
32+
catch(e: AssertionError) {
33+
val entry = e.getStackTrace()!![1]
34+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
35+
if ("infixCalls.kt:30" != actual) {
36+
return "fail 1: ${actual}"
37+
}
38+
exceptionCount++
39+
}
40+
41+
return if (exceptionCount == 3) "OK" else "fail"
42+
}
43+
44+
fun box(): String {
45+
return testProperLineNumber()
46+
}
47+
48+
public fun checkEquals(p1: String, p2: String) {
49+
throw AssertionError("fail")
50+
}
51+
52+
inline fun test(): String {
53+
return "123"
54+
}
55+
56+
fun String.fail(p: String): String {
57+
throw AssertionError("fail")
58+
}
59+
60+
fun call(): String {
61+
return "xxx"
62+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
fun testProperLineNumberAfterInline(): String {
2+
var exceptionCount = 0;
3+
try {
4+
checkEquals(test(),
5+
"12")
6+
}
7+
catch(e: AssertionError) {
8+
val entry = (e as java.lang.Throwable).getStackTrace()!!.get(1)
9+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
10+
if ("simpleCallWithParams.kt:4" != actual) {
11+
return "fail 1: ${actual}"
12+
}
13+
exceptionCount++
14+
}
15+
16+
try {
17+
checkEquals("12",
18+
test())
19+
}
20+
catch(e: AssertionError) {
21+
val entry = e.getStackTrace()!![1]
22+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
23+
if ("simpleCallWithParams.kt:17" != actual) {
24+
return "fail 2: ${actual}"
25+
}
26+
exceptionCount++
27+
}
28+
29+
return if (exceptionCount == 2) "OK" else "fail"
30+
}
31+
32+
fun testProperLineForOtherParameters(): String {
33+
var exceptionCount = 0;
34+
try {
35+
checkEquals(test(),
36+
fail())
37+
}
38+
catch(e: AssertionError) {
39+
val entry = e.getStackTrace()!![1]
40+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
41+
if ("simpleCallWithParams.kt:35" != actual) {
42+
return "fail 3: ${actual}"
43+
}
44+
exceptionCount++
45+
46+
}
47+
48+
try {
49+
checkEquals(fail(),
50+
test())
51+
}
52+
catch(e: AssertionError) {
53+
val entry = e.getStackTrace()!![1]
54+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
55+
if ("simpleCallWithParams.kt:49" != actual) {
56+
return "fail 4: ${actual}"
57+
}
58+
exceptionCount++
59+
}
60+
61+
try {
62+
checkEquals(fail(), test())
63+
}
64+
catch(e: AssertionError) {
65+
val entry = e.getStackTrace()!![1]
66+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
67+
if ("simpleCallWithParams.kt:62" != actual) {
68+
return "fail 5: ${actual}"
69+
}
70+
exceptionCount++
71+
}
72+
73+
try {
74+
checkEquals(fail(), test())
75+
}
76+
catch(e: AssertionError) {
77+
val entry = e.getStackTrace()!![1]
78+
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
79+
if ("simpleCallWithParams.kt:74" != actual) {
80+
return "fail 6: ${actual}"
81+
}
82+
exceptionCount++
83+
}
84+
85+
return if (exceptionCount == 4) "OK" else "fail"
86+
}
87+
88+
89+
fun box(): String {
90+
val res = testProperLineNumberAfterInline()
91+
if (res != "OK") return "$res"
92+
93+
return testProperLineForOtherParameters()
94+
}
95+
96+
public fun checkEquals(p1: String, p2: String) {
97+
throw AssertionError("fail")
98+
}
99+
100+
inline fun test(): String {
101+
return "123"
102+
}
103+
104+
fun fail(): String {
105+
throw AssertionError("fail")
106+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
fun box(){
2+
checkEquals(test(),
3+
fail())
4+
5+
checkEquals(fail(),
6+
test())
7+
}
8+
9+
public fun checkEquals(p1: String, p2: String) {
10+
throw AssertionError("fail")
11+
}
12+
13+
inline fun test() : String {
14+
return "123"
15+
}
16+
17+
fun fail() : String {
18+
throw AssertionError("fail")
19+
}
20+
21+
// 2 14 2 5 14 5 7 10 14 18
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
fun String.execute(p: String) = this + p
2+
3+
fun box(){
4+
test() execute
5+
fail()
6+
7+
fail() execute
8+
test()
9+
}
10+
11+
inline fun test() : String {
12+
return "123"
13+
}
14+
15+
fun fail() : String {
16+
throw AssertionError("fail")
17+
}
18+
19+
// 1 4 12 4 7 12 7 9 12 16
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
fun box(){
2+
test(test("1", "2"),
3+
fail())
4+
5+
test(fail(),
6+
test("1", "2"))
7+
}
8+
9+
public fun checkEquals(p1: String, p2: String) {
10+
throw AssertionError("fail")
11+
}
12+
13+
inline fun test(p: String, s: String) : String {
14+
return "123"
15+
}
16+
17+
fun fail() : String {
18+
throw AssertionError("fail")
19+
}
20+
21+
//2 14 2 14 5 14 5 14 7 10 14 18
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
fun box(){
2+
test() +
3+
fail()
4+
5+
fail() +
6+
test()
7+
}
8+
9+
inline fun test() : String {
10+
return "123"
11+
}
12+
13+
fun fail() : String {
14+
throw AssertionError("fail")
15+
}
16+
17+
// 2 10 3 5 6 10 7 10 14

0 commit comments

Comments
 (0)