Cache bytecodes for JetCodeFragment in Evaluate Expression
This commit is contained in:
@@ -612,7 +612,8 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testClass(javaClass<AbstractKotlinEvaluateExpressionTest>()) {
|
testClass(javaClass<AbstractKotlinEvaluateExpressionTest>()) {
|
||||||
model("debugger/tinyApp/src/evaluate")
|
model("debugger/tinyApp/src/evaluate/singleBreakpoint", testMethod = "doSingleBreakpointTest")
|
||||||
|
model("debugger/tinyApp/src/evaluate/multipleBreakpoints", testMethod = "doMultipleBreakpointsTest")
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass(javaClass<AbstractStubBuilderTest>()) {
|
testClass(javaClass<AbstractStubBuilderTest>()) {
|
||||||
|
|||||||
@@ -155,6 +155,9 @@
|
|||||||
<projectService serviceInterface="org.jetbrains.jet.asJava.KotlinLightClassForPackage$FileStubCache"
|
<projectService serviceInterface="org.jetbrains.jet.asJava.KotlinLightClassForPackage$FileStubCache"
|
||||||
serviceImplementation="org.jetbrains.jet.asJava.KotlinLightClassForPackage$FileStubCache"/>
|
serviceImplementation="org.jetbrains.jet.asJava.KotlinLightClassForPackage$FileStubCache"/>
|
||||||
|
|
||||||
|
<projectService serviceInterface="org.jetbrains.jet.plugin.debugger.evaluate.KotlinEvaluateExpressionCache"
|
||||||
|
serviceImplementation="org.jetbrains.jet.plugin.debugger.evaluate.KotlinEvaluateExpressionCache"/>
|
||||||
|
|
||||||
<errorHandler implementation="org.jetbrains.jet.plugin.reporter.KotlinReportSubmitter"/>
|
<errorHandler implementation="org.jetbrains.jet.plugin.reporter.KotlinReportSubmitter"/>
|
||||||
|
|
||||||
<internalFileTemplate name="Kotlin File"/>
|
<internalFileTemplate name="Kotlin File"/>
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* 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 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.jet.lang.psi.JetCodeFragment
|
||||||
|
import com.intellij.debugger.SourcePosition
|
||||||
|
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||||
|
import java.util.ArrayList
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
import com.intellij.util.containers.MultiMap
|
||||||
|
import org.jetbrains.jet.lang.types.JetType
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
|
import com.intellij.psi.JavaPsiFacade
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.jet.plugin.caches.resolve.JavaResolveExtension
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaClassImpl
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName
|
||||||
|
import org.jetbrains.jet.codegen.AsmUtil
|
||||||
|
|
||||||
|
class KotlinEvaluateExpressionCache(val project: Project) {
|
||||||
|
|
||||||
|
private val cachedCompiledData = CachedValuesManager.getManager(project).createCachedValue(
|
||||||
|
{
|
||||||
|
CachedValueProvider.Result<MultiMap<String, CompiledDataDescriptor>>(
|
||||||
|
MultiMap.create(), PsiModificationTracker.MODIFICATION_COUNT)
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
class object {
|
||||||
|
fun getInstance(project: Project) = ServiceManager.getService(project, javaClass<KotlinEvaluateExpressionCache>())!!
|
||||||
|
|
||||||
|
fun getOrCreateCompiledData(
|
||||||
|
codeFragment: JetCodeFragment,
|
||||||
|
sourcePosition: SourcePosition,
|
||||||
|
evaluationContext: EvaluationContextImpl,
|
||||||
|
create: (JetCodeFragment, SourcePosition) -> CompiledDataDescriptor
|
||||||
|
): CompiledDataDescriptor {
|
||||||
|
val evaluateExpressionCache = getInstance(codeFragment.getProject())
|
||||||
|
|
||||||
|
return synchronized(evaluateExpressionCache.cachedCompiledData) {
|
||||||
|
(): CompiledDataDescriptor ->
|
||||||
|
val cache = evaluateExpressionCache.cachedCompiledData.getValue()!!
|
||||||
|
val text = "${codeFragment.importsToString()}\n${codeFragment.getText()}"
|
||||||
|
|
||||||
|
val answer = cache[text].firstOrNull {
|
||||||
|
it.sourcePosition == sourcePosition || evaluateExpressionCache.canBeEvaluatedInThisContext(it, evaluationContext)
|
||||||
|
}
|
||||||
|
if (answer != null) return@synchronized answer
|
||||||
|
|
||||||
|
val newCompiledData = create(codeFragment, sourcePosition)
|
||||||
|
cache.putValue(text, newCompiledData)
|
||||||
|
|
||||||
|
return@synchronized newCompiledData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun canBeEvaluatedInThisContext(compiledData: CompiledDataDescriptor, context: EvaluationContextImpl): Boolean {
|
||||||
|
return compiledData.parameters.all { (p): Boolean ->
|
||||||
|
val (name, jetType) = p
|
||||||
|
val value = context.getFrameProxy()?.getStackFrame()?.findLocalVariable(name, failIfNotFound = false)
|
||||||
|
if (value == null) return@all false
|
||||||
|
|
||||||
|
val thisDescriptor = value.asmType.getClassDescriptor()
|
||||||
|
val superClassDescriptor = jetType.getConstructor().getDeclarationDescriptor() as? ClassDescriptor
|
||||||
|
return@all thisDescriptor != null && superClassDescriptor != null && DescriptorUtils.isSubclass(thisDescriptor, superClassDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Type.getClassDescriptor(): ClassDescriptor? {
|
||||||
|
if (AsmUtil.isPrimitive(this)) return null
|
||||||
|
|
||||||
|
val jvmName = JvmClassName.byInternalName(getInternalName()).getFqNameForClassNameWithoutDollars()
|
||||||
|
|
||||||
|
val platformClasses = JavaToKotlinClassMap.getInstance().mapPlatformClass(jvmName)
|
||||||
|
if (platformClasses.notEmpty) return platformClasses.first()
|
||||||
|
|
||||||
|
return ApplicationManager.getApplication()?.runReadAction<ClassDescriptor> {
|
||||||
|
val classes = JavaPsiFacade.getInstance(project).findClasses(jvmName.asString(), GlobalSearchScope.allScope(project))
|
||||||
|
if (classes.isEmpty()) null else JavaResolveExtension[project].resolveClass(JavaClassImpl(classes.first()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class CompiledDataDescriptor(val bytecodes: ByteArray, val sourcePosition: SourcePosition, val funName: String, val parameters: ParametersDescriptor)
|
||||||
|
|
||||||
|
class ParametersDescriptor : Iterable<Pair<String, JetType>> {
|
||||||
|
private val list = ArrayList<Pair<String, JetType>>()
|
||||||
|
|
||||||
|
fun add(name: String, jetType: JetType) {
|
||||||
|
list.add(name to jetType)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getParameterNames() = list.map { it.first }
|
||||||
|
|
||||||
|
override fun iterator() = list.iterator()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,10 +49,7 @@ import org.jetbrains.jet.codegen.ClassFileFactory
|
|||||||
import org.jetbrains.jet.OutputFileCollection
|
import org.jetbrains.jet.OutputFileCollection
|
||||||
import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
|
import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
|
||||||
import org.jetbrains.jet.lang.psi.JetCodeFragment
|
import org.jetbrains.jet.lang.psi.JetCodeFragment
|
||||||
import org.jetbrains.jet.lang.psi.JetImportList
|
|
||||||
import org.jetbrains.jet.lang.psi.codeFragmentUtil.skipVisibilityCheck
|
import org.jetbrains.jet.lang.psi.codeFragmentUtil.skipVisibilityCheck
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression
|
|
||||||
import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.Status
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import org.jetbrains.jet.codegen.CompilationErrorHandler
|
import org.jetbrains.jet.codegen.CompilationErrorHandler
|
||||||
import org.jetbrains.jet.lang.diagnostics.Severity
|
import org.jetbrains.jet.lang.diagnostics.Severity
|
||||||
@@ -60,6 +57,10 @@ import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages
|
|||||||
import com.sun.jdi.request.EventRequest
|
import com.sun.jdi.request.EventRequest
|
||||||
import com.sun.jdi.ObjectReference
|
import com.sun.jdi.ObjectReference
|
||||||
import com.intellij.debugger.engine.SuspendContext
|
import com.intellij.debugger.engine.SuspendContext
|
||||||
|
import org.jetbrains.jet.plugin.debugger.evaluate.KotlinEvaluateExpressionCache.*
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||||
|
import com.sun.jdi.StackFrame
|
||||||
|
import com.sun.jdi.VirtualMachine
|
||||||
|
|
||||||
object KotlinEvaluationBuilder: EvaluatorBuilder {
|
object KotlinEvaluationBuilder: EvaluatorBuilder {
|
||||||
override fun build(codeFragment: PsiElement, position: SourcePosition?): ExpressionEvaluator {
|
override fun build(codeFragment: PsiElement, position: SourcePosition?): ExpressionEvaluator {
|
||||||
@@ -86,9 +87,24 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
|||||||
val sourcePosition: SourcePosition
|
val sourcePosition: SourcePosition
|
||||||
) : Evaluator {
|
) : Evaluator {
|
||||||
override fun evaluate(context: EvaluationContextImpl): Any? {
|
override fun evaluate(context: EvaluationContextImpl): Any? {
|
||||||
|
var isCompiledDataFromCache = true
|
||||||
try {
|
try {
|
||||||
val compiledData = extractAndCompile(codeFragment, sourcePosition)
|
val compiledData = KotlinEvaluateExpressionCache.getOrCreateCompiledData(codeFragment, sourcePosition, context) {
|
||||||
return runEval4j(context, compiledData)
|
fragment, position ->
|
||||||
|
isCompiledDataFromCache = false
|
||||||
|
extractAndCompile(fragment, position)
|
||||||
|
}
|
||||||
|
val args = context.getArgumentsByNames(compiledData.parameters.getParameterNames())
|
||||||
|
val result = runEval4j(context, compiledData, args)
|
||||||
|
|
||||||
|
val virtualMachine = context.getDebugProcess().getVirtualMachineProxy().getVirtualMachine()
|
||||||
|
|
||||||
|
// If bytecode was taken from cache and exception was thrown - recompile bytecode and run eval4j again
|
||||||
|
if (result is ExceptionThrown && isCompiledDataFromCache) {
|
||||||
|
return runEval4j(context, extractAndCompile(codeFragment, sourcePosition), args).toJdiValue(virtualMachine)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toJdiValue(virtualMachine)
|
||||||
}
|
}
|
||||||
catch(e: EvaluateException) {
|
catch(e: EvaluateException) {
|
||||||
throw e
|
throw e
|
||||||
@@ -121,77 +137,79 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
|||||||
if (funName == null) {
|
if (funName == null) {
|
||||||
throw IllegalStateException("Extracted function should have a name: ${extractedFunction.getText()}")
|
throw IllegalStateException("Extracted function should have a name: ${extractedFunction.getText()}")
|
||||||
}
|
}
|
||||||
return CompiledDataDescriptor(outputFiles.first().asByteArray(), funName, extractedFunction.getParameterNamesForDebugger())
|
return CompiledDataDescriptor(outputFiles.first().asByteArray(), sourcePosition, funName, extractedFunction.getParametersForDebugger())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runEval4j(context: EvaluationContextImpl, compiledData: CompiledDataDescriptor): Any? {
|
private fun runEval4j(
|
||||||
|
context: EvaluationContextImpl,
|
||||||
|
compiledData: CompiledDataDescriptor,
|
||||||
|
args: List<Value>
|
||||||
|
): InterpreterResult {
|
||||||
val virtualMachine = context.getDebugProcess().getVirtualMachineProxy().getVirtualMachine()
|
val virtualMachine = context.getDebugProcess().getVirtualMachineProxy().getVirtualMachine()
|
||||||
|
|
||||||
var resultValue: Value? = null
|
var resultValue: InterpreterResult? = null
|
||||||
ClassReader(compiledData.bytecodes).accept(object : ClassVisitor(ASM5) {
|
ClassReader(compiledData.bytecodes).accept(object : ClassVisitor(ASM5) {
|
||||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||||
if (name == compiledData.funName) {
|
if (name == compiledData.funName) {
|
||||||
return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
|
return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
|
||||||
override fun visitEnd() {
|
override fun visitEnd() {
|
||||||
val value = interpreterLoop(
|
resultValue = interpreterLoop(
|
||||||
this,
|
this,
|
||||||
makeInitialFrame(this, context.getArgumentsByNames(compiledData.parameterNames)),
|
makeInitialFrame(this, args),
|
||||||
JDIEval(virtualMachine,
|
JDIEval(virtualMachine,
|
||||||
context.getClassLoader()!!,
|
context.getClassLoader()!!,
|
||||||
context.getSuspendContext().getThread()?.getThreadReference()!!, context.getSuspendContext().getInvokePolicy())
|
context.getSuspendContext().getThread()?.getThreadReference()!!,
|
||||||
|
context.getSuspendContext().getInvokePolicy())
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
return super.visitMethod(access, name, desc, signature, exceptions)
|
||||||
}
|
}
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
if (resultValue == null) {
|
return resultValue ?: throw IllegalStateException("resultValue is null: cannot find method ${compiledData.funName}")
|
||||||
throw IllegalStateException("resultValue is null: cannot find method ${compiledData.funName}")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return resultValue!!.asJdiValue(virtualMachine, resultValue!!.asmType)
|
private fun InterpreterResult.toJdiValue(vm: VirtualMachine): com.sun.jdi.Value? {
|
||||||
|
val jdiValue = when (this) {
|
||||||
|
is ValueReturned -> result
|
||||||
|
is ExceptionThrown -> exception(exception.toString())
|
||||||
|
is AbnormalTermination -> exception(message)
|
||||||
|
else -> throw IllegalStateException("Unknown result value produced by eval4j")
|
||||||
|
}
|
||||||
|
return jdiValue.asJdiValue(vm, jdiValue.asmType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SuspendContext.getInvokePolicy(): Int {
|
private fun SuspendContext.getInvokePolicy(): Int {
|
||||||
return if (getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD) ObjectReference.INVOKE_SINGLE_THREADED else 0
|
return if (getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD) ObjectReference.INVOKE_SINGLE_THREADED else 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JetNamedFunction.getParameterNamesForDebugger(): List<String> {
|
private fun JetNamedFunction.getParametersForDebugger(): ParametersDescriptor {
|
||||||
val result = arrayListOf<String>()
|
return ApplicationManager.getApplication()?.runReadAction(Computable {
|
||||||
if (getReceiverTypeRef() != null) {
|
val parameters = ParametersDescriptor()
|
||||||
result.add("this")
|
val bindingContext = getAnalysisResults().getBindingContext()
|
||||||
}
|
val descriptor = bindingContext[BindingContext.FUNCTION, this]
|
||||||
for (param in getValueParameters()) {
|
if (descriptor != null) {
|
||||||
result.add(param.getName()!!)
|
val receiver = descriptor.getReceiverParameter()
|
||||||
}
|
if (receiver != null) {
|
||||||
return result
|
parameters.add("this", receiver.getType())
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor.getValueParameters().forEach {
|
||||||
|
param ->
|
||||||
|
parameters.add(param.getName().asString(), param.getType())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters
|
||||||
|
})!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun EvaluationContextImpl.getArgumentsByNames(parameterNames: List<String>): List<Value> {
|
private fun EvaluationContextImpl.getArgumentsByNames(parameterNames: List<String>): List<Value> {
|
||||||
val frames = getFrameProxy()?.getStackFrame()
|
val frames = getFrameProxy()?.getStackFrame()
|
||||||
if (frames != null) {
|
if (frames != null) {
|
||||||
fun getValue(name: String): Value {
|
return parameterNames.map { frames.findLocalVariable(it)!! }
|
||||||
return try {
|
|
||||||
when (name) {
|
|
||||||
"this" -> frames.thisObject().asValue()
|
|
||||||
else -> frames.getValue(frames.visibleVariableByName(name)).asValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e: Exception) {
|
|
||||||
exception("Cannot get parameter value from local variables table: parameterName = ${name}. Note that captured parameters are unsupported yet.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parameterNames.map { getValue(it) }
|
|
||||||
}
|
}
|
||||||
return Collections.emptyList()
|
return Collections.emptyList()
|
||||||
}
|
}
|
||||||
@@ -283,6 +301,22 @@ fun checkForSyntacticErrors(file: JetFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class CompiledDataDescriptor(val bytecodes: ByteArray, val funName: String, val parameterNames: List<String>)
|
fun StackFrame.findLocalVariable(name: String, failIfNotFound: Boolean = true): Value? {
|
||||||
|
return try {
|
||||||
|
when (name) {
|
||||||
|
"this" -> thisObject().asValue()
|
||||||
|
else -> getValue(visibleVariableByName(name)).asValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
if (failIfNotFound) {
|
||||||
|
throw EvaluateExceptionUtil.createEvaluateException(
|
||||||
|
"Cannot find local variable: name = ${name}. Note that captured variables are unsupported yet.")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
LineBreakpoint created at clearCache.kt:12
|
||||||
|
LineBreakpoint created at clearCache.kt:20
|
||||||
|
LineBreakpoint created at clearCache.kt:31
|
||||||
|
LineBreakpoint created at clearCache.kt:42
|
||||||
|
LineBreakpoint created at clearCache.kt:52
|
||||||
|
LineBreakpoint created at clearCache.kt:60
|
||||||
|
LineBreakpoint created at clearCache.kt:78
|
||||||
|
LineBreakpoint created at clearCache.kt:86
|
||||||
|
LineBreakpoint created at clearCache.kt:95
|
||||||
|
LineBreakpoint created at clearCache.kt:105
|
||||||
|
LineBreakpoint created at clearCache.kt:113
|
||||||
|
LineBreakpoint created at clearCache.kt:124
|
||||||
|
LineBreakpoint created at clearCache.kt:133
|
||||||
|
LineBreakpoint created at clearCache.kt:143
|
||||||
|
LineBreakpoint created at clearCache.kt:151
|
||||||
|
LineBreakpoint created at clearCache.kt:169
|
||||||
|
LineBreakpoint created at clearCache.kt:174
|
||||||
|
LineBreakpoint created at clearCache.kt:181
|
||||||
|
LineBreakpoint created at clearCache.kt:189
|
||||||
|
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! clearCache.ClearCachePackage
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
clearCache.kt:11
|
||||||
|
clearCache.kt:19
|
||||||
|
clearCache.kt:30
|
||||||
|
clearCache.kt:30
|
||||||
|
clearCache.kt:41
|
||||||
|
clearCache.kt:41
|
||||||
|
clearCache.kt:51
|
||||||
|
clearCache.kt:59
|
||||||
|
clearCache.kt:77
|
||||||
|
clearCache.kt:85
|
||||||
|
clearCache.kt:94
|
||||||
|
clearCache.kt:104
|
||||||
|
clearCache.kt:112
|
||||||
|
clearCache.kt:123
|
||||||
|
clearCache.kt:132
|
||||||
|
clearCache.kt:142
|
||||||
|
clearCache.kt:150
|
||||||
|
clearCache.kt:168
|
||||||
|
clearCache.kt:173
|
||||||
|
clearCache.kt:180
|
||||||
|
clearCache.kt:188
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
package clearCache
|
||||||
|
|
||||||
|
import java.util.ArrayList
|
||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
|
fun primitiveTypes() {
|
||||||
|
if (true) {
|
||||||
|
val a: Any = 0
|
||||||
|
// EXPRESSION: a
|
||||||
|
// RESULT: instance of java.lang.Integer(id=ID): Ljava/lang/Integer;
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val a = 1
|
||||||
|
// EXPRESSION: a
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 1..2) {
|
||||||
|
// EXPRESSION: i
|
||||||
|
// RESULT: 1: I
|
||||||
|
|
||||||
|
// EXPRESSION: i
|
||||||
|
// RESULT: 2: I
|
||||||
|
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 5.0..6.0) {
|
||||||
|
// EXPRESSION: i
|
||||||
|
// RESULT: 5.0: D
|
||||||
|
|
||||||
|
// EXPRESSION: i
|
||||||
|
// RESULT: 6.0: D
|
||||||
|
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun subType() {
|
||||||
|
if (true) {
|
||||||
|
val o = Base()
|
||||||
|
// EXPRESSION: o.test()
|
||||||
|
// RESULT: 100: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val o = Derived()
|
||||||
|
// EXPRESSION: o.test()
|
||||||
|
// RESULT: 200: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class Base {
|
||||||
|
open fun test() = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived: Base() {
|
||||||
|
override fun test() = 200
|
||||||
|
}
|
||||||
|
|
||||||
|
fun subTypePlatform() {
|
||||||
|
if (true) {
|
||||||
|
val c: MutableList<String> = ArrayList<String>()
|
||||||
|
// EXPRESSION: c.size()
|
||||||
|
// RESULT: 0: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val c: List<String> = ArrayList<String>()
|
||||||
|
// EXPRESSION: c.size()
|
||||||
|
// RESULT: 0: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val c = ArrayList<String>()
|
||||||
|
c.add("a")
|
||||||
|
// EXPRESSION: c.size()
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val c = ArrayList<Int>()
|
||||||
|
c.add(1)
|
||||||
|
c.add(2)
|
||||||
|
// EXPRESSION: c.size()
|
||||||
|
// RESULT: 2: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val c = HashSet<Int>()
|
||||||
|
// EXPRESSION: c.size()
|
||||||
|
// RESULT: 0: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun genericRerun() {
|
||||||
|
if (true) {
|
||||||
|
val c = ArrayList<Int>()
|
||||||
|
c.add(1)
|
||||||
|
// EXPRESSION: c.get(0)
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val c = ArrayList<String>()
|
||||||
|
c.add("a")
|
||||||
|
// EXPRESSION: c.get(0)
|
||||||
|
// RESULT: "a": Ljava/lang/String;
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun innerClass() {
|
||||||
|
if (true) {
|
||||||
|
val o = TestInnerClasses.Base()
|
||||||
|
// EXPRESSION: o.test()
|
||||||
|
// RESULT: 100: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val o = TestInnerClasses.Derived()
|
||||||
|
// EXPRESSION: o.test()
|
||||||
|
// RESULT: 200: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestInnerClasses {
|
||||||
|
open class Base {
|
||||||
|
open fun test() = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived: Base() {
|
||||||
|
override fun test() = 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun objects() {
|
||||||
|
// EXPRESSION: obj.test()
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val a1 = 1
|
||||||
|
|
||||||
|
// EXPRESSION: obj.test()
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val a2 = 1
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val o: BaseObject = obj
|
||||||
|
// EXPRESSION: o.test()
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
val o = obj
|
||||||
|
// EXPRESSION: o.test()
|
||||||
|
// RESULT: 1: I
|
||||||
|
//Breakpoint!
|
||||||
|
val b = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val obj = object: BaseObject() { }
|
||||||
|
|
||||||
|
open class BaseObject {
|
||||||
|
fun test() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
primitiveTypes()
|
||||||
|
subType()
|
||||||
|
subTypePlatform()
|
||||||
|
genericRerun()
|
||||||
|
innerClass()
|
||||||
|
objects()
|
||||||
|
}
|
||||||
+52
-21
@@ -37,12 +37,9 @@ import java.util.Collections
|
|||||||
import com.intellij.debugger.engine.evaluation.EvaluateException
|
import com.intellij.debugger.engine.evaluation.EvaluateException
|
||||||
|
|
||||||
public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestCase() {
|
public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestCase() {
|
||||||
fun doTest(path: String) {
|
fun doSingleBreakpointTest(path: String) {
|
||||||
val file = File(path)
|
val file = File(path)
|
||||||
val fileContent = FileUtil.loadFile(file, true)
|
val expressions = loadTestDirectivesPairs(file, "// EXPRESSION: ", "// RESULT: ")
|
||||||
val expressions = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, "// EXPRESSION: ")
|
|
||||||
val expectedExpressionResults = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, "// RESULT: ")
|
|
||||||
assert(expressions.size == expectedExpressionResults.size, "Sizes of test directives are different")
|
|
||||||
|
|
||||||
val blocks = findFilesWithBlocks(file).map { FileUtil.loadFile(it, true) }
|
val blocks = findFilesWithBlocks(file).map { FileUtil.loadFile(it, true) }
|
||||||
val expectedBlockResults = blocks.map { InTextDirectivesUtils.findLinesWithPrefixesRemoved(it, "// RESULT: ").makeString("\n") }
|
val expectedBlockResults = blocks.map { InTextDirectivesUtils.findLinesWithPrefixesRemoved(it, "// RESULT: ").makeString("\n") }
|
||||||
@@ -51,34 +48,68 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestC
|
|||||||
|
|
||||||
onBreakpoint {
|
onBreakpoint {
|
||||||
val exceptions = linkedMapOf<String, Throwable>()
|
val exceptions = linkedMapOf<String, Throwable>()
|
||||||
for ((i, expression) in expressions.withIndices()) {
|
for ((expression, expected) in expressions) {
|
||||||
try {
|
mayThrow(exceptions, expression) {
|
||||||
evaluate(expression, CodeFragmentKind.EXPRESSION, expectedExpressionResults[i])
|
evaluate(expression, CodeFragmentKind.EXPRESSION, expected)
|
||||||
}
|
|
||||||
catch (e: Throwable) {
|
|
||||||
exceptions.put(expression, e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((i, block) in blocks.withIndices()) {
|
for ((i, block) in blocks.withIndices()) {
|
||||||
try {
|
mayThrow(exceptions, block) {
|
||||||
evaluate(block, CodeFragmentKind.CODE_BLOCK, expectedBlockResults[i])
|
evaluate(block, CodeFragmentKind.CODE_BLOCK, expectedBlockResults[i])
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
|
||||||
exceptions.put(block, e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exceptions.empty) {
|
checkExceptions(exceptions)
|
||||||
for (exc in exceptions.values()) {
|
|
||||||
exc.printStackTrace()
|
|
||||||
}
|
|
||||||
throw AssertionError("Test failed:\n" + exceptions.map { "expression: ${it.key}, exception: ${it.value.getMessage()}" }.makeString("\n"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun doMultipleBreakpointsTest(path: String) {
|
||||||
|
val expressions = loadTestDirectivesPairs(File(path), "// EXPRESSION: ", "// RESULT: ")
|
||||||
|
|
||||||
|
createDebugProcess(path)
|
||||||
|
|
||||||
|
val exceptions = linkedMapOf<String, Throwable>()
|
||||||
|
for ((expression, expected) in expressions) {
|
||||||
|
mayThrow(exceptions, expression) {
|
||||||
|
onBreakpoint {
|
||||||
|
evaluate(expression, CodeFragmentKind.EXPRESSION, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkExceptions(exceptions)
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkExceptions(exceptions: MutableMap<String, Throwable>) {
|
||||||
|
if (!exceptions.empty) {
|
||||||
|
for (exc in exceptions.values()) {
|
||||||
|
exc.printStackTrace()
|
||||||
|
}
|
||||||
|
throw AssertionError("Test failed:\n" + exceptions.map { "expression: ${it.key}, exception: ${it.value.getMessage()}" }.makeString("\n"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mayThrow(map: MutableMap<String, Throwable>, expression: String, f: () -> Unit) {
|
||||||
|
try {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
catch (e: Throwable) {
|
||||||
|
map.put(expression, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadTestDirectivesPairs(file: File, directivePrefix: String, expectedPrefix: String): List<Pair<String, String>> {
|
||||||
|
val fileContent = FileUtil.loadFile(file, true)
|
||||||
|
val directives = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, directivePrefix)
|
||||||
|
val expected = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, expectedPrefix)
|
||||||
|
assert(directives.size == expected.size, "Sizes of test directives are different")
|
||||||
|
return directives.zip(expected)
|
||||||
|
}
|
||||||
|
|
||||||
private fun findFilesWithBlocks(mainFile: File): List<File> {
|
private fun findFilesWithBlocks(mainFile: File): List<File> {
|
||||||
val mainFileName = mainFile.getName()
|
val mainFileName = mainFile.getName()
|
||||||
return mainFile.getParentFile()?.listFiles()?.filter { it.name.startsWith(mainFileName) && it.name != mainFileName } ?: Collections.emptyList()
|
return mainFile.getParentFile()?.listFiles()?.filter { it.name.startsWith(mainFileName) && it.name != mainFileName } ?: Collections.emptyList()
|
||||||
|
|||||||
+123
-100
@@ -30,110 +30,133 @@ import org.jetbrains.jet.plugin.debugger.evaluate.AbstractKotlinEvaluateExpressi
|
|||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("idea/testData/debugger/tinyApp/src/evaluate")
|
@InnerTestClasses({KotlinEvaluateExpressionTestGenerated.SingleBreakpoint.class, KotlinEvaluateExpressionTestGenerated.MultipleBreakpoints.class})
|
||||||
public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluateExpressionTest {
|
public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluateExpressionTest {
|
||||||
@TestMetadata("abstractFunCall.kt")
|
@TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint")
|
||||||
public void testAbstractFunCall() throws Exception {
|
public static class SingleBreakpoint extends AbstractKotlinEvaluateExpressionTest {
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/abstractFunCall.kt");
|
@TestMetadata("abstractFunCall.kt")
|
||||||
|
public void testAbstractFunCall() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/abstractFunCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInSingleBreakpoint() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("arrays.kt")
|
||||||
|
public void testArrays() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/arrays.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classFromAnotherPackage.kt")
|
||||||
|
public void testClassFromAnotherPackage() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/classFromAnotherPackage.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classObjectVal.kt")
|
||||||
|
public void testClassObjectVal() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/classObjectVal.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("collections.kt")
|
||||||
|
public void testCollections() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/collections.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("dependentOnFile.kt")
|
||||||
|
public void testDependentOnFile() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/dependentOnFile.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doubles.kt")
|
||||||
|
public void testDoubles() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/doubles.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("enums.kt")
|
||||||
|
public void testEnums() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/enums.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("errors.kt")
|
||||||
|
public void testErrors() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/errors.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extractLocalVariables.kt")
|
||||||
|
public void testExtractLocalVariables() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/extractLocalVariables.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extractThis.kt")
|
||||||
|
public void testExtractThis() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/extractThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extractVariablesFromCall.kt")
|
||||||
|
public void testExtractVariablesFromCall() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/extractVariablesFromCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("imports.kt")
|
||||||
|
public void testImports() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/imports.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("insertInBlock.kt")
|
||||||
|
public void testInsertInBlock() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/insertInBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multilineExpressionAtBreakpoint.kt")
|
||||||
|
public void testMultilineExpressionAtBreakpoint() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/multilineExpressionAtBreakpoint.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateMember.kt")
|
||||||
|
public void testPrivateMember() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/privateMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("protectedMember.kt")
|
||||||
|
public void testProtectedMember() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/protectedMember.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/simple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("stdlib.kt")
|
||||||
|
public void testStdlib() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/stdlib.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("vars.kt")
|
||||||
|
public void testVars() throws Exception {
|
||||||
|
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/vars.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInEvaluate() throws Exception {
|
@TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints")
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/debugger/tinyApp/src/evaluate"), Pattern.compile("^(.+)\\.kt$"), true);
|
public static class MultipleBreakpoints extends AbstractKotlinEvaluateExpressionTest {
|
||||||
|
public void testAllFilesPresentInMultipleBreakpoints() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("clearCache.kt")
|
||||||
|
public void testClearCache() throws Exception {
|
||||||
|
doMultipleBreakpointsTest("idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/clearCache.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("arrays.kt")
|
public static Test suite() {
|
||||||
public void testArrays() throws Exception {
|
TestSuite suite = new TestSuite("KotlinEvaluateExpressionTestGenerated");
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/arrays.kt");
|
suite.addTestSuite(SingleBreakpoint.class);
|
||||||
|
suite.addTestSuite(MultipleBreakpoints.class);
|
||||||
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classFromAnotherPackage.kt")
|
|
||||||
public void testClassFromAnotherPackage() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/classFromAnotherPackage.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("classObjectVal.kt")
|
|
||||||
public void testClassObjectVal() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/classObjectVal.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("collections.kt")
|
|
||||||
public void testCollections() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/collections.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("dependentOnFile.kt")
|
|
||||||
public void testDependentOnFile() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/dependentOnFile.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("doubles.kt")
|
|
||||||
public void testDoubles() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/doubles.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("enums.kt")
|
|
||||||
public void testEnums() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/enums.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("errors.kt")
|
|
||||||
public void testErrors() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/errors.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("extractLocalVariables.kt")
|
|
||||||
public void testExtractLocalVariables() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/extractLocalVariables.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("extractThis.kt")
|
|
||||||
public void testExtractThis() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/extractThis.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("extractVariablesFromCall.kt")
|
|
||||||
public void testExtractVariablesFromCall() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/extractVariablesFromCall.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("imports.kt")
|
|
||||||
public void testImports() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/imports.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("insertInBlock.kt")
|
|
||||||
public void testInsertInBlock() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/insertInBlock.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("multilineExpressionAtBreakpoint.kt")
|
|
||||||
public void testMultilineExpressionAtBreakpoint() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/multilineExpressionAtBreakpoint.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("privateMember.kt")
|
|
||||||
public void testPrivateMember() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/privateMember.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("protectedMember.kt")
|
|
||||||
public void testProtectedMember() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/protectedMember.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("simple.kt")
|
|
||||||
public void testSimple() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/simple.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("stdlib.kt")
|
|
||||||
public void testStdlib() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/stdlib.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("vars.kt")
|
|
||||||
public void testVars() throws Exception {
|
|
||||||
doTest("idea/testData/debugger/tinyApp/src/evaluate/vars.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user