1 /*******************************************************************************
2 * Copyright (c) 2000, 2020 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 * IBM Corporation - initial API and implementation
13 * Stephan Herrmann - Contributions for
14 * bug 349326 - [1.7] new warning for missing try-with-resources
15 * bug 186342 - [compiler][null] Using annotations for null checking
16 * bug 365519 - editorial cleanup after bug 186342 and bug 365387
17 * bug 358903 - Filter practically unimportant resource leak warnings
18 * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
19 * bug 388281 - [compiler][null] inheritance of null annotations as an option
20 * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
21 * bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
22 * bug 400421 - [compiler] Null analysis for fields does not take @com.google.inject.Inject into account
23 * bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
24 * bug 392384 - [1.8][compiler][null] Restore nullness info from type annotations in class files
25 * Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
26 * Bug 415291 - [1.8][null] differentiate type incompatibilities due to null annotations
27 * Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
28 * Bug 416176 - [1.8][compiler][null] null type annotations cause grief on type variables
29 * Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
30 * Bug 423504 - [1.8] Implement "18.5.3 Functional Interface Parameterization Inference"
31 * Bug 426792 - [1.8][inference][impl] generify new type inference engine
32 * Bug 428019 - [1.8][compiler] Type inference failure with nested generic invocation.
33 * Bug 427199 - [1.8][resource] avoid resource leak warnings on Streams that have no resource
34 * Bug 418743 - [1.8][null] contradictory annotations on invocation of generic method not reported
35 * Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
36 * Bug 431581 - Eclipse compiles what it should not
37 * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
38 * Bug 452788 - [1.8][compiler] Type not correctly inferred in lambda expression
39 * Bug 446442 - [1.8] merge null annotations from super methods
40 * Bug 456532 - [1.8][null] ReferenceBinding.appendNullAnnotation() includes phantom annotations in error messages
41 * Bug 410218 - Optional warning for arguments of "unexpected" types to Map#get(Object), Collection#remove(Object) et al.
42 * Jesper S Moller - Contributions for
43 * bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
44 * bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
45 * bug 527554 - [18.3] Compiler support for JEP 286 Local-Variable Type
46 * Ulrich Grave <ulrich.grave@gmx.de> - Contributions for
47 * bug 386692 - Missing "unused" warning on "autowired" fields
48 * Pierre-Yves B. <pyvesdev@gmail.com> - Contribution for
49 * bug 542520 - [JUnit 5] Warning The method xxx from the type X is never used locally is shown when using MethodSource
50 * Sebastian Zarnekow - Contributions for
51 * bug 544921 - [performance] Poor performance with large source files
52 *******************************************************************************/
53 package org.eclipse.jdt.internal.compiler.lookup;
54
55 import java.util.Arrays;
56 import java.util.Comparator;
57
58 import org.eclipse.jdt.core.compiler.CharOperation;
59 import org.eclipse.jdt.core.compiler.InvalidInputException;
60 import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
61 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
62 import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
63 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
64 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
65 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
66 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
67
68 /*
69 Not all fields defined by this type (& its subclasses) are initialized when it is created.
70 Some are initialized only when needed.
71
72 Accessors have been provided for some public fields so all TypeBindings have the same API...
73 but access public fields directly whenever possible.
74 Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
75
76 null is NOT a valid value for a non-public field... it just means the field is not initialized.
77 */
78
79 abstract public class ReferenceBinding extends TypeBinding {
80
81 public char[][] compoundName;
82 public char[] sourceName;
83 public int modifiers;
84 public PackageBinding fPackage;
85 char[] fileName;
86 char[] constantPoolName;
87 char[] signature;
88
89 private SimpleLookupTable compatibleCache;
90
91 int typeBits; // additional bits characterizing this type
92 protected MethodBinding [] singleAbstractMethod;
93
94 public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */
95 { this.id = TypeIds.T_undefined; }
96 @Override
97 public boolean hasTypeBit(int bit) { return false; }
98 };
99
100 private static final Comparator<FieldBinding> FIELD_COMPARATOR = new Comparator<FieldBinding>() {
101 @Override
102 public int compare(FieldBinding o1, FieldBinding o2) {
103 char[] n1 = o1.name;
104 char[] n2 = o2.name;
105 return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
106 }
107 };
108 private static final Comparator<MethodBinding> METHOD_COMPARATOR = new Comparator<MethodBinding>() {
109 @Override
110 public int compare(MethodBinding m1, MethodBinding m2) {
111 char[] s1 = m1.selector;
112 char[] s2 = m2.selector;
113 int c = ReferenceBinding.compare(s1, s2, s1.length, s2.length);
114 return c == 0 ? m1.parameters.length - m2.parameters.length : c;
115 }
116 };
117 static protected ProblemMethodBinding samProblemBinding = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod);
118
119
ReferenceBinding(ReferenceBinding prototype)120 public ReferenceBinding(ReferenceBinding prototype) {
121 super(prototype);
122
123 this.compoundName = prototype.compoundName;
124 this.sourceName = prototype.sourceName;
125 this.modifiers = prototype.modifiers;
126 this.fPackage = prototype.fPackage;
127 this.fileName = prototype.fileName;
128 this.constantPoolName = prototype.constantPoolName;
129 this.signature = prototype.signature;
130 this.compatibleCache = prototype.compatibleCache;
131 this.typeBits = prototype.typeBits;
132 this.singleAbstractMethod = prototype.singleAbstractMethod;
133 }
134
ReferenceBinding()135 public ReferenceBinding() {
136 super();
137 }
138
binarySearch(char[] name, FieldBinding[] sortedFields)139 public static FieldBinding binarySearch(char[] name, FieldBinding[] sortedFields) {
140 if (sortedFields == null)
141 return null;
142 int max = sortedFields.length;
143 if (max == 0)
144 return null;
145 int left = 0, right = max - 1, nameLength = name.length;
146 int mid = 0;
147 char[] midName;
148 while (left <= right) {
149 mid = left + (right - left) /2;
150 int compare = compare(name, midName = sortedFields[mid].name, nameLength, midName.length);
151 if (compare < 0) {
152 right = mid-1;
153 } else if (compare > 0) {
154 left = mid+1;
155 } else {
156 return sortedFields[mid];
157 }
158 }
159 return null;
160 }
161
162 /**
163 * Returns a combined range value representing: (start + (end<<32)), where start is the index of the first matching method
164 * (remember methods are sorted alphabetically on selectors), and end is the index of last contiguous methods with same
165 * selector.
166 * -1 means no method got found
167 * @param selector
168 * @param sortedMethods
169 * @return (start + (end<<32)) or -1 if no method found
170 */
binarySearch(char[] selector, MethodBinding[] sortedMethods)171 public static long binarySearch(char[] selector, MethodBinding[] sortedMethods) {
172 if (sortedMethods == null)
173 return -1;
174 int max = sortedMethods.length;
175 if (max == 0)
176 return -1;
177 int left = 0, right = max - 1, selectorLength = selector.length;
178 int mid = 0;
179 char[] midSelector;
180 while (left <= right) {
181 mid = left + (right - left) /2;
182 int compare = compare(selector, midSelector = sortedMethods[mid].selector, selectorLength, midSelector.length);
183 if (compare < 0) {
184 right = mid-1;
185 } else if (compare > 0) {
186 left = mid+1;
187 } else {
188 int start = mid, end = mid;
189 // find first method with same selector
190 while (start > left && CharOperation.equals(sortedMethods[start-1].selector, selector)){ start--; }
191 // find last method with same selector
192 while (end < right && CharOperation.equals(sortedMethods[end+1].selector, selector)){ end++; }
193 return start + ((long)end<< 32);
194 }
195 }
196 return -1;
197 }
198
199 /**
200 * Compares two strings lexicographically.
201 * The comparison is based on the Unicode value of each character in
202 * the strings.
203 *
204 * @return the value <code>0</code> if the str1 is equal to str2;
205 * a value less than <code>0</code> if str1
206 * is lexicographically less than str2;
207 * and a value greater than <code>0</code> if str1 is
208 * lexicographically greater than str2.
209 */
compare(char[] str1, char[] str2, int len1, int len2)210 static int compare(char[] str1, char[] str2, int len1, int len2) {
211 int n= Math.min(len1, len2);
212 int i= 0;
213 while (n-- != 0) {
214 char c1= str1[i];
215 char c2= str2[i++];
216 if (c1 != c2) {
217 return c1 - c2;
218 }
219 }
220 return len1 - len2;
221 }
222
223 /**
224 * Sort the field array using a quicksort
225 */
sortFields(FieldBinding[] sortedFields, int left, int right)226 public static void sortFields(FieldBinding[] sortedFields, int left, int right) {
227 Arrays.sort(sortedFields, left, right, FIELD_COMPARATOR);
228 }
229
230 /**
231 * Sort the field array using a quicksort
232 */
sortMethods(MethodBinding[] sortedMethods, int left, int right)233 public static void sortMethods(MethodBinding[] sortedMethods, int left, int right) {
234 Arrays.sort(sortedMethods, left, right, METHOD_COMPARATOR);
235 }
236
237 /**
238 * Sort the member types using a quicksort
239 */
sortMemberTypes(ReferenceBinding[] sortedMemberTypes, int left, int right)240 static void sortMemberTypes(ReferenceBinding[] sortedMemberTypes, int left, int right) {
241 Arrays.sort(sortedMemberTypes, left, right, BASIC_MEMBER_TYPES_COMPARATOR);
242 }
243
244 /**
245 * Compares two reference bindings by the value of the {@link #sourceName} field.
246 * A ReferenceBinding with a sourceName field that has the value null is considered
247 * to be smaller than a ReferenceBinding that does have a source name.
248 */
249 static final Comparator<ReferenceBinding> BASIC_MEMBER_TYPES_COMPARATOR = (ReferenceBinding o1, ReferenceBinding o2) -> {
250 char[] n1 = o1.sourceName;
251 char[] n2 = o2.sourceName;
252 // n1 or n2 may be null - compare without accessing the length of the array
253 if (n1 == null) {
254 if (n2 == null) {
255 return 0;
256 }
257 return -1;
258 } else if (n2 == null) {
259 return 1;
260 }
261 return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
262 };
263
264 /**
265 * Return the array of resolvable fields (resilience)
266 */
availableFields()267 public FieldBinding[] availableFields() {
268 return fields();
269 }
270
271 /**
272 * Return the array of resolvable methods (resilience)
273 */
availableMethods()274 public MethodBinding[] availableMethods() {
275 return methods();
276 }
277
hasHierarchyCheckStarted()278 public boolean hasHierarchyCheckStarted() {
279 return (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
280 }
281
setHierarchyCheckDone()282 public void setHierarchyCheckDone() {
283 return;
284 }
285
286
287 /**
288 * Answer true if the receiver can be instantiated
289 */
290 @Override
canBeInstantiated()291 public boolean canBeInstantiated() {
292 return (this.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation)) == 0;
293 }
294
295 /**
296 * Answer true if the receiver is visible to the invocationPackage.
297 */
canBeSeenBy(PackageBinding invocationPackage)298 public boolean canBeSeenBy(PackageBinding invocationPackage) {
299 if (isPublic()) return true;
300 if (isPrivate()) return false;
301
302 // isProtected() or isDefault()
303 return invocationPackage == this.fPackage;
304 }
305
306 /**
307 * Answer true if the receiver is visible to the receiverType and the invocationType.
308 */
canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType)309 public boolean canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType) {
310 if (isPublic()) return true;
311
312 if (isStatic() && (receiverType.isRawType() || receiverType.isParameterizedType()))
313 receiverType = receiverType.actualType(); // outer generics are irrelevant
314
315 if (TypeBinding.equalsEquals(invocationType, this) && TypeBinding.equalsEquals(invocationType, receiverType)) return true;
316
317 if (isProtected()) {
318 // answer true if the invocationType is the declaringClass or they are in the same package
319 // OR the invocationType is a subclass of the declaringClass
320 // AND the invocationType is the invocationType or its subclass
321 // OR the type is a static method accessed directly through a type
322 // OR previous assertions are true for one of the enclosing type
323 if (TypeBinding.equalsEquals(invocationType, this)) return true;
324 if (invocationType.fPackage == this.fPackage) return true;
325
326 TypeBinding currentType = invocationType.erasure();
327 TypeBinding declaringClass = enclosingType().erasure(); // protected types always have an enclosing one
328 if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
329 if (declaringClass == null) return false; // could be null if incorrect top-level protected type
330 //int depth = 0;
331 do {
332 if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
333 //depth++;
334 currentType = currentType.enclosingType();
335 } while (currentType != null);
336 return false;
337 }
338
339 if (isPrivate()) {
340 // answer true if the receiverType is the receiver or its enclosingType
341 // AND the invocationType and the receiver have a common enclosingType
342 receiverCheck: {
343 if (!(TypeBinding.equalsEquals(receiverType, this) || TypeBinding.equalsEquals(receiverType, enclosingType()))) {
344 // special tolerance for type variable direct bounds, but only if compliance <= 1.6, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622
345 if (receiverType.isTypeVariable()) {
346 TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType;
347 if (typeVariable.environment.globalOptions.complianceLevel <= ClassFileConstants.JDK1_6 && (typeVariable.isErasureBoundTo(erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())))
348 break receiverCheck;
349 }
350 return false;
351 }
352 }
353
354 if (TypeBinding.notEquals(invocationType, this)) {
355 ReferenceBinding outerInvocationType = invocationType;
356 ReferenceBinding temp = outerInvocationType.enclosingType();
357 while (temp != null) {
358 outerInvocationType = temp;
359 temp = temp.enclosingType();
360 }
361
362 ReferenceBinding outerDeclaringClass = (ReferenceBinding)erasure();
363 temp = outerDeclaringClass.enclosingType();
364 while (temp != null) {
365 outerDeclaringClass = temp;
366 temp = temp.enclosingType();
367 }
368 if (TypeBinding.notEquals(outerInvocationType, outerDeclaringClass)) return false;
369 }
370 return true;
371 }
372
373 // isDefault()
374 if (invocationType.fPackage != this.fPackage) return false;
375
376 ReferenceBinding currentType = receiverType;
377 TypeBinding originalDeclaringClass = (enclosingType() == null ? this : enclosingType()).original();
378 do {
379 if (currentType.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
380 if (TypeBinding.equalsEquals(originalDeclaringClass, currentType.erasure().original())) return true;
381 } else {
382 if (TypeBinding.equalsEquals(originalDeclaringClass, currentType.original())) return true;
383 }
384 PackageBinding currentPackage = currentType.fPackage;
385 // package could be null for wildcards/intersection types, ignore and recurse in superclass
386 if (currentPackage != null && currentPackage != this.fPackage) return false;
387 } while ((currentType = currentType.superclass()) != null);
388 return false;
389 }
390
391 /**
392 * Answer true if the receiver is visible to the type provided by the scope.
393 */
394 @Override
canBeSeenBy(Scope scope)395 public boolean canBeSeenBy(Scope scope) {
396 if (isPublic()) return true;
397
398 SourceTypeBinding invocationType = scope.enclosingSourceType();
399 if (TypeBinding.equalsEquals(invocationType, this)) return true;
400
401 if (invocationType == null) // static import call
402 return !isPrivate() && scope.getCurrentPackage() == this.fPackage;
403
404 if (isProtected()) {
405 // answer true if the invocationType is the declaringClass or they are in the same package
406 // OR the invocationType is a subclass of the declaringClass
407 // AND the invocationType is the invocationType or its subclass
408 // OR the type is a static method accessed directly through a type
409 // OR previous assertions are true for one of the enclosing type
410 if (invocationType.fPackage == this.fPackage) return true;
411
412 TypeBinding declaringClass = enclosingType(); // protected types always have an enclosing one
413 if (declaringClass == null) return false; // could be null if incorrect top-level protected type
414 declaringClass = declaringClass.erasure();// erasure cannot be null
415 TypeBinding currentType = invocationType.erasure();
416 // int depth = 0;
417 do {
418 if (TypeBinding.equalsEquals(declaringClass, invocationType)) return true;
419 if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
420 // depth++;
421 currentType = currentType.enclosingType();
422 } while (currentType != null);
423 return false;
424 }
425 if (isPrivate()) {
426 // answer true if the receiver and the invocationType have a common enclosingType
427 // already know they are not the identical type
428 ReferenceBinding outerInvocationType = invocationType;
429 ReferenceBinding temp = outerInvocationType.enclosingType();
430 while (temp != null) {
431 outerInvocationType = temp;
432 temp = temp.enclosingType();
433 }
434
435 ReferenceBinding outerDeclaringClass = (ReferenceBinding)erasure();
436 temp = outerDeclaringClass.enclosingType();
437 while (temp != null) {
438 outerDeclaringClass = temp;
439 temp = temp.enclosingType();
440 }
441 return TypeBinding.equalsEquals(outerInvocationType, outerDeclaringClass);
442 }
443
444 // isDefault()
445 return invocationType.fPackage == this.fPackage;
446 }
447
computeGenericTypeSignature(TypeVariableBinding[] typeVariables)448 public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {
449
450 boolean isMemberOfGeneric = isMemberType() && hasEnclosingInstanceContext() && (enclosingType().modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0;
451 if (typeVariables == Binding.NO_TYPE_VARIABLES && !isMemberOfGeneric) {
452 return signature();
453 }
454 StringBuffer sig = new StringBuffer(10);
455 if (isMemberOfGeneric) {
456 char[] typeSig = enclosingType().genericTypeSignature();
457 sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
458 sig.append('.'); // NOTE: cannot override trailing ';' with '.' in enclosing signature, since shared char[]
459 sig.append(this.sourceName);
460 } else {
461 char[] typeSig = signature();
462 sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
463 }
464 if (typeVariables == Binding.NO_TYPE_VARIABLES) {
465 sig.append(';');
466 } else {
467 sig.append('<');
468 for (int i = 0, length = typeVariables.length; i < length; i++) {
469 sig.append(typeVariables[i].genericTypeSignature());
470 }
471 sig.append(">;"); //$NON-NLS-1$
472 }
473 int sigLength = sig.length();
474 char[] result = new char[sigLength];
475 sig.getChars(0, sigLength, result, 0);
476 return result;
477 }
478
computeId()479 public void computeId() {
480 // note that more (configurable) ids are assigned from PackageBinding#checkIfNullAnnotationType()
481
482 // try to avoid multiple checks against a package/type name
483 switch (this.compoundName.length) {
484
485 case 3 :
486 char[] packageName = this.compoundName[0];
487 // expect only java.*.* and javax.*.* and junit.*.* and org.junit.*
488 switch (packageName.length) {
489 case 3: // only one type in this group, yet:
490 if (CharOperation.equals(TypeConstants.ORG_JUNIT_ASSERT, this.compoundName))
491 this.id = TypeIds.T_OrgJunitAssert;
492 return;
493 case 4:
494 if (!CharOperation.equals(TypeConstants.JAVA, packageName))
495 return;
496 break; // continue below ...
497 case 5:
498 switch (packageName[1]) {
499 case 'a':
500 if (CharOperation.equals(TypeConstants.JAVAX_ANNOTATION_INJECT_INJECT, this.compoundName))
501 this.id = TypeIds.T_JavaxInjectInject;
502 return;
503 case 'u':
504 if (CharOperation.equals(TypeConstants.JUNIT_FRAMEWORK_ASSERT, this.compoundName))
505 this.id = TypeIds.T_JunitFrameworkAssert;
506 return;
507 }
508 return;
509 default: return;
510 }
511 // ... at this point we know it's java.*.*
512
513 packageName = this.compoundName[1];
514 if (packageName.length == 0) return; // just to be safe
515 char[] typeName = this.compoundName[2];
516 if (typeName.length == 0) return; // just to be safe
517 // remaining types MUST be in java.*.*
518 if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) {
519 switch (packageName[0]) {
520 case 'i' :
521 if (CharOperation.equals(packageName, TypeConstants.IO)) {
522 switch (typeName[0]) {
523 case 'C' :
524 if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2]))
525 this.typeBits |= TypeIds.BitCloseable; // don't assign id, only typeBit (for analysis of resource leaks)
526 return;
527 case 'E' :
528 if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2]))
529 this.id = TypeIds.T_JavaIoExternalizable;
530 return;
531 case 'I' :
532 if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_IOEXCEPTION[2]))
533 this.id = TypeIds.T_JavaIoException;
534 return;
535 case 'O' :
536 if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_OBJECTSTREAMEXCEPTION[2]))
537 this.id = TypeIds.T_JavaIoObjectStreamException;
538 return;
539 case 'P' :
540 if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_PRINTSTREAM[2]))
541 this.id = TypeIds.T_JavaIoPrintStream;
542 return;
543 case 'S' :
544 if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_SERIALIZABLE[2]))
545 this.id = TypeIds.T_JavaIoSerializable;
546 return;
547 }
548 }
549 return;
550 case 'u' :
551 if (CharOperation.equals(packageName, TypeConstants.UTIL)) {
552 switch (typeName[0]) {
553 case 'C' :
554 if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_COLLECTION[2])) {
555 this.id = TypeIds.T_JavaUtilCollection;
556 this.typeBits |= TypeIds.BitCollection;
557 }
558 return;
559 case 'I' :
560 if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_ITERATOR[2]))
561 this.id = TypeIds.T_JavaUtilIterator;
562 return;
563 case 'L' :
564 if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_LIST[2])) {
565 this.id = TypeIds.T_JavaUtilList;
566 this.typeBits |= TypeIds.BitList;
567 }
568 return;
569 case 'M' :
570 if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_MAP[2])) {
571 this.id = TypeIds.T_JavaUtilMap;
572 this.typeBits |= TypeIds.BitMap;
573 }
574 return;
575 case 'O' :
576 if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_OBJECTS[2]))
577 this.id = TypeIds.T_JavaUtilObjects;
578 return;
579 }
580 }
581 return;
582 }
583 return;
584 }
585
586 // remaining types MUST be in java.lang.*
587 switch (typeName[0]) {
588 case 'A' :
589 switch(typeName.length) {
590 case 13 :
591 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
592 this.id = TypeIds.T_JavaLangAutoCloseable;
593 this.typeBits |= TypeIds.BitAutoCloseable;
594 }
595 return;
596 case 14:
597 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
598 this.id = TypeIds.T_JavaLangAssertionError;
599 return;
600 }
601 return;
602 case 'B' :
603 switch (typeName.length) {
604 case 4 :
605 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BYTE[2]))
606 this.id = TypeIds.T_JavaLangByte;
607 return;
608 case 7 :
609 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BOOLEAN[2]))
610 this.id = TypeIds.T_JavaLangBoolean;
611 return;
612 }
613 return;
614 case 'C' :
615 switch (typeName.length) {
616 case 5 :
617 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASS[2]))
618 this.id = TypeIds.T_JavaLangClass;
619 return;
620 case 9 :
621 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CHARACTER[2]))
622 this.id = TypeIds.T_JavaLangCharacter;
623 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLONEABLE[2]))
624 this.id = TypeIds.T_JavaLangCloneable;
625 return;
626 case 22 :
627 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
628 this.id = TypeIds.T_JavaLangClassNotFoundException;
629 return;
630 }
631 return;
632 case 'D' :
633 switch (typeName.length) {
634 case 6 :
635 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DOUBLE[2]))
636 this.id = TypeIds.T_JavaLangDouble;
637 return;
638 case 10 :
639 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DEPRECATED[2]))
640 this.id = TypeIds.T_JavaLangDeprecated;
641 return;
642 }
643 return;
644 case 'E' :
645 switch (typeName.length) {
646 case 4 :
647 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ENUM[2]))
648 this.id = TypeIds.T_JavaLangEnum;
649 return;
650 case 5 :
651 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ERROR[2]))
652 this.id = TypeIds.T_JavaLangError;
653 return;
654 case 9 :
655 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_EXCEPTION[2]))
656 this.id = TypeIds.T_JavaLangException;
657 return;
658 }
659 return;
660 case 'F' :
661 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FLOAT[2]))
662 this.id = TypeIds.T_JavaLangFloat;
663 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FUNCTIONAL_INTERFACE[2]))
664 this.id = TypeIds.T_JavaLangFunctionalInterface;
665 return;
666 case 'I' :
667 switch (typeName.length) {
668 case 7 :
669 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INTEGER[2]))
670 this.id = TypeIds.T_JavaLangInteger;
671 return;
672 case 8 :
673 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ITERABLE[2]))
674 this.id = TypeIds.T_JavaLangIterable;
675 return;
676 case 24 :
677 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2]))
678 this.id = TypeIds.T_JavaLangIllegalArgumentException;
679 return;
680 }
681 return;
682 case 'L' :
683 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_LONG[2]))
684 this.id = TypeIds.T_JavaLangLong;
685 return;
686 case 'N' :
687 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_NOCLASSDEFERROR[2]))
688 this.id = TypeIds.T_JavaLangNoClassDefError;
689 return;
690 case 'O' :
691 switch (typeName.length) {
692 case 6 :
693 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OBJECT[2]))
694 this.id = TypeIds.T_JavaLangObject;
695 return;
696 case 8 :
697 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OVERRIDE[2]))
698 this.id = TypeIds.T_JavaLangOverride;
699 return;
700 }
701 return;
702 case 'R' :
703 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2]))
704 this.id = TypeIds.T_JavaLangRuntimeException;
705 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RECORD[2]))
706 this.id = TypeIds.T_JavaLangRecord;
707 break;
708 case 'S' :
709 switch (typeName.length) {
710 case 5 :
711 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SHORT[2]))
712 this.id = TypeIds.T_JavaLangShort;
713 return;
714 case 6 :
715 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRING[2]))
716 this.id = TypeIds.T_JavaLangString;
717 else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SYSTEM[2]))
718 this.id = TypeIds.T_JavaLangSystem;
719 return;
720 case 11 :
721 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SAFEVARARGS[2]))
722 this.id = TypeIds.T_JavaLangSafeVarargs;
723 return;
724 case 12 :
725 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUFFER[2]))
726 this.id = TypeIds.T_JavaLangStringBuffer;
727 return;
728 case 13 :
729 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUILDER[2]))
730 this.id = TypeIds.T_JavaLangStringBuilder;
731 return;
732 case 16 :
733 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS[2]))
734 this.id = TypeIds.T_JavaLangSuppressWarnings;
735 return;
736 }
737 return;
738 case 'T' :
739 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_THROWABLE[2]))
740 this.id = TypeIds.T_JavaLangThrowable;
741 return;
742 case 'V' :
743 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_VOID[2]))
744 this.id = TypeIds.T_JavaLangVoid;
745 return;
746 }
747 break;
748
749 case 4:
750 // expect one type from com.*.*.*:
751 if (CharOperation.equals(TypeConstants.COM_GOOGLE_INJECT_INJECT, this.compoundName)) {
752 this.id = TypeIds.T_ComGoogleInjectInject;
753 return;
754 }
755 // otherwise only expect java.*.*.*
756 if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
757 return;
758 packageName = this.compoundName[1];
759 if (packageName.length == 0) return; // just to be safe
760
761 packageName = this.compoundName[2];
762 if (packageName.length == 0) return; // just to be safe
763 typeName = this.compoundName[3];
764 if (typeName.length == 0) return; // just to be safe
765 switch (packageName[0]) {
766 case 'a' :
767 if (CharOperation.equals(packageName, TypeConstants.ANNOTATION)) {
768 switch (typeName[0]) {
769 case 'A' :
770 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION[3]))
771 this.id = TypeIds.T_JavaLangAnnotationAnnotation;
772 return;
773 case 'D' :
774 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED[3]))
775 this.id = TypeIds.T_JavaLangAnnotationDocumented;
776 return;
777 case 'E' :
778 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE[3]))
779 this.id = TypeIds.T_JavaLangAnnotationElementType;
780 return;
781 case 'I' :
782 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED[3]))
783 this.id = TypeIds.T_JavaLangAnnotationInherited;
784 return;
785 case 'R' :
786 switch (typeName.length) {
787 case 9 :
788 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION[3]))
789 this.id = TypeIds.T_JavaLangAnnotationRetention;
790 return;
791 case 10 :
792 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_REPEATABLE[3]))
793 this.id = TypeIds.T_JavaLangAnnotationRepeatable;
794 return;
795 case 15 :
796 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3]))
797 this.id = TypeIds.T_JavaLangAnnotationRetentionPolicy;
798 return;
799 }
800 return;
801 case 'T' :
802 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_TARGET[3]))
803 this.id = TypeIds.T_JavaLangAnnotationTarget;
804 return;
805 }
806 }
807 return;
808 case 'i':
809 if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
810 if (typeName.length == 0) return; // just to be safe
811 switch (typeName[0]) {
812 case 'M' :
813 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE[3]))
814 this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
815 return;
816 }
817 }
818 return;
819 case 'r' :
820 if (CharOperation.equals(packageName, TypeConstants.REFLECT)) {
821 switch (typeName[0]) {
822 case 'C' :
823 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_CONSTRUCTOR[2]))
824 this.id = TypeIds.T_JavaLangReflectConstructor;
825 return;
826 case 'F' :
827 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_FIELD[2]))
828 this.id = TypeIds.T_JavaLangReflectField;
829 return;
830 case 'M' :
831 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_METHOD[2]))
832 this.id = TypeIds.T_JavaLangReflectMethod;
833 return;
834 }
835 }
836 return;
837 }
838 break;
839 case 5 :
840 packageName = this.compoundName[0];
841 switch (packageName[0]) {
842 case 'j' :
843 if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
844 return;
845 packageName = this.compoundName[1];
846 if (packageName.length == 0) return; // just to be safe
847
848 if (CharOperation.equals(TypeConstants.LANG, packageName)) {
849 packageName = this.compoundName[2];
850 if (packageName.length == 0) return; // just to be safe
851 switch (packageName[0]) {
852 case 'i' :
853 if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
854 typeName = this.compoundName[3];
855 if (typeName.length == 0) return; // just to be safe
856 switch (typeName[0]) {
857 case 'M' :
858 char[] memberTypeName = this.compoundName[4];
859 if (memberTypeName.length == 0) return; // just to be safe
860 if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[3])
861 && CharOperation.equals(memberTypeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[4]))
862 this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
863 return;
864 }
865 }
866 return;
867 }
868 return;
869 }
870 return;
871 case 'o':
872 if (!CharOperation.equals(TypeConstants.ORG, this.compoundName[0]))
873 return;
874 packageName = this.compoundName[1];
875 if (packageName.length == 0) return; // just to be safe
876
877 switch (packageName[0]) {
878 case 'e':
879 if (CharOperation.equals(TypeConstants.ECLIPSE, packageName)) {
880 packageName = this.compoundName[2];
881 if (packageName.length == 0) return; // just to be safe
882 switch (packageName[0]) {
883 case 'c' :
884 if (CharOperation.equals(packageName, TypeConstants.CORE)) {
885 typeName = this.compoundName[3];
886 if (typeName.length == 0) return; // just to be safe
887 switch (typeName[0]) {
888 case 'r' :
889 char[] memberTypeName = this.compoundName[4];
890 if (memberTypeName.length == 0) return; // just to be safe
891 if (CharOperation.equals(typeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[3])
892 && CharOperation.equals(memberTypeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[4]))
893 this.id = TypeIds.T_OrgEclipseCoreRuntimeAssert;
894 return;
895 }
896 }
897 return;
898 }
899 return;
900 }
901 return;
902 case 'a':
903 if (CharOperation.equals(TypeConstants.APACHE, packageName)) {
904 if (CharOperation.equals(TypeConstants.COMMONS, this.compoundName[2])) {
905 if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG_VALIDATE, this.compoundName))
906 this.id = TypeIds.T_OrgApacheCommonsLangValidate;
907 else if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG3_VALIDATE, this.compoundName))
908 this.id = TypeIds.T_OrgApacheCommonsLang3Validate;
909 }
910 }
911 return;
912 }
913 return;
914 case 'c':
915 if (!CharOperation.equals(TypeConstants.COM, this.compoundName[0]))
916 return;
917 if (CharOperation.equals(TypeConstants.COM_GOOGLE_COMMON_BASE_PRECONDITIONS, this.compoundName))
918 this.id = TypeIds.T_ComGoogleCommonBasePreconditions;
919 return;
920 }
921 break;
922 case 6:
923 if (CharOperation.equals(TypeConstants.ORG, this.compoundName[0])) {
924 if (CharOperation.equals(TypeConstants.SPRING, this.compoundName[1])) {
925 if (CharOperation.equals(TypeConstants.AUTOWIRED, this.compoundName[5])) {
926 if (CharOperation.equals(TypeConstants.ORG_SPRING_AUTOWIRED, this.compoundName)) {
927 this.id = TypeIds.T_OrgSpringframeworkBeansFactoryAnnotationAutowired;
928 }
929 }
930 return;
931 }
932 if (CharOperation.equals(TypeConstants.JUNIT, this.compoundName[1])) {
933 if (CharOperation.equals(TypeConstants.METHOD_SOURCE, this.compoundName[5])) {
934 if (CharOperation.equals(TypeConstants.ORG_JUNIT_METHOD_SOURCE, this.compoundName)) {
935 this.id = TypeIds.T_OrgJunitJupiterParamsProviderMethodSource;
936 }
937 }
938 return;
939 }
940 if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.ITYPEBINDING, this.compoundName[5]))
941 return;
942 if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_CORE_DOM_ITYPEBINDING, this.compoundName))
943 this.typeBits |= TypeIds.BitUninternedType;
944 }
945 break;
946 case 7 :
947 if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.TYPEBINDING, this.compoundName[6]))
948 return;
949 if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_INTERNAL_COMPILER_LOOKUP_TYPEBINDING, this.compoundName))
950 this.typeBits |= TypeIds.BitUninternedType;
951 break;
952 }
953 }
954
computeId(LookupEnvironment environment)955 public void computeId(LookupEnvironment environment) {
956 environment.getUnannotatedType(this);
957 }
958
959 /**
960 * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;
961 */
962 @Override
computeUniqueKey(boolean isLeaf)963 public char[] computeUniqueKey(boolean isLeaf) {
964 if (!isLeaf) return signature();
965 return genericTypeSignature();
966 }
967
968 /**
969 * Answer the receiver's constant pool name.
970 *
971 * NOTE: This method should only be used during/after code gen.
972 */
973 @Override
constantPoolName()974 public char[] constantPoolName() /* java/lang/Object */ {
975 if (this.constantPoolName != null) return this.constantPoolName;
976 return this.constantPoolName = CharOperation.concatWith(this.compoundName, '/');
977 }
978
979 @Override
debugName()980 public String debugName() {
981 return (this.compoundName != null) ? this.hasTypeAnnotations() ? annotatedDebugName() : new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
982 }
983
984 @Override
depth()985 public int depth() {
986 int depth = 0;
987 ReferenceBinding current = this;
988 while ((current = current.enclosingType()) != null)
989 depth++;
990 return depth;
991 }
992
detectAnnotationCycle()993 public boolean detectAnnotationCycle() {
994 if ((this.tagBits & TagBits.EndAnnotationCheck) != 0) return false; // already checked
995 if ((this.tagBits & TagBits.BeginAnnotationCheck) != 0) return true; // in the middle of checking its methods
996
997 this.tagBits |= TagBits.BeginAnnotationCheck;
998 MethodBinding[] currentMethods = methods();
999 boolean inCycle = false; // check each method before failing
1000 for (int i = 0, l = currentMethods.length; i < l; i++) {
1001 TypeBinding returnType = currentMethods[i].returnType.leafComponentType().erasure();
1002 if (TypeBinding.equalsEquals(this, returnType)) {
1003 if (this instanceof SourceTypeBinding) {
1004 MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
1005 ((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, this, decl != null ? decl.returnType : null);
1006 }
1007 } else if (returnType.isAnnotationType() && ((ReferenceBinding) returnType).detectAnnotationCycle()) {
1008 if (this instanceof SourceTypeBinding) {
1009 MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
1010 ((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, returnType, decl != null ? decl.returnType : null);
1011 }
1012 inCycle = true;
1013 }
1014 }
1015 if (inCycle)
1016 return true;
1017 this.tagBits |= TagBits.EndAnnotationCheck;
1018 return false;
1019 }
1020
enclosingTypeAt(int relativeDepth)1021 public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
1022 ReferenceBinding current = this;
1023 while (relativeDepth-- > 0 && current != null)
1024 current = current.enclosingType();
1025 return current;
1026 }
1027
enumConstantCount()1028 public int enumConstantCount() {
1029 int count = 0;
1030 FieldBinding[] fields = fields();
1031 for (int i = 0, length = fields.length; i < length; i++) {
1032 if ((fields[i].modifiers & ClassFileConstants.AccEnum) != 0) count++;
1033 }
1034 return count;
1035 }
1036
fieldCount()1037 public int fieldCount() {
1038 return fields().length;
1039 }
1040
fields()1041 public FieldBinding[] fields() {
1042 return Binding.NO_FIELDS;
1043 }
1044
getAccessFlags()1045 public final int getAccessFlags() {
1046 return this.modifiers & ExtraCompilerModifiers.AccJustFlag;
1047 }
1048
1049 /**
1050 * @return the JSR 175 annotations for this type.
1051 */
1052 @Override
getAnnotations()1053 public AnnotationBinding[] getAnnotations() {
1054 return retrieveAnnotations(this);
1055 }
1056
1057 /**
1058 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
1059 */
1060 @Override
getAnnotationTagBits()1061 public long getAnnotationTagBits() {
1062 return this.tagBits;
1063 }
1064
1065 /**
1066 * @return the enclosingInstancesSlotSize
1067 */
getEnclosingInstancesSlotSize()1068 public int getEnclosingInstancesSlotSize() {
1069 if (isStatic()) return 0;
1070 return enclosingType() == null ? 0 : 1;
1071 }
1072
getExactConstructor(TypeBinding[] argumentTypes)1073 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
1074 return null;
1075 }
1076
getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope)1077 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
1078 return null;
1079 }
getField(char[] fieldName, boolean needResolve)1080 public FieldBinding getField(char[] fieldName, boolean needResolve) {
1081 return null;
1082 }
1083 /**
1084 * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
1085 */
getFileName()1086 public char[] getFileName() {
1087 return this.fileName;
1088 }
1089
1090 /**
1091 * Find the member type with the given simple typeName. Benefits from the fact that
1092 * the array of {@link #memberTypes()} is sorted.
1093 */
getMemberType(char[] typeName)1094 public ReferenceBinding getMemberType(char[] typeName) {
1095 ReferenceBinding[] memberTypes = memberTypes();
1096 int memberTypeIndex = binarySearch(typeName, memberTypes);
1097 if (memberTypeIndex >= 0) {
1098 return memberTypes[memberTypeIndex];
1099 }
1100 return null;
1101 }
1102
1103 /**
1104 * Search the given sourceName in the list of sorted member types.
1105 *
1106 * Neither the array of sortedMemberTypes nor the given sourceName may be null.
1107 */
binarySearch(char[] sourceName, ReferenceBinding[] sortedMemberTypes)1108 static int binarySearch(char[] sourceName, ReferenceBinding[] sortedMemberTypes) {
1109 if (sortedMemberTypes == null)
1110 return -1;
1111 int max = sortedMemberTypes.length, nameLength = sourceName.length;
1112 if (max == 0)
1113 return -1;
1114 int left = 0, right = max - 1;
1115 while (left <= right) {
1116 int mid = left + (right - left) / 2;
1117 char[] midName = sortedMemberTypes[mid].sourceName;
1118 // The read source name may be null. In that case, the given sourceName is considered
1119 // to be larger than the current value at mid.
1120 int compare = midName == null ? 1 : compare(sourceName, midName, nameLength, midName.length);
1121 if (compare < 0) {
1122 right = mid-1;
1123 } else if (compare > 0) {
1124 left = mid+1;
1125 } else {
1126 return mid;
1127 }
1128 }
1129 return -1;
1130 }
1131
1132 @Override
getMethods(char[] selector)1133 public MethodBinding[] getMethods(char[] selector) {
1134 return Binding.NO_METHODS;
1135 }
1136
1137 // Answer methods named selector, which take no more than the suggestedParameterLength.
1138 // The suggested parameter length is optional and may not be guaranteed by every type.
getMethods(char[] selector, int suggestedParameterLength)1139 public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) {
1140 return getMethods(selector);
1141 }
1142
1143 /**
1144 * @return the outerLocalVariablesSlotSize
1145 */
getOuterLocalVariablesSlotSize()1146 public int getOuterLocalVariablesSlotSize() {
1147 return 0;
1148 }
1149
1150 @Override
getPackage()1151 public PackageBinding getPackage() {
1152 return this.fPackage;
1153 }
1154
getTypeVariable(char[] variableName)1155 public TypeVariableBinding getTypeVariable(char[] variableName) {
1156 TypeVariableBinding[] typeVariables = typeVariables();
1157 for (int i = typeVariables.length; --i >= 0;)
1158 if (CharOperation.equals(typeVariables[i].sourceName, variableName))
1159 return typeVariables[i];
1160 return null;
1161 }
1162
1163 @Override
hashCode()1164 public int hashCode() {
1165 // ensure ReferenceBindings hash to the same position as UnresolvedReferenceBindings so they can be replaced without rehashing
1166 // ALL ReferenceBindings are unique when created so equals() is the same as ==
1167 return (this.compoundName == null || this.compoundName.length == 0)
1168 ? super.hashCode()
1169 : CharOperation.hashCode(this.compoundName[this.compoundName.length - 1]);
1170 }
1171
identityHashCode()1172 final int identityHashCode() {
1173 return super.hashCode();
1174 }
1175
1176 /**
1177 * Returns true if the two types have an incompatible common supertype,
1178 * e.g. List<String> and List<Integer>
1179 */
hasIncompatibleSuperType(ReferenceBinding otherType)1180 public boolean hasIncompatibleSuperType(ReferenceBinding otherType) {
1181
1182 if (TypeBinding.equalsEquals(this, otherType)) return false;
1183
1184 ReferenceBinding[] interfacesToVisit = null;
1185 int nextPosition = 0;
1186 ReferenceBinding currentType = this;
1187 TypeBinding match;
1188 do {
1189 match = otherType.findSuperTypeOriginatingFrom(currentType);
1190 if (match != null && match.isProvablyDistinct(currentType))
1191 return true;
1192
1193 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
1194 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
1195 if (interfacesToVisit == null) {
1196 interfacesToVisit = itsInterfaces;
1197 nextPosition = interfacesToVisit.length;
1198 } else {
1199 int itsLength = itsInterfaces.length;
1200 if (nextPosition + itsLength >= interfacesToVisit.length)
1201 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
1202 nextInterface : for (int a = 0; a < itsLength; a++) {
1203 ReferenceBinding next = itsInterfaces[a];
1204 for (int b = 0; b < nextPosition; b++)
1205 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
1206 interfacesToVisit[nextPosition++] = next;
1207 }
1208 }
1209 }
1210 } while ((currentType = currentType.superclass()) != null);
1211
1212 for (int i = 0; i < nextPosition; i++) {
1213 currentType = interfacesToVisit[i];
1214 if (TypeBinding.equalsEquals(currentType, otherType)) return false;
1215 match = otherType.findSuperTypeOriginatingFrom(currentType);
1216 if (match != null && match.isProvablyDistinct(currentType))
1217 return true;
1218
1219 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
1220 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
1221 int itsLength = itsInterfaces.length;
1222 if (nextPosition + itsLength >= interfacesToVisit.length)
1223 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
1224 nextInterface : for (int a = 0; a < itsLength; a++) {
1225 ReferenceBinding next = itsInterfaces[a];
1226 for (int b = 0; b < nextPosition; b++)
1227 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
1228 interfacesToVisit[nextPosition++] = next;
1229 }
1230 }
1231 }
1232 return false;
1233 }
1234
hasMemberTypes()1235 public boolean hasMemberTypes() {
1236 return false;
1237 }
1238
1239 /**
1240 * Answer whether a @NonNullByDefault is applicable at the reference binding,
1241 * for 1.8 check if the default is applicable to the given kind of location.
1242 */
1243 // pre: null annotation analysis is enabled
hasNonNullDefaultFor(int location, int sourceStart)1244 boolean hasNonNullDefaultFor(int location, int sourceStart) {
1245 // Note, STB overrides for correctly handling local types
1246 ReferenceBinding currentType = this;
1247 while (currentType != null) {
1248 int nullDefault = ((ReferenceBinding)currentType.original()).getNullDefault();
1249 if (nullDefault != 0)
1250 return (nullDefault & location) != 0;
1251 currentType = currentType.enclosingType();
1252 }
1253 // package
1254 return (this.getPackage().getDefaultNullness() & location) != 0;
1255 }
1256
getNullDefault()1257 int getNullDefault() {
1258 return 0;
1259 }
1260
1261 @Override
acceptsNonNullDefault()1262 public boolean acceptsNonNullDefault() {
1263 return true;
1264 }
1265
hasRestrictedAccess()1266 public final boolean hasRestrictedAccess() {
1267 return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
1268 }
1269
1270 /** Query typeBits without triggering supertype lookup. */
hasNullBit(int mask)1271 public boolean hasNullBit(int mask) {
1272 return (this.typeBits & mask) != 0;
1273 }
1274
1275 /** Answer true if the receiver implements anInterface or is identical to anInterface.
1276 * If searchHierarchy is true, then also search the receiver's superclasses.
1277 *
1278 * NOTE: Assume that anInterface is an interface.
1279 */
implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy)1280 public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
1281 if (TypeBinding.equalsEquals(this, anInterface))
1282 return true;
1283
1284 ReferenceBinding[] interfacesToVisit = null;
1285 int nextPosition = 0;
1286 ReferenceBinding currentType = this;
1287 do {
1288 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
1289 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { // in code assist cases when source types are added late, may not be finished connecting hierarchy
1290 if (interfacesToVisit == null) {
1291 interfacesToVisit = itsInterfaces;
1292 nextPosition = interfacesToVisit.length;
1293 } else {
1294 int itsLength = itsInterfaces.length;
1295 if (nextPosition + itsLength >= interfacesToVisit.length)
1296 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
1297 nextInterface : for (int a = 0; a < itsLength; a++) {
1298 ReferenceBinding next = itsInterfaces[a];
1299 for (int b = 0; b < nextPosition; b++)
1300 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
1301 interfacesToVisit[nextPosition++] = next;
1302 }
1303 }
1304 }
1305 } while (searchHierarchy && (currentType = currentType.superclass()) != null);
1306
1307 for (int i = 0; i < nextPosition; i++) {
1308 currentType = interfacesToVisit[i];
1309 if (currentType.isEquivalentTo(anInterface))
1310 return true;
1311
1312 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
1313 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { // in code assist cases when source types are added late, may not be finished connecting hierarchy
1314 int itsLength = itsInterfaces.length;
1315 if (nextPosition + itsLength >= interfacesToVisit.length)
1316 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
1317 nextInterface : for (int a = 0; a < itsLength; a++) {
1318 ReferenceBinding next = itsInterfaces[a];
1319 for (int b = 0; b < nextPosition; b++)
1320 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
1321 interfacesToVisit[nextPosition++] = next;
1322 }
1323 }
1324 }
1325 return false;
1326 }
1327
1328 // Internal method... assume its only sent to classes NOT interfaces
implementsMethod(MethodBinding method)1329 boolean implementsMethod(MethodBinding method) {
1330 char[] selector = method.selector;
1331 ReferenceBinding type = this;
1332 while (type != null) {
1333 MethodBinding[] methods = type.methods();
1334 long range;
1335 if ((range = ReferenceBinding.binarySearch(selector, methods)) >= 0) {
1336 int start = (int) range, end = (int) (range >> 32);
1337 for (int i = start; i <= end; i++) {
1338 if (methods[i].areParametersEqual(method))
1339 return true;
1340 }
1341 }
1342 type = type.superclass();
1343 }
1344 return false;
1345 }
1346
1347 /**
1348 * Answer true if the receiver is an abstract type
1349 */
isAbstract()1350 public final boolean isAbstract() {
1351 return (this.modifiers & ClassFileConstants.AccAbstract) != 0;
1352 }
1353
1354 @Override
isAnnotationType()1355 public boolean isAnnotationType() {
1356 return (this.modifiers & ClassFileConstants.AccAnnotation) != 0;
1357 }
1358
isBinaryBinding()1359 public final boolean isBinaryBinding() {
1360 return (this.tagBits & TagBits.IsBinaryBinding) != 0;
1361 }
1362
1363 @Override
isClass()1364 public boolean isClass() {
1365 return (this.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) == 0;
1366 }
1367
getSourceTypeBinding(ReferenceBinding ref)1368 private static SourceTypeBinding getSourceTypeBinding(ReferenceBinding ref) {
1369 if (ref instanceof SourceTypeBinding)
1370 return (SourceTypeBinding) ref;
1371 if (ref instanceof ParameterizedTypeBinding) {
1372 ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) ref;
1373 return ptb.type instanceof SourceTypeBinding ? (SourceTypeBinding) ptb.type : null;
1374 }
1375 return null;
1376 }
isNestmateOf(ReferenceBinding other)1377 public boolean isNestmateOf(ReferenceBinding other) {
1378 SourceTypeBinding s1 = getSourceTypeBinding(this);
1379 SourceTypeBinding s2 = getSourceTypeBinding(other);
1380 if (s1 == null || s2 == null) return false;
1381
1382 return s1.isNestmateOf(s2);
1383 }
1384
1385 @Override
isProperType(boolean admitCapture18)1386 public boolean isProperType(boolean admitCapture18) {
1387 ReferenceBinding outer = enclosingType();
1388 if (outer != null && !outer.isProperType(admitCapture18))
1389 return false;
1390 return super.isProperType(admitCapture18);
1391 }
1392
1393 /**
1394 * Answer true if the receiver type can be assigned to the argument type (right)
1395 * In addition to improving performance, caching also ensures there is no infinite regression
1396 * since per nature, the compatibility check is recursive through parameterized type arguments (122775)
1397 */
1398 @Override
isCompatibleWith(TypeBinding otherType, Scope captureScope)1399 public boolean isCompatibleWith(TypeBinding otherType, /*@Nullable*/ Scope captureScope) {
1400 if (equalsEquals(otherType, this))
1401 return true;
1402
1403 if (otherType.id == TypeIds.T_JavaLangObject)
1404 return true;
1405 Object result;
1406 if (this.compatibleCache == null) {
1407 this.compatibleCache = new SimpleLookupTable(3);
1408 result = null;
1409 } else {
1410 result = this.compatibleCache.get(otherType); // [dbg reset] this.compatibleCache.put(otherType,null)
1411 if (result != null) {
1412 return result == Boolean.TRUE;
1413 }
1414 }
1415 this.compatibleCache.put(otherType, Boolean.FALSE); // protect from recursive call
1416 if (isCompatibleWith0(otherType, captureScope)) {
1417 this.compatibleCache.put(otherType, Boolean.TRUE);
1418 return true;
1419 }
1420 if (captureScope == null
1421 && this instanceof TypeVariableBinding
1422 && ((TypeVariableBinding)this).firstBound instanceof ParameterizedTypeBinding) {
1423 // see https://bugs.eclipse.org/395002#c9
1424 // in this case a subsequent check with captureScope != null may actually get
1425 // a better result, reset this info to ensure we're not blocking that re-check.
1426 this.compatibleCache.put(otherType, null);
1427 }
1428 return false;
1429 }
1430
1431 /**
1432 * Answer true if the receiver type can be assigned to the argument type (right)
1433 */
isCompatibleWith0(TypeBinding otherType, Scope captureScope)1434 private boolean isCompatibleWith0(TypeBinding otherType, /*@Nullable*/ Scope captureScope) {
1435 if (TypeBinding.equalsEquals(otherType, this))
1436 return true;
1437 if (otherType.id == TypeIds.T_JavaLangObject)
1438 return true;
1439 // equivalence may allow compatibility with array type through wildcard
1440 // bound
1441 if (isEquivalentTo(otherType))
1442 return true;
1443 switch (otherType.kind()) {
1444 case Binding.WILDCARD_TYPE :
1445 case Binding.INTERSECTION_TYPE:
1446 return false; // should have passed equivalence check above if
1447 // wildcard
1448 case Binding.TYPE_PARAMETER :
1449 // check compatibility with capture of ? super X
1450 if (otherType.isCapture()) {
1451 CaptureBinding otherCapture = (CaptureBinding) otherType;
1452 TypeBinding otherLowerBound;
1453 if ((otherLowerBound = otherCapture.lowerBound) != null) {
1454 if (otherLowerBound.isArrayType()) return false;
1455 return isCompatibleWith(otherLowerBound);
1456 }
1457 }
1458 if (otherType instanceof InferenceVariable) {
1459 // may interpret InferenceVariable as a joker, but only when within an outer lambda inference:
1460 if (captureScope != null) {
1461 MethodScope methodScope = captureScope.methodScope();
1462 if (methodScope != null) {
1463 ReferenceContext referenceContext = methodScope.referenceContext;
1464 if (referenceContext instanceof LambdaExpression
1465 && ((LambdaExpression)referenceContext).inferenceContext != null)
1466 return true;
1467 }
1468 }
1469 }
1470 //$FALL-THROUGH$
1471 case Binding.GENERIC_TYPE :
1472 case Binding.TYPE :
1473 case Binding.PARAMETERIZED_TYPE :
1474 case Binding.RAW_TYPE :
1475 case Binding.INTERSECTION_TYPE18 :
1476 switch (kind()) {
1477 case Binding.GENERIC_TYPE :
1478 case Binding.PARAMETERIZED_TYPE :
1479 case Binding.RAW_TYPE :
1480 if (TypeBinding.equalsEquals(erasure(), otherType.erasure()))
1481 return false; // should have passed equivalence check
1482 // above if same erasure
1483 }
1484 ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
1485 if (otherReferenceType.isIntersectionType18()) {
1486 ReferenceBinding[] intersectingTypes = ((IntersectionTypeBinding18)otherReferenceType).intersectingTypes;
1487 for (ReferenceBinding binding : intersectingTypes) {
1488 if (!isCompatibleWith(binding))
1489 return false;
1490 }
1491 return true;
1492 }
1493 if (otherReferenceType.isInterface()) { // could be annotation type
1494 if (implementsInterface(otherReferenceType, true))
1495 return true;
1496 if (this instanceof TypeVariableBinding && captureScope != null) {
1497 TypeVariableBinding typeVariable = (TypeVariableBinding) this;
1498 if (typeVariable.firstBound instanceof ParameterizedTypeBinding) {
1499 TypeBinding bound = typeVariable.firstBound.capture(captureScope, -1, -1); // no position needed as this capture will never escape this context
1500 return bound.isCompatibleWith(otherReferenceType);
1501 }
1502 }
1503 }
1504 if (isInterface()) // Explicit conversion from an interface
1505 // to a class is not allowed
1506 return false;
1507 return otherReferenceType.isSuperclassOf(this);
1508 default :
1509 return false;
1510 }
1511 }
1512
1513 @Override
isSubtypeOf(TypeBinding other, boolean simulatingBugJDK8026527)1514 public boolean isSubtypeOf(TypeBinding other, boolean simulatingBugJDK8026527) {
1515 if (isSubTypeOfRTL(other))
1516 return true;
1517 // TODO: if this has wildcards, perform capture before the next call:
1518 TypeBinding candidate = findSuperTypeOriginatingFrom(other);
1519 if (candidate == null)
1520 return false;
1521 if (TypeBinding.equalsEquals(candidate, other))
1522 return true;
1523
1524 // T<Ai...> <: T#RAW:
1525 if (other.isRawType() && TypeBinding.equalsEquals(candidate.erasure(), other.erasure()))
1526 return true;
1527
1528 TypeBinding[] sis = other.typeArguments();
1529 TypeBinding[] tis = candidate.typeArguments();
1530 if (tis == null || sis == null)
1531 return false;
1532 if (sis.length != tis.length)
1533 return false;
1534 for (int i = 0; i < sis.length; i++) {
1535 if (!tis[i].isTypeArgumentContainedBy(sis[i]))
1536 return false;
1537 }
1538 return true;
1539 }
1540
isSubTypeOfRTL(TypeBinding other)1541 protected boolean isSubTypeOfRTL(TypeBinding other) {
1542 if (TypeBinding.equalsEquals(this, other))
1543 return true;
1544 if (other instanceof CaptureBinding) {
1545 // for this one kind we must first unwrap the rhs:
1546 TypeBinding lower = ((CaptureBinding) other).lowerBound;
1547 return (lower != null && isSubtypeOf(lower, false));
1548 }
1549 if (other instanceof ReferenceBinding) {
1550 TypeBinding[] intersecting = ((ReferenceBinding) other).getIntersectingTypes();
1551 if (intersecting != null) {
1552 for (int i = 0; i < intersecting.length; i++) {
1553 if (!isSubtypeOf(intersecting[i], false))
1554 return false;
1555 }
1556 return true;
1557 }
1558 }
1559 return false;
1560 }
1561
1562 /**
1563 * Answer true if the receiver has default visibility
1564 */
isDefault()1565 public final boolean isDefault() {
1566 return (this.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate)) == 0;
1567 }
1568
1569 /**
1570 * Answer true if the receiver is a deprecated type
1571 */
isDeprecated()1572 public final boolean isDeprecated() {
1573 return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
1574 }
1575
1576 @Override
isEnum()1577 public boolean isEnum() {
1578 return (this.modifiers & ClassFileConstants.AccEnum) != 0;
1579 }
1580
1581 /**
1582 * Answer true if the receiver is final and cannot be subclassed
1583 */
isFinal()1584 public final boolean isFinal() {
1585 return (this.modifiers & ClassFileConstants.AccFinal) != 0;
1586 }
1587
1588 /**
1589 * Returns true if the type hierarchy is being connected
1590 */
isHierarchyBeingConnected()1591 public boolean isHierarchyBeingConnected() {
1592 return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
1593 }
1594 /**
1595 * Returns true if the type hierarchy is being connected "actively" i.e not paused momentatrily,
1596 * while resolving type arguments. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057
1597 */
isHierarchyBeingActivelyConnected()1598 public boolean isHierarchyBeingActivelyConnected() {
1599 return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0 && (this.tagBits & TagBits.PauseHierarchyCheck) == 0;
1600 }
1601
1602 /**
1603 * Returns true if the type hierarchy is connected
1604 */
isHierarchyConnected()1605 public boolean isHierarchyConnected() {
1606 return true;
1607 }
1608
1609 @Override
isInterface()1610 public boolean isInterface() {
1611 // consider strict interfaces and annotation types
1612 return (this.modifiers & ClassFileConstants.AccInterface) != 0;
1613 }
1614
1615 @Override
isFunctionalInterface(Scope scope)1616 public boolean isFunctionalInterface(Scope scope) {
1617 MethodBinding method;
1618 return isInterface() && (method = getSingleAbstractMethod(scope, true)) != null && method.isValidBinding();
1619 }
1620
1621 /**
1622 * Answer true if the receiver has private visibility
1623 */
isPrivate()1624 public final boolean isPrivate() {
1625 return (this.modifiers & ClassFileConstants.AccPrivate) != 0;
1626 }
1627
1628 /**
1629 * Answer true if the receiver or any of its enclosing types have private visibility
1630 */
isOrEnclosedByPrivateType()1631 public final boolean isOrEnclosedByPrivateType() {
1632 if (isLocalType()) return true; // catch all local types
1633 ReferenceBinding type = this;
1634 while (type != null) {
1635 if ((type.modifiers & ClassFileConstants.AccPrivate) != 0)
1636 return true;
1637 type = type.enclosingType();
1638 }
1639 return false;
1640 }
1641
1642 /**
1643 * Answer true if the receiver has protected visibility
1644 */
isProtected()1645 public final boolean isProtected() {
1646 return (this.modifiers & ClassFileConstants.AccProtected) != 0;
1647 }
1648
1649 /**
1650 * Answer true if the receiver has public visibility
1651 */
isPublic()1652 public final boolean isPublic() {
1653 return (this.modifiers & ClassFileConstants.AccPublic) != 0;
1654 }
1655
1656 /**
1657 * Answer true if the receiver is a static member type (or toplevel)
1658 */
1659 @Override
isStatic()1660 public final boolean isStatic() {
1661 return (this.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface)) != 0 || (this.tagBits & TagBits.IsNestedType) == 0;
1662 }
1663
1664 /**
1665 * Answer true if all float operations must adher to IEEE 754 float/double rules
1666 */
isStrictfp()1667 public final boolean isStrictfp() {
1668 return (this.modifiers & ClassFileConstants.AccStrictfp) != 0;
1669 }
1670
1671 /**
1672 * Answer true if the receiver is in the superclass hierarchy of aType
1673 * NOTE: Object.isSuperclassOf(Object) -> false
1674 */
isSuperclassOf(ReferenceBinding otherType)1675 public boolean isSuperclassOf(ReferenceBinding otherType) {
1676 while ((otherType = otherType.superclass()) != null) {
1677 if (otherType.isEquivalentTo(this)) return true;
1678 }
1679 return false;
1680 }
1681
1682 /**
1683 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isThrowable()
1684 */
1685 @Override
isThrowable()1686 public boolean isThrowable() {
1687 ReferenceBinding current = this;
1688 do {
1689 switch (current.id) {
1690 case TypeIds.T_JavaLangThrowable :
1691 case TypeIds.T_JavaLangError :
1692 case TypeIds.T_JavaLangRuntimeException :
1693 case TypeIds.T_JavaLangException :
1694 return true;
1695 }
1696 } while ((current = current.superclass()) != null);
1697 return false;
1698 }
1699
1700 /**
1701 * JLS 11.5 ensures that Throwable, Exception, RuntimeException and Error are directly connected.
1702 * (Throwable<- Exception <- RumtimeException, Throwable <- Error). Thus no need to check #isCompatibleWith
1703 * but rather check in type IDs so as to avoid some eager class loading for JCL writers.
1704 * When 'includeSupertype' is true, answers true if the given type can be a supertype of some unchecked exception
1705 * type (i.e. Throwable or Exception).
1706 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isUncheckedException(boolean)
1707 */
1708 @Override
isUncheckedException(boolean includeSupertype)1709 public boolean isUncheckedException(boolean includeSupertype) {
1710 switch (this.id) {
1711 case TypeIds.T_JavaLangError :
1712 case TypeIds.T_JavaLangRuntimeException :
1713 return true;
1714 case TypeIds.T_JavaLangThrowable :
1715 case TypeIds.T_JavaLangException :
1716 return includeSupertype;
1717 }
1718 ReferenceBinding current = this;
1719 while ((current = current.superclass()) != null) {
1720 switch (current.id) {
1721 case TypeIds.T_JavaLangError :
1722 case TypeIds.T_JavaLangRuntimeException :
1723 return true;
1724 case TypeIds.T_JavaLangThrowable :
1725 case TypeIds.T_JavaLangException :
1726 return false;
1727 }
1728 }
1729 return false;
1730 }
1731
1732 /**
1733 * Answer true if the receiver has private visibility and is used locally
1734 */
isUsed()1735 public final boolean isUsed() {
1736 return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0;
1737 }
1738
1739 /**
1740 * Answer true if the receiver is deprecated (or any of its enclosing types)
1741 */
isViewedAsDeprecated()1742 public final boolean isViewedAsDeprecated() {
1743 if ((this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0)
1744 return true;
1745 if (getPackage().isViewedAsDeprecated()) {
1746 this.tagBits |= (getPackage().tagBits & TagBits.AnnotationTerminallyDeprecated);
1747 return true;
1748 }
1749 return false;
1750 }
1751
1752 /**
1753 * Returns the member types of this type sorted by simple name.
1754 */
memberTypes()1755 public ReferenceBinding[] memberTypes() {
1756 return Binding.NO_MEMBER_TYPES;
1757 }
1758
methods()1759 public MethodBinding[] methods() {
1760 return Binding.NO_METHODS;
1761 }
1762
outermostEnclosingType()1763 public final ReferenceBinding outermostEnclosingType() {
1764 ReferenceBinding current = this;
1765 while (true) {
1766 ReferenceBinding last = current;
1767 if ((current = current.enclosingType()) == null)
1768 return last;
1769 }
1770 }
1771
1772 /**
1773 * Answer the source name for the type.
1774 * In the case of member types, as the qualified name from its top level type.
1775 * For example, for a member type N defined inside M & A: "A.M.N".
1776 */
1777 @Override
qualifiedSourceName()1778 public char[] qualifiedSourceName() {
1779 if (isMemberType())
1780 return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
1781 return sourceName();
1782 }
1783
1784 /**
1785 * Answer the receiver's signature.
1786 *
1787 * NOTE: This method should only be used during/after code gen.
1788 */
1789 @Override
readableName()1790 public char[] readableName() /*java.lang.Object, p.X<T> */ {
1791 return readableName(true);
1792 }
readableName(boolean showGenerics)1793 public char[] readableName(boolean showGenerics) /*java.lang.Object, p.X<T> */ {
1794 char[] readableName;
1795 if (isMemberType()) {
1796 readableName = CharOperation.concat(enclosingType().readableName(showGenerics && hasEnclosingInstanceContext()), this.sourceName, '.');
1797 } else {
1798 readableName = CharOperation.concatWith(this.compoundName, '.');
1799 }
1800 if (showGenerics) {
1801 TypeVariableBinding[] typeVars;
1802 if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
1803 StringBuffer nameBuffer = new StringBuffer(10);
1804 nameBuffer.append(readableName).append('<');
1805 for (int i = 0, length = typeVars.length; i < length; i++) {
1806 if (i > 0) nameBuffer.append(',');
1807 nameBuffer.append(typeVars[i].readableName());
1808 }
1809 nameBuffer.append('>');
1810 int nameLength = nameBuffer.length();
1811 readableName = new char[nameLength];
1812 nameBuffer.getChars(0, nameLength, readableName, 0);
1813 }
1814 }
1815 return readableName;
1816 }
1817
appendNullAnnotation(StringBuffer nameBuffer, CompilerOptions options)1818 protected void appendNullAnnotation(StringBuffer nameBuffer, CompilerOptions options) {
1819 if (options.isAnnotationBasedNullAnalysisEnabled) {
1820 if (options.usesNullTypeAnnotations()) {
1821 for (AnnotationBinding annotation : this.typeAnnotations) {
1822 ReferenceBinding annotationType = annotation.getAnnotationType();
1823 if (annotationType.hasNullBit(TypeIds.BitNonNullAnnotation|TypeIds.BitNullableAnnotation)) {
1824 nameBuffer.append('@').append(annotationType.shortReadableName()).append(' ');
1825 }
1826 }
1827 } else {
1828 // restore applied null annotation from tagBits:
1829 if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
1830 char[][] nonNullAnnotationName = options.nonNullAnnotationName;
1831 nameBuffer.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]).append(' ');
1832 }
1833 if ((this.tagBits & TagBits.AnnotationNullable) != 0) {
1834 char[][] nullableAnnotationName = options.nullableAnnotationName;
1835 nameBuffer.append('@').append(nullableAnnotationName[nullableAnnotationName.length-1]).append(' ');
1836 }
1837 }
1838 }
1839 }
1840
retrieveAnnotationHolder(Binding binding, boolean forceInitialization)1841 public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
1842 SimpleLookupTable store = storedAnnotations(forceInitialization, false);
1843 return store == null ? null : (AnnotationHolder) store.get(binding);
1844 }
1845
retrieveAnnotations(Binding binding)1846 AnnotationBinding[] retrieveAnnotations(Binding binding) {
1847 AnnotationHolder holder = retrieveAnnotationHolder(binding, true);
1848 return holder == null ? Binding.NO_ANNOTATIONS : holder.getAnnotations();
1849 }
1850
1851 @Override
setAnnotations(AnnotationBinding[] annotations, boolean forceStore)1852 public void setAnnotations(AnnotationBinding[] annotations, boolean forceStore) {
1853 storeAnnotations(this, annotations, forceStore);
1854 }
setContainerAnnotationType(ReferenceBinding value)1855 public void setContainerAnnotationType(ReferenceBinding value) {
1856 // Leave this to subclasses
1857 }
tagAsHavingDefectiveContainerType()1858 public void tagAsHavingDefectiveContainerType() {
1859 // Leave this to subclasses
1860 }
1861
1862 /**
1863 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#nullAnnotatedReadableName(CompilerOptions,boolean)
1864 */
1865 @Override
nullAnnotatedReadableName(CompilerOptions options, boolean shortNames)1866 public char[] nullAnnotatedReadableName(CompilerOptions options, boolean shortNames) {
1867 if (shortNames)
1868 return nullAnnotatedShortReadableName(options);
1869 return nullAnnotatedReadableName(options);
1870 }
1871
nullAnnotatedReadableName(CompilerOptions options)1872 char[] nullAnnotatedReadableName(CompilerOptions options) {
1873 StringBuffer nameBuffer = new StringBuffer(10);
1874 if (isMemberType()) {
1875 nameBuffer.append(enclosingType().nullAnnotatedReadableName(options, false));
1876 nameBuffer.append('.');
1877 appendNullAnnotation(nameBuffer, options);
1878 nameBuffer.append(this.sourceName);
1879 } else if (this.compoundName != null) {
1880 int i;
1881 int l=this.compoundName.length;
1882 for (i=0; i<l-1; i++) {
1883 nameBuffer.append(this.compoundName[i]);
1884 nameBuffer.append('.');
1885 }
1886 appendNullAnnotation(nameBuffer, options);
1887 nameBuffer.append(this.compoundName[i]);
1888 } else {
1889 // case of TypeVariableBinding with nullAnnotationTagBits:
1890 appendNullAnnotation(nameBuffer, options);
1891 if (this.sourceName != null)
1892 nameBuffer.append(this.sourceName);
1893 else // WildcardBinding, CaptureBinding have no sourceName
1894 nameBuffer.append(this.readableName());
1895 }
1896 TypeBinding [] arguments = typeArguments();
1897 if (arguments != null && arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
1898 nameBuffer.append('<');
1899 for (int i = 0, length = arguments.length; i < length; i++) {
1900 if (i > 0) nameBuffer.append(',');
1901 nameBuffer.append(arguments[i].nullAnnotatedReadableName(options, false));
1902 }
1903 nameBuffer.append('>');
1904 }
1905 int nameLength = nameBuffer.length();
1906 char[] readableName = new char[nameLength];
1907 nameBuffer.getChars(0, nameLength, readableName, 0);
1908 return readableName;
1909 }
1910
nullAnnotatedShortReadableName(CompilerOptions options)1911 char[] nullAnnotatedShortReadableName(CompilerOptions options) {
1912 StringBuffer nameBuffer = new StringBuffer(10);
1913 if (isMemberType()) {
1914 nameBuffer.append(enclosingType().nullAnnotatedReadableName(options, true));
1915 nameBuffer.append('.');
1916 appendNullAnnotation(nameBuffer, options);
1917 nameBuffer.append(this.sourceName);
1918 } else {
1919 appendNullAnnotation(nameBuffer, options);
1920 if (this.sourceName != null)
1921 nameBuffer.append(this.sourceName);
1922 else // WildcardBinding, CaptureBinding have no sourceName
1923 nameBuffer.append(this.shortReadableName());
1924 }
1925 TypeBinding [] arguments = typeArguments();
1926 if (arguments != null && arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
1927 nameBuffer.append('<');
1928 for (int i = 0, length = arguments.length; i < length; i++) {
1929 if (i > 0) nameBuffer.append(',');
1930 nameBuffer.append(arguments[i].nullAnnotatedReadableName(options, true));
1931 }
1932 nameBuffer.append('>');
1933 }
1934 int nameLength = nameBuffer.length();
1935 char[] shortReadableName = new char[nameLength];
1936 nameBuffer.getChars(0, nameLength, shortReadableName, 0);
1937 return shortReadableName;
1938 }
1939
1940 @Override
shortReadableName()1941 public char[] shortReadableName() /*Object*/ {
1942 return shortReadableName(true);
1943 }
shortReadableName(boolean showGenerics)1944 public char[] shortReadableName(boolean showGenerics) /*Object*/ {
1945 char[] shortReadableName;
1946 if (isMemberType()) {
1947 shortReadableName = CharOperation.concat(enclosingType().shortReadableName(showGenerics && hasEnclosingInstanceContext()), this.sourceName, '.');
1948 } else {
1949 shortReadableName = this.sourceName;
1950 }
1951 if (showGenerics) {
1952 TypeVariableBinding[] typeVars;
1953 if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
1954 StringBuffer nameBuffer = new StringBuffer(10);
1955 nameBuffer.append(shortReadableName).append('<');
1956 for (int i = 0, length = typeVars.length; i < length; i++) {
1957 if (i > 0) nameBuffer.append(',');
1958 nameBuffer.append(typeVars[i].shortReadableName());
1959 }
1960 nameBuffer.append('>');
1961 int nameLength = nameBuffer.length();
1962 shortReadableName = new char[nameLength];
1963 nameBuffer.getChars(0, nameLength, shortReadableName, 0);
1964 }
1965 }
1966 return shortReadableName;
1967 }
1968
1969 @Override
signature()1970 public char[] signature() /* Ljava/lang/Object; */ {
1971 if (this.signature != null)
1972 return this.signature;
1973
1974 return this.signature = CharOperation.concat('L', constantPoolName(), ';');
1975 }
1976
1977 @Override
sourceName()1978 public char[] sourceName() {
1979 return this.sourceName;
1980 }
1981
1982 /**
1983 * Perform an upwards type projection as per JLS 4.10.5
1984 * @param scope Relevant scope for evaluating type projection
1985 * @param mentionedTypeVariables Filter for mentioned type variabled
1986 * @returns Upwards type projection of 'this', or null if downwards projection is undefined
1987 */
1988 @Override
upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables)1989 public ReferenceBinding upwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
1990 return this;
1991 }
1992
1993 /**
1994 * Perform a downwards type projection as per JLS 4.10.5
1995 * @param scope Relevant scope for evaluating type projection
1996 * @param mentionedTypeVariables Filter for mentioned type variabled
1997 * @returns Downwards type projection of 'this', or null if downwards projection is undefined
1998 */
1999 @Override
downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables)2000 public ReferenceBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeVariables) {
2001 return this;
2002 }
2003
storeAnnotationHolder(Binding binding, AnnotationHolder holder)2004 void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
2005 if (holder == null) {
2006 SimpleLookupTable store = storedAnnotations(false, false);
2007 if (store != null)
2008 store.removeKey(binding);
2009 } else {
2010 SimpleLookupTable store = storedAnnotations(true, false);
2011 if (store != null)
2012 store.put(binding, holder);
2013 }
2014 }
2015
storeAnnotations(Binding binding, AnnotationBinding[] annotations, boolean forceStore)2016 void storeAnnotations(Binding binding, AnnotationBinding[] annotations, boolean forceStore) {
2017 AnnotationHolder holder = null;
2018 if (annotations == null || annotations.length == 0) {
2019 SimpleLookupTable store = storedAnnotations(false, forceStore);
2020 if (store != null)
2021 holder = (AnnotationHolder) store.get(binding);
2022 if (holder == null) return; // nothing to delete
2023 } else {
2024 SimpleLookupTable store = storedAnnotations(true, forceStore);
2025 if (store == null) return; // not supported
2026 holder = (AnnotationHolder) store.get(binding);
2027 if (holder == null)
2028 holder = new AnnotationHolder();
2029 }
2030 storeAnnotationHolder(binding, holder.setAnnotations(annotations));
2031 }
2032
storedAnnotations(boolean forceInitialize, boolean forceStore)2033 SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) {
2034 return null; // overrride if interested in storing annotations for the receiver, its fields and methods
2035 }
2036
2037 @Override
superclass()2038 public ReferenceBinding superclass() {
2039 return null;
2040 }
2041
2042 @Override
superInterfaces()2043 public ReferenceBinding[] superInterfaces() {
2044 return Binding.NO_SUPERINTERFACES;
2045 }
2046
syntheticEnclosingInstanceTypes()2047 public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
2048 if (isStatic()) return null;
2049 ReferenceBinding enclosingType = enclosingType();
2050 if (enclosingType == null)
2051 return null;
2052 return new ReferenceBinding[] {enclosingType};
2053 }
2054
unResolvedMethods()2055 MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
2056 return methods();
2057 }
2058
unResolvedFields()2059 public FieldBinding[] unResolvedFields() {
2060 return Binding.NO_FIELDS;
2061 }
2062
2063 /*
2064 * If a type - known to be a Closeable - is mentioned in one of our white lists
2065 * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
2066 */
applyCloseableClassWhitelists(CompilerOptions options)2067 protected int applyCloseableClassWhitelists(CompilerOptions options) {
2068 switch (this.compoundName.length) {
2069 case 3:
2070 if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
2071 if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) {
2072 char[] simpleName = this.compoundName[2];
2073 int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length;
2074 for (int i = 0; i < l; i++) {
2075 if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i]))
2076 return TypeIds.BitWrapperCloseable;
2077 }
2078 l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length;
2079 for (int i = 0; i < l; i++) {
2080 if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i]))
2081 return TypeIds.BitResourceFreeCloseable;
2082 }
2083 }
2084 }
2085 break;
2086 case 4:
2087 if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
2088 if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) {
2089 if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) {
2090 char[] simpleName = this.compoundName[3];
2091 int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length;
2092 for (int i = 0; i < l; i++) {
2093 if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i]))
2094 return TypeIds.BitWrapperCloseable;
2095 }
2096 }
2097 }
2098 }
2099 break;
2100 }
2101 int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length;
2102 for (int i = 0; i < l; i++) {
2103 if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i]))
2104 return TypeIds.BitWrapperCloseable;
2105 }
2106 if (options.analyseResourceLeaks) {
2107 ReferenceBinding mySuper = this.superclass();
2108 if (mySuper != null && mySuper.id != TypeIds.T_JavaLangObject) {
2109 if (hasMethodWithNumArgs(TypeConstants.CLOSE, 0))
2110 return 0; // close methods indicates: class may need more closing than super
2111 return mySuper.applyCloseableClassWhitelists(options);
2112 }
2113 }
2114 return 0;
2115 }
2116
hasMethodWithNumArgs(char[] selector, int numArgs)2117 protected boolean hasMethodWithNumArgs(char[] selector, int numArgs) {
2118 for (MethodBinding methodBinding : unResolvedMethods()) {
2119 if (CharOperation.equals(methodBinding.selector, selector)
2120 && methodBinding.parameters.length == numArgs) {
2121 return true;
2122 }
2123 }
2124 return false;
2125 }
2126
2127 /*
2128 * If a type - known to be a Closeable - is mentioned in one of our white lists
2129 * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
2130 */
applyCloseableInterfaceWhitelists()2131 protected int applyCloseableInterfaceWhitelists() {
2132 switch (this.compoundName.length) {
2133 case 4:
2134 for (int i=0; i<2; i++)
2135 if (!CharOperation.equals(this.compoundName[i], TypeConstants.JAVA_UTIL_STREAM[i]))
2136 return 0;
2137 for (char[] streamName : TypeConstants.RESOURCE_FREE_CLOSEABLE_J_U_STREAMS)
2138 if (CharOperation.equals(this.compoundName[3], streamName))
2139 return TypeIds.BitResourceFreeCloseable;
2140 break;
2141 }
2142 return 0;
2143 }
2144
getInterfaceAbstractContracts(Scope scope, boolean replaceWildcards, boolean filterDefaultMethods)2145 protected MethodBinding [] getInterfaceAbstractContracts(Scope scope, boolean replaceWildcards, boolean filterDefaultMethods) throws InvalidInputException {
2146
2147 if (!isInterface() || !isValidBinding()) {
2148 throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
2149 }
2150
2151 MethodBinding [] methods = methods();
2152 MethodBinding [] contracts = new MethodBinding[0];
2153 int contractsCount = 0;
2154 int contractsLength = 0;
2155
2156 ReferenceBinding [] superInterfaces = superInterfaces();
2157 for (int i = 0, length = superInterfaces.length; i < length; i++) {
2158 // filterDefaultMethods=false => keep default methods needed to filter out any abstract methods they may override:
2159 MethodBinding [] superInterfaceContracts = superInterfaces[i].getInterfaceAbstractContracts(scope, replaceWildcards, false);
2160 final int superInterfaceContractsLength = superInterfaceContracts == null ? 0 : superInterfaceContracts.length;
2161 if (superInterfaceContractsLength == 0) continue;
2162 if (contractsLength < contractsCount + superInterfaceContractsLength) {
2163 System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount);
2164 }
2165 System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount, superInterfaceContractsLength);
2166 contractsCount += superInterfaceContractsLength;
2167 }
2168
2169 LookupEnvironment environment = scope.environment();
2170 for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) {
2171 final MethodBinding method = methods[i];
2172 if (method == null || method.isStatic() || method.redeclaresPublicObjectMethod(scope) || method.isPrivate())
2173 continue;
2174 if (!method.isValidBinding())
2175 throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
2176 for (int j = 0; j < contractsCount;) {
2177 if ( contracts[j] != null && MethodVerifier.doesMethodOverride(method, contracts[j], environment)) {
2178 contractsCount--;
2179 // abstract method from super type overridden by present interface ==> contracts[j] = null;
2180 if (j < contractsCount) {
2181 System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
2182 continue;
2183 }
2184 }
2185 j++;
2186 }
2187 if (filterDefaultMethods && method.isDefaultMethod())
2188 continue; // skip default method itself
2189 if (contractsCount == contractsLength) {
2190 System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount);
2191 }
2192 if(environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
2193 ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(method, scope);
2194 }
2195 contracts[contractsCount++] = method;
2196 }
2197 // check mutual overriding of inherited methods (i.e., not from current type):
2198 for (int i = 0; i < contractsCount; i++) {
2199 MethodBinding contractI = contracts[i];
2200 if (TypeBinding.equalsEquals(contractI.declaringClass, this))
2201 continue;
2202 for (int j = 0; j < contractsCount; j++) {
2203 MethodBinding contractJ = contracts[j];
2204 if (i == j || TypeBinding.equalsEquals(contractJ.declaringClass, this))
2205 continue;
2206 if (contractI == contractJ || MethodVerifier.doesMethodOverride(contractI, contractJ, environment)) {
2207 contractsCount--;
2208 // abstract method from one super type overridden by other super interface ==> contracts[j] = null;
2209 if (j < contractsCount) {
2210 System.arraycopy(contracts, j+1, contracts, j, contractsCount - j);
2211 }
2212 j--;
2213 if (j < i)
2214 i--;
2215 continue;
2216 }
2217 }
2218 if (filterDefaultMethods && contractI.isDefaultMethod()) {
2219 contractsCount--;
2220 // remove default method after it has eliminated any matching abstract methods from contracts
2221 if (i < contractsCount) {
2222 System.arraycopy(contracts, i+1, contracts, i, contractsCount - i);
2223 }
2224 i--;
2225 }
2226 }
2227 if (contractsCount < contractsLength) {
2228 System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsCount], 0, contractsCount);
2229 }
2230 return contracts;
2231 }
2232 @Override
getSingleAbstractMethod(Scope scope, boolean replaceWildcards)2233 public MethodBinding getSingleAbstractMethod(Scope scope, boolean replaceWildcards) {
2234
2235 int index = replaceWildcards ? 0 : 1;
2236 if (this.singleAbstractMethod != null) {
2237 if (this.singleAbstractMethod[index] != null)
2238 return this.singleAbstractMethod[index];
2239 } else {
2240 this.singleAbstractMethod = new MethodBinding[2];
2241 }
2242
2243 if (this.compoundName != null)
2244 scope.compilationUnitScope().recordQualifiedReference(this.compoundName);
2245 MethodBinding[] methods = null;
2246 try {
2247 methods = getInterfaceAbstractContracts(scope, replaceWildcards, true);
2248 if (methods == null || methods.length == 0)
2249 return this.singleAbstractMethod[index] = samProblemBinding;
2250 int contractParameterLength = 0;
2251 char [] contractSelector = null;
2252 for (int i = 0, length = methods.length; i < length; i++) {
2253 MethodBinding method = methods[i];
2254 if (method == null) continue;
2255 if (contractSelector == null) {
2256 contractSelector = method.selector;
2257 contractParameterLength = method.parameters == null ? 0 : method.parameters.length;
2258 } else {
2259 int methodParameterLength = method.parameters == null ? 0 : method.parameters.length;
2260 if (methodParameterLength != contractParameterLength || !CharOperation.equals(method.selector, contractSelector))
2261 return this.singleAbstractMethod[index] = samProblemBinding;
2262 }
2263 }
2264 } catch (InvalidInputException e) {
2265 return this.singleAbstractMethod[index] = samProblemBinding;
2266 }
2267 if (methods.length == 1)
2268 return this.singleAbstractMethod[index] = methods[0];
2269
2270 final LookupEnvironment environment = scope.environment();
2271 boolean genericMethodSeen = false;
2272 int length = methods.length;
2273 boolean analyseNullAnnotations = environment.globalOptions.isAnnotationBasedNullAnalysisEnabled;
2274
2275 next:for (int i = length - 1; i >= 0; --i) {
2276 MethodBinding method = methods[i], otherMethod = null;
2277 if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
2278 genericMethodSeen = true;
2279 TypeBinding returnType = method.returnType;
2280 TypeBinding[] parameters = method.parameters;
2281 for (int j = 0; j < length; j++) {
2282 if (i == j) continue;
2283 otherMethod = methods[j];
2284 if (otherMethod.typeVariables != Binding.NO_TYPE_VARIABLES)
2285 genericMethodSeen = true;
2286
2287 if (genericMethodSeen) { // adapt type parameters.
2288 otherMethod = MethodVerifier.computeSubstituteMethod(otherMethod, method, environment);
2289 if (otherMethod == null)
2290 continue next;
2291 }
2292 if (!MethodVerifier.isSubstituteParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment))
2293 continue next;
2294 if (analyseNullAnnotations) {
2295 returnType = NullAnnotationMatching.strongerType(returnType, otherMethod.returnType, environment);
2296 parameters = NullAnnotationMatching.weakerTypes(parameters, otherMethod.parameters, environment);
2297 }
2298 }
2299 // If we reach here, we found a method that is override equivalent with every other method and is also return type substitutable. Compute kosher exceptions now ...
2300 ReferenceBinding [] exceptions = new ReferenceBinding[0];
2301 int exceptionsCount = 0, exceptionsLength = 0;
2302 final MethodBinding theAbstractMethod = method;
2303 boolean shouldEraseThrows = theAbstractMethod.typeVariables == Binding.NO_TYPE_VARIABLES && genericMethodSeen;
2304 boolean shouldAdaptThrows = theAbstractMethod.typeVariables != Binding.NO_TYPE_VARIABLES;
2305 final int typeVariableLength = theAbstractMethod.typeVariables.length;
2306
2307 none:for (i = 0; i < length; i++) {
2308 method = methods[i];
2309 ReferenceBinding[] methodThrownExceptions = method.thrownExceptions;
2310 int methodExceptionsLength = methodThrownExceptions == null ? 0: methodThrownExceptions.length;
2311 if (methodExceptionsLength == 0) break none;
2312 if (shouldAdaptThrows && method != theAbstractMethod) {
2313 System.arraycopy(methodThrownExceptions, 0, methodThrownExceptions = new ReferenceBinding[methodExceptionsLength], 0, methodExceptionsLength);
2314 for (int tv = 0; tv < typeVariableLength; tv++) {
2315 if (methodThrownExceptions[tv] instanceof TypeVariableBinding) {
2316 methodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
2317 }
2318 }
2319 }
2320 nextException: for (int j = 0; j < methodExceptionsLength; j++) {
2321 ReferenceBinding methodException = methodThrownExceptions[j];
2322 if (shouldEraseThrows)
2323 methodException = (ReferenceBinding) methodException.erasure();
2324 nextMethod: for (int k = 0; k < length; k++) {
2325 if (i == k) continue;
2326 otherMethod = methods[k];
2327 ReferenceBinding[] otherMethodThrownExceptions = otherMethod.thrownExceptions;
2328 int otherMethodExceptionsLength = otherMethodThrownExceptions == null ? 0 : otherMethodThrownExceptions.length;
2329 if (otherMethodExceptionsLength == 0) break none;
2330 if (shouldAdaptThrows && otherMethod != theAbstractMethod) {
2331 System.arraycopy(otherMethodThrownExceptions,
2332 0,
2333 otherMethodThrownExceptions = new ReferenceBinding[otherMethodExceptionsLength],
2334 0,
2335 otherMethodExceptionsLength);
2336 for (int tv = 0; tv < typeVariableLength; tv++) {
2337 if (otherMethodThrownExceptions[tv] instanceof TypeVariableBinding) {
2338 otherMethodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
2339 }
2340 }
2341 }
2342 for (int l = 0; l < otherMethodExceptionsLength; l++) {
2343 ReferenceBinding otherException = otherMethodThrownExceptions[l];
2344 if (shouldEraseThrows)
2345 otherException = (ReferenceBinding) otherException.erasure();
2346 if (methodException.isCompatibleWith(otherException))
2347 continue nextMethod;
2348 }
2349 continue nextException;
2350 }
2351 // If we reach here, method exception or its super type is covered by every throws clause.
2352 if (exceptionsCount == exceptionsLength) {
2353 System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsLength += 16], 0, exceptionsCount);
2354 }
2355 exceptions[exceptionsCount++] = methodException;
2356 }
2357 }
2358 if (exceptionsCount != exceptionsLength) {
2359 System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsCount], 0, exceptionsCount);
2360 }
2361 this.singleAbstractMethod[index] = new MethodBinding(theAbstractMethod.modifiers | ClassFileConstants.AccSynthetic,
2362 theAbstractMethod.selector,
2363 returnType,
2364 parameters,
2365 exceptions,
2366 theAbstractMethod.declaringClass);
2367 this.singleAbstractMethod[index].typeVariables = theAbstractMethod.typeVariables;
2368 return this.singleAbstractMethod[index];
2369 }
2370 return this.singleAbstractMethod[index] = samProblemBinding;
2371 }
2372
2373 // See JLS 4.9 bullet 1
isConsistentIntersection(TypeBinding[] intersectingTypes)2374 public static boolean isConsistentIntersection(TypeBinding[] intersectingTypes) {
2375 TypeBinding[] ci = new TypeBinding[intersectingTypes.length];
2376 for (int i = 0; i < ci.length; i++) {
2377 TypeBinding current = intersectingTypes[i];
2378 ci[i] = (current.isClass() || current.isArrayType())
2379 ? current : current.superclass();
2380 }
2381 TypeBinding mostSpecific = ci[0];
2382 for (int i = 1; i < ci.length; i++) {
2383 TypeBinding current = ci[i];
2384 // when invoked during type inference we only want to check inconsistency among real types:
2385 if (current.isTypeVariable() || current.isWildcard() || !current.isProperType(true))
2386 continue;
2387 if (mostSpecific.isSubtypeOf(current, false))
2388 continue;
2389 else if (current.isSubtypeOf(mostSpecific, false))
2390 mostSpecific = current;
2391 else
2392 return false;
2393 }
2394 return true;
2395 }
module()2396 public ModuleBinding module() {
2397 if (this.fPackage != null)
2398 return this.fPackage.enclosingModule;
2399 return null;
2400 }
2401
hasEnclosingInstanceContext()2402 public boolean hasEnclosingInstanceContext() {
2403 if (isMemberType() && !isStatic())
2404 return true;
2405 MethodBinding enclosingMethod = enclosingMethod();
2406 if (enclosingMethod != null)
2407 return !enclosingMethod.isStatic();
2408 return false;
2409 }
2410 }
2411