| // 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.Ignore; |
| 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"; |
| runDebugTestKotlin("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"; |
| runDebugTestKotlin("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"; |
| runDebugTestKotlin("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"; |
| runDebugTestKotlin("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()); |
| } |
| |
| } |