Type Cook

This commit is contained in:
Dmitri Boulytchev
2005-02-18 18:32:44 +03:00
parent 6c9ad968db
commit ec5cc1f8a9
15 changed files with 287 additions and 186 deletions
@@ -63,7 +63,8 @@ public abstract class RefactoringFactory {
public abstract TypeCookRefactoring createTypeCook(PsiElement[] elements,
boolean dropObsoleteCasts,
boolean leaveObjectsRaw,
boolean preserveRawArrays);
boolean preserveRawArrays,
boolean exhaustive);
/**
* Creates Introduce Parameter refactoring that replaces local variable with parameter.
@@ -54,6 +54,7 @@ public class RefactoringSettings implements JDOMExternalizable, ApplicationCompo
public boolean TYPE_COOK_DROP_CASTS = true;
public boolean TYPE_COOK_PRESERVE_RAW_ARRAYS = true;
public boolean TYPE_COOK_LEAVE_OBJECT_PARAMETERIZED_TYPES_RAW = true;
public boolean TYPE_COOK_EXHAUSTIVE = false;
public boolean TYPE_MIGRATION_PREVIEW_USAGES = true;
@@ -112,8 +112,9 @@ public class RefactoringFactoryImpl extends RefactoringFactory implements Projec
public TypeCookRefactoring createTypeCook(PsiElement[] elements,
boolean dropObsoleteCasts,
boolean leaveObjectsRaw,
boolean preserveRawArrays) {
return new TypeCookRefactoringImpl(myProject, elements, dropObsoleteCasts, leaveObjectsRaw, preserveRawArrays);
boolean preserveRawArrays,
boolean exhaustive) {
return new TypeCookRefactoringImpl(myProject, elements, dropObsoleteCasts, leaveObjectsRaw, preserveRawArrays, exhaustive);
}
public IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn,
@@ -21,7 +21,8 @@ public class TypeCookRefactoringImpl extends RefactoringImpl<TypeCookProcessor>
PsiElement[] elements,
final boolean dropObsoleteCasts,
final boolean leaveObjectsRaw,
final boolean preserveRawArrays) {
final boolean preserveRawArrays,
final boolean exh) {
super(new TypeCookProcessor(project, elements, new Settings() {
public boolean dropObsoleteCasts() {
return dropObsoleteCasts;
@@ -31,6 +32,10 @@ public class TypeCookRefactoringImpl extends RefactoringImpl<TypeCookProcessor>
return leaveObjectsRaw;
}
public boolean exhaustive() {
return exh;
}
public boolean preserveRawArrays() {
return preserveRawArrays;
}
@@ -11,4 +11,5 @@ public interface Settings {
boolean dropObsoleteCasts();
boolean preserveRawArrays();
boolean leaveObjectParameterizedTypesRaw();
boolean exhaustive();
}
@@ -19,7 +19,6 @@ import java.awt.*;
* To change this template use Options | File Templates.
*/
public class TypeCookDialog extends RefactoringDialog {
public static final String REFACTORING_NAME = "Generify";
private PsiElement[] myElements;
@@ -27,6 +26,7 @@ public class TypeCookDialog extends RefactoringDialog {
private JCheckBox myCbDropCasts = new JCheckBox("Drop obsolete casts");
private JCheckBox myCbPreserveRawArrays = new JCheckBox("Preserve raw arrays");
private JCheckBox myCbLeaveObjectParameterizedTypesRaw = new JCheckBox("Leave Object-parameterized types raw");
private JCheckBox myCbExhaustive = new JCheckBox("Perform exhaustive search");
public TypeCookDialog(Project project, PsiElement[] elements) {
super(project, true);
@@ -91,9 +91,15 @@ public class TypeCookDialog extends RefactoringDialog {
RefactoringSettings.getInstance().TYPE_COOK_LEAVE_OBJECT_PARAMETERIZED_TYPES_RAW);
}
if (myCbExhaustive.isEnabled()) {
myCbExhaustive.setSelected(
RefactoringSettings.getInstance().TYPE_COOK_EXHAUSTIVE);
}
myCbDropCasts.setMnemonic('D');
myCbPreserveRawArrays.setMnemonic('P');
myCbLeaveObjectParameterizedTypesRaw.setMnemonic('L');
myCbExhaustive.setMnemonic('E');
gbConstraints.insets = new Insets(4, 8, 4, 8);
@@ -119,6 +125,10 @@ public class TypeCookDialog extends RefactoringDialog {
gbConstraints.gridwidth = 2;
optionsPanel.add(myCbLeaveObjectParameterizedTypesRaw, gbConstraints);
gbConstraints.gridx = 0;
gbConstraints.gridwidth = 2;
optionsPanel.add(myCbExhaustive, gbConstraints);
return optionsPanel;
}
@@ -135,6 +145,7 @@ public class TypeCookDialog extends RefactoringDialog {
final boolean dropCasts = myCbDropCasts.isSelected();
final boolean preserveRawArrays = true; //myCbPreserveRawArrays.isSelected();
final boolean leaveObjectParameterizedTypesRaw = myCbLeaveObjectParameterizedTypesRaw.isSelected();
final boolean exh = myCbExhaustive.isSelected();
return new Settings() {
public boolean dropObsoleteCasts() {
@@ -148,6 +159,10 @@ public class TypeCookDialog extends RefactoringDialog {
public boolean leaveObjectParameterizedTypesRaw() {
return leaveObjectParameterizedTypesRaw;
}
public boolean exhaustive() {
return exh;
}
};
}
}
@@ -49,10 +49,10 @@ public class TypeCookProcessor extends BaseRefactoringProcessor {
tree.resolve();
final Binding[] solutions = tree.getSolutions();
final Binding solution = tree.getBestSolution();
if (solutions.length > 0) {
myResult.incorporateSolution(solutions[0]);
if (solution!= null) {
myResult.incorporateSolution(solution);
}
}
}
@@ -87,6 +87,8 @@ public class TypeCookProcessor extends BaseRefactoringProcessor {
myResult.apply (victims);
LOG.debug (myResult.getReport());
UndoManager.getInstance(myProject).undoableActionPerformed(new DummyComplexUndoableAction()); // force confirmation dialog for undo
}
@@ -28,76 +28,19 @@ public class Result {
private final HashSet<PsiElement> myVictims;
private final HashMap<PsiElement, PsiType> myTypes;
private final Project myProject;
private final Settings mySettings;
private final PsiTypeVariableFactory myFactory;
private final HashSet<PsiTypeCastExpression> myCasts;
private int myCookedNumber = -1;
private int myCastsRemoved = -1;
private Binding myBinding;
public Result(final System system) {
myVictims = system.myElements;
myTypes = system.myTypes;
myProject = system.myProject;
mySettings = system.mySettings;
myFactory = system.getVariableFactory();
}
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 subst instanceof PsiWildcardType ? subst : wcType.isExtends() ? PsiWildcardType.createExtends(manager, subst) : PsiWildcardType.createSuper(manager, subst);
}
else if (t instanceof PsiTypeVariable) {
if (myBinding == null) {
return null;
}
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;
}
myCasts = system.myCasts;
}
public void incorporateSolution(final Binding binding) {
@@ -110,24 +53,26 @@ public class Result {
}
public PsiType getCookedType(final PsiElement element) {
return substitute(myTypes.get(element));
if (myBinding != null) {
return myBinding.substitute(myTypes.get(element));
}
return Util.getType(element);
}
public HashSet<PsiElement> getCookedElements() {
myCookedNumber = 0;
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();
final PsiType originalType = Util.getType(element);
final PsiType cookedType = getCookedType(element);
if (cookedType != null && !originalType.equals(cookedType)) {
set.add(element);
myCookedNumber++;
}
}
@@ -139,19 +84,33 @@ public class Result {
final PsiElement element = e.next();
Util.changeType(element, getCookedType(element));
}
if (mySettings.dropObsoleteCasts() && element instanceof PsiTypeCastExpression){
final PsiTypeCastExpression cast = ((PsiTypeCastExpression)element);
if (mySettings.dropObsoleteCasts()) {
myCastsRemoved = 0;
if (cast.getType().equals(cast.getOperand().getType())){
for (final Iterator<PsiTypeCastExpression> c = myCasts.iterator(); c.hasNext();) {
final PsiTypeCastExpression cast = c.next();
if (cast.getType().equals(cast.getOperand().getType())) {
try {
cast.replace(cast.getOperand());
myCastsRemoved++;
}
catch (IncorrectOperationException e1) {
LOG.error (e1);
LOG.error(e1);
}
}
}
}
}
private String getRatio(final int x, final int y) {
return x != -1 ? x + " of " + y + (y != 0 ? " (" + (x * 100 / y) + "%)" : "") : "not calculated";
}
public String getReport() {
return "Items cooked : " + getRatio(myCookedNumber, myVictims.size()) + "\n" +
"Casts removed: " + getRatio(myCastsRemoved, myCasts.size()) + "\n";
}
}
@@ -24,6 +24,7 @@ import java.util.*;
public class System {
final HashSet<Constraint> myConstraints = new HashSet<Constraint>();
final HashSet<PsiElement> myElements;
final HashSet<PsiTypeCastExpression> myCasts;
final HashMap<PsiElement, PsiType> myTypes;
final PsiTypeVariableFactory myTypeVariableFactory;
final Project myProject;
@@ -42,6 +43,7 @@ public class System {
myTypeVariableFactory = factory;
myBoundVariables = null;
mySettings = settings;
myCasts = new HashSet<PsiTypeCastExpression> ();
}
public Project getProject() {
@@ -52,6 +54,10 @@ public class System {
return myConstraints;
}
public void addCast (final PsiTypeCastExpression cast){
myCasts.add(cast);
}
public void addSubtypeConstraint(final PsiType left, final PsiType right) {
if (left == null || right == null) {
return;
@@ -330,11 +336,7 @@ public class System {
for (final Iterator<PsiElement> e = myElements.iterator(); e.hasNext();) {
final PsiElement element = e.next();
data[i++] =
(element instanceof PsiVariable ? ((PsiVariable)element).getType() :
element instanceof PsiMethod ? ((PsiMethod)element).getReturnType() : ((PsiExpression)element).getType()).getCanonicalText() +
"\\n" +
elementString(element);
data[i++] = Util.getType(element).getCanonicalText() + "\\n" + elementString(element);
}
Arrays.sort(data,
@@ -375,7 +377,7 @@ public class System {
return element.toString();
}
public String dumpResult(final Binding[] bindings) {
public String dumpResult(final Binding bestBinding) {
final String[] data = new String[myElements.size()];
class Substitutor {
@@ -395,8 +397,8 @@ public class System {
: PsiWildcardType.createSuper(manager, subst);
}
else if (t instanceof PsiTypeVariable) {
if (bindings.length > 0) {
final PsiType b = bindings[0].apply(t);
if (bestBinding != null) {
final PsiType b = bestBinding.apply(t);
if (b instanceof Bottom || b instanceof PsiTypeVariable) {
return null;
@@ -471,4 +473,8 @@ public class System {
return repr.toString();
}
public Settings getSettings() {
return mySettings;
}
}
@@ -168,21 +168,7 @@ public class SystemBuilder {
return t;
}
if (e instanceof PsiVariable) {
t = ((PsiVariable)e).getType();
}
else if (e instanceof PsiTypeCastExpression) {
t = ((PsiTypeCastExpression)e).getCastType().getType();
}
else if (e instanceof PsiNewExpression) {
t = ((PsiNewExpression)e).getType();
}
else if (e instanceof PsiMethod) {
t = ((PsiMethod)e).getReturnType();
}
else {
LOG.error("Variable, method, new or cast expected but found " + (e == null ? " null" : e.getClass().getName()));
}
t = Util.getType(e);
final PsiType parameterizedType = Util.createParameterizedType(t, myTypeVariableFactory);
@@ -198,17 +184,7 @@ public class SystemBuilder {
return t;
}
if (e instanceof PsiVariable) {
return Util.banalize(((PsiVariable)e).getType());
}
else if (e instanceof PsiExpression) {
return Util.banalize(((PsiExpression)e).getType());
}
else if (e instanceof PsiMethod) {
return Util.banalize(((PsiMethod)e).getReturnType());
}
return null;
return Util.banalize(Util.getType(e));
}
private boolean isCooked(final PsiElement element) {
@@ -699,11 +675,6 @@ public class SystemBuilder {
e.valuateType(expression.getThenExpression()));
}
//public void visitMethodCallExpression(final PsiMethodCallExpression expression) {
// super.visitMethodCallExpression(expression);
// e.valuateType(expression);
//}
public void visitCallExpression(final PsiCallExpression expression) {
super.visitCallExpression(expression);
e.valuateType(expression);
@@ -722,9 +693,20 @@ public class SystemBuilder {
public void visitTypeCastExpression(final PsiTypeCastExpression expression) {
super.visitTypeCastExpression(expression);
system.addCast(expression);
system.addSubtypeConstraint(e.valuateType(expression.getOperand()), e.valuateType(expression));
}
public void visitVariable(final PsiVariable variable) {
super.visitVariable(variable);
final PsiExpression init = variable.getInitializer();
if (init != null) {
system.addSubtypeConstraint(e.valuateType(init), getType(variable));
}
}
public void visitNewExpression(final PsiNewExpression expression) {
super.visitNewExpression(expression);
@@ -755,9 +737,7 @@ public class SystemBuilder {
}
private void addBoundConstraints(final System system, final PsiType definedType, final PsiElement element) {
final PsiType elemenType =
(element instanceof PsiMethod) ? ((PsiMethod)element).getReturnType() :
(element instanceof PsiVariable) ? ((PsiVariable)element).getType() : null;
final PsiType elemenType = Util.getType(element);
if (elemenType != null) {
new Object() {
@@ -16,6 +16,8 @@ import java.util.HashSet;
public abstract class Binding {
public abstract PsiType apply(PsiType type);
public abstract PsiType substitute(PsiType type);
abstract Binding compose(Binding b);
final static int BETTER = 0;
@@ -33,7 +35,9 @@ public abstract class Binding {
public abstract boolean binds(final PsiTypeVariable var);
public abstract void merge (Binding b, boolean removeObject);
public abstract void merge(Binding b, boolean removeObject);
public abstract HashSet<PsiTypeVariable> getBoundVariables ();
public abstract HashSet<PsiTypeVariable> getBoundVariables();
public abstract int getWidth();
}
@@ -232,7 +232,7 @@ public class BindingFactory {
final BindingImpl b2 = (BindingImpl)binding;
final BindingImpl b1 = this;
int directoin = Binding.SAME;
int directoin = Binding.NONCOMPARABLE;
boolean first = true;
for (int i = 0; i < myBoundVariableIndices.length; i++) {
@@ -526,6 +526,76 @@ public class BindingFactory {
public HashSet<PsiTypeVariable> getBoundVariables() {
return myBoundVariables;
}
public int getWidth() {
int w = 0;
for (int i = 0; i < myBindings.length; i++) {
final PsiType type = substitute(myBindings[i]);
if (type != null) {
w++;
}
}
return w;
}
public 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 subst instanceof PsiWildcardType ? subst : wcType.isExtends()
? PsiWildcardType.createExtends(manager, subst)
: PsiWildcardType.createSuper(manager, subst);
}
else if (t instanceof PsiTypeVariable) {
final PsiType b = 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;
}
}
}
interface Balancer {
@@ -711,7 +781,7 @@ public class BindingFactory {
}
public Binding typeVar(PsiType x, PsiTypeVariable y) {
if (x == null){
if (x == null) {
return create(y, Bottom.BOTTOM);
}
@@ -13,6 +13,7 @@ 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.refactoring.typeCook.Util;
import com.intellij.refactoring.typeCook.Settings;
import com.intellij.util.graph.Graph;
import com.intellij.util.graph.DFSTBuilder;
import com.intellij.util.ArrayUtil;
@@ -35,6 +36,8 @@ public class ResolverTree {
private Binding myCurrentBinding;
private SolutionHolder mySolutions;
private Project myProject;
private HashMap<PsiTypeVariable, Integer> myBindingDegree;
private Settings mySettings;
private HashSet<Constraint> myConstraints;
@@ -44,6 +47,8 @@ public class ResolverTree {
myCurrentBinding = myBindingFactory.create();
myConstraints = system.getConstraints();
myProject = system.getProject();
myBindingDegree = calculateDegree(system.getConstraints());
mySettings = system.getSettings ();
reduceCyclicVariables();
}
@@ -54,6 +59,70 @@ public class ResolverTree {
mySolutions = parent.mySolutions;
myConstraints = constraints;
myProject = parent.myProject;
myBindingDegree = calculateDegree(constraints);
mySettings = parent.mySettings;
}
private static class PsiTypeVarCollector extends PsiExtendedTypeVisitor {
final HashSet<PsiTypeVariable> mySet = new HashSet<PsiTypeVariable>();
public Object visitTypeVariable(final PsiTypeVariable var) {
mySet.add(var);
return null;
}
public HashSet<PsiTypeVariable> getSet(final PsiType type) {
type.accept(this);
return mySet;
}
}
private boolean isBoundElseWhere(final PsiTypeVariable var) {
final Integer deg = myBindingDegree.get(var);
return deg == null || deg.intValue() > 1;
}
private boolean canBePruned(final Binding b) {
for (final Iterator<PsiTypeVariable> v = b.getBoundVariables().iterator(); v.hasNext();) {
final PsiTypeVariable var = v.next();
final PsiType type = b.apply(var);
if (!(type instanceof PsiTypeVariable) && isBoundElseWhere(var)) {
return false;
}
}
return !mySettings.exhaustive();
}
private HashMap<PsiTypeVariable, Integer> calculateDegree(final HashSet<Constraint> constraints) {
final HashMap<PsiTypeVariable, Integer> result = new HashMap<PsiTypeVariable, Integer>();
for (final Iterator<Constraint> c = constraints.iterator(); c.hasNext();) {
final Constraint constr = c.next();
final PsiTypeVarCollector collector = new PsiTypeVarCollector();
new Object() {
void setDegree(final HashSet<PsiTypeVariable> set) {
for (final Iterator<PsiTypeVariable> v = set.iterator(); v.hasNext();) {
final PsiTypeVariable var = v.next();
final Integer deg = result.get(var);
if (deg == null) {
result.put(var, new Integer(1));
}
else {
result.put(var, new Integer(deg.intValue() + 1));
}
}
}
}.setDegree(collector.getSet(constr.getRight()));
}
return result;
}
private HashSet<Constraint> apply(final Binding b, final HashSet<Constraint> constraints) {
@@ -190,21 +259,6 @@ public class ResolverTree {
}
}
private static class PsiTypeVarCollector extends PsiExtendedTypeVisitor {
final HashSet<PsiTypeVariable> mySet = new HashSet<PsiTypeVariable>();
public Object visitTypeVariable(final PsiTypeVariable var) {
mySet.add (var);
return null;
}
public HashSet<PsiTypeVariable> getSet (final PsiType type){
type.accept(this);
return mySet;
}
}
private void reduceTypeType(final Constraint constr) {
final PsiType left = constr.getLeft();
final PsiType right = constr.getRight();
@@ -217,21 +271,11 @@ public class ResolverTree {
if (indicator == 0) {
return;
}
else if (indicator == 2){// && riseBinding.equals(sinkBinding)) {
switch (riseBinding.compare(sinkBinding)) {
case Binding.SAME:
//case Binding.BETTER:
indicator = 1;
sinkBinding = null;
break;
//case Binding.WORSE:
// indicator = 1;
// riseBinding = null;
//break;
}
else if ((indicator == 2 && riseBinding.equals(sinkBinding)) || canBePruned(riseBinding)) {
indicator = 1;
sinkBinding = null;
}
myConstraints.remove(constr);
mySons = new ResolverTree[indicator];
@@ -327,18 +371,9 @@ public class ResolverTree {
if (indicator == 0) {
return;
}
else if (indicator == 2){// && riseBinding.equals(sinkBinding)) {
switch (riseBinding.compare(sinkBinding)) {
case Binding.SAME:
indicator = 1;
sinkBinding = null;
break;
//case Binding.WORSE:
// indicator = 1;
// riseBinding = null;
// break;
}
else if ((indicator == 2 && riseBinding.equals(sinkBinding)) || canBePruned(riseBinding)) {
indicator = 1;
sinkBinding = null;
}
PsiType[] riseRange = new PsiType[]{};
@@ -629,10 +664,10 @@ public class ResolverTree {
if (mySons.length > 0) {
for (int i = 0; i < mySons.length; i++) {
final ResolverTree son = mySons[i];
if (son != null) {
son.resolve();
if (mySons[i] != null) {
mySons[i].resolve();
mySons[i] = null;
}
}
}
@@ -645,7 +680,7 @@ public class ResolverTree {
}
}
public Binding[] getSolutions() {
return mySolutions.getBestSolutions();
public Binding getBestSolution() {
return mySolutions.getBestSolution();
}
}
@@ -18,24 +18,41 @@ public class SolutionHolder {
final Binding b2 = i.next();
switch (b1.compare(b2)) {
case Binding.WORSE:
case Binding.SAME:
return;
case Binding.WORSE:
case Binding.SAME:
return;
case Binding.BETTER:
mySolutions.remove(b2);
mySolutions.addFirst(b1);
return;
case Binding.BETTER:
mySolutions.remove(b2);
mySolutions.addFirst(b1);
return;
case Binding.NONCOMPARABLE:
continue;
case Binding.NONCOMPARABLE:
continue;
}
}
mySolutions.addFirst(b1);
}
public Binding[] getBestSolutions() {
public Binding[] getTopSolutions() {
return mySolutions.toArray(new Binding[]{});
}
public Binding getBestSolution() {
Binding best = null;
int width = 0;
for (final Iterator<Binding> b = mySolutions.iterator(); b.hasNext();) {
final Binding binding = b.next();
final int w = binding.getWidth();
if (w > width) {
width = w;
best = binding;
}
}
return best;
}
}
@@ -647,6 +647,10 @@ public class TypeCookTest extends MultiFileTestCase {
public boolean leaveObjectParameterizedTypesRaw() {
return false;
}
public boolean exhaustive() {
return false;
}
});
final com.intellij.refactoring.typeCook.deductive.builder.System commonSystem = b.build(new PsiElement[]{aClass});
@@ -668,14 +672,14 @@ public class TypeCookTest extends MultiFileTestCase {
}
}
Binding[] bindings = null;
Binding binding = null;
if (system != null) {
final ResolverTree tree = new ResolverTree(system);
tree.resolve();
bindings = tree.getSolutions();
binding = tree.getBestSolution();
}
//System.out.println("" + system);
@@ -715,7 +719,7 @@ public class TypeCookTest extends MultiFileTestCase {
//d.analyze();
//d.relax();
itemRepr = system != null ? system.dumpResult(bindings) : commonSystem.dumpString(); //d.resultString();
itemRepr = system != null ? system.dumpResult(binding) : commonSystem.dumpString(); //d.resultString();
itemName = className + ".1.items";
patternName = PathManagerEx.getTestDataPath() + getTestRoot() + getTestName(true) + "/after/" + itemName;