org.openrewrite.java.tree.J Maven / Gradle / Ivy
Show all versions of rewrite-java Show documentation
/*
* 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.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.NonFinal;
import org.openrewrite.*;
import org.openrewrite.internal.lang.NonNull;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.JavaPrinter;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.internal.*;
import org.openrewrite.java.search.FindTypes;
import org.openrewrite.marker.Markers;
import java.io.Serializable;
import java.lang.ref.WeakReference;
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;
@SuppressWarnings("unused")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@ref")
public interface J extends Serializable, Tree {
@SuppressWarnings("unchecked")
@Override
default R accept(TreeVisitor v, P p) {
return v instanceof JavaVisitor ?
(R) acceptJava((JavaVisitor) v, p) :
v.defaultValue(this, p);
}
@Nullable
default
J acceptJava(JavaVisitor
v, P p) {
return v.defaultValue(this, p);
}
default
String print(TreePrinter
printer, P p) {
return new JavaPrinter<>(printer).print(this, p);
}
@Override
default
String print(P p) {
return print(TreePrinter.identity(), p);
}
J2 withPrefix(Space space);
Space getPrefix();
default List getComments() {
return getPrefix().getComments();
}
default J2 withComments(List comments) {
return withPrefix(getPrefix().withComments(comments));
}
Coordinates getCoordinates();
@Incubating(since = "7.0.0")
default J2 withTemplate(JavaTemplate template, JavaCoordinates coordinates, Object... parameters) {
return template.withTemplate(this, coordinates, parameters);
}
@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
Space prefix;
@With
Markers markers;
@With
List annotations;
@With
TypeTree typeExpression;
@Override
public JavaType getType() {
return typeExpression.getType();
}
@Override
public AnnotatedType withType(@Nullable JavaType type) {
return withTypeExpression(typeExpression.withType(type));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitAnnotatedType(this, p);
}
@Override
public Coordinates.AnnotatedType getCoordinates() {
return new Coordinates.AnnotatedType(this);
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class Annotation implements J, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
NameTree annotationType;
public String getSimpleName() {
return annotationType instanceof Identifier ?
((Identifier) annotationType).getSimpleName() :
((J.FieldAccess) annotationType).getSimpleName();
}
@Nullable
JContainer arguments;
@Nullable
public List getArguments() {
return arguments == null ? null : arguments.getElements();
}
public Annotation withArguments(@Nullable List arguments) {
return getPadding().withArguments(JContainer.withElementsNullable(this.arguments, arguments));
}
@Override
public JavaType getType() {
return annotationType.getType();
}
@SuppressWarnings("unchecked")
@Override
public Annotation withType(@Nullable JavaType type) {
return withAnnotationType(annotationType.withType(type));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitAnnotation(this, p);
}
@Override
public Coordinates.Annotation getCoordinates() {
return new Coordinates.Annotation(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Annotation t;
@Nullable
public JContainer getArguments() {
return t.arguments;
}
public Annotation withArguments(@Nullable JContainer arguments) {
return t.arguments == arguments ? t : new Annotation(t.id, t.prefix, t.markers, t.annotationType, arguments);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class ArrayAccess implements J, Expression {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
Expression indexed;
@With
ArrayDimension dimension;
@With
@Nullable
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitArrayAccess(this, p);
}
@Override
public Coordinates.ArrayAccess getCoordinates() {
return new Coordinates.ArrayAccess(this);
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class ArrayType implements J, TypeTree, Expression {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
TypeTree elementType;
@With
List> dimensions;
@Override
public JavaType getType() {
return elementType.getType();
}
@SuppressWarnings("unchecked")
@Override
public ArrayType withType(@Nullable JavaType type) {
return type == getType() ? this : withElementType(elementType.withType(type));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitArrayType(this, p);
}
@Override
public Coordinates.ArrayType getCoordinates() {
return new Coordinates.ArrayType(this);
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class Assert implements J, Statement {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
Expression condition;
@Override
public
J acceptJava(JavaVisitor
v, P p) {
return v.visitAssert(this, p);
}
@Override
public Coordinates.Assert getCoordinates() {
return new Coordinates.Assert(this);
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class Assignment implements J, Statement, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Expression variable;
JLeftPadded assignment;
public Expression getAssignment() {
return assignment.getElement();
}
public Assignment withAssignment(Expression assignment) {
return getPadding().withAssignment(this.assignment.withElement(assignment));
}
@With
@Nullable
@Getter
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitAssignment(this, p);
}
@Override
public Coordinates.Assignment getCoordinates() {
return new Coordinates.Assignment(this);
}
@Override
public List getSideEffects() {
return singletonList(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Assignment t;
public JLeftPadded getAssignment() {
return t.assignment;
}
public Assignment withAssignment(JLeftPadded assignment) {
return t.assignment == assignment ? t : new Assignment(t.id, t.prefix, t.markers, t.variable, assignment, t.type);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class AssignmentOperation implements J, Statement, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Expression variable;
JLeftPadded operator;
public Type getOperator() {
return operator.getElement();
}
public AssignmentOperation withOperator(Type operator) {
return getPadding().withOperator(this.operator.withElement(operator));
}
@With
@Getter
Expression assignment;
@With
@Nullable
@Getter
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitAssignmentOperation(this, p);
}
@Override
public Coordinates.AssignmentOperation getCoordinates() {
return new Coordinates.AssignmentOperation(this);
}
@Override
public List getSideEffects() {
return singletonList(this);
}
public enum Type {
Addition,
Subtraction,
Multiplication,
Division,
Modulo,
BitAnd,
BitOr,
BitXor,
LeftShift,
RightShift,
UnsignedRightShift
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final AssignmentOperation t;
public JLeftPadded getOperator() {
return t.operator;
}
public AssignmentOperation withOperator(JLeftPadded operator) {
return t.operator == operator ? t : new AssignmentOperation(t.id, t.prefix, t.markers, t.variable, operator, t.assignment, t.type);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Data
final class Binary implements J, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
Expression left;
JLeftPadded operator;
public Type getOperator() {
return operator.getElement();
}
public Binary withOperator(Type operator) {
return getPadding().withOperator(this.operator.withElement(operator));
}
@With
Expression right;
@With
@Nullable
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitBinary(this, p);
}
@Override
public Coordinates.Binary getCoordinates() {
return new Coordinates.Binary(this);
}
@Override
public List getSideEffects() {
List sideEffects = new ArrayList<>(2);
sideEffects.addAll(left.getSideEffects());
sideEffects.addAll(right.getSideEffects());
return sideEffects;
}
public enum Type {
Addition,
Subtraction,
Multiplication,
Division,
Modulo,
LessThan,
GreaterThan,
LessThanOrEqual,
GreaterThanOrEqual,
Equal,
NotEqual,
BitAnd,
BitOr,
BitXor,
LeftShift,
RightShift,
UnsignedRightShift,
Or,
And
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Binary t;
public JLeftPadded getOperator() {
return t.operator;
}
public Binary withOperator(JLeftPadded operator) {
return t.operator == operator ? t : new Binary(t.id, t.prefix, t.markers, t.left, operator, t.right, t.type);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class Block implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@Getter
@EqualsAndHashCode.Include
UUID id;
@Getter
@With
Space prefix;
@Getter
@With
Markers markers;
JRightPadded statik;
public boolean isStatic() {
return statik.getElement();
}
public Block withStatic(boolean statik) {
return getPadding().withStatic(this.statik.withElement(statik));
}
List> statements;
public List getStatements() {
return JRightPadded.getElements(statements);
}
public Block withStatements(List statements) {
return getPadding().withStatements(JRightPadded.withElements(this.statements, statements));
}
@Getter
@With
Space end;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitBlock(this, p);
}
@Override
public Coordinates.Block getCoordinates() {
return new Coordinates.Block(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Block t;
public JRightPadded getStatic() {
return t.statik;
}
public Block withStatic(JRightPadded statik) {
return t.statik == statik ? t : new Block(t.id, t.prefix, t.markers, statik, t.statements, t.end);
}
public List> getStatements() {
return t.statements;
}
public Block withStatements(List> statements) {
return t.statements == statements ? t : new Block(t.id, t.prefix, t.markers, t.statik, statements, t.end);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class Break implements J, Statement {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
@Nullable
J.Identifier label;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitBreak(this, p);
}
@Override
public Coordinates.Break getCoordinates() {
return new Coordinates.Break(this);
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class Case implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Expression pattern;
JContainer statements;
public List getStatements() {
return statements.getElements();
}
public Case withStatements(List statements) {
return getPadding().withStatements(this.statements.getPadding().withElements(JRightPadded.withElements(
this.statements.getPadding().getElements(), statements)));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitCase(this, p);
}
@Override
public Coordinates.Case getCoordinates() {
return new Coordinates.Case(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Case t;
public JContainer getStatements() {
return t.statements;
}
public Case withStatements(JContainer statements) {
return t.statements == statements ? t : new Case(t.id, t.prefix, t.markers, t.pattern, statements);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class ClassDeclaration implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@Nullable
@NonFinal
transient WeakReference annotations;
@Getter
@EqualsAndHashCode.Include
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
List leadingAnnotations;
@With
@Getter
List modifiers;
Kind kind;
public Kind.Type getKind() {
return kind.getType();
}
public ClassDeclaration withKind(Kind.Type type) {
Kind k = getAnnotations().getKind();
if (k.type == type) {
return this;
} else {
return getAnnotations().withKind(k.withType(type));
}
}
@With
@Getter
Identifier name;
@Nullable
JContainer typeParameters;
@Nullable
public List getTypeParameters() {
return typeParameters == null ? null : typeParameters.getElements();
}
public ClassDeclaration withTypeParameters(@Nullable List typeParameters) {
return getPadding().withTypeParameters(JContainer.withElementsNullable(this.typeParameters, typeParameters));
}
@Nullable
JLeftPadded extendings;
@Nullable
public TypeTree getExtends() {
return extendings == null ? null : extendings.getElement();
}
public ClassDeclaration withExtends(@Nullable TypeTree extendings) {
return getPadding().withExtends(JLeftPadded.withElement(this.extendings, extendings));
}
@Nullable
JContainer implementings;
@Nullable
public List getImplements() {
return implementings == null ? null : implementings.getElements();
}
public ClassDeclaration withImplements(@Nullable List implementings) {
return getPadding().withImplements(JContainer.withElementsNullable(this.implementings, implementings));
}
@With
@Getter
Block body;
@With
@Getter
@Nullable
JavaType.Class type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitClassDeclaration(this, p);
}
// gather annotations from everywhere they may occur
public List getAllAnnotations() {
List allAnnotations = new ArrayList<>(leadingAnnotations);
for (J.Modifier modifier : modifiers) {
allAnnotations.addAll(modifier.getAnnotations());
}
allAnnotations.addAll(kind.getAnnotations());
return allAnnotations;
}
@Override
public Coordinates.ClassDeclaration getCoordinates() {
return new Coordinates.ClassDeclaration(this);
}
public String getSimpleName() {
return name.getSimpleName();
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
public static final class Kind implements J {
@Getter
@EqualsAndHashCode.Include
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
List annotations;
@With
@Getter
Type type;
@Override
public Coordinates getCoordinates() {
return new Coordinates.ClassDeclaration.Kind(this);
}
public enum Type {
Class,
Enum,
Interface,
Annotation
}
}
public boolean hasModifier(Modifier.Type modifier) {
return Modifier.hasModifier(getModifiers(), modifier);
}
@Override
public String toString() {
return "ClassDeclaration(" + ClassDeclarationToString.toString(this) + ")";
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final ClassDeclaration t;
@Nullable
public JLeftPadded getExtends() {
return t.extendings;
}
public ClassDeclaration withExtends(@Nullable JLeftPadded extendings) {
return t.extendings == extendings ? t : new ClassDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.kind, t.name, t.typeParameters, extendings, t.implementings, t.body, t.type);
}
@Nullable
public JContainer getImplements() {
return t.implementings;
}
public ClassDeclaration withImplements(@Nullable JContainer implementings) {
return t.implementings == implementings ? t : new ClassDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.kind, t.name, t.typeParameters, t.extendings, implementings, t.body, t.type);
}
@Nullable
public JContainer getTypeParameters() {
return t.typeParameters;
}
public ClassDeclaration withTypeParameters(@Nullable JContainer typeParameters) {
return t.typeParameters == typeParameters ? t : new ClassDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.kind, t.name, typeParameters, t.extendings, t.implementings, t.body, t.type);
}
}
public Annotations getAnnotations() {
Annotations a;
if (this.annotations == null) {
a = new Annotations(this);
this.annotations = new WeakReference<>(a);
} else {
a = this.annotations.get();
if (a == null || a.t != this) {
a = new Annotations(this);
this.annotations = new WeakReference<>(a);
}
}
return a;
}
@RequiredArgsConstructor
public static class Annotations {
private final ClassDeclaration t;
public Kind getKind() {
return t.kind;
}
public ClassDeclaration withKind(Kind kind) {
return t.kind == kind ? t : new ClassDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, kind, t.name, t.typeParameters, t.extendings, t.implementings, t.body, t.type);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class CompilationUnit implements J, SourceFile {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Path sourcePath;
@Nullable
JRightPadded packageDeclaration;
@Nullable
public Package getPackageDeclaration() {
return packageDeclaration == null ? null : packageDeclaration.getElement();
}
public CompilationUnit withPackageDeclaration(Package packageDeclaration) {
return getPadding().withPackageDeclaration(JRightPadded.withElement(this.packageDeclaration, packageDeclaration));
}
List> imports;
public List getImports() {
return JRightPadded.getElements(imports);
}
public CompilationUnit withImports(List imports) {
return getPadding().withImports(JRightPadded.withElements(this.imports, imports));
}
@With
@Getter
List classes;
@With
@Getter
Space eof;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitCompilationUnit(this, p);
}
@Override
public Coordinates.CompilationUnit getCoordinates() {
return new Coordinates.CompilationUnit(this);
}
public Set findType(String clazz) {
return FindTypes.find(this, clazz);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final CompilationUnit t;
@Nullable
public JRightPadded getPackageDeclaration() {
return t.packageDeclaration;
}
public CompilationUnit withPackageDeclaration(@Nullable JRightPadded packageDeclaration) {
return t.packageDeclaration == packageDeclaration ? t : new CompilationUnit(t.id, t.prefix, t.markers, t.sourcePath, packageDeclaration, t.imports, t.classes, t.eof);
}
public List> getImports() {
return t.imports;
}
public CompilationUnit withImports(List> imports) {
return t.imports == imports ? t : new CompilationUnit(t.id, t.prefix, t.markers, t.sourcePath, t.packageDeclaration, imports, t.classes, t.eof);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class Continue implements J, Statement {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
@Nullable
J.Identifier label;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitContinue(this, p);
}
@Override
public Coordinates.Continue getCoordinates() {
return new Coordinates.Continue(this);
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class DoWhileLoop implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
JRightPadded body;
public Statement getBody() {
return body.getElement();
}
public DoWhileLoop withBody(Statement body) {
return getPadding().withBody(this.body.withElement(body));
}
JLeftPadded> whileCondition;
public ControlParentheses getWhileCondition() {
return whileCondition.getElement();
}
public DoWhileLoop withWhileCondition(ControlParentheses whileCondition) {
return getPadding().withWhileCondition(this.whileCondition.withElement(whileCondition));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitDoWhileLoop(this, p);
}
@Override
public Coordinates.DoWhileLoop getCoordinates() {
return new Coordinates.DoWhileLoop(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final DoWhileLoop t;
public JRightPadded getBody() {
return t.body;
}
public DoWhileLoop withBody(JRightPadded body) {
return t.body == body ? t : new DoWhileLoop(t.id, t.prefix, t.markers, body, t.whileCondition);
}
public JLeftPadded> getWhileCondition() {
return t.whileCondition;
}
public DoWhileLoop withWhileCondition(JLeftPadded> whileCondition) {
return t.whileCondition == whileCondition ? t : new DoWhileLoop(t.id, t.prefix, t.markers, t.body, whileCondition);
}
}
}
@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
Space prefix;
@With
Markers markers;
@Override
public JavaType getType() {
return null;
}
@SuppressWarnings("unchecked")
@Override
public Empty withType(@Nullable JavaType type) {
return this;
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitEmpty(this, p);
}
@Override
public Coordinates.Empty getCoordinates() {
return new Coordinates.Empty(this);
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class EnumValue implements J {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
List annotations;
@With
Identifier name;
@With
@Nullable
NewClass initializer;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitEnumValue(this, p);
}
@Override
public Coordinates.EnumValue getCoordinates() {
return new Coordinates.EnumValue(this);
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class EnumValueSet implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
List> enums;
public List getEnums() {
return JRightPadded.getElements(enums);
}
public EnumValueSet withEnums(List enums) {
return getPadding().withEnums(JRightPadded.withElements(this.enums, enums));
}
@With
@Getter
boolean terminatedWithSemicolon;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitEnumValueSet(this, p);
}
@Override
public Coordinates.EnumValueSet getCoordinates() {
return new Coordinates.EnumValueSet(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final EnumValueSet t;
public List> getEnums() {
return t.enums;
}
public EnumValueSet withEnums(List> enums) {
return t.enums == enums ? t : new EnumValueSet(t.id, t.prefix, t.markers, enums, t.terminatedWithSemicolon);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class FieldAccess implements J, TypeTree, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Expression target;
JLeftPadded name;
public Identifier getName() {
return name.getElement();
}
public FieldAccess withName(Identifier name) {
return getPadding().withName(this.name.withElement(name));
}
@With
@Getter
@Nullable
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitFieldAccess(this, p);
}
@Override
public Coordinates.FieldAccess getCoordinates() {
return new Coordinates.FieldAccess(this);
}
public String getSimpleName() {
return name.getElement().getSimpleName();
}
@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 Identifier) {
return ((Identifier) fieldAccess.getTarget()).getSimpleName().equals(className.substring(0, className.lastIndexOf('.')));
}
return false;
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final FieldAccess t;
public JLeftPadded getName() {
return t.name;
}
public FieldAccess withName(JLeftPadded name) {
return t.name == name ? t : new FieldAccess(t.id, t.prefix, t.markers, t.target, name, t.type);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class ForEachLoop implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Control control;
JRightPadded body;
public Statement getBody() {
return body.getElement();
}
public ForEachLoop withBody(Statement body) {
return getPadding().withBody(this.body.withElement(body));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitForEachLoop(this, p);
}
@Override
public Coordinates.ForEachLoop getCoordinates() {
return new Coordinates.ForEachLoop(this);
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public static final class Control implements J {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
JRightPadded variable;
public VariableDeclarations getVariable() {
return variable.getElement();
}
public Control withVariable(VariableDeclarations variable) {
return getPadding().withVariable(this.variable.withElement(variable));
}
JRightPadded iterable;
public Expression getIterable() {
return iterable.getElement();
}
public Control withIterable(Expression iterable) {
return getPadding().withIterable(this.iterable.withElement(iterable));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitForEachControl(this, p);
}
@Override
public Coordinates.ForEachLoop.Control getCoordinates() {
return new Coordinates.ForEachLoop.Control(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Control t;
public JRightPadded getVariable() {
return t.variable;
}
public Control withVariable(JRightPadded variable) {
return t.variable == variable ? t : new Control(t.id, t.prefix, t.markers, variable, t.iterable);
}
public JRightPadded getIterable() {
return t.iterable;
}
public Control withIterable(JRightPadded iterable) {
return t.iterable == iterable ? t : new Control(t.id, t.prefix, t.markers, t.variable, iterable);
}
}
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final ForEachLoop t;
public JRightPadded getBody() {
return t.body;
}
public ForEachLoop withBody(JRightPadded body) {
return t.body == body ? t : new ForEachLoop(t.id, t.prefix, t.markers, t.control, body);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class ForLoop implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Control control;
JRightPadded body;
public Statement getBody() {
return body.getElement();
}
public ForLoop withBody(Statement body) {
return getPadding().withBody(this.body.withElement(body));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitForLoop(this, p);
}
@Override
public Coordinates.ForLoop getCoordinates() {
return new Coordinates.ForLoop(this);
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public static final class Control implements J {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
JRightPadded init;
public Statement getInit() {
return init.getElement();
}
public Control withInit(Statement init) {
return getPadding().withInit(this.init.withElement(init));
}
JRightPadded condition;
public Expression getCondition() {
return condition.getElement();
}
public Control withCondition(Expression condition) {
return getPadding().withCondition(this.condition.withElement(condition));
}
List> update;
public List getUpdate() {
return JRightPadded.getElements(update);
}
public Control withUpdate(List update) {
return getPadding().withUpdate(JRightPadded.withElements(this.update, update));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitForControl(this, p);
}
@Override
public Coordinates.ForLoop.Control getCoordinates() {
return new Coordinates.ForLoop.Control(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Control t;
public JRightPadded getInit() {
return t.init;
}
public ForLoop.Control withInit(JRightPadded init) {
return t.init == init ? t : new ForLoop.Control(t.id, t.prefix, t.markers, init, t.condition, t.update);
}
public JRightPadded getCondition() {
return t.condition;
}
public ForLoop.Control withCondition(JRightPadded condition) {
return t.condition == condition ? t : new ForLoop.Control(t.id, t.prefix, t.markers, t.init, condition, t.update);
}
public List> getUpdate() {
return t.update;
}
public ForLoop.Control withUpdate(List> update) {
return t.update == update ? t : new ForLoop.Control(t.id, t.prefix, t.markers, t.init, t.condition, update);
}
}
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final ForLoop t;
public JRightPadded getBody() {
return t.body;
}
public ForLoop withBody(JRightPadded body) {
return t.body == body ? t : new ForLoop(t.id, t.prefix, t.markers, t.control, body);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
final class Identifier implements J, TypeTree, Expression {
private static final Map> flyweights = new WeakHashMap<>();
@Getter
@EqualsAndHashCode.Include
UUID id;
@Getter
Space prefix;
@Getter
Markers markers;
IdentifierFlyweight identifier;
private Identifier(UUID id, IdentifierFlyweight identifier, Space prefix, Markers markers) {
this.id = id;
this.identifier = identifier;
this.prefix = prefix;
this.markers = markers;
}
@Override
public JavaType getType() {
return identifier.getType();
}
@SuppressWarnings("unchecked")
@Override
public Identifier withType(@Nullable JavaType type) {
if (type == getType()) {
return this;
}
return build(id, prefix, markers, getSimpleName(), type);
}
public String getSimpleName() {
return identifier.getSimpleName();
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitIdentifier(this, p);
}
@Override
public Coordinates.Identifier getCoordinates() {
return new Coordinates.Identifier(this);
}
public Identifier withName(String name) {
if (name.equals(identifier.getSimpleName())) {
return this;
}
return build(id, prefix, markers, name, getType());
}
@SuppressWarnings("unchecked")
public Identifier withMarkers(Markers markers) {
if (markers == this.markers) {
return this;
}
return build(id, prefix, markers, identifier.getSimpleName(), getType());
}
@SuppressWarnings("unchecked")
public Identifier withPrefix(Space prefix) {
if (prefix == this.prefix) {
return this;
}
return build(id, prefix, markers, identifier.getSimpleName(), getType());
}
@JsonCreator
public static Identifier build(UUID id,
Space prefix,
Markers markers,
String simpleName,
@Nullable JavaType type) {
synchronized (flyweights) {
return new Identifier(
id,
flyweights
.computeIfAbsent(simpleName, n -> new HashMap<>())
.computeIfAbsent(type, t -> new IdentifierFlyweight(simpleName, t)),
prefix,
markers
);
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@Data
public static final class IdentifierFlyweight implements Serializable {
String simpleName;
@Nullable
JavaType type;
}
/**
* Making debugging a bit easier
*/
public String toString() {
return "Ident(" + printTrimmed() + ")";
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class If implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
ControlParentheses ifCondition;
JRightPadded thenPart;
public Statement getThenPart() {
return thenPart.getElement();
}
public If withThenPart(Statement thenPart) {
return getPadding().withThenPart(this.thenPart.withElement(thenPart));
}
@With
@Nullable
@Getter
Else elsePart;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitIf(this, p);
}
@Override
public Coordinates.If getCoordinates() {
return new Coordinates.If(this);
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public static final class Else implements J {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
JRightPadded body;
public Statement getBody() {
return body.getElement();
}
public Else withBody(Statement body) {
return getPadding().withBody(this.body.withElement(body));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitElse(this, p);
}
@Override
public Coordinates.If.Else getCoordinates() {
return new Coordinates.If.Else(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Else t;
public JRightPadded getBody() {
return t.body;
}
public Else withBody(JRightPadded body) {
return t.body == body ? t : new Else(t.id, t.prefix, t.markers, body);
}
}
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final If t;
public JRightPadded getThenPart() {
return t.thenPart;
}
public If withThenPart(JRightPadded thenPart) {
return t.thenPart == thenPart ? t : new If(t.id, t.prefix, t.markers, t.ifCondition, thenPart, t.elsePart);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class Import implements J, Comparable {
@Nullable
@NonFinal
transient WeakReference padding;
@Getter
@EqualsAndHashCode.Include
UUID id;
@Getter
@With
Space prefix;
@Getter
@With
Markers markers;
JLeftPadded statik;
@With
@Getter
FieldAccess qualid;
public boolean isStatic() {
return statik.getElement();
}
public Import withStatic(boolean statik) {
return getPadding().withStatic(this.statik.withElement(statik));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitImport(this, p);
}
@Override
public Coordinates.Import getCoordinates() {
return new Coordinates.Import(this);
}
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();
}
/**
* Retrieve just the package from the import.
* e.g.:
*
* import org.foo.A; == "org.foo"
* import static org.foo.A.bar; == "org.foo"
* import org.foo.*; == "org.foo"
*
*/
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("."));
}
public String getClassName() {
String pkg = getPackageName();
return pkg.length() > 0 ? getTypeName().substring(pkg.length() + 1) : getTypeName();
}
@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());
}
/**
* Make debugging a bit easier
*/
public String toString() {
return "Import(" + ImportToString.toString(this) + ")";
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Import t;
public JLeftPadded getStatic() {
return t.statik;
}
public Import withStatic(JLeftPadded statik) {
return t.statik == statik ? t : new Import(t.id, t.prefix, t.markers, statik, t.qualid);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class InstanceOf implements J, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
JRightPadded expression;
public Expression getExpression() {
return expression.getElement();
}
public InstanceOf withExpression(Expression expression) {
return getPadding().withExpr(this.expression.withElement(expression));
}
@With
@Getter
J clazz;
@With
@Nullable
@Getter
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitInstanceOf(this, p);
}
@Override
public Coordinates.InstanceOf getCoordinates() {
return new Coordinates.InstanceOf(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final InstanceOf t;
public JRightPadded getExpr() {
return t.expression;
}
public InstanceOf withExpr(JRightPadded expression) {
return t.expression == expression ? t : new InstanceOf(t.id, t.prefix, t.markers, expression, t.clazz, t.type);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class Label implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
/**
* Right padded before the ':'
*/
JRightPadded label;
public Identifier getLabel() {
return label.getElement();
}
public Label withLabel(Identifier label) {
return getPadding().withLabel(this.label.withElement(label));
}
@With
@Getter
Statement statement;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitLabel(this, p);
}
@Override
public Coordinates.Label getCoordinates() {
return new Coordinates.Label(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Label t;
public JRightPadded getLabel() {
return t.label;
}
public Label withLabel(JRightPadded label) {
return t.label == label ? t : new Label(t.id, t.prefix, t.markers, label, t.statement);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class Lambda implements J, Expression {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
Parameters parameters;
@With
Space arrow;
@With
J body;
@With
@Nullable
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitLambda(this, p);
}
@Override
public Coordinates.Lambda getCoordinates() {
return new Coordinates.Lambda(this);
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public static final class Parameters implements J {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
boolean parenthesized;
List> parameters;
public List getParameters() {
return JRightPadded.getElements(parameters);
}
public Parameters withParameters(List parameters) {
return getPadding().withParams(JRightPadded.withElements(this.parameters, parameters));
}
@Override
public Coordinates.Lambda.Parameters getCoordinates() {
return new Coordinates.Lambda.Parameters(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final Parameters t;
public List> getParams() {
return t.parameters;
}
public Parameters withParams(List> parameters) {
return t.parameters == parameters ? t : new Parameters(t.id, t.prefix, t.markers, t.parenthesized, parameters);
}
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class Literal implements J, Expression {
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
@Nullable
Object value;
@With
String valueSource;
/**
* Including String literals
*/
JavaType.Primitive type;
@SuppressWarnings("unchecked")
@Override
public Literal withType(@Nullable JavaType type) {
if (type == this.type) {
return this;
}
if (type instanceof JavaType.Primitive) {
return new Literal(id, prefix, markers, value, valueSource, (JavaType.Primitive) type);
}
return this;
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitLiteral(this, p);
}
@Override
public Coordinates.Literal getCoordinates() {
return new Coordinates.Literal(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");
}
@Override
public String toString() {
return "Literal(" + LiteralToString.toString(this) + ")";
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class MemberReference implements J, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
Expression containing;
@Nullable
JContainer typeParameters;
@Nullable
public List getTypeParameters() {
return typeParameters == null ? null : typeParameters.getElements();
}
public MemberReference withTypeParameters(@Nullable List typeParameters) {
return getPadding().withTypeParameters(JContainer.withElementsNullable(this.typeParameters, typeParameters));
}
JLeftPadded reference;
public Identifier getReference() {
return reference.getElement();
}
public MemberReference withReference(Identifier reference) {
return getPadding().withReference(this.reference.withElement(reference));
}
/**
* In the case of a method reference, this will be the type of the functional interface that
* this method reference is supplying.
*/
@With
@Nullable
@Getter
JavaType type;
/**
* In the case of a method reference, this is the method type pointed to by {@link #reference}.
*/
@With
@Nullable
@Getter
JavaType referenceType;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitMemberReference(this, p);
}
@Override
public Coordinates.MemberReference getCoordinates() {
return new Coordinates.MemberReference(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final MemberReference t;
@Nullable
public JContainer getTypeParameters() {
return t.typeParameters;
}
public MemberReference withTypeParameters(@Nullable JContainer typeParameters) {
return t.typeParameters == typeParameters ? t : new MemberReference(t.id, t.prefix, t.markers, t.containing, typeParameters, t.reference, t.type, t.referenceType);
}
public JLeftPadded getReference() {
return t.reference;
}
public MemberReference withReference(JLeftPadded reference) {
return t.reference == reference ? t : new MemberReference(t.id, t.prefix, t.markers, t.containing, t.typeParameters, reference, t.type, t.referenceType);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class MethodDeclaration implements J, Statement {
@Nullable
@NonFinal
transient WeakReference padding;
@Nullable
@NonFinal
transient WeakReference annotations;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Getter
List leadingAnnotations;
@With
@Getter
List modifiers;
@Nullable
TypeParameters typeParameters;
@Nullable
public List getTypeParameters() {
return typeParameters == null ? null : typeParameters.getTypeParameters();
}
public MethodDeclaration withTypeParameters(@Nullable List typeParameters) {
if (typeParameters == null) {
if (this.getAnnotations().getTypeParameters() == null) {
return this;
} else {
return this.getAnnotations().withTypeParameters(null);
}
} else {
TypeParameters currentTypeParameters = this.getAnnotations().getTypeParameters();
if (currentTypeParameters == null) {
return getAnnotations().withTypeParameters(new TypeParameters(Tree.randomId(), Space.EMPTY, Markers.EMPTY,
null, typeParameters.stream().map(JRightPadded::build).collect(toList())));
} else {
return getAnnotations().withTypeParameters(currentTypeParameters.withTypeParameters(typeParameters));
}
}
}
/**
* Null for constructor declarations.
*/
@With
@Getter
@Nullable
TypeTree returnTypeExpression;
IdentifierWithAnnotations name;
public Identifier getName() {
return name.getIdentifier();
}
public MethodDeclaration withName(Identifier name) {
return getAnnotations().withName(this.name.withIdentifier(name));
}
JContainer parameters;
public List getParameters() {
return parameters.getElements();
}
public MethodDeclaration withParameters(List parameters) {
return getPadding().withParameters(JContainer.withElements(this.parameters, parameters));
}
@Nullable
JContainer throwz;
@Nullable
public List getThrows() {
return throwz == null ? null : throwz.getElements();
}
public MethodDeclaration withThrows(@Nullable List throwz) {
return getPadding().withThrows(JContainer.withElementsNullable(this.throwz, throwz));
}
/**
* Null for abstract method declarations and interface method declarations.
*/
@With
@Getter
@Nullable
Block body;
/**
* For default values on definitions of annotation parameters.
*/
@Nullable
JLeftPadded defaultValue;
@Nullable
public Expression getDefaultValue() {
return defaultValue == null ? null : defaultValue.getElement();
}
public MethodDeclaration withDefaultValue(@Nullable Expression defaultValue) {
return getPadding().withDefaultValue(JLeftPadded.withElement(this.defaultValue, defaultValue));
}
@With
@Getter
@Nullable
JavaType.Method type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitMethodDeclaration(this, p);
}
public boolean isAbstract() {
return body == null;
}
public boolean isConstructor() {
return getReturnTypeExpression() == null;
}
public String getSimpleName() {
return name.getIdentifier().getSimpleName();
}
public boolean hasModifier(Modifier.Type modifier) {
return Modifier.hasModifier(getModifiers(), modifier);
}
@Override
public String toString() {
return "MethodDeclaration(" + MethodDeclarationToString.toString(this) + ")";
}
@Override
public Coordinates.MethodDeclaration getCoordinates() {
return new Coordinates.MethodDeclaration(this);
}
// gather annotations from everywhere they may occur
public List getAllAnnotations() {
List allAnnotations = new ArrayList<>(leadingAnnotations);
for (J.Modifier modifier : modifiers) {
allAnnotations.addAll(modifier.getAnnotations());
}
if (typeParameters != null) {
allAnnotations.addAll(typeParameters.getAnnotations());
}
if (returnTypeExpression instanceof AnnotatedType) {
allAnnotations.addAll(((AnnotatedType) returnTypeExpression).getAnnotations());
}
allAnnotations.addAll(name.getAnnotations());
return allAnnotations;
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
public static final class IdentifierWithAnnotations {
@Getter
@With
Identifier identifier;
@Getter
List annotations;
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final MethodDeclaration t;
public JContainer getParameters() {
return t.parameters;
}
public MethodDeclaration withParameters(JContainer parameters) {
return t.parameters == parameters ? t : new MethodDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.typeParameters, t.returnTypeExpression, t.name, parameters, t.throwz, t.body, t.defaultValue, t.type);
}
@Nullable
public JContainer getThrows() {
return t.throwz;
}
public MethodDeclaration withThrows(@Nullable JContainer throwz) {
return t.throwz == throwz ? t : new MethodDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.typeParameters, t.returnTypeExpression, t.name, t.parameters, throwz, t.body, t.defaultValue, t.type);
}
@Nullable
public JLeftPadded getDefaultValue() {
return t.defaultValue;
}
public MethodDeclaration withDefaultValue(@Nullable JLeftPadded defaultValue) {
return t.defaultValue == defaultValue ? t : new MethodDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.typeParameters, t.returnTypeExpression, t.name, t.parameters, t.throwz, t.body, defaultValue, t.type);
}
}
public Annotations getAnnotations() {
Annotations a;
if (this.annotations == null) {
a = new Annotations(this);
this.annotations = new WeakReference<>(a);
} else {
a = this.annotations.get();
if (a == null || a.t != this) {
a = new Annotations(this);
this.annotations = new WeakReference<>(a);
}
}
return a;
}
@RequiredArgsConstructor
public static class Annotations {
private final MethodDeclaration t;
@Nullable
public TypeParameters getTypeParameters() {
return t.typeParameters;
}
public MethodDeclaration withTypeParameters(@Nullable TypeParameters typeParameters) {
return t.typeParameters == typeParameters ? t : new MethodDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, typeParameters, t.returnTypeExpression, t.name, t.parameters, t.throwz, t.body, t.defaultValue, t.type);
}
public IdentifierWithAnnotations getName() {
return t.name;
}
public MethodDeclaration withName(IdentifierWithAnnotations name) {
return t.name == name ? t : new MethodDeclaration(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.typeParameters, t.returnTypeExpression, name, t.parameters, t.throwz, t.body, t.defaultValue, t.type);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class MethodInvocation implements J, Statement, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
/**
* Right padded before the '.'
*/
@Nullable
JRightPadded select;
@Nullable
public Expression getSelect() {
return select == null ? null : select.getElement();
}
public MethodInvocation withSelect(@Nullable Expression select) {
return getPadding().withSelect(JRightPadded.withElement(this.select, select));
}
@Nullable
JContainer typeParameters;
@Nullable
public List getTypeParameters() {
return typeParameters == null ? null : typeParameters.getElements();
}
@With
@Getter
Identifier name;
JContainer arguments;
public List getArguments() {
return arguments.getElements();
}
public MethodInvocation withArguments(List arguments) {
return getPadding().withArguments(JContainer.withElements(this.arguments, arguments));
}
@Nullable
@Getter
JavaType.Method type;
@SuppressWarnings("unchecked")
@Override
public MethodInvocation withType(@Nullable JavaType type) {
if (type == this.type) {
return this;
}
if (type instanceof JavaType.Method) {
return new MethodInvocation(id, prefix, markers, select, typeParameters, name, arguments, (JavaType.Method) type);
}
return this;
}
public MethodInvocation withDeclaringType(JavaType.FullyQualified type) {
if (this.type == null) {
return this;
} else {
return withType(this.type.withDeclaringType(type));
}
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitMethodInvocation(this, p);
}
@Override
public Coordinates.MethodInvocation getCoordinates() {
return new Coordinates.MethodInvocation(this);
}
@Nullable
public JavaType getReturnType() {
return type == null ? null : type.getResolvedSignature() == null ? null :
type.getResolvedSignature().getReturnType();
}
public String getSimpleName() {
return name.getSimpleName();
}
@Override
public List getSideEffects() {
return singletonList(this);
}
@Override
public String toString() {
return "MethodInvocation(" + MethodInvocationToString.toString(this) + ")";
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final MethodInvocation t;
@Nullable
public JRightPadded getSelect() {
return t.select;
}
public MethodInvocation withSelect(@Nullable JRightPadded select) {
return t.select == select ? t : new MethodInvocation(t.id, t.prefix, t.markers, select, t.typeParameters, t.name, t.arguments, t.type);
}
@Nullable
public JContainer getTypeParameters() {
return t.typeParameters;
}
public MethodInvocation withTypeParameters(@Nullable JContainer typeParameters) {
return t.typeParameters == typeParameters ? t : new MethodInvocation(t.id, t.prefix, t.markers, t.select, typeParameters, t.name, t.arguments, t.type);
}
public JContainer getArguments() {
return t.arguments;
}
public MethodInvocation withArguments(JContainer arguments) {
return t.arguments == arguments ? t : new MethodInvocation(t.id, t.prefix, t.markers, t.select, t.typeParameters, t.name, arguments, t.type);
}
}
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@Data
final class Modifier implements J {
public static boolean hasModifier(Collection modifiers, Modifier.Type modifier) {
return modifiers.stream().anyMatch(m -> m.getType() == modifier);
}
@EqualsAndHashCode.Include
UUID id;
@With
Space prefix;
@With
Markers markers;
@With
Type type;
@With
@Getter
List annotations;
public enum Type {
Default,
Public,
Protected,
Private,
Abstract,
Static,
Final,
Native,
Strictfp,
Synchronized,
Transient,
Volatile,
}
@Override
public Coordinates.Modifier getCoordinates() {
return new Coordinates.Modifier(this);
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class MultiCatch implements J, TypeTree {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
List> alternatives;
public List getAlternatives() {
return JRightPadded.getElements(alternatives);
}
public MultiCatch withAlternatives(List alternatives) {
return getPadding().withAlternatives(JRightPadded.withElements(this.alternatives, alternatives));
}
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitMultiCatch(this, p);
}
@Override
public Coordinates.MultiCatch getCoordinates() {
return new Coordinates.MultiCatch(this);
}
@SuppressWarnings("unchecked")
@Override
public MultiCatch withType(@Nullable JavaType type) {
// cannot overwrite type directly, perform this operation on each alternative separately
return this;
}
@Override
public JavaType getType() {
return new JavaType.MultiCatch(alternatives.stream()
.filter(Objects::nonNull)
.map(alt -> alt.getElement().getType())
.collect(toList()));
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final MultiCatch t;
public List> getAlternatives() {
return t.alternatives;
}
public MultiCatch withAlternatives(List> alternatives) {
return t.alternatives == alternatives ? t : new MultiCatch(t.id, t.prefix, t.markers, alternatives);
}
}
}
@ToString
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
final class NewArray implements J, Expression {
@Nullable
@NonFinal
transient WeakReference padding;
@EqualsAndHashCode.Include
@Getter
UUID id;
@With
@Getter
Space prefix;
@With
@Getter
Markers markers;
@With
@Nullable
@Getter
TypeTree typeExpression;
@With
@Getter
List dimensions;
@Nullable
JContainer initializer;
@Nullable
public List getInitializer() {
return initializer == null ? null : initializer.getElements();
}
@With
@Nullable
@Getter
JavaType type;
@Override
public J acceptJava(JavaVisitor
v, P p) {
return v.visitNewArray(this, p);
}
@Override
public Coordinates.NewArray getCoordinates() {
return new Coordinates.NewArray(this);
}
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
} else {
p = this.padding.get();
if (p == null || p.t != this) {
p = new Padding(this);
this.padding = new WeakReference<>(p);
}
}
return p;
}
@RequiredArgsConstructor
public static class Padding {
private final NewArray t;
@Nullable
public JContainer getInitializer() {
return t.initializer;
}
public NewArray withInitializer(@Nullable JContainer