org.openrewrite.Tree Maven / Gradle / Ivy
Show all versions of rewrite-core 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;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.jspecify.annotations.Nullable;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.marker.Markers;
import java.util.UUID;
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@c")
@JsonPropertyOrder({"@c"}) // serialize type info first
@JsonIgnoreProperties(ignoreUnknown = true)
public interface Tree {
@SuppressWarnings("unused")
@JsonProperty("@c")
default String getJacksonPolymorphicTypeTag() {
return getClass().getName();
}
static UUID randomId() {
//noinspection ConstantConditions
return UUID.randomUUID();
}
/**
* An id that can be used to identify a particular AST element, even after transformations have taken place on it
*
* @return A unique identifier
*/
UUID getId();
Markers getMarkers();
T withMarkers(Markers markers);
T withId(UUID id);
/**
* Supports polymorphic visiting via {@link TreeVisitor#visit(Tree, Object)}. This is useful in cases where an AST
* type contains a field that is of a type with a hierarchy. The visitor doesn't have to figure out which visit
* method to call by using instanceof.
*
* @param v visitor
* @param p visit context
* @param visitor return type
* @param visit context type
* @return visitor result
*/
default @Nullable R accept(TreeVisitor v, P p) {
return v.defaultValue(this, p);
}
/**
* Checks the supplied argument to see if the supplied visitor and its context would be valid arguments
* to accept().
* Typically, this involves checking that the visitor is of a type that operates on this kind of tree.
* e.g.: A Java Tree implementation would return true for JavaVisitors and false for MavenVisitors
*
* @param the visitor's context argument
* @return 'true' if the arguments to this function would be valid arguments to accept()
*/
boolean isAcceptable(TreeVisitor, P> v, P p);
default
TreeVisitor, PrintOutputCapture
> printer(Cursor cursor) {
return cursor.firstEnclosingOrThrow(SourceFile.class).printer(cursor);
}
default String print(Cursor cursor) {
return print(cursor, new PrintOutputCapture<>(0));
}
default
String print(Cursor cursor, PrintOutputCapture
out) {
this.
printer(cursor).visit(this, out, cursor);
return out.getOut();
}
default String print(TreeVisitor, PrintOutputCapture> printer) {
PrintOutputCapture outputCapture = new PrintOutputCapture<>(0);
printer.visit(this, outputCapture);
return outputCapture.getOut();
}
default String printTrimmed(P p, Cursor cursor) {
return StringUtils.trimIndent(print(cursor, new PrintOutputCapture<>(p)));
}
default String printTrimmed(Cursor cursor) {
return StringUtils.trimIndent(print(cursor));
}
default String printTrimmed(TreeVisitor, PrintOutputCapture> printer) {
return StringUtils.trimIndent(print(printer));
}
default boolean isScope(@Nullable Tree tree) {
//noinspection ConstantConditions
return tree != null && tree.getId() != null && tree.getId().equals(getId());
}
default T2 cast() {
//noinspection unchecked
return (T2) this;
}
}