IDEA-172425 Support method references to private constructors
authorVitaliy.Bibaev <vitaliy.bibaev@jetbrains.com>
Mon, 5 Mar 2018 12:01:27 +0000 (15:01 +0300)
committerVitaliy.Bibaev <vitaliy.bibaev@jetbrains.com>
Mon, 5 Mar 2018 12:01:27 +0000 (15:01 +0300)
java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ConstructorReflectionAccessor.java
java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReferenceReflectionAccessor.java

index 5194777db84f6dc6fbfcaea6223a8254fac0e154..bfe00bc7e7c5b01b5ca05dcd598da7cef391d61f 100644 (file)
@@ -33,18 +33,9 @@ public class ConstructorReflectionAccessor extends ReflectionAccessorBase<Constr
       public void visitNewExpression(PsiNewExpression expression) {
         super.visitNewExpression(expression);
         if (expression.getAnonymousClass() != null || expression.getArrayInitializer() != null) return;
-        PsiMethod constructor = expression.resolveConstructor();
-        if (constructor != null) {
-          PsiClass containingClass = constructor.getContainingClass();
-          if (containingClass != null && !PsiReflectionAccessUtil.isAccessibleMember(constructor)) {
-            result.add(new ConstructorDescriptor(expression, constructor, containingClass));
-          }
-        }
-        else {
-          PsiJavaCodeReferenceElement classReference = expression.getClassReference();
-          if (classReference instanceof PsiClass && !PsiReflectionAccessUtil.isAccessible((PsiClass)classReference)) {
-            result.add(new ConstructorDescriptor(expression, null, (PsiClass)classReference));
-          }
+        ConstructorDescriptor descriptor = ConstructorDescriptor.createIfInaccessible(expression);
+        if (descriptor != null) {
+          result.add(descriptor);
         }
       }
     });
@@ -85,6 +76,25 @@ public class ConstructorReflectionAccessor extends ReflectionAccessorBase<Constr
     // null if and only if default constructor is used
     @Nullable public final PsiMethod constructor;
 
+    @Nullable
+    public static ConstructorDescriptor createIfInaccessible(@NotNull PsiNewExpression expression) {
+      PsiMethod constructor = expression.resolveConstructor();
+      if (constructor != null) {
+        PsiClass containingClass = constructor.getContainingClass();
+        if (containingClass != null && !PsiReflectionAccessUtil.isAccessibleMember(constructor)) {
+          return new ConstructorDescriptor(expression, constructor, containingClass);
+        }
+      }
+      else {
+        PsiJavaCodeReferenceElement classReference = expression.getClassReference();
+        if (classReference instanceof PsiClass && !PsiReflectionAccessUtil.isAccessible((PsiClass)classReference)) {
+          return new ConstructorDescriptor(expression, null, (PsiClass)classReference);
+        }
+      }
+
+      return null;
+    }
+
     public ConstructorDescriptor(@NotNull PsiNewExpression expression, @Nullable PsiMethod constructor, PsiClass psiClass) {
       newExpression = expression;
       this.constructor = constructor;
index aeba7e7f81938639982e964d5466deb620631a05..4875d2c69312a34785cfbf4461d2bafc65314bd7 100644 (file)
@@ -4,20 +4,25 @@ package com.intellij.refactoring.extractMethodObject.reflect;
 import com.intellij.psi.*;
 import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor;
 import com.intellij.refactoring.extractMethodObject.PsiReflectionAccessUtil;
+import com.intellij.refactoring.extractMethodObject.reflect.ConstructorReflectionAccessor.ConstructorDescriptor;
 import com.intellij.refactoring.util.LambdaRefactoringUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import static com.intellij.refactoring.extractMethodObject.reflect.ConstructorReflectionAccessor.ConstructorDescriptor.createIfInaccessible;
+
 /**
  * @author Vitaliy.Bibaev
  */
 public class MethodReferenceReflectionAccessor
   extends ReferenceReflectionAccessorBase<MethodReferenceReflectionAccessor.MethodReferenceDescriptor> {
   private final MethodReflectionAccessor myMethodAccessor;
+  private final ConstructorReflectionAccessor myConstructorReflectionAccessor;
   public MethodReferenceReflectionAccessor(@NotNull PsiClass psiClass,
                                            @NotNull PsiElementFactory elementFactory) {
     super(psiClass, elementFactory);
     myMethodAccessor = new MethodReflectionAccessor(psiClass, elementFactory);
+    myConstructorReflectionAccessor = new ConstructorReflectionAccessor(psiClass, elementFactory);
   }
 
   @Nullable
@@ -41,7 +46,13 @@ public class MethodReferenceReflectionAccessor
     PsiLambdaExpression lambda = LambdaRefactoringUtil.convertMethodReferenceToLambda(descriptor.expression, false, true);
     if (lambda != null) {
       PsiElement lambdaBody = lambda.getBody();
-      if (lambdaBody instanceof PsiMethodCallExpression) {
+      if (lambdaBody instanceof PsiNewExpression) {
+        ConstructorDescriptor constructorDescriptor = createIfInaccessible((PsiNewExpression)lambdaBody);
+        if (constructorDescriptor != null) {
+          myConstructorReflectionAccessor.grantAccess(constructorDescriptor);
+        }
+      }
+      else if (lambdaBody instanceof PsiMethodCallExpression) {
         PsiMethodCallExpression callExpression = (PsiMethodCallExpression)lambdaBody;
         PsiMethod method = callExpression.resolveMethod();
         if (method != null) {