diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java index 9a11ba17a57a9..9cab2c519f752 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java @@ -292,6 +292,11 @@ public boolean isUberJar() { return type.equalsIgnoreCase(PackageConfig.BuiltInType.UBER_JAR.getValue()); } + public boolean isNativeOrNativeSources() { + return type.equalsIgnoreCase(PackageConfig.BuiltInType.NATIVE.getValue()) + || type.equalsIgnoreCase(PackageConfig.BuiltInType.NATIVE_SOURCES.getValue()); + } + public String getRunnerSuffix() { return addRunnerSuffix ? runnerSuffix : ""; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeOrNativeSourcesBuild.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeOrNativeSourcesBuild.java index c6ff3aae33f6d..7e4e243172d0e 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeOrNativeSourcesBuild.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeOrNativeSourcesBuild.java @@ -19,8 +19,7 @@ public class NativeOrNativeSourcesBuild implements BooleanSupplier { @Override public boolean getAsBoolean() { - return packageConfig.type.equalsIgnoreCase(PackageConfig.BuiltInType.NATIVE.getValue()) - || packageConfig.type.equalsIgnoreCase(PackageConfig.BuiltInType.NATIVE_SOURCES.getValue()); + return packageConfig.isNativeOrNativeSources(); } } diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java index e362d555376dd..cd3b2473511c2 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java @@ -88,6 +88,7 @@ import io.quarkus.deployment.builditem.ServiceStartBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import io.quarkus.deployment.pkg.PackageConfig; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; import io.quarkus.fs.util.ZipUtils; import io.quarkus.gizmo.ClassOutput; @@ -830,7 +831,8 @@ void validateExpressions(TemplatesAnalysisBuildItem templatesAnalysis, BeanDiscoveryFinishedBuildItem beanDiscovery, List checkedTemplates, List templateData, - QuteConfig config) { + QuteConfig config, + PackageConfig packageConfig) { long start = System.nanoTime(); @@ -887,6 +889,14 @@ public String apply(String id) { // Maps an expression generated id to the last match of an expression (i.e. the type of the last part) Map generatedIdsToMatches = new HashMap<>(); + // Register all param declarations as targets of implicit value resolvers + for (ParameterDeclaration paramDeclaration : templateAnalysis.parameterDeclarations) { + Type type = TypeInfos.resolveTypeFromTypeInfo(paramDeclaration.getTypeInfo()); + if (type != null) { + implicitClassToMembersUsed.put(type.name(), new HashSet<>()); + } + } + // Iterate over all top-level expressions found in the template for (Expression expression : templateAnalysis.expressions) { if (expression.isLiteral()) { @@ -916,15 +926,21 @@ public String apply(String id) { // ========================================================================== // Register implicit value resolvers for classes collected during validation // ========================================================================== + boolean isNonNativeBuild = !packageConfig.isNativeOrNativeSources(); for (Entry> entry : implicitClassToMembersUsed.entrySet()) { - if (entry.getValue().isEmpty()) { - // No members + if (entry.getValue().isEmpty() && isNonNativeBuild) { + // No members used - skip the generation for non-native builds continue; } ClassInfo clazz = index.getClassByName(entry.getKey()); if (clazz != null) { - implicitClasses.produce(new ImplicitValueResolverBuildItem(clazz, - new TemplateDataBuilder().addIgnore(buildIgnorePattern(entry.getValue())).build())); + TemplateDataBuilder builder = new TemplateDataBuilder(); + if (isNonNativeBuild) { + // Optimize the generated value resolvers + // I.e. only fields/methods used in templates are considered and all other members are ignored + builder.addIgnore(buildIgnorePattern(entry.getValue())); + } + implicitClasses.produce(new ImplicitValueResolverBuildItem(clazz, builder.build())); } } } @@ -1784,7 +1800,8 @@ public Function apply(ClassInfo clazz) { continue; } if (uncontrolled.containsKey(implicitClassName)) { - LOGGER.debugf("Implicit value resolver for %d ignored: %s declared on %s", uncontrolled.get(implicitClassName), + LOGGER.debugf("Implicit value resolver for %s ignored: %s declared on %s", implicitClassName, + uncontrolled.get(implicitClassName), uncontrolled.get(implicitClassName).target()); continue; } diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/TypeInfos.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/TypeInfos.java index 93c7b5eb664d3..51aa6b0e8aa03 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/TypeInfos.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/TypeInfos.java @@ -104,6 +104,27 @@ static Info create(String typeInfo, Expression.Part part, IndexView index, Funct } } + static Type resolveTypeFromTypeInfo(String typeInfo) { + if (typeInfo.startsWith(TYPE_INFO_SEPARATOR)) { + int endIdx = typeInfo.substring(1, typeInfo.length()).indexOf(Expressions.TYPE_INFO_SEPARATOR); + if (endIdx < 1) { + throw new IllegalArgumentException("Invalid type info: " + typeInfo); + } + String typeInfoStr = typeInfo.substring(1, endIdx + 1); + if (!isArray(typeInfoStr)) { + Type primitiveType = decodePrimitive(typeInfoStr); + if (primitiveType == null) { + return resolveType(typeInfoStr); + } + } + } + return null; + } + + static boolean isArray(String typeInfo) { + return typeInfo == null ? false : typeInfo.indexOf(ARRAY_DIM) > 0; + } + private static ClassInfo getClassInfo(String val, IndexView index, Function templateIdToPathFun, Origin expressionOrigin) { DotName rawClassName = rawClassName(val);