blob: cdba21b53b066e489c936497889dc56cead0cae9 [file] [log] [blame]
// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.debug;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.apache.harmony.jpda.tests.framework.jdwp.Value;
import org.junit.Test;
// TODO check double-depth inline (an inline in another inline)
public class KotlinInlineTest extends KotlinDebugTestBase {
@Test
public void testStepOverInline() throws Throwable {
String methodName = "singleInline";
runDebugTest(
getD8Config(),
"KotlinInline",
breakpoint("KotlinInline", methodName),
run(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(41, s.getLineNumber());
s.checkLocal("this");
}),
stepOver(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(42, s.getLineNumber());
s.checkLocal("this");
}),
kotlinStepOver(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(43, s.getLineNumber());
s.checkLocal("this");
}),
run());
}
@Test
public void testStepIntoInline() throws Throwable {
String methodName = "singleInline";
runDebugTest(
getD8Config(),
"KotlinInline",
breakpoint("KotlinInline", methodName),
run(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(41, s.getLineNumber());
s.checkLocal("this");
}),
stepOver(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(42, s.getLineNumber());
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
// The actual line number (the one encoded in debug information) is different than the
// source file one.
// TODO(shertz) extract original line number from JSR-45's SMAP (only supported on
// Android O+).
assertTrue(42 != s.getLineNumber());
s.checkLocal("this");
}),
run());
}
@Test
public void testStepOutInline() throws Throwable {
String methodName = "singleInline";
runDebugTest(
getD8Config(),
"KotlinInline",
breakpoint("KotlinInline", methodName),
run(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(41, s.getLineNumber());
s.checkLocal("this");
}),
stepOver(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(42, s.getLineNumber());
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
}),
kotlinStepOut(),
inspect(s -> {
assertEquals("KotlinInline", s.getClassName());
assertEquals(methodName, s.getMethodName());
assertEquals("KotlinInline.kt", s.getSourceFile());
assertEquals(43, s.getLineNumber());
s.checkLocal("this");
}),
run());
}
@Test
public void testKotlinInline() throws Throwable {
final String inliningMethodName = "invokeInlinedFunctions";
runDebugTest(
getD8Config(),
"KotlinInline",
breakpoint("KotlinInline", inliningMethodName),
run(),
inspect(s -> {
assertEquals(inliningMethodName, s.getMethodName());
assertEquals(16, s.getLineNumber());
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
// We must have stepped into the code of the inlined method but the actual current method
// did not change.
assertEquals(inliningMethodName, s.getMethodName());
// TODO(shertz) get the original line if JSR45 is supported by the targeted ART runtime.
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
assertEquals(inliningMethodName, s.getMethodName());
assertEquals(17, s.getLineNumber());
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
assertEquals(inliningMethodName, s.getMethodName());
assertEquals(18, s.getLineNumber());
s.checkLocal("this");
s.checkLocal("inA", Value.createInt(1));
// This is a "hidden" lv added by Kotlin (which is neither initialized nor used).
s.checkLocal("$i$f$inlinedA");
s.checkLocal("$i$a$1$inlinedA");
}),
stepInto(),
inspect(s -> {
// We must have stepped into the code of the second inlined method but the actual current
// method did not change.
assertEquals(inliningMethodName, s.getMethodName());
// TODO(shertz) get the original line if JSR45 is supported by the targeted ART runtime.
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
assertEquals(inliningMethodName, s.getMethodName());
assertEquals(19, s.getLineNumber());
s.checkLocal("this");
}),
stepInto(),
inspect(s -> {
assertEquals(inliningMethodName, s.getMethodName());
assertEquals(20, s.getLineNumber());
s.checkLocal("this");
s.checkLocal("inB", Value.createInt(2));
// This is a "hidden" lv added by Kotlin (which is neither initialized nor used).
s.checkLocal("$i$f$inlinedB");
s.checkLocal("$i$a$1$inlinedB");
}),
run());
}
}