<s> package org . eclipse . jdt . internal . compiler . classfmt ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . codegen . AttributeNamesConstants ; import org . eclipse . jdt . internal . compiler . codegen . ConstantPool ; import org . eclipse . jdt . internal . compiler . env . IBinaryAnnotation ; import org . eclipse . jdt . internal . compiler . env . IBinaryMethod ; import org . eclipse . jdt . internal . compiler . util . Util ; public class MethodInfo extends ClassFileStruct implements IBinaryMethod , Comparable { static private final char [ ] [ ] noException = CharOperation . NO_CHAR_CHAR ; static private final char [ ] [ ] noArgumentNames = CharOperation . NO_CHAR_CHAR ; protected int accessFlags ; protected int attributeBytes ; protected char [ ] descriptor ; protected char [ ] [ ] exceptionNames ; protected char [ ] name ; protected char [ ] signature ; protected int signatureUtf8Offset ; protected long tagBits ; protected char [ ] [ ] argumentNames ; protected int argumentNamesIndex ; public static MethodInfo createMethod ( byte classFileBytes [ ] , int offsets [ ] , int offset ) { MethodInfo methodInfo = new MethodInfo ( classFileBytes , offsets , offset ) ; int attributesCount = methodInfo . u2At ( 6 ) ; int readOffset = 8 ; AnnotationInfo [ ] annotations = null ; AnnotationInfo [ ] [ ] parameterAnnotations = null ; for ( int i = 0 ; i < attributesCount ; i ++ ) { int utf8Offset = methodInfo . constantPoolOffsets [ methodInfo . u2At ( readOffset ) ] - methodInfo . structOffset ; char [ ] attributeName = methodInfo . utf8At ( utf8Offset + 3 , methodInfo . u2At ( utf8Offset + 1 ) ) ; if ( attributeName . length > 0 ) { switch ( attributeName [ 0 ] ) { case 'S' : if ( CharOperation . equals ( AttributeNamesConstants . SignatureName , attributeName ) ) methodInfo . signatureUtf8Offset = methodInfo . constantPoolOffsets [ methodInfo . u2At ( readOffset + 6 ) ] - methodInfo . structOffset ; break ; case 'R' : AnnotationInfo [ ] methodAnnotations = null ; AnnotationInfo [ ] [ ] paramAnnotations = null ; if ( CharOperation . equals ( attributeName , AttributeNamesConstants . RuntimeVisibleAnnotationsName ) ) { methodAnnotations = decodeMethodAnnotations ( readOffset , true , methodInfo ) ; } else if ( CharOperation . equals ( attributeName , AttributeNamesConstants . RuntimeInvisibleAnnotationsName ) ) { methodAnnotations = decodeMethodAnnotations ( readOffset , false , methodInfo ) ; } else if ( CharOperation . equals ( attributeName , AttributeNamesConstants . RuntimeVisibleParameterAnnotationsName ) ) { paramAnnotations = decodeParamAnnotations ( readOffset , true , methodInfo ) ; } else if ( CharOperation . equals ( attributeName , AttributeNamesConstants . RuntimeInvisibleParameterAnnotationsName ) ) { paramAnnotations = decodeParamAnnotations ( readOffset , false , methodInfo ) ; } if ( methodAnnotations != null ) { if ( annotations == null ) { annotations = methodAnnotations ; } else { int length = annotations . length ; AnnotationInfo [ ] newAnnotations = new AnnotationInfo [ length + methodAnnotations . length ] ; System . arraycopy ( annotations , 0 , newAnnotations , 0 , length ) ; System . arraycopy ( methodAnnotations , 0 , newAnnotations , length , methodAnnotations . length ) ; annotations = newAnnotations ; } } else if ( paramAnnotations != null ) { int numberOfParameters = paramAnnotations . length ; if ( parameterAnnotations == null ) { parameterAnnotations = paramAnnotations ; } else { for ( int p = 0 ; p < numberOfParameters ; p ++ ) { int numberOfAnnotations = paramAnnotations [ p ] == null ? 0 : paramAnnotations [ p ] . length ; if ( numberOfAnnotations > 0 ) { if ( parameterAnnotations [ p ] == null ) { parameterAnnotations [ p ] = paramAnnotations [ p ] ; } else { int length = parameterAnnotations [ p ] . length ; AnnotationInfo [ ] newAnnotations = new AnnotationInfo [ length + numberOfAnnotations ] ; System . arraycopy ( parameterAnnotations [ p ] , 0 , newAnnotations , 0 , length ) ; System . arraycopy ( paramAnnotations [ p ] , 0 , newAnnotations , length , numberOfAnnotations ) ; parameterAnnotations [ p ] = newAnnotations ; } } } } } break ; } } readOffset += ( 6 + methodInfo . u4At ( readOffset + 2 ) ) ; } methodInfo . attributeBytes = readOffset ; if ( parameterAnnotations != null ) return new MethodInfoWithParameterAnnotations ( methodInfo , annotations , parameterAnnotations ) ; if ( annotations != null ) return new MethodInfoWithAnnotations ( methodInfo , annotations ) ; return methodInfo ; } static AnnotationInfo [ ] decodeAnnotations ( int offset , boolean runtimeVisible , int numberOfAnnotations , MethodInfo methodInfo ) { AnnotationInfo [ ] result = new AnnotationInfo [ numberOfAnnotations ] ; int readOffset = offset ; for ( int i = 0 ; i < numberOfAnnotations ; i ++ ) { result [ i ] = new AnnotationInfo ( methodInfo . reference , methodInfo . constantPoolOffsets , readOffset + methodInfo . structOffset , runtimeVisible , false ) ; readOffset += result [ i ] . readOffset ; } return result ; } static AnnotationInfo [ ] decodeMethodAnnotations ( int offset , boolean runtimeVisible , MethodInfo methodInfo ) { int numberOfAnnotations = methodInfo . u2At ( offset + 6 ) ; if ( numberOfAnnotations > 0 ) { AnnotationInfo [ ] annos = decodeAnnotations ( offset + 8 , runtimeVisible , numberOfAnnotations , methodInfo ) ; if ( runtimeVisible ) { int numStandardAnnotations = 0 ; for ( int i = 0 ; i < numberOfAnnotations ; i ++ ) { long standardAnnoTagBits = annos [ i ] . standardAnnotationTagBits ; methodInfo . tagBits |= standardAnnoTagBits ; if ( standardAnnoTagBits != 0 ) { annos [ i ] = null ; numStandardAnnotations ++ ; } } if ( numStandardAnnotations != 0 ) { if ( numStandardAnnotations == numberOfAnnotations ) return null ; AnnotationInfo [ ] temp = new AnnotationInfo [ numberOfAnnotations - numStandardAnnotations ] ; int tmpIndex = 0 ; for ( int i = 0 ; i < numberOfAnnotations ; i ++ ) if ( annos [ i ] != null ) temp [ tmpIndex ++ ] = annos [ i ] ; annos = temp ; } } return annos ; } return null ; } static AnnotationInfo [ ] [ ] decodeParamAnnotations ( int offset , boolean runtimeVisible , MethodInfo methodInfo ) { AnnotationInfo [ ] [ ] allParamAnnotations = null ; int numberOfParameters = methodInfo . u1At ( offset + 6 ) ; if ( numberOfParameters > 0 ) { int readOffset = offset + 7 ; for ( int i = 0 ; i < numberOfParameters ; i ++ ) { int numberOfAnnotations = methodInfo . u2At ( readOffset ) ; readOffset += 2 ; if ( numberOfAnnotations > 0 ) { if ( allParamAnnotations == null ) allParamAnnotations = new AnnotationInfo [ numberOfParameters ] [ ] ; AnnotationInfo [ ] annos = decodeAnnotations ( readOffset , runtimeVisible , numberOfAnnotations , methodInfo ) ; allParamAnnotations [ i ] = annos ; for ( int aIndex = 0 ; aIndex < annos . length ; aIndex ++ ) readOffset += annos [ aIndex ] . readOffset ; } } } return allParamAnnotations ; } protected MethodInfo ( byte classFileBytes [ ] , int offsets [ ] , int offset ) { super ( classFileBytes , offsets , offset ) ; this . accessFlags = - 1 ; this . signatureUtf8Offset = - 1 ; } public int compareTo ( Object o ) { MethodInfo otherMethod = ( MethodInfo ) o ; int result = new String ( getSelector ( ) ) . compareTo ( new String ( otherMethod . getSelector ( ) ) ) ; if ( result != 0 ) return result ; return new String ( getMethodDescriptor ( ) ) . compareTo ( new String ( otherMethod . getMethodDescriptor ( ) ) ) ; } public boolean equals ( Object o ) { if ( ! ( o instanceof MethodInfo ) ) { return false ; } MethodInfo otherMethod = ( MethodInfo ) o ; return CharOperation . equals ( getSelector ( ) , otherMethod . getSelector ( ) ) && CharOperation . equals ( getMethodDescriptor ( ) , otherMethod . getMethodDescriptor ( ) ) ; } public int hashCode ( ) { return CharOperation . hashCode ( getSelector ( ) ) + CharOperation . hashCode ( getMethodDescriptor ( ) ) ; } public IBinaryAnnotation [ ] getAnnotations ( ) { return null ; } public char [ ] [ ] getArgumentNames ( ) { if ( this . argumentNames == null ) { readCodeAttribute ( ) ; } return this . argumentNames ; } public Object getDefaultValue ( ) { return null ; } public char [ ] [ ] getExceptionTypeNames ( ) { if ( this . exceptionNames == null ) { readExceptionAttributes ( ) ; } return this . exceptionNames ; } public char [ ] getGenericSignature ( ) { if ( this . signatureUtf8Offset != - 1 ) { if ( this . signature == null ) { this . signature = utf8At ( this . signatureUtf8Offset + 3 , u2At ( this . signatureUtf8Offset + 1 ) ) ; } return this . signature ; } return null ; } public char [ ] getMethodDescriptor ( ) { if ( this . descriptor == null ) { int utf8Offset = this . constantPoolOffsets [ u2At ( 4 ) ] - this . structOffset ; this . descriptor = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; } return this . descriptor ; } public int getModifiers ( ) { if ( this . accessFlags == - 1 ) { this . accessFlags = u2At ( 0 ) ; readModifierRelatedAttributes ( ) ; } return this . accessFlags ; } public IBinaryAnnotation [ ] getParameterAnnotations ( int index ) { return null ; } public char [ ] getSelector ( ) { if ( this . name == null ) { int utf8Offset = this . constantPoolOffsets [ u2At ( 2 ) ] - this . structOffset ; this . name = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; } return this . name ; } public long getTagBits ( ) { return this . tagBits ; } protected void initialize ( ) { getModifiers ( ) ; getSelector ( ) ; getMethodDescriptor ( ) ; getExceptionTypeNames ( ) ; getGenericSignature ( ) ; getArgumentNames ( ) ; reset ( ) ; } public boolean isClinit ( ) { char [ ] selector = getSelector ( ) ; return selector [ 0 ] == '<' && selector . length == 8 ; } public boolean isConstructor ( ) { char [ ] selector = getSelector ( ) ; return selector [ 0 ] == '<' && selector . length == 6 ; } public boolean isSynthetic ( ) { return ( getModifiers ( ) & ClassFileConstants . AccSynthetic ) != 0 ; } private void readExceptionAttributes ( ) { int attributesCount = u2At ( 6 ) ; int readOffset = 8 ; for ( int i = 0 ; i < attributesCount ; i ++ ) { int utf8Offset = this . constantPoolOffsets [ u2At ( readOffset ) ] - this . structOffset ; char [ ] attributeName = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; if ( CharOperation . equals ( attributeName , AttributeNamesConstants . ExceptionsName ) ) { int entriesNumber = u2At ( readOffset + 6 ) ; readOffset += 8 ; if ( entriesNumber == 0 ) { this . exceptionNames = noException ; } else { this . exceptionNames = new char [ entriesNumber ] [ ] ; for ( int j = 0 ; j < entriesNumber ; j ++ ) { utf8Offset = this . constantPoolOffsets [ u2At ( this . constantPoolOffsets [ u2At ( readOffset ) ] - this . structOffset + 1 ) ] - this . structOffset ; this . exceptionNames [ j ] = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; readOffset += 2 ; } } } else { readOffset += ( 6 + u4At ( readOffset + 2 ) ) ; } } if ( this . exceptionNames == null ) { this . exceptionNames = noException ; } } private void readModifierRelatedAttributes ( ) { int attributesCount = u2At ( 6 ) ; int readOffset = 8 ; for ( int i = 0 ; i < attributesCount ; i ++ ) { int utf8Offset = this . constantPoolOffsets [ u2At ( readOffset ) ] - this . structOffset ; char [ ] attributeName = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; if ( attributeName . length != 0 ) { switch ( attributeName [ 0 ] ) { case 'D' : if ( CharOperation . equals ( attributeName , AttributeNamesConstants . DeprecatedName ) ) this . accessFlags |= ClassFileConstants . AccDeprecated ; break ; case 'S' : if ( CharOperation . equals ( attributeName , AttributeNamesConstants . SyntheticName ) ) this . accessFlags |= ClassFileConstants . AccSynthetic ; break ; case 'A' : if ( CharOperation . equals ( attributeName , AttributeNamesConstants . AnnotationDefaultName ) ) this . accessFlags |= ClassFileConstants . AccAnnotationDefault ; break ; case 'V' : if ( CharOperation . equals ( attributeName , AttributeNamesConstants . VarargsName ) ) this . accessFlags |= ClassFileConstants . AccVarargs ; } } readOffset += ( 6 + u4At ( readOffset + 2 ) ) ; } } public int sizeInBytes ( ) { return this . attributeBytes ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( ) ; toString ( buffer ) ; return buffer . toString ( ) ; } void toString ( StringBuffer buffer ) { buffer . append ( getClass ( ) . getName ( ) ) ; toStringContent ( buffer ) ; } protected void toStringContent ( StringBuffer buffer ) { int modifiers = getModifiers ( ) ; char [ ] desc = getGenericSignature ( ) ; if ( desc == null ) desc = getMethodDescriptor ( ) ; buffer . append ( '{' ) . append ( ( ( modifiers & ClassFileConstants . AccDeprecated ) != 0 ? "deprecated " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0001 ) == 1 ? "public " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0002 ) == 0x0002 ? "private " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0004 ) == 0x0004 ? "protected " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0008 ) == 0x000008 ? "static " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0010 ) == 0x0010 ? "final " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0040 ) == 0x0040 ? "bridge " : Util . EMPTY_STRING ) + ( ( modifiers & 0x0080 ) == 0x0080 ? "varargs " : Util . EMPTY_STRING ) ) . append ( getSelector ( ) ) . append ( desc ) . append ( '}' ) ; } private void readCodeAttribute ( ) { int attributesCount = u2At ( 6 ) ; int readOffset = 8 ; if ( attributesCount != 0 ) { for ( int i = 0 ; i < attributesCount ; i ++ ) { int utf8Offset = this . constantPoolOffsets [ u2At ( readOffset ) ] - this . structOffset ; char [ ] attributeName = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; if ( CharOperation . equals ( attributeName , AttributeNamesConstants . CodeName ) ) { decodeCodeAttribute ( readOffset ) ; if ( this . argumentNames == null ) { this . argumentNames = noArgumentNames ; } return ; } else { readOffset += ( 6 + u4At ( readOffset + 2 ) ) ; } } } this . argumentNames = noArgumentNames ; } private void decodeCodeAttribute ( int offset ) { int readOffset = offset + 10 ; int codeLength = ( int ) u4At ( readOffset ) ; readOffset += ( 4 + codeLength ) ; int exceptionTableLength = u2At ( readOffset ) ; readOffset += 2 ; if ( exceptionTableLength != 0 ) { for ( int i = 0 ; i < exceptionTableLength ; i ++ ) { readOffset += 8 ; } } int attributesCount = u2At ( readOffset ) ; readOffset += 2 ; for ( int i = 0 ; i < attributesCount ; i ++ ) { int utf8Offset = this . constantPoolOffsets [ u2At ( readOffset ) ] - this . structOffset ; char [ ] attributeName = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; if ( CharOperation . equals ( attributeName , AttributeNamesConstants . LocalVariableTableName ) ) { decodeLocalVariableAttribute ( readOffset , codeLength ) ; } readOffset += ( 6 + u4At ( readOffset + 2 ) ) ; } } private void decodeLocalVariableAttribute ( int offset , int codeLength ) { int readOffset = offset + 6 ; final int length = u2At ( readOffset ) ; if ( length != 0 ) { readOffset += 2 ; this . argumentNames = new char [ length ] [ ] ; this . argumentNamesIndex = 0 ; for ( int i = 0 ; i < length ; i ++ ) { int startPC = u2At ( readOffset ) ; if ( startPC == 0 ) { int nameIndex = u2At ( 4 + readOffset ) ; int utf8Offset = this . constantPoolOffsets [ nameIndex ] - this . structOffset ; char [ ] localVariableName = utf8At ( utf8Offset + 3 , u2At ( utf8Offset + 1 ) ) ; if ( ! CharOperation . equals ( localVariableName , ConstantPool . This ) ) { this . argumentNames [ this . argumentNamesIndex ++ ] = localVariableName ; } } else { break ; } readOffset += 10 ; } if ( this . argumentNamesIndex != this . argumentNames . length ) { System . arraycopy ( this . argumentNames , 0 , ( this . argumentNames = new char [ this . argumentNamesIndex ] [ ] ) , 0 , this . argumentNamesIndex ) ; } } } } </s>