<s> package org . eclipse . jdt . internal . compiler . ast ; import org . eclipse . jdt . core . compiler . * ; import org . eclipse . jdt . internal . compiler . * ; import org . eclipse . jdt . internal . compiler . flow . FlowInfo ; import org . eclipse . jdt . internal . compiler . impl . * ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . codegen . * ; import org . eclipse . jdt . internal . compiler . lookup . * ; import org . eclipse . jdt . internal . compiler . problem . * ; import org . eclipse . jdt . internal . compiler . parser . * ; import org . eclipse . jdt . internal . compiler . util . Util ; public abstract class AbstractMethodDeclaration extends ASTNode implements ProblemSeverities , ReferenceContext { public MethodScope scope ; public char [ ] selector ; public int declarationSourceStart ; public int declarationSourceEnd ; public int modifiers ; public int modifiersSourceStart ; public Annotation [ ] annotations ; public Argument [ ] arguments ; public TypeReference [ ] thrownExceptions ; public Statement [ ] statements ; public int explicitDeclarations ; public MethodBinding binding ; public boolean ignoreFurtherInvestigation = false ; public Javadoc javadoc ; public int bodyStart ; public int bodyEnd = - 1 ; public CompilationResult compilationResult ; AbstractMethodDeclaration ( CompilationResult compilationResult ) { this . compilationResult = compilationResult ; } public void abort ( int abortLevel , CategorizedProblem problem ) { switch ( abortLevel ) { case AbortCompilation : throw new AbortCompilation ( this . compilationResult , problem ) ; case AbortCompilationUnit : throw new AbortCompilationUnit ( this . compilationResult , problem ) ; case AbortType : throw new AbortType ( this . compilationResult , problem ) ; default : throw new AbortMethod ( this . compilationResult , problem ) ; } } public void createArgumentBindings ( ) { if ( this . arguments != null && this . binding != null ) { for ( int i = 0 , length = this . arguments . length ; i < length ; i ++ ) { Argument argument = this . arguments [ i ] ; argument . createBinding ( this . scope , this . binding . parameters [ i ] ) ; if ( ( argument . binding . tagBits & ( TagBits . AnnotationNonNull | TagBits . AnnotationNullable ) ) != 0 ) { if ( this . binding . parameterNonNullness == null ) this . binding . parameterNonNullness = new Boolean [ this . arguments . length ] ; this . binding . parameterNonNullness [ i ] = Boolean . valueOf ( ( argument . binding . tagBits & TagBits . AnnotationNonNull ) != 0 ) ; } } } } public void bindArguments ( ) { if ( this . arguments != null ) { if ( this . binding == null ) { for ( int i = 0 , length = this . arguments . length ; i < length ; i ++ ) { this . arguments [ i ] . bind ( this . scope , null , true ) ; } return ; } boolean used = this . binding . isAbstract ( ) || this . binding . isNative ( ) ; AnnotationBinding [ ] [ ] paramAnnotations = null ; for ( int i = 0 , length = this . arguments . length ; i < length ; i ++ ) { Argument argument = this . arguments [ i ] ; argument . bind ( this . scope , this . binding . parameters [ i ] , used ) ; if ( argument . annotations != null ) { if ( paramAnnotations == null ) { paramAnnotations = new AnnotationBinding [ length ] [ ] ; for ( int j = 0 ; j < i ; j ++ ) { paramAnnotations [ j ] = Binding . NO_ANNOTATIONS ; } } paramAnnotations [ i ] = argument . binding . getAnnotations ( ) ; } else if ( paramAnnotations != null ) { paramAnnotations [ i ] = Binding . NO_ANNOTATIONS ; } } if ( paramAnnotations != null ) this . binding . setParameterAnnotations ( paramAnnotations ) ; } } public void bindThrownExceptions ( ) { if ( this . thrownExceptions != null && this . binding != null && this . binding . thrownExceptions != null ) { int thrownExceptionLength = this . thrownExceptions . length ; int length = this . binding . thrownExceptions . length ; if ( length == thrownExceptionLength ) { for ( int i = 0 ; i < length ; i ++ ) { this . thrownExceptions [ i ] . resolvedType = this . binding . thrownExceptions [ i ] ; } } else { int bindingIndex = 0 ; for ( int i = 0 ; i < thrownExceptionLength && bindingIndex < length ; i ++ ) { TypeReference thrownException = this . thrownExceptions [ i ] ; ReferenceBinding thrownExceptionBinding = this . binding . thrownExceptions [ bindingIndex ] ; char [ ] [ ] bindingCompoundName = thrownExceptionBinding . compoundName ; if ( bindingCompoundName == null ) continue ; if ( thrownException instanceof SingleTypeReference ) { int lengthName = bindingCompoundName . length ; char [ ] thrownExceptionTypeName = thrownException . getTypeName ( ) [ 0 ] ; if ( CharOperation . equals ( thrownExceptionTypeName , bindingCompoundName [ lengthName - 1 ] ) ) { thrownException . resolvedType = thrownExceptionBinding ; bindingIndex ++ ; } } else { if ( CharOperation . equals ( thrownException . getTypeName ( ) , bindingCompoundName ) ) { thrownException . resolvedType = thrownExceptionBinding ; bindingIndex ++ ; } } } } } } void analyseArguments ( FlowInfo flowInfo ) { if ( this . arguments != null ) { for ( int i = 0 , count = this . arguments . length ; i < count ; i ++ ) { if ( this . binding . parameterNonNullness != null ) { Boolean nonNullNess = this . binding . parameterNonNullness [ i ] ; if ( nonNullNess != null ) { if ( nonNullNess . booleanValue ( ) ) flowInfo . markAsDefinitelyNonNull ( this . arguments [ i ] . binding ) ; else flowInfo . markPotentiallyNullBit ( this . arguments [ i ] . binding ) ; } } flowInfo . markAsDefinitelyAssigned ( this . arguments [ i ] . binding ) ; } } } public CompilationResult compilationResult ( ) { return this . compilationResult ; } public void generateCode ( ClassScope classScope , ClassFile classFile ) { int problemResetPC = 0 ; classFile . codeStream . wideMode = false ; if ( this . ignoreFurtherInvestigation ) { if ( this . binding == null ) return ; int problemsLength ; CategorizedProblem [ ] problems = this . scope . referenceCompilationUnit ( ) . compilationResult . getProblems ( ) ; CategorizedProblem [ ] problemsCopy = new CategorizedProblem [ problemsLength = problems . length ] ; System . arraycopy ( problems , 0 , problemsCopy , 0 , problemsLength ) ; classFile . addProblemMethod ( this , this . binding , problemsCopy ) ; return ; } boolean restart = false ; boolean abort = false ; do { try { problemResetPC = classFile . contentsOffset ; this . generateCode ( classFile ) ; restart = false ; } catch ( AbortMethod e ) { if ( e . compilationResult == CodeStream . RESTART_IN_WIDE_MODE ) { classFile . contentsOffset = problemResetPC ; classFile . methodCount -- ; classFile . codeStream . resetInWideMode ( ) ; restart = true ; } else if ( e . compilationResult == CodeStream . RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE ) { classFile . contentsOffset = problemResetPC ; classFile . methodCount -- ; classFile . codeStream . resetForCodeGenUnusedLocals ( ) ; restart = true ; } else { restart = false ; abort = true ; } } } while ( restart ) ; if ( abort ) { int problemsLength ; CategorizedProblem [ ] problems = this . scope . referenceCompilationUnit ( ) . compilationResult . getAllProblems ( ) ; CategorizedProblem [ ] problemsCopy = new CategorizedProblem [ problemsLength = problems . length ] ; System . arraycopy ( problems , 0 , problemsCopy , 0 , problemsLength ) ; classFile . addProblemMethod ( this , this . binding , problemsCopy , problemResetPC ) ; } } public void generateCode ( ClassFile classFile ) { classFile . generateMethodInfoHeader ( this . binding ) ; int methodAttributeOffset = classFile . contentsOffset ; int attributeNumber = classFile . generateMethodInfoAttributes ( this . binding ) ; if ( ( ! this . binding . isNative ( ) ) && ( ! this . binding . isAbstract ( ) ) ) { int codeAttributeOffset = classFile . contentsOffset ; classFile . generateCodeAttributeHeader ( ) ; CodeStream codeStream = classFile . codeStream ; codeStream . reset ( this , classFile ) ; this . scope . computeLocalVariablePositions ( this . binding . isStatic ( ) ? 0 : 1 , codeStream ) ; if ( this . arguments != null ) { for ( int i = 0 , max = this . arguments . length ; i < max ; i ++ ) { LocalVariableBinding argBinding ; codeStream . addVisibleLocalVariable ( argBinding = this . arguments [ i ] . binding ) ; argBinding . recordInitializationStartPC ( 0 ) ; } } if ( this . statements != null ) { for ( int i = 0 , max = this . statements . length ; i < max ; i ++ ) this . statements [ i ] . generateCode ( this . scope , codeStream ) ; } if ( this . ignoreFurtherInvestigation ) { throw new AbortMethod ( this . scope . referenceCompilationUnit ( ) . compilationResult , null ) ; } if ( ( this . bits & ASTNode . NeedFreeReturn ) != 0 ) { codeStream . return_ ( ) ; } codeStream . exitUserScope ( this . scope ) ; codeStream . recordPositionsFrom ( 0 , this . declarationSourceEnd ) ; try { classFile . completeCodeAttribute ( codeAttributeOffset ) ; } catch ( NegativeArraySizeException e ) { throw new AbortMethod ( this . scope . referenceCompilationUnit ( ) . compilationResult , null ) ; } attributeNumber ++ ; } else { checkArgumentsSize ( ) ; } classFile . completeMethodInfo ( this . binding , methodAttributeOffset , attributeNumber ) ; } private void checkArgumentsSize ( ) { TypeBinding [ ] parameters = this . binding . parameters ; int size = 1 ; for ( int i = 0 , max = parameters . length ; i < max ; i ++ ) { switch ( parameters [ i ] . id ) { case TypeIds . T_long : case TypeIds . T_double : size += 2 ; break ; default : size ++ ; break ; } if ( size > 0xFF ) { this . scope . problemReporter ( ) . noMoreAvailableSpaceForArgument ( this . scope . locals [ i ] , this . scope . locals [ i ] . declaration ) ; } } } public CompilationUnitDeclaration getCompilationUnitDeclaration ( ) { if ( this . scope != null ) { return this . scope . compilationUnitScope ( ) . referenceContext ; } return null ; } public boolean hasErrors ( ) { return this . ignoreFurtherInvestigation ; } public boolean isAbstract ( ) { if ( this . binding != null ) return this . binding . isAbstract ( ) ; return ( this . modifiers & ClassFileConstants . AccAbstract ) != 0 ; } public boolean isAnnotationMethod ( ) { return false ; } public boolean isClinit ( ) { return false ; } public boolean isConstructor ( ) { return false ; } public boolean isDefaultConstructor ( ) { return false ; } public boolean isInitializationMethod ( ) { return false ; } public boolean isMethod ( ) { return false ; } public boolean isNative ( ) { if ( this . binding != null ) return this . binding . isNative ( ) ; return ( this . modifiers & ClassFileConstants . AccNative ) != 0 ; } public boolean isStatic ( ) { if ( this . binding != null ) return this . binding . isStatic ( ) ; return ( this . modifiers & ClassFileConstants . AccStatic ) != 0 ; } public abstract void parseStatements ( Parser parser , CompilationUnitDeclaration unit ) ; public StringBuffer print ( int tab , StringBuffer output ) { if ( this . javadoc != null ) { this . javadoc . print ( tab , output ) ; } printIndent ( tab , output ) ; printModifiers ( this . modifiers , output ) ; if ( this . annotations != null ) printAnnotations ( this . annotations , output ) ; TypeParameter [ ] typeParams = typeParameters ( ) ; if ( typeParams != null ) { output . append ( '<' ) ; int max = typeParams . length - 1 ; for ( int j = 0 ; j < max ; j ++ ) { typeParams [ j ] . print ( 0 , output ) ; output . append ( ", " ) ; } typeParams [ max ] . print ( 0 , output ) ; output . append ( '>' ) ; } printReturnType ( 0 , output ) . append ( this . selector ) . append ( '(' ) ; if ( this . arguments != null ) { for ( int i = 0 ; i < this . arguments . length ; i ++ ) { if ( i > 0 ) output . append ( ", " ) ; this . arguments [ i ] . print ( 0 , output ) ; } } output . append ( ')' ) ; if ( this . thrownExceptions != null ) { output . append ( " throws " ) ; for ( int i = 0 ; i < this . thrownExceptions . length ; i ++ ) { if ( i > 0 ) output . append ( ", " ) ; this . thrownExceptions [ i ] . print ( 0 , output ) ; } } printBody ( tab + 1 , output ) ; return output ; } public StringBuffer printBody ( int indent , StringBuffer output ) { if ( isAbstract ( ) || ( this . modifiers & ExtraCompilerModifiers . AccSemicolonBody ) != 0 ) return output . append ( ';' ) ; output . append ( " {" ) ; if ( this . statements != null ) { for ( int i = 0 ; i < this . statements . length ; i ++ ) { output . append ( '\n' ) ; this . statements [ i ] . printStatement ( indent , output ) ; } } output . append ( '\n' ) ; printIndent ( indent == 0 ? 0 : indent - 1 , output ) . append ( '}' ) ; return output ; } public StringBuffer printReturnType ( int indent , StringBuffer output ) { return output ; } public void resolve ( ClassScope upperScope ) { if ( this . binding == null ) { this . ignoreFurtherInvestigation = true ; } try { bindArguments ( ) ; bindThrownExceptions ( ) ; resolveJavadoc ( ) ; resolveAnnotations ( this . scope , this . annotations , this . binding ) ; validateNullAnnotations ( ) ; resolveStatements ( ) ; if ( this . binding != null && ( this . binding . getAnnotationTagBits ( ) & TagBits . AnnotationDeprecated ) == 0 && ( this . binding . modifiers & ClassFileConstants . AccDeprecated ) != 0 && this . scope . compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_5 ) { this . scope . problemReporter ( ) . missingDeprecatedAnnotationForMethod ( this ) ; } } catch ( AbortMethod e ) { this . ignoreFurtherInvestigation = true ; } } public void resolveJavadoc ( ) { if ( this . binding == null ) return ; if ( this . javadoc != null ) { this . javadoc . resolve ( this . scope ) ; return ; } if ( this . binding . declaringClass != null && ! this . binding . declaringClass . isLocalType ( ) ) { int javadocVisibility = this . binding . modifiers & ExtraCompilerModifiers . AccVisibilityMASK ; ClassScope classScope = this . scope . classScope ( ) ; ProblemReporter reporter = this . scope . problemReporter ( ) ; int severity = reporter . computeSeverity ( IProblem . JavadocMissing ) ; if ( severity != ProblemSeverities . Ignore ) { if ( classScope != null ) { javadocVisibility = Util . computeOuterMostVisibility ( classScope . referenceType ( ) , javadocVisibility ) ; } int javadocModifiers = ( this . binding . modifiers & ~ ExtraCompilerModifiers . AccVisibilityMASK ) | javadocVisibility ; reporter . javadocMissing ( this . sourceStart , this . sourceEnd , severity , javadocModifiers ) ; } } } public void resolveStatements ( ) { if ( this . statements != null ) { for ( int i = 0 , length = this . statements . length ; i < length ; i ++ ) { this . statements [ i ] . resolve ( this . scope ) ; } } else if ( ( this . bits & UndocumentedEmptyBlock ) != 0 ) { if ( ! this . isConstructor ( ) || this . arguments != null ) { this . scope . problemReporter ( ) . undocumentedEmptyBlock ( this . bodyStart - 1 , this . bodyEnd + 1 ) ; } } } public void tagAsHavingErrors ( ) { this . ignoreFurtherInvestigation = true ; } public void traverse ( ASTVisitor visitor , ClassScope classScope ) { } public TypeParameter [ ] typeParameters ( ) { return null ; } void validateNullAnnotations ( ) { if ( this . binding != null && this . binding . parameterNonNullness != null ) { int length = this . binding . parameters . length ; for ( int i = 0 ; i < length ; i ++ ) { if ( this . binding . parameterNonNullness [ i ] != null ) { long nullAnnotationTagBit = this . binding . parameterNonNullness [ i ] . booleanValue ( ) ? TagBits . AnnotationNonNull : TagBits . AnnotationNullable ; this . scope . validateNullAnnotation ( nullAnnotationTagBit , this . arguments [ i ] . type , this . arguments [ i ] . annotations ) ; } } } } } </s>