Fix breakpoints in inline functions after dexing (KT-12896)
#KT-12896 In Progress
This commit is contained in:
@@ -744,13 +744,13 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractKotlinSteppingTest>() {
|
||||
model("debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto", testMethod = "doStepIntoTest", testClassName = "StepInto")
|
||||
model("debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto", testMethod = "doSmartStepIntoTest", testClassName = "SmartStepInto")
|
||||
model("debugger/tinyApp/src/stepping/stepInto", testMethod = "doStepIntoTest", testClassName = "StepIntoOnly")
|
||||
model("debugger/tinyApp/src/stepping/stepOut", testMethod = "doStepOutTest")
|
||||
model("debugger/tinyApp/src/stepping/stepOver", testMethod = "doStepOverTest")
|
||||
model("debugger/tinyApp/src/stepping/filters", testMethod = "doStepIntoTest")
|
||||
model("debugger/tinyApp/src/stepping/custom", testMethod = "doCustomTest")
|
||||
model("debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doStepIntoTest", testClassName = "StepInto")
|
||||
model("debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doSmartStepIntoTest", testClassName = "SmartStepInto")
|
||||
model("debugger/tinyApp/src/stepping/stepInto", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doStepIntoTest", testClassName = "StepIntoOnly")
|
||||
model("debugger/tinyApp/src/stepping/stepOut", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doStepOutTest")
|
||||
model("debugger/tinyApp/src/stepping/stepOver", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doStepOverTest")
|
||||
model("debugger/tinyApp/src/stepping/filters", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doStepIntoTest")
|
||||
model("debugger/tinyApp/src/stepping/custom", pattern = KT_WITHOUT_DOTS_IN_NAME, testMethod = "doCustomTest")
|
||||
}
|
||||
|
||||
testClass<AbstractKotlinEvaluateExpressionTest>() {
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil.findFilesWithExactPackage
|
||||
import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
||||
@@ -46,11 +47,13 @@ object DebuggerUtils {
|
||||
scope: GlobalSearchScope,
|
||||
className: JvmClassName,
|
||||
fileName: String): KtFile? {
|
||||
return findSourceFileForClass(
|
||||
project,
|
||||
listOf(scope, KotlinSourceFilterScope.librarySources(GlobalSearchScope.allScope(project), project)),
|
||||
className,
|
||||
fileName)
|
||||
return runReadAction {
|
||||
findSourceFileForClass(
|
||||
project,
|
||||
listOf(scope, KotlinSourceFilterScope.librarySources(GlobalSearchScope.allScope(project), project)),
|
||||
className,
|
||||
fileName)
|
||||
}
|
||||
}
|
||||
|
||||
fun findSourceFileForClass(
|
||||
|
||||
@@ -256,12 +256,24 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
throw NoDataException.INSTANCE
|
||||
}
|
||||
try {
|
||||
if (myDebugProcess.isDexDebug()) {
|
||||
val inlineLocations = noStrataLocationsOfLineForInlineFunctions(type, position, myDebugProcess.searchScope)
|
||||
if (!inlineLocations.isEmpty()) {
|
||||
return inlineLocations
|
||||
}
|
||||
}
|
||||
|
||||
val line = position.line + 1
|
||||
|
||||
val locations = if (myDebugProcess.virtualMachineProxy.versionHigher("1.4"))
|
||||
type.locationsOfLine(KOTLIN_STRATA_NAME, null, line).filter { it.sourceName(KOTLIN_STRATA_NAME) == position.file.name }
|
||||
else
|
||||
type.locationsOfLine(line)
|
||||
if (locations == null || locations.isEmpty()) throw NoDataException.INSTANCE
|
||||
|
||||
if (locations == null || locations.isEmpty()) {
|
||||
throw NoDataException.INSTANCE
|
||||
}
|
||||
|
||||
return locations
|
||||
}
|
||||
catch (e: AbsentInformationException) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.sun.jdi.Location
|
||||
import com.sun.jdi.ReferenceType
|
||||
import org.jetbrains.kotlin.idea.refactoring.getLineStartOffset
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
|
||||
fun noStrataLocationsOfLineForInlineFunctions(type: ReferenceType, position: SourcePosition, sourceSearchScope: GlobalSearchScope): List<Location> {
|
||||
val line = position.line
|
||||
val file = position.file
|
||||
val project = position.file.project
|
||||
|
||||
val lineStartOffset = file.getLineStartOffset(line) ?: return listOf()
|
||||
val element = file.findElementAt(lineStartOffset) ?: return listOf()
|
||||
|
||||
val isInInline = runReadAction { element.parents.any { it is KtFunction && it.hasModifier(KtTokens.INLINE_KEYWORD) } }
|
||||
if (!isInInline) return listOf()
|
||||
|
||||
val lines = inlinedLinesNumbers(line + 1, position.file.name, FqName(type.name()), type.sourceName(), project, sourceSearchScope)
|
||||
val inlineLocations = lines.flatMap { type.locationsOfLine(it) }
|
||||
|
||||
return inlineLocations
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.compiler.CompilerPaths
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectFileIndex
|
||||
@@ -53,6 +54,27 @@ fun inlineLineAndFileByPosition(lineNumber: Int, fqName: FqName, fileName: Strin
|
||||
return mapStacktraceLineToSource(smapData, lineNumber, project, SourceLineKind.EXECUTED_LINE, searchScope)
|
||||
}
|
||||
|
||||
internal fun inlinedLinesNumbers(
|
||||
inlineLineNumber: Int, inlineFileName: String,
|
||||
destinationTypeFqName: FqName, destinationFileName: String,
|
||||
project: Project, sourceSearchScope: GlobalSearchScope): List<Int> {
|
||||
val internalName = destinationTypeFqName.asString().replace('.', '/')
|
||||
val jvmClassName = JvmClassName.byInternalName(internalName)
|
||||
|
||||
val file = DebuggerUtils.findSourceFileForClassIncludeLibrarySources(project, sourceSearchScope, jvmClassName, destinationFileName) ?:
|
||||
return listOf()
|
||||
|
||||
val virtualFile = file.virtualFile ?: return listOf()
|
||||
|
||||
val bytes = readClassFile(project, jvmClassName, virtualFile) ?: return listOf()
|
||||
val smapData = readDebugInfo(bytes) ?: return listOf()
|
||||
|
||||
val smap = smapData.kotlinStrata ?: return listOf()
|
||||
|
||||
val mappingToInlinedFile = smap.fileMappings.firstOrNull() { it.name == inlineFileName } ?: return listOf()
|
||||
return mappingToInlinedFile.lineMappings.map { it.mapSourceToDest(inlineLineNumber) }
|
||||
}
|
||||
|
||||
fun isInlineFunctionLineNumber(file: VirtualFile, lineNumber: Int, project: Project): Boolean {
|
||||
val linesInFile = file.toPsiFile(project)?.getLineCount() ?: return false
|
||||
return lineNumber > linesInFile
|
||||
@@ -79,9 +101,9 @@ fun readClassFile(project: Project,
|
||||
val outputDir = CompilerPaths.getModuleOutputDirectory(module, /*forTests = */ false) ?: return null
|
||||
|
||||
val className = fqNameWithInners.asString().replace('.', '$')
|
||||
val classByByDirectory = findClassFileByPath(jvmName.packageFqName.asString(), className, outputDir) ?: return null
|
||||
val classByDirectory = findClassFileByPath(jvmName.packageFqName.asString(), className, outputDir) ?: return null
|
||||
|
||||
return classByByDirectory.readBytes()
|
||||
return classByDirectory.readBytes()
|
||||
}
|
||||
|
||||
else -> return null
|
||||
@@ -94,6 +116,13 @@ private fun findClassFileByPath(packageName: String, className: String, outputDi
|
||||
val parentDirectory = File(outDirFile, packageName.replace(".", File.separator))
|
||||
if (!parentDirectory.exists()) return null
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
val beforeDexFileClassFile = File(parentDirectory, className + ".class.before_dex")
|
||||
if (beforeDexFileClassFile.exists()) {
|
||||
return beforeDexFileClassFile
|
||||
}
|
||||
}
|
||||
|
||||
val classFile = File(parentDirectory, className + ".class")
|
||||
if (classFile.exists()) {
|
||||
return classFile
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
LineBreakpoint created at dexManyFilesWithInlineCalls1.First.kt:5
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! dexManyFilesWithInlineCalls1.DexManyFilesWithInlineCalls1Kt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
dexManyFilesWithInlineCalls1.First.kt:5
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,7 @@
|
||||
LineBreakpoint created at dexManyFilesWithInlineCalls2.Second.kt:5
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! dexManyFilesWithInlineCalls2.DexManyFilesWithInlineCalls2Kt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
dexManyFilesWithInlineCalls2.Second.kt:5
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,10 @@
|
||||
LineBreakpoint created at dexSeveralInlineCallsFromOtherFile.Other.kt:6
|
||||
LineBreakpoint created at dexSeveralInlineCallsFromOtherFile.kt:5
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! dexSeveralInlineCallsFromOtherFile.DexSeveralInlineCallsFromOtherFileKt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
dexSeveralInlineCallsFromOtherFile.kt:5
|
||||
dexSeveralInlineCallsFromOtherFile.Other.kt:6
|
||||
dexSeveralInlineCallsFromOtherFile.Other.kt:6
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,8 @@
|
||||
LineBreakpoint created at dexStopInInlineFun.kt:10
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! dexStopInInlineFun.DexStopInInlineFunKt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
dexStopInInlineFun.kt:10
|
||||
dexStopInInlineFun.kt:11
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -0,0 +1,8 @@
|
||||
LineBreakpoint created at dexStopInInlineInOtherFile.Other.kt:6
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! dexStopInInlineInOtherFile.DexStopInInlineInOtherFileKt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
dexStopInInlineInOtherFile.Other.kt:6
|
||||
dexStopInInlineInOtherFile.Other.kt:7
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package dexManyFilesWithInlineCalls1.first
|
||||
|
||||
inline fun firstInline() {
|
||||
// Breakpoint 1
|
||||
1 + 1
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package dexManyFilesWithInlineCalls1.second
|
||||
|
||||
inline fun secondInline() {
|
||||
1 + 1
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package dexManyFilesWithInlineCalls1
|
||||
|
||||
import dexManyFilesWithInlineCalls1.first.*
|
||||
import dexManyFilesWithInlineCalls1.second.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
firstInline()
|
||||
}
|
||||
|
||||
fun unused() {
|
||||
secondInline()
|
||||
}
|
||||
|
||||
// ADDITIONAL_BREAKPOINT: dexManyFilesWithInlineCalls1.First.kt: Breakpoint 1
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package dexManyFilesWithInlineCalls2.first
|
||||
|
||||
inline fun firstInline() {
|
||||
1 + 1
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package dexManyFilesWithInlineCalls2.second
|
||||
|
||||
inline fun secondInline() {
|
||||
// Breakpoint 1
|
||||
1 + 1
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package dexManyFilesWithInlineCalls2
|
||||
|
||||
import dexManyFilesWithInlineCalls2.first.*
|
||||
import dexManyFilesWithInlineCalls2.second.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
secondInline()
|
||||
}
|
||||
|
||||
fun unused() {
|
||||
firstInline()
|
||||
}
|
||||
|
||||
// ADDITIONAL_BREAKPOINT: dexManyFilesWithInlineCalls2.Second.kt: Breakpoint 1
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
package dexSeveralInlineCallsFromOtherFile
|
||||
|
||||
inline fun inlineFun() {
|
||||
var i = 1
|
||||
// Breakpoint 1
|
||||
i++
|
||||
i++
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package dexSeveralInlineCallsFromOtherFile
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
//Breakpoint!
|
||||
firstCall()
|
||||
secondCall()
|
||||
}
|
||||
|
||||
fun firstCall() {
|
||||
inlineFun()
|
||||
}
|
||||
|
||||
fun secondCall() {
|
||||
inlineFun()
|
||||
}
|
||||
|
||||
// RESUME: 2
|
||||
// ADDITIONAL_BREAKPOINT: dexSeveralInlineCallsFromOtherFile.Other.kt: Breakpoint 1
|
||||
@@ -0,0 +1,12 @@
|
||||
package dexStopInInlineFun
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
inlineFun()
|
||||
}
|
||||
|
||||
inline fun inlineFun() {
|
||||
var i = 1
|
||||
//Breakpoint!
|
||||
i++
|
||||
i++
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package dexStopInInlineInOtherFile
|
||||
|
||||
inline fun inlineFun() {
|
||||
var i = 1
|
||||
// Breakpoint 1
|
||||
i++
|
||||
i++
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package dexStopInInlineInOtherFile
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
inlineFun()
|
||||
}
|
||||
|
||||
// ADDITIONAL_BREAKPOINT: dexStopInInlineInOtherFile.Other.kt: Breakpoint 1
|
||||
@@ -52,7 +52,7 @@ abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestBase() {
|
||||
val fileText = FileUtil.loadFile(File(path))
|
||||
|
||||
configureSettings(fileText)
|
||||
|
||||
createAdditionalBreakpoints(fileText)
|
||||
createDebugProcess(path)
|
||||
|
||||
val prefix = "// $command: "
|
||||
|
||||
@@ -34,7 +34,7 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class StepInto extends AbstractKotlinSteppingTest {
|
||||
public void testAllFilesPresentInStepInto() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectFunFromClass.kt")
|
||||
@@ -121,7 +121,7 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SmartStepInto extends AbstractKotlinSteppingTest {
|
||||
public void testAllFilesPresentInSmartStepInto() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectFunFromClass.kt")
|
||||
@@ -214,7 +214,7 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInStepIntoOnly() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepInto"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepInto"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("continueLabel.kt")
|
||||
@@ -313,7 +313,7 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class StepOut extends AbstractKotlinSteppingTest {
|
||||
public void testAllFilesPresentInStepOut() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepOut"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepOut"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("fwBackingField.kt")
|
||||
@@ -370,7 +370,19 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class StepOver extends AbstractKotlinSteppingTest {
|
||||
public void testAllFilesPresentInStepOver() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepOver"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/stepOver"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("dexStopInInlineFun.kt")
|
||||
public void testDexStopInInlineFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/dexStopInInlineFun.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dexStopInInlineInOtherFile.kt")
|
||||
public void testDexStopInInlineInOtherFile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOver/dexStopInInlineInOtherFile.kt");
|
||||
doStepOverTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ifCapturedVariableKt9118.kt")
|
||||
@@ -475,7 +487,7 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Filters extends AbstractKotlinSteppingTest {
|
||||
public void testAllFilesPresentInFilters() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/filters"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/filters"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("checkNotNull.kt")
|
||||
@@ -556,7 +568,7 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Custom extends AbstractKotlinSteppingTest {
|
||||
public void testAllFilesPresentInCustom() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/custom"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/custom"), Pattern.compile("^([^.]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("crossinlineLiteral.kt")
|
||||
@@ -565,6 +577,24 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
||||
doCustomTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dexManyFilesWithInlineCalls1.kt")
|
||||
public void testDexManyFilesWithInlineCalls1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/dexManyFilesWithInlineCalls1.kt");
|
||||
doCustomTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dexManyFilesWithInlineCalls2.kt")
|
||||
public void testDexManyFilesWithInlineCalls2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/dexManyFilesWithInlineCalls2.kt");
|
||||
doCustomTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dexSeveralInlineCallsFromOtherFile.kt")
|
||||
public void testDexSeveralInlineCallsFromOtherFile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/dexSeveralInlineCallsFromOtherFile.kt");
|
||||
doCustomTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("funLiteral.kt")
|
||||
public void testFunLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/funLiteral.kt");
|
||||
|
||||
@@ -22,16 +22,16 @@ import org.jetbrains.org.objectweb.asm.ClassWriter
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.io.File
|
||||
|
||||
val DEX_BEFORE_PATCH_EXTENSION = "before_dex"
|
||||
|
||||
fun patchDexTests(dir: File) {
|
||||
dir.listFiles({ file -> file.isDirectory && file.name.startsWith("dex") }).forEach { dir ->
|
||||
dir.listFiles { testOutputFile -> testOutputFile.extension == "class" }.forEach { classFile ->
|
||||
applyDexLikePatch(classFile)
|
||||
}
|
||||
dir.listFiles { testOutputFile -> testOutputFile.extension == "class" }.forEach(::applyDexLikePatch)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyDexLikePatch(file: File) {
|
||||
file.copyTo(File(file.absolutePath + ".temp"))
|
||||
file.copyTo(File(file.absolutePath + ".$DEX_BEFORE_PATCH_EXTENSION"))
|
||||
|
||||
val reader = ClassReader(file.readBytes())
|
||||
val writer = ClassWriter(ClassWriter.COMPUTE_FRAMES)
|
||||
|
||||
Reference in New Issue
Block a user