IDEA-172425 Simplify conditions of usage magic accessor/reflection
authorVitaliy.Bibaev <vitaliy.bibaev@jetbrains.com>
Thu, 22 Mar 2018 12:20:49 +0000 (15:20 +0300)
committerVitaliy.Bibaev <vitaliy.bibaev@jetbrains.com>
Thu, 22 Mar 2018 12:33:33 +0000 (15:33 +0300)
Move logic about the decision to use/not to use MagicAccessorImpl and
access through the reflection into ExtractLightMethodObjectHandler

java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java
java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java
java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java
java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java

index 1c57767665e8ecf4251493d99bfeee0b63b15a4a..553a9a51699229d0c7ef26063eee1100104b58cd 100644 (file)
@@ -16,7 +16,6 @@ import com.intellij.openapi.application.ReadAction;
 import com.intellij.openapi.compiler.ClassObject;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
-import com.intellij.openapi.util.registry.Registry;
 import com.intellij.psi.PsiElement;
 import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler;
 import com.sun.jdi.ClassLoaderReference;
@@ -64,7 +63,7 @@ public abstract class CompilingEvaluator implements ExpressionEvaluator {
 
     JavaSdkVersion version = JavaSdkVersion.fromVersionString(((VirtualMachineProxyImpl)process.getVirtualMachineProxy()).version());
     Collection<ClassObject> classes = compile(version);
-    defineClasses(version, classes, autoLoadContext, process, classLoader);
+    defineClasses(classes, autoLoadContext, process, classLoader);
 
     try {
       // invoke base evaluator on call code
@@ -87,13 +86,11 @@ public abstract class CompilingEvaluator implements ExpressionEvaluator {
     }
   }
 
-  private void defineClasses(JavaSdkVersion version,
-                             Collection<ClassObject> classes,
+  private void defineClasses(Collection<ClassObject> classes,
                              EvaluationContext context,
                              DebugProcess process,
                              ClassLoaderReference classLoader) throws EvaluateException {
-    boolean useMagicAccessorImpl = version != null && !version.isAtLeast(JavaSdkVersion.JDK_1_9) &&
-                                   Registry.is("debugger.compiling.evaluator.magic.accessor");
+    boolean useMagicAccessorImpl = myData.useMagicAccessor();
 
     for (ClassObject cls : classes) {
       if (cls.getPath().contains(GEN_CLASS_NAME)) {
index aa6c3db1647ecd38cbda6045acddbd0e1ebc88c2..19f2b49a83caf513be7a91ebeacddd46f7228d57 100644 (file)
@@ -3,6 +3,7 @@ package com.intellij.debugger.ui.impl.watch;
 
 import com.intellij.compiler.CompilerConfiguration;
 import com.intellij.compiler.server.BuildManager;
+import com.intellij.debugger.engine.DebugProcessImpl;
 import com.intellij.debugger.engine.SuspendContextImpl;
 import com.intellij.debugger.engine.evaluation.EvaluateException;
 import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
@@ -145,23 +146,14 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator {
     if (Registry.is("debugger.compiling.evaluator") && psiContext != null) {
       return ApplicationManager.getApplication().runReadAction((ThrowableComputable<ExpressionEvaluator, EvaluateException>)() -> {
         try {
-          boolean useReflection = Registry.is("debugger.compiling.evaluator.reflection.access.with.java8");
           XDebugSession currentSession = XDebuggerManager.getInstance(project).getCurrentSession();
-          if (!useReflection && currentSession != null) {
-            XSuspendContext suspendContext = currentSession.getSuspendContext();
-            if (suspendContext instanceof SuspendContextImpl) {
-              JavaSdkVersion version =
-                JavaSdkVersion.fromVersionString(((SuspendContextImpl)suspendContext).getDebugProcess().getVirtualMachineProxy().version());
-              useReflection = version != null && version.isAtLeast(JavaSdkVersion.JDK_1_9);
-            }
-          }
-
+          JavaSdkVersion javaVersion = getJavaVersion(currentSession);
           ExtractLightMethodObjectHandler.ExtractedData data = ExtractLightMethodObjectHandler.extractLightMethodObject(
             project,
             findPhysicalContext(psiContext),
             fragmentFactory.apply(psiContext),
             getGeneratedClassName(),
-            useReflection);
+            javaVersion);
           if (data != null) {
             return new CompilingEvaluatorImpl(project, psiContext, data);
           }
@@ -186,4 +178,17 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator {
     }
     return element;
   }
+
+  @Nullable
+  public static JavaSdkVersion getJavaVersion(@Nullable XDebugSession session) {
+    if (session != null) {
+      XSuspendContext suspendContext = session.getSuspendContext();
+      if (suspendContext instanceof SuspendContextImpl) {
+        DebugProcessImpl debugProcess = ((SuspendContextImpl)suspendContext).getDebugProcess();
+        return JavaSdkVersion.fromVersionString(debugProcess.getVirtualMachineProxy().version());
+      }
+    }
+
+    return null;
+  }
 }
index ee04860d3900aed7a9dd2cb034fac2b45c89b0d7..b4ba548e78b2742d530dacbd1bb588746d396a71 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.refactoring.extractMethodObject;
 import com.intellij.codeInsight.CodeInsightUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
@@ -49,11 +50,13 @@ public class ExtractLightMethodObjectHandler {
     private final String myGeneratedCallText;
     private final PsiClass myGeneratedInnerClass;
     private final PsiElement myAnchor;
+    private final boolean myUseMagicAccessor;
 
-    public ExtractedData(String generatedCallText, PsiClass generatedInnerClass, PsiElement anchor) {
+    public ExtractedData(String generatedCallText, PsiClass generatedInnerClass, PsiElement anchor, boolean useMagicAccessor) {
       myGeneratedCallText = generatedCallText;
       myGeneratedInnerClass = generatedInnerClass;
       myAnchor = anchor;
+      myUseMagicAccessor = useMagicAccessor;
     }
 
     public PsiElement getAnchor() {
@@ -67,6 +70,10 @@ public class ExtractLightMethodObjectHandler {
     public PsiClass getGeneratedInnerClass() {
       return myGeneratedInnerClass;
     }
+
+    public boolean useMagicAccessor() {
+      return myUseMagicAccessor;
+    }
   }
 
   @Nullable
@@ -74,7 +81,7 @@ public class ExtractLightMethodObjectHandler {
                                                        @Nullable PsiElement originalContext,
                                                        @NotNull final PsiCodeFragment fragment,
                                                        final String methodName,
-                                                       boolean useReflection) throws PrepareFailedException {
+                                                       @Nullable JavaSdkVersion javaVersion) throws PrepareFailedException {
     final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
     PsiElement[] elements = completeToStatementArray(fragment, elementFactory);
     if (elements == null) {
@@ -199,7 +206,9 @@ public class ExtractLightMethodObjectHandler {
     PsiStatement outStatement = elementFactory.createStatementFromText("System.out.println(" + outputVariables + ");", anchor);
     outStatement = (PsiStatement)container.addAfter(outStatement, elementsCopy[elementsCopy.length - 1]);
 
-    if (Registry.is("debugger.compiling.evaluator.magic.accessor") && !useReflection) {
+    boolean useMagicAccessor = Registry.is("debugger.compiling.evaluator.magic.accessor") &&
+                               javaVersion != null && !javaVersion.isAtLeast(JavaSdkVersion.JDK_1_9);
+    if (useMagicAccessor) {
       copy.accept(new JavaRecursiveElementWalkingVisitor() {
         private void makePublic(PsiMember method) {
           if (method.hasModifierProperty(PsiModifier.PRIVATE)) {
@@ -262,6 +271,8 @@ public class ExtractLightMethodObjectHandler {
     final PsiClass inner = extractMethodObjectProcessor.getInnerClass();
     final PsiMethod[] methods = inner.findMethodsByName("invoke", false);
 
+    boolean useReflection = javaVersion == null || javaVersion.isAtLeast(JavaSdkVersion.JDK_1_9) ||
+                            Registry.is("debugger.compiling.evaluator.reflection.access.with.java8");
     if (useReflection && methods.length == 1) {
       final PsiMethod method = methods[0];
       CompositeReflectionAccessor.createAccessorToEverything(inner, elementFactory)
@@ -271,7 +282,7 @@ public class ExtractLightMethodObjectHandler {
     final String generatedCall = copy.getText().substring(startOffset, outStatement.getTextOffset());
     return new ExtractedData(generatedCall,
                              (PsiClass)CodeStyleManager.getInstance(project).reformat(extractMethodObjectProcessor.getInnerClass()),
-                             originalAnchor);
+                             originalAnchor, useMagicAccessor);
   }
 
   @Nullable
index dec6518bcba64d04fc9522415db301f9b05cccf9..64ca8200f096f69ae681f131491bedc83c3bf356 100644 (file)
@@ -17,6 +17,8 @@
 package com.intellij.java.refactoring;
 
 import com.intellij.JavaTestUtil;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.psi.JavaCodeFragment;
 import com.intellij.psi.JavaCodeFragmentFactory;
 import com.intellij.psi.PsiClass;
@@ -46,13 +48,31 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase {
     final JavaCodeFragmentFactory fragmentFactory = JavaCodeFragmentFactory.getInstance(getProject());
     final JavaCodeFragment fragment = codeBlock ? fragmentFactory.createCodeBlockCodeFragment(evaluatedText, context, false) : fragmentFactory.createExpressionCodeFragment(evaluatedText, context, null, false);
     final ExtractLightMethodObjectHandler.ExtractedData extractedData =
-      ExtractLightMethodObjectHandler.extractLightMethodObject(getProject(), context, fragment, "test", false);
+      ExtractLightMethodObjectHandler.extractLightMethodObject(getProject(), context, fragment, "test", JavaSdkVersion.JDK_1_8);
     assertNotNull(extractedData);
     assertEquals(expectedCallSite, extractedData.getGeneratedCallText());
     final PsiClass innerClass = extractedData.getGeneratedInnerClass();
     assertEquals(expectedClass, innerClass.getText());
   }
 
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    Registry.get("debugger.compiling.evaluator.magic.accessor").setValue(true);
+    Registry.get("debugger.compiling.evaluator.reflection.access.with.java8").setValue(false);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    try {
+      Registry.get("debugger.compiling.evaluator.magic.accessor").resetToDefault();
+      Registry.get("debugger.compiling.evaluator.reflection.access.with.java8").resetToDefault();
+    }
+    finally {
+      super.tearDown();
+    }
+  }
+
   public void testSimpleGeneration() throws Exception {
     doTest("int i = 0; int j = 0;", "Test test = new Test().invoke();int i = test.getI();int j = test.getJ();",