blob: 57ccbdc54e5005444cb4a03ed3006e9bf7d67560 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.class2greylist;
import org.apache.bcel.classfile.AnnotationEntry;
import org.apache.bcel.classfile.DescendingVisitor;
import org.apache.bcel.classfile.EmptyVisitor;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.FieldOrMethod;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import java.util.Map;
/**
* Visits a JavaClass instance and passes any annotated members to a {@link AnnotationHandler}
* according to the map provided.
*/
public class AnnotationVisitor extends EmptyVisitor {
private final JavaClass mClass;
private final Status mStatus;
private final DescendingVisitor mDescendingVisitor;
private final Map<String, AnnotationHandler> mAnnotationHandlers;
/**
* Creates a visitor for a class.
*
* @param clazz Class to visit
* @param status For reporting debug information
* @param handlers Map of {@link AnnotationHandler}. The keys should be annotation names, as
* class descriptors.
*/
public AnnotationVisitor(JavaClass clazz, Status status,
Map<String, AnnotationHandler> handlers) {
mClass = clazz;
mStatus = status;
mAnnotationHandlers = handlers;
mDescendingVisitor = new DescendingVisitor(clazz, this);
}
public void visit() {
mStatus.debug("Visit class %s", mClass.getClassName());
mDescendingVisitor.visit();
}
@Override
public void visitMethod(Method method) {
visitMember(method, "L%s;->%s%s");
}
@Override
public void visitField(Field field) {
visitMember(field, "L%s;->%s:%s");
}
private void visitMember(FieldOrMethod member, String signatureFormatString) {
mStatus.debug("Visit member %s : %s", member.getName(), member.getSignature());
AnnotationContext context = new AnnotationContext(mStatus, member,
(JavaClass) mDescendingVisitor.predecessor(), signatureFormatString);
for (AnnotationEntry a : member.getAnnotationEntries()) {
if (mAnnotationHandlers.containsKey(a.getAnnotationType())) {
mStatus.debug("Member has annotation %s for which we have a handler",
a.getAnnotationType());
mAnnotationHandlers.get(a.getAnnotationType()).handleAnnotation(a, context);
} else {
mStatus.debug("Member has annotation %s for which we do not have a handler",
a.getAnnotationType());
}
}
}
}