Repository: micronaut-projects/micronaut-core
File: http/src/main/java/io/micronaut/http/bind/binders/QueryValueArgumentBinder.java (Java)

Code before:

    private BindingResult<T> bindPojo(ArgumentConversionContext<T> context,
                                      HttpRequest<?> source,
                                      AnnotationMetadata annotationMetadata,
                                      ConvertibleMultiValues<String> parameters,
                                      Argument<T> argument) {
        Optional<BeanIntrospection<T>> introspectionOpt = BeanIntrospector.SHARED.findIntrospection(argument.getType());
        if (introspectionOpt.isEmpty()) {
            return BindingResult.unsatisfied();
        }

        BeanIntrospection<T> introspection = introspectionOpt.get();
        BeanIntrospection.Builder<T> introspectionBuilder = introspection.builder();

        for (BeanProperty<T, Object> property : introspection.getBeanProperties()) {
            String propertyName = property.getName();
            Optional<String> value = parameters.getFirst(propertyName);

            if (value.isEmpty()) {
                value = property.asArgument()
                    .getAnnotationMetadata()
                    .stringValue(Bindable.class, "defaultValue");
            }

            if (value.isPresent()) {
                Optional<Object> converted = conversionService.convert(value.get(), context.with(property.asArgument()));
                if (converted.isPresent()) {
                    try {
                        introspectionBuilder.with(propertyName, converted.get());
                    } catch (Exception e) {
                        context.reject(property.asArgument(), e);
                        return BindingResult.unsatisfied();
                    }
                }
            }
        }

        try {
            T instance = introspectionBuilder.build();
            return () -> Optional.of(instance);
        } catch (Exception e) {
            context.reject(argument, e);
            return BindingResult.unsatisfied();
        }
    }

    @Override
    protected String getParameterName(Argument<T> argument) {
        return argument.getAnnotationMetadata().stringValue(QueryValue.class).orElse(argument.getName());
    }
}

Review comment (refactor):
remove this call to `asArgument()` and just use builder argument as above

Code after:
        return doBind(context, parameters, BindingResult.unsatisfied());
    }

    private BindingResult<T> bindPojo(ArgumentConversionContext<T> context,
                                      ConvertibleMultiValues<String> parameters,
                                      Argument<T> argument) {
        Optional<BeanIntrospection<T>> introspectionOpt = BeanIntrospector.SHARED.findIntrospection(argument.getType());
        if (introspectionOpt.isEmpty()) {
            return BindingResult.unsatisfied();
        }

        BeanIntrospection<T> introspection = introspectionOpt.get();
        BeanIntrospection.Builder<T> introspectionBuilder = introspection.builder();
        Argument<?>[] builderArguments = introspectionBuilder.getBuilderArguments();

        for (int index = 0; index < builderArguments.length; index++) {
            Argument<?> builderArg = builderArguments[index];
            String propertyName = builderArg.getName();
            List<String> values = parameters.getAll(propertyName);
            boolean hasNoValue = values.isEmpty();
            @Nullable String defaultValue = hasNoValue ? builderArg
                .getAnnotationMetadata()
                .stringValue(Bindable.class, "defaultValue").orElse(null) : null;

            ArgumentConversionContext<?> conversionContext = context.with(builderArg);
            Optional<?> converted = hasNoValue ? conversionService.convert(defaultValue, conversionContext) : conversionService.convert(values, conversionContext);
            if (converted.isPresent()) {
                try {
                    @SuppressWarnings({"unchecked"})
                    Argument<Object> rawArg = (Argument<Object>) builderArg;
                    introspectionBuilder.with(index, rawArg, converted.get());
                } catch (Exception e) {
                    context.reject(builderArg, e);
                    return BindingResult.unsatisfied();
                }
            } else if (conversionContext.hasErrors()) {
                ConversionError conversionError = conversionContext.getLastError().orElse(null);
                if (conversionError != null) {
                    Exception cause = conversionError.getCause();
                    context.reject(builderArg, cause);
                    return BindingResult.unsatisfied();
                }
            }
        }

        try {
            T instance = introspectionBuilder.build();
            return () -> Optional.of(instance);
        } catch (Exception e) {
            context.reject(argument, e);
            return BindingResult.unsatisfied();