blob: ac1fbddb892ae9b7e00796acca115018715289a7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.acceleo.aql.evaluation;
import java.util.ArrayDeque;
import java.util.Deque;
import org.eclipse.acceleo.ModuleElement;
/**
* This will represent a stack of calls as known by Acceleo.
* <p>
* We need to keep a reference to the "starting point" of a given stack in order to be able to go back down
* into overriden modules all the way to there, since this starting point might very well not be the module
* containing the first module element of our stack. For example, if a module M1 imports M2 which extends M3,
* M1 tries to call a template that's only available in M3, the first module element called on that stack will
* be the one from M3, but if that template calls another that is overriden in M2, we need to be able to go
* back down to M2.
* </p>
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
public class AcceleoCallStack {
/** The module qualified name that was the starting point of us creating this stack. */
private final String startingModuleQualifiedName;
/** The underlying call stack. */
private final Deque<ModuleElement> stack;
/**
* Creates a stack starting at the given module.
*
* @param startingModuleQualifiedName
* The module qualified name that will be considered the "starting point" of this stack.
*/
public AcceleoCallStack(String startingModuleQualifiedName) {
this.startingModuleQualifiedName = startingModuleQualifiedName;
this.stack = new ArrayDeque<ModuleElement>();
}
public Deque<ModuleElement> getStack() {
return stack;
}
public String getStartingModuleQualifiedName() {
return startingModuleQualifiedName;
}
/**
* Adds the given {@link ModuleElement} to the top of this stack.
*
* @param moduleElement
* The {@link ModuleElement} we're pushing atop the stack.
*/
public void push(ModuleElement moduleElement) {
stack.addLast(moduleElement);
}
/**
* Retrieves and removes the {@link ModuleElement} atop this stack.
*
* @return The {@link ModuleElement} that was at the top of this stack if any, <code>null</code>
* otherwise.
*/
public ModuleElement pop() {
return stack.pollLast();
}
/**
* Retrieves the {@link ModuleElement} atop this stack without removing it.
*
* @return The {@link ModuleElement} at the top of this stack if any, <code>null</code> otherwise.
*/
public ModuleElement peek() {
return stack.peekLast();
}
/**
* Returns <code>true</code> if this stack contains no element.
*
* @return <code>true</code> if this stack contains no element.
*/
public boolean isEmpty() {
return stack.isEmpty();
}
}