Search in sources :

Example 1 with StringSwitchWriter

use of io.micronaut.inject.writer.StringSwitchWriter in project micronaut-core by micronaut-projects.

the class BeanIntrospectionWriter method buildFindIndexedProperty.

private void buildFindIndexedProperty(ClassWriter classWriter) {
    if (indexByAnnotationAndValue.isEmpty()) {
        return;
    }
    GeneratorAdapter writer = new GeneratorAdapter(classWriter.visitMethod(Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, FIND_INDEXED_PROPERTY_METHOD.getName(), FIND_INDEXED_PROPERTY_METHOD.getDescriptor(), null, null), ACC_PROTECTED | Opcodes.ACC_FINAL, FIND_INDEXED_PROPERTY_METHOD.getName(), FIND_INDEXED_PROPERTY_METHOD.getDescriptor());
    writer.loadThis();
    writer.loadArg(0);
    writer.invokeVirtual(Type.getType(Class.class), new Method("getName", Type.getType(String.class), new Type[] {}));
    int classNameLocal = writer.newLocal(Type.getType(String.class));
    writer.storeLocal(classNameLocal);
    writer.loadLocal(classNameLocal);
    new StringSwitchWriter() {

        @Override
        protected Set<String> getKeys() {
            return indexByAnnotationAndValue.keySet().stream().map(s -> s.annotationName).collect(Collectors.toSet());
        }

        @Override
        protected void pushStringValue() {
            writer.loadLocal(classNameLocal);
        }

        @Override
        protected void onMatch(String annotationName, Label end) {
            if (indexByAnnotationAndValue.keySet().stream().anyMatch(s -> s.annotationName.equals(annotationName) && s.value == null)) {
                Label falseLabel = new Label();
                writer.loadArg(1);
                writer.ifNonNull(falseLabel);
                String propertyName = indexByAnnotationAndValue.get(new AnnotationWithValue(annotationName, null));
                int propertyIndex = getPropertyIndex(propertyName);
                writer.loadThis();
                writer.push(propertyIndex);
                writer.invokeVirtual(introspectionType, FIND_PROPERTY_BY_INDEX_METHOD);
                writer.returnValue();
                writer.visitLabel(falseLabel);
            } else {
                Label falseLabel = new Label();
                writer.loadArg(1);
                writer.ifNonNull(falseLabel);
                writer.goTo(end);
                writer.visitLabel(falseLabel);
            }
            Set<String> valueMatches = indexByAnnotationAndValue.keySet().stream().filter(s -> s.annotationName.equals(annotationName) && s.value != null).map(s -> s.value).collect(Collectors.toSet());
            if (!valueMatches.isEmpty()) {
                new StringSwitchWriter() {

                    @Override
                    protected Set<String> getKeys() {
                        return valueMatches;
                    }

                    @Override
                    protected void pushStringValue() {
                        writer.loadArg(1);
                    }

                    @Override
                    protected void onMatch(String value, Label end) {
                        String propertyName = indexByAnnotationAndValue.get(new AnnotationWithValue(annotationName, value));
                        int propertyIndex = getPropertyIndex(propertyName);
                        writer.loadThis();
                        writer.push(propertyIndex);
                        writer.invokeVirtual(introspectionType, FIND_PROPERTY_BY_INDEX_METHOD);
                        writer.returnValue();
                    }
                }.write(writer);
            }
            writer.goTo(end);
        }
    }.write(writer);
    writer.push((String) null);
    writer.returnValue();
    writer.visitMaxs(DEFAULT_MAX_STACK, 1);
    writer.visitEnd();
}
Also used : ElementQuery(io.micronaut.inject.ast.ElementQuery) Arrays(java.util.Arrays) ArrayUtils(io.micronaut.core.util.ArrayUtils) FieldElement(io.micronaut.inject.ast.FieldElement) Internal(io.micronaut.core.annotation.Internal) BeanIntrospectionReference(io.micronaut.core.beans.BeanIntrospectionReference) Type(org.objectweb.asm.Type) Map(java.util.Map) NameUtils(io.micronaut.core.naming.NameUtils) AbstractBeanIntrospectionReference(io.micronaut.core.beans.AbstractBeanIntrospectionReference) AbstractAnnotationMetadataWriter(io.micronaut.inject.writer.AbstractAnnotationMetadataWriter) AnnotationMetadataWriter(io.micronaut.inject.annotation.AnnotationMetadataWriter) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) Collection(java.util.Collection) Set(java.util.Set) NotNull(javax.validation.constraints.NotNull) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Introspected(io.micronaut.core.annotation.Introspected) List(java.util.List) MethodElement(io.micronaut.inject.ast.MethodElement) JavaModelUtils(io.micronaut.inject.processing.JavaModelUtils) ClassWriter(org.objectweb.asm.ClassWriter) AbstractInitializableBeanIntrospection(io.micronaut.inject.beans.AbstractInitializableBeanIntrospection) Label(org.objectweb.asm.Label) ClassElement(io.micronaut.inject.ast.ClassElement) HashMap(java.util.HashMap) StringSwitchWriter(io.micronaut.inject.writer.StringSwitchWriter) DefaultAnnotationMetadata(io.micronaut.inject.annotation.DefaultAnnotationMetadata) ConstructorElement(io.micronaut.inject.ast.ConstructorElement) ParameterElement(io.micronaut.inject.ast.ParameterElement) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Method(org.objectweb.asm.commons.Method) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TypedElement(io.micronaut.inject.ast.TypedElement) Nullable(io.micronaut.core.annotation.Nullable) AnnotationMetadataReference(io.micronaut.inject.annotation.AnnotationMetadataReference) BiConsumer(java.util.function.BiConsumer) Argument(io.micronaut.core.type.Argument) ClassWriterOutputVisitor(io.micronaut.inject.writer.ClassWriterOutputVisitor) LinkedHashSet(java.util.LinkedHashSet) OutputStream(java.io.OutputStream) Opcodes(org.objectweb.asm.Opcodes) IOException(java.io.IOException) ReflectionUtils(io.micronaut.core.reflect.ReflectionUtils) NonNull(io.micronaut.core.annotation.NonNull) DispatchWriter(io.micronaut.inject.writer.DispatchWriter) BeanIntrospection(io.micronaut.core.beans.BeanIntrospection) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Collections(java.util.Collections) Type(org.objectweb.asm.Type) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) StringSwitchWriter(io.micronaut.inject.writer.StringSwitchWriter) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method)

