/* This file was generated by SableCC (http://www.sablecc.org/). */

package com.google.clearsilver.jsilver.syntax.node;

import java.util.*;
import com.google.clearsilver.jsilver.syntax.analysis.*;

@SuppressWarnings("nls")
public final class ASequenceExpression extends PExpression
{
    private final LinkedList<PExpression> _args_ = new LinkedList<PExpression>();

    public ASequenceExpression()
    {
        // Constructor
    }

    public ASequenceExpression(
        @SuppressWarnings("hiding") List<PExpression> _args_)
    {
        // Constructor
        setArgs(_args_);

    }

    @Override
    public Object clone()
    {
        return new ASequenceExpression(
            cloneList(this._args_));
    }

    public void apply(Switch sw)
    {
        ((Analysis) sw).caseASequenceExpression(this);
    }

    public LinkedList<PExpression> getArgs()
    {
        return this._args_;
    }

    public void setArgs(List<PExpression> list)
    {
        this._args_.clear();
        this._args_.addAll(list);
        for(PExpression e : list)
        {
            if(e.parent() != null)
            {
                e.parent().removeChild(e);
            }

            e.parent(this);
        }
    }

    @Override
    public String toString()
    {
        return ""
            + toString(this._args_);
    }

    @Override
    void removeChild(@SuppressWarnings("unused") Node child)
    {
        // Remove child
        if(this._args_.remove(child))
        {
            return;
        }

        throw new RuntimeException("Not a child.");
    }

    @Override
    void replaceChild(@SuppressWarnings("unused") Node oldChild, @SuppressWarnings("unused") Node newChild)
    {
        // Replace child
        for(ListIterator<PExpression> i = this._args_.listIterator(); i.hasNext();)
        {
            if(i.next() == oldChild)
            {
                if(newChild != null)
                {
                    i.set((PExpression) newChild);
                    newChild.parent(this);
                    oldChild.parent(null);
                    return;
                }

                i.remove();
                oldChild.parent(null);
                return;
            }
        }

        throw new RuntimeException("Not a child.");
    }
}
