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

org.checkerframework.dataflow.cfg.node.Node Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.43.0
Show newest version
package org.checkerframework.dataflow.cfg.node;

import com.sun.source.tree.Tree;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicLong;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.cfg.block.Block;
import org.checkerframework.dataflow.cfg.builder.CFGBuilder;
import org.checkerframework.dataflow.qual.Pure;
import org.plumelib.util.UniqueId;

/**
 * A node in the abstract representation used for Java code inside a basic block.
 *
 * 

The following invariants hold: * *

 * block == null || block instanceof RegularBlock || block instanceof ExceptionBlock
 * block != null ⇔ block.getNodes().contains(this)
 * 
* *
 * type != null
 * tree != null ⇒ node.getType() == InternalUtils.typeOf(node.getTree())
 * 
* * Note that two {@code Node}s can be {@code .equals} but represent different CFG nodes. Take care * to use reference equality, maps that handle identity {@code IdentityHashMap}, and sets like * {@code IdentityMostlySingleton}. * * @see org.checkerframework.dataflow.util.IdentityMostlySingleton */ public abstract class Node implements UniqueId { /** * The basic block this node belongs to. If null, this object represents a method formal * parameter. */ protected @Nullable Block block; /** Is this node an l-value? */ protected boolean lvalue = false; /** * Does this node represent a tree that appears in the source code (true) or one that the CFG * builder added while desugaring (false). */ protected boolean inSource = true; /** * The type of this node. For {@link Node}s with {@link Tree}s, this type is the type of the * {@link Tree}. Otherwise, it is the type is set by the {@link CFGBuilder}. */ protected final TypeMirror type; /** The unique ID for the next-created object. */ static final AtomicLong nextUid = new AtomicLong(0); /** The unique ID of this object. */ final long uid = nextUid.getAndIncrement(); /** * Returns the unique ID of this object. * * @return the unique ID of this object */ @Override public long getUid(@UnknownInitialization Node this) { return uid; } /** * Creates a new Node. * * @param type the type of the node */ protected Node(TypeMirror type) { assert type != null; this.type = type; } /** * Returns the basic block this node belongs to (or {@code null} if it represents the parameter of * a method). * * @return the basic block this node belongs to (or {@code null} if it represents the parameter of * a method) */ public @Nullable Block getBlock() { return block; } /** Set the basic block this node belongs to. */ public void setBlock(Block b) { block = b; } /** * Returns the {@link Tree} in the abstract syntax tree, or {@code null} if no corresponding tree * exists. For instance, this is the case for an {@link ImplicitThisNode}. * * @return the corresponding {@link Tree} or {@code null} */ @Pure public abstract @Nullable Tree getTree(); /** * Returns a {@link TypeMirror} representing the type of a {@link Node}. A {@link Node} will * always have a type even when it has no {@link Tree}. * * @return a {@link TypeMirror} representing the type of this {@link Node} */ public TypeMirror getType() { return type; } /** * Accept method of the visitor pattern. * * @param result type of the operation * @param

parameter type * @param visitor the visitor to be applied to this node * @param p the parameter for this operation */ public abstract R accept(NodeVisitor visitor, P p); /** Is the node an lvalue or not? */ @Pure public boolean isLValue() { return lvalue; } /** Make this node an l-value. */ public void setLValue() { lvalue = true; } public boolean getInSource() { return inSource; } public void setInSource(boolean inSrc) { inSource = inSrc; } /** * Returns a collection containing all of the operand {@link Node}s of this {@link Node}. * * @return a collection containing all of the operand {@link Node}s of this {@link Node} */ public abstract Collection getOperands(); /** * Returns a collection containing all of the operand {@link Node}s of this {@link Node}, as well * as (transitively) the operands of its operands. * * @return a collection containing all of the operand {@link Node}s of this {@link Node}, as well * as (transitively) the operands of its operands */ public Collection getTransitiveOperands() { ArrayDeque operands = new ArrayDeque<>(getOperands()); ArrayDeque transitiveOperands = new ArrayDeque<>(operands.size()); while (!operands.isEmpty()) { Node next = operands.removeFirst(); operands.addAll(next.getOperands()); transitiveOperands.add(next); } return transitiveOperands; } /** * Returns a verbose string representation of this, useful for debugging. * * @return a printed representation of this */ public String toStringDebug() { return String.format("%s [%s]", this, this.getClassAndUid()); } /** * Returns a verbose string representation of a collection of nodes, useful for debugging.. * * @param nodes a collection of nodes to format * @return a printed representation of the given collection */ public static String nodeCollectionToString(Collection nodes) { StringJoiner result = new StringJoiner(", ", "[", "]"); for (Node n : nodes) { result.add(n.toStringDebug()); } return result.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy