Fix evaluation for static interface methods declared in Java (KT-23585)

This commit is contained in:
Yan Zhulanow
2018-11-27 22:17:10 +09:00
parent 3d7b503cd6
commit 27ea02929a
7 changed files with 92 additions and 9 deletions
+24 -5
View File
@@ -16,6 +16,7 @@
package org.jetbrains.eval4j.jdi
import com.intellij.openapi.util.text.StringUtil
import com.sun.jdi.*
import org.jetbrains.eval4j.*
import org.jetbrains.eval4j.Value
@@ -48,6 +49,8 @@ class JDIEval(
Type.DOUBLE_TYPE.className to vm.mirrorOf(1.0).type()
)
private val isJava8OrLater = StringUtil.compareVersionNumbers(vm.version(), "1.8") >= 0
override fun loadClass(classType: Type): Value {
return loadClass(classType, defaultClassLoader)
}
@@ -251,17 +254,33 @@ class JDIEval(
if (!method.isStatic) {
throwBrokenCodeException(NoSuchMethodError("Method is not static: $methodDesc"))
}
val _class = method.declaringType()
if (_class !is ClassType) throwBrokenCodeException(NoSuchMethodError("Static method is a non-class type: $method"))
val declaringType = method.declaringType()
val args = mapArguments(arguments, method.safeArgumentTypes())
if (shouldInvokeMethodWithReflection(method, args)) {
return invokeMethodWithReflection(_class.asType(), NULL_VALUE, args, methodDesc)
return invokeMethodWithReflection(declaringType.asType(), NULL_VALUE, args, methodDesc)
}
args.disableCollection()
val result = mayThrow { _class.invokeMethod(thread, method, args, invokePolicy) }.ifFail(method)
val result = mayThrow {
when (declaringType) {
is ClassType -> declaringType.invokeMethod(thread, method, args, invokePolicy)
is InterfaceType -> {
if (!isJava8OrLater) {
val message = "Calling interface static methods is not supported in JVM ${vm.version()} ($method)"
throwBrokenCodeException(NoSuchMethodError(message))
}
declaringType.invokeMethod(thread, method, args, invokePolicy)
}
else -> {
val message = "Calling static methods is only supported for classes and interfaces ($method)"
throwBrokenCodeException(NoSuchMethodError(message))
}
}
}.ifFail(method)
args.enableCollection()
return result.asValue()
}
@@ -0,0 +1,11 @@
package javaStaticMethods
import forTests.javaContext.JavaClass.JavaStatic
fun main() {
//Breakpoint!
val a = 5
}
// EXPRESSION: JavaStatic.state()
// RESULT: 1: I
@@ -0,0 +1,8 @@
LineBreakpoint created at javaStaticMethods.kt:7
Run Java
Connected to the target VM
javaStaticMethods.kt:7
Compile bytecode for JavaStatic.state()
Disconnected from the target VM
Process finished with exit code 0
@@ -46,4 +46,8 @@ public class JavaClass {
public void property() {
int breakpoint = 1;
}
public interface JavaStatic {
static int state() { return 1; }
}
}
@@ -41,11 +41,15 @@ import com.intellij.testFramework.EdtTestUtil;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.xdebugger.XDebugSession;
import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import kotlin.io.FilesKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage;
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade;
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder;
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil;
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
@@ -89,6 +93,9 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
protected static final String KOTLIN_LIBRARY_NAME = "KotlinLibrary";
private static final String CUSTOM_LIBRARY_NAME = "CustomLibrary";
@Nullable
private String oldJvmTarget = null;
@Override
protected OutputChecker initOutputChecker() {
return new KotlinOutputChecker(
@@ -128,6 +135,12 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
NoStrataPositionManagerHelperKt.setEmulateDexDebugInTests(true);
}
super.setUp();
Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(myProject).update(s -> {
oldJvmTarget = s.getJvmTarget();
s.setJvmTarget("1.8");
return Unit.INSTANCE;
});
}
private static void deleteLocalCacheDirectory(boolean assertDeleteSuccess) {
@@ -215,6 +228,11 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
@Override
protected void tearDown() throws Exception {
Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(myProject).update(s -> {
s.setJvmTarget(oldJvmTarget);
return Unit.INSTANCE;
});
if (DexLikeBytecodePatchKt.needDexPatch(getTestName(true))) {
NoStrataPositionManagerHelperKt.setEmulateDexDebugInTests(false);
}
@@ -233,7 +251,7 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
protected void setUpModule() {
super.setUpModule();
IdeaTestUtil.setModuleLanguageLevel(myModule, LanguageLevel.JDK_1_6);
IdeaTestUtil.setModuleLanguageLevel(myModule, LanguageLevel.JDK_1_8);
String outputDirPath = getAppOutputPath();
File outDir = new File(outputDirPath);
@@ -249,7 +267,7 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
String sourcesDir = modulePath + File.separator + "src";
MockLibraryUtil.compileKotlin(sourcesDir, outDir, CUSTOM_LIBRARY_JAR.getPath());
MockLibraryUtil.compileKotlin(sourcesDir, outDir, CollectionsKt.listOf("-jvm-target", "1.8"), CUSTOM_LIBRARY_JAR.getPath());
List<String> options =
Arrays.asList("-d", outputDirPath, "-classpath",
@@ -41,11 +41,15 @@ import com.intellij.testFramework.EdtTestUtil;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.xdebugger.XDebugSession;
import kotlin.Unit;
import kotlin.collections.CollectionsKt;
import kotlin.io.FilesKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage;
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade;
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder;
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil;
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
@@ -89,6 +93,9 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
protected static final String KOTLIN_LIBRARY_NAME = "KotlinLibrary";
private static final String CUSTOM_LIBRARY_NAME = "CustomLibrary";
@Nullable
private String oldJvmTarget = null;
@Override
protected OutputChecker initOutputChecker() {
return new KotlinOutputChecker(
@@ -128,6 +135,12 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
NoStrataPositionManagerHelperKt.setEmulateDexDebugInTests(true);
}
super.setUp();
Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(myProject).update(s -> {
oldJvmTarget = s.getJvmTarget();
s.setJvmTarget("1.8");
return Unit.INSTANCE;
});
}
@Override
@@ -245,6 +258,11 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
@Override
protected void tearDown() throws Exception {
Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(myProject).update(s -> {
s.setJvmTarget(oldJvmTarget);
return Unit.INSTANCE;
});
if (DexLikeBytecodePatchKt.needDexPatch(getTestName(true))) {
NoStrataPositionManagerHelperKt.setEmulateDexDebugInTests(false);
}
@@ -263,7 +281,7 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
protected void setUpModule() {
super.setUpModule();
IdeaTestUtil.setModuleLanguageLevel(myModule, LanguageLevel.JDK_1_6);
IdeaTestUtil.setModuleLanguageLevel(myModule, LanguageLevel.JDK_1_8);
String outputDirPath = getAppOutputPath();
File outDir = new File(outputDirPath);
@@ -279,7 +297,7 @@ public abstract class KotlinDebuggerTestCase extends DescriptorTestCase {
String sourcesDir = modulePath + File.separator + "src";
MockLibraryUtil.compileKotlin(sourcesDir, outDir, CUSTOM_LIBRARY_JAR.getPath());
MockLibraryUtil.compileKotlin(sourcesDir, outDir, CollectionsKt.listOf("-jvm-target", "1.8"), CUSTOM_LIBRARY_JAR.getPath());
List<String> options =
Arrays.asList("-d", outputDirPath, "-classpath",
@@ -206,6 +206,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/internalProperty.kt");
}
@TestMetadata("javaStaticMethods.kt")
public void testJavaStaticMethods() throws Exception {
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/javaStaticMethods.kt");
}
@TestMetadata("kt12206BasePropertyWithoutBackingField.kt")
public void testKt12206BasePropertyWithoutBackingField() throws Exception {
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt12206BasePropertyWithoutBackingField.kt");