1 11 package org.eclipse.jdt.internal.corext.refactoring.typeconstraints; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collection ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.LinkedHashSet ; 19 import java.util.List ; 20 import java.util.Set ; 21 22 import org.eclipse.core.runtime.Assert; 23 24 import org.eclipse.jdt.core.dom.ArrayCreation; 25 import org.eclipse.jdt.core.dom.ArrayInitializer; 26 import org.eclipse.jdt.core.dom.Assignment; 27 import org.eclipse.jdt.core.dom.CastExpression; 28 import org.eclipse.jdt.core.dom.CatchClause; 29 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 30 import org.eclipse.jdt.core.dom.ConditionalExpression; 31 import org.eclipse.jdt.core.dom.ConstructorInvocation; 32 import org.eclipse.jdt.core.dom.Expression; 33 import org.eclipse.jdt.core.dom.FieldAccess; 34 import org.eclipse.jdt.core.dom.FieldDeclaration; 35 import org.eclipse.jdt.core.dom.IBinding; 36 import org.eclipse.jdt.core.dom.IMethodBinding; 37 import org.eclipse.jdt.core.dom.ITypeBinding; 38 import org.eclipse.jdt.core.dom.IVariableBinding; 39 import org.eclipse.jdt.core.dom.InstanceofExpression; 40 import org.eclipse.jdt.core.dom.MethodDeclaration; 41 import org.eclipse.jdt.core.dom.MethodInvocation; 42 import org.eclipse.jdt.core.dom.Name; 43 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 44 import org.eclipse.jdt.core.dom.QualifiedName; 45 import org.eclipse.jdt.core.dom.ReturnStatement; 46 import org.eclipse.jdt.core.dom.SimpleName; 47 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 48 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 49 import org.eclipse.jdt.core.dom.SuperFieldAccess; 50 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 51 import org.eclipse.jdt.core.dom.ThisExpression; 52 import org.eclipse.jdt.core.dom.Type; 53 import org.eclipse.jdt.core.dom.VariableDeclaration; 54 import org.eclipse.jdt.core.dom.VariableDeclarationExpression; 55 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 56 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 57 58 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 59 import org.eclipse.jdt.internal.corext.dom.Bindings; 60 import org.eclipse.jdt.internal.corext.refactoring.rename.MethodChecks; 61 62 66 public class FullConstraintCreator extends ConstraintCreator{ 67 68 private final IConstraintVariableFactory fConstraintVariableFactory; 69 private final ITypeConstraintFactory fTypeConstraintFactory; 70 private IContext fContext; 71 72 public FullConstraintCreator(){ 73 this(new ConstraintVariableFactory(), new TypeConstraintFactory()); 74 } 75 76 public FullConstraintCreator(IConstraintVariableFactory cFactory, 77 ITypeConstraintFactory tFactory) { 78 Assert.isTrue(cFactory != null); 79 fConstraintVariableFactory= cFactory; 80 fTypeConstraintFactory= tFactory; 81 fContext= new NullContext(); 82 } 83 84 public IContext getContext() { 85 return fContext; 86 } 87 88 public void setContext(IContext context) { 89 fContext= context; 90 } 91 92 public ITypeConstraintFactory getConstraintFactory(){ 93 return fTypeConstraintFactory; 94 } 95 96 public IConstraintVariableFactory getConstraintVariableFactory(){ 97 return fConstraintVariableFactory; 98 } 99 100 103 public ITypeConstraint[] create(ArrayInitializer arrayInitializer){ 104 ITypeBinding arrayBinding= arrayInitializer.resolveTypeBinding(); 105 Assert.isTrue(arrayBinding.isArray()); 106 List expressions= arrayInitializer.expressions(); 107 List constraints= new ArrayList (); 108 Type type= getTypeParent(arrayInitializer); 109 ConstraintVariable typeVariable= fConstraintVariableFactory.makeTypeVariable(type); 110 for (int i= 0; i < expressions.size(); i++) { 111 Expression each= (Expression) expressions.get(i); 112 ITypeConstraint[] c= fTypeConstraintFactory.createSubtypeConstraint( 113 fConstraintVariableFactory.makeExpressionOrTypeVariable(each, getContext()), 114 typeVariable); 115 constraints.addAll(Arrays.asList(c)); 116 } 117 return (ITypeConstraint[])constraints.toArray(new ITypeConstraint[constraints.size()]); 118 } 119 120 123 public ITypeConstraint[] create(Assignment assignment){ 124 return fTypeConstraintFactory.createSubtypeConstraint( 125 fConstraintVariableFactory.makeExpressionOrTypeVariable(assignment.getRightHandSide(), getContext()), 126 fConstraintVariableFactory.makeExpressionOrTypeVariable(assignment.getLeftHandSide(), getContext())); 127 } 128 129 132 public ITypeConstraint[] create(CastExpression castExpression){ 133 Expression expression= castExpression.getExpression(); 134 Type type= castExpression.getType(); 135 ITypeConstraint[] definesConstraint= fTypeConstraintFactory.createDefinesConstraint(fConstraintVariableFactory.makeExpressionOrTypeVariable(castExpression, getContext()), 136 fConstraintVariableFactory.makeTypeVariable(castExpression.getType())); 137 if (isClassBinding(expression.resolveTypeBinding()) && isClassBinding(type.resolveBinding())){ 138 ConstraintVariable expressionVariable= fConstraintVariableFactory.makeExpressionOrTypeVariable(expression, getContext()); 139 ConstraintVariable castExpressionVariable= fConstraintVariableFactory.makeExpressionOrTypeVariable(castExpression, getContext()); 140 ITypeConstraint[] c2 = createOrOrSubtypeConstraint(expressionVariable, castExpressionVariable); 141 if (definesConstraint.length == 0){ 142 return c2; 143 } else { 144 ITypeConstraint c1 = definesConstraint[0]; 145 Collection constraints= new ArrayList (); 146 constraints.add(c1); 147 constraints.addAll(Arrays.asList(c2)); 148 return (ITypeConstraint[])constraints.toArray(new ITypeConstraint[constraints.size()]); 149 } 150 } else 151 return definesConstraint; 152 } 153 154 public ITypeConstraint[] create(CatchClause node) { 155 SingleVariableDeclaration exception= node.getException(); 156 ConstraintVariable nameVariable= fConstraintVariableFactory.makeExpressionOrTypeVariable(exception.getName(), getContext()); 157 158 ITypeConstraint[] defines= fTypeConstraintFactory.createDefinesConstraint( 159 nameVariable, 160 fConstraintVariableFactory.makeTypeVariable(exception.getType())); 161 162 ITypeBinding throwable= node.getAST().resolveWellKnownType("java.lang.Throwable"); ITypeConstraint[] catchBound= fTypeConstraintFactory.createSubtypeConstraint( 164 nameVariable, 165 fConstraintVariableFactory.makeRawBindingVariable(throwable)); 166 167 ArrayList result= new ArrayList (); 168 result.addAll(Arrays.asList(defines)); 169 result.addAll(Arrays.asList(catchBound)); 170 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 171 } 172 173 174 177 public ITypeConstraint[] create(ClassInstanceCreation instanceCreation){ 178 List arguments= instanceCreation.arguments(); 179 List result= new ArrayList (arguments.size()); 180 IMethodBinding methodBinding= instanceCreation.resolveConstructorBinding(); 181 result.addAll(Arrays.asList(getArgumentConstraints(arguments, methodBinding))); 182 if (instanceCreation.getAnonymousClassDeclaration() == null){ 183 ConstraintVariable constructorVar= fConstraintVariableFactory.makeExpressionOrTypeVariable(instanceCreation, getContext()); 184 ConstraintVariable typeVar= fConstraintVariableFactory.makeRawBindingVariable(instanceCreation.resolveTypeBinding()); 185 result.addAll(Arrays.asList(fTypeConstraintFactory.createDefinesConstraint(constructorVar, typeVar))); 186 } 187 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 188 } 189 190 193 public ITypeConstraint[] create(ConstructorInvocation invocation){ 194 List arguments= invocation.arguments(); 195 List result= new ArrayList (arguments.size()); 196 IMethodBinding methodBinding= invocation.resolveConstructorBinding(); 197 result.addAll(Arrays.asList(getArgumentConstraints(arguments, methodBinding))); 198 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 199 } 200 201 204 public ITypeConstraint[] create(FieldAccess access){ 205 Expression expression= access.getExpression(); 206 SimpleName name= access.getName(); 207 IBinding binding= name.resolveBinding(); 208 if (! (binding instanceof IVariableBinding)) 209 return new ITypeConstraint[0]; 210 IVariableBinding vb= (IVariableBinding)binding; 211 return createConstraintsForAccessToField(vb, expression, access); 212 } 213 214 217 public ITypeConstraint[] create(FieldDeclaration fd){ 218 List result= new ArrayList (); 219 result.addAll(Arrays.asList(getConstraintsFromFragmentList(fd.fragments(), fd.getType()))); 220 result.addAll(getConstraintsForHiding(fd)); 221 result.addAll(getConstraintsForFieldDeclaringTypes(fd)); 222 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 223 } 224 225 228 public ITypeConstraint[] create(InstanceofExpression instanceofExpression){ 229 Expression expression= instanceofExpression.getLeftOperand(); 230 Type type= instanceofExpression.getRightOperand(); 231 if (isClassBinding(expression.resolveTypeBinding()) && isClassBinding(type.resolveBinding())) { 232 ConstraintVariable expressionVar= fConstraintVariableFactory.makeExpressionOrTypeVariable(expression, getContext()); 233 ConstraintVariable typeVariable= fConstraintVariableFactory.makeTypeVariable(type); 234 return createOrOrSubtypeConstraint(expressionVar, typeVariable); 235 } else 236 return new ITypeConstraint[0]; 237 } 238 239 242 public ITypeConstraint[] create(ConditionalExpression node) { 243 List result= new ArrayList (); 244 Expression thenExpression= node.getThenExpression(); 245 Expression elseExpression= node.getElseExpression(); 246 ConstraintVariable whole= fConstraintVariableFactory.makeExpressionOrTypeVariable(node, getContext()); 247 ConstraintVariable ev1= fConstraintVariableFactory.makeExpressionOrTypeVariable(thenExpression, getContext()); 248 ConstraintVariable ev2= fConstraintVariableFactory.makeExpressionOrTypeVariable(elseExpression, getContext()); 249 ITypeConstraint[] constraints1= fTypeConstraintFactory.createEqualsConstraint(ev1, ev2); 250 ITypeConstraint[] constraints2= fTypeConstraintFactory.createSubtypeConstraint(ev1, whole); 251 ITypeConstraint[] constraints3= fTypeConstraintFactory.createSubtypeConstraint(ev2, whole); 252 result.addAll(Arrays.asList(constraints1)); 253 result.addAll(Arrays.asList(constraints2)); 254 result.addAll(Arrays.asList(constraints3)); 255 return (ITypeConstraint[])result.toArray(new ITypeConstraint[result.size()]); 256 } 257 258 261 public ITypeConstraint[] create(MethodDeclaration declaration){ 262 List result= new ArrayList (); 263 IMethodBinding methodBinding= declaration.resolveBinding(); 264 if (methodBinding == null) 265 return new ITypeConstraint[0]; 266 ITypeConstraint[] constraints = fTypeConstraintFactory.createDefinesConstraint( 267 fConstraintVariableFactory.makeDeclaringTypeVariable(methodBinding), 268 fConstraintVariableFactory.makeRawBindingVariable(methodBinding.getDeclaringClass())); 269 result.addAll(Arrays.asList(constraints)); 270 if (! methodBinding.isConstructor() && ! methodBinding.getReturnType().isPrimitive()){ 271 ConstraintVariable returnTypeBindingVariable= fConstraintVariableFactory.makeReturnTypeVariable(methodBinding); 272 ConstraintVariable returnTypeVariable= fConstraintVariableFactory.makeTypeVariable(declaration.getReturnType2()); 273 ITypeConstraint[] defines= fTypeConstraintFactory.createDefinesConstraint( 274 returnTypeBindingVariable, returnTypeVariable); 275 result.addAll(Arrays.asList(defines)); 276 } 277 for (int i= 0, n= declaration.parameters().size(); i < n; i++) { 278 SingleVariableDeclaration paramDecl= (SingleVariableDeclaration)declaration.parameters().get(i); 279 ConstraintVariable parameterTypeVariable= fConstraintVariableFactory.makeParameterTypeVariable(methodBinding, i); 280 ConstraintVariable parameterNameVariable= fConstraintVariableFactory.makeExpressionOrTypeVariable(paramDecl.getName(), getContext()); 281 ITypeConstraint[] constraint= fTypeConstraintFactory.createDefinesConstraint( 282 parameterTypeVariable, parameterNameVariable); 283 result.addAll(Arrays.asList(constraint)); 284 } 285 if (MethodChecks.isVirtual(methodBinding)){ 286 Collection constraintsForOverriding = getConstraintsForOverriding(methodBinding); 287 result.addAll(constraintsForOverriding); 288 } 289 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 290 } 291 292 295 public ITypeConstraint[] create(ParenthesizedExpression node) { 296 ConstraintVariable v1= fConstraintVariableFactory.makeExpressionOrTypeVariable(node, getContext()); 297 ConstraintVariable v2= fConstraintVariableFactory.makeExpressionOrTypeVariable(node.getExpression(), getContext()); 298 ITypeConstraint[] equal= fTypeConstraintFactory.createEqualsConstraint(v1, v2); 299 return equal; 300 } 301 302 305 public ITypeConstraint[] create(MethodInvocation invocation){ 306 List arguments= invocation.arguments(); 307 List result= new ArrayList (arguments.size()); 308 IMethodBinding methodBinding= invocation.resolveMethodBinding(); 309 if (methodBinding == null) 310 return new ITypeConstraint[0]; 311 ITypeConstraint[] returnTypeConstraint= getReturnTypeConstraint(invocation, methodBinding); 312 result.addAll(Arrays.asList(returnTypeConstraint)); 313 result.addAll(Arrays.asList(getArgumentConstraints(arguments, methodBinding))); 314 if (invocation.getExpression() != null){ 315 if(MethodChecks.isVirtual(methodBinding)){ 316 IMethodBinding[] rootDefs= getRootDefs(methodBinding); 317 Assert.isTrue(rootDefs.length > 0); 318 ConstraintVariable expressionVar= fConstraintVariableFactory.makeExpressionOrTypeVariable(invocation.getExpression(), getContext()); 319 if (rootDefs.length == 1){ 320 result.addAll(Arrays.asList(fTypeConstraintFactory.createSubtypeConstraint(expressionVar, fConstraintVariableFactory.makeDeclaringTypeVariable(rootDefs[0])))); 321 }else{ 322 Collection constraints= new ArrayList (); 323 for (int i= 0; i < rootDefs.length; i++) { 324 ConstraintVariable rootDefTypeVar= fConstraintVariableFactory.makeDeclaringTypeVariable(rootDefs[i]); 325 ITypeConstraint[] tc= fTypeConstraintFactory.createSubtypeConstraint(expressionVar, rootDefTypeVar); 326 constraints.addAll(Arrays.asList(tc)); 327 } 328 ITypeConstraint[] constraintsArray= (ITypeConstraint[])constraints.toArray(new ITypeConstraint[constraints.size()]); 329 if (constraintsArray.length > 0){ 330 result.add(fTypeConstraintFactory.createCompositeOrTypeConstraint(constraintsArray)); 331 } 332 } 333 } else { 334 ConstraintVariable typeVar= fConstraintVariableFactory.makeDeclaringTypeVariable(methodBinding); 335 ConstraintVariable expressionVar= fConstraintVariableFactory.makeExpressionOrTypeVariable(invocation.getExpression(), getContext()); 336 result.addAll(Arrays.asList(fTypeConstraintFactory.createSubtypeConstraint(expressionVar, typeVar))); 337 } 338 } 339 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 340 } 341 342 345 public ITypeConstraint[] create(QualifiedName qualifiedName){ 346 SimpleName name= qualifiedName.getName(); 347 Name qualifier= qualifiedName.getQualifier(); 348 IBinding nameBinding= name.resolveBinding(); 349 if (nameBinding instanceof IVariableBinding){ 350 IVariableBinding vb= (IVariableBinding)nameBinding; 351 if (vb.isField()) 352 return createConstraintsForAccessToField(vb, qualifier, qualifiedName); 353 } return new ITypeConstraint[0]; 355 } 356 357 360 public ITypeConstraint[] create(ReturnStatement returnStatement){ 361 if (returnStatement.getExpression() == null) 362 return new ITypeConstraint[0]; 363 364 ConstraintVariable returnTypeVariable= fConstraintVariableFactory.makeReturnTypeVariable(returnStatement); 365 return fTypeConstraintFactory.createSubtypeConstraint( 366 fConstraintVariableFactory.makeExpressionOrTypeVariable(returnStatement.getExpression(), getContext()), 367 returnTypeVariable); 368 } 369 370 373 public ITypeConstraint[] create(SingleVariableDeclaration svd){ 374 ITypeConstraint[] defines= fTypeConstraintFactory.createDefinesConstraint( 375 fConstraintVariableFactory.makeExpressionOrTypeVariable(svd.getName(), getContext()), 376 fConstraintVariableFactory.makeTypeVariable(svd.getType())); 377 if (svd.getInitializer() == null) 378 return defines; 379 ITypeConstraint[] constraints = fTypeConstraintFactory.createSubtypeConstraint( 380 fConstraintVariableFactory.makeExpressionOrTypeVariable(svd.getInitializer(), getContext()), 381 fConstraintVariableFactory.makeExpressionOrTypeVariable(svd.getName(), getContext())); 382 if (defines.length == 0 && constraints.length == 0){ 383 return new ITypeConstraint[0]; 384 } else if (defines.length == 0){ 385 return constraints; 386 } else if (constraints.length == 0){ 387 return defines; 388 } else { 389 List all= new ArrayList (); 390 all.addAll(Arrays.asList(defines)); 391 all.addAll(Arrays.asList(constraints)); 392 return (ITypeConstraint[])all.toArray(); 393 } 394 } 395 396 399 public ITypeConstraint[] create(SuperConstructorInvocation invocation){ 400 List arguments= invocation.arguments(); 401 List result= new ArrayList (arguments.size()); 402 IMethodBinding methodBinding= invocation.resolveConstructorBinding(); 403 result.addAll(Arrays.asList(getArgumentConstraints(arguments, methodBinding))); 404 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 405 } 406 407 410 public ITypeConstraint[] create(SuperFieldAccess access){ 411 SimpleName name= access.getName(); 412 IBinding binding= name.resolveBinding(); 413 if (! (binding instanceof IVariableBinding)) 414 return new ITypeConstraint[0]; 415 IVariableBinding vb= (IVariableBinding)binding; 416 return createConstraintsForAccessToField(vb, null, access); 417 } 418 419 422 public ITypeConstraint[] create(SuperMethodInvocation invocation){ 423 List arguments= invocation.arguments(); 424 List result= new ArrayList (arguments.size()); 425 IMethodBinding methodBinding= invocation.resolveMethodBinding(); 426 ITypeConstraint[] returnTypeConstraint= getReturnTypeConstraint(invocation, methodBinding); 427 result.addAll(Arrays.asList(returnTypeConstraint)); 428 result.addAll(Arrays.asList(getArgumentConstraints(arguments, methodBinding))); 429 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 430 } 431 432 435 public ITypeConstraint[] create(ThisExpression expression){ 436 ConstraintVariable thisExpression= fConstraintVariableFactory.makeExpressionOrTypeVariable(expression, getContext()); 437 ConstraintVariable declaringType= fConstraintVariableFactory.makeRawBindingVariable(expression.resolveTypeBinding()); return fTypeConstraintFactory.createDefinesConstraint(thisExpression, declaringType); 439 } 440 441 444 public ITypeConstraint[] create(VariableDeclarationExpression vde){ 445 return getConstraintsFromFragmentList(vde.fragments(), vde.getType()); 446 } 447 448 451 public ITypeConstraint[] create(VariableDeclarationFragment vdf){ 452 if (vdf.getInitializer() == null) 453 return new ITypeConstraint[0]; 454 return fTypeConstraintFactory.createSubtypeConstraint( 455 fConstraintVariableFactory.makeExpressionOrTypeVariable(vdf.getInitializer(), getContext()), 456 fConstraintVariableFactory.makeExpressionOrTypeVariable(vdf.getName(), getContext())); 457 } 458 459 462 public ITypeConstraint[] create(VariableDeclarationStatement vds){ 463 return getConstraintsFromFragmentList(vds.fragments(), vds.getType()); 464 } 465 466 467 469 private Collection getConstraintsForFieldDeclaringTypes(FieldDeclaration fd) { 470 Collection result= new ArrayList (fd.fragments().size()); 471 for (Iterator iter= fd.fragments().iterator(); iter.hasNext();) { 472 VariableDeclarationFragment varDecl= (VariableDeclarationFragment) iter.next(); 473 IVariableBinding binding= varDecl.resolveBinding(); 474 Assert.isTrue(binding.isField()); 475 result.addAll(Arrays.asList(fTypeConstraintFactory.createDefinesConstraint( 476 fConstraintVariableFactory.makeDeclaringTypeVariable(binding), 477 fConstraintVariableFactory.makeRawBindingVariable(binding.getDeclaringClass())))); 478 } 479 return result; 480 } 481 482 private Collection getConstraintsForHiding(FieldDeclaration fd) { 483 Collection result= new ArrayList (); 484 for (Iterator iter= fd.fragments().iterator(); iter.hasNext();) { 485 result.addAll(getConstraintsForHiding((VariableDeclarationFragment) iter.next())); 486 } 487 return result; 488 } 489 490 private Collection getConstraintsForHiding(VariableDeclarationFragment fragment) { 491 Collection result= new ArrayList (); 492 IVariableBinding fieldBinding= fragment.resolveBinding(); 493 Assert.isTrue(fieldBinding.isField()); 494 Set declaringTypes= getDeclaringSuperTypes(fieldBinding); 495 ConstraintVariable hiddingFieldVar= fConstraintVariableFactory.makeDeclaringTypeVariable(fieldBinding); 496 for (Iterator iter= declaringTypes.iterator(); iter.hasNext();) { 497 ITypeBinding declaringSuperType= (ITypeBinding) iter.next(); 498 IVariableBinding hiddenField= findField(fieldBinding, declaringSuperType); 499 Assert.isTrue(hiddenField.isField()); 500 ConstraintVariable hiddenFieldVar= fConstraintVariableFactory.makeDeclaringTypeVariable(hiddenField); 501 result.addAll(Arrays.asList(fTypeConstraintFactory.createStrictSubtypeConstraint(hiddingFieldVar, hiddenFieldVar))); 502 } 503 return result; 504 } 505 506 private ITypeConstraint[] getConstraintsFromFragmentList(List fragments, Type type) { 507 int size= fragments.size(); 508 ConstraintVariable typeVariable= fConstraintVariableFactory.makeTypeVariable(type); 509 List result= new ArrayList ((size * (size - 1))/2); 510 for (int i= 0; i < size; i++) { 511 VariableDeclarationFragment fragment1= (VariableDeclarationFragment) fragments.get(i); 512 SimpleName fragment1Name= fragment1.getName(); 513 result.addAll(Arrays.asList(fTypeConstraintFactory.createDefinesConstraint( 514 fConstraintVariableFactory.makeExpressionOrTypeVariable(fragment1Name, getContext()), 515 typeVariable))); 516 for (int j= i + 1; j < size; j++) { 517 VariableDeclarationFragment fragment2= (VariableDeclarationFragment) fragments.get(j); 518 result.addAll(Arrays.asList(fTypeConstraintFactory.createEqualsConstraint( 519 fConstraintVariableFactory.makeExpressionOrTypeVariable(fragment1Name, getContext()), 520 fConstraintVariableFactory.makeExpressionOrTypeVariable(fragment2.getName(), getContext())))); 521 } 522 } 523 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 524 } 525 526 private Collection getConstraintsForOverriding(IMethodBinding overriddingMethod) { 527 Collection result= new ArrayList (); 528 Set declaringSupertypes= getDeclaringSuperTypes(overriddingMethod); 529 for (Iterator iter= declaringSupertypes.iterator(); iter.hasNext();) { 530 ITypeBinding superType= (ITypeBinding) iter.next(); 531 IMethodBinding overriddenMethod= findMethod(overriddingMethod, superType); 532 Assert.isNotNull(overriddenMethod); if (Bindings.equals(overriddingMethod, overriddenMethod)) continue; 534 ITypeConstraint[] returnTypeConstraint= fTypeConstraintFactory.createEqualsConstraint( 535 fConstraintVariableFactory.makeReturnTypeVariable(overriddenMethod), 536 fConstraintVariableFactory.makeReturnTypeVariable(overriddingMethod)); 537 result.addAll(Arrays.asList(returnTypeConstraint)); 538 Assert.isTrue(overriddenMethod.getParameterTypes().length == overriddingMethod.getParameterTypes().length); 539 for (int i= 0, n= overriddenMethod.getParameterTypes().length; i < n; i++) { 540 ITypeConstraint[] parameterTypeConstraint= fTypeConstraintFactory.createEqualsConstraint( 541 fConstraintVariableFactory.makeParameterTypeVariable(overriddenMethod, i), 542 fConstraintVariableFactory.makeParameterTypeVariable(overriddingMethod, i)); 543 result.addAll(Arrays.asList(parameterTypeConstraint)); 544 } 545 ITypeConstraint[] declaringTypeConstraint= fTypeConstraintFactory.createStrictSubtypeConstraint( 546 fConstraintVariableFactory.makeDeclaringTypeVariable(overriddingMethod), 547 fConstraintVariableFactory.makeDeclaringTypeVariable(overriddenMethod)); 548 result.addAll(Arrays.asList(declaringTypeConstraint)); 549 } 550 return result; 551 } 552 553 private ITypeConstraint[] getReturnTypeConstraint(Expression invocation, IMethodBinding methodBinding){ 554 if (methodBinding == null || methodBinding.isConstructor() || methodBinding.getReturnType().isPrimitive()) 555 return new ITypeConstraint[0]; 556 ConstraintVariable returnTypeVariable= fConstraintVariableFactory.makeReturnTypeVariable(methodBinding); 557 ConstraintVariable invocationVariable= fConstraintVariableFactory.makeExpressionOrTypeVariable(invocation, getContext()); 558 return fTypeConstraintFactory.createDefinesConstraint(invocationVariable, returnTypeVariable); 559 } 560 561 private ITypeConstraint[] getArgumentConstraints(List arguments, IMethodBinding methodBinding){ 562 List result= new ArrayList (arguments.size()); 563 for (int i= 0, n= arguments.size(); i < n; i++) { 564 Expression argument= (Expression) arguments.get(i); 565 ConstraintVariable expressionVariable= fConstraintVariableFactory.makeExpressionOrTypeVariable(argument, getContext()); 566 ConstraintVariable parameterTypeVariable= fConstraintVariableFactory.makeParameterTypeVariable(methodBinding, i); 567 ITypeConstraint[] argConstraint= fTypeConstraintFactory.createSubtypeConstraint(expressionVariable, parameterTypeVariable); 568 result.addAll(Arrays.asList(argConstraint)); 569 } 570 return (ITypeConstraint[]) result.toArray(new ITypeConstraint[result.size()]); 571 } 572 573 private static Type getTypeParent(ArrayInitializer arrayInitializer) { 574 if (arrayInitializer.getParent() instanceof ArrayCreation){ 575 return ((ArrayCreation)arrayInitializer.getParent()).getType().getElementType(); 576 } else if (arrayInitializer.getParent() instanceof ArrayInitializer){ 577 return getTypeParent((ArrayInitializer) arrayInitializer.getParent()); 578 } else if (arrayInitializer.getParent() instanceof VariableDeclaration){ 579 VariableDeclaration parent= (VariableDeclaration)arrayInitializer.getParent(); 580 581 if (parent.getParent() instanceof VariableDeclarationStatement){ 582 Type type= ((VariableDeclarationStatement)parent.getParent()).getType(); 583 return ASTNodes.getElementType(type); 584 } else if (parent.getParent() instanceof VariableDeclarationExpression){ 585 Type type= ((VariableDeclarationExpression)parent.getParent()).getType(); 586 return ASTNodes.getElementType(type); 587 } else if (parent.getParent() instanceof FieldDeclaration){ 588 Type type= ((FieldDeclaration)parent.getParent()).getType(); 589 return ASTNodes.getElementType(type); 590 } 591 } 592 Assert.isTrue(false); return null; 594 } 595 596 private ITypeConstraint[] createOrOrSubtypeConstraint(ConstraintVariable var1, ConstraintVariable var2){ 597 ITypeConstraint[] c1= fTypeConstraintFactory.createSubtypeConstraint(var1, var2); 598 ITypeConstraint[] c2= fTypeConstraintFactory.createSubtypeConstraint(var2, var1); 599 if (c1.length == 0 && c2.length == 0){ 600 return new ITypeConstraint[0]; 601 } 602 return new ITypeConstraint[]{ fTypeConstraintFactory.createCompositeOrTypeConstraint(new ITypeConstraint[]{c1[0], c2[0]}) }; 603 } 604 605 private ITypeConstraint[] createConstraintsForAccessToField(IVariableBinding fieldBinding, Expression qualifier, Expression accessExpression){ 606 Assert.isTrue(fieldBinding.isField()); 607 ITypeConstraint[] defines= fTypeConstraintFactory.createDefinesConstraint( 608 fConstraintVariableFactory.makeExpressionOrTypeVariable(accessExpression, getContext()), 609 fConstraintVariableFactory.makeRawBindingVariable(fieldBinding.getType())); 610 if (qualifier == null) 611 return defines; 612 ITypeConstraint[] subType= fTypeConstraintFactory.createSubtypeConstraint( 613 fConstraintVariableFactory.makeExpressionOrTypeVariable(qualifier, getContext()), 614 fConstraintVariableFactory.makeDeclaringTypeVariable(fieldBinding)); 615 616 if (defines.length == 0){ 617 return subType; 618 } else if (subType.length == 0){ 619 return defines; 620 } else { 621 return new ITypeConstraint[]{defines[0], subType[0]}; 622 } 623 } 624 625 private static IVariableBinding findField(IVariableBinding fieldBinding, ITypeBinding type) { 626 if (fieldBinding.getDeclaringClass().equals(type)) 627 return fieldBinding; 628 return Bindings.findFieldInType(type, fieldBinding.getName()); 629 } 630 631 634 private static Set getDeclaringSuperTypes(IVariableBinding fieldBinding) { 635 ITypeBinding[] allSuperTypes= Bindings.getAllSuperTypes(fieldBinding.getDeclaringClass()); 636 Set result= new HashSet (); 637 for (int i= 0; i < allSuperTypes.length; i++) { 638 ITypeBinding type= allSuperTypes[i]; 639 if (findField(fieldBinding, type) != null) 640 result.add(type); 641 } 642 return result; 643 } 644 645 protected static IMethodBinding[] getRootDefs(IMethodBinding methodBinding) { 647 Set declaringSuperTypes= getDeclaringSuperTypes(methodBinding); 648 Set result= new LinkedHashSet (); 649 for (Iterator iter= declaringSuperTypes.iterator(); iter.hasNext();) { 650 ITypeBinding type= (ITypeBinding) iter.next(); 651 if (! containsASuperType(type, declaringSuperTypes)) 652 result.add(findMethod(methodBinding, type)); 653 } 654 655 if (result.size() == 0){ 656 result.add(methodBinding); 657 } 658 return (IMethodBinding[]) result.toArray(new IMethodBinding[result.size()]); 659 } 660 661 666 private static boolean containsASuperType(ITypeBinding type, Set declaringSuperTypes) { 667 for (Iterator iter= declaringSuperTypes.iterator(); iter.hasNext();) { 668 ITypeBinding maybeSuperType= (ITypeBinding) iter.next(); 669 if (! Bindings.equals(maybeSuperType, type) && Bindings.isSuperType(maybeSuperType, type)) 670 return true; 671 } 672 return false; 673 } 674 675 678 protected static Set getDeclaringSuperTypes(IMethodBinding methodBinding) { 679 ITypeBinding superClass = methodBinding.getDeclaringClass(); 680 Set allSuperTypes= new LinkedHashSet (); 681 allSuperTypes.addAll(Arrays.asList(Bindings.getAllSuperTypes(superClass))); 682 if (allSuperTypes.isEmpty()) 683 allSuperTypes.add(methodBinding.getDeclaringClass()); Set result= new HashSet (); 685 for (Iterator iter= allSuperTypes.iterator(); iter.hasNext();) { 686 ITypeBinding type= (ITypeBinding) iter.next(); 687 if (findMethod(methodBinding, type) != null) 688 result.add(type); 689 } 690 return result; 691 } 692 693 protected static IMethodBinding findMethod(IMethodBinding methodBinding, ITypeBinding type) { 694 if (methodBinding.getDeclaringClass().equals(type)) 695 return methodBinding; 696 return Bindings.findOverriddenMethodInType(type, methodBinding); 697 } 698 699 private static boolean isClassBinding(ITypeBinding typeBinding){ 700 return typeBinding != null && typeBinding.isClass(); 701 } 702 703 } 704 | Popular Tags |