Skip to content

Commit

Permalink
Provide qute.native.enabled setting
Browse files Browse the repository at this point in the history
Fixes redhat-developer#629

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed May 3, 2022
1 parent f7ef2e8 commit 4377583
Show file tree
Hide file tree
Showing 31 changed files with 1,433 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.acme.qute;

import java.math.BigDecimal;

import io.quarkus.qute.TemplateData;

@TemplateData(target = BigDecimal.class)
@TemplateData(ignoreSuperclasses = true)
public class ItemWithTemplateData {

public final String name;

public final BigDecimal price;

public ItemWithTemplateData(BigDecimal price, String name) {
this.price = price;
this.name = name;
}

public Item[] getDerivedItems() {
return null;
}

public static BigDecimal staticMethod(Item item) {
return item.price.multiply(new BigDecimal("0.9"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.List;
import java.util.Optional;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.junit.Assert;
import org.junit.Assume;
Expand Down Expand Up @@ -294,6 +295,50 @@ public void string() throws Exception {
assertExtendedTypes("java.lang.String", "java.lang.CharSequence", extendedTypes);
}

@Test
public void templateData() throws CoreException, Exception {
loadMavenProject(QuteMavenProjectName.qute_quickstart);

QuteResolvedJavaTypeParams params = new QuteResolvedJavaTypeParams("org.acme.qute.ItemWithTemplateData",
QuteMavenProjectName.qute_quickstart);
ResolvedJavaTypeInfo result = QuteSupportForTemplate.getInstance().getResolvedJavaType(params, getJDTUtils(),
new NullProgressMonitor());
Assert.assertNotNull(result);
Assert.assertEquals("org.acme.qute.ItemWithTemplateData", result.getSignature());
Assert.assertFalse(result.isIterable());

// @TemplateData

// @TemplateData(target = BigDecimal.class)
// @TemplateData(ignoreSuperclasses = true)
// public class ItemWithTemplateData {
Assert.assertNotNull(result.getTemplateDataAnnotations());
Assert.assertEquals(2, result.getTemplateDataAnnotations().size());
// @TemplateData(target = BigDecimal.class)
Assert.assertFalse(result.getTemplateDataAnnotations().get(0).isIgnoreSuperclasses());
// @TemplateData(ignoreSuperclasses = true)
Assert.assertTrue(result.getTemplateDataAnnotations().get(1).isIgnoreSuperclasses());

// Fields
Assert.assertNotNull(result.getFields());
Assert.assertEquals(2, result.getFields().size());
Assert.assertEquals("name", result.getFields().get(0).getName());
Assert.assertEquals("java.lang.String", result.getFields().get(0).getType());
Assert.assertEquals("price", result.getFields().get(1).getName());
Assert.assertEquals("java.math.BigDecimal", result.getFields().get(1).getType());

// Methods
Assert.assertNotNull(result.getMethods());
Assert.assertEquals(1, result.getMethods().size());
Assert.assertEquals("getDerivedItems() : org.acme.qute.Item[]", result.getMethods().get(0).getSignature());

// Invalid methods(static method)
JavaMethodInfo discountedPriceMethod = findMethod(result, "staticMethod");
Assert.assertNull(discountedPriceMethod);
InvalidMethodReason reason = result.getInvalidMethodReason("staticMethod");
Assert.assertEquals(InvalidMethodReason.Static, reason);
}

private static void assertExtendedTypes(String type, String extendedType, List<String> extendedTypes) {
Assert.assertTrue("The Java type '" + type + "' should extends '" + extendedType + "'.",
extendedTypes.contains(extendedType));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2022 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.qute.commons;

/**
* '@io.quarkus.runtime.annotations.RegisterForReflection' annotation
*
* This annotation that can be used to force a class to be registered for
* reflection in native image mode
*/
public class RegisterForReflectionAnnotation {

public RegisterForReflectionAnnotation() {
setMethods(true);
setFields(true);
}

/**
* If the methods should be registered
*/
private boolean methods;

/**
* If the fields should be registered
*/
private boolean fields;

public boolean isMethods() {
return methods;
}

public void setMethods(boolean methods) {
this.methods = methods;
}

public boolean isFields() {
return fields;
}

public void setFields(boolean fields) {
this.fields = fields;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public class ResolvedJavaTypeInfo extends JavaTypeInfo {

private Boolean isIterable;

private RegisterForReflectionAnnotation registerForReflectionAnnotation;

private List<TemplateDataAnnotation> templateDataAnnotations;

/**
* Returns list of extended types.
*
Expand Down Expand Up @@ -178,13 +182,44 @@ private synchronized boolean computeIsIterable() {
return iterable;
}

/**
* Returns the list of '@io.quarkus.qute.TemplateData' annotations for the Java
* type.
*
* @return the list of '@io.quarkus.qute.TemplateData' annotations for the Java
* type.
*/
public List<TemplateDataAnnotation> getTemplateDataAnnotations() {
return templateDataAnnotations;
}

/**
* Set the list of '@io.quarkus.qute.TemplateData' annotations for the Java
* type.
*
* @param templateDataAnnotations the list of '@io.quarkus.qute.TemplateData'
* annotations for the Java type.
*/
public void setTemplateDataAnnotations(List<TemplateDataAnnotation> templateDataAnnotations) {
this.templateDataAnnotations = templateDataAnnotations;
}

public RegisterForReflectionAnnotation getRegisterForReflectionAnnotation() {
return registerForReflectionAnnotation;
}

public void setRegisterForReflectionAnnotation(RegisterForReflectionAnnotation registerForReflectionAnnotation) {
this.registerForReflectionAnnotation = registerForReflectionAnnotation;
}

@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
b.add("name", this.getName());
b.add("signature", this.getSignature());
b.add("iterableOf", this.getIterableOf());
b.add("iterableType", this.getIterableType());
b.add("templateDataAnnotations", this.getTemplateDataAnnotations());
return b.toString();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.qute.commons;

import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;

/**
* '@io.quarkus.qute.TemplateData' annotation.
*
* @author Angelo ZERR
*
*/
public class TemplateDataAnnotation {

/**
* If set to true do not automatically analyze superclasses.
*/
private Boolean ignoreSuperclasses;

public boolean isIgnoreSuperclasses() {
return ignoreSuperclasses != null && ignoreSuperclasses.booleanValue();
}

public void setIgnoreSuperclasses(Boolean ignoreSuperclasses) {
this.ignoreSuperclasses = ignoreSuperclasses;
}

@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
b.add("ignoreSuperclasses", this.isIgnoreSuperclasses());
return b.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
Expand Down Expand Up @@ -53,20 +54,24 @@
import com.redhat.qute.commons.QuteJavaTypesParams;
import com.redhat.qute.commons.QuteProjectParams;
import com.redhat.qute.commons.QuteResolvedJavaTypeParams;
import com.redhat.qute.commons.RegisterForReflectionAnnotation;
import com.redhat.qute.commons.ResolvedJavaTypeInfo;
import com.redhat.qute.commons.TemplateDataAnnotation;
import com.redhat.qute.commons.datamodel.DataModelParameter;
import com.redhat.qute.commons.datamodel.DataModelProject;
import com.redhat.qute.commons.datamodel.DataModelTemplate;
import com.redhat.qute.commons.datamodel.QuteDataModelProjectParams;
import com.redhat.qute.commons.usertags.QuteUserTagParams;
import com.redhat.qute.commons.usertags.UserTagInfo;
import com.redhat.qute.jdt.internal.QuteJavaConstants;
import com.redhat.qute.jdt.internal.resolver.AbstractTypeResolver;
import com.redhat.qute.jdt.internal.resolver.ClassFileTypeResolver;
import com.redhat.qute.jdt.internal.resolver.CompilationUnitTypeResolver;
import com.redhat.qute.jdt.internal.resolver.ITypeResolver;
import com.redhat.qute.jdt.internal.template.JavaTypesSearch;
import com.redhat.qute.jdt.internal.template.QuarkusIntegrationForQute;
import com.redhat.qute.jdt.internal.template.TemplateDataSupport;
import com.redhat.qute.jdt.utils.AnnotationUtils;
import com.redhat.qute.jdt.utils.IJDTUtils;
import com.redhat.qute.jdt.utils.JDTQuteProjectUtils;

Expand Down Expand Up @@ -409,7 +414,7 @@ public ResolvedJavaTypeInfo getResolvedJavaType(QuteResolvedJavaTypeParams param
}
} else {
// ex : String implements CharSequence, ....
ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(monitor);
ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(monitor);
IType[] allSuperTypes = typeHierarchy.getSupertypes(type);
extendedTypes = Stream.of(allSuperTypes) //
.map(superType -> superType.getFullyQualifiedName()) //
Expand All @@ -427,9 +432,47 @@ public ResolvedJavaTypeInfo getResolvedJavaType(QuteResolvedJavaTypeParams param
resolvedType.setMethods(methodsInfo);
resolvedType.setInvalidMethods(invalidMethods);
resolvedType.setExtendedTypes(extendedTypes);
collectAnnotations(resolvedType, type);
return resolvedType;
}

private static void collectAnnotations(ResolvedJavaTypeInfo resolvedType, IType type) throws JavaModelException {
List<TemplateDataAnnotation> templateDataAnnotations = null;
RegisterForReflectionAnnotation registerForReflectionAnnotation = null;
IAnnotation[] annotations = type.getAnnotations();
for (IAnnotation annotation : annotations) {
if (AnnotationUtils.isMatchAnnotation(annotation, QuteJavaConstants.TEMPLATE_DATA_ANNOTATION)) {
// @TemplateData
if (templateDataAnnotations == null) {
templateDataAnnotations = new ArrayList<>();
}
templateDataAnnotations.add(createTemplateData(annotation));
} else if (AnnotationUtils.isMatchAnnotation(annotation,
QuteJavaConstants.REGISTER_FOR_REFLECTION_ANNOTATION)) {
// @RegisterForReflection
registerForReflectionAnnotation = createRegisterForReflection(annotation);
}
}
resolvedType.setTemplateDataAnnotations(templateDataAnnotations);
resolvedType.setRegisterForReflectionAnnotation(registerForReflectionAnnotation);
}

private static TemplateDataAnnotation createTemplateData(IAnnotation templateDataAnnotation)
throws JavaModelException {
TemplateDataAnnotation templateData = new TemplateDataAnnotation();
String ignoreSuperclasses = AnnotationUtils.getAnnotationMemberValue(templateDataAnnotation,
QuteJavaConstants.TEMPLATE_DATA_ANNOTATION_IGNORE_SUPER_CLASSES);
if ("true".equals(ignoreSuperclasses)) {
templateData.setIgnoreSuperclasses(Boolean.TRUE);
}
return templateData;
}

private static RegisterForReflectionAnnotation createRegisterForReflection(IAnnotation annotation) {
RegisterForReflectionAnnotation registerForReflectionAnnotation = new RegisterForReflectionAnnotation();
return registerForReflectionAnnotation;
}

private String getFullQualifiedName(IProgressMonitor monitor, IJavaProject javaProject, String name)
throws JavaModelException {
if (name.indexOf('.') != -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,35 @@ public class QuteJavaConstants {

public static final String JAVAX_INJECT_NAMED_ANNOTATION = "javax.inject.Named";

public static final String LOCATION_ANNOTATION = "io.quarkus.qute.Location";

public static final String TEMPLATE_CLASS = "io.quarkus.qute.Template";

public static final String ENGINE_BUILDER_CLASS = "io.quarkus.qute.EngineBuilder";

public static final String VALUE_ANNOTATION_NAME = "value";

// @CheckedTemplate

public static final String CHECKED_TEMPLATE_ANNOTATION = "io.quarkus.qute.CheckedTemplate";

public static final String OLD_CHECKED_TEMPLATE_ANNOTATION = "io.quarkus.qute.api.CheckedTemplate";

// @TemplateExtension

public static final String TEMPLATE_EXTENSION_ANNOTATION = "io.quarkus.qute.TemplateExtension";

public static final String TEMPLATE_EXTENSION_ANNOTATION_NAMESPACE = "namespace";

public static final String TEMPLATE_EXTENSION_ANNOTATION_MATCH_NAME = "matchName";

public static final String LOCATION_ANNOTATION = "io.quarkus.qute.Location";

public static final String TEMPLATE_CLASS = "io.quarkus.qute.Template";
// @TemplateData

public static final String ENGINE_BUILDER_CLASS = "io.quarkus.qute.EngineBuilder";
public static final String TEMPLATE_DATA_ANNOTATION = "io.quarkus.qute.TemplateData";

public static final String VALUE_ANNOTATION_NAME = "value";
public static final String TEMPLATE_DATA_ANNOTATION_IGNORE_SUPER_CLASSES = "ignoreSuperclasses";

// @io.quarkus.runtime.annotations.RegisterForReflection

public static final String REGISTER_FOR_REFLECTION_ANNOTATION = "io.quarkus.runtime.annotations.RegisterForReflection";
}
Loading

0 comments on commit 4377583

Please sign in to comment.