001/*
002 * Copyright (c) 2012-2018 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others
003 *
004 * This program and the accompanying materials are made available under the
005 * terms of the Eclipse Public License 2.0 which is available at
006 * http://www.eclipse.org/legal/epl-2.0.
007 *
008 * SPDX-License-Identifier: EPL-2.0
009 */
010
011package gololang.ir;
012
013import java.util.Collections;
014import java.util.List;
015
016import static gololang.Messages.message;
017
018/**
019 * A named argument in a function call.
020 *
021 * <p>Represents nodes such as:
022 * <pre class="listing"><code class="lang-golo" data-lang="golo">
023 * foo(b=42, a=bar("answer"))
024 * </code></pre>
025 */
026public final class NamedArgument extends ExpressionStatement<NamedArgument> {
027
028  private final String name;
029  private ExpressionStatement<?> expression;
030
031  private NamedArgument(String name, ExpressionStatement<?> expression) {
032    super();
033    this.name = name;
034    this.setExpression(expression);
035  }
036
037  public static NamedArgument of(String name, Object value) {
038    return new NamedArgument(name, ExpressionStatement.of(value));
039  }
040
041  protected NamedArgument self() { return this; }
042
043  public String getName() {
044    return this.name;
045  }
046
047  public ExpressionStatement<?> expression() {
048    return this.expression;
049  }
050
051  /**
052   * Defines the value of the named argument.
053   *
054   * <p>This is a builder method.
055   *
056   * @param value the {@link ExpressionStatement} to use as the value of the argument.
057   */
058  private void setExpression(ExpressionStatement<?> value) {
059    this.expression = makeParentOf(value);
060  }
061
062  /**
063   * {@inheritDoc}
064   *
065   * <p>Always throws an exception since {@link NamedArgument} can't have a local declaration.
066   */
067  @Override
068  public NamedArgument with(Object a) {
069    throw new UnsupportedOperationException(message("invalid_local_definition", this.getClass().getName()));
070  }
071
072  @Override
073  public boolean hasLocalDeclarations() {
074    return false;
075  }
076
077  /**
078   * {@inheritDoc}
079   */
080  @Override
081  public void accept(GoloIrVisitor visitor) {
082    visitor.visitNamedArgument(this);
083  }
084
085  /**
086   * {@inheritDoc}
087   */
088  @Override
089  public List<GoloElement<?>> children() {
090    return Collections.singletonList(expression);
091  }
092
093  /**
094   * {@inheritDoc}
095   */
096  @Override
097  protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) {
098    if (this.expression != original) {
099      throw doesNotContain(original);
100    }
101    this.setExpression(ExpressionStatement.of(newElement));
102  }
103}