org.openrewrite.java.recipes.MissingOptionExample Maven / Gradle / Ivy
Show all versions of rewrite-java Show documentation
/*
* Copyright 2024 the original author or authors.
*
* 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.openrewrite.java.recipes;
import org.openrewrite.*;
import org.openrewrite.java.AddOrUpdateAnnotationAttribute;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.TypeUtils;
public class MissingOptionExample extends Recipe {
private static final String ORG_OPENREWRITE_OPTION = "org.openrewrite.Option";
@Override
public String getDisplayName() {
return "Find missing `@Option` `example` values";
}
@Override
public String getDescription() {
return "Find `@Option` annotations that are missing `example` values for documentation.";
}
@Override
public TreeVisitor, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>(ORG_OPENREWRITE_OPTION, false),
new JavaIsoVisitor() {
@Override
public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) {
J.Annotation an = super.visitAnnotation(annotation, ctx);
if (!TypeUtils.isOfClassType(annotation.getType(), ORG_OPENREWRITE_OPTION) || an.getArguments() == null) {
return an;
}
// Skip if there is already an example value, or valid options
boolean hasExample = an.getArguments().stream().anyMatch(exp -> {
if (exp instanceof J.Assignment) {
Expression variable = ((J.Assignment) exp).getVariable();
if (variable instanceof J.Identifier) {
String simpleName = ((J.Identifier) variable).getSimpleName();
return "example".equals(simpleName) || "valid".equals(simpleName);
}
}
return false;
});
if (hasExample) {
return an;
}
// Skip boolean and non-String primitive fields, as examples there are trivial
Cursor parent = getCursor().getParent();
if (parent != null && parent.getValue() instanceof J.VariableDeclarations) {
J.VariableDeclarations variableDeclarations = parent.getValue();
if (variableDeclarations.getTypeExpression() != null) {
JavaType type = variableDeclarations.getTypeExpression().getType();
if (!TypeUtils.isString(type)) {
if (type instanceof JavaType.Primitive ||
type instanceof JavaType.FullyQualified &&
"java.lang".equals(((JavaType.FullyQualified) type).getPackageName())) {
return an;
}
}
}
}
AddOrUpdateAnnotationAttribute addOrUpdateAnnotationAttribute = new AddOrUpdateAnnotationAttribute(ORG_OPENREWRITE_OPTION, "example", "TODO Provide a usage example for the docs", true);
return (J.Annotation) addOrUpdateAnnotationAttribute.getVisitor().visitNonNull(an, ctx, getCursor().getParent());
}
});
}
}