//generated by abstract-syntax-gen
package de.peeeq.wurstscript.jassIm;
import java.util.*;

@SuppressWarnings({"cast", "unused", "rawtypes"})
public abstract class ImClasses extends AsgList<ImClass> implements Element{
    public ImClasses copy() {
        ImClasses result = new ImClassesImpl();
        for (ImClass elem : this) {
            result.add((ImClass) elem.copy());
        }
        return result;
    }

    @Override public ImClasses copyWithRefs() {
        ImClasses res = copy();
        Element self = this;
        res.accept(new Element.DefaultVisitor() {
            @Override public void visit(ImVarArrayAccess e) {
                super.visit(e);
                // check reference var
                {
                    Element elem = e.getVar();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setVar((ImVar) res.followPath(self.pathTo(e.getVar())));
                    }
                }
            }
            @Override public void visit(ImVarargLoop e) {
                super.visit(e);
                // check reference loopVar
                {
                    Element elem = e.getLoopVar();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setLoopVar((ImVar) res.followPath(self.pathTo(e.getLoopVar())));
                    }
                }
            }
            @Override public void visit(ImMemberAccess e) {
                super.visit(e);
                // check reference var
                {
                    Element elem = e.getVar();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setVar((ImVar) res.followPath(self.pathTo(e.getVar())));
                    }
                }
            }
            @Override public void visit(ImFuncRef e) {
                super.visit(e);
                // check reference func
                {
                    Element elem = e.getFunc();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setFunc((ImFunction) res.followPath(self.pathTo(e.getFunc())));
                    }
                }
            }
            @Override public void visit(ImFunctionCall e) {
                super.visit(e);
                // check reference func
                {
                    Element elem = e.getFunc();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setFunc((ImFunction) res.followPath(self.pathTo(e.getFunc())));
                    }
                }
            }
            @Override public void visit(ImMethodCall e) {
                super.visit(e);
                // check reference method
                {
                    Element elem = e.getMethod();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setMethod((ImMethod) res.followPath(self.pathTo(e.getMethod())));
                    }
                }
            }
            @Override public void visit(ImMethod e) {
                super.visit(e);
                // check reference implementation
                {
                    Element elem = e.getImplementation();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setImplementation((ImFunction) res.followPath(self.pathTo(e.getImplementation())));
                    }
                }
            }
            @Override public void visit(ImVarAccess e) {
                super.visit(e);
                // check reference var
                {
                    Element elem = e.getVar();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setVar((ImVar) res.followPath(self.pathTo(e.getVar())));
                    }
                }
            }
            @Override public void visit(ImTypeVarDispatch e) {
                super.visit(e);
                // check reference typeVariable
                {
                    Element elem = e.getTypeVariable();
                    while (elem != self && elem != null) {
                        elem = elem.getParent();
                    }
                    if (elem == self) {
                        e.setTypeVariable((ImTypeVar) res.followPath(self.pathTo(e.getTypeVariable())));
                    }
                }
            }
        });
        return res;
    }

    /** */
    public abstract String toString();
    /** */
    public abstract ImFunction getNearestFunc();
    /** */
    public abstract de.peeeq.wurstscript.ast.Element attrTrace();
    /** */
    public abstract ImProg attrProg();
}