Example 2 with StringSwitchWriter

use of io.micronaut.inject.writer.StringSwitchWriter in project micronaut-core by micronaut-projects.

the class BeanIntrospectionWriter method buildGetIndexedProperties.

private void buildGetIndexedProperties(ClassWriter classWriter) {
    if (indexByAnnotations.isEmpty()) {
        return;
    }
    GeneratorAdapter writer = new GeneratorAdapter(classWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, GET_INDEXED_PROPERTIES.getName(), GET_INDEXED_PROPERTIES.getDescriptor(), null, null), ACC_PUBLIC | Opcodes.ACC_FINAL, GET_INDEXED_PROPERTIES.getName(), GET_INDEXED_PROPERTIES.getDescriptor());
    writer.loadThis();
    writer.loadArg(0);
    writer.invokeVirtual(Type.getType(Class.class), new Method("getName", Type.getType(String.class), new Type[] {}));
    int classNameLocal = writer.newLocal(Type.getType(String.class));
    writer.storeLocal(classNameLocal);
    writer.loadLocal(classNameLocal);
    new StringSwitchWriter() {

        @Override
        protected Set<String> getKeys() {
            return indexByAnnotations.keySet();
        }

        @Override
        protected void pushStringValue() {
            writer.loadLocal(classNameLocal);
        }

        @Override
        protected void onMatch(String annotationName, Label end) {
            writer.loadThis();
            writer.getStatic(introspectionType, annotationIndexFields.get(annotationName), Type.getType(int[].class));
            writer.invokeVirtual(introspectionType, GET_BP_INDEXED_SUBSET_METHOD);
            writer.returnValue();
        }
    }.write(writer);
    writer.invokeStatic(Type.getType(Collections.class), COLLECTIONS_EMPTY_LIST);
    writer.returnValue();
    writer.visitMaxs(DEFAULT_MAX_STACK, 1);
    writer.visitEnd();
}
Also used : Type(org.objectweb.asm.Type) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) StringSwitchWriter(io.micronaut.inject.writer.StringSwitchWriter) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method) Collections(java.util.Collections)

Example 3 with StringSwitchWriter

use of io.micronaut.inject.writer.StringSwitchWriter in project micronaut-core by micronaut-projects.

the class BeanIntrospectionWriter method buildPropertyIndexOfMethod.

private void buildPropertyIndexOfMethod(ClassWriter classWriter) {
    GeneratorAdapter findMethod = new GeneratorAdapter(classWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, PROPERTY_INDEX_OF.getName(), PROPERTY_INDEX_OF.getDescriptor(), null, null), ACC_PUBLIC | Opcodes.ACC_FINAL, PROPERTY_INDEX_OF.getName(), PROPERTY_INDEX_OF.getDescriptor());
    new StringSwitchWriter() {

        @Override
        protected Set<String> getKeys() {
            Set<String> keys = new HashSet<>();
            for (BeanPropertyData prop : beanProperties) {
                keys.add(prop.name);
            }
            for (BeanFieldData field : beanFields) {
                keys.add(field.beanField.getName());
            }
            return keys;
        }

        @Override
        protected void pushStringValue() {
            findMethod.loadArg(0);
        }

        @Override
        protected void onMatch(String value, Label end) {
            findMethod.loadThis();
            findMethod.push(getPropertyIndex(value));
            findMethod.returnValue();
        }
    }.write(findMethod);
    findMethod.push(-1);
    findMethod.returnValue();
    findMethod.visitMaxs(DEFAULT_MAX_STACK, 1);
    findMethod.visitEnd();
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) StringSwitchWriter(io.micronaut.inject.writer.StringSwitchWriter) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter)

Aggregations

StringSwitchWriter (io.micronaut.inject.writer.StringSwitchWriter)3 HashSet (java.util.HashSet)3 LinkedHashSet (java.util.LinkedHashSet)3 Set (java.util.Set)3 Label (org.objectweb.asm.Label)3 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)3 Collections (java.util.Collections)2 Type (org.objectweb.asm.Type)2 Method (org.objectweb.asm.commons.Method)2 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)1 Internal (io.micronaut.core.annotation.Internal)1 Introspected (io.micronaut.core.annotation.Introspected)1 NonNull (io.micronaut.core.annotation.NonNull)1 Nullable (io.micronaut.core.annotation.Nullable)1 AbstractBeanIntrospectionReference (io.micronaut.core.beans.AbstractBeanIntrospectionReference)1 BeanIntrospection (io.micronaut.core.beans.BeanIntrospection)1 BeanIntrospectionReference (io.micronaut.core.beans.BeanIntrospectionReference)1 NameUtils (io.micronaut.core.naming.NameUtils)1 ReflectionUtils (io.micronaut.core.reflect.ReflectionUtils)1 Argument (io.micronaut.core.type.Argument)1