diff --git a/source/com/intellij/refactoring/typeCook/Bottom.java b/source/com/intellij/psi/Bottom.java similarity index 75% rename from source/com/intellij/refactoring/typeCook/Bottom.java rename to source/com/intellij/psi/Bottom.java index 26e27f3eb44f..f424b6bd9b55 100644 --- a/source/com/intellij/refactoring/typeCook/Bottom.java +++ b/source/com/intellij/psi/Bottom.java @@ -1,15 +1,9 @@ -package com.intellij.refactoring.typeCook; +package com.intellij.psi; -import com.intellij.psi.PsiType; -import com.intellij.psi.PsiTypeVisitor; import com.intellij.psi.search.GlobalSearchScope; /** - * Created by IntelliJ IDEA. - * User: db - * Date: 18.12.2003 - * Time: 18:55:48 - * To change this template use Options | File Templates. + * Used in Generify refactoring */ public class Bottom extends PsiType { public final static Bottom BOTTOM = new Bottom(); @@ -47,7 +41,10 @@ public class Bottom extends PsiType { } public A accept(PsiTypeVisitor visitor) { - return null; + if (visitor instanceof PsiTypeVisitorEx) { + return ((PsiTypeVisitorEx)visitor).visitBottom(this); + } + return visitor.visitType(this); } public PsiType[] getSuperTypes() { diff --git a/source/com/intellij/psi/PsiTypeVariable.java b/source/com/intellij/psi/PsiTypeVariable.java new file mode 100644 index 000000000000..797867853b62 --- /dev/null +++ b/source/com/intellij/psi/PsiTypeVariable.java @@ -0,0 +1,17 @@ +package com.intellij.psi; + +/** + * Used in Generify refactoring + */ +public abstract class PsiTypeVariable extends PsiType { + public abstract int getIndex(); + public abstract boolean isValidInContext (PsiType type); + + public A accept(PsiTypeVisitor visitor) { + if (visitor instanceof PsiTypeVisitorEx) { + return ((PsiTypeVisitorEx)visitor).visitTypeVariable(this); + } + + return visitor.visitType(this); + } +} diff --git a/source/com/intellij/psi/PsiTypeVisitorEx.java b/source/com/intellij/psi/PsiTypeVisitorEx.java new file mode 100644 index 000000000000..d4a89bd48962 --- /dev/null +++ b/source/com/intellij/psi/PsiTypeVisitorEx.java @@ -0,0 +1,14 @@ +package com.intellij.psi; + +/** + * @author ven + */ +public class PsiTypeVisitorEx extends PsiTypeVisitor { + public A visitTypeVariable(PsiTypeVariable var) { + return visitType(var); + } + + public A visitBottom (Bottom bottom) { + return visitType(bottom); + } +} diff --git a/source/com/intellij/psi/impl/PsiSubstitutorImpl.java b/source/com/intellij/psi/impl/PsiSubstitutorImpl.java index 239d211936ca..0ba25fdddfde 100644 --- a/source/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/source/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -52,7 +52,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutorEx { } } - private abstract class SubstitutionVisitor extends PsiTypeVisitor { + private abstract class SubstitutionVisitor extends PsiTypeVisitorEx { public PsiType visitType(PsiType type) { LOG.assertTrue(false); return null; @@ -103,6 +103,14 @@ public class PsiSubstitutorImpl implements PsiSubstitutorEx { return new PsiEllipsisType(substitutedComponentType); } + public PsiType visitTypeVariable(final PsiTypeVariable var) { + return var; + } + + public PsiType visitBottom(final Bottom bottom) { + return bottom; + } + public abstract PsiType visitClassType(PsiClassType classType); } diff --git a/source/com/intellij/refactoring/typeCook/Util.java b/source/com/intellij/refactoring/typeCook/Util.java index a82aef9c1991..d44ed2f2ab2b 100644 --- a/source/com/intellij/refactoring/typeCook/Util.java +++ b/source/com/intellij/refactoring/typeCook/Util.java @@ -4,8 +4,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.refactoring.typeCook.deductive.PsiTypeIntersection; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.psi.PsiTypeVariable; import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; import com.intellij.util.IncorrectOperationException; @@ -310,57 +309,6 @@ public class Util { return t; } - public static PsiType substituteType(final PsiType type, final PsiSubstitutor subst) { - if (type == null) return null; - if (type instanceof PsiWildcardType) { - final PsiWildcardType wcType = ((PsiWildcardType)type); - final PsiType bound = wcType.getBound(); - - if (bound != null) { - final PsiClass aClass = resolveType(bound).getElement(); - - if (aClass != null) { - final PsiManager manager = aClass.getManager(); - - return wcType.isExtends() - ? PsiWildcardType.createExtends(manager, substituteType(bound, subst)) - : PsiWildcardType.createSuper(manager, substituteType(bound, subst)); - } - } - - return type; - } - else { - final int level = type.getArrayDimensions(); - final PsiClassType.ClassResolveResult result = resolveType(type); - final PsiClass aClass = result.getElement(); - - if (aClass != null) { - final PsiSubstitutor aSubst = result.getSubstitutor(); - final PsiManager manager = aClass.getManager(); - - if (aClass instanceof PsiTypeParameter) { - final PsiType sType = subst.substitute(((PsiTypeParameter)aClass)); - - return createArrayType(sType == null ? PsiType.getJavaLangObject(manager, aClass.getResolveScope()) : sType, level); - } - - final PsiTypeParameter[] aParms = getTypeParametersList(aClass); - PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; - - for (int i = 0; i < aParms.length; i++) { - PsiTypeParameter aParm = aParms[i]; - - theSubst = theSubst.put(aParm, substituteType(aSubst.substitute(aParm), subst)); - } - - return createArrayType(aClass.getManager().getElementFactory().createType(aClass, theSubst), level); - } - - return type; - } - } - public static boolean bindsTypeVariables(final PsiType t) { if (t == null) { return false; @@ -378,10 +326,12 @@ public class Util { return bindsTypeVariables(((PsiWildcardType)t).getBound()); } - if (t instanceof PsiTypeIntersection) { - final PsiTypeIntersection itype = ((PsiTypeIntersection)t); - - return bindsTypeVariables(itype.getLeft()) || bindsTypeVariables(itype.getRight()); + if (t instanceof PsiIntersectionType) { + final PsiType[] conjuncts = ((PsiIntersectionType)t).getConjuncts(); + for (int i = 0; i < conjuncts.length; i++) { + if (bindsTypeVariables(conjuncts[i])) return true; + } + return false; } final PsiClassType.ClassResolveResult result = resolveType(t); diff --git a/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java b/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java index 1c3c41adf9b4..e29ad7ca4f0b 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java +++ b/source/com/intellij/refactoring/typeCook/deductive/PsiExtendedTypeVisitor.java @@ -1,8 +1,6 @@ package com.intellij.refactoring.typeCook.deductive; -import com.intellij.psi.PsiTypeVisitor; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; import java.util.Iterator; @@ -13,9 +11,7 @@ import java.util.Iterator; * Time: 7:20:09 PM * To change this template use File | Settings | File Templates. */ -public abstract class PsiExtendedTypeVisitor extends PsiTypeVisitor { - public abstract X visitTypeVariable(PsiTypeVariable var); - +public abstract class PsiExtendedTypeVisitor extends PsiTypeVisitorEx { public X visitClassType(final PsiClassType classType) { super.visitClassType(classType); final PsiClassType.ClassResolveResult result = classType.resolveGenerics(); diff --git a/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java b/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java index ce32cb361408..56cb03151d3d 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java +++ b/source/com/intellij/refactoring/typeCook/deductive/PsiTypeVariableFactory.java @@ -155,14 +155,6 @@ public class PsiTypeVariableFactory { return text.equals(getPresentableText()); } - public A accept(PsiTypeVisitor visitor) { - if (visitor instanceof PsiExtendedTypeVisitor) { - return ((PsiExtendedTypeVisitor)visitor).visitTypeVariable(this); - } - - return null; - } - public GlobalSearchScope getResolveScope() { return null; } diff --git a/source/com/intellij/refactoring/typeCook/deductive/builder/Result.java b/source/com/intellij/refactoring/typeCook/deductive/builder/Result.java index 1c745c9520ba..7738d9dfbbaa 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/builder/Result.java +++ b/source/com/intellij/refactoring/typeCook/deductive/builder/Result.java @@ -2,10 +2,10 @@ package com.intellij.refactoring.typeCook.deductive.builder; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.psi.PsiTypeVariable; import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; import com.intellij.refactoring.typeCook.deductive.resolver.Binding; -import com.intellij.refactoring.typeCook.Bottom; +import com.intellij.psi.Bottom; import com.intellij.refactoring.typeCook.Util; import com.intellij.refactoring.typeCook.Settings; import com.intellij.openapi.project.Project; diff --git a/source/com/intellij/refactoring/typeCook/deductive/builder/System.java b/source/com/intellij/refactoring/typeCook/deductive/builder/System.java index ff9697ba2df7..7f8b30bf058c 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/builder/System.java +++ b/source/com/intellij/refactoring/typeCook/deductive/builder/System.java @@ -3,10 +3,9 @@ package com.intellij.refactoring.typeCook.deductive.builder; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.typeCook.Util; -import com.intellij.refactoring.typeCook.Bottom; +import com.intellij.psi.Bottom; import com.intellij.refactoring.typeCook.Settings; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; -import com.intellij.refactoring.typeCook.deductive.PsiTypeIntersection; +import com.intellij.psi.PsiTypeVariable; import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; import com.intellij.refactoring.typeCook.deductive.resolver.Binding; import com.intellij.openapi.project.Project; @@ -207,7 +206,7 @@ public class System { boundVars.add((PsiTypeVariable)t); } else if (t instanceof PsiArrayType) { - visit(((PsiArrayType)t).getDeepComponentType()); + visit(t.getDeepComponentType()); } else if (t instanceof PsiClassType) { final PsiSubstitutor subst = Util.resolveType(t).getSubstitutor(); @@ -216,9 +215,12 @@ public class System { visit(j.next()); } } - else if (t instanceof PsiTypeIntersection) { - visit(((PsiTypeIntersection)t).getLeft()); - visit(((PsiTypeIntersection)t).getRight()); + else if (t instanceof PsiIntersectionType) { + final PsiType[] conjuncts = ((PsiIntersectionType)t).getConjuncts(); + for (int j = 0; j < conjuncts.length; j++) { + visit(conjuncts[j]); + + } } } }.visit(constraint); diff --git a/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java b/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java index b889c301f48b..5c8081fb6d70 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java +++ b/source/com/intellij/refactoring/typeCook/deductive/builder/SystemBuilder.java @@ -7,7 +7,7 @@ import com.intellij.psi.search.PsiSearchHelper; import com.intellij.psi.util.*; import com.intellij.refactoring.typeCook.Settings; import com.intellij.refactoring.typeCook.Util; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.psi.PsiTypeVariable; import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; import com.intellij.refactoring.typeCook.deductive.util.VictimCollector; import com.intellij.util.containers.HashMap; @@ -260,10 +260,10 @@ public class SystemBuilder { if (!qualifierClass.equals(aClass)) { supertypeSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(aClass, qualifierClass, PsiSubstitutor.EMPTY); - aType = Util.substituteType(aType, supertypeSubstitutor); + aType = supertypeSubstitutor.substitute(aType); } - aType = Util.substituteType(aType, qualifierSubstitutor); + aType = qualifierSubstitutor.substitute(aType); } } @@ -289,7 +289,7 @@ public class SystemBuilder { system.addSubtypeConstraint(argumenType, parmType); } else { - parmType = Util.substituteType(Util.substituteType(parameters[i].getType(), supertypeSubstitutor), qualifierSubstitutor); + parmType = qualifierSubstitutor.substitute(supertypeSubstitutor.substitute(parameters[i].getType())); if (!Util.bindsTypeVariables(parmType) && !Util.bindsTypeParameters(parmType, typeParameters)) { parmType = Util.banalize(parmType); @@ -318,47 +318,47 @@ public class SystemBuilder { for (int j = 0; j < extypes.length; j++) { final PsiClassType ext = extypes[j]; - final PsiType extype = Util.substituteType(new Object() { - public PsiType substitute(final PsiType ext) { - final PsiClassType.ClassResolveResult result = - Util.resolveType(ext); - final PsiClass aClass = result.getElement(); + final PsiType extype = qualifier.substitute(new Object() { + public PsiType substitute(final PsiType ext) { + final PsiClassType.ClassResolveResult result = + Util.resolveType(ext); + final PsiClass aClass = result.getElement(); - if (aClass != null) { - if (aClass instanceof PsiTypeParameter) { - final PsiType type = mapping.get(aClass); + if (aClass != null) { + if (aClass instanceof PsiTypeParameter) { + final PsiType type = mapping.get(aClass); - if (type != null) { - return type; + if (type != null) { + return type; + } + + return ext; } - return ext; - } + final PsiSubstitutor aSubst = result.getSubstitutor(); + PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; - final PsiSubstitutor aSubst = result.getSubstitutor(); - PsiSubstitutor theSubst = PsiSubstitutor.EMPTY; + for (final Iterator p = + aSubst.getSubstitutionMap().keySet().iterator(); + p.hasNext();) { + final PsiTypeParameter parm = p.next(); - for (final Iterator p = - aSubst.getSubstitutionMap().keySet().iterator(); - p.hasNext();) { - final PsiTypeParameter parm = p.next(); + PsiType type = aSubst.substitute(parm); - PsiType type = aSubst.substitute(parm); + if (type != null) { + type = substitute(type); + } - if (type != null) { - type = substitute(type); + theSubst = theSubst.put(parm, type); } - theSubst = theSubst.put(parm, type); + return aClass.getManager().getElementFactory() + .createType(aClass, theSubst); } - return aClass.getManager().getElementFactory() - .createType(aClass, theSubst); + return ext; } - - return ext; - } - }.substitute(ext), qualifier); + }.substitute(ext)); system.addSubtypeConstraint(pv, extype); } @@ -378,7 +378,7 @@ public class SystemBuilder { final PsiType theBound = wildcard.getBound(); if (theBound != null) { - final PsiType bound = Util.substituteType(Util.substituteType(theBound, supertype), qualifier); + final PsiType bound = qualifier.substitute(supertype.substitute(theBound)); if (Util.bindsTypeVariables(bound)) { final PsiType var = myTypeVariableFactory.create(); @@ -409,7 +409,7 @@ public class SystemBuilder { subst = subst.put(aTypeParm, parmVar); } - final PsiType bnd = Util.substituteType(bound, subst); + final PsiType bnd = subst.substitute(bound); if (wildcard.isExtends()) { system.addSubtypeConstraint(bnd, var); @@ -489,7 +489,7 @@ public class SystemBuilder { theSubst = theSubst.put(parm, type); } - return Util.substituteType(aType, theSubst); + return theSubst.substitute(aType); } } else if (expr instanceof PsiParenthesizedExpression) { @@ -524,10 +524,10 @@ public class SystemBuilder { if (!aClass.equals(superClass) && field.isPhysical()) { aType = - Util.substituteType(aType, TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY)); + TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY).substitute(aType); } - return Util.substituteType(aType, aSubst); + return aSubst.substitute(aType); } } else if (element != null) { @@ -754,10 +754,10 @@ public class SystemBuilder { if (bound != null) { if (wildcard.isExtends()) { - system.addSubtypeConstraint(Util.banalize(Util.substituteType(replaceWildCards(bound), definedSubst)), var); + system.addSubtypeConstraint(Util.banalize(definedSubst.substitute(replaceWildCards(bound))), var); } else { - system.addSubtypeConstraint(var, Util.banalize(Util.substituteType(replaceWildCards(bound), definedSubst))); + system.addSubtypeConstraint(var, Util.banalize(definedSubst.substitute(replaceWildCards(bound)))); } } @@ -785,7 +785,7 @@ public class SystemBuilder { } }.replaceWildCards(extendsList[j]); - system.addSubtypeConstraint(definedType, Util.banalize(Util.substituteType(extendsType, definedSubst))); + system.addSubtypeConstraint(definedType, Util.banalize(definedSubst.substitute(extendsType))); } } else { diff --git a/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java b/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java index 31e6760b0fd0..bbb8bf6c48ee 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java +++ b/source/com/intellij/refactoring/typeCook/deductive/resolver/Binding.java @@ -1,8 +1,7 @@ package com.intellij.refactoring.typeCook.deductive.resolver; import com.intellij.psi.PsiType; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.psi.PsiTypeVariable; import java.util.HashSet; diff --git a/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java b/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java index 27caf1669b50..b995859ec2da 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java +++ b/source/com/intellij/refactoring/typeCook/deductive/resolver/BindingFactory.java @@ -1,12 +1,12 @@ package com.intellij.refactoring.typeCook.deductive.resolver; import com.intellij.refactoring.typeCook.deductive.PsiTypeVariableFactory; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.psi.PsiTypeVariable; import com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor; import com.intellij.refactoring.typeCook.deductive.builder.Constraint; import com.intellij.refactoring.typeCook.deductive.builder.Subtype; import com.intellij.refactoring.typeCook.Util; -import com.intellij.refactoring.typeCook.Bottom; +import com.intellij.psi.Bottom; import com.intellij.psi.*; import com.intellij.psi.search.PsiSearchHelper; import com.intellij.psi.search.GlobalSearchScope; diff --git a/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java b/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java index b421b6bc538b..7a645078a49b 100644 --- a/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java +++ b/source/com/intellij/refactoring/typeCook/deductive/resolver/ResolverTree.java @@ -7,11 +7,11 @@ import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.refactoring.typeCook.deductive.PsiTypeVariable; +import com.intellij.psi.PsiTypeVariable; import com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor; import com.intellij.refactoring.typeCook.deductive.builder.Constraint; import com.intellij.refactoring.typeCook.deductive.builder.Subtype; -import com.intellij.refactoring.typeCook.Bottom; +import com.intellij.psi.Bottom; import com.intellij.refactoring.typeCook.Util; import com.intellij.refactoring.typeCook.Settings; import com.intellij.util.graph.Graph;