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 static gololang.Messages.message;
014
015/**
016 * A constant value.
017 */
018public final class ConstantStatement extends ExpressionStatement<ConstantStatement> {
019
020  private Object value;
021
022  private ConstantStatement(Object value) {
023    super();
024    this.value = value;
025  }
026
027  /**
028   * Creates a constant value.
029   *
030   * <p>
031   */
032  public static ConstantStatement of(Object o) {
033    if (o instanceof ConstantStatement) {
034      return (ConstantStatement) o;
035    }
036    if (o instanceof Class || o instanceof ClassReference) {
037      return new ConstantStatement(ClassReference.of(o));
038    }
039    if (!isLiteralValue(o)) {
040      throw new IllegalArgumentException("Not a constant value: " + o);
041    }
042    return new ConstantStatement(o);
043  }
044
045  public static boolean isLiteralValue(Object v) {
046    return v == null
047        || v instanceof String
048        || v instanceof Character
049        || v instanceof Number
050        || v instanceof Boolean
051        || v instanceof Class || v instanceof ClassReference
052        || v instanceof FunctionRef;
053  }
054
055  public Object value() {
056    return value;
057  }
058
059  public ConstantStatement value(Object v) {
060    this.value = v;
061    return this;
062  }
063
064  protected ConstantStatement self() { return this; }
065
066  /**
067   * {@inheritDoc}
068   *
069   * <p>Always throws an exception since {@link NamedArgument} can't have a local declaration.
070   */
071  @Override
072  public ConstantStatement with(Object a) {
073    throw new UnsupportedOperationException(message("invalid_local_definition", this.getClass().getName()));
074  }
075
076  @Override
077  public boolean hasLocalDeclarations() {
078    return false;
079  }
080
081  /**
082   * {@inheritDoc}
083   */
084  @Override
085  public String toString() {
086    return String.format("`%s`", value);
087  }
088
089  /**
090   * {@inheritDoc}
091   */
092  @Override
093  public void accept(GoloIrVisitor visitor) {
094    visitor.visitConstantStatement(this);
095  }
096
097  /**
098   * {@inheritDoc}
099   */
100  @Override
101  protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) {
102    throw cantReplace();
103  }
104}