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

template.ast.State.tt Maven / Gradle / Ivy

There is a newer version: 2.3.6
Show newest version
# Copyright (c) 2013-2016, The JastAdd Team
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the Lund University nor the names of its
#       contributors may be used to endorse or promote products derived from
#       this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

ASTNode$State = [[
/** @apilevel internal */
public class $StateClass {
  /** @apilevel internal */
  protected static class CircularValue {
    Object value;
    Cycle cycle;
  }

  /**
   * Instances of this class are used to uniquely identify circular evaluation cycles.
   * @apilevel internal
   */
  protected static class Cycle {
  }

  /** The cycle ID used outside of circular evaluation. */
  public static final Cycle NON_CYCLE = new Cycle();

  /**
   * Tracks the state of the current circular evaluation. This class defines a
   * stack structure where the next element on the stack is pointed to by the
   * {@code next} field.
   * @apilevel internal
   */
  protected static class CircleState {
    final CircleState next;
    boolean inCircle = false;
$if(LegacyRewrite)
    boolean resetCycle = false;
$endif
    boolean change = false;

    /** Evaluation depth of lazy attributes. */
    int lazyAttribute = 0;

$if(CacheCycle)
    boolean lastCycle = false;

$endif
$if(ComponentCheck)
    boolean completed = false; // Whether the circular evaluation has completed.

$endif
    /** Cycle ID of the latest cycle in this circular evaluation. */
    Cycle cycle = NON_CYCLE;

    protected CircleState(CircleState next) {
      this.next = next;
    }
  }

  /** Sentinel circle state representing non-circular evaluation. */
  private static final CircleState CIRCLE_BOTTOM = new CircleState(null);

  /**
   * Current circular state.
   * @apilevel internal
   */
  private CircleState circle = CIRCLE_BOTTOM;

  /** @apilevel internal */
  protected boolean inCircle() {
    return circle.inCircle;
  }

  /** @apilevel internal */
  protected boolean calledByLazyAttribute() {
    return circle.lazyAttribute > 0;
  }

  /** @apilevel internal */
  protected void enterLazyAttribute() {
    circle.lazyAttribute += 1;
  }

  /** @apilevel internal */
  protected void leaveLazyAttribute() {
    circle.lazyAttribute -= 1;
  }

  /** @apilevel internal */
  protected void enterCircle() {
    CircleState next = new CircleState(circle);
    next.inCircle = true;
    circle = next;
  }

  /** @apilevel internal */
  protected void leaveCircle() {
$if(ComponentCheck)
    circle.completed = true;
$endif
    circle = circle.next;
  }

  /** @apilevel internal */
  protected Cycle nextCycle() {
    Cycle cycle = new Cycle();
    circle.cycle = cycle;
    return cycle;
  }

  /** @apilevel internal */
  protected Cycle cycle() {
    return circle.cycle;
  }

  /** @apilevel internal */
  protected CircleState currentCircle() {
    return circle;
  }

$if(ComponentCheck)
  /**
   * Throws a RuntimeException if called on a different circular evaluation
   * than the given circle state.
   * @apilevel internal
   */
  protected void assertSameCircle(CircleState prev, String attribute) {
    if (prev != null && !prev.completed && prev != currentCircle()) {
      throw new RuntimeException(String.format("Circular definition of attribute %s.", attribute));
    }
  }
$endif

  /** @apilevel internal */
  protected void setChangeInCycle() {
    circle.change = true;
  }

  /** @apilevel internal */
  protected boolean testAndClearChangeInCycle() {
    boolean change = circle.change;
    circle.change = false;
    return change;
  }

  /** @apilevel internal */
  protected boolean changeInCycle() {
    return circle.change;
  }

$if(CacheCycle)
  /** @apilevel internal */
  protected boolean lastCycle() {
    return circle.lastCycle;
  }

  /** @apilevel internal */
  protected void startLastCycle() {
    circle.lastCycle = true;
  }
$endif

$if(LegacyRewrite)
  /** @apilevel internal */
  protected void startResetCycle() {
    circle.resetCycle = true;
  }

  /** @apilevel internal */
  protected boolean resetCycle() {
    return circle.resetCycle;
  }

$endif
  protected $StateClass() {
$if(ComponentCheck)
    circle.completed = true;
$endif
$if(LegacyRewrite)
    stack = new int[64];
    pos = 0;
$endif
  }
$if(LegacyRewrite)
  /** @apilevel internal */
  public static final int REWRITE_CHANGE = 1;

  /** @apilevel internal */
  public static final int REWRITE_NOCHANGE = 2;

  /** @apilevel internal */
  public static final int REWRITE_INTERRUPT = 3;

  public int boundariesCrossed = 0;

  // state code
  private int[] stack;

  private int pos;

  private void ensureSize(int size) {
    if (size < stack.length) {
      return;
    }
    int[] newStack = new int[stack.length * 2];
    System.arraycopy(stack, 0, newStack, 0, stack.length);
    stack = newStack;
  }

  public void push(int i) {
    ensureSize(pos+1);
    stack[pos++] = i;
  }

  public int pop() {
    return stack[--pos];
  }

  public int peek() {
    return stack[pos - 1];
  }
$endif
  $include(State.incHook)

$if(TracingEnabled)
  private Trace trace = null;
  public Trace trace() {
    if (trace == null) {
      trace = new Trace();
    }
    return trace;
  }
  $include(TraceClass)
$endif
}
]]

ASTNode$State.reset [[
  /** @apilevel internal */
  public void $StateClass.reset() {
    $SynchBegin
    // Reset circular evaluation state.
    circle = CIRCLE_BOTTOM;
$if(LegacyRewrite)
    boundariesCrossed = 0;
$endif
    $SynchEnd
  }
]]




© 2015 - 2024 Weber Informatics LLC | Privacy Policy