1 11 package org.eclipse.jdt.internal.corext.refactoring.structure.constraints; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collection ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.LinkedList ; 19 import java.util.Map ; 20 21 import org.eclipse.core.runtime.Assert; 22 23 import org.eclipse.jdt.core.ICompilationUnit; 24 25 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType; 26 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.CastVariable2; 27 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ConstraintVariable2; 28 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeConstraint2; 29 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeConstraintVariable; 30 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ITypeSet; 31 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ImmutableTypeVariable2; 32 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TypeEquivalenceSet; 33 34 39 public class SuperTypeConstraintsSolver { 40 41 42 public static final String DATA_TYPE_ESTIMATE= "te"; 44 45 protected final SuperTypeConstraintsModel fModel; 46 47 48 protected Map fObsoleteCasts= null; 49 50 51 protected LinkedList fProcessable= null; 52 53 54 protected Map fTypeOccurrences= null; 55 56 61 public SuperTypeConstraintsSolver(final SuperTypeConstraintsModel model) { 62 Assert.isNotNull(model); 63 64 fModel= model; 65 } 66 67 73 private void computeConditionalTypeConstraints(final Collection constraints, final int level) { 74 ITypeConstraint2 constraint= null; 75 for (final Iterator iterator= constraints.iterator(); iterator.hasNext();) { 76 constraint= (ITypeConstraint2) iterator.next(); 77 if (constraint instanceof ConditionalTypeConstraint) { 78 final ConditionalTypeConstraint conditional= (ConditionalTypeConstraint) constraint; 79 fModel.createEqualityConstraint(constraint.getLeft(), constraint.getRight()); 80 fModel.createEqualityConstraint(conditional.getExpression(), constraint.getLeft()); 81 fModel.createEqualityConstraint(conditional.getExpression(), constraint.getRight()); 82 } 83 } 84 } 85 86 92 private void computeNonCovariantConstraints(final Collection constraints, final int level) { 93 if (level != 3) { 94 ITypeConstraint2 constraint= null; 95 for (final Iterator iterator= constraints.iterator(); iterator.hasNext();) { 96 constraint= (ITypeConstraint2) iterator.next(); 97 if (constraint instanceof CovariantTypeConstraint) 98 fModel.createEqualityConstraint(constraint.getLeft(), constraint.getRight()); 99 } 100 } 101 } 102 103 108 private void computeObsoleteCasts(final Collection variables) { 109 fObsoleteCasts= new HashMap (); 110 CastVariable2 variable= null; 111 for (final Iterator iterator= variables.iterator(); iterator.hasNext();) { 112 variable= (CastVariable2) iterator.next(); 113 final TType type= (TType) variable.getExpressionVariable().getData(DATA_TYPE_ESTIMATE); 114 if (type != null && type.canAssignTo(variable.getType())) { 115 final ICompilationUnit unit= variable.getCompilationUnit(); 116 Collection casts= (Collection ) fObsoleteCasts.get(unit); 117 if (casts != null) 118 casts.add(variable); 119 else { 120 casts= new ArrayList (1); 121 casts.add(variable); 122 fObsoleteCasts.put(unit, casts); 123 } 124 } 125 } 126 } 127 128 134 protected ITypeSet computeTypeEstimate(final ConstraintVariable2 variable) { 135 final TType type= variable.getType(); 136 if (variable instanceof ImmutableTypeVariable2 || !type.getErasure().equals(fModel.getSubType().getErasure())) 137 return SuperTypeSet.createTypeSet(type); 138 return SuperTypeSet.createTypeSet(type, fModel.getSuperType()); 139 } 140 141 146 private void computeTypeEstimates(final Collection variables) { 147 ConstraintVariable2 variable= null; 148 for (final Iterator iterator= variables.iterator(); iterator.hasNext();) { 149 variable= (ConstraintVariable2) iterator.next(); 150 TypeEquivalenceSet set= variable.getTypeEquivalenceSet(); 151 if (set == null) { 152 set= new TypeEquivalenceSet(variable); 153 set.setTypeEstimate(computeTypeEstimate(variable)); 154 variable.setTypeEquivalenceSet(set); 155 } else { 156 ITypeSet estimate= variable.getTypeEstimate(); 157 if (estimate == null) { 158 final ConstraintVariable2[] contributing= set.getContributingVariables(); 159 estimate= SuperTypeSet.getUniverse(); 160 for (int index= 0; index < contributing.length; index++) 161 estimate= estimate.restrictedTo(computeTypeEstimate(contributing[index])); 162 set.setTypeEstimate(estimate); 163 } 164 } 165 } 166 } 167 168 173 private void computeTypeOccurrences(final Collection variables) { 174 fTypeOccurrences= new HashMap (); 175 final TType superErasure= fModel.getSuperType().getErasure(); 176 TType estimatedType= null; 177 ITypeSet set= null; 178 ICompilationUnit unit= null; 179 ConstraintVariable2 variable= null; 180 ITypeConstraintVariable declaration= null; 181 TType variableType= null; 182 for (final Iterator iterator= variables.iterator(); iterator.hasNext();) { 183 variable= (ConstraintVariable2) iterator.next(); 184 if (variable instanceof ITypeConstraintVariable) { 185 declaration= (ITypeConstraintVariable) variable; 186 variableType= variable.getType(); 187 set= declaration.getTypeEstimate(); 188 if (set != null) { 189 estimatedType= set.chooseSingleType(); 190 if (estimatedType != null) { 191 final TType typeErasure= estimatedType.getErasure(); 192 if (!typeErasure.equals(variableType.getErasure()) && typeErasure.equals(superErasure)) { 193 declaration.setData(DATA_TYPE_ESTIMATE, estimatedType); 194 unit= declaration.getCompilationUnit(); 195 if (unit != null) { 196 Collection matches= (Collection ) fTypeOccurrences.get(unit); 197 if (matches != null) 198 matches.add(declaration); 199 else { 200 matches= new ArrayList (1); 201 matches.add(declaration); 202 fTypeOccurrences.put(unit, matches); 203 } 204 } 205 } 206 } 207 } 208 } 209 } 210 } 211 212 217 public final Map getObsoleteCasts() { 218 return fObsoleteCasts; 219 } 220 221 226 public final Map getTypeOccurrences() { 227 return fTypeOccurrences; 228 } 229 230 235 private void processConstraints(final Collection constraints) { 236 final int level= fModel.getCompliance(); 237 ITypeConstraint2 constraint= null; 238 for (final Iterator iterator= constraints.iterator(); iterator.hasNext();) { 239 constraint= (ITypeConstraint2) iterator.next(); 240 if ((level == 3 || !(constraint instanceof CovariantTypeConstraint)) && !(constraint instanceof ConditionalTypeConstraint)) { 241 final ConstraintVariable2 leftVariable= constraint.getLeft(); 242 final ITypeSet leftEstimate= leftVariable.getTypeEstimate(); 243 final TypeEquivalenceSet set= leftVariable.getTypeEquivalenceSet(); 244 final ITypeSet newEstimate= leftEstimate.restrictedTo(constraint.getRight().getTypeEstimate()); 245 if (leftEstimate != newEstimate) { 246 set.setTypeEstimate(newEstimate); 247 fProcessable.addAll(Arrays.asList(set.getContributingVariables())); 248 } 249 } 250 } 251 } 252 253 256 public final void solveConstraints() { 257 fProcessable= new LinkedList (); 258 final Collection variables= fModel.getConstraintVariables(); 259 final Collection constraints= fModel.getTypeConstraints(); 260 final int level= fModel.getCompliance(); 261 computeNonCovariantConstraints(constraints, level); 262 263 computeConditionalTypeConstraints(constraints, level); 265 266 computeTypeEstimates(variables); 267 fProcessable.addAll(variables); 268 Collection usage= null; 269 ConstraintVariable2 variable= null; 270 while (!fProcessable.isEmpty()) { 271 variable= (ConstraintVariable2) fProcessable.removeFirst(); 272 usage= SuperTypeConstraintsModel.getVariableUsage(variable); 273 if (!usage.isEmpty()) 274 processConstraints(usage); 275 else 276 variable.setData(DATA_TYPE_ESTIMATE, variable.getTypeEstimate().chooseSingleType()); 277 } 278 computeTypeOccurrences(variables); 279 computeObsoleteCasts(fModel.getCastVariables()); 280 } 281 } 282 | Popular Tags |