IrNode.java
/*******************************************************************************
* Copyright (c) 2025 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.queryrender.sparql.ir;
import java.util.Collections;
import java.util.Set;
import java.util.function.UnaryOperator;
import org.eclipse.rdf4j.query.algebra.Var;
/**
* Base class for textual SPARQL Intermediate Representation (IR) nodes.
*
* Design goals: - Keep IR nodes small and predictable; they are close to the final SPARQL surface form and
* intentionally avoid carrying evaluation semantics. - Favour immutability from the perspective of transforms:
* implementors should not mutate existing instances inside transforms but instead build new nodes as needed. - Provide
* a single {@link #print(IrPrinter)} entry point so pretty-printing concerns are centralized in the {@link IrPrinter}
* implementation.
*/
public abstract class IrNode {
@SuppressWarnings("unused")
public final String _className = this.getClass().getName();
private boolean newScope;
public IrNode(boolean newScope) {
this.newScope = newScope;
}
/** Default no-op printing; concrete nodes override. */
abstract public void print(IrPrinter p);
/**
* Function-style child transformation hook used by the transform pipeline to descend into nested structures.
*
* Contract: - Leaf nodes return {@code this} unchanged. - Container nodes return a new instance with their
* immediate children transformed using the provided operator. - Implementations must not mutate {@code this} or its
* existing children.
*/
public IrNode transformChildren(UnaryOperator<IrNode> op) {
return this;
}
public boolean isNewScope() {
return newScope;
}
public void setNewScope(boolean newScope) {
this.newScope = newScope;
}
/**
* Collect variables referenced by this node and all of its children (if any).
*
* Default implementation returns an empty set; container and triple-like nodes override to include their own Vars
* and recurse into child nodes.
*/
public Set<Var> getVars() {
return Collections.emptySet();
}
}