From 1e0b70247beab3736ec4a9301efaace198112aa7 Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Mon, 2 Nov 2015 16:15:30 +0300 Subject: [PATCH] Add debug log for evaluate expression --- .../evaluate/KotlinEvaluationBuilder.kt | 42 +++++++++++++++---- .../extractFunctionForDebuggerUtil.kt | 20 +++++---- 2 files changed, 46 insertions(+), 16 deletions(-) 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 f831ff1e996..628eaefca90 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,9 @@ import java.util.* internal val RECEIVER_NAME = "\$receiver" internal val THIS_NAME = "this" -val logger = Logger.getInstance(KotlinEvaluator::class.java) +val LOG = Logger.getInstance("#org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluator") + +private val DEBUG_MODE = false object KotlinEvaluationBuilder: EvaluatorBuilder { override fun build(codeFragment: PsiElement, position: SourcePosition?): ExpressionEvaluator { @@ -110,7 +112,7 @@ object KotlinEvaluationBuilder: EvaluatorBuilder { attachmentByPsiFile(codeFragment), Attachment("breakpoint.info", "line: ${position.line}")) - logger.error("Trying to evaluate ${codeFragment.javaClass} with context ${codeFragment.context?.javaClass}", mergeAttachments(*attachments)) + LOG.error("Trying to evaluate ${codeFragment.javaClass} with context ${codeFragment.context?.javaClass}", mergeAttachments(*attachments)) throw EvaluateExceptionUtil.createEvaluateException("Couldn't evaluate kotlin expression in this context") } @@ -144,6 +146,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour throw e } catch(e: ProcessCanceledException) { + LOG.debug(e) exception(e) } catch(e: VMDisconnectedException) { @@ -153,7 +156,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour val attachments = arrayOf(attachmentByPsiFile(sourcePosition.file), attachmentByPsiFile(codeFragment), Attachment("breakpoint.info", "line: ${sourcePosition.line}")) - logger.error(LogMessageEx.createEvent( + LOG.error(LogMessageEx.createEvent( "Couldn't evaluate expression", ExceptionUtil.getThrowableText(e), mergeAttachments(*attachments))) @@ -176,11 +179,24 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour val parametersDescriptor = extractionResult.getParametersForDebugger(codeFragment) val extractedFunction = extractionResult.declaration as KtNamedFunction + if (LOG.isDebugEnabled) { + LOG.debug("Extracted function:\n" + runReadAction { extractedFunction.text }) + } + val classFileFactory = createClassFileFactory(codeFragment, extractedFunction, context, parametersDescriptor) val outputFiles = classFileFactory.asList().filterClassFiles() .sortedBy { it.relativePath.length } + for (file in outputFiles) { + if (LOG.isDebugEnabled) { + LOG.debug("Output file generated: ${file.relativePath}") + } + if (DEBUG_MODE) { + println(file.asText()) + } + } + val funName = runReadAction { extractedFunction.name } ?: throw IllegalStateException("Extracted function should have a name: ${extractedFunction.text}") @@ -322,12 +338,16 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour private fun EvaluationContextImpl.getArgumentsForEval4j(parameters: ParametersDescriptor, parameterTypes: Array): List { val frameVisitor = FrameVisitor(this) return parameters.zip(parameterTypes).map { - if (it.first.value != null) { + val result = if (it.first.value != null) { it.first.value!! } else { frameVisitor.findValue(it.first.callText, it.second, checkType = false, failIfNotFound = true)!! } + if (LOG.isDebugEnabled) { + LOG.debug("Parameter for eval4j: name = ${it.first.callText}, type = ${it.second}, value = $result") + } + result } } @@ -339,6 +359,9 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour ): ClassFileFactory { return runReadAction { val jetFile = createFileForDebugger(codeFragment, extractedFunction) + if (LOG.isDebugEnabled) { + LOG.debug("File for eval4j:\n${runReadAction { jetFile.text }}") + } val (bindingContext, moduleDescriptor, files) = jetFile.checkForErrors(true) @@ -351,7 +374,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour val state = GenerationState( jetFile.project, - ClassBuilderFactories.BINARIES, + if (!DEBUG_MODE) ClassBuilderFactories.BINARIES else ClassBuilderFactories.TEST, moduleDescriptor, bindingContext, files, @@ -373,9 +396,9 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour val paramRef = valueParameter.typeReference if (paramRef == null) { - logger.error("Each parameter for extracted function should have a type reference", - Attachment("codeFragment.txt", codeFragment.text), - Attachment("extractedFunction.txt", extractedFunction.text)) + LOG.error("Each parameter for extracted function should have a type reference", + Attachment("codeFragment.txt", codeFragment.text), + Attachment("extractedFunction.txt", extractedFunction.text)) exception("An exception occurs during Evaluate Expression Action") } @@ -397,6 +420,9 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour val localVariable = visitor.findValue(localVariableName, asmType = null, checkType = false, failIfNotFound = false) ?: exception("Couldn't find local variable this in current frame to get classType for anonymous type $paramAnonymousType}") record(CodegenBinding.ASM_TYPE, declarationDescriptor, localVariable.asmType) + if (LOG.isDebugEnabled) { + LOG.debug("Asm type ${localVariable.asmType.className} was recorded for ${declarationDescriptor.name}") + } } } } 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 19c94e77473..c47810091c8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt @@ -43,13 +43,13 @@ fun getFunctionForExtractedFragment( fun getErrorMessageForExtractFunctionResult(analysisResult: AnalysisResult, tmpFile: KtFile): String { if (KotlinInternalMode.enabled) { - logger.error("Couldn't extract function for debugger:\n" + - "FILE NAME: ${breakpointFile.name}\n" + - "BREAKPOINT LINE: $breakpointLine\n" + - "CODE FRAGMENT:\n${codeFragment.text}\n" + - "ERRORS:\n${analysisResult.messages.map { "$it: ${it.renderMessage()}" }.joinToString("\n")}\n" + - "TMPFILE_TEXT:\n${tmpFile.text}\n" + - "FILE TEXT: \n${breakpointFile.text}\n") + LOG.error("Couldn't extract function for debugger:\n" + + "FILE NAME: ${breakpointFile.name}\n" + + "BREAKPOINT LINE: $breakpointLine\n" + + "CODE FRAGMENT:\n${codeFragment.text}\n" + + "ERRORS:\n${analysisResult.messages.map { "$it: ${it.renderMessage()}" }.joinToString("\n")}\n" + + "TMPFILE_TEXT:\n${tmpFile.text}\n" + + "FILE TEXT: \n${breakpointFile.text}\n") } return analysisResult.messages.map { errorMessage -> val message = when(errorMessage) { @@ -75,6 +75,10 @@ fun getFunctionForExtractedFragment( if (newDebugExpressions.isEmpty()) return null val tmpFile = newDebugExpressions.first().getContainingKtFile() + if (LOG.isDebugEnabled) { + LOG.debug("TMP_FILE:\n${runReadAction { tmpFile.text }}") + } + val targetSibling = tmpFile.declarations.firstOrNull() ?: return null val options = ExtractionOptions(inferUnitTypeForUnusedValues = false, @@ -262,7 +266,7 @@ private fun addDebugExpressionBeforeContextElement(codeFragment: KtCodeFragment, is KtExpression -> { val newDebugExpression = parent.addBefore(expr, elementBefore) if (newDebugExpression == null) { - logger.error("Couldn't insert debug expression ${expr.text} to context file before ${elementBefore.text}") + LOG.error("Couldn't insert debug expression ${expr.text} to context file before ${elementBefore.text}") return emptyList() } parent.addBefore(psiFactory.createNewLine(), elementBefore)