001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.compiler.ir;
011
012import java.util.Collections;
013import java.util.LinkedList;
014import java.util.List;
015
016public abstract class AbstractInvocation extends ExpressionStatement {
017
018  private final String name;
019  private final List<ExpressionStatement> arguments = new LinkedList<>();
020  protected boolean usesNamedArguments = false;
021
022  AbstractInvocation(String name) {
023    super();
024    this.name = name;
025  }
026
027  public String getName() {
028    return name;
029  }
030
031  private void addArgument(ExpressionStatement argument) {
032    arguments.add(argument);
033    makeParentOf(argument);
034  }
035
036  public AbstractInvocation withArgs(Object... arguments) {
037    for (Object argument : arguments) {
038      addArgument(ExpressionStatement.of(argument));
039    }
040    return this;
041  }
042
043  public List<ExpressionStatement> getArguments() {
044    return Collections.unmodifiableList(arguments);
045  }
046
047  public int getArity() {
048    return arguments.size();
049  }
050
051  public boolean usesNamedArguments() {
052    return usesNamedArguments;
053  }
054
055  public boolean namedArgumentsComplete() {
056    return this.arguments.isEmpty() || this.usesNamedArguments;
057  }
058
059  public AbstractInvocation withNamedArguments() {
060    setUsesNamedArguments(true);
061    return this;
062  }
063
064  private void setUsesNamedArguments(boolean usesNamedArguments) {
065    this.usesNamedArguments = usesNamedArguments;
066  }
067
068  @Override
069  public void walk(GoloIrVisitor visitor) {
070    for (ExpressionStatement arg : arguments) {
071      arg.accept(visitor);
072    }
073  }
074
075  @Override
076  protected void replaceElement(GoloElement original, GoloElement newElement) {
077    if (newElement instanceof ExpressionStatement && arguments.contains(original)) {
078      this.arguments.set(arguments.indexOf((ExpressionStatement) original),
079          (ExpressionStatement) newElement);
080    } else {
081      throw cantReplace(original, newElement);
082    }
083  }
084}