Avoid using 'loadClass()' as it doesn't cache the results
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.debugger.evaluate
|
|||||||
import com.intellij.debugger.engine.DebugProcessImpl
|
import com.intellij.debugger.engine.DebugProcessImpl
|
||||||
import com.intellij.debugger.engine.SuspendContextImpl
|
import com.intellij.debugger.engine.SuspendContextImpl
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluateException
|
import com.intellij.debugger.engine.evaluation.EvaluateException
|
||||||
|
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||||
import com.intellij.debugger.impl.DebuggerUtilsEx
|
import com.intellij.debugger.impl.DebuggerUtilsEx
|
||||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||||
@@ -53,31 +54,35 @@ class ExecutionContext(val evaluationContext: EvaluationContextImpl, val framePr
|
|||||||
return debugProcess.newInstance(arrayType, dimension)
|
return debugProcess.newInstance(arrayType, dimension)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(
|
@Throws(EvaluateException::class)
|
||||||
InvocationException::class,
|
fun findClass(name: String, classLoader: ClassLoaderReference? = null): ReferenceType? {
|
||||||
ClassNotLoadedException::class,
|
debugProcess.findClass(evaluationContext, name, classLoader)?.let { return it }
|
||||||
IncompatibleThreadStateException::class,
|
|
||||||
InvalidTypeException::class,
|
|
||||||
EvaluateException::class
|
|
||||||
)
|
|
||||||
fun loadClass(asmType: Type, classLoader: ClassLoaderReference? = null): ReferenceType? {
|
|
||||||
return loadClass(asmType.className, classLoader)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(
|
// If 'isAutoLoadClasses' is true, `findClass()` already did this
|
||||||
InvocationException::class,
|
if (!evaluationContext.isAutoLoadClasses) {
|
||||||
ClassNotLoadedException::class,
|
try {
|
||||||
IncompatibleThreadStateException::class,
|
debugProcess.loadClass(evaluationContext, name, classLoader)
|
||||||
InvalidTypeException::class,
|
} catch (e: InvocationException) {
|
||||||
EvaluateException::class
|
throw EvaluateExceptionUtil.createEvaluateException(e)
|
||||||
)
|
} catch (e: ClassNotLoadedException) {
|
||||||
fun loadClass(name: String, classLoader: ClassLoaderReference? = null): ReferenceType? {
|
throw EvaluateExceptionUtil.createEvaluateException(e)
|
||||||
return debugProcess.loadClass(evaluationContext, name, classLoader)
|
} catch (e: IncompatibleThreadStateException) {
|
||||||
|
throw EvaluateExceptionUtil.createEvaluateException(e)
|
||||||
|
} catch (e: InvalidTypeException) {
|
||||||
|
throw EvaluateExceptionUtil.createEvaluateException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(EvaluateException::class)
|
@Throws(EvaluateException::class)
|
||||||
fun findClass(name: String, classLoader: ClassLoaderReference? = null): ReferenceType? {
|
fun findClass(asmType: Type, classLoader: ClassLoaderReference? = null): ReferenceType? {
|
||||||
return debugProcess.findClass(evaluationContext, name, classLoader)
|
if (asmType.sort != Type.OBJECT && asmType.sort != Type.ARRAY) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return findClass(asmType.className, classLoader)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun keepReference(reference: ObjectReference) {
|
fun keepReference(reference: ObjectReference) {
|
||||||
|
|||||||
+3
-3
@@ -292,7 +292,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
|
|||||||
): Value? {
|
): Value? {
|
||||||
return try {
|
return try {
|
||||||
runEvaluation(context, compiledData, classLoader) { args ->
|
runEvaluation(context, compiledData, classLoader) { args ->
|
||||||
val mainClassType = context.loadClass(Type.getObjectType(GENERATED_CLASS_NAME), classLoader) as? ClassType
|
val mainClassType = context.findClass(GENERATED_CLASS_NAME, classLoader) as? ClassType
|
||||||
?: error("Can not find class \"$GENERATED_CLASS_NAME\"")
|
?: error("Can not find class \"$GENERATED_CLASS_NAME\"")
|
||||||
val mainMethod = mainClassType.methods().single { it.name() == GENERATED_FUNCTION_NAME }
|
val mainMethod = mainClassType.methods().single { it.name() == GENERATED_FUNCTION_NAME }
|
||||||
val returnValue = context.invokeMethod(mainClassType, mainMethod, args)
|
val returnValue = context.invokeMethod(mainClassType, mainMethod, args)
|
||||||
@@ -332,11 +332,11 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
|
|||||||
// Preload additional classes
|
// Preload additional classes
|
||||||
compiledData.classes
|
compiledData.classes
|
||||||
.filter { !it.isMainClass }
|
.filter { !it.isMainClass }
|
||||||
.forEach { context.loadClass(Type.getObjectType(it.className), classLoader) }
|
.forEach { context.findClass(it.className, classLoader) }
|
||||||
|
|
||||||
return context.vm.virtualMachine.executeWithBreakpointsDisabled {
|
return context.vm.virtualMachine.executeWithBreakpointsDisabled {
|
||||||
for (parameterType in compiledData.mainMethodSignature.parameterTypes) {
|
for (parameterType in compiledData.mainMethodSignature.parameterTypes) {
|
||||||
context.loadClass(parameterType, classLoader)
|
context.findClass(parameterType, classLoader)
|
||||||
}
|
}
|
||||||
val args = calculateMainMethodCallArguments(context, compiledData)
|
val args = calculateMainMethodCallArguments(context, compiledData)
|
||||||
block(args)
|
block(args)
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ abstract class AbstractAndroidClassLoadingAdapter : ClassLoadingAdapter {
|
|||||||
|
|
||||||
protected fun tryLoadClass(context: ExecutionContext, fqName: String, classLoader: ClassLoaderReference?): ReferenceType? {
|
protected fun tryLoadClass(context: ExecutionContext, fqName: String, classLoader: ClassLoaderReference?): ReferenceType? {
|
||||||
return try {
|
return try {
|
||||||
context.loadClass(fqName, classLoader)
|
context.debugProcess.loadClass(context.evaluationContext, fqName, classLoader)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -130,7 +130,7 @@ class EvaluatorValueConverter(private val context: ExecutionContext) {
|
|||||||
val unboxedType = value.asmType()
|
val unboxedType = value.asmType()
|
||||||
val boxedType = box(unboxedType)
|
val boxedType = box(unboxedType)
|
||||||
|
|
||||||
val boxedTypeClass = (context.loadClass(boxedType) as ClassType?)
|
val boxedTypeClass = (context.findClass(boxedType) as ClassType?)
|
||||||
?: error("Class $boxedType is not loaded")
|
?: error("Class $boxedType is not loaded")
|
||||||
|
|
||||||
val methodDesc = AsmType.getMethodDescriptor(boxedType, unboxedType)
|
val methodDesc = AsmType.getMethodDescriptor(boxedType, unboxedType)
|
||||||
@@ -173,13 +173,13 @@ class EvaluatorValueConverter(private val context: ExecutionContext) {
|
|||||||
val primitiveType = value.asmType()
|
val primitiveType = value.asmType()
|
||||||
val refType = PRIMITIVE_TO_REF.getValue(primitiveType)
|
val refType = PRIMITIVE_TO_REF.getValue(primitiveType)
|
||||||
|
|
||||||
val refTypeClass = (context.loadClass(refType) as ClassType?)
|
val refTypeClass = (context.findClass(refType) as ClassType?)
|
||||||
?: error("Class $refType is not loaded")
|
?: error("Class $refType is not loaded")
|
||||||
|
|
||||||
return wrapRef(value, refTypeClass)
|
return wrapRef(value, refTypeClass)
|
||||||
} else {
|
} else {
|
||||||
val refType = AsmType.getType(Ref.ObjectRef::class.java)
|
val refType = AsmType.getType(Ref.ObjectRef::class.java)
|
||||||
val refTypeClass = (context.loadClass(refType) as ClassType?)
|
val refTypeClass = (context.findClass(refType) as ClassType?)
|
||||||
?: error("Class $refType is not loaded")
|
?: error("Class $refType is not loaded")
|
||||||
|
|
||||||
return wrapRef(value, refTypeClass)
|
return wrapRef(value, refTypeClass)
|
||||||
|
|||||||
Reference in New Issue
Block a user