001/*
002 * Copyright (c) 2012-2021 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 org.eclipse.golo.compiler.PackageAndClass;
014
015import java.util.List;
016import java.util.Collection;
017import java.util.Iterator;
018
019/**
020 * Interface for Golo elements that can contain functions (module, augmentations, ...).
021 */
022public interface FunctionContainer extends Iterable<GoloFunction> {
023
024  default Iterator<GoloFunction> iterator() {
025    return getFunctions().iterator();
026  }
027
028  List<GoloFunction> getFunctions();
029
030  /**
031   * Adds a function to this container.
032   */
033  void addFunction(GoloFunction func);
034
035  /**
036   * Adds a macro invocation to this container.
037   *
038   * <p>The macro is supposed to return a {@link GoloFunction} when expanded.
039   */
040  void addMacroInvocation(MacroInvocation macroCall);
041
042  /**
043   * Adds a function or a macro invocation according to the given argument.
044   *
045   * @see #addFunction(GoloFunction)
046   * @see #addMacroInvocation(MacroInvocation)
047   */
048  default void addElement(Object elt) {
049    if (elt instanceof GoloFunction) {
050      addFunction((GoloFunction) elt);
051    } else if (elt instanceof MacroInvocation) {
052      addMacroInvocation((MacroInvocation) elt);
053    } else if (!(elt instanceof Noop)) {
054      throw new IllegalArgumentException("Can't add a " + elt.getClass().getName());
055    }
056  }
057
058  PackageAndClass getPackageAndClass();
059
060  default void addFunctions(Collection<GoloFunction> funcs) {
061    for (GoloFunction f : funcs) {
062      addFunction(f);
063    }
064  }
065
066  default GoloFunction getFunction(GoloFunction function) {
067    for (GoloFunction f : getFunctions()) {
068      if (f.equals(function)) {
069        return f;
070      }
071    }
072    return null;
073  }
074
075  boolean hasFunctions();
076}