Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.jar.asm.AnnotationVisitor;
import net.bytebuddy.jar.asm.ClassReader;
Expand All @@ -34,17 +33,11 @@ public TypeDescription parse(Class<?> loadedType) {

TypeOutline typeOutline =
new TypeOutline(
ClassFileVersion.ofThisVm().getMinorMajorVersion(),
loadedType.getModifiers(),
loadedType.getName(),
null != superClass ? superClass.getName() : null,
extractTypeNames(loadedType.getInterfaces()));

Class<?> declaringClass = loadedType.getDeclaringClass();
if (null != declaringClass) {
typeOutline.declaredBy(declaringClass.getName());
}

for (Annotation a : loadedType.getDeclaredAnnotations()) {
typeOutline.declare(annotationOutline(Type.getDescriptor(a.annotationType())));
}
Expand Down Expand Up @@ -91,7 +84,6 @@ static final class OutlineTypeExtractor extends ClassVisitor {
TypeOutline typeOutline;
FieldOutline fieldOutline;
MethodOutline methodOutline;
boolean selfContained = true;

OutlineTypeExtractor() {
super(OpenedClassReader.ASM_API);
Expand All @@ -105,23 +97,7 @@ public void visit(
String signature,
String superName,
String[] interfaces) {
typeOutline = new TypeOutline(version, access, name, superName, interfaces);
}

@Override
public void visitOuterClass(String owner, String name, String descriptor) {
selfContained = false;
}

@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (typeOutline.getInternalName().equals(name)) {
if (null != outerName) {
typeOutline.declaredBy(outerName);
} else if (null == innerName && !selfContained) {
typeOutline.anonymousType();
}
}
typeOutline = new TypeOutline(access, name, superName, interfaces);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,6 @@ public TypeList.Generic getInterfaces() {
return outline().getInterfaces();
}

@Override
public TypeDescription getDeclaringType() {
return outline().getDeclaringType();
}

@Override
public boolean isPublic() {
return isPublicFilter.contains(name) || super.isPublic();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import java.util.ArrayList;
import java.util.List;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.field.FieldDescription;
Expand All @@ -27,21 +26,17 @@ final class TypeOutline extends WithName {
private static final MethodList<MethodDescription.InDefinedShape> NO_METHODS =
new MethodList.Empty<>();

private final int classFileVersion;
private final int modifiers;
private final String superName;
private final String[] interfaces;
private String declaringName;
private boolean anonymousType;

private List<AnnotationDescription> declaredAnnotations;

private final List<FieldDescription.InDefinedShape> declaredFields = new ArrayList<>();
private final List<MethodDescription.InDefinedShape> declaredMethods = new ArrayList<>();

TypeOutline(int version, int access, String internalName, String superName, String[] interfaces) {
TypeOutline(int access, String internalName, String superName, String[] interfaces) {
super(internalName.replace('/', '.'));
this.classFileVersion = version;
this.modifiers = access & ALLOWED_TYPE_MODIFIERS;
this.superName = superName;
this.interfaces = interfaces;
Expand Down Expand Up @@ -72,19 +67,6 @@ public TypeList.Generic getInterfaces() {
return new TypeList.Generic.Explicit(outlines);
}

@Override
public TypeDescription getDeclaringType() {
if (null != declaringName) {
return findType(declaringName.replace('/', '.'));
}
return null;
}

@Override
public TypeDescription getEnclosingType() {
return getDeclaringType(); // equivalent for outline purposes
}

@Override
public int getModifiers() {
return modifiers;
Expand Down Expand Up @@ -114,11 +96,6 @@ private boolean matchesMask(int mask) {
return (this.getModifiers() & mask) == mask;
}

@Override
public ClassFileVersion getClassFileVersion() {
return ClassFileVersion.ofMinorMajor(classFileVersion);
}

@Override
public AnnotationList getDeclaredAnnotations() {
return null == declaredAnnotations
Expand All @@ -136,15 +113,6 @@ public MethodList<MethodDescription.InDefinedShape> getDeclaredMethods() {
return declaredMethods.isEmpty() ? NO_METHODS : new MethodList.Explicit<>(declaredMethods);
}

@Override
public boolean isAnonymousType() {
return anonymousType;
}

void declaredBy(String declaringName) {
this.declaringName = declaringName;
}

void declare(AnnotationDescription annotation) {
if (null != annotation) {
if (null == declaredAnnotations) {
Expand All @@ -165,8 +133,4 @@ void declare(MethodDescription.InDefinedShape method) {
declaredMethods.add(method);
}
}

void anonymousType() {
anonymousType = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import spock.lang.Specification

class OutlineTypeParserTest extends Specification {

void 'test modifiers are correct and anonymous classes are detected'() {
void 'test modifiers are correct'() {
setup:
final parser = new OutlineTypeParser()
final locator = ClassFileLocators.classFileLocator(Thread.currentThread().contextClassLoader)
Expand All @@ -15,12 +15,13 @@ class OutlineTypeParserTest extends Specification {
final outline = parser.parse(bytes)

then:
outline.anonymousType == anonymous
outline.interface == isinterface
outline.abstract == isabstract
outline.annotation == annotation
outline.enum == isenum

// isAnonymousType is no longer supported in outlines for performance reasons

where:
clazz | anonymous | isinterface | isabstract | annotation | isenum
'datadog.trace.agent.test.EnclosedClasses' | false | false | false | false | false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,30 @@ protected boolean doMatch(TypeDescription target) {
}
};

// this deliberately only considers anonymous types following the Java naming convention
private static final ElementMatcher.Junction<TypeDescription> ANONYMOUS_TYPE_MATCHER =
new ElementMatcher.Junction.ForNonNullValues<TypeDescription>() {
@Override
protected boolean doMatch(TypeDescription target) {
String name = target.getName();
// search the name in reverse until we find a $ or non-digit
for (int end = name.length() - 1, i = end; i > 0; i--) {
char c = name.charAt(i);
if (c == '$' && i < end) {
return true; // only seen digits so far, assume anonymous
} else if (c < '0' || c > '9') {
break; // non-digit character found, assume not anonymous
}
}
return false;
}
};

static {
if (Config.get().isIastAnonymousClassesEnabled()) {
INSTANCE = TRIE_MATCHER;
} else {
INSTANCE = TRIE_MATCHER.and(not(TypeDescription::isAnonymousType));
INSTANCE = TRIE_MATCHER.and(not(ANONYMOUS_TYPE_MATCHER));
}
}
}
Expand Down