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}