<s> package org . eclipse . jdt . internal . compiler . ast ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . ASTVisitor ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . impl . CompilerOptions ; import org . eclipse . jdt . internal . compiler . impl . Constant ; import org . eclipse . jdt . internal . compiler . impl . IrritantSet ; import org . eclipse . jdt . internal . compiler . lookup . * ; public abstract class Annotation extends Expression { final static MemberValuePair [ ] NoValuePairs = new MemberValuePair [ 0 ] ; public int declarationSourceEnd ; public Binding recipient ; public TypeReference type ; private AnnotationBinding compilerAnnotation = null ; public static long getRetentionPolicy ( char [ ] policyName ) { if ( policyName == null || policyName . length == 0 ) return 0 ; switch ( policyName [ 0 ] ) { case 'C' : if ( CharOperation . equals ( policyName , TypeConstants . UPPER_CLASS ) ) return TagBits . AnnotationClassRetention ; break ; case 'S' : if ( CharOperation . equals ( policyName , TypeConstants . UPPER_SOURCE ) ) return TagBits . AnnotationSourceRetention ; break ; case 'R' : if ( CharOperation . equals ( policyName , TypeConstants . UPPER_RUNTIME ) ) return TagBits . AnnotationRuntimeRetention ; break ; } return 0 ; } public static long getTargetElementType ( char [ ] elementName ) { if ( elementName == null || elementName . length == 0 ) return 0 ; switch ( elementName [ 0 ] ) { case 'A' : if ( CharOperation . equals ( elementName , TypeConstants . UPPER_ANNOTATION_TYPE ) ) return TagBits . AnnotationForAnnotationType ; break ; case 'C' : if ( CharOperation . equals ( elementName , TypeConstants . UPPER_CONSTRUCTOR ) ) return TagBits . AnnotationForConstructor ; break ; case 'F' : if ( CharOperation . equals ( elementName , TypeConstants . UPPER_FIELD ) ) return TagBits . AnnotationForField ; break ; case 'L' : if ( CharOperation . equals ( elementName , TypeConstants . UPPER_LOCAL_VARIABLE ) ) return TagBits . AnnotationForLocalVariable ; break ; case 'M' : if ( CharOperation . equals ( elementName , TypeConstants . UPPER_METHOD ) ) return TagBits . AnnotationForMethod ; break ; case 'P' : if ( CharOperation . equals ( elementName , TypeConstants . UPPER_PARAMETER ) ) return TagBits . AnnotationForParameter ; else if ( CharOperation . equals ( elementName , TypeConstants . UPPER_PACKAGE ) ) return TagBits . AnnotationForPackage ; break ; case 'T' : if ( CharOperation . equals ( elementName , TypeConstants . TYPE ) ) return TagBits . AnnotationForType ; break ; } return 0 ; } public ElementValuePair [ ] computeElementValuePairs ( ) { return Binding . NO_ELEMENT_VALUE_PAIRS ; } private long detectStandardAnnotation ( Scope scope , ReferenceBinding annotationType , MemberValuePair valueAttribute ) { long tagBits = 0 ; switch ( annotationType . id ) { case TypeIds . T_JavaLangAnnotationRetention : if ( valueAttribute != null ) { Expression expr = valueAttribute . value ; if ( ( expr . bits & Binding . VARIABLE ) == Binding . FIELD ) { FieldBinding field = ( ( Reference ) expr ) . fieldBinding ( ) ; if ( field != null && field . declaringClass . id == T_JavaLangAnnotationRetentionPolicy ) { tagBits |= getRetentionPolicy ( field . name ) ; } } } break ; case TypeIds . T_JavaLangAnnotationTarget : tagBits |= TagBits . AnnotationTarget ; if ( valueAttribute != null ) { Expression expr = valueAttribute . value ; if ( expr instanceof ArrayInitializer ) { ArrayInitializer initializer = ( ArrayInitializer ) expr ; final Expression [ ] expressions = initializer . expressions ; if ( expressions != null ) { for ( int i = 0 , length = expressions . length ; i < length ; i ++ ) { Expression initExpr = expressions [ i ] ; if ( ( initExpr . bits & Binding . VARIABLE ) == Binding . FIELD ) { FieldBinding field = ( ( Reference ) initExpr ) . fieldBinding ( ) ; if ( field != null && field . declaringClass . id == T_JavaLangAnnotationElementType ) { long element = getTargetElementType ( field . name ) ; if ( ( tagBits & element ) != 0 ) { scope . problemReporter ( ) . duplicateTargetInTargetAnnotation ( annotationType , ( NameReference ) initExpr ) ; } else { tagBits |= element ; } } } } } } else if ( ( expr . bits & Binding . VARIABLE ) == Binding . FIELD ) { FieldBinding field = ( ( Reference ) expr ) . fieldBinding ( ) ; if ( field != null && field . declaringClass . id == T_JavaLangAnnotationElementType ) { tagBits |= getTargetElementType ( field . name ) ; } } } break ; case TypeIds . T_JavaLangDeprecated : tagBits |= TagBits . AnnotationDeprecated ; break ; case TypeIds . T_JavaLangAnnotationDocumented : tagBits |= TagBits . AnnotationDocumented ; break ; case TypeIds . T_JavaLangAnnotationInherited : tagBits |= TagBits . AnnotationInherited ; break ; case TypeIds . T_JavaLangOverride : tagBits |= TagBits . AnnotationOverride ; break ; case TypeIds . T_JavaLangSuppressWarnings : tagBits |= TagBits . AnnotationSuppressWarnings ; break ; } return tagBits ; } public AnnotationBinding getCompilerAnnotation ( ) { return this . compilerAnnotation ; } public abstract MemberValuePair [ ] memberValuePairs ( ) ; public StringBuffer printExpression ( int indent , StringBuffer output ) { output . append ( '@' ) ; this . type . printExpression ( 0 , output ) ; return output ; } public void recordSuppressWarnings ( Scope scope , int startSuppresss , int endSuppress , boolean isSuppressingWarnings ) { IrritantSet suppressWarningIrritants = null ; MemberValuePair [ ] pairs = memberValuePairs ( ) ; pairLoop : for ( int i = 0 , length = pairs . length ; i < length ; i ++ ) { MemberValuePair pair = pairs [ i ] ; if ( CharOperation . equals ( pair . name , TypeConstants . VALUE ) ) { Expression value = pair . value ; if ( value instanceof ArrayInitializer ) { ArrayInitializer initializer = ( ArrayInitializer ) value ; Expression [ ] inits = initializer . expressions ; if ( inits != null ) { for ( int j = 0 , initsLength = inits . length ; j < initsLength ; j ++ ) { Constant cst = inits [ j ] . constant ; if ( cst != Constant . NotAConstant && cst . typeID ( ) == T_JavaLangString ) { IrritantSet irritants = CompilerOptions . warningTokenToIrritants ( cst . stringValue ( ) ) ; if ( irritants != null ) { if ( suppressWarningIrritants == null ) { suppressWarningIrritants = new IrritantSet ( irritants ) ; } else if ( suppressWarningIrritants . set ( irritants ) == null ) { scope . problemReporter ( ) . unusedWarningToken ( inits [ j ] ) ; } } else { scope . problemReporter ( ) . unhandledWarningToken ( inits [ j ] ) ; } } } } } else { Constant cst = value . constant ; if ( cst != Constant . NotAConstant && cst . typeID ( ) == T_JavaLangString ) { IrritantSet irritants = CompilerOptions . warningTokenToIrritants ( cst . stringValue ( ) ) ; if ( irritants != null ) { suppressWarningIrritants = new IrritantSet ( irritants ) ; } else { scope . problemReporter ( ) . unhandledWarningToken ( value ) ; } } } break pairLoop ; } } if ( isSuppressingWarnings && suppressWarningIrritants != null ) { scope . referenceCompilationUnit ( ) . recordSuppressWarnings ( suppressWarningIrritants , this , startSuppresss , endSuppress ) ; } } public TypeBinding resolveType ( BlockScope scope ) { if ( this . compilerAnnotation != null ) return this . resolvedType ; this . constant = Constant . NotAConstant ; TypeBinding typeBinding = this . type . resolveType ( scope ) ; if ( typeBinding == null ) { return null ; } this . resolvedType = typeBinding ; if ( ! typeBinding . isAnnotationType ( ) && typeBinding . isValidBinding ( ) ) { scope . problemReporter ( ) . typeMismatchError ( typeBinding , scope . getJavaLangAnnotationAnnotation ( ) , this . type , null ) ; return null ; } ReferenceBinding annotationType = ( ReferenceBinding ) this . resolvedType ; MethodBinding [ ] methods = annotationType . methods ( ) ; MemberValuePair [ ] originalValuePairs = memberValuePairs ( ) ; MemberValuePair valueAttribute = null ; MemberValuePair [ ] pairs ; int pairsLength = originalValuePairs . length ; if ( pairsLength > 0 ) { System . arraycopy ( originalValuePairs , 0 , pairs = new MemberValuePair [ pairsLength ] , 0 , pairsLength ) ; } else { pairs = originalValuePairs ; } nextMember : for ( int i = 0 , requiredLength = methods . length ; i < requiredLength ; i ++ ) { MethodBinding method = methods [ i ] ; char [ ] selector = method . selector ; boolean foundValue = false ; nextPair : for ( int j = 0 ; j < pairsLength ; j ++ ) { MemberValuePair pair = pairs [ j ] ; if ( pair == null ) continue nextPair ; char [ ] name = pair . name ; if ( CharOperation . equals ( name , selector ) ) { if ( valueAttribute == null && CharOperation . equals ( name , TypeConstants . VALUE ) ) { valueAttribute = pair ; } pair . binding = method ; pair . resolveTypeExpecting ( scope , method . returnType ) ; pairs [ j ] = null ; foundValue = true ; boolean foundDuplicate = false ; for ( int k = j + 1 ; k < pairsLength ; k ++ ) { MemberValuePair otherPair = pairs [ k ] ; if ( otherPair == null ) continue ; if ( CharOperation . equals ( otherPair . name , selector ) ) { foundDuplicate = true ; scope . problemReporter ( ) . duplicateAnnotationValue ( annotationType , otherPair ) ; otherPair . binding = method ; otherPair . resolveTypeExpecting ( scope , method . returnType ) ; pairs [ k ] = null ; } } if ( foundDuplicate ) { scope . problemReporter ( ) . duplicateAnnotationValue ( annotationType , pair ) ; continue nextMember ; } } } if ( ! foundValue && ( method . modifiers & ClassFileConstants . AccAnnotationDefault ) == 0 && ( this . bits & IsRecovered ) == 0 ) { scope . problemReporter ( ) . missingValueForAnnotationMember ( this , selector ) ; } } for ( int i = 0 ; i < pairsLength ; i ++ ) { if ( pairs [ i ] != null ) { scope . problemReporter ( ) . undefinedAnnotationValue ( annotationType , pairs [ i ] ) ; pairs [ i ] . resolveTypeExpecting ( scope , null ) ; } } this . compilerAnnotation = scope . environment ( ) . createAnnotation ( ( ReferenceBinding ) this . resolvedType , computeElementValuePairs ( ) ) ; long tagBits = detectStandardAnnotation ( scope , annotationType , valueAttribute ) ; scope . referenceCompilationUnit ( ) . recordSuppressWarnings ( IrritantSet . NLS , null , this . sourceStart , this . declarationSourceEnd ) ; if ( this . recipient != null ) { if ( tagBits != 0 ) { switch ( this . recipient . kind ( ) ) { case Binding . PACKAGE : ( ( PackageBinding ) this . recipient ) . tagBits |= tagBits ; break ; case Binding . TYPE : case Binding . GENERIC_TYPE : SourceTypeBinding sourceType = ( SourceTypeBinding ) this . recipient ; sourceType . tagBits |= tagBits ; if ( ( tagBits & TagBits . AnnotationSuppressWarnings ) != 0 ) { TypeDeclaration typeDeclaration = sourceType . scope . referenceContext ; int start ; if ( scope . referenceCompilationUnit ( ) . types [ 0 ] == typeDeclaration ) { start = 0 ; } else { start = typeDeclaration . declarationSourceStart ; } recordSuppressWarnings ( scope , start , typeDeclaration . declarationSourceEnd , scope . compilerOptions ( ) . suppressWarnings ) ; } break ; case Binding . METHOD : MethodBinding sourceMethod = ( MethodBinding ) this . recipient ; sourceMethod . tagBits |= tagBits ; if ( ( tagBits & TagBits . AnnotationSuppressWarnings ) != 0 ) { sourceType = ( SourceTypeBinding ) sourceMethod . declaringClass ; AbstractMethodDeclaration methodDeclaration = sourceType . scope . referenceContext . declarationOf ( sourceMethod ) ; recordSuppressWarnings ( scope , methodDeclaration . declarationSourceStart , methodDeclaration . declarationSourceEnd , scope . compilerOptions ( ) . suppressWarnings ) ; } break ; case Binding . FIELD : FieldBinding sourceField = ( FieldBinding ) this . recipient ; sourceField . tagBits |= tagBits ; if ( ( tagBits & TagBits . AnnotationSuppressWarnings ) != 0 ) { sourceType = ( SourceTypeBinding ) sourceField . declaringClass ; FieldDeclaration fieldDeclaration = sourceType . scope . referenceContext . declarationOf ( sourceField ) ; recordSuppressWarnings ( scope , fieldDeclaration . declarationSourceStart , fieldDeclaration . declarationSourceEnd , scope . compilerOptions ( ) . suppressWarnings ) ; } break ; case Binding . LOCAL : LocalVariableBinding variable = ( LocalVariableBinding ) this . recipient ; variable . tagBits |= tagBits ; if ( ( tagBits & TagBits . AnnotationSuppressWarnings ) != 0 ) { LocalDeclaration localDeclaration = variable . declaration ; recordSuppressWarnings ( scope , localDeclaration . declarationSourceStart , localDeclaration . declarationSourceEnd , scope . compilerOptions ( ) . suppressWarnings ) ; } break ; } } if ( scope . compilationUnitScope ( ) . checkTargetCompatibility ( ) ) { checkTargetCompatibility : { long metaTagBits = annotationType . getAnnotationTagBits ( ) ; if ( ( metaTagBits & TagBits . AnnotationTargetMASK ) == 0 ) break checkTargetCompatibility ; switch ( this . recipient . kind ( ) ) { case Binding . PACKAGE : if ( ( metaTagBits & TagBits . AnnotationForPackage ) != 0 ) break checkTargetCompatibility ; break ; case Binding . TYPE : case Binding . GENERIC_TYPE : if ( ( ( ReferenceBinding ) this . recipient ) . isAnnotationType ( ) ) { if ( ( metaTagBits & ( TagBits . AnnotationForAnnotationType | TagBits . AnnotationForType ) ) != 0 ) break checkTargetCompatibility ; } else if ( ( metaTagBits & TagBits . AnnotationForType ) != 0 ) { break checkTargetCompatibility ; } else if ( ( metaTagBits & TagBits . AnnotationForPackage ) != 0 ) { if ( CharOperation . equals ( ( ( ReferenceBinding ) this . recipient ) . sourceName , TypeConstants . PACKAGE_INFO_NAME ) ) break checkTargetCompatibility ; } break ; case Binding . METHOD : if ( ( ( MethodBinding ) this . recipient ) . isConstructor ( ) ) { if ( ( metaTagBits & TagBits . AnnotationForConstructor ) != 0 ) break checkTargetCompatibility ; } else if ( ( metaTagBits & TagBits . AnnotationForMethod ) != 0 ) break checkTargetCompatibility ; break ; case Binding . FIELD : if ( ( metaTagBits & TagBits . AnnotationForField ) != 0 ) break checkTargetCompatibility ; break ; case Binding . LOCAL : if ( ( ( ( LocalVariableBinding ) this . recipient ) . tagBits & TagBits . IsArgument ) != 0 ) { if ( ( metaTagBits & TagBits . AnnotationForParameter ) != 0 ) break checkTargetCompatibility ; } else if ( ( annotationType . tagBits & TagBits . AnnotationForLocalVariable ) != 0 ) break checkTargetCompatibility ; break ; } scope . problemReporter ( ) . disallowedTargetForAnnotation ( this ) ; } } } return this . resolvedType ; } public abstract void traverse ( ASTVisitor visitor , BlockScope scope ) ; } </s>