MetricsGatherer.java

/*
 *  Copyright (c) 2001-2024, Jean Tessier
 *  All rights reserved.
 *  
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *  
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *  
 *      * Neither the name of Jean Tessier nor the names of his contributors
 *        may be used to endorse or promote products derived from this software
 *        without specific prior written permission.
 *  
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jeantessier.classreader;

import java.util.*;
import java.util.stream.*;

public class MetricsGatherer extends VisitorBase {
    private final Collection<String> classes = new TreeSet<>();
    private final Collection<String> interfaces = new TreeSet<>();
    private final Collection<Method_info> methods = new TreeSet<>();
    private final Collection<Field_info> fields = new TreeSet<>();
    private final Collection<Classfile> syntheticClasses = new TreeSet<>();
    private final Collection<Field_info> syntheticFields = new TreeSet<>();
    private final Collection<Method_info> syntheticMethods = new TreeSet<>();
    private final Collection<InnerClass> syntheticInnerClasses = new TreeSet<>();
    private final Collection<Classfile> annotationClasses = new TreeSet<>();
    private final Collection<InnerClass> annotationInnerClasses = new TreeSet<>();
    private final Collection<Classfile> enumClasses = new TreeSet<>();
    private final Collection<Field_info> enumFields = new TreeSet<>();
    private final Collection<InnerClass> enumInnerClasses = new TreeSet<>();
    private final Collection<Classfile> deprecatedClasses = new TreeSet<>();
    private final Collection<Field_info> deprecatedFields = new TreeSet<>();
    private final Collection<Method_info> deprecatedMethods = new TreeSet<>();
    private final Collection<Classfile> publicClasses = new TreeSet<>();
    private final Collection<Field_info> publicFields = new TreeSet<>();
    private final Collection<Method_info> publicMethods = new TreeSet<>();
    private final Collection<InnerClass> publicInnerClasses = new TreeSet<>();
    private final Collection<Field_info> protectedFields = new TreeSet<>();
    private final Collection<Method_info> protectedMethods = new TreeSet<>();
    private final Collection<InnerClass> protectedInnerClasses = new TreeSet<>();
    private final Collection<Field_info> privateFields = new TreeSet<>();
    private final Collection<Method_info> privateMethods = new TreeSet<>();
    private final Collection<InnerClass> privateInnerClasses = new TreeSet<>();
    private final Collection<Classfile> packageClasses = new TreeSet<>();
    private final Collection<Field_info> packageFields = new TreeSet<>();
    private final Collection<Method_info> packageMethods = new TreeSet<>();
    private final Collection<InnerClass> packageInnerClasses = new TreeSet<>();
    private final Collection<Classfile> abstractClasses = new TreeSet<>();
    private final Collection<Method_info> abstractMethods = new TreeSet<>();
    private final Collection<InnerClass> abstractInnerClasses = new TreeSet<>();
    private final Collection<Field_info> staticFields = new TreeSet<>();
    private final Collection<Method_info> staticMethods = new TreeSet<>();
    private final Collection<InnerClass> staticInnerClasses = new TreeSet<>();
    private final Collection<Classfile> finalClasses = new TreeSet<>();
    private final Collection<Field_info> finalFields = new TreeSet<>();
    private final Collection<Method_info> finalMethods = new TreeSet<>();
    private final Collection<InnerClass> finalInnerClasses = new TreeSet<>();
    private final Collection<Classfile> superClasses = new TreeSet<>();
    private final Collection<Classfile> moduleClasses = new TreeSet<>();
    private final Collection<Method_info> synchronizedMethods = new TreeSet<>();
    private final Collection<Method_info> nativeMethods = new TreeSet<>();
    private final Collection<Method_info> bridgeMethods = new TreeSet<>();
    private final Collection<Method_info> varargsMethods = new TreeSet<>();
    private final Collection<Method_info> strictMethods = new TreeSet<>();
    private final Collection<Field_info> volatileFields = new TreeSet<>();
    private final Collection<Field_info> transientFields = new TreeSet<>();
    private final Map<Integer, Long> constantPoolEntryCounts = new HashMap<>();
    private final Map<String, Long> attributeCounts = new HashMap<>();
    private final Collection<Custom_attribute> customAttributes = new LinkedList<>();
    private final long[] instructionCounts = new long[256];

    private boolean visitingConstantPool = false;

    public MetricsGatherer() {
        IntStream.rangeClosed(1, 20).filter(tag -> tag != 2 && tag != 13 && tag != 14).forEach(tag -> constantPoolEntryCounts.put(tag, 0L));
        Arrays.stream(AttributeType.values()).forEach(attributeType -> attributeCounts.put(attributeType.getAttributeName(), 0L));
        attributeCounts.put("Custom", 0L);
    }

    public Collection<String> getClasses() {
        return classes;
    }

    public Collection<String> getInterfaces() {
        return interfaces;
    }

    public Collection<Method_info> getMethods() {
        return methods;
    }

    public Collection<Field_info> getFields() {
        return fields;
    }

    public Collection<Classfile> getSyntheticClasses() {
        return syntheticClasses;
    }

    public Collection<Field_info> getSyntheticFields() {
        return syntheticFields;
    }

    public Collection<Method_info> getSyntheticMethods() {
        return syntheticMethods;
    }

    public Collection<InnerClass> getSyntheticInnerClasses() {
        return syntheticInnerClasses;
    }

    public Collection<Classfile> getAnnotationClasses() {
        return annotationClasses;
    }

    public Collection<InnerClass> getAnnotationInnerClasses() {
        return annotationInnerClasses;
    }

    public Collection<Classfile> getEnumClasses() {
        return enumClasses;
    }

    public Collection<Field_info> getEnumFields() {
        return enumFields;
    }

    public Collection<InnerClass> getEnumInnerClasses() {
        return enumInnerClasses;
    }

    public Collection<Classfile> getDeprecatedClasses() {
        return deprecatedClasses;
    }

    public Collection<Field_info> getDeprecatedFields() {
        return deprecatedFields;
    }

    public Collection<Method_info> getDeprecatedMethods() {
        return deprecatedMethods;
    }

    public Collection<Classfile> getPublicClasses() {
        return publicClasses;
    }

    public Collection<Field_info> getPublicFields() {
        return publicFields;
    }

    public Collection<Method_info> getPublicMethods() {
        return publicMethods;
    }

    public Collection<InnerClass> getPublicInnerClasses() {
        return publicInnerClasses;
    }

    public Collection<Field_info> getProtectedFields() {
        return protectedFields;
    }

    public Collection<Method_info> getProtectedMethods() {
        return protectedMethods;
    }

    public Collection<InnerClass> getProtectedInnerClasses() {
        return protectedInnerClasses;
    }

    public Collection<Field_info> getPrivateFields() {
        return privateFields;
    }

    public Collection<Method_info> getPrivateMethods() {
        return privateMethods;
    }

    public Collection<InnerClass> getPrivateInnerClasses() {
        return privateInnerClasses;
    }

    public Collection<Classfile> getPackageClasses() {
        return packageClasses;
    }

    public Collection<Field_info> getPackageFields() {
        return packageFields;
    }

    public Collection<Method_info> getPackageMethods() {
        return packageMethods;
    }

    public Collection<InnerClass> getPackageInnerClasses() {
        return packageInnerClasses;
    }

    public Collection<Classfile> getAbstractClasses() {
        return abstractClasses;
    }

    public Collection<Method_info> getAbstractMethods() {
        return abstractMethods;
    }

    public Collection<InnerClass> getAbstractInnerClasses() {
        return abstractInnerClasses;
    }

    public Collection<Field_info> getStaticFields() {
        return staticFields;
    }

    public Collection<Method_info> getStaticMethods() {
        return staticMethods;
    }

    public Collection<InnerClass> getStaticInnerClasses() {
        return staticInnerClasses;
    }

    public Collection<Classfile> getFinalClasses() {
        return finalClasses;
    }

    public Collection<Field_info> getFinalFields() {
        return finalFields;
    }

    public Collection<Method_info> getFinalMethods() {
        return finalMethods;
    }

    public Collection<InnerClass> getFinalInnerClasses() {
        return finalInnerClasses;
    }

    public Collection<Classfile> getSuperClasses() {
        return superClasses;
    }

    public Collection<Classfile> getModuleClasses() {
        return moduleClasses;
    }

    public Collection<Method_info> getSynchronizedMethods() {
        return synchronizedMethods;
    }

    public Collection<Method_info> getNativeMethods() {
        return nativeMethods;
    }

    public Collection<Method_info> getBridgeMethods() {
        return bridgeMethods;
    }

    public Collection<Method_info> getVarargsMethods() {
        return varargsMethods;
    }

    public Collection<Method_info> getStrictMethods() {
        return strictMethods;
    }

    public Collection<Field_info> getVolatileFields() {
        return volatileFields;
    }

    public Collection<Field_info> getTransientFields() {
        return transientFields;
    }

    public Map<Integer, Long> getConstantPoolEntryCounts() {
        return constantPoolEntryCounts;
    }
    public Map<String, Long> getAttributeCounts() {
        return attributeCounts;
    }

    public Collection<Custom_attribute> getCustomAttributes() {
        return customAttributes;
    }

    public long[] getInstructionCounts() {
        return instructionCounts;
    }
    
    // Classfile
    public void visitClassfile(Classfile classfile) {
        classfile.getConstantPool().accept(this);

        if (classfile.isPublic()) {
            publicClasses.add(classfile);
        } else {
            packageClasses.add(classfile);
        }

        if (classfile.isFinal()) {
            finalClasses.add(classfile);
        }

        if (classfile.isSuper()) {
            superClasses.add(classfile);
        }

        if (classfile.isInterface()) {
            interfaces.add(classfile.getClassName());
        } else {
            classes.add(classfile.getClassName());
        }

        if (classfile.isAbstract()) {
            abstractClasses.add(classfile);
        }

        if (classfile.isSynthetic()) {
            syntheticClasses.add(classfile);
        }

        if (classfile.isAnnotation()) {
            annotationClasses.add(classfile);
        }

        if (classfile.isEnum()) {
            enumClasses.add(classfile);
        }

        if (classfile.isModule()) {
            moduleClasses.add(classfile);
        }

        if (classfile.isDeprecated()) {
            deprecatedClasses.add(classfile);
        }

        super.visitClassfile(classfile);
    }

    // ConstantPool

    public void visitConstantPool(ConstantPool constantPool) {
        visitingConstantPool = true;
        super.visitConstantPool(constantPool);
        visitingConstantPool = false;
    }

    public void visitClass_info(Class_info entry) {
        super.visitClass_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Class);
    }

    public void visitFieldRef_info(FieldRef_info entry) {
        super.visitFieldRef_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Fieldref);
    }

    public void visitMethodRef_info(MethodRef_info entry) {
        super.visitMethodRef_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Methodref);
    }

    public void visitInterfaceMethodRef_info(InterfaceMethodRef_info entry) {
        super.visitInterfaceMethodRef_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_InterfaceMethodref);
    }

    public void visitString_info(String_info entry) {
        super.visitString_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_String);
    }

    public void visitInteger_info(Integer_info entry) {
        super.visitInteger_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Integer);
    }

    public void visitFloat_info(Float_info entry) {
        super.visitFloat_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Float);
    }

    public void visitLong_info(Long_info entry) {
        super.visitLong_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Long);
    }

    public void visitDouble_info(Double_info entry) {
        super.visitDouble_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Double);
    }

    public void visitNameAndType_info(NameAndType_info entry) {
        super.visitNameAndType_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_NameAndType);
    }

    public void visitUTF8_info(UTF8_info entry) {
        super.visitUTF8_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Utf8);
    }

    public void visitMethodHandle_info(MethodHandle_info entry) {
        super.visitMethodHandle_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_MethodHandle);
    }

    public void visitMethodType_info(MethodType_info entry) {
        super.visitMethodType_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_MethodType);
    }

    public void visitDynamic_info(Dynamic_info entry) {
        super.visitDynamic_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Dynamic);
    }

    public void visitInvokeDynamic_info(InvokeDynamic_info entry) {
        super.visitInvokeDynamic_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_InvokeDynamic);
    }

    public void visitModule_info(Module_info entry) {
        super.visitModule_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Module);
    }

    public void visitPackage_info(Package_info entry) {
        super.visitPackage_info(entry);
        visitConstantPoolEntry(com.jeantessier.classreader.impl.ConstantPoolEntry.CONSTANT_Package);
    }

    // Features
    public void visitField_info(Field_info entry) {
        fields.add(entry);

        if (entry.isPublic()) {
            publicFields.add(entry);
        } else if (entry.isPrivate()) {
            privateFields.add(entry);
        } else if (entry.isProtected()) {
            protectedFields.add(entry);
        } else {
            packageFields.add(entry);
        }

        if (entry.isFinal()) {
            finalFields.add(entry);
        }

        if (entry.isDeprecated()) {
            deprecatedFields.add(entry);
        }

        if (entry.isSynthetic()) {
            syntheticFields.add(entry);
        }

        if (entry.isStatic()) {
            staticFields.add(entry);
        }

        if (entry.isTransient()) {
            transientFields.add(entry);
        }

        if (entry.isVolatile()) {
            volatileFields.add(entry);
        }

        if (entry.isEnum()) {
            enumFields.add(entry);
        }

        super.visitField_info(entry);
    }

    public void visitMethod_info(Method_info entry) {
        methods.add(entry);

        if (entry.isPublic()) {
            publicMethods.add(entry);
        } else if (entry.isPrivate()) {
            privateMethods.add(entry);
        } else if (entry.isProtected()) {
            protectedMethods.add(entry);
        } else {
            packageMethods.add(entry);
        }

        if (entry.isFinal()) {
            finalMethods.add(entry);
        }

        if (entry.isAbstract()) {
            abstractMethods.add(entry);
        }

        if (entry.isDeprecated()) {
            deprecatedMethods.add(entry);
        }

        if (entry.isSynthetic()) {
            syntheticMethods.add(entry);
        }

        if (entry.isStatic()) {
            staticMethods.add(entry);
        }

        if (entry.isSynchronized()) {
            synchronizedMethods.add(entry);
        }

        if (entry.isBridge()) {
            bridgeMethods.add(entry);
        }

        if (entry.isVarargs()) {
            varargsMethods.add(entry);
        }

        if (entry.isNative()) {
            nativeMethods.add(entry);
        }

        if (entry.isStrict()) {
            strictMethods.add(entry);
        }

        super.visitMethod_info(entry);
    }

    // Attributes
    public void visitConstantValue_attribute(ConstantValue_attribute attribute) {
        super.visitConstantValue_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitCode_attribute(Code_attribute attribute) {
        super.visitCode_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitStackMapTable_attribute(StackMapTable_attribute attribute) {
        super.visitStackMapTable_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitExceptions_attribute(Exceptions_attribute attribute) {
        super.visitExceptions_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitInnerClasses_attribute(InnerClasses_attribute attribute) {
        super.visitInnerClasses_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitEnclosingMethod_attribute(EnclosingMethod_attribute attribute) {
        super.visitEnclosingMethod_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitSynthetic_attribute(Synthetic_attribute attribute) {
        super.visitSynthetic_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitSignature_attribute(Signature_attribute attribute) {
        super.visitSignature_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitSourceFile_attribute(SourceFile_attribute attribute) {
        super.visitSourceFile_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitSourceDebugExtension_attribute(SourceDebugExtension_attribute attribute) {
        super.visitSourceDebugExtension_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitLineNumberTable_attribute(LineNumberTable_attribute attribute) {
        super.visitLineNumberTable_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitLocalVariableTable_attribute(LocalVariableTable_attribute attribute) {
        super.visitLocalVariableTable_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitLocalVariableTypeTable_attribute(LocalVariableTypeTable_attribute attribute) {
        super.visitLocalVariableTypeTable_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitRuntimeVisibleAnnotations_attribute(RuntimeVisibleAnnotations_attribute attribute) {
        super.visitRuntimeVisibleAnnotations_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitRuntimeInvisibleAnnotations_attribute(RuntimeInvisibleAnnotations_attribute attribute) {
        super.visitRuntimeInvisibleAnnotations_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitRuntimeVisibleParameterAnnotations_attribute(RuntimeVisibleParameterAnnotations_attribute attribute) {
        super.visitRuntimeVisibleParameterAnnotations_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitRuntimeInvisibleParameterAnnotations_attribute(RuntimeInvisibleParameterAnnotations_attribute attribute) {
        super.visitRuntimeInvisibleParameterAnnotations_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitAnnotationDefault_attribute(AnnotationDefault_attribute attribute) {
        super.visitAnnotationDefault_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitBootstrapMethods_attribute(BootstrapMethods_attribute attribute) {
        super.visitBootstrapMethods_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitMethodParameters_attribute(MethodParameters_attribute attribute) {
        super.visitMethodParameters_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitModule_attribute(Module_attribute attribute) {
        super.visitModule_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitModulePackages_attribute(ModulePackages_attribute attribute) {
        super.visitModulePackages_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitModuleMainClass_attribute(ModuleMainClass_attribute attribute) {
        super.visitModuleMainClass_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitNestHost_attribute(NestHost_attribute attribute) {
        super.visitNestHost_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitNestMembers_attribute(NestMembers_attribute attribute) {
        super.visitNestMembers_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitRecord_attribute(Record_attribute attribute) {
        super.visitRecord_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitPermittedSubclasses_attribute(PermittedSubclasses_attribute attribute) {
        super.visitPermittedSubclasses_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
    }

    public void visitCustom_attribute(Custom_attribute attribute) {
        super.visitCustom_attribute(attribute);
        visitAttribute(attribute.getAttributeName());
        customAttributes.add(attribute);
    }

    private void visitConstantPoolEntry(int tag) {
        if (visitingConstantPool) {
            constantPoolEntryCounts.put(tag, constantPoolEntryCounts.get(tag) + 1);
        }
    }

    private void visitAttribute(String attributeName) {
        attributeCounts.put(attributeName, attributeCounts.get(attributeName) + 1);
    }

    // Attribute helpers
    public void visitInstruction(Instruction helper) {
        getInstructionCounts()[helper.getOpcode()]++;

        super.visitInstruction(helper);
    }

    public void visitInnerClass(InnerClass helper) {
        if (helper.isPublic()) {
            publicInnerClasses.add(helper);
        } else if (helper.isPrivate()) {
            privateInnerClasses.add(helper);
        } else if (helper.isProtected()) {
            protectedInnerClasses.add(helper);
        } else {
            packageInnerClasses.add(helper);
        }

        if (helper.isStatic()) {
            staticInnerClasses.add(helper);
        }

        if (helper.isFinal()) {
            finalInnerClasses.add(helper);
        }

        if (helper.isInterface()) {
            interfaces.add(helper.getInnerClassInfo());
        } else {
            classes.add(helper.getInnerClassInfo());
        }

        if (helper.isAbstract()) {
            abstractInnerClasses.add(helper);
        }

        if (helper.isSynthetic()) {
            syntheticInnerClasses.add(helper);
        }

        if (helper.isAnnotation()) {
            annotationInnerClasses.add(helper);
        }

        if (helper.isEnum()) {
            enumInnerClasses.add(helper);
        }
    }
}