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.*;
014import org.eclipse.golo.compiler.PackageAndClass;
015import static gololang.Messages.message;
016
017/**
018 * Named augmentation definition.
019 */
020public final class NamedAugmentation extends GoloElement<NamedAugmentation> implements FunctionContainer, ToplevelGoloElement, NamedElement {
021  private final PackageAndClass name;
022  private final Set<GoloFunction> functions = new LinkedHashSet<>();
023
024  private NamedAugmentation(PackageAndClass name) {
025    super();
026    this.name = name;
027  }
028
029  /**
030   * Creates a named augmentation.
031   *
032   * @param name the name of the augmentation (compatible with {@link PackageAndClass#of(Object)})
033   */
034  public static NamedAugmentation of(Object name) {
035    return new NamedAugmentation(PackageAndClass.of(name));
036  }
037
038  @Override
039  public String getName() {
040    return this.name.toString();
041  }
042
043  public PackageAndClass getPackageAndClass() {
044    return this.name;
045  }
046
047  protected NamedAugmentation self() { return this; }
048
049  /**
050   * {@inheritDoc}
051   */
052  @Override
053  public List<GoloFunction> getFunctions() {
054    return new ArrayList<>(functions);
055  }
056
057  /**
058   * {@inheritDoc}
059   */
060  @Override
061  public void addFunction(GoloFunction func) {
062    if (func.getArity() == 0) {
063      throw new IllegalArgumentException(message("augment_function_no_args", func.getName(), this.getPackageAndClass()));
064    }
065    functions.add(makeParentOf(func));
066  }
067
068  /**
069   * {@inheritDoc}
070   */
071  @Override
072  public boolean hasFunctions() {
073    return !functions.isEmpty();
074  }
075
076  /**
077   * Adds the elements to this augmentation.
078   *
079   * <p>This is a builder method.
080   *
081   * @see FunctionContainer#addElement(Object)
082   */
083  public NamedAugmentation add(Object... elts) {
084    for (Object elt : elts) {
085      addElement(elt);
086    }
087    return this;
088  }
089
090  /**
091   * {@inheritDoc}
092   */
093  @Override
094  public void accept(GoloIrVisitor visitor) {
095    visitor.visitNamedAugmentation(this);
096  }
097
098  /**
099   * {@inheritDoc}
100   */
101  @Override
102  public List<GoloElement<?>> children() {
103    LinkedList<GoloElement<?>> children = new LinkedList<>(functions);
104    return children;
105  }
106
107  /**
108   * {@inheritDoc}
109   */
110  @Override
111  protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) {
112    if (functions.contains(original)) {
113      functions.remove(original);
114    } else {
115      throw cantReplace(original, newElement);
116    }
117    addElement(newElement);
118  }
119}