Package com.buschmais.jqassistant.core.scanner.impl.visitor

Source Code of com.buschmais.jqassistant.core.scanner.impl.visitor.AnnotationVisitor

package com.buschmais.jqassistant.core.scanner.impl.visitor;

import com.buschmais.jqassistant.core.model.api.descriptor.FieldDescriptor;
import com.buschmais.jqassistant.core.model.api.descriptor.TypeDescriptor;
import com.buschmais.jqassistant.core.model.api.descriptor.ValueDescriptor;
import com.buschmais.jqassistant.core.model.api.descriptor.value.*;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.lang.annotation.Annotation;
import java.util.LinkedList;
import java.util.List;

/**
* An annotation visitor.
* <p>Adds a dependency from the annotated types to the types of the annotation values.</p>
*/
public class AnnotationVisitor extends org.objectweb.asm.AnnotationVisitor {

    private VisitorHelper visitorHelper;

    private ArrayValueDescriptor arrayValueDescriptor;

    private AnnotationValueDescriptor annotationValueDescriptor;

    /**
     * Constructor.
     *
     * @param visitorHelper The {@link VisitorHelper}.
     */
    protected AnnotationVisitor(AnnotationValueDescriptor annotationValueDescriptor, VisitorHelper visitorHelper) {
        super(Opcodes.ASM4);
        this.annotationValueDescriptor = annotationValueDescriptor;
        this.visitorHelper = visitorHelper;
    }

    @Override
    public void visit(final String name, final Object value) {
        if (value instanceof Type) {
            String type = visitorHelper.getType((Type) value);
            ClassValueDescriptor valueDescriptor = createValue(ClassValueDescriptor.class, name);
            valueDescriptor.setValue(visitorHelper.getTypeDescriptor(type));
            addValue(name, valueDescriptor);
        } else {
            PrimitiveValueDescriptor valueDescriptor = createValue(PrimitiveValueDescriptor.class, name);
            TypeDescriptor typeDescriptor = visitorHelper.getTypeDescriptor(value.getClass().getName());
            valueDescriptor.setType(typeDescriptor);
            valueDescriptor.setValue(value);
            addValue(name, valueDescriptor);
        }
    }

    @Override
    public void visitEnum(final String name, final String desc, final String value) {
        EnumerationValueDescriptor valueDescriptor = createValue(EnumerationValueDescriptor.class, name);
        TypeDescriptor typeDescriptor = visitorHelper.getTypeDescriptor(visitorHelper.getType(desc));
        FieldDescriptor fieldDescriptor = visitorHelper.getFieldDescriptor(typeDescriptor, visitorHelper.getFieldSignature(value, desc));
        valueDescriptor.setType(visitorHelper.getTypeDescriptor(Enum.class.getName()));
        valueDescriptor.setValue(fieldDescriptor);
        addValue(name, valueDescriptor);
    }

    @Override
    public AnnotationVisitor visitAnnotation(final String name, final String desc) {
        AnnotationValueDescriptor valueDescriptor = createValue(AnnotationValueDescriptor.class, name);
        valueDescriptor.setType(visitorHelper.getTypeDescriptor(visitorHelper.getType(desc)));
        addValue(name, valueDescriptor);
        return new AnnotationVisitor(valueDescriptor, visitorHelper);
    }

    @Override
    public AnnotationVisitor visitArray(final String name) {
        this.arrayValueDescriptor = createValue(ArrayValueDescriptor.class, name);
        addValue(name, arrayValueDescriptor);
        return this;
    }

    @Override
    public void visitEnd() {
    }

    /**
     * Create a value descriptor of given type and name and initializes it.
     *
     * @param type The class type.
     * @param name The name
     * @param <T>  The type.
     * @return The initialized descriptor.
     */
    private <T extends ValueDescriptor> T createValue(Class<T> type, String name) {
        if (name != null) {
            this.arrayValueDescriptor = null;
        }
        String valueName;
        String fullQualifiedName;
        if (arrayValueDescriptor != null) {
            valueName = "[" + getListValue(this.arrayValueDescriptor).size() + "]";
            fullQualifiedName = this.arrayValueDescriptor.getFullQualifiedName() + valueName;
        } else {
            valueName = name;
            fullQualifiedName = this.annotationValueDescriptor.getFullQualifiedName() + ":" + valueName;
        }
        T valueDescriptor = visitorHelper.getValueDescriptor(type, fullQualifiedName);
        valueDescriptor.setName(valueName);
        return valueDescriptor;
    }

    /**
     * Add the descriptor as value to the current annotation or array value.
     *
     * @param name  The name.
     * @param value The value.
     */
    private void addValue(String name, ValueDescriptor value) {
        if (arrayValueDescriptor != null && name == null) {
            getListValue(arrayValueDescriptor).add(value);
        } else {
            getListValue(annotationValueDescriptor).add(value);
        }
    }

    /**
     * Get the list of referenced values.
     *
     * @param valueDescriptor The value descriptor containing a list value.
     * @param <T>             The type of the value descriptor.
     * @return The list of referenced values.
     */
    private <T extends ValueDescriptor<List<ValueDescriptor>>> List<ValueDescriptor> getListValue(T valueDescriptor) {
        List<ValueDescriptor> values = valueDescriptor.getValue();
        if (values == null) {
            values = new LinkedList<>();
            valueDescriptor.setValue(values);
        }
        return values;
    }
}
TOP

Related Classes of com.buschmais.jqassistant.core.scanner.impl.visitor.AnnotationVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.