From 2a2d7cd35888ce9c0c43e2c95db0e0f539a47164 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 21 Jul 2016 18:59:27 +0300 Subject: [PATCH] Emulate debugging after dexing for stepping tests with 'dex' prefix (KT-12896) Remove SourceDebugExtension attribute from resulting class files #KT-12896 In Progress --- .../idea/debugger/KotlinDebuggerTestCase.java | 6 ++- .../idea/debugger/dexLikeBytecodePatch.kt | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/dexLikeBytecodePatch.kt diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestCase.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestCase.java index 2892d74de7c..89b76316273 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestCase.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinDebuggerTestCase.java @@ -60,14 +60,14 @@ import java.util.Collection; import java.util.List; public abstract class KotlinDebuggerTestCase extends DescriptorTestCase { - protected static final String TINY_APP = PluginTestCaseBase.getTestDataPathBase() + "/debugger/tinyApp"; + private static final String TINY_APP = PluginTestCaseBase.getTestDataPathBase() + "/debugger/tinyApp"; private static boolean IS_TINY_APP_COMPILED = false; private static File CUSTOM_LIBRARY_JAR; private static final File CUSTOM_LIBRARY_SOURCES = new File(PluginTestCaseBase.getTestDataPathBase() + "/debugger/customLibraryForTinyApp"); protected static final String KOTLIN_LIBRARY_NAME = "KotlinLibrary"; - protected static final String CUSTOM_LIBRARY_NAME = "CustomLibrary"; + private static final String CUSTOM_LIBRARY_NAME = "CustomLibrary"; @Override protected OutputChecker initOutputChecker() { @@ -138,6 +138,8 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase { throw new RuntimeException(e); } + DexLikeBytecodePatchKt.patchDexTests(outDir); + IS_TINY_APP_COMPILED = true; } diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/dexLikeBytecodePatch.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/dexLikeBytecodePatch.kt new file mode 100644 index 00000000000..0844b6150d5 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/dexLikeBytecodePatch.kt @@ -0,0 +1,53 @@ +/* + * 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 org.jetbrains.org.objectweb.asm.ClassReader +import org.jetbrains.org.objectweb.asm.ClassVisitor +import org.jetbrains.org.objectweb.asm.ClassWriter +import org.jetbrains.org.objectweb.asm.Opcodes +import java.io.File + +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) + } + } +} + +private fun applyDexLikePatch(file: File) { + file.copyTo(File(file.absolutePath + ".temp")) + + val reader = ClassReader(file.readBytes()) + val writer = ClassWriter(ClassWriter.COMPUTE_FRAMES) + + val visitor = writer + .withRemoveSourceDebugExtensionVisitor() + + reader.accept(visitor, 0) + + file.writeBytes(writer.toByteArray()) +} + +private fun ClassVisitor.withRemoveSourceDebugExtensionVisitor(): ClassVisitor { + return object : ClassVisitor(Opcodes.ASM5, this) { + override fun visitSource(source: String?, debug: String?) { + super.visitSource(source, null) + } + } +} \ No newline at end of file