All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.java.tree.J Maven / Gradle / Ivy

/*
 * Copyright 2020 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.tree; import com.fasterxml.jackson.annotation.*; import com.koloboke.collect.map.hash.HashObjObjMaps; import lombok.*; import lombok.experimental.FieldDefaults; import org.openrewrite.*; import org.openrewrite.internal.lang.NonNull; import org.openrewrite.internal.lang.Nullable; import org.openrewrite.java.JavaSourceVisitor; import org.openrewrite.java.JavaStyle; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.internal.PrintJava; import org.openrewrite.java.search.*; import java.io.Serializable; import java.nio.file.Path; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import static java.util.Arrays.stream; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import static org.openrewrite.Formatting.EMPTY; import static org.openrewrite.Formatting.format; import static org.openrewrite.Tree.randomId; @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@ref") public interface J extends Serializable, Tree { @Override default R accept(SourceVisitor v) { return v instanceof JavaSourceVisitor ? acceptJava((JavaSourceVisitor) v) : v.defaultTo(null); } default R acceptJava(JavaSourceVisitor v) { return v.defaultTo(null); } @Override default String print() { return new PrintJava().visit(this); } @SuppressWarnings("unchecked") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class AnnotatedType implements J, Expression, TypeTree { @EqualsAndHashCode.Include UUID id; @With List annotations; @With TypeTree typeExpr; @With Formatting formatting; @Override public JavaType getType() { return typeExpr.getType(); } @Override public AnnotatedType withType(@Nullable JavaType type) { return withTypeExpr(typeExpr.withType(type)); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitAnnotatedType(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Annotation implements J, Expression { @EqualsAndHashCode.Include UUID id; @With NameTree annotationType; @With @Nullable Arguments args; @With Formatting formatting; @JsonIgnore @Override public JavaType getType() { return annotationType.getType(); } @SuppressWarnings("unchecked") @Override public Annotation withType(@Nullable JavaType type) { return withAnnotationType(annotationType.withType(type)); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitAnnotation(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Arguments implements J { @EqualsAndHashCode.Include UUID id; @With List args; @With Formatting formatting; } @Override public Optional whenType(Class treeType) { return Optional.empty(); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class ArrayAccess implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Expression indexed; @With Dimension dimension; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitArrayAccess(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Dimension implements J { @EqualsAndHashCode.Include UUID id; @With Expression index; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class ArrayType implements J, TypeTree, Expression { @EqualsAndHashCode.Include UUID id; @With TypeTree elementType; @With List dimensions; @With Formatting formatting; @Override public JavaType getType() { return elementType.getType(); } @SuppressWarnings("unchecked") @Override public ArrayType withType(JavaType type) { return withElementType(elementType.withType(type)); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitArrayType(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Dimension implements J { @EqualsAndHashCode.Include UUID id; @With Empty inner; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Assert implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Expression condition; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitAssert(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Assign implements J, Statement, Expression { @EqualsAndHashCode.Include UUID id; @With Expression variable; @With Expression assignment; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitAssign(this); } @JsonIgnore @Override public List getSideEffects() { return singletonList(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class AssignOp implements J, Statement, Expression { @EqualsAndHashCode.Include UUID id; @With Expression variable; @With Operator operator; @With Expression assignment; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitAssignOp(this); } @JsonIgnore @Override public List getSideEffects() { return singletonList(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) public static abstract class Operator implements J { @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Addition extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Subtraction extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Multiplication extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Division extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Modulo extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class BitAnd extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class BitOr extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class BitXor extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class LeftShift extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class RightShift extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class UnsignedRightShift extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Binary implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Expression left; @With Operator operator; @With Expression right; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitBinary(this); } @JsonIgnore @Override public List getSideEffects() { List sideEffects = new ArrayList<>(2); sideEffects.addAll(left.getSideEffects()); sideEffects.addAll(right.getSideEffects()); return sideEffects; } @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) public static abstract class Operator implements J { @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Addition extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Subtraction extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Multiplication extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Division extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Modulo extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class LessThan extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class GreaterThan extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class LessThanOrEqual extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class GreaterThanOrEqual extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Equal extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class NotEqual extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class BitAnd extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class BitOr extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class BitXor extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class LeftShift extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class RightShift extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class UnsignedRightShift extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Or extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class And extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @AllArgsConstructor final class Block implements J, Statement { @Getter @EqualsAndHashCode.Include UUID id; @Nullable Empty statik; public Block withStatic(Empty statik) { return new Block<>(id, statik, statements, formatting, end); } @With @Getter List statements; @Getter @With Formatting formatting; @With @Getter End end; @Nullable public Empty getStatic() { return statik; } @SuppressWarnings("unchecked") @Override public R acceptJava(JavaSourceVisitor v) { return v.visitBlock((Block) this); } @JsonIgnore public int getIndent() { return Formatting.getIndent(end.getPrefix()); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class End implements J { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Break implements J, Statement { @EqualsAndHashCode.Include UUID id; @With @Nullable Ident label; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitBreak(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Case implements J, Statement { @EqualsAndHashCode.Include UUID id; @With @Nullable Expression pattern; @With List statements; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitCase(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @AllArgsConstructor final class ClassDecl implements J, Statement { @Getter @EqualsAndHashCode.Include UUID id; @With @Getter List annotations; @Getter List modifiers; public ClassDecl withModifiers(List modifiers) { if (modifiers == this.modifiers) { return this; } return new ClassDecl(id, annotations, modifiers, kind, name, typeParameters, extendings, implementings, body, type, formatting); } public ClassDecl withModifiers(String... modifierKeywords) { List fixedModifiers = Modifier.withModifiers(modifiers, modifierKeywords); if (fixedModifiers == modifiers) { return this; } else if (modifiers.isEmpty()) { return withModifiers(fixedModifiers).withKind(kind.withPrefix(" ")); } return withModifiers(fixedModifiers); } @With @Getter Kind kind; @With @Getter Ident name; @With @Getter @Nullable TypeParameters typeParameters; @Nullable Extends extendings; public ClassDecl withExtends(@Nullable Extends extendings) { if(extendings == this.extendings) { return this; } return new ClassDecl(id, annotations, modifiers, kind, name, typeParameters, extendings, implementings, body, type, formatting); } @JsonProperty("extendings") @Nullable public Extends getExtends() { return extendings; } @Nullable Implements implementings; public ClassDecl withImplements(@Nullable Implements implementings) { if(implementings == this.implementings) { return this; } return new ClassDecl(id, annotations, modifiers, kind, name, typeParameters, extendings, implementings, body, type, formatting); } @JsonProperty("implementings") @Nullable public Implements getImplements() { return implementings; } @With @Getter Block body; @Getter @Nullable JavaType.Class type; @Getter @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitClassDecl(this); } @JsonIgnore public String getSimpleName() { return name.getSimpleName(); } @Nullable public EnumValueSet getEnumValues() { return body.getStatements().stream() .filter(EnumValueSet.class::isInstance) .map(EnumValueSet.class::cast) .findAny() .orElse(null); } @JsonIgnore public List getFields() { return body.getStatements().stream() .filter(VariableDecls.class::isInstance) .map(VariableDecls.class::cast) .collect(toList()); } @JsonIgnore public List getMethods() { return body.getStatements().stream() .filter(MethodDecl.class::isInstance) .map(MethodDecl.class::cast) .collect(toList()); } @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) public static abstract class Kind implements J { @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Class extends Kind { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Enum extends Kind { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Interface extends Kind { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Annotation extends Kind { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Extends implements J { @EqualsAndHashCode.Include UUID id; @With TypeTree from; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Implements implements J { @EqualsAndHashCode.Include UUID id; @With List from; @With Formatting formatting; } /** * Find fields defined on this class, but do not include inherited fields up the type hierarchy */ public List findFields(String clazz) { return new FindFields(clazz).visit(this); } /** * Find fields defined up the type hierarchy, but do not include fields defined directly on this class */ public List findInheritedFields(String clazz) { return new FindInheritedFields(clazz).visit(this); } public List findMethodCalls(String signature) { return new FindMethods(signature).visit(this); } public Set findType(String clazz) { return new FindType(clazz).visit(this); } public List findAnnotations(String signature) { return new FindAnnotations(signature).visit(this); } public List findAnnotationsOnClass(String signature) { FindAnnotations findAnnotations = new FindAnnotations(signature); return getAnnotations().stream().flatMap(a -> findAnnotations.visitAnnotation(a).stream()).collect(toList()); } public boolean hasType(String clazz) { return new HasType(clazz).visit(this); } public boolean hasModifier(String modifier) { return Modifier.hasModifier(getModifiers(), modifier); } @JsonIgnore public boolean isEnum() { return kind instanceof Kind.Enum; } @JsonIgnore public boolean isClass() { return kind instanceof Kind.Class; } @JsonIgnore public boolean isInterface() { return kind instanceof Kind.Interface; } @JsonIgnore public boolean isAnnotation() { return kind instanceof Kind.Annotation; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class CompilationUnit implements J, SourceFile { @EqualsAndHashCode.Include UUID id; String sourcePath; @With Collection metadata; @With @Nullable Package packageDecl; @With List imports; @With List classes; @With Formatting formatting; @With Collection styles; @Override public Collection getStyles() { return styles; } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitCompilationUnit(this); } public boolean hasImport(String clazz) { return new HasImport(clazz).visit(this); } public boolean hasType(String clazz) { return new HasType(clazz).visit(this); } public List findMethodCalls(String signature) { return new FindMethods(signature).visit(this); } public Set findType(String clazz) { return new FindType(clazz).visit(this); } public static J.CompilationUnit buildEmptyClass(Path sourceSet, String packageName, String className) { String sourcePath = sourceSet .resolve(packageName.replace(".", System.getProperty("separator") == null ? "/" : System.getProperty("separator"))) .resolve(className + ".java") .toString(); return new J.CompilationUnit(randomId(), sourcePath, emptyList(), new J.Package(randomId(), TreeBuilder.buildName(packageName).withPrefix(" "), EMPTY), emptyList(), singletonList(new J.ClassDecl(randomId(), emptyList(), emptyList(), new ClassDecl.Kind.Class(randomId(), EMPTY), TreeBuilder.buildName(className).withPrefix(" "), null, null, null, new Try.Block<>(randomId(), null, emptyList(), format(" "), new Block.End(randomId(), format("\n"))), JavaType.Class.build(packageName + "." + className), format("\n\n")).withModifiers("public")), EMPTY, emptyList()); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Continue implements J, Statement { @EqualsAndHashCode.Include UUID id; @With @Nullable Ident label; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitContinue(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class DoWhileLoop implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Statement body; @With While whileCondition; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitDoWhileLoop(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class While implements J { @EqualsAndHashCode.Include UUID id; @With Parentheses condition; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Empty implements J, Statement, Expression, TypeTree { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; @Override public JavaType getType() { return null; } @SuppressWarnings("unchecked") @Override public Empty withType(JavaType type) { return this; } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitEmpty(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class EnumValue implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Ident name; @With @Nullable NewClass initializer; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitEnumValue(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class EnumValueSet implements J, Statement { @EqualsAndHashCode.Include UUID id; @With List enums; boolean terminatedWithSemicolon; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitEnumValueSet(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class FieldAccess implements J, TypeTree, Expression { @EqualsAndHashCode.Include UUID id; @With Expression target; @With Ident name; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitFieldAccess(this); } @JsonIgnore public String getSimpleName() { return name.getSimpleName(); } @JsonIgnore @Override public List getSideEffects() { return target.getSideEffects(); } /** * Make debugging a bit easier */ public String toString() { return "FieldAccess(" + printTrimmed() + ")"; } /** * @return For expressions like {@code String.class}, this casts target expression to a {@link NameTree}. * If the field access is not a reference to a class type, returns null. */ @Nullable public NameTree asClassReference() { if (target instanceof NameTree) { String fqn = null; if (type instanceof JavaType.Class) { fqn = ((JavaType.Class) type).getFullyQualifiedName(); } else if (type instanceof JavaType.ShallowClass) { fqn = ((JavaType.ShallowClass) type).getFullyQualifiedName(); } return "java.lang.Class".equals(fqn) ? (NameTree) target : null; } return null; } public boolean isFullyQualifiedClassReference(String className) { return isFullyQualifiedClassReference(this, className); } /** * Evaluate whether the specified MethodMatcher and this FieldAccess are describing the same type or not. * Known limitation/bug: MethodMatchers can have patterns/wildcards like "com.*.Bar" instead of something * concrete like "com.foo.Bar". This limitation is not desirable or intentional and should be fixed. * If a methodMatcher is passed that includes wildcards the result will always be "false" * * @param methodMatcher a methodMatcher whose internal pattern is fully concrete (no wildcards) * */ public boolean isFullyQualifiedClassReference(MethodMatcher methodMatcher) { String hopefullyFullyQualifiedMethod = methodMatcher.getTargetTypePattern().pattern() + "." + methodMatcher.getMethodNamePattern().pattern(); return isFullyQualifiedClassReference(this, hopefullyFullyQualifiedMethod); } private boolean isFullyQualifiedClassReference(J.FieldAccess fieldAccess, String className) { if (!className.contains(".")) { return false; } if (!fieldAccess.getName().getSimpleName().equals(className.substring(className.lastIndexOf('.') + 1))) { return false; } if (fieldAccess.getTarget() instanceof J.FieldAccess) { return isFullyQualifiedClassReference((J.FieldAccess) fieldAccess.getTarget(), className.substring(0, className.lastIndexOf('.'))); } if (fieldAccess.getTarget() instanceof J.Ident) { return ((J.Ident) fieldAccess.getTarget()).getSimpleName().equals(className.substring(0, className.lastIndexOf('.'))); } return false; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class ForEachLoop implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Control control; @With Statement body; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitForEachLoop(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Control implements J { @EqualsAndHashCode.Include UUID id; @With VariableDecls variable; @With Expression iterable; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class ForLoop implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Control control; @With Statement body; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitForLoop(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Control implements J { @EqualsAndHashCode.Include UUID id; @With Statement init; @With Expression condition; @With List update; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Getter final class Ident implements J, TypeTree, Expression { private static final Map> flyweights = HashObjObjMaps.newMutableMap(); @EqualsAndHashCode.Include UUID id; IdentFlyweight ident; @With Formatting formatting; private Ident(UUID id, IdentFlyweight ident, Formatting formatting) { this.id = id; this.ident = ident; this.formatting = formatting; } @Override public JavaType getType() { return ident.getType(); } @SuppressWarnings("unchecked") @Override public Ident withType(JavaType type) { return build(id, getSimpleName(), type, formatting); } @JsonIgnore public String getSimpleName() { return ident.getSimpleName(); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitIdentifier(this); } public Ident withName(String name) { return build(id, name, getType(), formatting); } @JsonCreator public static Ident build(@JsonProperty("id") UUID id, @JsonProperty("simpleName") String simpleName, @JsonProperty("type") @Nullable JavaType type, @JsonProperty("formatting") Formatting formatting) { synchronized (flyweights) { return new Ident( id, flyweights .computeIfAbsent(simpleName, n -> HashObjObjMaps.newMutableMap()) .computeIfAbsent(type, t -> new IdentFlyweight(simpleName, t)), formatting ); } } public static Ident buildClassName(String fullyQualifiedName) { JavaType.Class classType = JavaType.Class.build(fullyQualifiedName); return J.Ident.build( randomId(), classType.getClassName(), classType, EMPTY ); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Data public static final class IdentFlyweight implements Serializable { String simpleName; @Nullable JavaType type; } /** * Making debugging a bit easier */ public String toString() { return "Ident(" + printTrimmed() + ")"; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class If implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Parentheses ifCondition; @With Statement thenPart; @With @Nullable Else elsePart; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitIf(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Else implements J { @EqualsAndHashCode.Include UUID id; @With Statement statement; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitElse(this); } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @AllArgsConstructor final class Import implements J, Comparable { @Getter @EqualsAndHashCode.Include UUID id; @With @Getter FieldAccess qualid; @With boolean statik; @Getter @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitImport(this); } public boolean isStatic() { return statik; } @JsonIgnore public boolean isFromType(String clazz) { if ("*".equals(qualid.getSimpleName())) { return qualid.target.printTrimmed().equals(Arrays.stream(clazz.split("\\.")) .filter(pkgOrNam -> Character.isLowerCase(pkgOrNam.charAt(0))) .collect(Collectors.joining(".")) ); } return (isStatic() ? qualid.getTarget().printTrimmed() : qualid.printTrimmed()).equals(clazz); } public String getTypeName() { return isStatic() ? qualid.getTarget().printTrimmed() : qualid.printTrimmed(); } @JsonIgnore public String getPackageName() { JavaType.Class importType = TypeUtils.asClass(qualid.getType()); if (importType != null) { return importType.getPackageName(); } AtomicBoolean takeWhile = new AtomicBoolean(true); return stream(qualid.getTarget().printTrimmed().split("\\.")) .filter(pkg -> { takeWhile.set(takeWhile.get() && !pkg.isEmpty() && Character.isLowerCase(pkg.charAt(0))); return takeWhile.get(); }) .collect(joining(".")); } @Override public int compareTo(Import o) { String p1 = this.getPackageName(); String p2 = o.getPackageName(); String[] p1s = p1.split("\\."); String[] p2s = p2.split("\\."); for (int i = 0; i < p1s.length; i++) { String s = p1s[i]; if (p2s.length < i + 1) { return 1; } if (!s.equals(p2s[i])) { return s.compareTo(p2s[i]); } } return p1s.length < p2s.length ? -1 : this.getQualid().getSimpleName().compareTo(o.getQualid().getSimpleName()); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class InstanceOf implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Expression expr; @With Tree clazz; @With @Nullable JavaType type; @With private final Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitInstanceOf(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Label implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Ident label; @With Statement statement; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitLabel(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Lambda implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Parameters paramSet; @With Arrow arrow; @With Tree body; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitLambda(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Arrow implements J { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Parameters implements J { @EqualsAndHashCode.Include UUID id; @With boolean parenthesized; @With List params; Formatting formatting = EMPTY; @SuppressWarnings("unchecked") @Override public T withFormatting(Formatting fmt) { return (T) this; } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Literal implements J, Expression { @EqualsAndHashCode.Include UUID id; @With @Nullable Object value; @With String valueSource; /** * Including String literals */ JavaType.Primitive type; @SuppressWarnings("unchecked") @Override public Literal withType(JavaType type) { if (type instanceof JavaType.Primitive) { return new Literal(id, value, valueSource, (JavaType.Primitive) type, formatting); } return this; } @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitLiteral(this); } public String transformValue(Function transform) { Matcher valueMatcher = Pattern.compile("(.*)" + Pattern.quote(value == null ? "null" : value.toString()) + "(.*)") .matcher(printTrimmed().replace("\\", "")); if (valueMatcher.find()) { String prefix = valueMatcher.group(1); String suffix = valueMatcher.group(2); //noinspection unchecked return prefix + transform.apply((T) value) + suffix; } throw new IllegalStateException("Encountered a literal `" + this + "` that could not be transformed"); } public static Literal buildString(String value) { return new J.Literal( randomId(), value, "\"" + value + "\"", JavaType.Primitive.String, EMPTY ); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class MemberReference implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Expression containing; @With @Nullable TypeParameters typeParameters; @With Ident reference; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitMemberReference(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor final class MethodDecl implements J { @Getter @EqualsAndHashCode.Include UUID id; @With @Getter List annotations; @Getter List modifiers; public MethodDecl withModifiers(List modifiers) { if (modifiers == this.modifiers) { return this; } return new MethodDecl(id, annotations, modifiers, typeParameters, returnTypeExpr, name, params, throwz, body, defaultValue, formatting); } public MethodDecl withModifiers(String... modifierKeywords) { List fixedModifiers = Modifier.withModifiers(modifiers, modifierKeywords); if (fixedModifiers == modifiers) { return this; } else if (modifiers.isEmpty()) { if (typeParameters != null) { return withModifiers(Formatting.formatFirstPrefix(fixedModifiers, typeParameters.getPrefix())) .withTypeParameters(typeParameters.withPrefix(" ")); } else if (returnTypeExpr != null) { return withModifiers(Formatting.formatFirstPrefix(fixedModifiers, returnTypeExpr.getPrefix())) .withReturnTypeExpr(returnTypeExpr.withPrefix(" ")); } else { return withModifiers(Formatting.formatFirstPrefix(fixedModifiers, name.getPrefix())) .withName(name.withPrefix(" ")); } } return withModifiers(fixedModifiers); } @With @Getter @Nullable TypeParameters typeParameters; /** * Null for constructor declarations. */ @With @Getter @Nullable TypeTree returnTypeExpr; @With @Getter Ident name; @With @Getter Parameters params; @Nullable Throws throwz; public MethodDecl withThrows(Throws throwz) { if(throwz == this.throwz) { return this; } return new MethodDecl(id, annotations, modifiers, typeParameters, returnTypeExpr, name, params, throwz, body, defaultValue, formatting); } @JsonProperty("throwz") @Nullable public Throws getThrows() { return throwz; } /** * Null for abstract method declarations and interface method declarations. */ @With @Getter @Nullable Block body; @With @Getter @Nullable Default defaultValue; @Getter @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitMethod(this); } @JsonIgnore public boolean isAbstract() { return body == null; } public boolean hasType(String clazz) { return new HasType(clazz).visit(this); } public List findAnnotations(String signature) { return new FindAnnotations(signature).visit(this); } @JsonIgnore public boolean isConstructor() { return getReturnTypeExpr() == null; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Parameters implements J { @EqualsAndHashCode.Include UUID id; @With List params; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Throws implements J { @EqualsAndHashCode.Include UUID id; @With List exceptions; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Default implements J { @EqualsAndHashCode.Include UUID id; @With Expression value; @With Formatting formatting; } @JsonIgnore public String getSimpleName() { return name.getSimpleName(); } public boolean hasModifier(String modifier) { return Modifier.hasModifier(getModifiers(), modifier); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class MethodInvocation implements J, Statement, Expression { @EqualsAndHashCode.Include UUID id; @With @Nullable Expression select; @With @Nullable TypeParameters typeParameters; @With Ident name; @With Arguments args; @Nullable JavaType.Method type; @With Formatting formatting; @SuppressWarnings("unchecked") @Override public MethodInvocation withType(JavaType type) { if (type instanceof JavaType.Method) { return new MethodInvocation(id, select, typeParameters, name, args, (JavaType.Method) type, formatting); } return this; } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitMethodInvocation(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } @JsonIgnore @Nullable public JavaType getReturnType() { return type == null ? null : type.getResolvedSignature() == null ? null : type.getResolvedSignature().getReturnType(); } @JsonIgnore public String getSimpleName() { return name.getSimpleName(); } @JsonIgnore @Override public List getSideEffects() { return singletonList(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Arguments implements J { @EqualsAndHashCode.Include UUID id; @With List args; @With Formatting formatting; } } @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) abstract class Modifier implements J { static boolean hasModifier(Collection modifiers, String modifier) { return modifiers.stream().anyMatch(m -> m.getClass().getSimpleName() .toLowerCase().equals(modifier)); } /** * Adds a new modifier(s) to a modifier list in a canonical way, e.g. add final after static and visibility modifiers, * static before final and after visibility modifiers. * * @param existing The existing list of modifiers to add to. * @param modifierKeywords The new modifiers to add. * @return A new list containing the new modifier, or the original list instance if the modifier * is already present in the list. */ static List withModifiers(List existing, String... modifierKeywords) { boolean visibilityChanged = false; List modifiers = new ArrayList<>(existing); for (String modifier : modifierKeywords) { int sizeBeforeAdd = modifiers.size(); if ("final".equals(modifier) && !hasModifier(existing, "final")) { boolean finalAdded = false; for (int i = 0; i < sizeBeforeAdd; i++) { Modifier m = modifiers.get(i); if (m instanceof Static) { modifiers.add(i + 1, new Final(randomId(), format(" "))); finalAdded = true; break; } if (i == modifiers.size() - 1) { modifiers.set(i, m.withSuffix("")); modifiers.add(i + 1, new Final(randomId(), format(" ", m.getSuffix()))); finalAdded = true; } } if (!finalAdded) { modifiers.add(0, new Final(randomId(), EMPTY)); } } else if ("static".equals(modifier) && !hasModifier(existing, "static")) { boolean staticAdded = false; int afterAccessModifier = 0; for (int i = 0; i < sizeBeforeAdd; i++) { Modifier m = modifiers.get(i); if (m instanceof Private || m instanceof Protected || m instanceof Public) { afterAccessModifier = i + 1; } else if (m instanceof Final) { modifiers.set(i, m.withFormatting(format(" ", m.getSuffix()))); modifiers.add(i, new Static(randomId(), format(m.getPrefix()))); staticAdded = true; break; } if (i == modifiers.size() - 1) { modifiers.set(i, m.withSuffix("")); modifiers.add(afterAccessModifier, new Static(randomId(), format(" ", m.getSuffix()))); staticAdded = true; } } if (!staticAdded) { modifiers.add(0, new Static(randomId(), EMPTY)); } } else if (("public".equals(modifier) || "protected".equals(modifier) || "private".equals(modifier)) && !hasModifier(existing, modifier)) { boolean accessModifierAdded = false; for (int i = 0; i < sizeBeforeAdd; i++) { Modifier m = modifiers.get(i); if (m instanceof Private || m instanceof Protected || m instanceof Public) { // replace a different access modifier in place modifiers.set(i, buildModifier(modifier, m.getFormatting())); accessModifierAdded = true; visibilityChanged = true; break; } if (i == modifiers.size() - 1) { modifiers.add(0, buildModifier(modifier, format(modifiers.get(0).getPrefix(), m.getSuffix()))); modifiers.set(i + 1, m.withFormatting(format(" ", ""))); accessModifierAdded = true; } } if (!accessModifierAdded) { modifiers.add(0, buildModifier(modifier, EMPTY)); } } } return visibilityChanged || modifiers.size() > existing.size() ? modifiers : existing; } private static J.Modifier buildModifier(String modifier, Formatting formatting) { Modifier access; switch (modifier) { case "public": access = new Public(randomId(), formatting); break; case "protected": access = new Protected(randomId(), formatting); break; case "private": default: access = new Private(randomId(), formatting); break; } return access; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Default extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Public extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Protected extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Private extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Abstract extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Static extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Final extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Native extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Strictfp extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Synchronized extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Transient extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Volatile extends Modifier { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class MultiCatch implements J, TypeTree { @EqualsAndHashCode.Include UUID id; @With List alternatives; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitMultiCatch(this); } @SuppressWarnings("unchecked") @Override public MultiCatch withType(JavaType type) { // cannot overwrite type directly, perform this operation on each alternative separately return this; } @JsonIgnore @Override public JavaType getType() { return new JavaType.MultiCatch(alternatives.stream() .filter(Objects::nonNull) .map(NameTree::getType) .collect(toList())); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class NewArray implements J, Expression { @EqualsAndHashCode.Include UUID id; @With @Nullable TypeTree typeExpr; @With List dimensions; @With @Nullable Initializer initializer; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitNewArray(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Dimension implements J { @EqualsAndHashCode.Include UUID id; @With Expression size; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Initializer implements J { @EqualsAndHashCode.Include UUID id; @With List elements; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class NewClass implements J, Statement, Expression { @EqualsAndHashCode.Include UUID id; @Nullable @With J.Ident encl; New nooh; public NewClass withNew(New nooh) { return new NewClass(id, encl, nooh, clazz, args, body, type, formatting); } @Nullable @With TypeTree clazz; @Nullable @With Arguments args; @With @Nullable Block body; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitNewClass(this); } @JsonIgnore @Override public List getSideEffects() { return singletonList(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Arguments implements J { @EqualsAndHashCode.Include UUID id; @With List args; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class New implements J { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Package implements J { @EqualsAndHashCode.Include UUID id; @With Expression expr; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitPackage(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class ParameterizedType implements J, TypeTree, Expression { @EqualsAndHashCode.Include UUID id; @With NameTree clazz; @With @Nullable TypeParameters typeParameters; @With Formatting formatting; @Override public JavaType getType() { return clazz.getType(); } @SuppressWarnings("unchecked") @Override public ParameterizedType withType(JavaType type) { return withClazz(clazz.withType(type)); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitParameterizedType(this); } public static ParameterizedType build(String typeName, String... genericTypeNames) { JavaType.Class typeNameType = JavaType.Class.build(typeName); return new J.ParameterizedType( randomId(), J.Ident.build( randomId(), typeNameType.getClassName(), typeNameType, EMPTY), new J.TypeParameters( randomId(), Formatting.formatFirstPrefix( stream(genericTypeNames) .map(generic -> { JavaType.Class genericType = JavaType.Class.build(generic); return new J.TypeParameter( randomId(), emptyList(), J.Ident.build( randomId(), genericType.getClassName(), genericType, EMPTY ), null, format(" ") ); }) .collect(Collectors.toList()), "" ), EMPTY), EMPTY ); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Parentheses implements J, Expression { @EqualsAndHashCode.Include UUID id; @With T tree; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitParentheses(this); } @JsonIgnore @Override public List getSideEffects() { return tree instanceof Expression ? ((Expression) tree).getSideEffects() : emptyList(); } @Override public JavaType getType() { return tree instanceof Expression ? ((Expression) tree).getType() : tree instanceof NameTree ? ((NameTree) tree).getType() : null; } @SuppressWarnings("unchecked") @Override public Parentheses withType(JavaType type) { return tree instanceof Expression ? ((Expression) tree).withType(type) : tree instanceof NameTree ? ((NameTree) tree).withType(type) : this; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @AllArgsConstructor final class Primitive implements J, TypeTree, Expression { @Getter @EqualsAndHashCode.Include UUID id; JavaType.Primitive type; @SuppressWarnings("unchecked") @Override public Primitive withType(JavaType type) { if (!(type instanceof JavaType.Primitive)) { throw new IllegalArgumentException("Cannot apply a non-primitive type to Primitve"); } return new Primitive(id, (JavaType.Primitive) type, formatting); } @Override @NonNull public JavaType.Primitive getType() { return type; } @Getter @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitPrimitive(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Return implements J, Statement { @EqualsAndHashCode.Include UUID id; @With @Nullable Expression expr; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitReturn(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Switch implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Parentheses selector; @With Block cases; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitSwitch(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Synchronized implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Parentheses lock; @With Block body; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitSynchronized(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Ternary implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Expression condition; @With Expression truePart; @With Expression falsePart; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitTernary(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Throw implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Expression exception; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitThrow(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @AllArgsConstructor final class Try implements J, Statement { @Getter @EqualsAndHashCode.Include UUID id; @With @Getter @Nullable Resources resources; @With @Getter Block body; @With @Getter List catches; @Nullable Finally finallie; public Try withFinally(Finally finallie) { if(finallie == this.finallie) { return this; } return new Try(id, resources, body, catches, finallie, formatting); } @Nullable public Finally getFinally() { return finallie; } @Getter @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitTry(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Resources implements J { @EqualsAndHashCode.Include UUID id; @With List decls; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Catch implements J { @EqualsAndHashCode.Include UUID id; @With Parentheses param; @With Block body; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitCatch(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Finally implements J { @EqualsAndHashCode.Include UUID id; @With Block body; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitFinally(this); } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class TypeCast implements J, Expression { @EqualsAndHashCode.Include UUID id; @With Parentheses clazz; @With Expression expr; @With Formatting formatting; @Override public JavaType getType() { return clazz.getType(); } @SuppressWarnings("unchecked") @Override public TypeCast withType(JavaType type) { return withClazz(clazz.withType(type)); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitTypeCast(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class TypeParameter implements J { @EqualsAndHashCode.Include UUID id; @With List annotations; /** * Will be either a {@link TypeTree} or {@link Wildcard}. Wildcards aren't possible in * every context where type parameters may be defined (e.g. not possible on new statements). */ @With Expression name; @With @Nullable Bounds bounds; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitTypeParameter(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Bounds implements J { @EqualsAndHashCode.Include UUID id; @With List types; @With Formatting formatting; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class TypeParameters implements J { @EqualsAndHashCode.Include UUID id; @With List params; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitTypeParameters(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Unary implements J, Statement, Expression { @EqualsAndHashCode.Include UUID id; @With Operator operator; @With Expression expr; @With @Nullable JavaType type; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitUnary(this); } @JsonIgnore @Override public List getSideEffects() { return expr.getSideEffects(); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public abstract static class Operator implements J { // NOTE: only some operators may have empty formatting @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class PreIncrement extends Operator { @EqualsAndHashCode.Include UUID id; Formatting formatting = EMPTY; @SuppressWarnings("unchecked") @Override public T withFormatting(Formatting fmt) { return (T) this; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class PreDecrement extends Operator { @EqualsAndHashCode.Include UUID id; Formatting formatting = EMPTY; @SuppressWarnings("unchecked") @Override public T withFormatting(Formatting fmt) { return (T) this; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class PostIncrement extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class PostDecrement extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Positive extends Operator { @EqualsAndHashCode.Include UUID id; Formatting formatting = EMPTY; @SuppressWarnings("unchecked") @Override public T withFormatting(Formatting fmt) { return (T) this; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Negative extends Operator { @EqualsAndHashCode.Include UUID id; Formatting formatting = EMPTY; @SuppressWarnings("unchecked") @Override public T withFormatting(Formatting fmt) { return (T) this; } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Complement extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Not extends Operator { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class UnparsedSource implements J, Statement, Expression { @EqualsAndHashCode.Include UUID id; @With String source; @With Formatting formatting; @Override public JavaType getType() { return null; } @SuppressWarnings("unchecked") @Override public UnparsedSource withType(JavaType type) { return null; } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitUnparsedSource(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class VariableDecls implements J, Statement { @EqualsAndHashCode.Include UUID id; @With List annotations; List modifiers; public VariableDecls withModifiers(List modifiers) { if (modifiers == this.modifiers) { return this; } return new VariableDecls(id, annotations, modifiers, typeExpr, varargs, dimensionsBeforeName, vars, formatting); } public VariableDecls withModifiers(String... modifierKeywords) { if (typeExpr == null) { // cannot place modifiers on VariableDecls that occur in places where a type expression // is not also present (e.g. Lambda parameters). return this; } List fixedModifiers = Modifier.withModifiers(modifiers, modifierKeywords); if (fixedModifiers == modifiers) { return this; } else if (modifiers.isEmpty()) { return withModifiers(Formatting.formatFirstPrefix(fixedModifiers, typeExpr.getPrefix())) .withTypeExpr(typeExpr.withPrefix(" ")); } return withModifiers(fixedModifiers); } @With @Nullable TypeTree typeExpr; @With @Nullable Varargs varargs; @With List dimensionsBeforeName; @With List vars; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitMultiVariable(this); } @JsonIgnore @Override public boolean isSemicolonTerminated() { return true; } public List findAnnotations(String signature) { return new FindAnnotations(signature).visit(this); } @JsonIgnore public JavaType.Class getTypeAsClass() { return typeExpr == null ? null : TypeUtils.asClass(typeExpr.getType()); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Varargs implements J { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Dimension implements J { @EqualsAndHashCode.Include UUID id; @With Empty whitespace; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class NamedVar implements J, NameTree { @EqualsAndHashCode.Include UUID id; @With Ident name; @With List dimensionsAfterName; @With @Nullable Expression initializer; @With @Nullable JavaType type; @With Formatting formatting; @JsonIgnore public String getSimpleName() { return name.getSimpleName(); } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitVariable(this); } @JsonIgnore public boolean isField(Cursor cursor) { return cursor .getParentOrThrow() // J.VariableDecls .getParentOrThrow() // J.Block .getParentOrThrow() // maybe J.ClassDecl .getTree() instanceof J.ClassDecl; } } public boolean hasModifier(String modifier) { return Modifier.hasModifier(getModifiers(), modifier); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class WhileLoop implements J, Statement { @EqualsAndHashCode.Include UUID id; @With Parentheses condition; @With Statement body; @With Formatting formatting; @Override public R acceptJava(JavaSourceVisitor v) { return v.visitWhileLoop(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class Wildcard implements J, Expression { @EqualsAndHashCode.Include UUID id; @With @Nullable Bound bound; @With @Nullable NameTree boundedType; @With Formatting formatting; @Override public JavaType getType() { return null; } @SuppressWarnings("unchecked") @Override public Wildcard withType(JavaType type) { return this; } @Override public R acceptJava(JavaSourceVisitor v) { return v.visitWildcard(this); } @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) public abstract static class Bound implements J { @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Extends extends Bound { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data public static final class Super extends Bound { @EqualsAndHashCode.Include UUID id; @With Formatting formatting; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy