WhileLoopStmt.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.stmt;
import java.util.Optional;
import org.sandbox.ast.api.expr.ASTExpr;
/**
* Immutable record representing a while loop statement.
* Provides fluent access to the condition expression and body statement.
*
* <p>Example usage:</p>
* <pre>
* // Old style:
* if (node instanceof WhileStatement) {
* WhileStatement ws = (WhileStatement) node;
* Expression condition = ws.getExpression();
* // ...
* }
*
* // New style:
* stmt.asWhileLoop()
* .flatMap(WhileLoopStmt::condition)
* .filter(cond -> cond.hasType("boolean"))
* .ifPresent(cond -> { });
* </pre>
*/
public record WhileLoopStmt(
Optional<ASTExpr> condition,
Optional<ASTStmt> body
) implements ASTStmt {
/**
* Creates a WhileLoopStmt record.
*
* @param condition the loop condition
* @param body the loop body statement
*/
public WhileLoopStmt {
condition = condition == null ? Optional.empty() : condition;
body = body == null ? Optional.empty() : body;
}
/**
* Checks if this loop has a condition.
*
* @return true if condition is present
*/
public boolean hasCondition() {
return condition.isPresent();
}
/**
* Checks if this loop has a body statement.
*
* @return true if body is present
*/
public boolean hasBody() {
return body.isPresent();
}
/**
* Checks if the condition has a specific type.
*
* @param qualifiedTypeName the fully qualified type name
* @return true if condition has this type
*/
public boolean conditionHasType(String qualifiedTypeName) {
return condition.flatMap(ASTExpr::type)
.map(t -> t.is(qualifiedTypeName))
.orElse(false);
}
/**
* Checks if the condition expression has the primitive boolean type.
*
* @return true if the condition is present and has type {@code boolean}
*/
public boolean hasBooleanTypedCondition() {
return condition.map(c -> c.hasType("boolean")).orElse(false);
}
/**
* Checks if the condition expression has the primitive boolean type.
* <p>
* Note: despite its name, this method does <strong>not</strong> check whether
* the condition is a compile-time constant; it only checks that the
* condition is of type {@code boolean}.
* </p>
*
* @return true if the condition is present and has type {@code boolean}
* @deprecated Use {@link #hasBooleanTypedCondition()} instead.
*/
@Deprecated
public boolean hasConstantCondition() {
return hasBooleanTypedCondition();
}
/**
* Builder for creating WhileLoopStmt instances.
*/
public static class Builder {
private Optional<ASTExpr> condition = Optional.empty();
private Optional<ASTStmt> body = Optional.empty();
/**
* Sets the condition expression.
*
* @param condition the loop condition
* @return this builder
*/
public Builder condition(ASTExpr condition) {
this.condition = Optional.ofNullable(condition);
return this;
}
/**
* Sets the body statement.
*
* @param body the loop body
* @return this builder
*/
public Builder body(ASTStmt body) {
this.body = Optional.ofNullable(body);
return this;
}
/**
* Builds the WhileLoopStmt.
*
* @return the while loop statement
*/
public WhileLoopStmt build() {
return new WhileLoopStmt(condition, body);
}
}
/**
* Creates a new builder.
*
* @return a new builder
*/
public static Builder builder() {
return new Builder();
}
}