1 11 package org.eclipse.jdt.internal.eval; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 15 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 16 import org.eclipse.jdt.internal.compiler.lookup.Binding; 17 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 18 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 19 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite; 20 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 21 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; 22 import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; 23 import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; 24 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; 25 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; 26 import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; 27 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 28 import org.eclipse.jdt.internal.compiler.lookup.Scope; 29 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 30 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 31 import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; 32 33 37 public class CodeSnippetScope extends BlockScope { 38 43 protected CodeSnippetScope(int kind, Scope parent) { 44 super(kind, parent); 45 } 46 50 public CodeSnippetScope(BlockScope parent) { 51 super(parent); 52 } 53 58 public CodeSnippetScope(BlockScope parent, int variableCount) { 59 super(parent, variableCount); 60 } 61 67 68 public final boolean canBeSeenByForCodeSnippet(FieldBinding fieldBinding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { 69 if (fieldBinding.isPublic()) return true; 70 71 ReferenceBinding invocationType = (ReferenceBinding) receiverType; 72 if (invocationType == fieldBinding.declaringClass) return true; 73 74 if (fieldBinding.isProtected()) { 75 if (invocationType == fieldBinding.declaringClass) return true; 80 if (invocationType.fPackage == fieldBinding.declaringClass.fPackage) return true; 81 if (fieldBinding.declaringClass.isSuperclassOf(invocationType)) { 82 if (invocationSite.isSuperAccess()) return true; 83 if (receiverType instanceof ArrayBinding) 85 return false; 86 if (invocationType.isSuperclassOf((ReferenceBinding) receiverType)) 87 return true; 88 if (fieldBinding.isStatic()) 89 return true; } 91 return false; 92 } 93 94 if (fieldBinding.isPrivate()) { 95 if (receiverType != fieldBinding.declaringClass) return false; 98 99 if (invocationType != fieldBinding.declaringClass) { 100 ReferenceBinding outerInvocationType = invocationType; 101 ReferenceBinding temp = outerInvocationType.enclosingType(); 102 while (temp != null) { 103 outerInvocationType = temp; 104 temp = temp.enclosingType(); 105 } 106 107 ReferenceBinding outerDeclaringClass = fieldBinding.declaringClass; 108 temp = outerDeclaringClass.enclosingType(); 109 while (temp != null) { 110 outerDeclaringClass = temp; 111 temp = temp.enclosingType(); 112 } 113 if (outerInvocationType != outerDeclaringClass) return false; 114 } 115 return true; 116 } 117 118 if (invocationType.fPackage != fieldBinding.declaringClass.fPackage) return false; 120 121 if (receiverType instanceof ArrayBinding) 123 return false; 124 ReferenceBinding type = (ReferenceBinding) receiverType; 125 PackageBinding declaringPackage = fieldBinding.declaringClass.fPackage; 126 do { 127 if (fieldBinding.declaringClass == type) return true; 128 if (declaringPackage != type.fPackage) return false; 129 } while ((type = type.superclass()) != null); 130 return false; 131 } 132 138 public final boolean canBeSeenByForCodeSnippet(MethodBinding methodBinding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { 139 if (methodBinding.isPublic()) return true; 140 141 ReferenceBinding invocationType = (ReferenceBinding) receiverType; 142 if (invocationType == methodBinding.declaringClass && invocationType == receiverType) return true; 143 144 if (methodBinding.isProtected()) { 145 if (invocationType == methodBinding.declaringClass) return true; 150 if (invocationType.fPackage == methodBinding.declaringClass.fPackage) return true; 151 if (methodBinding.declaringClass.isSuperclassOf(invocationType)) { 152 if (invocationSite.isSuperAccess()) return true; 153 if (receiverType instanceof ArrayBinding) 155 return false; 156 if (invocationType.isSuperclassOf((ReferenceBinding) receiverType)) 157 return true; 158 if (methodBinding.isStatic()) 159 return true; } 161 return false; 162 } 163 164 if (methodBinding.isPrivate()) { 165 if (receiverType != methodBinding.declaringClass) return false; 168 169 if (invocationType != methodBinding.declaringClass) { 170 ReferenceBinding outerInvocationType = invocationType; 171 ReferenceBinding temp = outerInvocationType.enclosingType(); 172 while (temp != null) { 173 outerInvocationType = temp; 174 temp = temp.enclosingType(); 175 } 176 177 ReferenceBinding outerDeclaringClass = methodBinding.declaringClass; 178 temp = outerDeclaringClass.enclosingType(); 179 while (temp != null) { 180 outerDeclaringClass = temp; 181 temp = temp.enclosingType(); 182 } 183 if (outerInvocationType != outerDeclaringClass) return false; 184 } 185 return true; 186 } 187 188 if (invocationType.fPackage != methodBinding.declaringClass.fPackage) return false; 190 191 if (receiverType instanceof ArrayBinding) 193 return false; 194 ReferenceBinding type = (ReferenceBinding) receiverType; 195 PackageBinding declaringPackage = methodBinding.declaringClass.fPackage; 196 do { 197 if (methodBinding.declaringClass == type) return true; 198 if (declaringPackage != type.fPackage) return false; 199 } while ((type = type.superclass()) != null); 200 return false; 201 } 202 208 209 public final boolean canBeSeenByForCodeSnippet(ReferenceBinding referenceBinding, ReferenceBinding receiverType) { 210 if (referenceBinding.isPublic()) return true; 211 212 if (receiverType == referenceBinding) return true; 213 214 if (referenceBinding.isProtected()) { 215 return receiverType.fPackage == referenceBinding.fPackage 218 || referenceBinding.isSuperclassOf(receiverType) 219 || referenceBinding.enclosingType().isSuperclassOf(receiverType); } 221 222 if (referenceBinding.isPrivate()) { 223 ReferenceBinding outerInvocationType = receiverType; 226 ReferenceBinding temp = outerInvocationType.enclosingType(); 227 while (temp != null) { 228 outerInvocationType = temp; 229 temp = temp.enclosingType(); 230 } 231 232 ReferenceBinding outerDeclaringClass = referenceBinding; 233 temp = outerDeclaringClass.enclosingType(); 234 while (temp != null) { 235 outerDeclaringClass = temp; 236 temp = temp.enclosingType(); 237 } 238 return outerInvocationType == outerDeclaringClass; 239 } 240 241 return receiverType.fPackage == referenceBinding.fPackage; 243 } 244 public MethodBinding findExactMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { 246 MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, null); 247 if (exactMethod != null){ 248 if (receiverType.isInterface() || canBeSeenByForCodeSnippet(exactMethod, receiverType, invocationSite, this)) 249 return exactMethod; 250 } 251 return null; 252 } 253 255 264 265 public FieldBinding findFieldForCodeSnippet(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) { 266 if (receiverType.isBaseType()) 267 return null; 268 if (receiverType.isArrayType()) { 269 TypeBinding leafType = receiverType.leafComponentType(); 270 if (leafType instanceof ReferenceBinding) 271 if (!((ReferenceBinding)leafType).canBeSeenBy(this)) { 272 return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ProblemReasons.ReceiverTypeNotVisible); 273 } 274 if (CharOperation.equals(fieldName, LENGTH)) 275 return ArrayBinding.ArrayLength; 276 return null; 277 } 278 279 ReferenceBinding currentType = (ReferenceBinding) receiverType; 280 if (!currentType.canBeSeenBy(this)) 281 return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.ReceiverTypeNotVisible); 282 283 FieldBinding field = currentType.getField(fieldName, true ); 284 if (field != null) { 285 if (canBeSeenByForCodeSnippet(field, currentType, invocationSite, this)) 286 return field; 287 else 288 return new ProblemFieldBinding(field , field.declaringClass, fieldName, ProblemReasons.NotVisible); 289 } 290 291 ReferenceBinding[][] interfacesToVisit = null; 293 int lastPosition = -1; 294 FieldBinding visibleField = null; 295 boolean keepLooking = true; 296 boolean notVisible = false; while (keepLooking) { 298 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 299 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 300 if (interfacesToVisit == null) 301 interfacesToVisit = new ReferenceBinding[5][]; 302 if (++lastPosition == interfacesToVisit.length) 303 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); 304 interfacesToVisit[lastPosition] = itsInterfaces; 305 } 306 if ((currentType = currentType.superclass()) == null) 307 break; 308 309 if ((field = currentType.getField(fieldName, true )) != null) { 310 keepLooking = false; 311 if (canBeSeenByForCodeSnippet(field, receiverType, invocationSite, this)) { 312 if (visibleField == null) 313 visibleField = field; 314 else 315 return new ProblemFieldBinding(visibleField, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous); 316 } else { 317 notVisible = true; 318 } 319 } 320 } 321 322 if (interfacesToVisit != null) { 324 ProblemFieldBinding ambiguous = null; 325 org.eclipse.jdt.internal.compiler.util.SimpleSet interfacesSeen = new org.eclipse.jdt.internal.compiler.util.SimpleSet(lastPosition * 2); 326 done : for (int i = 0; i <= lastPosition; i++) { 327 ReferenceBinding[] interfaces = interfacesToVisit[i]; 328 for (int j = 0, length = interfaces.length; j < length; j++) { 329 ReferenceBinding anInterface = interfaces[j]; 330 if (interfacesSeen.addIfNotIncluded(anInterface) == anInterface) { 331 if ((field = anInterface.getField(fieldName, true )) != null) { 333 if (visibleField == null) { 334 visibleField = field; 335 } else { 336 ambiguous = new ProblemFieldBinding(visibleField, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous); 337 break done; 338 } 339 } else { 340 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 341 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 342 if (++lastPosition == interfacesToVisit.length) 343 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition); 344 interfacesToVisit[lastPosition] = itsInterfaces; 345 } 346 } 347 } 348 } 349 } 350 if (ambiguous != null) return ambiguous; 351 } 352 353 if (visibleField != null) 354 return visibleField; 355 if (notVisible) 356 return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.NotVisible); 357 return null; 358 } 359 public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { 361 MethodBinding methodBinding = super.findMethod(receiverType, selector, argumentTypes, invocationSite); 362 if (methodBinding != null && methodBinding.isValidBinding()) 363 if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) 364 return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible); 365 return methodBinding; 366 } 367 368 public MethodBinding findMethodForArray(ArrayBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { 370 ReferenceBinding object = getJavaLangObject(); 371 MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes, null); 372 if (methodBinding != null) { 373 if (argumentTypes == Binding.NO_PARAMETERS && CharOperation.equals(selector, CLONE)) 375 return new MethodBinding((methodBinding.modifiers & ~ClassFileConstants.AccProtected) | ClassFileConstants.AccPublic, CLONE, methodBinding.returnType, argumentTypes, null, object); 376 if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) 377 return methodBinding; 378 } 379 380 methodBinding = findMethod(object, selector, argumentTypes, invocationSite); 382 if (methodBinding == null) 383 return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound); 384 if (methodBinding.isValidBinding()) { 385 MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite); 386 if (compatibleMethod == null) 387 return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotFound); 388 methodBinding = compatibleMethod; 389 if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) 390 return new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, ProblemReasons.NotVisible); 391 } 392 return methodBinding; 393 } 394 425 426 public Binding getBinding(char[][] compoundName, int mask, InvocationSite invocationSite, ReferenceBinding receiverType) { 427 Binding binding = getBinding(compoundName[0], mask | Binding.TYPE | Binding.PACKAGE, invocationSite, true ); 428 invocationSite.setFieldIndex(1); 429 if (!binding.isValidBinding() || binding instanceof VariableBinding) 430 return binding; 431 432 int length = compoundName.length; 433 int currentIndex = 1; 434 foundType: if (binding instanceof PackageBinding) { 435 PackageBinding packageBinding = (PackageBinding) binding; 436 437 while (currentIndex < length) { 438 binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); 439 invocationSite.setFieldIndex(currentIndex); 440 if (binding == null) { 441 if (currentIndex == length) return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, ProblemReasons.NotFound); 443 else 444 return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NotFound); 445 } 446 if (binding instanceof ReferenceBinding) { 447 if (!binding.isValidBinding()) 448 return new ProblemReferenceBinding( 449 CharOperation.subarray(compoundName, 0, currentIndex), 450 ((ReferenceBinding)binding).closestMatch(), 451 binding.problemId()); 452 if (!this.canBeSeenByForCodeSnippet((ReferenceBinding) binding, receiverType)) 453 return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), (ReferenceBinding) binding, ProblemReasons.NotVisible); 454 break foundType; 455 } 456 packageBinding = (PackageBinding) binding; 457 } 458 459 return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, ProblemReasons.NotFound); 461 } 462 463 while (currentIndex < length) { 465 ReferenceBinding typeBinding = (ReferenceBinding) binding; 466 char[] nextName = compoundName[currentIndex++]; 467 invocationSite.setFieldIndex(currentIndex); 468 if ((binding = findFieldForCodeSnippet(typeBinding, nextName, invocationSite)) != null) { 469 if (!binding.isValidBinding()) { 470 return new ProblemFieldBinding( 471 (FieldBinding)binding, 472 ((FieldBinding)binding).declaringClass, 473 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 474 binding.problemId()); 475 } 476 break; } 478 if ((binding = findMemberType(nextName, typeBinding)) == null) 479 return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), typeBinding, ProblemReasons.NotFound); 480 if (!binding.isValidBinding()) 481 return new ProblemReferenceBinding( 482 CharOperation.subarray(compoundName, 0, currentIndex), 483 ((ReferenceBinding)binding).closestMatch(), 484 binding.problemId()); 485 } 486 487 if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) { FieldBinding field = (FieldBinding) binding; 489 if (!field.isStatic()) { 490 return new ProblemFieldBinding( 491 field, 492 field.declaringClass, 493 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 494 ProblemReasons.NonStaticReferenceInStaticContext); 495 } 496 return binding; 497 } 498 if ((mask & Binding.TYPE) != 0 && (binding instanceof ReferenceBinding)) { return binding; 500 } 501 502 return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NotFound); 504 } 505 514 515 public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) { 516 MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes); 517 if (methodBinding != null) { 518 if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) { 519 return methodBinding; 520 } 521 } 522 MethodBinding[] methods = receiverType.getMethods(TypeConstants.INIT); 523 if (methods == Binding.NO_METHODS) { 524 return new ProblemMethodBinding(TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound); 525 } 526 MethodBinding[] compatible = new MethodBinding[methods.length]; 527 int compatibleIndex = 0; 528 for (int i = 0, length = methods.length; i < length; i++) { 529 MethodBinding compatibleMethod = computeCompatibleMethod(methods[i], argumentTypes, invocationSite); 530 if (compatibleMethod != null) 531 compatible[compatibleIndex++] = compatibleMethod; 532 } 533 if (compatibleIndex == 0) 534 return new ProblemMethodBinding(TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound); 536 MethodBinding[] visible = new MethodBinding[compatibleIndex]; 537 int visibleIndex = 0; 538 for (int i = 0; i < compatibleIndex; i++) { 539 MethodBinding method = compatible[i]; 540 if (canBeSeenByForCodeSnippet(method, receiverType, invocationSite, this)) { 541 visible[visibleIndex++] = method; 542 } 543 } 544 if (visibleIndex == 1) { 545 return visible[0]; 546 } 547 if (visibleIndex == 0) { 548 return new ProblemMethodBinding(compatible[0], TypeConstants.INIT, compatible[0].parameters, ProblemReasons.NotVisible); 549 } 550 return mostSpecificClassMethodBinding(visible, visibleIndex, invocationSite); 551 } 552 563 564 public FieldBinding getFieldForCodeSnippet(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) { 565 FieldBinding field = findFieldForCodeSnippet(receiverType, fieldName, invocationSite); 566 if (field == null) 567 return new ProblemFieldBinding(receiverType instanceof ReferenceBinding ? (ReferenceBinding) receiverType : null, fieldName, ProblemReasons.NotFound); 568 else 569 return field; 570 } 571 584 585 public MethodBinding getImplicitMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) { 586 MethodBinding methodBinding = findExactMethod(receiverType, selector, argumentTypes, invocationSite); 588 if (methodBinding == null) 589 methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite); 590 if (methodBinding != null) { if (methodBinding.isValidBinding()) 592 if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) 593 return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible); 594 return methodBinding; 595 } 596 return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound); 597 } 598 } 599 | Popular Tags |