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.LinkedHashSet;
013import java.util.Set;
014import java.util.Collections;
015
016public class ClosureReference extends ExpressionStatement {
017
018  private GoloFunction target;
019  private final Set<String> capturedReferenceNames = new LinkedHashSet<>();
020
021  ClosureReference(GoloFunction target) {
022    super();
023    setTarget(target);
024  }
025
026  public GoloFunction getTarget() {
027    return target;
028  }
029
030  private void setTarget(GoloFunction target) {
031    this.target = target;
032    makeParentOf(target);
033    this.setASTNode(target.getASTNode());
034    updateCapturedReferenceNames();
035  }
036
037  public Set<String> getCapturedReferenceNames() {
038    return Collections.unmodifiableSet(capturedReferenceNames);
039  }
040
041  public void updateCapturedReferenceNames() {
042    for (String name : target.getSyntheticParameterNames()) {
043      capturedReferenceNames.add(name);
044    }
045  }
046
047  public ClosureReference block(Object... statements) {
048    this.target.block(statements);
049    return this;
050  }
051
052  public ClosureReference returns(Object expression) {
053    this.target.returns(expression);
054    return this;
055  }
056
057  @Override
058  public void accept(GoloIrVisitor visitor) {
059    visitor.visitClosureReference(this);
060  }
061
062  @Override
063  public void walk(GoloIrVisitor visitor) {
064    target.accept(visitor);
065  }
066
067  @Override
068  protected void replaceElement(GoloElement original, GoloElement newElement) {
069    if (newElement instanceof GoloFunction && target.equals(original)) {
070      setTarget((GoloFunction) newElement);
071    } else {
072      throw cantReplace(original, newElement);
073    }
074  }
075}