mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
create field from parameter: all erase unavailable type params (IDEA-56163)
This commit is contained in:
+25
-12
@@ -37,16 +37,15 @@ import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.CreateFieldFromParameterAction");
|
||||
@@ -57,15 +56,29 @@ public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
if (parameter == null) return null;
|
||||
PsiType type = parameter.getType();
|
||||
if (type instanceof PsiEllipsisType) type = ((PsiEllipsisType)type).toArrayType();
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass instanceof PsiTypeParameter && parameter.getDeclarationScope() == ((PsiTypeParameter)psiClass).getOwner()) {
|
||||
final PsiReferenceList extendsList = psiClass.getExtendsList();
|
||||
LOG.assertTrue(extendsList != null);
|
||||
final PsiClassType[] types = extendsList.getReferencedTypes();
|
||||
if (types.length > 0) return types;
|
||||
return new PsiType[]{PsiType.getJavaLangObject(parameter.getManager(), GlobalSearchScope.allScope(parameter.getProject()))};
|
||||
final PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type);
|
||||
final PsiClass psiClass = result.getElement();
|
||||
if (psiClass == null) return new PsiType[] {type};
|
||||
final HashSet<PsiTypeParameter> usedTypeParameters = new HashSet<PsiTypeParameter>();
|
||||
RefactoringUtil.collectTypeParameters(usedTypeParameters, parameter);
|
||||
for (Iterator<PsiTypeParameter> iterator = usedTypeParameters.iterator(); iterator.hasNext();) {
|
||||
PsiTypeParameter usedTypeParameter = iterator.next();
|
||||
if (parameter.getDeclarationScope() != usedTypeParameter.getOwner()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return new PsiType[]{type};
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(parameter.getProject());
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
for (PsiTypeParameter usedTypeParameter : usedTypeParameters) {
|
||||
subst = subst.put(usedTypeParameter, TypeConversionUtil.typeParameterErasure(usedTypeParameter));
|
||||
}
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
final Map<PsiTypeParameter, PsiType> typeMap = result.getSubstitutor().getSubstitutionMap();
|
||||
for (PsiTypeParameter typeParameter : typeMap.keySet()) {
|
||||
final PsiType psiType = typeMap.get(typeParameter);
|
||||
substitutor = substitutor.put(typeParameter, psiType != null ? subst.substitute(psiType) : null);
|
||||
}
|
||||
return new PsiType[]{psiClass instanceof PsiTypeParameter ? subst.substitute((PsiTypeParameter)psiClass) : elementFactory.createType(psiClass, substitutor)};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1173,31 +1173,8 @@ public class RefactoringUtil {
|
||||
final Set<PsiTypeParameter> used = new HashSet<PsiTypeParameter>();
|
||||
for (final PsiElement element : elements) {
|
||||
if (element == null) continue;
|
||||
element.accept(new JavaRecursiveElementVisitor() { //pull up extends cls class with type params
|
||||
collectTypeParameters(used, element); //pull up extends cls class with type params
|
||||
|
||||
@Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
super.visitReferenceElement(reference);
|
||||
if (!reference.isQualified()) {
|
||||
final PsiElement resolved = reference.resolve();
|
||||
if (resolved instanceof PsiTypeParameter) {
|
||||
final PsiTypeParameter typeParameter = (PsiTypeParameter)resolved;
|
||||
if (PsiTreeUtil.isAncestor(typeParameter.getOwner(), element, true)) {
|
||||
used.add(typeParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(final PsiExpression expression) {
|
||||
super.visitExpression(expression);
|
||||
final PsiType type = expression.getType();
|
||||
final PsiClass resolved = PsiUtil.resolveClassInType(type);
|
||||
if (resolved instanceof PsiTypeParameter && PsiTreeUtil.isAncestor(((PsiTypeParameter)resolved).getOwner(), element, true)){
|
||||
used.add((PsiTypeParameter)resolved);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (fromList != null) {
|
||||
@@ -1228,4 +1205,31 @@ public class RefactoringUtil {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectTypeParameters(final Set<PsiTypeParameter> used, final PsiElement element) {
|
||||
element.accept(new JavaRecursiveElementVisitor() {
|
||||
@Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
super.visitReferenceElement(reference);
|
||||
if (!reference.isQualified()) {
|
||||
final PsiElement resolved = reference.resolve();
|
||||
if (resolved instanceof PsiTypeParameter) {
|
||||
final PsiTypeParameter typeParameter = (PsiTypeParameter)resolved;
|
||||
if (PsiTreeUtil.isAncestor(typeParameter.getOwner(), element, true)) {
|
||||
used.add(typeParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(final PsiExpression expression) {
|
||||
super.visitExpression(expression);
|
||||
final PsiType type = expression.getType();
|
||||
final PsiClass resolved = PsiUtil.resolveClassInType(type);
|
||||
if (resolved instanceof PsiTypeParameter && PsiTreeUtil.isAncestor(((PsiTypeParameter)resolved).getOwner(), element, true)){
|
||||
used.add((PsiTypeParameter)resolved);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Create Field For Parameter 'p1'" "true"
|
||||
|
||||
import java.util.*;
|
||||
class Test{
|
||||
private final List<String> myP1;
|
||||
|
||||
<T extends String> void f(List<T> p1){
|
||||
myP1 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Create Field For Parameter 'p1'" "true"
|
||||
|
||||
import java.util.*;
|
||||
class Test<T>{
|
||||
private final List<T> myP1;
|
||||
|
||||
void f(List<T> p1){
|
||||
myP1 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Create Field For Parameter 'p1'" "true"
|
||||
|
||||
import java.util.*;
|
||||
class Test{
|
||||
private final List<Object> myP1;
|
||||
|
||||
<T> void f(List<T> p1){
|
||||
myP1 = p1;
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Create Field For Parameter 'p1'" "true"
|
||||
|
||||
import java.util.*;
|
||||
class Test{
|
||||
<T extends String> void f(List<T> p<caret>1){
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Create Field For Parameter 'p1'" "true"
|
||||
|
||||
import java.util.*;
|
||||
class Test<T>{
|
||||
void f(List<T> p<caret>1){
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Create Field For Parameter 'p1'" "true"
|
||||
|
||||
import java.util.*;
|
||||
class Test{
|
||||
<T> void f(List<T> p<caret>1){
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user