📄 classreader.java
字号:
final byte[] c = new byte[b.length + 1000];
System.arraycopy( b,
0,
c,
0,
len );
b = c;
}
}
}
// ------------------------------------------------------------------------
// Public methods
// ------------------------------------------------------------------------
/**
* Makes the given visitor visit the Java class of this {@link ClassReader}.
* This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
*
* @param classVisitor the visitor that must visit this class.
* @param skipDebug <tt>true</tt> if the debug information of the class
* must not be visited. In this case the
* {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
* {@link MethodVisitor#visitLineNumber visitLineNumber} methods will
* not be called.
*/
public void accept(final ClassVisitor classVisitor,
final boolean skipDebug) {
accept( classVisitor,
new Attribute[0],
skipDebug );
}
/**
* Makes the given visitor visit the Java class of this {@link ClassReader}.
* This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
*
* @param classVisitor the visitor that must visit this class.
* @param attrs prototypes of the attributes that must be parsed during the
* visit of the class. Any attribute whose type is not equal to the
* type of one the prototypes will be ignored.
* @param skipDebug <tt>true</tt> if the debug information of the class
* must not be visited. In this case the
* {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
* {@link MethodVisitor#visitLineNumber visitLineNumber} methods will
* not be called.
*/
public void accept(final ClassVisitor classVisitor,
final Attribute[] attrs,
final boolean skipDebug) {
final byte[] b = this.b; // the bytecode array
final char[] c = new char[this.maxStringLength]; // buffer used to read strings
int i, j, k; // loop variables
int u, v, w; // indexes in b
Attribute attr;
int access;
String name;
String desc;
String attrName;
String signature;
int anns = 0;
int ianns = 0;
Attribute cattrs = null;
// visits the header
u = this.header;
access = readUnsignedShort( u );
name = readClass( u + 2,
c );
v = this.items[readUnsignedShort( u + 4 )];
final String superClassName = v == 0 ? null : readUTF8( v,
c );
final String[] implementedItfs = new String[readUnsignedShort( u + 6 )];
w = 0;
u += 8;
for ( i = 0; i < implementedItfs.length; ++i ) {
implementedItfs[i] = readClass( u,
c );
u += 2;
}
// skips fields and methods
v = u;
i = readUnsignedShort( v );
v += 2;
for ( ; i > 0; --i ) {
j = readUnsignedShort( v + 6 );
v += 8;
for ( ; j > 0; --j ) {
v += 6 + readInt( v + 2 );
}
}
i = readUnsignedShort( v );
v += 2;
for ( ; i > 0; --i ) {
j = readUnsignedShort( v + 6 );
v += 8;
for ( ; j > 0; --j ) {
v += 6 + readInt( v + 2 );
}
}
// reads the class's attributes
signature = null;
String sourceFile = null;
String sourceDebug = null;
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
i = readUnsignedShort( v );
v += 2;
for ( ; i > 0; --i ) {
attrName = readUTF8( v,
c );
if ( attrName.equals( "SourceFile" ) ) {
sourceFile = readUTF8( v + 6,
c );
} else if ( attrName.equals( "Deprecated" ) ) {
access |= Opcodes.ACC_DEPRECATED;
} else if ( attrName.equals( "Synthetic" ) ) {
access |= Opcodes.ACC_SYNTHETIC;
} else if ( attrName.equals( "Annotation" ) ) {
access |= Opcodes.ACC_ANNOTATION;
} else if ( attrName.equals( "Enum" ) ) {
access |= Opcodes.ACC_ENUM;
} else if ( attrName.equals( "InnerClasses" ) ) {
w = v + 6;
} else if ( attrName.equals( "Signature" ) ) {
signature = readUTF8( v + 6,
c );
} else if ( attrName.equals( "SourceDebugExtension" ) ) {
final int len = readInt( v + 2 );
sourceDebug = readUTF( v + 6,
len,
new char[len] );
} else if ( attrName.equals( "EnclosingMethod" ) ) {
enclosingOwner = readClass( v + 6,
c );
final int item = readUnsignedShort( v + 8 );
if ( item != 0 ) {
enclosingName = readUTF8( this.items[item],
c );
enclosingDesc = readUTF8( this.items[item] + 2,
c );
}
} else if ( attrName.equals( "RuntimeVisibleAnnotations" ) ) {
anns = v + 6;
} else if ( attrName.equals( "RuntimeInvisibleAnnotations" ) ) {
ianns = v + 6;
} else {
attr = readAttribute( attrs,
attrName,
v + 6,
readInt( v + 2 ),
c,
-1,
null );
if ( attr != null ) {
attr.next = cattrs;
cattrs = attr;
}
}
v += 6 + readInt( v + 2 );
}
// calls the visit method
classVisitor.visit( readInt( 4 ),
access,
name,
signature,
superClassName,
implementedItfs );
// calls the visitSource method
if ( sourceFile != null || sourceDebug != null ) {
classVisitor.visitSource( sourceFile,
sourceDebug );
}
// calls the visitOuterClass method
if ( enclosingOwner != null ) {
classVisitor.visitOuterClass( enclosingOwner,
enclosingName,
enclosingDesc );
}
// visits the class annotations
for ( i = 1; i >= 0; --i ) {
v = i == 0 ? ianns : anns;
if ( v != 0 ) {
j = readUnsignedShort( v );
v += 2;
for ( ; j > 0; --j ) {
desc = readUTF8( v,
c );
v += 2;
v = readAnnotationValues( v,
c,
classVisitor.visitAnnotation( desc,
i != 0 ) );
}
}
}
// visits the class attributes
while ( cattrs != null ) {
attr = cattrs.next;
cattrs.next = null;
classVisitor.visitAttribute( cattrs );
cattrs = attr;
}
// class the visitInnerClass method
if ( w != 0 ) {
i = readUnsignedShort( w );
w += 2;
for ( ; i > 0; --i ) {
classVisitor.visitInnerClass( readUnsignedShort( w ) == 0 ? null : readClass( w,
c ),
readUnsignedShort( w + 2 ) == 0 ? null : readClass( w + 2,
c ),
readUnsignedShort( w + 4 ) == 0 ? null : readUTF8( w + 4,
c ),
readUnsignedShort( w + 6 ) );
w += 8;
}
}
// visits the fields
i = readUnsignedShort( u );
u += 2;
for ( ; i > 0; --i ) {
access = readUnsignedShort( u );
name = readUTF8( u + 2,
c );
desc = readUTF8( u + 4,
c );
// visits the field's attributes and looks for a ConstantValue
// attribute
int fieldValueItem = 0;
signature = null;
anns = 0;
ianns = 0;
cattrs = null;
j = readUnsignedShort( u + 6 );
u += 8;
for ( ; j > 0; --j ) {
attrName = readUTF8( u,
c );
if ( attrName.equals( "ConstantValue" ) ) {
fieldValueItem = readUnsignedShort( u + 6 );
} else if ( attrName.equals( "Synthetic" ) ) {
access |= Opcodes.ACC_SYNTHETIC;
} else if ( attrName.equals( "Deprecated" ) ) {
access |= Opcodes.ACC_DEPRECATED;
} else if ( attrName.equals( "Enum" ) ) {
access |= Opcodes.ACC_ENUM;
} else if ( attrName.equals( "Signature" ) ) {
signature = readUTF8( u + 6,
c );
} else if ( attrName.equals( "RuntimeVisibleAnnotations" ) ) {
anns = u + 6;
} else if ( attrName.equals( "RuntimeInvisibleAnnotations" ) ) {
ianns = u + 6;
} else {
attr = readAttribute( attrs,
attrName,
u + 6,
readInt( u + 2 ),
c,
-1,
null );
if ( attr != null ) {
attr.next = cattrs;
cattrs = attr;
}
}
u += 6 + readInt( u + 2 );
}
// reads the field's value, if any
final Object value = (fieldValueItem == 0 ? null : readConst( fieldValueItem,
c ));
// visits the field
final FieldVisitor fv = classVisitor.visitField( access,
name,
desc,
signature,
value );
// visits the field annotations and attributes
if ( fv != null ) {
for ( j = 1; j >= 0; --j ) {
v = j == 0 ? ianns : anns;
if ( v != 0 ) {
k = readUnsignedShort( v );
v += 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -