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
013/**
014 * Assignment statement in Golo code.
015 * <p>
016 * An assignment is a statement like:
017 * <pre class="listing"><code class="lang-golo" data-lang="golo">
018 * var foo = 42
019 * let bar = a(more: complex()) + expression
020 * </code></pre>
021 */
022public final class AssignmentStatement extends GoloAssignment<AssignmentStatement> implements ToplevelGoloElement {
023  private LocalReference localReference;
024
025  AssignmentStatement() { super(); }
026
027  /**
028   * Full assignment creation in one call.
029   * <p>
030   * A lot less readable than the fluent API, but useful when doing meta-generation
031   *
032   * @param ref the reference to assign to ({@link AssignmentStatement#to(Object...)}).
033   * @param value the value to assign ({@link AssignmentStatement#as(Object)}).
034   * @param declaring whether the assignment is a declaring one.
035   * @return an initialized assignment element.
036   */
037  public static AssignmentStatement create(Object ref, Object value, Object declaring) {
038    return new AssignmentStatement().to(ref).as(value).declaring((boolean) declaring);
039  }
040
041  /**
042   * Creates a uninitialized assignment.
043   */
044  public static AssignmentStatement create() {
045    return new AssignmentStatement();
046  }
047
048  protected AssignmentStatement self() { return this; }
049
050  public LocalReference getLocalReference() {
051    return localReference;
052  }
053
054  /**
055   * {@inheritDoc}
056   */
057  @Override
058  public AssignmentStatement variable() {
059    this.localReference.variable();
060    return this;
061  }
062
063  /**
064   * {@inheritDoc}
065   */
066  @Override
067  public boolean isConstant() {
068    return this.localReference.isConstant();
069  }
070
071  /**
072   * {@inheritDoc}
073   */
074  @Override
075  public LocalReference[] getReferences() {
076    if (localReference != null) {
077      return new LocalReference[]{localReference};
078    }
079    return new LocalReference[0];
080  }
081
082  /**
083   * {@inheritDoc}
084   */
085  @Override
086  public int getReferencesCount() {
087    return localReference == null ? 0 : 1;
088  }
089
090  /**
091   * {@inheritDoc}
092   */
093  @Override
094  public AssignmentStatement to(Object... refs) {
095    if (refs.length != 1 || refs[0] == null) {
096      throw new IllegalArgumentException("Must assign to one reference");
097    }
098    this.localReference = makeParentOf(LocalReference.of(refs[0]));
099    return this;
100  }
101
102  @Override
103  public String toString() {
104    return String.format("%s = %s", localReference, expression().toString());
105  }
106
107  /**
108   * {@inheritDoc}
109   */
110  @Override
111  public void accept(GoloIrVisitor visitor) {
112    visitor.visitAssignmentStatement(this);
113  }
114}