1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import org.eclipse.jdt.internal.compiler.ast.*; 14 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 15 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 16 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 17 import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; 18 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; 19 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 20 21 26 public class MethodScope extends BlockScope { 27 28 public ReferenceContext referenceContext; 29 public boolean isStatic; 31 public boolean isConstructorCall = false; 33 public FieldBinding initializedField; public int lastVisibleFieldID = -1; 37 public int analysisIndex; public boolean isPropagatingInnerClassEmulation; 40 41 public int lastIndex = 0; 43 public long[] definiteInits = new long[4]; 44 public long[][] extraDefiniteInits = new long[4][]; 45 46 public boolean insideTypeAnnotation = false; 48 49 public SyntheticArgumentBinding[] extraSyntheticArguments; 51 52 public MethodScope(ClassScope parent, ReferenceContext context, boolean isStatic) { 53 54 super(METHOD_SCOPE, parent); 55 locals = new LocalVariableBinding[5]; 56 this.referenceContext = context; 57 this.isStatic = isStatic; 58 this.startIndex = 0; 59 } 60 61 63 private void checkAndSetModifiersForConstructor(MethodBinding methodBinding) { 64 65 int modifiers = methodBinding.modifiers; 66 final ReferenceBinding declaringClass = methodBinding.declaringClass; 67 if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0) 68 problemReporter().duplicateModifierForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext); 69 70 if ((((ConstructorDeclaration) referenceContext).bits & ASTNode.IsDefaultConstructor) != 0) { 71 final int DECLARING_FLAGS = ClassFileConstants.AccEnum|ClassFileConstants.AccPublic|ClassFileConstants.AccProtected; 73 final int VISIBILITY_FLAGS = ClassFileConstants.AccPrivate|ClassFileConstants.AccPublic|ClassFileConstants.AccProtected; 74 int flags; 75 if ((flags = declaringClass.modifiers & DECLARING_FLAGS) != 0) { 76 if ((flags & ClassFileConstants.AccEnum) != 0) { 77 modifiers &= ~VISIBILITY_FLAGS; 78 modifiers |= ClassFileConstants.AccPrivate; } else { 80 modifiers &= ~VISIBILITY_FLAGS; 81 modifiers |= flags; } 83 } 84 } 85 86 int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag; 88 89 final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStrictfp); 91 if (declaringClass.isEnum() && (((ConstructorDeclaration) referenceContext).bits & ASTNode.IsDefaultConstructor) == 0) { 92 final int UNEXPECTED_ENUM_CONSTR_MODIFIERS = ~(ClassFileConstants.AccPrivate | ClassFileConstants.AccStrictfp); 93 if ((realModifiers & UNEXPECTED_ENUM_CONSTR_MODIFIERS) != 0) { 94 problemReporter().illegalModifierForEnumConstructor((AbstractMethodDeclaration) referenceContext); 95 modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_ENUM_CONSTR_MODIFIERS; 96 } else if ((((AbstractMethodDeclaration) referenceContext).modifiers & ClassFileConstants.AccStrictfp) != 0) { 97 problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext); 99 } 100 modifiers |= ClassFileConstants.AccPrivate; } else if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) { 102 problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext); 103 modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_MODIFIERS; 104 } else if ((((AbstractMethodDeclaration) referenceContext).modifiers & ClassFileConstants.AccStrictfp) != 0) { 105 problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext); 107 } 108 109 int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate); 111 if ((accessorBits & (accessorBits - 1)) != 0) { 112 problemReporter().illegalVisibilityModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext); 113 114 if ((accessorBits & ClassFileConstants.AccPublic) != 0) { 116 if ((accessorBits & ClassFileConstants.AccProtected) != 0) 117 modifiers &= ~ClassFileConstants.AccProtected; 118 if ((accessorBits & ClassFileConstants.AccPrivate) != 0) 119 modifiers &= ~ClassFileConstants.AccPrivate; 120 } else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) { 121 modifiers &= ~ClassFileConstants.AccPrivate; 122 } 123 } 124 125 129 methodBinding.modifiers = modifiers; 130 } 131 132 134 private void checkAndSetModifiersForMethod(MethodBinding methodBinding) { 135 136 int modifiers = methodBinding.modifiers; 137 final ReferenceBinding declaringClass = methodBinding.declaringClass; 138 if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0) 139 problemReporter().duplicateModifierForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext); 140 141 int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag; 143 144 if (declaringClass.isInterface()) { 146 if ((realModifiers & ~(ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract)) != 0) { 147 if ((declaringClass.modifiers & ClassFileConstants.AccAnnotation) != 0) 148 problemReporter().illegalModifierForAnnotationMember((AbstractMethodDeclaration) referenceContext); 149 else 150 problemReporter().illegalModifierForInterfaceMethod((AbstractMethodDeclaration) referenceContext); 151 } 152 return; 153 } 154 155 final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected 157 | ClassFileConstants.AccAbstract | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccSynchronized | ClassFileConstants.AccNative | ClassFileConstants.AccStrictfp); 158 if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) { 159 problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext); 160 modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_MODIFIERS; 161 } 162 163 int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate); 165 if ((accessorBits & (accessorBits - 1)) != 0) { 166 problemReporter().illegalVisibilityModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext); 167 168 if ((accessorBits & ClassFileConstants.AccPublic) != 0) { 170 if ((accessorBits & ClassFileConstants.AccProtected) != 0) 171 modifiers &= ~ClassFileConstants.AccProtected; 172 if ((accessorBits & ClassFileConstants.AccPrivate) != 0) 173 modifiers &= ~ClassFileConstants.AccPrivate; 174 } else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) { 175 modifiers &= ~ClassFileConstants.AccPrivate; 176 } 177 } 178 179 if ((modifiers & ClassFileConstants.AccAbstract) != 0) { 181 int incompatibleWithAbstract = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccSynchronized | ClassFileConstants.AccNative | ClassFileConstants.AccStrictfp; 182 if ((modifiers & incompatibleWithAbstract) != 0) 183 problemReporter().illegalAbstractModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext); 184 if (!methodBinding.declaringClass.isAbstract()) 185 problemReporter().abstractMethodInAbstractClass((SourceTypeBinding) declaringClass, (AbstractMethodDeclaration) referenceContext); 186 } 187 188 193 if ((modifiers & ClassFileConstants.AccNative) != 0 && (modifiers & ClassFileConstants.AccStrictfp) != 0) 195 problemReporter().nativeMethodsCannotBeStrictfp(declaringClass, (AbstractMethodDeclaration) referenceContext); 196 197 if (((realModifiers & ClassFileConstants.AccStatic) != 0) && declaringClass.isNestedType() && !declaringClass.isStatic()) 199 problemReporter().unexpectedStaticModifierForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext); 200 201 methodBinding.modifiers = modifiers; 202 } 203 204 209 public void computeLocalVariablePositions(int initOffset, CodeStream codeStream) { 210 211 boolean isReportingUnusedArgument = false; 212 213 if (referenceContext instanceof AbstractMethodDeclaration) { 214 AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration)referenceContext; 215 MethodBinding method = methodDecl.binding; 216 if (!(method.isAbstract() 217 || (method.isImplementing() && !compilerOptions().reportUnusedParameterWhenImplementingAbstract) 218 || (method.isOverriding() && !method.isImplementing() && !compilerOptions().reportUnusedParameterWhenOverridingConcrete) 219 || method.isMain())) { 220 isReportingUnusedArgument = true; 221 } 222 } 223 this.offset = initOffset; 224 this.maxOffset = initOffset; 225 226 int ilocal = 0, maxLocals = this.localIndex; 228 while (ilocal < maxLocals) { 229 LocalVariableBinding local = locals[ilocal]; 230 if (local == null || ((local.tagBits & TagBits.IsArgument) == 0)) break; 232 if (isReportingUnusedArgument 234 && local.useFlag == LocalVariableBinding.UNUSED 235 && ((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { this.problemReporter().unusedArgument(local.declaration); 237 } 238 239 codeStream.record(local); 241 242 local.resolvedPosition = this.offset; 244 245 if ((local.type == TypeBinding.LONG) || (local.type == TypeBinding.DOUBLE)) { 246 this.offset += 2; 247 } else { 248 this.offset++; 249 } 250 if (this.offset > 0xFF) { this.problemReporter().noMoreAvailableSpaceForArgument(local, local.declaration); 253 } 254 ilocal++; 255 } 256 257 if (extraSyntheticArguments != null) { 259 for (int iarg = 0, maxArguments = extraSyntheticArguments.length; iarg < maxArguments; iarg++){ 260 SyntheticArgumentBinding argument = extraSyntheticArguments[iarg]; 261 argument.resolvedPosition = this.offset; 262 if ((argument.type == TypeBinding.LONG) || (argument.type == TypeBinding.DOUBLE)){ 263 this.offset += 2; 264 } else { 265 this.offset++; 266 } 267 if (this.offset > 0xFF) { this.problemReporter().noMoreAvailableSpaceForArgument(argument, (ASTNode)this.referenceContext); 269 } 270 } 271 } 272 this.computeLocalVariablePositions(ilocal, this.offset, codeStream); 273 } 274 275 280 MethodBinding createMethod(AbstractMethodDeclaration method) { 281 282 this.referenceContext = method; 284 method.scope = this; 285 SourceTypeBinding declaringClass = referenceType().binding; 286 int modifiers = method.modifiers | ExtraCompilerModifiers.AccUnresolved; 287 if (method.isConstructor()) { 288 if (method.isDefaultConstructor()) 289 modifiers |= ExtraCompilerModifiers.AccIsDefaultConstructor; 290 method.binding = new MethodBinding(modifiers, null, null, declaringClass); 291 checkAndSetModifiersForConstructor(method.binding); 292 } else { 293 if (declaringClass.isInterface()) modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract; 295 method.binding = 296 new MethodBinding(modifiers, method.selector, null, null, null, declaringClass); 297 checkAndSetModifiersForMethod(method.binding); 298 } 299 this.isStatic = method.binding.isStatic(); 300 301 Argument[] argTypes = method.arguments; 302 int argLength = argTypes == null ? 0 : argTypes.length; 303 if (argLength > 0 && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { 304 if (argTypes[--argLength].isVarArgs()) 305 method.binding.modifiers |= ClassFileConstants.AccVarargs; 306 while (--argLength >= 0) { 307 if (argTypes[argLength].isVarArgs()) 308 problemReporter().illegalVararg(argTypes[argLength], method); 309 } 310 } 311 312 TypeParameter[] typeParameters = method.typeParameters(); 313 if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) { 315 method.binding.typeVariables = Binding.NO_TYPE_VARIABLES; 316 } else { 317 method.binding.typeVariables = createTypeVariables(typeParameters, method.binding); 318 method.binding.modifiers |= ExtraCompilerModifiers.AccGenericSignature; 319 } 320 return method.binding; 321 } 322 323 333 public FieldBinding findField( 334 TypeBinding receiverType, 335 char[] fieldName, 336 InvocationSite invocationSite, 337 boolean needResolve) { 338 339 FieldBinding field = super.findField(receiverType, fieldName, invocationSite, needResolve); 340 if (field == null) 341 return null; 342 if (!field.isValidBinding()) 343 return field; if (field.isStatic()) 345 return field; 347 if (!isConstructorCall || receiverType != enclosingSourceType()) 348 return field; 349 350 if (invocationSite instanceof SingleNameReference) 351 return new ProblemFieldBinding( 352 field, field.declaringClass, 354 fieldName, 355 ProblemReasons.NonStaticReferenceInConstructorInvocation); 356 if (invocationSite instanceof QualifiedNameReference) { 357 QualifiedNameReference name = (QualifiedNameReference) invocationSite; 359 if (name.binding == null) 360 return new ProblemFieldBinding( 362 field, field.declaringClass, 364 fieldName, 365 ProblemReasons.NonStaticReferenceInConstructorInvocation); 366 } 367 return field; 368 } 369 370 public boolean isInsideConstructor() { 371 372 return (referenceContext instanceof ConstructorDeclaration); 373 } 374 375 public boolean isInsideInitializer() { 376 377 return (referenceContext instanceof TypeDeclaration); 378 } 379 380 public boolean isInsideInitializerOrConstructor() { 381 382 return (referenceContext instanceof TypeDeclaration) 383 || (referenceContext instanceof ConstructorDeclaration); 384 } 385 386 392 public ProblemReporter problemReporter() { 393 394 MethodScope outerMethodScope; 395 if ((outerMethodScope = outerMostMethodScope()) == this) { 396 ProblemReporter problemReporter = referenceCompilationUnit().problemReporter; 397 problemReporter.referenceContext = referenceContext; 398 return problemReporter; 399 } 400 return outerMethodScope.problemReporter(); 401 } 402 403 public final int recordInitializationStates(FlowInfo flowInfo) { 404 405 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return -1; 406 407 UnconditionalFlowInfo unconditionalFlowInfo = flowInfo.unconditionalInitsWithoutSideEffect(); 408 long[] extraInits = unconditionalFlowInfo.extra == null ? 409 null : unconditionalFlowInfo.extra[0]; 410 long inits = unconditionalFlowInfo.definiteInits; 411 checkNextEntry : for (int i = lastIndex; --i >= 0;) { 412 if (definiteInits[i] == inits) { 413 long[] otherInits = extraDefiniteInits[i]; 414 if ((extraInits != null) && (otherInits != null)) { 415 if (extraInits.length == otherInits.length) { 416 int j, max; 417 for (j = 0, max = extraInits.length; j < max; j++) { 418 if (extraInits[j] != otherInits[j]) { 419 continue checkNextEntry; 420 } 421 } 422 return i; 423 } 424 } else { 425 if ((extraInits == null) && (otherInits == null)) { 426 return i; 427 } 428 } 429 } 430 } 431 432 if (definiteInits.length == lastIndex) { 434 System.arraycopy( 436 definiteInits, 437 0, 438 (definiteInits = new long[lastIndex + 20]), 439 0, 440 lastIndex); 441 System.arraycopy( 442 extraDefiniteInits, 443 0, 444 (extraDefiniteInits = new long[lastIndex + 20][]), 445 0, 446 lastIndex); 447 } 448 definiteInits[lastIndex] = inits; 449 if (extraInits != null) { 450 extraDefiniteInits[lastIndex] = new long[extraInits.length]; 451 System.arraycopy( 452 extraInits, 453 0, 454 extraDefiniteInits[lastIndex], 455 0, 456 extraInits.length); 457 } 458 return lastIndex++; 459 } 460 461 463 public AbstractMethodDeclaration referenceMethod() { 464 465 if (referenceContext instanceof AbstractMethodDeclaration) return (AbstractMethodDeclaration) referenceContext; 466 return null; 467 } 468 469 473 public TypeDeclaration referenceType() { 474 475 return ((ClassScope) parent).referenceContext; 476 } 477 478 String basicToString(int tab) { 479 480 String newLine = "\n"; for (int i = tab; --i >= 0;) 482 newLine += "\t"; 484 String s = newLine + "--- Method Scope ---"; newLine += "\t"; s += newLine + "locals:"; for (int i = 0; i < localIndex; i++) 488 s += newLine + "\t" + locals[i].toString(); s += newLine + "startIndex = " + startIndex; s += newLine + "isConstructorCall = " + isConstructorCall; s += newLine + "initializedField = " + initializedField; s += newLine + "lastVisibleFieldID = " + lastVisibleFieldID; s += newLine + "referenceContext = " + referenceContext; return s; 495 } 496 497 } 498 | Popular Tags |