1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import org.eclipse.jdt.internal.compiler.ast.TypeParameter; 14 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; 15 import org.eclipse.jdt.internal.compiler.util.SimpleSet; 16 17 class MethodVerifier15 extends MethodVerifier { 18 19 MethodVerifier15(LookupEnvironment environment) { 20 super(environment); 21 } 22 boolean areMethodsCompatible(MethodBinding one, MethodBinding two) { 23 MethodBinding sub = computeSubstituteMethod(two, one); 24 return sub != null && doesSubstituteMethodOverride(one, sub) && areReturnTypesCompatible(one, sub); 25 } 26 boolean areParametersEqual(MethodBinding one, MethodBinding two) { 27 TypeBinding[] oneArgs = one.parameters; 28 TypeBinding[] twoArgs = two.parameters; 29 if (oneArgs == twoArgs) return true; 30 31 int length = oneArgs.length; 32 if (length != twoArgs.length) return false; 33 34 if (one.declaringClass.isInterface()) { 35 for (int i = 0; i < length; i++) 36 if (!areTypesEqual(oneArgs[i], twoArgs[i])) 37 return false; 38 } else { 39 int i; 42 foundRAW: for (i = 0; i < length; i++) { 43 if (!areTypesEqual(oneArgs[i], twoArgs[i])) { 44 if (oneArgs[i].leafComponentType().isRawType()) { 45 if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType())) { 46 for (int j = 0; j < i; j++) 49 if (oneArgs[j].leafComponentType().isParameterizedType()) 50 return false; 51 break foundRAW; 53 } 54 } 55 return false; 56 } 57 } 58 for (i++; i < length; i++) { 60 if (!areTypesEqual(oneArgs[i], twoArgs[i])) { 61 if (oneArgs[i].leafComponentType().isRawType()) 62 if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType())) 63 continue; 64 return false; 65 } else if (oneArgs[i].leafComponentType().isParameterizedType()) { 66 return false; } 68 } 69 } 70 return true; 71 } 72 boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) { 73 if (one.returnType == two.returnType) return true; 74 return areReturnTypesCompatible0(one, two); 75 } 76 boolean areTypesEqual(TypeBinding one, TypeBinding two) { 77 if (one == two) return true; 78 79 if (one.isParameterizedType() && two.isParameterizedType()) 81 return one.isEquivalentTo(two) && two.isEquivalentTo(one); 82 83 return false; } 90 boolean canSkipInheritedMethods() { 91 if (this.type.superclass() != null) 92 if (this.type.superclass().isAbstract() || this.type.superclass().isParameterizedType()) 93 return false; 94 return this.type.superInterfaces() == Binding.NO_SUPERINTERFACES; 95 } 96 boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) { 97 return two == null || (one.declaringClass == two.declaringClass && !one.declaringClass.isParameterizedType()); 99 } 100 void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) { 101 super.checkConcreteInheritedMethod(concreteMethod, abstractMethods); 102 103 for (int i = 0, l = abstractMethods.length; i < l; i++) { 104 MethodBinding abstractMethod = abstractMethods[i]; 105 if (concreteMethod.isVarargs() != abstractMethod.isVarargs()) 106 problemReporter().varargsConflict(concreteMethod, abstractMethod, this.type); 107 108 MethodBinding originalInherited = abstractMethod.original(); 110 if (originalInherited.returnType != concreteMethod.returnType) { 111 if (abstractMethod.returnType.leafComponentType().isParameterizedType()) { 112 if (concreteMethod.returnType.leafComponentType().isRawType()) 113 problemReporter().unsafeReturnTypeOverride(concreteMethod, originalInherited, this.type); 114 } else if (abstractMethod.hasSubstitutedReturnType() && originalInherited.returnType.leafComponentType().isTypeVariable()) { 115 if (((TypeVariableBinding) originalInherited.returnType.leafComponentType()).declaringElement == originalInherited) { TypeBinding currentReturnType = concreteMethod.returnType.leafComponentType(); 117 if (!currentReturnType.isTypeVariable() || ((TypeVariableBinding) currentReturnType).declaringElement != concreteMethod) 118 problemReporter().unsafeReturnTypeOverride(concreteMethod, originalInherited, this.type); 119 } 120 } 121 } 122 if (originalInherited.declaringClass.isInterface() 124 && this.type.superclass.erasure().findSuperTypeWithSameErasure(originalInherited.declaringClass) == null) { 125 this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original()); 126 } 127 } 128 } 129 void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods) { 130 if (currentMethod.isVarargs() != inheritedMethod.isVarargs()) 131 problemReporter(currentMethod).varargsConflict(currentMethod, inheritedMethod, this.type); 132 133 MethodBinding originalInherited = inheritedMethod.original(); 135 if (originalInherited.returnType != currentMethod.returnType) { 136 if (inheritedMethod.returnType.leafComponentType().isParameterizedType() && currentMethod.returnType.leafComponentType().isRawType()) { 139 problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type); 140 } else if (inheritedMethod.hasSubstitutedReturnType() && originalInherited.returnType.leafComponentType().isTypeVariable()) { 141 if (((TypeVariableBinding) originalInherited.returnType.leafComponentType()).declaringElement == originalInherited) { TypeBinding currentReturnType = currentMethod.returnType.leafComponentType(); 143 if (!currentReturnType.isTypeVariable() || ((TypeVariableBinding) currentReturnType).declaringElement != currentMethod) 144 problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type); 145 } 146 } 147 } 148 149 if (this.type.addSyntheticBridgeMethod(originalInherited, currentMethod.original()) != null) { 150 for (int i = 0, l = allInheritedMethods.length; i < l; i++) { 151 MethodBinding otherInheritedMethod = allInheritedMethods[i]; 152 MethodBinding otherOriginal = otherInheritedMethod.original(); 153 if (otherOriginal == originalInherited || otherOriginal == otherInheritedMethod) continue; 155 if (inheritedMethod.areParametersEqual(otherInheritedMethod)) continue; 156 if (otherInheritedMethod.declaringClass.erasure() != inheritedMethod.declaringClass.erasure()) 158 if (otherInheritedMethod.declaringClass.findSuperTypeWithSameErasure(inheritedMethod.declaringClass) != null) 159 continue; 160 if (detectInheritedNameClash(originalInherited, otherOriginal)) 161 return; 162 } 163 } 164 } 165 void checkForNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) { 166 168 176 182 189 193 198 if (currentMethod.declaringClass.isInterface() || currentMethod.isStatic()) return; 199 200 if (!detectNameClash(currentMethod, inheritedMethod)) { TypeBinding[] currentParams = currentMethod.parameters; 202 TypeBinding[] inheritedParams = inheritedMethod.parameters; 203 int length = currentParams.length; 204 if (length != inheritedParams.length) return; 206 for (int i = 0; i < length; i++) 207 if (currentParams[i] != inheritedParams[i]) 208 if (currentParams[i].isBaseType() != inheritedParams[i].isBaseType() || !inheritedParams[i].isCompatibleWith(currentParams[i])) 209 return; 211 ReferenceBinding[] interfacesToVisit = null; 212 int nextPosition = 0; 213 ReferenceBinding superType = inheritedMethod.declaringClass; 214 ReferenceBinding[] itsInterfaces = superType.superInterfaces(); 215 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 216 nextPosition = itsInterfaces.length; 217 interfacesToVisit = itsInterfaces; 218 } 219 superType = superType.superclass(); while (superType != null && superType.isValidBinding()) { 221 MethodBinding[] methods = superType.getMethods(currentMethod.selector); 222 for (int m = 0, n = methods.length; m < n; m++) { 223 MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); 224 if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) 225 return; 226 } 227 if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 228 if (interfacesToVisit == null) { 229 interfacesToVisit = itsInterfaces; 230 nextPosition = interfacesToVisit.length; 231 } else { 232 int itsLength = itsInterfaces.length; 233 if (nextPosition + itsLength >= interfacesToVisit.length) 234 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 235 nextInterface : for (int a = 0; a < itsLength; a++) { 236 ReferenceBinding next = itsInterfaces[a]; 237 for (int b = 0; b < nextPosition; b++) 238 if (next == interfacesToVisit[b]) continue nextInterface; 239 interfacesToVisit[nextPosition++] = next; 240 } 241 } 242 } 243 superType = superType.superclass(); 244 } 245 246 for (int i = 0; i < nextPosition; i++) { 247 superType = interfacesToVisit[i]; 248 if (superType.isValidBinding()) { 249 MethodBinding[] methods = superType.getMethods(currentMethod.selector); 250 for (int m = 0, n = methods.length; m < n; m++){ 251 MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); 252 if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) 253 return; 254 } 255 if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 256 int itsLength = itsInterfaces.length; 257 if (nextPosition + itsLength >= interfacesToVisit.length) 258 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 259 nextInterface : for (int a = 0; a < itsLength; a++) { 260 ReferenceBinding next = itsInterfaces[a]; 261 for (int b = 0; b < nextPosition; b++) 262 if (next == interfacesToVisit[b]) continue nextInterface; 263 interfacesToVisit[nextPosition++] = next; 264 } 265 } 266 } 267 } 268 } 269 } 270 void checkInheritedMethods(MethodBinding inheritedMethod, MethodBinding otherInheritedMethod) { 271 if (inheritedMethod.declaringClass.erasure() == otherInheritedMethod.declaringClass.erasure()) { 273 if (inheritedMethod.areParameterErasuresEqual(otherInheritedMethod)) { 274 problemReporter().duplicateInheritedMethods(this.type, inheritedMethod, otherInheritedMethod); 275 return; 276 } 277 } else if (inheritedMethod.declaringClass.findSuperTypeWithSameErasure(otherInheritedMethod.declaringClass) != null) { 278 return; 280 } 281 282 292 if (inheritedMethod.declaringClass.isInterface() || inheritedMethod.isStatic()) return; 293 294 detectInheritedNameClash(inheritedMethod.original(), otherInheritedMethod.original()); 295 } 296 void checkInheritedMethods(MethodBinding[] methods, int length) { 297 int count = length; 298 int[] skip = new int[count]; 299 nextMethod : for (int i = 0, l = length - 1; i < l; i++) { 300 if (skip[i] == -1) continue nextMethod; 301 MethodBinding method = methods[i]; 302 MethodBinding[] duplicates = null; 303 for (int j = i + 1; j <= l; j++) { 304 MethodBinding method2 = methods[j]; 305 if (method.declaringClass == method2.declaringClass && areMethodsCompatible(method, method2)) { 306 skip[j] = -1; 307 if (duplicates == null) 308 duplicates = new MethodBinding[length]; 309 duplicates[j] = method2; 310 } 311 } 312 if (duplicates != null) { 313 int concreteCount = method.isAbstract() ? 0 : 1; 317 MethodBinding methodToKeep = method; for (int m = 0, s = duplicates.length; m < s; m++) { 319 if (duplicates[m] != null) { 320 if (!duplicates[m].isAbstract()) { 321 methodToKeep = duplicates[m]; 322 concreteCount++; 323 } 324 } 325 } 326 if (concreteCount != 1) { 327 for (int m = 0, s = duplicates.length; m < s; m++) { 328 if (duplicates[m] != null) { 329 problemReporter().duplicateInheritedMethods(this.type, method, duplicates[m]); 330 count--; 331 if (methodToKeep == duplicates[m]) 332 methods[i] = null; 333 else 334 methods[m] = null; 335 } 336 } 337 } 338 } 339 } 340 if (count < length) { 341 if (count == 1) return; MethodBinding[] newMethods = new MethodBinding[count]; 343 for (int i = length; --i >= 0;) 344 if (methods[i] != null) 345 newMethods[--count] = methods[i]; 346 methods = newMethods; 347 length = newMethods.length; 348 } 349 350 super.checkInheritedMethods(methods, length); 351 } 352 boolean checkInheritedReturnTypes(MethodBinding[] methods, int length) { 353 int[] areIncompatible = null; 356 for (int i = 0, l = this.type.isAbstract() ? length - 2 : 0; i <= l;) { 358 MethodBinding method = methods[i++]; 359 nextMethod : for (int j = i; j < length; j++) { 360 if (!areReturnTypesCompatible(method, methods[j])) { 361 if (this.type.isInterface()) 362 for (int m = length; --m >= 0;) 363 if (methods[m].declaringClass.id == TypeIds.T_JavaLangObject) 364 continue nextMethod; if (isUnsafeReturnTypeOverride(method, methods[j])) { 367 problemReporter(method).unsafeReturnTypeOverride(method, methods[j], this.type); 368 continue nextMethod; 369 } 370 if (areIncompatible == null) 371 areIncompatible = new int[length]; 372 areIncompatible[i - 1] = -1; 373 areIncompatible[j] = -1; 374 } 375 } 376 } 377 if (areIncompatible == null) 378 return true; 379 380 int count = 0; 381 for (int i = 0; i < length; i++) 382 if (areIncompatible[i] == -1) count++; 383 if (count == length) { 384 problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length); 385 return false; 386 } 387 MethodBinding[] methodsToReport = new MethodBinding[count]; 388 for (int i = 0, index = 0; i < length; i++) 389 if (areIncompatible[i] == -1) 390 methodsToReport[index++] = methods[i]; 391 problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methodsToReport, count); 392 return false; 393 } 394 void checkMethods() { 395 boolean mustImplementAbstractMethods = mustImplementAbstractMethods(); 396 boolean skipInheritedMethods = mustImplementAbstractMethods && canSkipInheritedMethods(); char[][] methodSelectors = this.inheritedMethods.keyTable; 398 nextSelector : for (int s = methodSelectors.length; --s >= 0;) { 399 if (methodSelectors[s] == null) continue nextSelector; 400 401 MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(methodSelectors[s]); 402 if (current == null && skipInheritedMethods) 403 continue nextSelector; 404 405 MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s]; 406 if (inherited.length == 1 && current == null) { if (mustImplementAbstractMethods && inherited[0].isAbstract()) 408 checkAbstractMethod(inherited[0]); 409 continue nextSelector; 410 } 411 412 int index = -1; 413 MethodBinding[] matchingInherited = new MethodBinding[inherited.length]; 414 byte[] foundMatch = new byte[inherited.length]; 415 if (current != null) { 416 for (int i = 0, length1 = current.length; i < length1; i++) { 417 MethodBinding currentMethod = current[i]; 418 for (int j = 0, length2 = inherited.length; j < length2; j++) { 419 MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod); 420 if (inheritedMethod != null) { 421 if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) { 422 matchingInherited[++index] = inheritedMethod; 423 foundMatch[j] = 1; } else { 425 checkForNameClash(currentMethod, inheritedMethod); 426 } 427 } 428 } 429 if (index >= 0) { 430 checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1, inherited); while (index >= 0) matchingInherited[index--] = null; } 436 } 437 } 438 439 for (int i = 0, length = inherited.length; i < length; i++) { 440 if (foundMatch[i] == 1) continue; 441 442 MethodBinding inheritedMethod = inherited[i]; 443 matchingInherited[++index] = inheritedMethod; 444 for (int j = i + 1; j < length; j++) { 445 MethodBinding otherInheritedMethod = inherited[j]; 446 if (foundMatch[j] == 1 || canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) 447 continue; 448 otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); 449 if (otherInheritedMethod != null) { 450 if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass 451 && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { 452 matchingInherited[++index] = otherInheritedMethod; 453 foundMatch[j] = 1; } else { 455 checkInheritedMethods(inheritedMethod, otherInheritedMethod); 456 } 457 } 458 } 459 if (index == -1) continue; 460 461 if (index > 0) 462 checkInheritedMethods(matchingInherited, index + 1); else if (mustImplementAbstractMethods && index == 0 && matchingInherited[0].isAbstract()) 464 checkAbstractMethod(matchingInherited[0]); 465 while (index >= 0) matchingInherited[index--] = null; } 467 } 468 } 469 void checkTypeVariableMethods(TypeParameter typeParameter) { 470 char[][] methodSelectors = this.inheritedMethods.keyTable; 471 nextSelector : for (int s = methodSelectors.length; --s >= 0;) { 472 if (methodSelectors[s] == null) continue nextSelector; 473 MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s]; 474 if (inherited.length == 1) continue nextSelector; 475 476 int index = -1; 477 MethodBinding[] matchingInherited = new MethodBinding[inherited.length]; 478 for (int i = 0, length = inherited.length; i < length; i++) { 479 while (index >= 0) matchingInherited[index--] = null; MethodBinding inheritedMethod = inherited[i]; 481 if (inheritedMethod != null) { 482 matchingInherited[++index] = inheritedMethod; 483 for (int j = i + 1; j < length; j++) { 484 MethodBinding otherInheritedMethod = inherited[j]; 485 if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) 486 continue; 487 otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); 488 if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { 489 matchingInherited[++index] = otherInheritedMethod; 490 inherited[j] = null; } 492 } 493 } 494 if (index > 0) { 495 MethodBinding first = matchingInherited[0]; 496 int count = index + 1; 497 while (--count > 0 && areReturnTypesCompatible(first, matchingInherited[count])){} 498 if (count > 0) { problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(typeParameter, matchingInherited, index + 1); 500 continue nextSelector; 501 } 502 } 503 } 504 } 505 } 506 MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { 507 if (inheritedMethod == null) return null; 508 if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; 510 if (currentMethod.declaringClass instanceof BinaryTypeBinding) 512 ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod); 513 if (inheritedMethod.declaringClass instanceof BinaryTypeBinding) 514 ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod); 515 516 TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables; 517 if (inheritedTypeVariables == Binding.NO_TYPE_VARIABLES) return inheritedMethod; 518 int inheritedLength = inheritedTypeVariables.length; 519 TypeVariableBinding[] typeVariables = currentMethod.typeVariables; 520 int length = typeVariables.length; 521 if (length > 0 && inheritedLength != length) return inheritedMethod; TypeBinding[] arguments = new TypeBinding[inheritedLength]; 523 if (inheritedLength <= length) { 524 System.arraycopy(typeVariables, 0, arguments, 0, inheritedLength); 525 } else { 526 System.arraycopy(typeVariables, 0, arguments, 0, length); 527 for (int i = length; i < inheritedLength; i++) 528 arguments[i] = inheritedTypeVariables[i].upperBound(); 529 } 530 ParameterizedGenericMethodBinding substitute = 531 this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); 532 533 for (int i = 0; i < inheritedLength; i++) { 537 TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i]; 538 TypeBinding argument = arguments[i]; 539 if (argument instanceof TypeVariableBinding) { 540 TypeVariableBinding typeVariable = (TypeVariableBinding) argument; 541 if (typeVariable.firstBound == inheritedTypeVariable.firstBound) { 542 if (typeVariable.firstBound == null) 543 continue; } else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) { 545 if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass()) 546 return inheritedMethod; } 548 if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass) 549 return inheritedMethod; int interfaceLength = inheritedTypeVariable.superInterfaces.length; 551 ReferenceBinding[] interfaces = typeVariable.superInterfaces; 552 if (interfaceLength != interfaces.length) 553 return inheritedMethod; next : for (int j = 0; j < interfaceLength; j++) { 556 TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]); 557 for (int k = 0; k < interfaceLength; k++) 558 if (superType == interfaces[k]) 559 continue next; 560 return inheritedMethod; } 562 } else if (inheritedTypeVariable.boundCheck(substitute, argument) != TypeConstants.OK) { 563 return inheritedMethod; 564 } 565 } 566 return substitute; 567 } 568 boolean detectInheritedNameClash(MethodBinding inherited, MethodBinding otherInherited) { 569 if (!inherited.areParameterErasuresEqual(otherInherited) || inherited.returnType.erasure() != otherInherited.returnType.erasure()) return false; 570 571 problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited); 572 return true; 573 } 574 boolean detectNameClash(MethodBinding current, MethodBinding inherited) { 575 MethodBinding original = inherited.original(); if (!current.areParameterErasuresEqual(original) || current.returnType.erasure() != original.returnType.erasure()) return false; 577 578 problemReporter(current).methodNameClash(current, 579 inherited.declaringClass.isRawType() ? inherited : original); 580 return true; 581 } 582 public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { 583 MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method); 584 return substitute != null && doesSubstituteMethodOverride(method, substitute); 585 } 586 boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) { 589 if (!areParametersEqual(method, substituteMethod)) { 590 if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod)) 595 return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method); 596 return false; 597 } 598 599 if (substituteMethod instanceof ParameterizedGenericMethodBinding) { 600 return ! (hasGenericParameter(method) && method.typeVariables == Binding.NO_TYPE_VARIABLES); 602 } 603 604 return method.typeVariables == Binding.NO_TYPE_VARIABLES; 606 } 607 boolean hasGenericParameter(MethodBinding method) { 608 if (method.genericSignature() == null) return false; 609 610 TypeBinding[] params = method.parameters; 612 for (int i = 0, l = params.length; i < l; i++) { 613 TypeBinding param = params[i].leafComponentType(); 614 if (param instanceof ReferenceBinding) { 615 int modifiers = ((ReferenceBinding) param).modifiers; 616 if ((modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) 617 return true; 618 } 619 } 620 return false; 621 } 622 boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) { 623 return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding); 625 } 626 SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) { 627 ReferenceBinding[] interfacesToVisit = null; 628 int nextPosition = 0; 629 ReferenceBinding[] itsInterfaces = superInterfaces; 630 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 631 nextPosition = itsInterfaces.length; 632 interfacesToVisit = itsInterfaces; 633 } 634 635 boolean isInconsistent = this.type.isHierarchyInconsistent(); 636 ReferenceBinding superType = superclass; 637 while (superType != null && superType.isValidBinding()) { 638 isInconsistent |= superType.isHierarchyInconsistent(); 639 if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 640 if (interfacesToVisit == null) { 641 interfacesToVisit = itsInterfaces; 642 nextPosition = interfacesToVisit.length; 643 } else { 644 int itsLength = itsInterfaces.length; 645 if (nextPosition + itsLength >= interfacesToVisit.length) 646 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 647 nextInterface : for (int a = 0; a < itsLength; a++) { 648 ReferenceBinding next = itsInterfaces[a]; 649 for (int b = 0; b < nextPosition; b++) 650 if (next == interfacesToVisit[b]) continue nextInterface; 651 interfacesToVisit[nextPosition++] = next; 652 } 653 } 654 } 655 superType = superType.superclass(); 656 } 657 658 for (int i = 0; i < nextPosition; i++) { 659 superType = interfacesToVisit[i]; 660 if (superType.isValidBinding()) { 661 isInconsistent |= superType.isHierarchyInconsistent(); 662 if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 663 int itsLength = itsInterfaces.length; 664 if (nextPosition + itsLength >= interfacesToVisit.length) 665 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 666 nextInterface : for (int a = 0; a < itsLength; a++) { 667 ReferenceBinding next = itsInterfaces[a]; 668 for (int b = 0; b < nextPosition; b++) 669 if (next == interfacesToVisit[b]) continue nextInterface; 670 interfacesToVisit[nextPosition++] = next; 671 } 672 } 673 } 674 } 675 676 if (!isInconsistent) return null; SimpleSet copy = null; 678 for (int i = 0; i < nextPosition; i++) { 679 ReferenceBinding current = interfacesToVisit[i]; 680 if (current.isValidBinding()) { 681 TypeBinding erasure = current.erasure(); 682 for (int j = i + 1; j < nextPosition; j++) { 683 ReferenceBinding next = interfacesToVisit[j]; 684 if (next.isValidBinding() && next.erasure() == erasure) { 685 if (copy == null) 686 copy = new SimpleSet(nextPosition); 687 copy.add(interfacesToVisit[i]); 688 copy.add(interfacesToVisit[j]); 689 } 690 } 691 } 692 } 693 return copy; 694 } 695 boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) { 697 if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) 698 return false; 700 inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); 701 return inheritedMethod != null 702 && inheritedMethod.returnType == existingMethod.returnType && super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType); 704 } 705 boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) { 706 if (currentMethod.returnType == inheritedMethod.returnType.erasure()) { 708 TypeBinding[] currentParams = currentMethod.parameters; 709 TypeBinding[] inheritedParams = inheritedMethod.parameters; 710 for (int i = 0, l = currentParams.length; i < l; i++) 711 if (!areTypesEqual(currentParams[i], inheritedParams[i])) 712 return true; 713 } 714 if (currentMethod.typeVariables == Binding.NO_TYPE_VARIABLES 715 && inheritedMethod.original().typeVariables != Binding.NO_TYPE_VARIABLES 716 && currentMethod.returnType.erasure().findSuperTypeWithSameErasure(inheritedMethod.returnType.erasure()) != null) { 717 return true; 718 } 719 return false; 720 } 721 boolean reportIncompatibleReturnTypeError(MethodBinding currentMethod, MethodBinding inheritedMethod) { 722 if (isUnsafeReturnTypeOverride(currentMethod, inheritedMethod)) { 723 problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, inheritedMethod, this.type); 724 return false; 725 } 726 return super.reportIncompatibleReturnTypeError(currentMethod, inheritedMethod); 727 } 728 void verify(SourceTypeBinding someType) { 729 if (someType.isAnnotationType()) 730 someType.detectAnnotationCycle(); 731 732 super.verify(someType); 733 734 for (int i = someType.typeVariables.length; --i >= 0;) { 735 TypeVariableBinding var = someType.typeVariables[i]; 736 if (var.superInterfaces == Binding.NO_SUPERINTERFACES) continue; 738 if (var.superInterfaces.length == 1 && var.superclass.id == TypeIds.T_JavaLangObject) continue; 739 740 this.currentMethods = new HashtableOfObject(0); 741 ReferenceBinding superclass = var.superclass(); 742 if (superclass.kind() == Binding.TYPE_PARAMETER) 743 superclass = (ReferenceBinding) superclass.erasure(); 744 ReferenceBinding[] itsInterfaces = var.superInterfaces(); 745 ReferenceBinding[] superInterfaces = new ReferenceBinding[itsInterfaces.length]; 746 for (int j = itsInterfaces.length; --j >= 0;) { 747 superInterfaces[j] = itsInterfaces[j].kind() == Binding.TYPE_PARAMETER 748 ? (ReferenceBinding) itsInterfaces[j].erasure() 749 : itsInterfaces[j]; 750 } 751 computeInheritedMethods(superclass, superInterfaces); 752 checkTypeVariableMethods(someType.scope.referenceContext.typeParameters[i]); 753 } 754 } 755 } 756 | Popular Tags |