1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.core.compiler.*; 14 import org.eclipse.jdt.internal.compiler.*; 15 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 16 import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext; 17 import org.eclipse.jdt.internal.compiler.impl.*; 18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 19 import org.eclipse.jdt.internal.compiler.codegen.*; 20 import org.eclipse.jdt.internal.compiler.lookup.*; 21 import org.eclipse.jdt.internal.compiler.problem.*; 22 import org.eclipse.jdt.internal.compiler.parser.*; 23 24 public abstract class AbstractMethodDeclaration 25 extends ASTNode 26 implements ProblemSeverities, ReferenceContext { 27 28 public MethodScope scope; 29 public char[] selector; 32 public int declarationSourceStart; 33 public int declarationSourceEnd; 34 public int modifiers; 35 public int modifiersSourceStart; 36 public Annotation[] annotations; 37 public Argument[] arguments; 38 public TypeReference[] thrownExceptions; 39 public Statement[] statements; 40 public int explicitDeclarations; 41 public MethodBinding binding; 42 public boolean ignoreFurtherInvestigation = false; 43 44 public Javadoc javadoc; 45 46 public int bodyStart; 47 public int bodyEnd = -1; 48 public CompilationResult compilationResult; 49 50 AbstractMethodDeclaration(CompilationResult compilationResult){ 51 this.compilationResult = compilationResult; 52 } 53 54 57 public void abort(int abortLevel, CategorizedProblem problem) { 58 59 switch (abortLevel) { 60 case AbortCompilation : 61 throw new AbortCompilation(this.compilationResult, problem); 62 case AbortCompilationUnit : 63 throw new AbortCompilationUnit(this.compilationResult, problem); 64 case AbortType : 65 throw new AbortType(this.compilationResult, problem); 66 default : 67 throw new AbortMethod(this.compilationResult, problem); 68 } 69 } 70 71 public abstract void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo info); 72 73 76 public void bindArguments() { 77 78 if (this.arguments != null) { 79 if (this.binding == null) { 81 for (int i = 0, length = this.arguments.length; i < length; i++) { 82 this.arguments[i].bind(this.scope, null, true); 83 } 84 return; 85 } 86 boolean used = this.binding.isAbstract() || this.binding.isNative(); 87 AnnotationBinding[][] paramAnnotations = null; 88 for (int i = 0, length = this.arguments.length; i < length; i++) { 89 Argument argument = this.arguments[i]; 90 argument.bind(this.scope, this.binding.parameters[i], used); 91 if (argument.annotations != null) { 92 this.binding.tagBits |= TagBits.HasParameterAnnotations; 93 if (paramAnnotations == null) 94 paramAnnotations = new AnnotationBinding[length][]; 95 paramAnnotations[i] = argument.binding.getAnnotations(); 96 } 97 } 98 if (paramAnnotations != null) 99 this.binding.setParameterAnnotations(paramAnnotations); 100 } 101 } 102 103 106 public void bindThrownExceptions() { 107 108 if (this.thrownExceptions != null 109 && this.binding != null 110 && this.binding.thrownExceptions != null) { 111 int thrownExceptionLength = this.thrownExceptions.length; 112 int length = this.binding.thrownExceptions.length; 113 if (length == thrownExceptionLength) { 114 for (int i = 0; i < length; i++) { 115 this.thrownExceptions[i].resolvedType = this.binding.thrownExceptions[i]; 116 } 117 } else { 118 int bindingIndex = 0; 119 for (int i = 0; i < thrownExceptionLength && bindingIndex < length; i++) { 120 TypeReference thrownException = this.thrownExceptions[i]; 121 ReferenceBinding thrownExceptionBinding = this.binding.thrownExceptions[bindingIndex]; 122 char[][] bindingCompoundName = thrownExceptionBinding.compoundName; 123 if (bindingCompoundName == null) continue; if (thrownException instanceof SingleTypeReference) { 125 int lengthName = bindingCompoundName.length; 127 char[] thrownExceptionTypeName = thrownException.getTypeName()[0]; 128 if (CharOperation.equals(thrownExceptionTypeName, bindingCompoundName[lengthName - 1])) { 129 thrownException.resolvedType = thrownExceptionBinding; 130 bindingIndex++; 131 } 132 } else { 133 if (CharOperation.equals(thrownException.getTypeName(), bindingCompoundName)) { 135 thrownException.resolvedType = thrownExceptionBinding; 136 bindingIndex++; 137 } 138 } 139 } 140 } 141 } 142 } 143 144 public CompilationResult compilationResult() { 145 146 return this.compilationResult; 147 } 148 149 154 public void generateCode(ClassScope classScope, ClassFile classFile) { 155 156 int problemResetPC = 0; 157 classFile.codeStream.wideMode = false; if (this.ignoreFurtherInvestigation) { 159 if (this.binding == null) 161 return; int problemsLength; 163 CategorizedProblem[] problems = 164 this.scope.referenceCompilationUnit().compilationResult.getProblems(); 165 CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length]; 166 System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); 167 classFile.addProblemMethod(this, this.binding, problemsCopy); 168 return; 169 } 170 try { 172 problemResetPC = classFile.contentsOffset; 173 this.generateCode(classFile); 174 } catch (AbortMethod e) { 175 if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { 177 try { 179 classFile.contentsOffset = problemResetPC; 180 classFile.methodCount--; 181 classFile.codeStream.wideMode = true; this.generateCode(classFile); } catch (AbortMethod e2) { 184 int problemsLength; 185 CategorizedProblem[] problems = 186 this.scope.referenceCompilationUnit().compilationResult.getAllProblems(); 187 CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length]; 188 System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); 189 classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC); 190 } 191 } else { 192 int problemsLength; 194 CategorizedProblem[] problems = 195 this.scope.referenceCompilationUnit().compilationResult.getAllProblems(); 196 CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length]; 197 System.arraycopy(problems, 0, problemsCopy, 0, problemsLength); 198 classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC); 199 } 200 } 201 } 202 203 public void generateCode(ClassFile classFile) { 204 205 classFile.generateMethodInfoHeader(this.binding); 206 int methodAttributeOffset = classFile.contentsOffset; 207 int attributeNumber = classFile.generateMethodInfoAttribute(this.binding); 208 if ((!this.binding.isNative()) && (!this.binding.isAbstract())) { 209 int codeAttributeOffset = classFile.contentsOffset; 210 classFile.generateCodeAttributeHeader(); 211 CodeStream codeStream = classFile.codeStream; 212 codeStream.reset(this, classFile); 213 this.scope.computeLocalVariablePositions(this.binding.isStatic() ? 0 : 1, codeStream); 215 216 if (this.arguments != null) { 218 for (int i = 0, max = this.arguments.length; i < max; i++) { 219 LocalVariableBinding argBinding; 220 codeStream.addVisibleLocalVariable(argBinding = this.arguments[i].binding); 221 argBinding.recordInitializationStartPC(0); 222 } 223 } 224 if (this.statements != null) { 225 for (int i = 0, max = this.statements.length; i < max; i++) 226 this.statements[i].generateCode(this.scope, codeStream); 227 } 228 if ((this.bits & ASTNode.NeedFreeReturn) != 0) { 229 codeStream.return_(); 230 } 231 codeStream.exitUserScope(this.scope); 233 codeStream.recordPositionsFrom(0, this.declarationSourceEnd); 234 classFile.completeCodeAttribute(codeAttributeOffset); 235 attributeNumber++; 236 } else { 237 checkArgumentsSize(); 238 } 239 classFile.completeMethodInfo(methodAttributeOffset, attributeNumber); 240 241 if (this.ignoreFurtherInvestigation) { 243 throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null); 244 } 245 } 246 247 private void checkArgumentsSize() { 248 TypeBinding[] parameters = this.binding.parameters; 249 int size = 1; for (int i = 0, max = parameters.length; i < max; i++) { 251 TypeBinding parameter = parameters[i]; 252 if (parameter == TypeBinding.LONG || parameter == TypeBinding.DOUBLE) { 253 size += 2; 254 } else { 255 size++; 256 } 257 if (size > 0xFF) { 258 this.scope.problemReporter().noMoreAvailableSpaceForArgument(this.scope.locals[i], this.scope.locals[i].declaration); 259 } 260 } 261 } 262 263 public boolean hasErrors() { 264 return this.ignoreFurtherInvestigation; 265 } 266 267 public boolean isAbstract() { 268 269 if (this.binding != null) 270 return this.binding.isAbstract(); 271 return (this.modifiers & ClassFileConstants.AccAbstract) != 0; 272 } 273 274 public boolean isAnnotationMethod() { 275 276 return false; 277 } 278 279 public boolean isClinit() { 280 281 return false; 282 } 283 284 public boolean isConstructor() { 285 286 return false; 287 } 288 289 public boolean isDefaultConstructor() { 290 291 return false; 292 } 293 294 public boolean isInitializationMethod() { 295 296 return false; 297 } 298 299 public boolean isMethod() { 300 301 return false; 302 } 303 304 public boolean isNative() { 305 306 if (this.binding != null) 307 return this.binding.isNative(); 308 return (this.modifiers & ClassFileConstants.AccNative) != 0; 309 } 310 311 public boolean isStatic() { 312 313 if (this.binding != null) 314 return this.binding.isStatic(); 315 return (this.modifiers & ClassFileConstants.AccStatic) != 0; 316 } 317 318 323 public abstract void parseStatements( 324 Parser parser, 325 CompilationUnitDeclaration unit); 326 327 public StringBuffer print(int tab, StringBuffer output) { 328 329 if (this.javadoc != null) { 330 this.javadoc.print(tab, output); 331 } 332 printIndent(tab, output); 333 printModifiers(this.modifiers, output); 334 if (this.annotations != null) printAnnotations(this.annotations, output); 335 336 TypeParameter[] typeParams = typeParameters(); 337 if (typeParams != null) { 338 output.append('<'); 339 int max = typeParams.length - 1; 340 for (int j = 0; j < max; j++) { 341 typeParams[j].print(0, output); 342 output.append(", "); } 344 typeParams[max].print(0, output); 345 output.append('>'); 346 } 347 348 printReturnType(0, output).append(this.selector).append('('); 349 if (this.arguments != null) { 350 for (int i = 0; i < this.arguments.length; i++) { 351 if (i > 0) output.append(", "); this.arguments[i].print(0, output); 353 } 354 } 355 output.append(')'); 356 if (this.thrownExceptions != null) { 357 output.append(" throws "); for (int i = 0; i < this.thrownExceptions.length; i++) { 359 if (i > 0) output.append(", "); this.thrownExceptions[i].print(0, output); 361 } 362 } 363 printBody(tab + 1, output); 364 return output; 365 } 366 367 public StringBuffer printBody(int indent, StringBuffer output) { 368 369 if (isAbstract() || (this.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) 370 return output.append(';'); 371 372 output.append(" {"); if (this.statements != null) { 374 for (int i = 0; i < this.statements.length; i++) { 375 output.append('\n'); 376 this.statements[i].printStatement(indent, output); 377 } 378 } 379 output.append('\n'); 380 printIndent(indent == 0 ? 0 : indent - 1, output).append('}'); 381 return output; 382 } 383 384 public StringBuffer printReturnType(int indent, StringBuffer output) { 385 386 return output; 387 } 388 389 public void resolve(ClassScope upperScope) { 390 391 if (this.binding == null) { 392 this.ignoreFurtherInvestigation = true; 393 } 394 395 try { 396 bindArguments(); 397 bindThrownExceptions(); 398 resolveJavadoc(); 399 resolveAnnotations(scope, this.annotations, this.binding); 400 resolveStatements(); 401 if (this.binding != null 403 && (this.binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0 404 && (this.binding.modifiers & ClassFileConstants.AccDeprecated) != 0 405 && this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { 406 this.scope.problemReporter().missingDeprecatedAnnotationForMethod(this); 407 } 408 } catch (AbortMethod e) { this.ignoreFurtherInvestigation = true; 410 } 411 } 412 413 public void resolveJavadoc() { 414 415 if (this.binding == null) return; 416 if (this.javadoc != null) { 417 this.javadoc.resolve(this.scope); 418 return; 419 } 420 if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) { 421 this.scope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers); 422 } 423 } 424 425 public void resolveStatements() { 426 427 if (this.statements != null) { 428 for (int i = 0, length = this.statements.length; i < length; i++) { 429 this.statements[i].resolve(this.scope); 430 } 431 } else if ((this.bits & UndocumentedEmptyBlock) != 0) { 432 this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd+1); 433 } 434 } 435 436 public void tagAsHavingErrors() { 437 438 this.ignoreFurtherInvestigation = true; 439 } 440 441 public void traverse( 442 ASTVisitor visitor, 443 ClassScope classScope) { 444 } 446 447 public TypeParameter[] typeParameters() { 448 return null; 449 } 450 } 451 | Popular Tags |