ASTExpr.java
/*******************************************************************************
* Copyright (c) 2026 Carsten Hammer.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Carsten Hammer
*******************************************************************************/
package org.sandbox.ast.api.expr;
import java.util.Optional;
import org.sandbox.ast.api.core.ASTWrapper;
import org.sandbox.ast.api.info.TypeInfo;
/**
* Base interface for expression wrappers.
* Provides fluent query methods for working with AST expressions.
*
* <p>This is a marker interface extended by specific expression types like
* {@link MethodInvocationExpr}, {@link FieldAccessExpr}, etc.</p>
*
* <p>Example usage:</p>
* <pre>
* ASTExpr expr = ...;
* expr.asMethodInvocation()
* .flatMap(MethodInvocationExpr::receiver)
* .filter(receiver -> receiver.isSimpleName())
* .ifPresent(name -> { });
* </pre>
*/
public interface ASTExpr extends ASTWrapper {
/**
* Gets the type of this expression, if available.
*
* @return the type information, or empty if type cannot be resolved
*/
Optional<TypeInfo> type();
/**
* Attempts to cast this expression to a {@link MethodInvocationExpr}.
*
* @return the method invocation, or empty if this is not a method invocation
*/
default Optional<MethodInvocationExpr> asMethodInvocation() {
return this instanceof MethodInvocationExpr mi ? Optional.of(mi) : Optional.empty();
}
/**
* Attempts to cast this expression to a {@link SimpleNameExpr}.
*
* @return the simple name, or empty if this is not a simple name
*/
default Optional<SimpleNameExpr> asSimpleName() {
return this instanceof SimpleNameExpr sn ? Optional.of(sn) : Optional.empty();
}
/**
* Attempts to cast this expression to a {@link FieldAccessExpr}.
*
* @return the field access, or empty if this is not a field access
*/
default Optional<FieldAccessExpr> asFieldAccess() {
return this instanceof FieldAccessExpr fa ? Optional.of(fa) : Optional.empty();
}
/**
* Attempts to cast this expression to a {@link CastExpr}.
*
* @return the cast expression, or empty if this is not a cast
*/
default Optional<CastExpr> asCast() {
return this instanceof CastExpr ce ? Optional.of(ce) : Optional.empty();
}
/**
* Attempts to cast this expression to an {@link InfixExpr}.
*
* @return the infix expression, or empty if this is not an infix expression
*/
default Optional<InfixExpr> asInfix() {
return this instanceof InfixExpr ie ? Optional.of(ie) : Optional.empty();
}
/**
* Checks if this expression is a simple name.
*
* @return true if this is a simple name
*/
default boolean isSimpleName() {
return this instanceof SimpleNameExpr;
}
/**
* Checks if this expression is a method invocation.
*
* @return true if this is a method invocation
*/
default boolean isMethodInvocation() {
return this instanceof MethodInvocationExpr;
}
/**
* Checks if this expression is a field access.
*
* @return true if this is a field access
*/
default boolean isFieldAccess() {
return this instanceof FieldAccessExpr;
}
/**
* Checks if this expression has a specific type.
*
* @param qualifiedTypeName the fully qualified type name
* @return true if the expression has this type
*/
default boolean hasType(String qualifiedTypeName) {
return type().map(t -> t.is(qualifiedTypeName)).orElse(false);
}
/**
* Checks if this expression has a specific type.
*
* @param clazz the class to check
* @return true if the expression has this type
*/
default boolean hasType(Class<?> clazz) {
return type().map(t -> t.is(clazz)).orElse(false);
}
}