Debugger: Implement EvaluatorBuilder for evaluate expression for kotlin files
This commit is contained in:
@@ -3,4 +3,7 @@
|
|||||||
name='com.intellij.debugger.ExecutionWithDebuggerToolsTestCase void onBreakpoint(com.intellij.debugger.engine.SuspendContextRunnable) 0'>
|
name='com.intellij.debugger.ExecutionWithDebuggerToolsTestCase void onBreakpoint(com.intellij.debugger.engine.SuspendContextRunnable) 0'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
<item name='com.intellij.debugger.SourcePosition'>
|
||||||
|
<annotation name='org.jetbrains.annotations.Nullable'/>
|
||||||
|
</item>
|
||||||
</root>
|
</root>
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
<root>
|
<root>
|
||||||
|
<item name='com.intellij.debugger.engine.DebugProcessImpl com.intellij.debugger.jdi.VirtualMachineProxyImpl getVirtualMachineProxy()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item
|
<item
|
||||||
name='com.intellij.debugger.engine.MethodFilter boolean locationMatches(com.intellij.debugger.engine.DebugProcessImpl, com.sun.jdi.Location) 0'>
|
name='com.intellij.debugger.engine.MethodFilter boolean locationMatches(com.intellij.debugger.engine.DebugProcessImpl, com.sun.jdi.Location) 0'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
<root>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 1'>
|
||||||
|
<annotation name='org.jetbrains.annotations.Nullable'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 2'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createPresentationCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createPresentationCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createPresentationCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 1'>
|
||||||
|
<annotation name='org.jetbrains.annotations.Nullable'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.CodeFragmentFactory com.intellij.psi.JavaCodeFragment createPresentationCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 2'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 1'>
|
||||||
|
<annotation name='org.jetbrains.annotations.Nullable'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory com.intellij.psi.JavaCodeFragment createCodeFragment(com.intellij.debugger.engine.evaluation.TextWithImports, com.intellij.psi.PsiElement, com.intellij.openapi.project.Project) 2'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.EvaluateException'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil com.intellij.debugger.engine.evaluation.EvaluateException createEvaluateException(java.lang.String)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil com.intellij.debugger.engine.evaluation.EvaluateException createEvaluateException(java.lang.String, java.lang.Throwable) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.Nullable'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil com.intellij.debugger.engine.evaluation.EvaluateException createEvaluateException(java.lang.String, java.lang.Throwable) 1'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil com.intellij.debugger.engine.evaluation.EvaluateException createEvaluateException(java.lang.Throwable)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.EvaluationContextImpl'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.TextWithImports'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.TextWithImports com.intellij.debugger.engine.evaluation.CodeFragmentKind getKind()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.TextWithImports java.lang.String getText()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.TextWithImports java.lang.String toExternalForm()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.TextWithImports void setText(java.lang.String) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<root>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.expression.Evaluator java.lang.Object evaluate(com.intellij.debugger.engine.evaluation.EvaluationContextImpl) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator build(com.intellij.psi.PsiElement, com.intellij.debugger.SourcePosition)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator build(com.intellij.psi.PsiElement, com.intellij.debugger.SourcePosition) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator build(com.intellij.psi.PsiElement, com.intellij.debugger.SourcePosition) 1'>
|
||||||
|
<annotation name='org.jetbrains.annotations.Nullable'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator build(com.intellij.psi.PsiElement, com.intellij.debugger.SourcePosition) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl.Builder com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator buildElement(com.intellij.psi.PsiElement) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
</root>
|
||||||
@@ -1,4 +1,12 @@
|
|||||||
<root>
|
<root>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.impl.EditorTextProvider com.intellij.debugger.engine.evaluation.TextWithImports getEditorText(com.intellij.psi.PsiElement) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item
|
||||||
|
name='com.intellij.debugger.impl.EditorTextProvider com.intellij.openapi.util.Pair<com.intellij.psi.PsiElement,com.intellij.openapi.util.TextRange> findExpression(com.intellij.psi.PsiElement, boolean) 0'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item name='com.intellij.debugger.impl.OutputChecker'>
|
<item name='com.intellij.debugger.impl.OutputChecker'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<root>
|
||||||
|
<item name='com.intellij.debugger.jdi.VirtualMachineProxyImpl com.sun.jdi.VirtualMachine getVirtualMachine()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
</root>
|
||||||
@@ -26,6 +26,7 @@ import java.io.StringWriter;
|
|||||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||||
public class ClassBuilderFactories {
|
public class ClassBuilderFactories {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static ClassBuilderFactory TEST = new ClassBuilderFactory() {
|
public static ClassBuilderFactory TEST = new ClassBuilderFactory() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -54,6 +55,7 @@ public class ClassBuilderFactories {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static ClassBuilderFactory BINARIES = new ClassBuilderFactory() {
|
public static ClassBuilderFactory BINARIES = new ClassBuilderFactory() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -46,5 +46,5 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
|
|
||||||
override fun getFileType() = JetFileType.INSTANCE
|
override fun getFileType() = JetFileType.INSTANCE
|
||||||
|
|
||||||
override fun getEvaluatorBuilder() = null
|
override fun getEvaluatorBuilder() = KotlinEvaluationBuilder
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.jet.plugin.debugger.evaluate
|
||||||
|
|
||||||
|
import org.jetbrains.jet.plugin.debugger.evaluate.*
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.debugger.SourcePosition
|
||||||
|
import com.intellij.debugger.engine.evaluation.*
|
||||||
|
import com.intellij.debugger.engine.evaluation.expression.*
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM
|
||||||
|
import com.google.common.base.Predicates
|
||||||
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils
|
||||||
|
import org.jetbrains.jet.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.jet.codegen.ClassBuilderFactories
|
||||||
|
import java.util.Collections
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.jet.codegen.state.Progress
|
||||||
|
import org.jetbrains.jet.codegen.CompilationErrorHandler
|
||||||
|
import org.jetbrains.jet.codegen.KotlinCodegenFacade
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.testFramework.LightVirtualFile
|
||||||
|
import org.jetbrains.jet.plugin.JetLanguage
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
|
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||||
|
import com.intellij.psi.PsiFileFactory
|
||||||
|
import com.intellij.openapi.vfs.CharsetToolkit
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes.ASM5
|
||||||
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
|
import com.intellij.openapi.util.Computable
|
||||||
|
import org.jetbrains.eval4j.*
|
||||||
|
import org.jetbrains.eval4j.jdi.JDIEval
|
||||||
|
import org.jetbrains.eval4j.jdi.asJdiValue
|
||||||
|
import org.jetbrains.eval4j.jdi.makeInitialFrame
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||||
|
import org.jetbrains.jet.plugin.caches.resolve.KotlinDeclarationsCache
|
||||||
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||||
|
import org.jetbrains.jet.OutputFileCollection
|
||||||
|
|
||||||
|
object KotlinEvaluationBuilder: EvaluatorBuilder {
|
||||||
|
override fun build(codeFragment: PsiElement, position: SourcePosition?): ExpressionEvaluator {
|
||||||
|
return ExpressionEvaluatorImpl(KotlinEvaluator(codeFragment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinEvaluator(val codeFragment: PsiElement) : Evaluator {
|
||||||
|
override fun evaluate(context: EvaluationContextImpl): Any? {
|
||||||
|
return ApplicationManager.getApplication()?.runReadAction(object: Computable<Any> {
|
||||||
|
override fun compute(): Any? {
|
||||||
|
val fileText = template.replace("!EXPRESSION!", codeFragment.getText())
|
||||||
|
val virtualFile = LightVirtualFile("debugFile.kt", JetLanguage.INSTANCE, fileText)
|
||||||
|
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET)
|
||||||
|
val file = (PsiFileFactory.getInstance(codeFragment.getProject()) as PsiFileFactoryImpl).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false) as JetFile
|
||||||
|
|
||||||
|
val analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationAndCheckForErrors(
|
||||||
|
file.getProject(),
|
||||||
|
Collections.singletonList(file),
|
||||||
|
Predicates.alwaysTrue())
|
||||||
|
//val analyzeExhaust = AnalyzerFacadeWithCache.analyzeFileWithCache(file)
|
||||||
|
//analyzeExhaust.forceResolveAll()
|
||||||
|
|
||||||
|
val bindingContext = analyzeExhaust.getBindingContext()
|
||||||
|
try {
|
||||||
|
analyzeExhaust.throwIfError()
|
||||||
|
AnalyzingUtils.throwExceptionOnErrors(bindingContext)
|
||||||
|
}
|
||||||
|
catch (e: IllegalStateException) {
|
||||||
|
throw EvaluateExceptionUtil.createEvaluateException(e.getMessage())
|
||||||
|
}
|
||||||
|
|
||||||
|
val state = GenerationState(
|
||||||
|
file.getProject(),
|
||||||
|
ClassBuilderFactories.BINARIES,
|
||||||
|
bindingContext,
|
||||||
|
Collections.singletonList(file),
|
||||||
|
true)
|
||||||
|
|
||||||
|
KotlinCodegenFacade.compileCorrectFiles(state) {
|
||||||
|
e, msg ->
|
||||||
|
exception("$msg\n${e?.getMessage() ?: ""}")
|
||||||
|
}
|
||||||
|
|
||||||
|
// KT-4509
|
||||||
|
val outputFiles = (state.getFactory() : OutputFileCollection).asList().filter { it.relativePath != "$packageInternalName.class" }
|
||||||
|
if (outputFiles.size() != 1) exception("More than one class file found. Note that lambdas, classes and objects are unsupported yet.\n${outputFiles.makeString("\n")}")
|
||||||
|
|
||||||
|
var resultValue: Value? = null
|
||||||
|
|
||||||
|
val virtualMachine = context.getDebugProcess().getVirtualMachineProxy().getVirtualMachine()
|
||||||
|
|
||||||
|
ClassReader(outputFiles.first().asByteArray()).accept(object : ClassVisitor(ASM5) {
|
||||||
|
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||||
|
if (name == "debugFun") {
|
||||||
|
return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
|
||||||
|
override fun visitEnd() {
|
||||||
|
val value = interpreterLoop(
|
||||||
|
this,
|
||||||
|
makeInitialFrame(this, listOf()),
|
||||||
|
JDIEval(virtualMachine,
|
||||||
|
context.getClassLoader()!!,
|
||||||
|
context.getSuspendContext().getThread()?.getThreadReference()!!)
|
||||||
|
)
|
||||||
|
|
||||||
|
resultValue = when (value) {
|
||||||
|
is ValueReturned -> value.result
|
||||||
|
is ExceptionThrown -> exception(value.exception.toString())
|
||||||
|
is AbnormalTermination -> exception(value.message)
|
||||||
|
else -> throw IllegalStateException("Unknown result value produced by eval4j")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.visitMethod(access, name, desc, signature, exceptions)
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
if (resultValue == null) exception("Cannot evaluate expression")
|
||||||
|
|
||||||
|
return resultValue!!.asJdiValue(virtualMachine, resultValue!!.asmType)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModifier(): Modifier? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun exception(msg: String) = throw EvaluateExceptionUtil.createEvaluateException(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val template = """
|
||||||
|
package packageForDebugger
|
||||||
|
|
||||||
|
fun debugFun() = run {
|
||||||
|
!EXPRESSION!
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
private val packageInternalName = PackageClassUtils.getPackageClassFqName(FqName("packageForDebugger")).asString().replace(".", "/")
|
||||||
Reference in New Issue
Block a user