diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionCache.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionCache.kt index b8be4a18b5d..4f690654299 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionCache.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluateExpressionCache.kt @@ -16,22 +16,22 @@ package org.jetbrains.kotlin.idea.debugger.evaluate -import com.intellij.openapi.project.Project -import com.intellij.psi.util.CachedValuesManager -import com.intellij.psi.util.CachedValueProvider -import com.intellij.psi.util.PsiModificationTracker -import org.jetbrains.kotlin.psi.KtCodeFragment import com.intellij.debugger.SourcePosition import com.intellij.debugger.engine.evaluation.EvaluationContextImpl -import java.util.ArrayList import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.project.Project +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiModificationTracker import com.intellij.util.containers.MultiMap -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.apache.log4j.Logger import org.jetbrains.eval4j.Value +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.util.application.runReadAction +import org.jetbrains.kotlin.psi.KtCodeFragment +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.types.KotlinType +import java.util.* class KotlinEvaluateExpressionCache(val project: Project) { @@ -89,7 +89,6 @@ class KotlinEvaluateExpressionCache(val project: Project) { val bytecodes: ByteArray, val additionalClasses: List>, val sourcePosition: SourcePosition, - val funName: String, val parameters: ParametersDescriptor ) diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt index c6f83caeabe..5fe1fc1988b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/KotlinEvaluationBuilder.kt @@ -81,7 +81,8 @@ import java.util.* internal val RECEIVER_NAME = "\$receiver" internal val THIS_NAME = "this" -val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluator") +internal val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluator") +internal val GENERATED_FUNCTION_NAME = "generated_for_debugger_kotlin_rulezzzz" private val DEBUG_MODE = false @@ -197,9 +198,6 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour } } - val funName = runReadAction { extractedFunction.name } - ?: throw IllegalStateException("Extracted function should have a name: ${extractedFunction.text}") - val additionalFiles = if (outputFiles.size < 2) emptyList() else outputFiles.subList(1, outputFiles.size).map { getClassName(it.relativePath) to it.asByteArray() } @@ -207,7 +205,6 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour outputFiles.first().asByteArray(), additionalFiles, sourcePosition, - funName, parametersDescriptor) } @@ -225,7 +222,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour var resultValue: InterpreterResult? = null ClassReader(compiledData.bytecodes).accept(object : ClassVisitor(ASM5) { override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor? { - if (name == compiledData.funName) { + if (name == GENERATED_FUNCTION_NAME) { val argumentTypes = Type.getArgumentTypes(desc) val args = context.getArgumentsForEval4j(compiledData.parameters, argumentTypes) @@ -255,7 +252,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour } }, 0) - return resultValue ?: throw IllegalStateException("resultValue is null: cannot find method ${compiledData.funName}") + return resultValue ?: throw IllegalStateException("resultValue is null: cannot find method " + GENERATED_FUNCTION_NAME) } private fun boxOrUnboxArgumentIfNeeded(eval: JDIEval, argumentValue: Value, parameterType: Type): Value { @@ -469,7 +466,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour } private val template = """ -package packageForDebugger +!PACKAGE! !IMPORT_LIST! @@ -481,17 +478,17 @@ private fun createFileForDebugger(codeFragment: KtCodeFragment, ): KtFile { val containingContextFile = codeFragment.getContextContainingFile() val importsFromContextFile = containingContextFile?.importList?.let { it.text + "\n" } ?: "" - val packageFromContextFile = containingContextFile?.packageName?.let { - if (it.isNotBlank()) "import $it.*\n" else null - } ?: "" var fileText = template.replace( "!IMPORT_LIST!", - packageFromContextFile - + importsFromContextFile - + codeFragment.importsToString().split(KtCodeFragment.IMPORT_SEPARATOR).joinToString("\n") + importsFromContextFile + codeFragment.importsToString().split(KtCodeFragment.IMPORT_SEPARATOR).joinToString("\n") ) + val packageFromContextFile = containingContextFile?.packageName?.let { + if (it.isNotBlank()) "package $it" else "" + } ?: "" + fileText = fileText.replace("!PACKAGE!", packageFromContextFile) + val extractedFunctionText = extractedFunction.text assert(extractedFunctionText != null) { "Text of extracted function shouldn't be null" } fileText = fileText.replace("!FUNCTION!", extractedFunction.text!!) diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt index 71c082ba750..a0dd580a163 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt @@ -100,7 +100,7 @@ fun getFunctionForExtractedFragment( val generatorOptions = ExtractionGeneratorOptions(inTempFile = true, flexibleTypesAllowed = true, - allowDummyName = true, + dummyName = GENERATED_FUNCTION_NAME, allowExpressionBody = false) return ExtractionGeneratorConfiguration(validationResult.descriptor, generatorOptions).generateDeclaration() } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt index 0355d0c39c8..efd6ed2ba41 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt @@ -414,7 +414,7 @@ data class ExtractionGeneratorOptions( val inTempFile: Boolean = false, val target: ExtractionTarget = ExtractionTarget.FUNCTION, val flexibleTypesAllowed: Boolean = false, - val allowDummyName: Boolean = false, + val dummyName: String? = null, val allowExpressionBody: Boolean = true, val delayInitialOccurrenceReplacement: Boolean = false ) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt index 213d266d7f7..82093066cda 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt @@ -93,7 +93,7 @@ fun ExtractionGeneratorConfiguration.getDeclarationText( builder.receiver(if (isFunctionType) "($receiverTypeAsString)" else receiverTypeAsString) } - builder.name(if (descriptor.name == "" && generatorOptions.allowDummyName) "myFun" else descriptor.name) + builder.name(generatorOptions.dummyName ?: descriptor.name) descriptor.parameters.forEach { parameter -> builder.param(parameter.name, diff --git a/idea/testData/debugger/tinyApp/outs/_kt.out b/idea/testData/debugger/tinyApp/outs/_kt.out index 81a5891814a..0e547b84ef1 100644 --- a/idea/testData/debugger/tinyApp/outs/_kt.out +++ b/idea/testData/debugger/tinyApp/outs/_kt.out @@ -3,6 +3,7 @@ LineBreakpoint created at .kt.kt:5 Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' .kt.kt:5 Compile bytecode for 1 + 1 +Compile bytecode for Test(1).a Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/.kt.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/.kt.kt index 2e6e1e793f0..8c7e5a4749c 100644 --- a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/.kt.kt +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/.kt.kt @@ -5,5 +5,10 @@ fun main(args: Array) { args.size() } +class Test(val a: Int) + // EXPRESSION: 1 + 1 // RESULT: 2: I + +// EXPRESSION: Test(1).a +// RESULT: 1: I diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceObject.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceObject.kt index 8dd8114e733..da6fe34da19 100644 --- a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceObject.kt +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceObject.kt @@ -16,4 +16,4 @@ interface T { // RESULT: 1: I // EXPRESSION: object: T {} -// RESULT: instance of packageForDebugger.DebugFileKt$myFun$1(id=ID): LpackageForDebugger/DebugFileKt$myFun$1; \ No newline at end of file +// RESULT: instance of ceObject.DebugFileKt$generated_for_debugger_kotlin_rulezzzz$1(id=ID): LceObject/DebugFileKt$generated_for_debugger_kotlin_rulezzzz$1; \ No newline at end of file