package org.aspectj.apache.bcel.classfile;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos;
import org.aspectj.apache.bcel.generic.Type;
public final class Method extends FieldOrMethod {
public static final AnnotationGen[][] NO_PARAMETER_ANNOTATIONS = new AnnotationGen[][] {};
public static final Method[] NoMethods = new Method[0];
private boolean parameterAnnotationsOutOfDate = true;
private AnnotationGen[][] unpackedParameterAnnotations;
private Method() {
parameterAnnotationsOutOfDate = true;
}
public Method(Method c) {
super(c);
parameterAnnotationsOutOfDate = true;
}
Method(DataInputStream file, ConstantPool constant_pool) throws IOException {
super(file, constant_pool);
}
public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes, ConstantPool constant_pool) {
super(access_flags, name_index, signature_index, attributes, constant_pool);
parameterAnnotationsOutOfDate = true;
}
public void accept(ClassVisitor v) {
v.visitMethod(this);
}
@Override
public void setAttributes(Attribute[] attributes) {
parameterAnnotationsOutOfDate = true;
super.setAttributes(attributes);
}
public final Code getCode() {
return AttributeUtils.getCodeAttribute(attributes);
}
public final ExceptionTable getExceptionTable() {
return AttributeUtils.getExceptionTableAttribute(attributes);
}
public final LocalVariableTable getLocalVariableTable() {
Code code = getCode();
if (code != null)
return code.getLocalVariableTable();
return null;
}
public final LineNumberTable getLineNumberTable() {
Code code = getCode();
if (code != null)
return code.getLineNumberTable();
return null;
}
@Override
public final String toString() {
ConstantUtf8 c;
String name, signature, access;
StringBuffer buf;
access = Utility.accessToString(modifiers);
c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8);
signature = c.getValue();
c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8);
name = c.getValue();
signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable());
buf = new StringBuffer(signature);
for (int i = 0; i < attributes.length; i++) {
Attribute a = attributes[i];
if (!((a instanceof Code) || (a instanceof ExceptionTable)))
buf.append(" [" + a.toString() + "]");
}
ExceptionTable e = getExceptionTable();
if (e != null) {
String str = e.toString();
if (!str.equals(""))
buf.append("\n\t\tthrows " + str);
}
return buf.toString();
}
public Type getReturnType() {
return Type.getReturnType(getSignature());
}
public Type[] getArgumentTypes() {
return Type.getArgumentTypes(getSignature());
}
private void ensureParameterAnnotationsUnpacked() {
if (!parameterAnnotationsOutOfDate)
return;
parameterAnnotationsOutOfDate = false;
int parameterCount = getArgumentTypes().length;
if (parameterCount == 0) {
unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS;
return;
}
RuntimeVisParamAnnos parameterAnnotationsVis = null;
RuntimeInvisParamAnnos parameterAnnotationsInvis = null;
Attribute[] attrs = getAttributes();
for (int i = 0; i < attrs.length; i++) {
Attribute attribute = attrs[i];
if (attribute instanceof RuntimeVisParamAnnos) {
parameterAnnotationsVis = (RuntimeVisParamAnnos) attribute;
} else if (attribute instanceof RuntimeInvisParamAnnos) {
parameterAnnotationsInvis = (RuntimeInvisParamAnnos) attribute;
}
}
boolean foundSome = false;
if (parameterAnnotationsInvis != null || parameterAnnotationsVis != null) {
List<AnnotationGen[]> annotationsForEachParameter = new ArrayList<AnnotationGen[]>();
AnnotationGen[] visibleOnes = null;
AnnotationGen[] invisibleOnes = null;
for (int i = 0; i < parameterCount; i++) {
int count = 0;
visibleOnes = new AnnotationGen[0];
invisibleOnes = new AnnotationGen[0];
if (parameterAnnotationsVis != null) {
visibleOnes = parameterAnnotationsVis.getAnnotationsOnParameter(i);
count += visibleOnes.length;
}
if (parameterAnnotationsInvis != null) {
invisibleOnes = parameterAnnotationsInvis.getAnnotationsOnParameter(i);
count += invisibleOnes.length;
}
AnnotationGen[] complete = AnnotationGen.NO_ANNOTATIONS;
if (count != 0) {
complete = new AnnotationGen[visibleOnes.length + invisibleOnes.length];
System.arraycopy(visibleOnes, 0, complete, 0, visibleOnes.length);
System.arraycopy(invisibleOnes, 0, complete, visibleOnes.length, invisibleOnes.length);
foundSome = true;
}
annotationsForEachParameter.add(complete);
}
if (foundSome) {
unpackedParameterAnnotations = annotationsForEachParameter.toArray(new AnnotationGen[][] {});
return;
}
}
unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS;
}
public AnnotationGen[] getAnnotationsOnParameter(int i) {
ensureParameterAnnotationsUnpacked();
if (unpackedParameterAnnotations == NO_PARAMETER_ANNOTATIONS) {
return AnnotationGen.NO_ANNOTATIONS;
}
return unpackedParameterAnnotations[i];
}
public AnnotationGen[][] getParameterAnnotations() {
ensureParameterAnnotationsUnpacked();
return unpackedParameterAnnotations;
}
}