Add debug log for evaluate expression

This commit is contained in:
Natalia Ukhorskaya
2015-11-02 16:15:30 +03:00
parent 6c61d437f1
commit 1e0b70247b
2 changed files with 46 additions and 16 deletions
@@ -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<Type>): List<Value> {
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}")
}
}
}
}
@@ -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)