001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.compiler.ir;
011
012import org.eclipse.golo.compiler.parser.GoloASTNode;
013
014import java.util.List;
015import java.util.LinkedList;
016import static java.util.Collections.unmodifiableList;
017import static java.util.Objects.requireNonNull;
018
019public final class DestructuringAssignment extends GoloStatement {
020  private final List<LocalReference> references = new LinkedList<>();
021  private boolean isVarargs = false;
022  private boolean isDeclaring = false;
023  private ExpressionStatement expression;
024
025  DestructuringAssignment() {
026    super();
027  }
028
029  @Override
030  public DestructuringAssignment ofAST(GoloASTNode n) {
031    super.ofAST(n);
032    return this;
033  }
034
035  public boolean isVarargs() {
036    return this.isVarargs;
037  }
038
039  public DestructuringAssignment varargs(boolean varargs) {
040    this.isVarargs = varargs;
041    return this;
042  }
043
044  public DestructuringAssignment varargs() {
045    return varargs(true);
046  }
047
048  public DestructuringAssignment declaring() {
049    return declaring(true);
050  }
051
052  public DestructuringAssignment declaring(boolean d) {
053    this.isDeclaring = d;
054    return this;
055  }
056
057  public boolean isDeclaring() {
058    return this.isDeclaring;
059  }
060
061  public ExpressionStatement getExpression() {
062    return this.expression;
063  }
064
065  public DestructuringAssignment expression(Object expr) {
066    this.expression = ExpressionStatement.of(expr);
067    makeParentOf(expression);
068    return this;
069  }
070
071  public List<LocalReference> getReferences() {
072    return unmodifiableList(this.references);
073  }
074
075  public DestructuringAssignment to(Object var) {
076    requireNonNull(var);
077    if (var instanceof Iterable) {
078      for (Object o : (Iterable) var) {
079        this.to(o);
080      }
081    } else if (var instanceof LocalReference) {
082      references.add((LocalReference) var);
083    } else {
084      throw new IllegalArgumentException("LocalReference expected, got a " + var.getClass());
085    }
086    return this;
087  }
088
089  @Override
090  public String toString() {
091    List<String> names = new LinkedList<>();
092    for (LocalReference r : getReferences()) {
093      names.add(r.toString());
094    }
095    return String.join(", ", names) + " = " + getExpression().toString();
096  }
097
098  @Override
099  public void accept(GoloIrVisitor visitor) {
100    visitor.visitDestructuringAssignment(this);
101  }
102
103  @Override
104  public void walk(GoloIrVisitor visitor) {
105    for (LocalReference ref : references) {
106      ref.accept(visitor);
107    }
108    expression.accept(visitor);
109  }
110
111  @Override
112  protected void replaceElement(GoloElement original, GoloElement newElement) {
113    if (expression == original && newElement instanceof ExpressionStatement) {
114      expression(newElement);
115    } else {
116      throw cantReplace(original, newElement);
117    }
118  }
119}