Skip to content

Commit

Permalink
Added support for enclosing method and general inner class info
Browse files Browse the repository at this point in the history
  • Loading branch information
n1hility committed Oct 6, 2014
1 parent 1992f26 commit 6fe7481
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 21 deletions.
4 changes: 4 additions & 0 deletions src/main/java/org/jboss/jandex/AnnotationInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ public String toString(boolean simple) {
}

void setTarget(AnnotationTarget target) {
if (this.target != null) {
throw new IllegalStateException("Attempt to modify target post-initialization");
}

this.target = target;
}

Expand Down
26 changes: 13 additions & 13 deletions src/main/java/org/jboss/jandex/AnnotationValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,55 +73,55 @@ public abstract class AnnotationValue {
this.name = name;
}

public static final AnnotationValue createByteValue(String name, byte b) {
public static AnnotationValue createByteValue(String name, byte b) {
return new ByteValue(name, b);
}

public static final AnnotationValue createShortValue(String name, short s) {
public static AnnotationValue createShortValue(String name, short s) {
return new ShortValue(name, s);
}

public static final AnnotationValue createIntegerValue(String name, int i) {
public static AnnotationValue createIntegerValue(String name, int i) {
return new IntegerValue(name, i);
}

public static final AnnotationValue createCharacterValue(String name, char c) {
public static AnnotationValue createCharacterValue(String name, char c) {
return new CharacterValue(name, c);
}

public static final AnnotationValue createFloatValue(String name, float f) {
public static AnnotationValue createFloatValue(String name, float f) {
return new FloatValue(name, f);
}

public static final AnnotationValue createDouleValue(String name, double d) {
public static AnnotationValue createDouleValue(String name, double d) {
return new DoubleValue(name, d);
}

public static final AnnotationValue createLongalue(String name, long l) {
public static AnnotationValue createLongalue(String name, long l) {
return new LongValue(name, l);
}

public static final AnnotationValue createBooleanValue(String name, boolean bool) {
public static AnnotationValue createBooleanValue(String name, boolean bool) {
return new BooleanValue(name, bool);
}

public static final AnnotationValue createStringValue(String name, String string) {
public static AnnotationValue createStringValue(String name, String string) {
return new StringValue(name, string);
}

public static final AnnotationValue createClassValue(String name, Type type) {
public static AnnotationValue createClassValue(String name, Type type) {
return new ClassValue(name, type);
}

public static final AnnotationValue createEnumValue(String name, DotName typeName, String value) {
public static AnnotationValue createEnumValue(String name, DotName typeName, String value) {
return new EnumValue(name, typeName, value);
}

public static final AnnotationValue createArrayValue(String name, AnnotationValue[] values) {
public static AnnotationValue createArrayValue(String name, AnnotationValue[] values) {
return new ArrayValue(name, values);
}

public static final AnnotationValue createNestedAnnotationValue(String name, AnnotationInstance instance)
public static AnnotationValue createNestedAnnotationValue(String name, AnnotationInstance instance)
{
return new NestedAnnotation(name, instance);
}
Expand Down
99 changes: 96 additions & 3 deletions src/main/java/org/jboss/jandex/ClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package org.jboss.jandex;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -51,14 +50,67 @@ public final class ClassInfo implements AnnotationTarget {
private final DotName superName;
private final List<DotName> interfaces;
private final Map<DotName, List<AnnotationInstance>> annotations;

// Not final to allow lazy initialization, immutable once published
private List<Type> interfaceTypes;
private Type superClassType;
private List<Type> typeParameters;
private List<MethodInfo> methods;
private List<FieldInfo> fields;

// Not final to allow lazy initialization, immutable once published
private boolean hasNoArgsConstructor;
private NestingInfo nestingInfo;

public enum NestingType {TOP_LEVEL, INNER, LOCAL, ANONYMOUS}

private static final class NestingInfo {
private DotName enclosingClass;
private String simpleName;
private EnclosingMethodInfo enclosingMethod;
}

public static final class EnclosingMethodInfo {
private String name;
private Type returnType;
private List<Type> parameters;
private DotName enclosingClass;


public String name() {
return name;
}

public Type returnType() {
return returnType;
}

public List<Type> parameters() {
return parameters;
}

public DotName enclosingClass() {
return enclosingClass;
}

EnclosingMethodInfo(String name, Type returnType, List<Type> parameters, DotName enclosingClass) {
this.name = name;
this.returnType = returnType;
this.parameters = Collections.unmodifiableList(parameters);
this.enclosingClass = enclosingClass;
}

public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(returnType).append(' ').append(enclosingClass).append('.').append(name).append('(');
for (int i = 0; i < parameters.size(); i++) {
builder.append(parameters.get(i));
if (i + 1 < parameters.size())
builder.append(", ");
}
builder.append(')');
return builder.toString();
}

}

ClassInfo(DotName name, DotName superName, short flags, List<DotName> interfaces, Map<DotName, List<AnnotationInstance>> annotations) {
this(name, superName, flags, interfaces, annotations, false);
Expand Down Expand Up @@ -149,6 +201,30 @@ public final boolean hasNoArgsConstructor() {
return hasNoArgsConstructor;
}

public NestingType nestingType() {
if (nestingInfo == null) {
return NestingType.TOP_LEVEL;
} else if (nestingInfo.enclosingClass != null) {
return NestingType.INNER;
} else if (nestingInfo.simpleName != null) {
return NestingType.LOCAL;
}

return NestingType.ANONYMOUS;
}

public String simpleName() {
return nestingInfo != null ? nestingInfo.simpleName : null;
}

public DotName enclosingClass() {
return nestingInfo != null ? nestingInfo.enclosingClass : null;
}

public EnclosingMethodInfo enclosingMethod() {
return nestingInfo != null ? nestingInfo.enclosingMethod : null;
}

/** Lazily initialize hasNoArgsConstructor. Can only be called before publication */
void setHasNoArgsConstructor(boolean hasNoArgsConstructor) {
this.hasNoArgsConstructor = hasNoArgsConstructor;
Expand All @@ -173,4 +249,21 @@ void setInterfaceTypes(List<Type> interfaceTypes) {
void setTypeParameters(List<Type> typeParameters) {
this.typeParameters = Collections.unmodifiableList(typeParameters);
}

void setInnerClassInfo(DotName enclosingClass, String simpleName) {
if (nestingInfo == null) {
nestingInfo = new NestingInfo();
}

nestingInfo.enclosingClass = enclosingClass;
nestingInfo.simpleName = simpleName;
}

void setEnclosingMethod(EnclosingMethodInfo enclosingMethod) {
if (nestingInfo == null) {
nestingInfo = new NestingInfo();
}

nestingInfo.enclosingMethod = enclosingMethod;
}
}
67 changes: 63 additions & 4 deletions src/main/java/org/jboss/jandex/Indexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.jboss.jandex;

import static org.jboss.jandex.ClassInfo.EnclosingMethodInfo;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
Expand Down Expand Up @@ -119,19 +121,26 @@ public final class Indexer {
0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73
};

// "EnclosingMethod"
private final static byte[] ENCLOSING_METHOD = new byte[] {
0x45, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64
};

private final static int RUNTIME_ANNOTATIONS_LEN = RUNTIME_ANNOTATIONS.length;
private final static int RUNTIME_PARAM_ANNOTATIONS_LEN = RUNTIME_PARAM_ANNOTATIONS.length;
private final static int RUNTIME_TYPE_ANNOTATIONS_LEN = RUNTIME_TYPE_ANNOTATIONS.length;
private final static int SIGNATURE_LEN = SIGNATURE.length;
private final static int EXCEPTIONS_LEN = EXCEPTIONS.length;
private final static int INNER_CLASSES_LEN = INNER_CLASSES.length;
private final static int ENCLOSING_METHOD_LEN = ENCLOSING_METHOD.length;

private final static int HAS_RUNTIME_ANNOTATION = 1;
private final static int HAS_RUNTIME_PARAM_ANNOTATION = 2;
private final static int HAS_RUNTIME_TYPE_ANNOTATION = 3;
private final static int HAS_SIGNATURE = 4;
private final static int HAS_EXCEPTIONS = 5;
private final static int HAS_INNNER_CLASSES = 6;
private final static int HAS_INNER_CLASSES = 6;
private final static int HAS_ENCLOSING_METHOD = 7;

private final static String INIT_METHOD_NAME = "<init>";
private IdentityHashMap<AnnotationTarget, Object> signaturePresent;
Expand Down Expand Up @@ -241,7 +250,6 @@ private void processMethodInfo(DataInputStream data) throws IOException {

IntegerHolder pos = new IntegerHolder();
List<Type> parameters = parseMethodArgs(descriptor, pos);
pos.i++;
Type returnType = parseType(descriptor, pos);

MethodInfo method = new MethodInfo(currentClass, name, parameters, returnType, flags);
Expand Down Expand Up @@ -333,8 +341,10 @@ private void processAttributes(DataInputStream data, AnnotationTarget target) th
processSignature(data, target);
} else if (annotationAttribute == HAS_EXCEPTIONS && target instanceof MethodInfo) {
processExceptions(data, (MethodInfo) target);
} else if (annotationAttribute == HAS_INNNER_CLASSES && target instanceof ClassInfo) {
} else if (annotationAttribute == HAS_INNER_CLASSES && target instanceof ClassInfo) {
processInnerClasses(data, (ClassInfo) target);
} else if (annotationAttribute == HAS_ENCLOSING_METHOD && target instanceof ClassInfo) {
processEnclosingMethod(data, (ClassInfo) target);
} else {
skipFully(data, attributeLen);
}
Expand All @@ -359,10 +369,32 @@ private void processInnerClasses(DataInputStream data, ClassInfo target) throws
String simpleName = simpleIndex == 0 ? null : decodeUtf8Entry(simpleIndex);
int flags = data.readUnsignedShort();

if (innerClass.equals(target.name())) {
target.setInnerClassInfo(outerClass, simpleName);
}

innerClasses.put(innerClass, new InnerClassInfo(innerClass, outerClass, simpleName, flags));
}
}

private void processEnclosingMethod(DataInputStream data, ClassInfo target) throws IOException {
int classIndex = data.readUnsignedShort();
int index = data.readUnsignedShort();
if (index == 0) {
return; // Enclosed in a static or an instance variable
}

DotName enclosingClass = decodeClassEntry(classIndex);
NameAndType nameAndType = decodeNameAndTypeEntry(index);

IntegerHolder pos = new IntegerHolder();
List<Type> parameters = parseMethodArgs(nameAndType.descriptor, pos);
Type returnType = parseType(nameAndType.descriptor, pos);

EnclosingMethodInfo method = new EnclosingMethodInfo(nameAndType.name, returnType, parameters, enclosingClass);
target.setEnclosingMethod(method);
}


private void processTypeAnnotations(DataInputStream data, AnnotationTarget target) throws IOException {
int numAnnotations = data.readUnsignedShort();
Expand Down Expand Up @@ -1001,6 +1033,30 @@ private String decodeUtf8Entry(int index) {
return new String(pool, ++pos, len, Charset.forName("UTF-8"));
}

private static class NameAndType {
private String name;
private String descriptor;

private NameAndType(String name, String descriptor) {
this.name = name;
this.descriptor = descriptor;
}
}

private NameAndType decodeNameAndTypeEntry(int index) {
byte[] pool = constantPool;
int[] offsets = constantPoolOffsets;

int pos = offsets[index - 1];
if (pool[pos] != CONSTANT_NAMEANDTYPE)
throw new IllegalStateException("Constant pool entry is not a name and type type: " + index + ":" + pos);

int nameIndex = (pool[++pos] & 0xFF) << 8 | (pool[++pos] & 0xFF);
int descriptorIndex = (pool[++pos] & 0xFF) << 8 | (pool[++pos] & 0xFF);

return new NameAndType(intern(decodeUtf8Entry(nameIndex)), decodeUtf8Entry(descriptorIndex));
}

private int bitsToInt(byte[] pool, int pos) {
return (pool[++pos] & 0xFF) << 24 | (pool[++pos] & 0xFF) << 16 | (pool[++pos] & 0xFF) << 8 | (pool[++pos] & 0xFF);
}
Expand Down Expand Up @@ -1079,6 +1135,7 @@ private List<Type> parseMethodArgs(String descriptor, IntegerHolder pos) {
types.add(parseType(descriptor, pos));
}

pos.i++;
return types;
}

Expand Down Expand Up @@ -1189,7 +1246,9 @@ private boolean processConstantPool(DataInputStream stream) throws IOException {
} else if (len == EXCEPTIONS_LEN && match(buf, offset, EXCEPTIONS)) {
annoAttributes[pos] = HAS_EXCEPTIONS;
} else if (len == INNER_CLASSES_LEN && match(buf, offset, INNER_CLASSES)) {
annoAttributes[pos] = HAS_INNNER_CLASSES;
annoAttributes[pos] = HAS_INNER_CLASSES;
} else if (len == ENCLOSING_METHOD_LEN && match(buf, offset, ENCLOSING_METHOD)) {
annoAttributes[pos] = HAS_ENCLOSING_METHOD;
}
offset += len;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public void testIndexer() throws IOException {
System.out.println(field.type());
}

for (MethodInfo method : index.getClassByName(DotName.createSimple("org.wildfly.security.VExample$1Fun")).methods()) {
ClassInfo localClazz = index.getClassByName(DotName.createSimple("org.wildfly.security.VExample$1Fun"));
for (MethodInfo method : localClazz.methods()) {
Type[] args = method.args();
if (args.length > 0) {
System.out.println(args[0]);
Expand All @@ -82,6 +83,9 @@ public void testIndexer() throws IOException {
}
System.out.println(clazz.superClassType());

System.out.println(localClazz.enclosingMethod());
System.out.println(localClazz.nestingType());
System.out.println(localClazz.enclosingClass());
}


Expand Down

0 comments on commit 6fe7481

Please sign in to comment.