mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
preselect available type, leave inacessible in combo
This commit is contained in:
+3
-2
@@ -71,7 +71,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
PsiLocalVariable local,
|
||||
PsiExpression[] occurences,
|
||||
boolean isStatic) {
|
||||
return IntroduceConstantHandler.this.showRefactoringDialog(project, editor, aClass, local.getInitializer(), local.getType(), occurences, null, null);
|
||||
return IntroduceConstantHandler.this.showRefactoringDialog(project, editor, aClass, local.getInitializer(), local.getType(), occurences, local, null);
|
||||
}
|
||||
};
|
||||
return localToFieldHandler.convertLocalToField(localVariable, editor);
|
||||
@@ -86,6 +86,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
PsiExpression[] occurences,
|
||||
PsiElement anchorElement,
|
||||
PsiElement anchorElementIfAll) {
|
||||
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expr != null ? expr : anchorElement, PsiMethod.class);
|
||||
for (PsiExpression occurrence : occurences) {
|
||||
if (RefactoringUtil.isAssignmentLHS(occurrence)) {
|
||||
String message =
|
||||
@@ -133,7 +134,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
|
||||
final IntroduceConstantDialog dialog =
|
||||
new IntroduceConstantDialog(project, parentClass, expr, localVariable, false, occurences, getParentClass(),
|
||||
new TypeSelectorManagerImpl(project, type, expr, occurences));
|
||||
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurences));
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) {
|
||||
if (occurences.length > 1) {
|
||||
|
||||
+1
-21
@@ -20,7 +20,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
@@ -28,7 +27,6 @@ import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.occurences.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
@@ -96,13 +94,12 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
final boolean currentMethodConstructor = containingMethod != null && containingMethod.isConstructor();
|
||||
final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && anchorElement instanceof PsiStatement;
|
||||
final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && anchorElementIfAll instanceof PsiStatement;
|
||||
type = checkIfTypeAccessible(type, project, parentClass, containingMethod);
|
||||
IntroduceFieldDialog dialog = new IntroduceFieldDialog(
|
||||
project, parentClass, expr, localVariable,
|
||||
currentMethodConstructor,
|
||||
false, declareStatic, occurencesNumber,
|
||||
allowInitInMethod, allowInitInMethodIfAll,
|
||||
new TypeSelectorManagerImpl(project, type, expr, occurences)
|
||||
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurences)
|
||||
);
|
||||
dialog.show();
|
||||
|
||||
@@ -125,23 +122,6 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
dialog.getFieldType(), localVariable != null, (TargetDestination)null, false, false);
|
||||
}
|
||||
|
||||
private static PsiType checkIfTypeAccessible(PsiType type, Project project, PsiClass parentClass, PsiMethod containingMethod) {
|
||||
final PsiClass typeClass = PsiUtil.resolveClassInType(type);
|
||||
if (typeClass != null) {
|
||||
if (typeClass instanceof PsiTypeParameter) {
|
||||
if (ArrayUtil.find(parentClass.getTypeParameters(), typeClass) == -1) { //unknown type parameter
|
||||
type = PsiType.getJavaLangObject(PsiManager.getInstance(project), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
} else if (PsiTreeUtil.isAncestor(containingMethod, typeClass, true)) { //local class type
|
||||
final PsiClassType[] superTypes = typeClass.getSuperTypes();
|
||||
if (superTypes.length > 0) {
|
||||
return checkIfTypeAccessible(superTypes[0], project, parentClass, containingMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static boolean isInSuperOrThis(PsiExpression occurence) {
|
||||
return !NotInSuperCallOccurenceFilter.INSTANCE.isOK(occurence) || !NotInThisCallFilter.INSTANCE.isOK(occurence);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,14 @@ import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -35,7 +38,7 @@ import java.util.*;
|
||||
* @author dsl
|
||||
*/
|
||||
public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
private final PsiType myDefaultType;
|
||||
private PsiType myDefaultType;
|
||||
private final PsiExpression myMainOccurence;
|
||||
private final PsiExpression[] myOccurrences;
|
||||
private final PsiType[] myTypesForMain;
|
||||
@@ -47,27 +50,7 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
private ExpectedTypesProvider myExpectedTypesProvider;
|
||||
|
||||
public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression mainOccurence, PsiExpression[] occurrences) {
|
||||
myFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
myDefaultType = type;
|
||||
myMainOccurence = mainOccurence;
|
||||
myOccurrences = occurrences;
|
||||
myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project);
|
||||
|
||||
myOccurrenceClassProvider = createOccurrenceClassProvider();
|
||||
myTypesForMain = getTypesForMain();
|
||||
myTypesForAll = getTypesForAll(true);
|
||||
|
||||
myIsOneSuggestion =
|
||||
myTypesForMain.length == 1 && myTypesForAll.length == 1 &&
|
||||
myTypesForAll[0].equals(myTypesForMain[0]);
|
||||
if (myIsOneSuggestion) {
|
||||
myTypeSelector = new TypeSelector(myTypesForAll[0]);
|
||||
}
|
||||
else {
|
||||
myTypeSelector = new TypeSelector();
|
||||
}
|
||||
|
||||
|
||||
this(project, type, null, mainOccurence, occurrences);
|
||||
}
|
||||
|
||||
public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression[] occurrences) {
|
||||
@@ -94,10 +77,64 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
}
|
||||
}
|
||||
|
||||
public TypeSelectorManagerImpl(Project project,
|
||||
PsiType type,
|
||||
PsiMethod containingMethod,
|
||||
PsiExpression mainOccurence,
|
||||
PsiExpression[] occurrences) {
|
||||
myFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
myDefaultType = type;
|
||||
myMainOccurence = mainOccurence;
|
||||
myOccurrences = occurrences;
|
||||
myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project);
|
||||
|
||||
myOccurrenceClassProvider = createOccurrenceClassProvider();
|
||||
myTypesForMain = getTypesForMain();
|
||||
myTypesForAll = getTypesForAll(true);
|
||||
|
||||
if (containingMethod != null) {
|
||||
if (PsiUtil.resolveClassInType(type) != null) {
|
||||
myDefaultType = checkIfTypeAccessible(type, project, containingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
myIsOneSuggestion =
|
||||
myTypesForMain.length == 1 && myTypesForAll.length == 1 &&
|
||||
myTypesForAll[0].equals(myTypesForMain[0]);
|
||||
if (myIsOneSuggestion) {
|
||||
myTypeSelector = new TypeSelector(myTypesForAll[0]);
|
||||
}
|
||||
else {
|
||||
myTypeSelector = new TypeSelector();
|
||||
}
|
||||
}
|
||||
|
||||
private PsiType checkIfTypeAccessible(PsiType type, Project project, PsiMethod containingMethod) {
|
||||
PsiClass parentClass = containingMethod.getContainingClass();
|
||||
final PsiClass typeClass = PsiUtil.resolveClassInType(type);
|
||||
if (typeClass != null) {
|
||||
if (typeClass instanceof PsiTypeParameter) {
|
||||
if (ArrayUtil.find(parentClass.getTypeParameters(), typeClass) == -1) { //unknown type parameter
|
||||
return PsiType.getJavaLangObject(PsiManager.getInstance(project), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
} else if (PsiTreeUtil.isAncestor(containingMethod, typeClass, true)) { //local class type
|
||||
final int nextTypeIdx = ArrayUtil.find(myTypesForAll, type) + 1;
|
||||
if (nextTypeIdx < myTypesForAll.length) {
|
||||
return checkIfTypeAccessible(myTypesForAll[nextTypeIdx], project, containingMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public PsiType[] getTypesForAll() {
|
||||
return myTypesForAll;
|
||||
}
|
||||
|
||||
public PsiType getDefaultType() {
|
||||
return myDefaultType;
|
||||
}
|
||||
|
||||
private ExpectedTypesProvider.ExpectedClassProvider createOccurrenceClassProvider() {
|
||||
final Set<PsiClass> occurrenceClasses = new HashSet<PsiClass>();
|
||||
for (final PsiExpression occurence : myOccurrences) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
void foo() {
|
||||
class C {}
|
||||
C c<caret>c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Test {
|
||||
class C {}
|
||||
|
||||
void foo() {
|
||||
C c<caret>c;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.PsiLocalVariable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
@@ -87,6 +88,37 @@ public class IntroduceConstantTest extends LightCodeInsightTestCase {
|
||||
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
public void testResultedType() throws Exception {
|
||||
checkDefaultType("java.lang.Object");
|
||||
}
|
||||
|
||||
public void testResultedTypeWhenNonLocal() throws Exception {
|
||||
checkDefaultType("Test.C");
|
||||
}
|
||||
|
||||
private void checkDefaultType(final String expectedType) throws Exception {
|
||||
configureByFile(BASE_PATH + getTestName(false) + ".java");
|
||||
new MockIntroduceConstantHandler(null){
|
||||
@Override
|
||||
protected Settings showRefactoringDialog(Project project,
|
||||
Editor editor,
|
||||
PsiClass parentClass,
|
||||
PsiExpression expr,
|
||||
PsiType type,
|
||||
PsiExpression[] occurences,
|
||||
PsiElement anchorElement,
|
||||
PsiElement anchorElementIfAll) {
|
||||
final TypeSelectorManagerImpl selectorManager =
|
||||
new TypeSelectorManagerImpl(project, type, PsiTreeUtil.getParentOfType(anchorElement, PsiMethod.class), expr, occurences);
|
||||
final PsiType psiType = selectorManager.getDefaultType();
|
||||
Assert.assertEquals(psiType.getCanonicalText(), expectedType);
|
||||
return new Settings("xxx", true, true, true,
|
||||
InitializationPlace.IN_FIELD_DECLARATION, getVisibility(), null, psiType, false,
|
||||
parentClass, false, false);
|
||||
}
|
||||
}.invoke(getProject(), getEditor(), getFile(), null);
|
||||
}
|
||||
|
||||
protected Sdk getProjectJDK() {
|
||||
return JavaSdkImpl.getMockJdk17("java 1.5");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user