proguard.classfile.visitor.ReferencedClassVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proguard-core Show documentation
Show all versions of proguard-core Show documentation
ProGuardCORE is a free library to read, analyze, modify, and write Java class files.
/*
* ProGuardCORE -- library to process Java bytecode.
*
* Copyright (c) 2002-2020 Guardsquare NV
*
* 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 proguard.classfile.visitor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.kotlin.*;
import proguard.classfile.kotlin.visitor.*;
/**
* This {@link ClassVisitor}, {@link MemberVisitor}, {@link ConstantVisitor}, {@link AttributeVisitor}, etc.
* lets a given {@link ClassVisitor} visit all the referenced classes of the elements
* that it visits. Only downstream elements are considered (in order to avoid
* loops and repeated visits)
*
* It also considers references in the Kotlin metadata of this class, if includeKotlinMetadata = true.
* So that, for example, a Kotlin function referencing a type alias
* will execute the delegate class visitor for the referencedClass of the alias.
*
* @author Eric Lafortune
* @author James Hamilton
*/
public class ReferencedClassVisitor
implements ClassVisitor,
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor,
AnnotationVisitor,
ElementValueVisitor
{
private final ClassVisitor classVisitor;
private final KotlinReferencedClassVisitor kotlinReferencedClassVisitor;
public ReferencedClassVisitor(ClassVisitor classVisitor)
{
this(false, classVisitor);
}
public ReferencedClassVisitor(boolean includeKotlinMetadata,
ClassVisitor classVisitor)
{
this.classVisitor = classVisitor;
this.kotlinReferencedClassVisitor = includeKotlinMetadata ? new KotlinReferencedClassVisitor() : null;
}
// Implementations for ClassVisitor.
@Override
public void visitAnyClass(Clazz clazz)
{
throw new UnsupportedOperationException(this.getClass().getName() + " does not support " + clazz.getClass().getName());
}
@Override
public void visitProgramClass(ProgramClass programClass)
{
// Visit the constant pool entries.
programClass.constantPoolEntriesAccept(this);
// Visit the fields and methods.
programClass.fieldsAccept(this);
programClass.methodsAccept(this);
// Visit the attributes.
programClass.attributesAccept(this);
if (kotlinReferencedClassVisitor != null)
{
programClass.kotlinMetadataAccept(kotlinReferencedClassVisitor);
}
}
@Override
public void visitLibraryClass(LibraryClass libraryClass)
{
// Visit the superclass and interfaces.
libraryClass.superClassAccept(classVisitor);
libraryClass.interfacesAccept(classVisitor);
// Visit the fields and methods.
libraryClass.fieldsAccept(this);
libraryClass.methodsAccept(this);
if (kotlinReferencedClassVisitor != null)
{
libraryClass.kotlinMetadataAccept(kotlinReferencedClassVisitor);
}
}
// Implementations for MemberVisitor.
@Override
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
// Let the visitor visit the classes referenced in the descriptor string.
programMember.referencedClassesAccept(classVisitor);
// Visit the attributes.
programMember.attributesAccept(programClass, this);
}
@Override
public void visitLibraryMember(LibraryClass programClass, LibraryMember libraryMember)
{
// Let the visitor visit the classes referenced in the descriptor string.
libraryMember.referencedClassesAccept(classVisitor);
}
// Implementations for ConstantVisitor.
@Override
public void visitAnyConstant(Clazz clazz, Constant constant) {}
@Override
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
// Let the visitor visit the class referenced in the string constant.
stringConstant.referencedClassAccept(classVisitor);
}
@Override
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
// Let the visitor visit the class referenced in the reference constant.
refConstant.referencedClassAccept(classVisitor);
}
@Override
public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
{
// Let the visitor visit the class referenced in the reference constant.
invokeDynamicConstant.referencedClassesAccept(classVisitor);
}
@Override
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Let the visitor visit the class referenced in the class constant.
classConstant.referencedClassAccept(classVisitor);
}
@Override
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
// Let the visitor visit the classes referenced in the method type constant.
methodTypeConstant.referencedClassesAccept(classVisitor);
}
// Implementations for AttributeVisitor.
@Override
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
@Override
public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
{
// Let the visitor visit the class of the enclosing method.
enclosingMethodAttribute.referencedClassAccept(classVisitor);
}
@Override
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
// Visit the attributes of the code attribute.
codeAttribute.attributesAccept(clazz, method, this);
}
@Override
public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
{
// Visit the local variables.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
@Override
public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
{
// Visit the local variable types.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
}
@Override
public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
{
// Let the visitor visit the classes referenced in the signature string.
signatureAttribute.referencedClassesAccept(classVisitor);
}
@Override
public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
{
// Visit the annotations.
annotationsAttribute.annotationsAccept(clazz, this);
}
@Override
public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
{
// Visit the parameter annotations.
parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
}
@Override
public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
{
// Visit the default element value.
annotationDefaultAttribute.defaultValueAccept(clazz, this);
}
// Implementations for LocalVariableInfoVisitor.
@Override
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
// Let the visitor visit the class referenced in the local variable.
localVariableInfo.referencedClassAccept(classVisitor);
}
// Implementations for LocalVariableTypeInfoVisitor.
@Override
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
// Let the visitor visit the classes referenced in the local variable type.
localVariableTypeInfo.referencedClassesAccept(classVisitor);
}
// Implementations for AnnotationVisitor.
@Override
public void visitAnnotation(Clazz clazz, Annotation annotation)
{
// Let the visitor visit the classes referenced in the annotation.
annotation.referencedClassesAccept(classVisitor);
// Visit the element values.
annotation.elementValuesAccept(clazz, this);
}
// Implementations for ElementValueVisitor.
@Override
public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue) {}
@Override
public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
{
// Let the visitor visit the classes referenced in the constant element value.
enumConstantElementValue.referencedClassesAccept(classVisitor);
}
@Override
public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
{
// Let the visitor visit the classes referenced in the class element value.
classElementValue.referencedClassesAccept(classVisitor);
}
@Override
public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
{
// Visit the contained annotation.
annotationElementValue.annotationAccept(clazz, this);
}
@Override
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
// Visit the element values.
arrayElementValue.elementValuesAccept(clazz, annotation, this);
}
private class KotlinReferencedClassVisitor
implements KotlinMetadataVisitor,
KotlinTypeVisitor,
KotlinTypeAliasVisitor,
KotlinFunctionVisitor,
KotlinTypeParameterVisitor,
KotlinValueParameterVisitor,
KotlinPropertyVisitor,
KotlinAnnotationVisitor,
KotlinAnnotationArgumentVisitor
{
// Implementations for KotlinTypeVisitor.
@Override
public void visitAnyType(Clazz clazz, KotlinTypeMetadata kotlinTypeMetadata)
{
if (kotlinTypeMetadata.referencedClass != null)
{
kotlinTypeMetadata.referencedClass.accept(classVisitor);
}
kotlinTypeMetadata.annotationsAccept(clazz, this);
}
// Implementations for KotlinMetadataVisitor.
@Override
public void visitAnyKotlinMetadata(Clazz clazz, KotlinMetadata kotlinMetadata) { }
@Override
public void visitKotlinDeclarationContainerMetadata(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata)
{
kotlinDeclarationContainerMetadata.typeAliasesAccept(clazz, this);
kotlinDeclarationContainerMetadata.functionsAccept(clazz, this);
kotlinDeclarationContainerMetadata.propertiesAccept(clazz, this);
kotlinDeclarationContainerMetadata.delegatedPropertiesAccept(clazz, this);
}
@Override
public void visitKotlinSyntheticClassMetadata(Clazz clazz,
KotlinSyntheticClassKindMetadata kotlinSyntheticClassKindMetadata)
{
kotlinSyntheticClassKindMetadata.functionsAccept(clazz, this);
}
// Implementations for KotlinTypeAliasVisitor.
@Override
public void visitTypeAlias(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinTypeAliasMetadata kotlinTypeAliasMetadata)
{
kotlinTypeAliasMetadata.annotationsAccept( clazz, this);
kotlinTypeAliasMetadata.typeParametersAccept(clazz, kotlinDeclarationContainerMetadata, this);
kotlinTypeAliasMetadata.expandedTypeAccept( clazz, kotlinDeclarationContainerMetadata, this);
kotlinTypeAliasMetadata.underlyingTypeAccept(clazz, kotlinDeclarationContainerMetadata, this);
}
// Implementations for KotlinFunctionVisitor.
@Override
public void visitAnyFunction(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata)
{
kotlinFunctionMetadata.receiverTypeAccept(clazz, kotlinMetadata, this);
kotlinFunctionMetadata.returnTypeAccept(clazz, kotlinMetadata, this);
kotlinFunctionMetadata.typeParametersAccept(clazz, kotlinMetadata, this);
kotlinFunctionMetadata.valueParametersAccept(clazz, kotlinMetadata, this);
}
// Implementations for KotlinTypeParameterVisitor.
@Override
public void visitAnyTypeParameter(Clazz clazz, KotlinTypeParameterMetadata kotlinTypeParameterMetadata)
{
kotlinTypeParameterMetadata.annotationsAccept(clazz, this);
kotlinTypeParameterMetadata.upperBoundsAccept(clazz, this);
}
// Implementations for KotlinValueParameterVisitor.
@Override
public void visitAnyValueParameter(Clazz clazz, KotlinValueParameterMetadata kotlinValueParameterMetadata) { }
@Override
public void visitConstructorValParameter(Clazz clazz,
KotlinClassKindMetadata kotlinClassKindMetadata,
KotlinConstructorMetadata kotlinConstructorMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata)
{
kotlinValueParameterMetadata.typeAccept(clazz, kotlinClassKindMetadata, kotlinConstructorMetadata, this);
}
@Override
public void visitFunctionValParameter(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata)
{
kotlinValueParameterMetadata.typeAccept(clazz, kotlinMetadata, kotlinFunctionMetadata, this);
}
@Override
public void visitPropertyValParameter(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata)
{
kotlinValueParameterMetadata.typeAccept(clazz, kotlinDeclarationContainerMetadata, kotlinPropertyMetadata, this);
}
// Implementations for KotlinPropertyVisitor.
@Override
public void visitAnyProperty(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata)
{
kotlinPropertyMetadata.receiverTypeAccept( clazz, kotlinDeclarationContainerMetadata, this);
kotlinPropertyMetadata.typeAccept( clazz, kotlinDeclarationContainerMetadata, this);
kotlinPropertyMetadata.setterParametersAccept(clazz, kotlinDeclarationContainerMetadata, this);
kotlinPropertyMetadata.typeParametersAccept( clazz, kotlinDeclarationContainerMetadata, this);
}
// Implementations for KotlinAnnotationVisitor.
@Override
public void visitAnyAnnotation(Clazz clazz, KotlinAnnotatable annotatable, KotlinAnnotation annotation)
{
annotation.referencedClassAccept(classVisitor);
annotation.argumentsAccept(clazz, annotatable, this);
}
// Implementations for KotlinAnnotationArgumentVisitor
@Override
public void visitAnyArgument(Clazz clazz, KotlinAnnotatable annotatable, KotlinAnnotation annotation, KotlinAnnotationArgument argument, KotlinAnnotationArgument.Value value)
{
argument.referencedMethodAccept(new ReferencedClassVisitor(classVisitor));
}
@Override
public void visitClassArgument(Clazz clazz, KotlinAnnotatable annotatable, KotlinAnnotation annotation, KotlinAnnotationArgument argument, KotlinAnnotationArgument.ClassValue value)
{
this.visitAnyArgument(clazz, annotatable, annotation, argument, value);
value.referencedClassAccept(classVisitor);
}
@Override
public void visitEnumArgument(Clazz clazz, KotlinAnnotatable annotatable, KotlinAnnotation annotation, KotlinAnnotationArgument argument, KotlinAnnotationArgument.EnumValue value)
{
this.visitAnyArgument(clazz, annotatable, annotation, argument, value);
value.referencedClassAccept(classVisitor);
}
@Override
public void visitArrayArgument(Clazz clazz, KotlinAnnotatable annotatable, KotlinAnnotation annotation, KotlinAnnotationArgument argument, KotlinAnnotationArgument.ArrayValue value)
{
this.visitAnyArgument(clazz, annotatable, annotation, argument, value);
value.elementsAccept(clazz, annotatable, annotation, argument, this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy