mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
Type cook finished
This commit is contained in:
@@ -8,7 +8,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringImpl;
|
||||
import com.intellij.refactoring.TypeCookRefactoring;
|
||||
import com.intellij.refactoring.typeCook.TypeCookProcessor;
|
||||
import com.intellij.refactoring.typeCook.deductive.TypeCookProcessor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -778,5 +778,71 @@ public class Util {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void changeType(final PsiElement element, final PsiType type) {
|
||||
try {
|
||||
if (element instanceof PsiTypeCastExpression) {
|
||||
final PsiTypeCastExpression cast = ((PsiTypeCastExpression)element);
|
||||
|
||||
cast.getCastType().replace(cast.getManager().getElementFactory().createTypeElement(type));
|
||||
}
|
||||
else if (element instanceof PsiVariable) {
|
||||
final PsiVariable field = ((PsiVariable)element);
|
||||
|
||||
field.normalizeDeclaration();
|
||||
field.getTypeElement().replace(field.getManager().getElementFactory().createTypeElement(type));
|
||||
}
|
||||
else if (element instanceof PsiMethod) {
|
||||
final PsiMethod method = ((PsiMethod)element);
|
||||
|
||||
method.getReturnTypeElement().replace(method.getManager().getElementFactory().createTypeElement(type));
|
||||
}
|
||||
else if (element instanceof PsiNewExpression) {
|
||||
final PsiNewExpression newx = (PsiNewExpression)element;
|
||||
final PsiClassType.ClassResolveResult result = Util.resolveType(type);
|
||||
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiSubstitutor subst = result.getSubstitutor();
|
||||
final PsiTypeParameter[] parms = Util.getTypeParametersList(result.getElement());
|
||||
|
||||
if (parms.length >= 0 && subst.substitute(parms[0]) != null) {
|
||||
PsiJavaCodeReferenceElement classReference = newx.getClassReference();
|
||||
PsiReferenceParameterList list = null;
|
||||
|
||||
if (classReference == null) {
|
||||
list = newx.getAnonymousClass().getBaseClassReference().getParameterList();
|
||||
}
|
||||
else {
|
||||
list = classReference.getParameterList();
|
||||
}
|
||||
|
||||
if (list == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiElementFactory factory = newx.getManager().getElementFactory();
|
||||
|
||||
PsiTypeElement[] elements = list.getTypeParameterElements();
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
elements[i].delete();
|
||||
}
|
||||
|
||||
for (int i = 0; i < parms.length; i++) {
|
||||
PsiType aType = subst.substitute(parms[i]);
|
||||
list.add(factory.createTypeElement(aType == null ? PsiType.getJavaLangObject(list.getManager()) : aType));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.error ("Unexpected element type " + element.getClass().getName());
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error("Incorrect Operation Exception thrown in CastRole.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.intellij.refactoring.typeCook.deductive.builder;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable;
|
||||
import com.intellij.refactoring.typeCook.deductive.resolver.Binding;
|
||||
import com.intellij.refactoring.typeCook.Bottom;
|
||||
import com.intellij.refactoring.typeCook.Util;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: db
|
||||
* Date: Feb 7, 2005
|
||||
* Time: 7:40:34 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class Result {
|
||||
final HashSet<PsiElement> myVictims;
|
||||
final HashMap<PsiElement, PsiType> myTypes;
|
||||
final Project myProject;
|
||||
|
||||
Binding myBinding;
|
||||
|
||||
public Result(final System system) {
|
||||
myVictims = system.myElements;
|
||||
myTypes = system.myTypes;
|
||||
myProject = system.myProject;
|
||||
}
|
||||
|
||||
final private PsiType substitute(final PsiType t) {
|
||||
if (t instanceof PsiWildcardType) {
|
||||
final PsiWildcardType wcType = (PsiWildcardType)t;
|
||||
final PsiType bound = wcType.getBound();
|
||||
|
||||
if (bound == null) {
|
||||
return t;
|
||||
}
|
||||
|
||||
final PsiManager manager = PsiManager.getInstance(myProject);
|
||||
final PsiType subst = substitute(bound);
|
||||
return wcType.isExtends() ? PsiWildcardType.createExtends(manager, subst) : PsiWildcardType.createSuper(manager, subst);
|
||||
}
|
||||
else if (t instanceof PsiTypeVariable) {
|
||||
final PsiType b = myBinding.apply(t);
|
||||
|
||||
if (b instanceof Bottom || b instanceof PsiTypeVariable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return substitute(b);
|
||||
}
|
||||
else if (t instanceof Bottom) {
|
||||
return null;
|
||||
}
|
||||
else if (t instanceof PsiArrayType) {
|
||||
return substitute(((PsiArrayType)t).getComponentType()).createArrayType();
|
||||
}
|
||||
else if (t instanceof PsiClassType) {
|
||||
final PsiClassType.ClassResolveResult result = ((PsiClassType)t).resolveGenerics();
|
||||
|
||||
final PsiClass aClass = result.getElement();
|
||||
final PsiSubstitutor aSubst = result.getSubstitutor();
|
||||
|
||||
if (aClass == null) {
|
||||
return t;
|
||||
}
|
||||
|
||||
PsiSubstitutor theSubst = PsiSubstitutor.EMPTY;
|
||||
|
||||
for (final Iterator<PsiTypeParameter> p = aSubst.getSubstitutionMap().keySet().iterator(); p.hasNext();) {
|
||||
final PsiTypeParameter parm = p.next();
|
||||
final PsiType type = aSubst.substitute(parm);
|
||||
|
||||
theSubst = theSubst.put(parm, substitute(type));
|
||||
}
|
||||
|
||||
return aClass.getManager().getElementFactory().createType(aClass, theSubst);
|
||||
}
|
||||
else {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public void incorporateSolution(final Binding binding) {
|
||||
if (myBinding == null) {
|
||||
myBinding = binding;
|
||||
}
|
||||
else {
|
||||
myBinding.merge(binding);
|
||||
}
|
||||
}
|
||||
|
||||
public PsiType getCookedType(final PsiElement element) {
|
||||
return substitute(myTypes.get(element));
|
||||
}
|
||||
|
||||
public HashSet<PsiElement> getCookedElements() {
|
||||
final HashSet<PsiElement> set = new HashSet<PsiElement>();
|
||||
|
||||
for (final Iterator<PsiElement> e = myVictims.iterator(); e.hasNext();) {
|
||||
final PsiElement element = e.next();
|
||||
final PsiType originalType =
|
||||
element instanceof PsiMethod
|
||||
? ((PsiMethod)element).getReturnType()
|
||||
: element instanceof PsiVariable
|
||||
? ((PsiVariable)element).getType()
|
||||
: ((PsiExpression)element).getType();
|
||||
|
||||
if (!originalType.equals(getCookedType(element))){
|
||||
set.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public void apply(final HashSet<PsiElement> victims) {
|
||||
for (final Iterator<PsiElement> e=victims.iterator(); e.hasNext();){
|
||||
final PsiElement element = e.next();
|
||||
|
||||
Util.changeType(element, getCookedType(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class SystemBuilder {
|
||||
myTypeVariableFactory = new PsiTypeVariableFactory();
|
||||
}
|
||||
|
||||
public HashSet<PsiElement> collect(final PsiElement[] scopes) {
|
||||
private HashSet<PsiElement> collect(final PsiElement[] scopes) {
|
||||
return new VictimCollector(scopes, mySettings).getVictims();
|
||||
}
|
||||
|
||||
@@ -848,6 +848,10 @@ public class SystemBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
public System build (final PsiElement[] scopes) {
|
||||
return build(collect(scopes));
|
||||
}
|
||||
|
||||
public System build(final HashSet<PsiElement> victims) {
|
||||
final PsiSearchHelper helper = myManager.getSearchHelper();
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory;
|
||||
import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: db
|
||||
@@ -30,4 +32,8 @@ public abstract class Binding {
|
||||
public abstract Binding reduceRecursive();
|
||||
|
||||
public abstract boolean binds(final PsiTypeVariable var);
|
||||
|
||||
public abstract void merge (Binding b);
|
||||
|
||||
public abstract HashSet<PsiTypeVariable> getBoundVariables ();
|
||||
}
|
||||
|
||||
@@ -450,6 +450,24 @@ public class BindingFactory {
|
||||
public boolean binds(final PsiTypeVariable var) {
|
||||
return myBindings[var.getIndex()] != null;
|
||||
}
|
||||
|
||||
public void merge(Binding b) {
|
||||
for (final Iterator<PsiTypeVariable> v=b.getBoundVariables().iterator(); v.hasNext();){
|
||||
final PsiTypeVariable var = v.next();
|
||||
final int index = var.getIndex();
|
||||
|
||||
if (myBindings[index] != null){
|
||||
LOG.error ("Oops... Binding conflict...");
|
||||
}
|
||||
else {
|
||||
myBindings[index] = b.apply(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<PsiTypeVariable> getBoundVariables() {
|
||||
return myBoundVariables;
|
||||
}
|
||||
}
|
||||
|
||||
interface Balancer {
|
||||
|
||||
@@ -1 +1 @@
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<? extends Simple>\nPsiField:x
|
||||
|
||||
@@ -1 +1 @@
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<? extends Simple>\nPsiField:x
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<? extends Simple>\nPsiField:x
|
||||
LinkedList<Simple>\nPsiField:y
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<? extends Simple>\nPsiField:x
|
||||
LinkedList<java.lang.Object>\nPsiField:y
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<? extends Simple>\nPsiField:x
|
||||
LinkedList<Simple>\nPsiField:y
|
||||
|
||||
@@ -1 +1 @@
|
||||
List\nPsiLocalVariable:y
|
||||
List<java.lang.String>\nPsiLocalVariable:y
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
A\nPsiLocalVariable:a
|
||||
List\nPsiLocalVariable:y
|
||||
List<java.lang.String>\nPsiLocalVariable:y
|
||||
|
||||
@@ -1 +1 @@
|
||||
Collection\nparameter 0 of g
|
||||
Collection<B>\nparameter 0 of g
|
||||
|
||||
2
testData/refactoring/typeCook/t129/after/Test.1.items
Normal file
2
testData/refactoring/typeCook/t129/after/Test.1.items
Normal file
@@ -0,0 +1,2 @@
|
||||
Collection<B>\nparameter 0 of g
|
||||
Set<B>\nPsiLocalVariable:x
|
||||
2
testData/refactoring/typeCook/t129/after/Test.items
Normal file
2
testData/refactoring/typeCook/t129/after/Test.items
Normal file
@@ -0,0 +1,2 @@
|
||||
Collection\nparameter 0 of g
|
||||
Set\nPsiLocalVariable:x
|
||||
@@ -1,3 +1,3 @@
|
||||
LinkedList<LinkedList>\nPsiField:y
|
||||
LinkedList<? extends LinkedList>\nPsiField:y
|
||||
LinkedList\nPsiField:x
|
||||
LinkedList\nPsiTypeCastExpression:(LinkedList) y.get()
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
List<java.lang.Object>\nPsiLocalVariable:requests
|
||||
List<java.lang.Object>\nPsiTypeCastExpression:(ArrayList)requestMap.get(new A())
|
||||
ArrayList\nPsiLocalVariable:requests
|
||||
ArrayList\nPsiTypeCastExpression:(ArrayList)requestMap.get(new A())
|
||||
Map\nparameter 0 of f
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LinkedList<? extends Simple>\nPsiField:y
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<Simple>\nPsiField:y
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LinkedList<Simple>\nPsiField:x
|
||||
LinkedList<? extends Simple>\nPsiField:x
|
||||
LinkedList<Simple>\nPsiField:y
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
LinkedList<LinkedList>\nPsiField:x
|
||||
LinkedList<? extends LinkedList>\nPsiField:x
|
||||
LinkedList<java.lang.Object>\nPsiField:y
|
||||
LinkedList\nPsiTypeCastExpression:(LinkedList) x.get()
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
LinkedList<java.lang.Integer,java.lang.String>\nPsiLocalVariable:y
|
||||
ListLinked<java.lang.String,java.lang.Integer>\nPsiLocalVariable:x
|
||||
ListLinked<java.lang.String,java.lang.Integer>\nnew
|
||||
LinkedList<? extends java.lang.Integer,java.lang.String>\nPsiLocalVariable:y
|
||||
ListLinked<java.lang.String,? extends java.lang.Integer>\nPsiLocalVariable:x
|
||||
ListLinked<java.lang.String,? extends java.lang.Integer>\nnew
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
LinkedList<java.lang.Integer,java.lang.Object>\nPsiLocalVariable:y
|
||||
ListLinked<java.lang.Object,java.lang.Integer>\nPsiLocalVariable:x
|
||||
ListLinked<java.lang.Object,java.lang.Integer>\nnew
|
||||
LinkedList<? extends java.lang.Integer,java.io.Serializable>\nPsiLocalVariable:y
|
||||
ListLinked<java.io.Serializable,? extends java.lang.Integer>\nPsiLocalVariable:x
|
||||
ListLinked<java.io.Serializable,? extends java.lang.Integer>\nnew
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
LinkedList<java.lang.Object>\nPsiLocalVariable:y
|
||||
LinkedList<java.lang.Object>\nnew
|
||||
LinkedList<java.lang.Object>\nparameter 0 of f
|
||||
LinkedList<java.io.Serializable>\nPsiLocalVariable:y
|
||||
LinkedList<java.io.Serializable>\nnew
|
||||
LinkedList<java.io.Serializable>\nparameter 0 of f
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
LinkedList<LinkedList<java.lang.Object>>\nPsiLocalVariable:x
|
||||
LinkedList<java.lang.Object>\nPsiLocalVariable:y
|
||||
LinkedList<java.lang.Object>\nPsiLocalVariable:z
|
||||
LinkedList<LinkedList<java.io.Serializable>>\nPsiLocalVariable:x
|
||||
LinkedList<java.io.Serializable>\nPsiLocalVariable:y
|
||||
LinkedList<java.io.Serializable>\nPsiLocalVariable:z
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
List<java.lang.String,java.lang.String>\nPsiLocalVariable:x
|
||||
List<java.lang.String,java.lang.String>\nnew
|
||||
List\nPsiLocalVariable:x
|
||||
List\nnew
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
List<java.lang.Object>\nPsiLocalVariable:x
|
||||
List<java.lang.Object>\nPsiLocalVariable:y
|
||||
List<java.lang.Object>\nnew
|
||||
List<java.lang.Object>\nnew
|
||||
List<java.io.Serializable>\nPsiLocalVariable:x
|
||||
List<java.io.Serializable>\nPsiLocalVariable:y
|
||||
List<java.io.Serializable>\nnew
|
||||
List<java.io.Serializable>\nnew
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Iterator<Set<java.lang.String>>\nPsiLocalVariable:i
|
||||
OfList<Set<java.lang.String>>\nPsiLocalVariable:x
|
||||
OfList<Set<java.lang.String>>\nnew
|
||||
Iterator<? extends Set<java.lang.String>>\nPsiLocalVariable:i
|
||||
OfList<? extends Set<java.lang.String>>\nPsiLocalVariable:x
|
||||
OfList<? extends Set<java.lang.String>>\nnew
|
||||
Set<java.lang.String>\nPsiLocalVariable:u
|
||||
Set<java.lang.String>\nPsiTypeCastExpression:(Set) i.get()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Iterator<Set<java.lang.String>>\nPsiLocalVariable:i
|
||||
OfList<Set<java.lang.String>>\nPsiLocalVariable:x
|
||||
OfList<Set<java.lang.String>>\nnew
|
||||
Set<java.lang.String>\nPsiLocalVariable:u
|
||||
Set<java.lang.String>\nPsiTypeCastExpression:(Set) i.get()
|
||||
Iterator<? extends Set<? extends java.lang.String>>\nPsiLocalVariable:i
|
||||
OfList<? extends Set<? extends java.lang.String>>\nPsiLocalVariable:x
|
||||
OfList<? extends Set<? extends java.lang.String>>\nnew
|
||||
Set<? extends java.lang.String>\nPsiLocalVariable:u
|
||||
Set<? extends java.lang.String>\nPsiTypeCastExpression:(Set) i.get()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Iterator<Set<java.lang.String>>\nPsiLocalVariable:i
|
||||
OfList<Set<java.lang.String>>\nPsiLocalVariable:x
|
||||
OfList<Set<java.lang.String>>\nnew
|
||||
Iterator<? extends Set<java.lang.String>>\nPsiLocalVariable:i
|
||||
OfList<? extends Set<java.lang.String>>\nPsiLocalVariable:x
|
||||
OfList<? extends Set<java.lang.String>>\nnew
|
||||
Set<java.lang.String>\nPsiLocalVariable:u
|
||||
Set<java.lang.String>\nPsiTypeCastExpression:(Set) i.get()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
List<java.lang.Object>[]\nPsiLocalVariable:x
|
||||
List<java.lang.Object>[]\nnew
|
||||
List<java.lang.Object>\nPsiLocalVariable:y
|
||||
List<java.lang.Object>\nPsiLocalVariable:z
|
||||
List<java.lang.Object>\nnew
|
||||
List<java.lang.Object>\nnew
|
||||
List<java.io.Serializable>[]\nPsiLocalVariable:x
|
||||
List<java.io.Serializable>[]\nnew
|
||||
List<java.io.Serializable>\nPsiLocalVariable:y
|
||||
List<java.io.Serializable>\nPsiLocalVariable:z
|
||||
List<java.io.Serializable>\nnew
|
||||
List<java.io.Serializable>\nnew
|
||||
|
||||
@@ -1 +1 @@
|
||||
List\nPsiLocalVariable:x
|
||||
List<java.lang.String>\nPsiLocalVariable:x
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
List<int[]>\nPsiLocalVariable:x
|
||||
List<int[]>\nnew
|
||||
List<? extends int[]>\nPsiLocalVariable:x
|
||||
List<? extends int[]>\nnew
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
List\nparameter 0 of f
|
||||
List\nparameter 0 of g
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
List\nparameter 0 of f
|
||||
List\nparameter 0 of g
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
List<List<java.lang.Object>>\nPsiLocalVariable:x
|
||||
List<List<java.lang.Object>>\nPsiLocalVariable:y
|
||||
List<List<java.lang.Object>>\nnew
|
||||
List<List<java.lang.Object>>\nnew
|
||||
List<List<java.io.Serializable>>\nPsiLocalVariable:x
|
||||
List<List<java.io.Serializable>>\nPsiLocalVariable:y
|
||||
List<List<java.io.Serializable>>\nnew
|
||||
List<List<java.io.Serializable>>\nnew
|
||||
|
||||
@@ -649,7 +649,7 @@ public class TypeCookTest extends MultiFileTestCase {
|
||||
}
|
||||
});
|
||||
|
||||
final com.intellij.refactoring.typeCook.deductive.builder.System commonSystem = b.build(b.collect(new PsiElement[]{aClass}));
|
||||
final com.intellij.refactoring.typeCook.deductive.builder.System commonSystem = b.build(new PsiElement[]{aClass});
|
||||
|
||||
System.out.println("System built:\n" + commonSystem);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user