constructor reference: don't ignore constructor parameters during method reference...
[idea/community.git] / java / java-impl / src / com / intellij / refactoring / extractMethodObject / reflect / LocalVariableDeclarationDescriptor.java
1 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.refactoring.extractMethodObject.reflect;
3
4 import com.intellij.psi.*;
5 import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor;
6 import org.jetbrains.annotations.NotNull;
7 import org.jetbrains.annotations.Nullable;
8
9 import java.util.ArrayList;
10 import java.util.List;
11
12 public class LocalVariableDeclarationDescriptor implements ItemToReplaceDescriptor {
13   private final List<AccessibleLocalVariable> myVariables;
14   private final PsiDeclarationStatement myDeclarationStatement;
15
16   public LocalVariableDeclarationDescriptor(@NotNull List<AccessibleLocalVariable> names, PsiDeclarationStatement statement) {
17     myVariables = names;
18     myDeclarationStatement = statement;
19   }
20
21   @Nullable
22   public static ItemToReplaceDescriptor createIfInaccessible(@NotNull PsiDeclarationStatement declarationStatement) {
23     List<AccessibleLocalVariable> variables = new ArrayList<>();
24     for (PsiElement element : declarationStatement.getDeclaredElements()) {
25       if (!(element instanceof PsiLocalVariable)) {
26         return null;
27       }
28
29       PsiLocalVariable variable = (PsiLocalVariable)element;
30       String name = variable.getName();
31       PsiType variableType = variable.getType();
32       if (name != null && !PsiReflectionAccessUtil.isAccessibleType(variableType)) {
33         variables.add(new AccessibleLocalVariable(name, PsiReflectionAccessUtil.nearestAccessibleType(variableType), variable));
34       }
35     }
36
37     if (!variables.isEmpty()) {
38       return new LocalVariableDeclarationDescriptor(variables, declarationStatement);
39     }
40     return null;
41   }
42
43   @Override
44   public void replace(@NotNull PsiClass outerClass,
45                       @NotNull PsiElementFactory elementFactory,
46                       @NotNull PsiMethodCallExpression callExpression) {
47     AccessibleLocalVariable variable = myVariables.get(0);
48     PsiDeclarationStatement lastDeclaration = variable.toVariableDeclaration(elementFactory);
49     myDeclarationStatement.replace(lastDeclaration);
50
51     for (int i = 1; i < myVariables.size(); i++) {
52       variable = myVariables.get(i);
53       PsiDeclarationStatement declaration = variable.toVariableDeclaration(elementFactory);
54       lastDeclaration.getParent().addAfter(declaration, lastDeclaration);
55       lastDeclaration = declaration;
56     }
57   }
58
59   private static class AccessibleLocalVariable {
60     private final String myName;
61     private final PsiType myAccessibleType;
62     private final PsiLocalVariable myLocalVariable;
63
64     private AccessibleLocalVariable(@NotNull String name, @NotNull PsiType type, @NotNull PsiLocalVariable localVariable) {
65       myName = name;
66       myAccessibleType = type;
67       myLocalVariable = localVariable;
68     }
69
70     private PsiDeclarationStatement toVariableDeclaration(@NotNull PsiElementFactory elementFactory) {
71       return elementFactory.createVariableDeclarationStatement(myName, myAccessibleType, myLocalVariable.getInitializer(), myLocalVariable);
72     }
73   }
74 }