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

main.org.openrewrite.kotlin.tree.K Maven / Gradle / Ivy

There is a newer version: 1.22.1
Show newest version
/*
 * Copyright 2022 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.kotlin.tree; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.*; import lombok.experimental.FieldDefaults; import lombok.experimental.NonFinal; import org.jspecify.annotations.Nullable; import org.openrewrite.*; import org.openrewrite.internal.ListUtils; import org.openrewrite.java.JavaPrinter; import org.openrewrite.java.JavaTypeVisitor; import org.openrewrite.java.internal.TypesInUse; import org.openrewrite.java.service.AutoFormatService; import org.openrewrite.java.service.ImportService; import org.openrewrite.java.tree.*; import org.openrewrite.kotlin.KotlinVisitor; import org.openrewrite.kotlin.internal.KotlinPrinter; import org.openrewrite.kotlin.service.KotlinAutoFormatService; import org.openrewrite.kotlin.service.KotlinImportService; import org.openrewrite.marker.Markers; import java.beans.Transient; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.stream.Collectors; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; public interface K extends J { @SuppressWarnings("unchecked") @Override default R accept(TreeVisitor v, P p) { return (R) acceptKotlin(v.adapt(KotlinVisitor.class), p); } @Override default

boolean isAcceptable(TreeVisitor v, P p) { return v.isAdaptableTo(KotlinVisitor.class); } default

@Nullable J acceptKotlin(KotlinVisitor

v, P p) { return v.defaultValue(this, p); } @Override Space getPrefix(); @Override default List getComments() { return getPrefix().getComments(); } @SuppressWarnings({"DataFlowIssue", "DuplicatedCode"}) @ToString @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class CompilationUnit implements K, JavaSourceFile, SourceFile { @Nullable @NonFinal transient SoftReference typesInUse; @Nullable @NonFinal transient WeakReference padding; @EqualsAndHashCode.Include @With @Getter UUID id; @With @Getter @Nullable String shebang; @With @Getter Space prefix; @With @Getter Markers markers; @With @Getter Path sourcePath; @With @Getter @Nullable FileAttributes fileAttributes; @Nullable // for backwards compatibility @With(AccessLevel.PRIVATE) String charsetName; @With @Getter boolean charsetBomMarked; @With @Getter @Nullable Checksum checksum; @Transient @Override public long getWeight(Predicate uniqueIdentity) { AtomicInteger n = new AtomicInteger(); new KotlinVisitor() { final JavaTypeVisitor typeVisitor = new JavaTypeVisitor() { @Override public JavaType visit(@Nullable JavaType javaType, AtomicInteger n) { if (javaType != null && uniqueIdentity.test(javaType)) { n.incrementAndGet(); return super.visit(javaType, n); } //noinspection ConstantConditions return javaType; } }; @Override public @Nullable J visit(@Nullable Tree tree, AtomicInteger n) { if (tree != null) { n.incrementAndGet(); } return super.visit(tree, n); } @Override public JavaType visitType(@Nullable JavaType javaType, AtomicInteger n) { return typeVisitor.visit(javaType, n); } @Override public Markers visitMarkers(@Nullable Markers markers, AtomicInteger n) { if (markers != null) { n.addAndGet(markers.getMarkers().size()); } return markers; } }.visit(this, n); return n.get(); } @Override public Charset getCharset() { return charsetName == null ? StandardCharsets.UTF_8 : Charset.forName(charsetName); } @SuppressWarnings("unchecked") @Override public SourceFile withCharset(Charset charset) { return withCharsetName(charset.name()); } @With @Getter List annotations; @Nullable JRightPadded packageDeclaration; @Override public @Nullable Package getPackageDeclaration() { return packageDeclaration == null ? null : packageDeclaration.getElement(); } @Override public K.CompilationUnit withPackageDeclaration(Package packageDeclaration) { return getPadding().withPackageDeclaration(JRightPadded.withElement(this.packageDeclaration, packageDeclaration)); } List> imports; @Override public List getImports() { return JRightPadded.getElements(imports); } @Override public K.CompilationUnit withImports(List imports) { return getPadding().withImports(JRightPadded.withElements(this.imports, imports)); } List> statements; public List getStatements() { return JRightPadded.getElements(statements); } public K.CompilationUnit withStatements(List statements) { return getPadding().withStatements(JRightPadded.withElements(this.statements, statements)); } @With @Getter Space eof; @Override @Transient public List getClasses() { return statements.stream() .map(JRightPadded::getElement) .filter(J.ClassDeclaration.class::isInstance) .map(J.ClassDeclaration.class::cast) .collect(Collectors.toList()); } /** * K.CompilationUnits may contain K.ClassDeclarations, which isn't supported through withClasses. * Please use withStatements to update the statements of this compilation unit. */ @Deprecated @Override public K.CompilationUnit withClasses(List classes) { return getPadding().withClasses(JRightPadded.withElements(this.getPadding().getClasses(), classes)); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitCompilationUnit(this, p); } @Override public

