mirror of
https://github.com/apple/pkl.git
synced 2026-01-11 22:30:54 +01:00
Add @Generated annotation to generated Java types (#1075)
JaCoCo automatically excludes methods and classes annotated with @Generated from the coverage reports. This is very important to us as generated code should not normally be included in the coverage report. We want to measure the coverage of the code that we actually wrote and maintain, not the code that was automatically generated by tools. By introducing a property generatedAnnotation (default value false) one could enable writing @Generated on Java types to be generated. Co-authored-by: Nullpointer <mike.schulze@tealium.com>
This commit is contained in:
@@ -29,6 +29,9 @@ data class CliJavaCodeGeneratorOptions(
|
||||
/** The characters to use for indenting generated source code. */
|
||||
val indent: String = " ",
|
||||
|
||||
/** Whether to add a <code>@Generated</code> annotation to the types to be generated. */
|
||||
val generatedAnnotation: Boolean = false,
|
||||
|
||||
/**
|
||||
* Whether to generate public getter methods and private/protected fields instead of public
|
||||
* fields.
|
||||
@@ -82,6 +85,7 @@ data class CliJavaCodeGeneratorOptions(
|
||||
internal fun toJavaCodeGeneratorOptions() =
|
||||
JavaCodeGeneratorOptions(
|
||||
indent,
|
||||
generatedAnnotation,
|
||||
generateGetters,
|
||||
generateJavadoc,
|
||||
generateSpringBootConfig,
|
||||
|
||||
@@ -47,6 +47,9 @@ data class JavaCodeGeneratorOptions(
|
||||
/** The characters to use for indenting generated Java code. */
|
||||
val indent: String = " ",
|
||||
|
||||
/** Whether to add a <code>@Generated</code> annotation to the types to be generated. */
|
||||
val generatedAnnotation: Boolean = false,
|
||||
|
||||
/**
|
||||
* Whether to generate public getter methods and protected final fields instead of public final
|
||||
* fields.
|
||||
@@ -560,6 +563,11 @@ class JavaCodeGenerator(
|
||||
fun generateClass(): TypeSpec.Builder {
|
||||
val builder =
|
||||
TypeSpec.classBuilder(javaPoetClassName.simpleName()).addModifiers(Modifier.PUBLIC)
|
||||
if (codegenOptions.generatedAnnotation) {
|
||||
val name = ClassName.get("org.pkl.config.java", "Generated")
|
||||
val generated = AnnotationSpec.builder(name).build()
|
||||
builder.addAnnotation(generated)
|
||||
}
|
||||
|
||||
// stateless final module classes are non-instantiable by choice
|
||||
val isInstantiable =
|
||||
|
||||
@@ -55,6 +55,13 @@ class PklJavaCodegenCommand : ModulesCommand(name = "pkl-codegen-java", helpLink
|
||||
)
|
||||
.default(defaults.indent)
|
||||
|
||||
private val generatedAnnotation: Boolean by
|
||||
option(
|
||||
names = arrayOf("--generated-annotation"),
|
||||
help = "Whether to add a @Generated annotation to the types to be generated.",
|
||||
)
|
||||
.flag()
|
||||
|
||||
private val generateGetters: Boolean by
|
||||
option(
|
||||
names = arrayOf("--generate-getters"),
|
||||
@@ -132,6 +139,7 @@ class PklJavaCodegenCommand : ModulesCommand(name = "pkl-codegen-java", helpLink
|
||||
base = baseOptions.baseOptions(modules, projectOptions),
|
||||
outputDir = outputDir,
|
||||
indent = indent,
|
||||
generatedAnnotation = generatedAnnotation,
|
||||
generateGetters = generateGetters,
|
||||
generateJavadoc = generateJavadoc,
|
||||
generateSpringBootConfig = generateSpringBoot,
|
||||
|
||||
@@ -859,6 +859,24 @@ class JavaCodeGeneratorTest {
|
||||
assertThat(fooClass.declaredFields).allSatisfy(Consumer { it.name.startsWith("_") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedAnnotation() {
|
||||
val javaCode =
|
||||
generateJavaCode(
|
||||
"""
|
||||
module my.mod
|
||||
|
||||
class GeneratedAnnotation {
|
||||
test: Boolean = true
|
||||
}
|
||||
"""
|
||||
.trimIndent(),
|
||||
JavaCodeGeneratorOptions(generatedAnnotation = true),
|
||||
)
|
||||
|
||||
assertThat(javaCode).compilesSuccessfully().isEqualToResourceFile("GeneratedAnnotation.jva")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getters() {
|
||||
val javaCode =
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package my;
|
||||
|
||||
import java.lang.Object;
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
import java.lang.StringBuilder;
|
||||
import java.util.Objects;
|
||||
import org.pkl.config.java.Generated;
|
||||
import org.pkl.config.java.mapper.Named;
|
||||
|
||||
@Generated
|
||||
public final class Mod {
|
||||
private Mod() {
|
||||
}
|
||||
|
||||
private static void appendProperty(StringBuilder builder, String name, Object value) {
|
||||
builder.append("\n ").append(name).append(" = ");
|
||||
String[] lines = Objects.toString(value).split("\n");
|
||||
builder.append(lines[0]);
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
builder.append("\n ").append(lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Generated
|
||||
public static final class GeneratedAnnotation {
|
||||
public final boolean test;
|
||||
|
||||
public GeneratedAnnotation(@Named("test") boolean test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
public GeneratedAnnotation withTest(boolean test) {
|
||||
return new GeneratedAnnotation(test);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (this.getClass() != obj.getClass()) return false;
|
||||
GeneratedAnnotation other = (GeneratedAnnotation) obj;
|
||||
if (!Objects.equals(this.test, other.test)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = 31 * result + Objects.hashCode(this.test);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(100);
|
||||
builder.append(GeneratedAnnotation.class.getSimpleName()).append(" {");
|
||||
appendProperty(builder, "test", this.test);
|
||||
builder.append("\n}");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.config.java;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/** Indicates that the annotated class was generated by Pkl. */
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Generated {}
|
||||
@@ -190,6 +190,7 @@ public class PklPlugin implements Plugin<Project> {
|
||||
configureBaseSpec(spec);
|
||||
configureCodeGenSpec(spec);
|
||||
|
||||
spec.getAddGeneratedAnnotation().convention(false);
|
||||
spec.getGenerateGetters().convention(false);
|
||||
spec.getGenerateJavadoc().convention(false);
|
||||
// Not using `convention()` so that users can disable generation of
|
||||
@@ -206,6 +207,7 @@ public class PklPlugin implements Plugin<Project> {
|
||||
.configure(
|
||||
task -> {
|
||||
configureCodeGenTask(task, spec);
|
||||
task.getGeneratedAnnotation().set(spec.getAddGeneratedAnnotation());
|
||||
task.getGenerateGetters().set(spec.getGenerateGetters());
|
||||
task.getGenerateJavadoc().set(spec.getGenerateJavadoc());
|
||||
task.getParamsAnnotation().set(spec.getParamsAnnotation());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,8 @@ import org.gradle.api.tasks.SourceSet;
|
||||
public interface CodeGenSpec extends ModulesSpec {
|
||||
DirectoryProperty getOutputDir();
|
||||
|
||||
Property<Boolean> getAddGeneratedAnnotation();
|
||||
|
||||
Property<SourceSet> getSourceSet();
|
||||
|
||||
Property<String> getIndent();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,12 +19,17 @@ import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.MapProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
|
||||
public abstract class CodeGenTask extends ModulesTask {
|
||||
@OutputDirectory
|
||||
public abstract DirectoryProperty getOutputDir();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<Boolean> getGeneratedAnnotation();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getIndent();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,6 +47,7 @@ public abstract class JavaCodeGenTask extends CodeGenTask {
|
||||
getCliBaseOptions(),
|
||||
getProject().file(getOutputDir()).toPath(),
|
||||
getIndent().get(),
|
||||
getGeneratedAnnotation().get(),
|
||||
getGenerateGetters().get(),
|
||||
getGenerateJavadoc().get(),
|
||||
getGenerateSpringBootConfig().get(),
|
||||
|
||||
Reference in New Issue
Block a user