TreeVisitor> printer(Cursor cursor) { return new KotlinPrinter<>(); } @Override @Transient public TypesInUse getTypesInUse() { TypesInUse cache; if (this.typesInUse == null) { cache = TypesInUse.build(this); this.typesInUse = new SoftReference<>(cache); } else { cache = this.typesInUse.get(); if (cache == null || cache.getCu() != this) { cache = TypesInUse.build(this); this.typesInUse = new SoftReference<>(cache); } } return cache; } @Override 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 implements JavaSourceFile.Padding { private final K.CompilationUnit t; public @Nullable JRightPadded getPackageDeclaration() { return t.packageDeclaration; } public K.CompilationUnit withPackageDeclaration(@Nullable JRightPadded packageDeclaration) { return t.packageDeclaration == packageDeclaration ? t : new K.CompilationUnit(t.id, t.shebang, t.prefix, t.markers, t.sourcePath, t.fileAttributes, t.charsetName, t.charsetBomMarked, null, t.annotations, packageDeclaration, t.imports, t.statements, t.eof); } @Transient public List> getClasses() { //noinspection unchecked return t.statements.stream() .filter(s -> s.getElement() instanceof J.ClassDeclaration) .map(s -> (JRightPadded) (Object) s) .collect(Collectors.toList()); } public K.CompilationUnit withClasses(List> classes) { List> statements = t.statements.stream() .filter(s -> !(s.getElement() instanceof J.ClassDeclaration)) .collect(Collectors.toList()); //noinspection unchecked statements.addAll(0, classes.stream() .map(i -> (JRightPadded) (Object) i) .collect(Collectors.toList())); return t.getPadding().getClasses() == classes ? t : new K.CompilationUnit(t.id, t.shebang, t.prefix, t.markers, t.sourcePath, t.fileAttributes, t.charsetName, t.charsetBomMarked, t.checksum, t.annotations, t.packageDeclaration, t.imports, statements, t.eof); } @Override public List> getImports() { return t.imports; } @Override public K.CompilationUnit withImports(List> imports) { return t.imports == imports ? t : new K.CompilationUnit(t.id, t.shebang, t.prefix, t.markers, t.sourcePath, t.fileAttributes, t.charsetName, t.charsetBomMarked, null, t.annotations, t.packageDeclaration, imports, t.statements, t.eof); } public List> getStatements() { return t.statements; } public K.CompilationUnit withStatements(List> statements) { return t.statements == statements ? t : new K.CompilationUnit(t.id, t.shebang, t.prefix, t.markers, t.sourcePath, t.fileAttributes, t.charsetName, t.charsetBomMarked, t.checksum, t.annotations, t.packageDeclaration, t.imports, statements, t.eof); } } @Override @SuppressWarnings("unchecked") public T service(Class service) { String serviceName = service.getName(); try { Class serviceClass; if (KotlinImportService.class.getName().equals(serviceName)) { serviceClass = service; } else if (ImportService.class.getName().equals(serviceName)) { serviceClass = (Class) service.getClassLoader().loadClass(KotlinImportService.class.getName()); } else if (KotlinAutoFormatService.class.getName().equals(serviceName)) { serviceClass = service; } else if (AutoFormatService.class.getName().equals(serviceName)) { serviceClass = (Class) service.getClassLoader().loadClass(KotlinAutoFormatService.class.getName()); } else { return JavaSourceFile.super.service(service); } return (T) serviceClass.getConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } } /** * In Kotlin all expressions can be annotated with annotations with the corresponding annotation target. */ @Getter @SuppressWarnings("unchecked") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @With final class AnnotatedExpression implements K, Expression { @EqualsAndHashCode.Include UUID id; Markers markers; List annotations; Expression expression; @Override public Space getPrefix() { return annotations.isEmpty() ? expression.getPrefix() : annotations.get(0).getPrefix(); } @Override public J2 withPrefix(Space space) { return (J2) (annotations.isEmpty() ? withExpression(expression.withPrefix(space)) : withAnnotations(ListUtils.mapFirst(annotations, a -> a.withPrefix(space)))); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitAnnotatedExpression(this, p); } @Override public @Nullable JavaType getType() { return expression.getType(); } @Override public T withType(@Nullable JavaType type) { // type must be changed on expression return (T) this; } @Transient @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class AnnotationType implements K, NameTree { @Nullable @NonFinal transient WeakReference padding; @Getter @With @EqualsAndHashCode.Include UUID id; @Getter @With Space prefix; @Getter @With Markers markers; JRightPadded useSite; @Getter @With J.Annotation callee; public Expression getUseSite() { return useSite.getElement(); } @Override public @Nullable JavaType getType() { return callee.getType(); } @Override public T withType(@Nullable JavaType type) { //noinspection unchecked return (T) withCallee(callee.withType(type)); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitAnnotationType(this, p); } public K.AnnotationType.Padding getPadding() { K.AnnotationType.Padding p; if (this.padding == null) { p = new K.AnnotationType.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new K.AnnotationType.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @RequiredArgsConstructor public static class Padding { private final K.AnnotationType t; public JRightPadded getUseSite() { return t.useSite; } public K.AnnotationType withUseSite(JRightPadded useSite) { return t.useSite == useSite ? t : new K.AnnotationType(t.id, t.prefix, t.markers, useSite, t.callee ); } } } @SuppressWarnings("unused") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) @Data final class Binary implements K, Expression, TypedTree { @Nullable @NonFinal transient WeakReference padding; @With @EqualsAndHashCode.Include UUID id; @With Space prefix; @With Markers markers; @With Expression left; JLeftPadded operator; public K.Binary.Type getOperator() { return operator.getElement(); } public K.Binary withOperator(K.Binary.Type operator) { return getPadding().withOperator(this.operator.withElement(operator)); } @With Expression right; @With Space after; @With @Nullable JavaType type; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitBinary(this, p); } @Transient @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } public enum Type { Contains, Elvis, NotContains, @Deprecated // kept for backwards compatibility Get, IdentityEquals, IdentityNotEquals, RangeTo, RangeUntil } public K.Binary.Padding getPadding() { K.Binary.Padding p; if (this.padding == null) { p = new K.Binary.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new K.Binary.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @RequiredArgsConstructor public static class Padding { private final K.Binary t; public JLeftPadded getOperator() { return t.operator; } public K.Binary withOperator(JLeftPadded operator) { return t.operator == operator ? t : new K.Binary(t.id, t.prefix, t.markers, t.left, operator, t.right, t.after, t.type); } } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @SuppressWarnings({"unused", "unchecked"}) @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data @With final class ClassDeclaration implements K, Statement, TypedTree { @EqualsAndHashCode.Include UUID id; Markers markers; J.ClassDeclaration classDeclaration; TypeConstraints typeConstraints; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitClassDeclaration(this, p); } @Override public J2 withPrefix(Space space) { return (J2) withClassDeclaration(classDeclaration.withPrefix(space)); } @Override public Space getPrefix() { return classDeclaration.getPrefix(); } @Transient @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } @Override public @Nullable JavaType getType() { return classDeclaration.getType(); } @Override public T withType(@Nullable JavaType type) { return (T) withClassDeclaration(classDeclaration.withType(type)); } } @SuppressWarnings({"unused", "unchecked"}) @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) @Data final class Constructor implements K, Statement, TypedTree { @Nullable @NonFinal transient WeakReference padding; @EqualsAndHashCode.Include @With UUID id; @With Markers markers; @With J.MethodDeclaration methodDeclaration; // A replacement of `colon` and `constructorInvocation` JLeftPadded invocation; public ConstructorInvocation getInvocation() { return invocation.getElement(); } public K.Constructor withInvocation(ConstructorInvocation invocation) { return getPadding().withInvocation(this.invocation.withElement(invocation)); } // For backward compatibility, handle removed fields `colon` and `constructorInvocation` which has been relocated to `invocation` // Todo, Remove when we feel good that kotlin LSTs have been rebuilt. @Deprecated @JsonCreator public Constructor(UUID id, Markers markers, J.MethodDeclaration methodDeclaration, @Nullable @JsonProperty("colon") Space colon, @Nullable @JsonProperty("constructorInvocation") ConstructorInvocation constructorInvocation, JLeftPadded invocation ) { padding = null; this.id = id; this.markers = markers; this.methodDeclaration = methodDeclaration; if (colon != null && constructorInvocation != null) { this.invocation = new JLeftPadded<>(colon, constructorInvocation, Markers.EMPTY); } else { this.invocation = invocation; } } @Override public Constructor withType(@Nullable JavaType type) { return this; // type must be changed on method declaration } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitConstructor(this, p); } @Override public J2 withPrefix(Space space) { return (J2) withMethodDeclaration(methodDeclaration.withPrefix(space)); } @Override public Space getPrefix() { return methodDeclaration.getPrefix(); } @Override public @Nullable JavaType getType() { return methodDeclaration.getType(); } @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } public K.Constructor.Padding getPadding() { K.Constructor.Padding p; if (this.padding == null) { p = new K.Constructor.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new K.Constructor.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @RequiredArgsConstructor public static class Padding { private final K.Constructor t; public JLeftPadded getInvocation() { return t.invocation; } public K.Constructor withInvocation(JLeftPadded invocation) { return t.invocation == invocation ? t : new K.Constructor(t.id, t.markers, t.methodDeclaration, invocation); } } } @SuppressWarnings({"unused", "unchecked"}) @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class ConstructorInvocation implements K, TypeTree { @Nullable @NonFinal transient WeakReference padding; @Getter @With @EqualsAndHashCode.Include UUID id; @Getter @With Space prefix; @Getter @With Markers markers; @Getter @With TypeTree typeTree; JContainer arguments; public List getArguments() { return arguments.getElements(); } public ConstructorInvocation withArguments(List arguments) { return getPadding().withArguments(JContainer.withElements(this.arguments, arguments)); } @Override public ConstructorInvocation withType(@Nullable JavaType type) { return withTypeTree(typeTree.withType(type)); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitConstructorInvocation(this, p); } public ConstructorInvocation.Padding getPadding() { ConstructorInvocation.Padding p; if (this.padding == null) { p = new ConstructorInvocation.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new ConstructorInvocation.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @Override public @Nullable JavaType getType() { return typeTree.getType(); } @RequiredArgsConstructor public static class Padding { private final ConstructorInvocation t; public JContainer getArguments() { return t.arguments; } public ConstructorInvocation withArguments(JContainer arguments) { return t.arguments == arguments ? t : new ConstructorInvocation(t.id, t.prefix, t.markers, t.typeTree, arguments); } } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @SuppressWarnings({"unused", "unchecked"}) @Getter @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @With final class DelegatedSuperType implements K, TypeTree { @EqualsAndHashCode.Include UUID id; Markers markers; TypeTree typeTree; Space by; Expression delegate; @Override public DelegatedSuperType withType(@Nullable JavaType type) { return withTypeTree(typeTree.withType(type)); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitDelegatedSuperType(this, p); } @Override public J2 withPrefix(Space space) { return (J2) withTypeTree(typeTree.withPrefix(space)); } @Override public Space getPrefix() { return typeTree.getPrefix(); } @Override public @Nullable JavaType getType() { return typeTree.getType(); } @Override public String toString() { return withBy(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @SuppressWarnings("unused") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class DestructuringDeclaration implements K, Statement { @Nullable @NonFinal transient WeakReference padding; @Getter @With @EqualsAndHashCode.Include UUID id; @Getter @With Space prefix; @Getter @With Markers markers; @Getter @With J.VariableDeclarations initializer; @Deprecated // Use destructAssignments instead @Nullable JContainer assignments; JContainer destructAssignments; @Deprecated public @Nullable List getAssignments() { return assignments != null ? assignments.getElements() : null; } public List getDestructAssignments() { return destructAssignments.getElements(); } @Deprecated public K.DestructuringDeclaration withAssignments(List assignments) { return getPadding().withAssignments(requireNonNull(JContainer.withElementsNullable(this.assignments, assignments))); } public K.DestructuringDeclaration withDestructAssignments(List assignments) { return getPadding().withDestructAssignments(requireNonNull(JContainer.withElementsNullable(this.destructAssignments, assignments))); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitDestructuringDeclaration(this, p); } @Override @Transient public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } public K.DestructuringDeclaration.Padding getPadding() { K.DestructuringDeclaration.Padding p; if (this.padding == null) { p = new K.DestructuringDeclaration.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new K.DestructuringDeclaration.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @RequiredArgsConstructor public static class Padding { private final K.DestructuringDeclaration t; @Deprecated public @Nullable JContainer getAssignments() { return t.assignments; } @Deprecated public DestructuringDeclaration withAssignments(JContainer assignments) { return t; } public JContainer getDestructAssignments() { return t.destructAssignments; } public DestructuringDeclaration withDestructAssignments(JContainer assignments) { return t.destructAssignments == assignments ? t : new DestructuringDeclaration(t.id, t.prefix, t.markers, t.initializer, null, assignments); } } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @Getter @SuppressWarnings("unchecked") @ToString @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @With final class ExpressionStatement implements K, Expression, Statement { @EqualsAndHashCode.Include UUID id; Expression expression; // For backwards compatibility with older ASTs before there was an id field @SuppressWarnings("unused") public ExpressionStatement(Expression expression) { this.id = Tree.randomId(); this.expression = expression; } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { J j = v.visit(getExpression(), p); if (j instanceof ExpressionStatement) { return j; } else if (j instanceof Expression) { return withExpression((Expression) j); } return j; } @Override public J2 withPrefix(Space space) { return (J2) withExpression(expression.withPrefix(space)); } @Override public Space getPrefix() { return expression.getPrefix(); } @Override public J2 withMarkers(Markers markers) { return (J2) withExpression(expression.withMarkers(markers)); } @Override public Markers getMarkers() { return expression.getMarkers(); } @Override public @Nullable JavaType getType() { return expression.getType(); } @Override public T withType(@Nullable JavaType type) { ExpressionStatement newExpression = withExpression(expression.withType(type)); return (T) (newExpression == expression ? this : newExpression); } @Transient @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } } @SuppressWarnings({"unused", "EqualsBetweenInconvertibleTypes", "DuplicatedCode"}) @ToString @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class FunctionType implements K, TypeTree, Expression { @Nullable @NonFinal transient WeakReference padding; @With @EqualsAndHashCode.Include @Getter UUID id; @With Space prefix; @Override public Space getPrefix() { //noinspection ConstantConditions return prefix == null ? returnType.getElement().getPrefix() : prefix; } @With Markers markers; @Override public Markers getMarkers() { // For backwards compatibility with older LST before there was a prefix field //noinspection ConstantConditions return markers == null ? returnType.getMarkers() : markers; } @With List leadingAnnotations; public List getLeadingAnnotations() { // for backwards compatibility with older LST before there was a leading annotations field //noinspection ConstantConditions return leadingAnnotations == null ? Collections.emptyList() : leadingAnnotations; } @With List modifiers; public List getModifiers() { // for backwards compatibility with older LST before there was a modifiers field //noinspection ConstantConditions return modifiers == null ? Collections.emptyList() : modifiers; } @Nullable @With @Getter JRightPadded receiver; @Nullable JContainer parameters; public List getParameters() { return parameters != null ? parameters.getElements() : emptyList(); } public FunctionType withParameters(List parameters) { return getPadding().withParameters(JContainer.withElementsNullable(this.parameters, parameters)); } @Nullable // nullable for LST backwards compatibility reasons only @With @Getter Space arrow; @With @Getter JRightPadded returnType; @Override public @Nullable JavaType getType() { // for backwards compatibility with older LST before there was a returnType field //noinspection ConstantValue return returnType != null && returnType.getElement() != null ? returnType.getElement().getType() : null; } @Override public T withType(@Nullable JavaType type) { TypeTree newType = returnType.getElement().withType(type); //noinspection unchecked return (T) (newType == type ? this : withReturnType(returnType.withElement(newType))); } @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitFunctionType(this, p); } @SuppressWarnings("unchecked") @ToString @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Getter @RequiredArgsConstructor @With public static final class Parameter implements K, TypeTree { @EqualsAndHashCode.Include UUID id; Markers markers; @Nullable Identifier name; TypeTree parameterType; @Override public Space getPrefix() { return name != null ? name.getPrefix() : parameterType.getPrefix(); } @Override public J2 withPrefix(Space space) { //noinspection unchecked return (J2) (name != null ? withName(name.withPrefix(space)) : withType(parameterType.withPrefix(space))); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitFunctionTypeParameter(this, p); } @Override public JavaType getType() { return parameterType.getType(); } @Override public T withType(@Nullable JavaType type) { return (T) new Parameter(id, markers, name, this.parameterType.withType(type)); } } 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 FunctionType t; public @Nullable JContainer getParameters() { return t.parameters; } public FunctionType withParameters(@Nullable JContainer parameters) { return t.parameters == parameters ? t : new FunctionType(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.receiver, parameters, t.arrow, t.returnType); } } } @SuppressWarnings("unused") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class ListLiteral implements K, Expression, TypedTree { @Nullable @NonFinal transient WeakReference padding; @Getter @With @EqualsAndHashCode.Include UUID id; @Getter @With Space prefix; @Getter @With Markers markers; JContainer elements; public List getElements() { return elements.getElements(); } public ListLiteral withElements(List elements) { return getPadding().withElements(JContainer.withElements(this.elements, elements)); } @Getter @With @Nullable JavaType type; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitListLiteral(this, p); } @Transient @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } public Padding getPadding() { ListLiteral.Padding p; if (this.padding == null) { p = new ListLiteral.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new ListLiteral.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @RequiredArgsConstructor public static class Padding { private final ListLiteral t; public JContainer getElements() { return t.elements; } public ListLiteral withElements(JContainer elements) { return t.elements == elements ? t : new ListLiteral(t.id, t.prefix, t.markers, elements, t.type); } } } @SuppressWarnings({"unused", "unchecked"}) @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data @With final class MethodDeclaration implements K, Statement, TypedTree { @EqualsAndHashCode.Include UUID id; Markers markers; J.MethodDeclaration methodDeclaration; TypeConstraints typeConstraints; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitMethodDeclaration(this, p); } @Override public J2 withPrefix(Space space) { return (J2) withMethodDeclaration(methodDeclaration.withPrefix(space)); } @Override public Space getPrefix() { return methodDeclaration.getPrefix(); } @Transient @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } @Override public @Nullable JavaType getType() { return methodDeclaration.getType(); } @Override public T withType(@Nullable JavaType type) { return (T) withMethodDeclaration(methodDeclaration.withType(type)); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class MultiAnnotationType implements K, NameTree { @Nullable @NonFinal transient WeakReference padding; @Getter @With @EqualsAndHashCode.Include UUID id; @Getter @With Space prefix; @Getter @With Markers markers; JRightPadded useSite; @Getter @With JContainer annotations; public Expression getUseSite() { return useSite.getElement(); } @Override public @Nullable JavaType getType() { // use site has no type return null; } @Override public T withType(@Nullable JavaType type) { return (T) this; } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitMultiAnnotationType(this, p); } public K.MultiAnnotationType.Padding getPadding() { K.MultiAnnotationType.Padding p; if (this.padding == null) { p = new K.MultiAnnotationType.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new K.MultiAnnotationType.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @RequiredArgsConstructor public static class Padding { private final K.MultiAnnotationType t; public JRightPadded getUseSite() { return t.useSite; } public K.MultiAnnotationType withUseSite(JRightPadded useSite) { return t.useSite == useSite ? t : new K.MultiAnnotationType(t.id, t.prefix, t.markers, useSite, t.annotations ); } } } @Value @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @With class NamedVariableInitializer implements K, Expression { @EqualsAndHashCode.Include UUID id; Space prefix; Markers markers; List initializations; @Override public @Nullable JavaType getType() { return null; } @Override public T withType(@Nullable JavaType type) { throw new UnsupportedOperationException("NamedVariableInitializer cannot have a type"); } @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitNamedVariableInitializer(this, p); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) @With @Data final class Property implements K, Statement { @Nullable @NonFinal transient WeakReference padding; @EqualsAndHashCode.Include UUID id; Space prefix; Markers markers; @Nullable JContainer typeParameters; public @Nullable List getTypeParameters() { return typeParameters == null ? null : typeParameters.getElements(); } JRightPadded paddedVariableDeclarations; @Nullable TypeConstraints typeConstraints; // A replacement of `getter`,`setter` and `isSetterFirst` JContainer accessors; @Nullable JRightPadded receiver; // For backward compatibility, handle removed fields `getter`, 'setter' and `isSetterFirst` which has been relocated to `accessors` // Todo, Remove when all kotlin LSTs have been rebuilt. @Deprecated @JsonCreator public Property(UUID id, Space prefix, Markers markers, JContainer typeParameters, @Nullable JRightPadded paddedVariableDeclarations, @Nullable VariableDeclarations variableDeclarations, K.@Nullable TypeConstraints typeConstraints, @JsonProperty("getter") J.@Nullable MethodDeclaration getter, @JsonProperty("setter") J.@Nullable MethodDeclaration setter, @Nullable @JsonProperty("isSetterFirst") Boolean isSetterFirst, JContainer accessors, @Nullable JRightPadded receiver ) { this.id = id; this.prefix = prefix; this.markers = markers; this.typeParameters = typeParameters; if (variableDeclarations != null) { // from old LST this.paddedVariableDeclarations = new JRightPadded<>(variableDeclarations, Space.EMPTY, Markers.EMPTY); } else { this.paddedVariableDeclarations = requireNonNull(paddedVariableDeclarations); } this.typeConstraints = typeConstraints; if (getter != null || setter != null || isSetterFirst != null) { List> rps = new ArrayList<>(2); // handle old LST removed fields `getter`, 'setter' and `isSetterFirst` which has been relocated to `accessors` if (setter != null) { rps.add(new JRightPadded<>(setter, Space.EMPTY, Markers.EMPTY)); } if (getter != null) { rps.add(new JRightPadded<>(getter, Space.EMPTY, Markers.EMPTY)); } if (Boolean.FALSE.equals(isSetterFirst)) { Collections.reverse(rps); } this.accessors = JContainer.build(rps); } else { this.accessors = accessors; } this.receiver = receiver; } public J.VariableDeclarations getVariableDeclarations() { return paddedVariableDeclarations.getElement(); } public @Nullable Expression getReceiver() { return receiver == null ? null : receiver.getElement(); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitProperty(this, p); } @Override @Transient public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } public Property.Padding getPadding() { Property.Padding p; if (this.padding == null) { p = new Property.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new Property.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } @SuppressWarnings("unused") @RequiredArgsConstructor public static class Padding { private final Property t; public JRightPadded getVariableDeclarations() { return t.paddedVariableDeclarations; } public Property withVariableDeclarations(JRightPadded variableDeclarations) { return t.paddedVariableDeclarations == variableDeclarations ? t : new Property(t.id, t.prefix, t.markers, t.typeParameters, variableDeclarations, t.typeConstraints, t.accessors, t.receiver); } public @Nullable JContainer getTypeParameters() { return t.typeParameters; } public Property withTypeParameters(@Nullable JContainer typeParameters) { return t.typeParameters == typeParameters ? t : new Property(t.id, t.prefix, t.markers, typeParameters, t.paddedVariableDeclarations, t.typeConstraints, t.accessors, t.receiver); } public @Nullable JRightPadded getReceiver() { return t.receiver; } public @Nullable Property withReceiver(@Nullable JRightPadded receiver) { return t.receiver == receiver ? t : new Property(t.id, t.prefix, t.markers, t.typeParameters, t.paddedVariableDeclarations, t.typeConstraints, t.accessors, receiver); } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @AllArgsConstructor(access = AccessLevel.PRIVATE) @Data @With final class Return implements K, Statement, Expression { @EqualsAndHashCode.Include UUID id; /** * @deprecated Wrap with {@link AnnotatedExpression} to add annotations. To be deleted. */ @Deprecated List annotations; J.Return expression; J.@Nullable Identifier label; public Return(UUID id, J.Return expression, J.@Nullable Identifier label) { this(id, Collections.emptyList(), expression, label); } @Override public Space getPrefix() { return expression.getPrefix(); } @Override public J2 withPrefix(Space space) { //noinspection unchecked return (J2) withExpression(expression.withPrefix(space)); } @Override public Markers getMarkers() { return expression.getMarkers(); } @Override public J2 withMarkers(Markers markers) { //noinspection unchecked return (J2) withExpression(expression.withMarkers(markers)); } @Override public @Nullable JavaType getType() { //noinspection DataFlowIssue return expression.getExpression().getType(); } @Override public T withType(@Nullable JavaType type) { // to change the expression of a return, change the type of its expression //noinspection unchecked return (T) this; } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitReturn(this, p); } @Override @Transient public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @Value @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @With class SpreadArgument implements K, Expression { @EqualsAndHashCode.Include UUID id; Space prefix; Markers markers; Expression expression; @Override public @Nullable JavaType getType() { return expression.getType() != null ? new JavaType.Array(null, expression.getType(), null) : null; } @Override public T withType(@Nullable JavaType type) { throw new UnsupportedOperationException("Type of SpreadArgument cannot be changed directly"); } @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitSpreadArgument(this, p); } } /** * Kotlin defines certain java statements like J.If as expression. *

* Has no state or behavior of its own aside from the Expression it wraps. */ @Getter @SuppressWarnings("unchecked") @ToString @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @With final class StatementExpression implements K, Expression, Statement { @EqualsAndHashCode.Include UUID id; Statement statement; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { J j = v.visit(getStatement(), p); if (j instanceof StatementExpression) { return j; } else if (j instanceof Statement) { return withStatement((Statement) j); } return j; } @Override public J2 withPrefix(Space space) { return (J2) withStatement(statement.withPrefix(space)); } @Override public Space getPrefix() { return statement.getPrefix(); } @Override public J2 withMarkers(Markers markers) { return (J2) withStatement(statement.withMarkers(markers)); } @Override public Markers getMarkers() { return statement.getMarkers(); } @Override public @Nullable JavaType getType() { return null; } @Override public T withType(@Nullable JavaType type) { throw new UnsupportedOperationException("StatementExpression cannot have a type"); } @Transient @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @Data @With final class StringTemplate implements K, Statement, Expression { @EqualsAndHashCode.Include UUID id; Space prefix; Markers markers; String delimiter; List strings; @Nullable JavaType type; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitStringTemplate(this, p); } @Transient @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @Data @With public static final class Expression implements K { @EqualsAndHashCode.Include UUID id; @Nullable Space prefix; @Override public Space getPrefix() { return prefix == null ? Space.EMPTY : prefix; } Markers markers; J tree; @Nullable Space after; public Space getAfter() { return after == null ? Space.EMPTY : after; } boolean enclosedInBraces; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitStringTemplateExpression(this, p); } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data @With final class This implements K, Expression { @EqualsAndHashCode.Include UUID id; Space prefix; Markers markers; J.@Nullable Identifier label; @Nullable JavaType type; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitThis(this, p); } @Override @Transient public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class TypeAlias implements K, Statement, TypedTree { @Nullable @NonFinal transient WeakReference padding; @Getter @With @EqualsAndHashCode.Include UUID id; @Getter @With Space prefix; @Getter @With Markers markers; @With @Getter List leadingAnnotations; @Getter @With List modifiers; @With @Getter Identifier name; @Nullable JContainer typeParameters; public @Nullable List getTypeParameters() { return typeParameters == null ? null : typeParameters.getElements(); } public TypeAlias withTypeParameters(@Nullable List typeParameters) { return getPadding().withTypeParameters(JContainer.withElementsNullable(this.typeParameters, typeParameters)); } @Getter @With JLeftPadded initializer; @Nullable @Getter @With JavaType type; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitTypeAlias(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()); } return allAnnotations; } public String getSimpleName() { return name.getSimpleName(); } @Override @Transient public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } public TypeAlias.Padding getPadding() { TypeAlias.Padding p; if (this.padding == null) { p = new TypeAlias.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new TypeAlias.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } @RequiredArgsConstructor public static class Padding { private final TypeAlias t; public @Nullable JContainer getTypeParameters() { return t.typeParameters; } public TypeAlias withTypeParameters(@Nullable JContainer typeParameters) { return t.typeParameters == typeParameters ? t : new TypeAlias(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.name, typeParameters, t.initializer, t.type); } public @Nullable JLeftPadded getInitializer() { return t.initializer; } public TypeAlias withInitializer(@Nullable JLeftPadded initializer) { return t.initializer == initializer ? t : new TypeAlias(t.id, t.prefix, t.markers, t.leadingAnnotations, t.modifiers, t.name, t.typeParameters, initializer, t.type); } } } @SuppressWarnings("unchecked") @Getter @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class TypeConstraints implements K { @Nullable @NonFinal transient WeakReference padding; @With @EqualsAndHashCode.Include UUID id; @With Markers markers; JContainer constraints; public List getConstraints() { return constraints.getElements(); } public TypeConstraints withConstraints(List constraints) { return getPadding().withConstraints(requireNonNull(JContainer.withElementsNullable(this.constraints, constraints))); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitTypeConstraints(this, p); } @Override public J2 withPrefix(Space space) { return (J2) getPadding().withConstraints(constraints.withBefore(space)); } @Override public Space getPrefix() { return constraints.getBefore(); } public TypeConstraints.Padding getPadding() { TypeConstraints.Padding p; if (this.padding == null) { p = new TypeConstraints.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new TypeConstraints.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } @RequiredArgsConstructor public static class Padding { private final TypeConstraints t; public JContainer getConstraints() { return t.constraints; } public TypeConstraints withConstraints(JContainer constraints) { return t.constraints == constraints ? t : new TypeConstraints(t.id, t.markers, constraints); } } } @Getter @SuppressWarnings("unchecked") @ToString @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @With final class TypeParameterExpression implements K, Expression { @EqualsAndHashCode.Include UUID id; TypeParameter typeParameter; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { J j = v.visit(getTypeParameter(), p); if (j instanceof TypeParameterExpression) { return j; } else if (j instanceof TypeParameter) { return withTypeParameter((TypeParameter) j); } return j; } @Override public J2 withPrefix(Space space) { return (J2) withTypeParameter(typeParameter.withPrefix(space)); } @Override public Space getPrefix() { return typeParameter.getPrefix(); } @Override public J2 withMarkers(Markers markers) { return (J2) withTypeParameter(typeParameter.withMarkers(markers)); } @Override public Markers getMarkers() { return typeParameter.getMarkers(); } @Override public @Nullable JavaType getType() { return null; } @Override public T withType(@Nullable JavaType type) { return (T) typeParameter; } @Transient @Override public CoordinateBuilder.Expression getCoordinates() { return new CoordinateBuilder.Expression(this); } } @SuppressWarnings("unused") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class Unary implements K, Statement, Expression, TypedTree { @Nullable @NonFinal transient WeakReference padding; @With @EqualsAndHashCode.Include @Getter UUID id; @With @Getter Space prefix; @With @Getter Markers markers; JLeftPadded operator; public Type getOperator() { return operator.getElement(); } public K.Unary withOperator(Type operator) { return getPadding().withOperator(this.operator.withElement(operator)); } @With @Getter Expression expression; @With @Nullable @Getter JavaType type; @Override public R accept(TreeVisitor v, P p) { return K.super.accept(v, p); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitUnary(this, p); } @Override public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } @Override @Transient public List getSideEffects() { return getOperator().isModifying() ? singletonList(this) : expression.getSideEffects(); } @SuppressWarnings("SwitchStatementWithTooFewBranches") public enum Type { NotNull; public boolean isModifying() { switch (this) { case NotNull: default: return false; } } } public K.Unary.Padding getPadding() { K.Unary.Padding p; if (this.padding == null) { p = new K.Unary.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new K.Unary.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new JavaPrinter<>()); } @RequiredArgsConstructor public static class Padding { private final K.Unary t; public JLeftPadded getOperator() { return t.operator; } public K.Unary withOperator(JLeftPadded operator) { return t.operator == operator ? t : new K.Unary(t.id, t.prefix, t.markers, operator, t.expression, t.type); } } } @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @Data final class When implements K, Statement, Expression { @With @EqualsAndHashCode.Include UUID id; @With Space prefix; @With Markers markers; @Nullable @With ControlParentheses selector; @With Block branches; @Nullable JavaType type; @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitWhen(this, p); } @Override public @Nullable JavaType getType() { return type; } @SuppressWarnings("unchecked") @Override public When withType(@Nullable JavaType type) { if (type == this.type) { return this; } return new When(id, prefix, markers, selector, branches, this.type); } @Override @Transient public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } } @SuppressWarnings("unused") @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true) @RequiredArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) final class WhenBranch implements K, Statement { @Nullable @NonFinal transient WeakReference padding; @With @EqualsAndHashCode.Include @Getter UUID id; @With @Getter Space prefix; @With @Getter Markers markers; JContainer expressions; public List getExpressions() { return expressions.getElements(); } public WhenBranch withExpressions(List expressions) { return getPadding().withExpressions(requireNonNull(JContainer.withElementsNullable(this.expressions, expressions))); } JRightPadded body; public J getBody() { return body.getElement(); } public WhenBranch withBody(J body) { return getPadding().withBody(JRightPadded.withElement(this.body, body)); } @Override public

J acceptKotlin(KotlinVisitor

v, P p) { return v.visitWhenBranch(this, p); } @Override @Transient public CoordinateBuilder.Statement getCoordinates() { return new CoordinateBuilder.Statement(this); } public WhenBranch.Padding getPadding() { WhenBranch.Padding p; if (this.padding == null) { p = new WhenBranch.Padding(this); this.padding = new WeakReference<>(p); } else { p = this.padding.get(); if (p == null || p.t != this) { p = new WhenBranch.Padding(this); this.padding = new WeakReference<>(p); } } return p; } @Override public String toString() { return withPrefix(Space.EMPTY).printTrimmed(new KotlinPrinter<>()); } @RequiredArgsConstructor public static class Padding { private final WhenBranch t; public JRightPadded getBody() { return t.body; } public WhenBranch withBody(JRightPadded body) { return t.body == body ? t : new WhenBranch(t.id, t.prefix, t.markers, t.expressions, body); } public JContainer getExpressions() { return t.expressions; } public WhenBranch withExpressions(JContainer expressions) { return t.expressions == expressions ? t : new WhenBranch(t.id, t.prefix, t.markers, expressions, t.body); } } } }