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 org.eclipse.golo.compiler.parser.GoloASTNode;
013import java.util.Objects;
014
015public class TryCatchFinally extends GoloStatement {
016
017  private final String exceptionId;
018  private Block tryBlock;
019  private Block catchBlock;
020  private Block finallyBlock;
021
022  TryCatchFinally(String exceptionId) {
023    super();
024    this.exceptionId = exceptionId;
025  }
026
027  @Override
028  public TryCatchFinally ofAST(GoloASTNode node) {
029    super.ofAST(node);
030    return this;
031  }
032
033  public String getExceptionId() {
034    return exceptionId;
035  }
036
037  public Block getTryBlock() {
038    return tryBlock;
039  }
040
041  public TryCatchFinally trying(Object block) {
042    tryBlock = (Block) block;
043    makeParentOf(tryBlock);
044    return this;
045  }
046
047  public Block getCatchBlock() {
048    return catchBlock;
049  }
050
051  public TryCatchFinally catching(Object block) {
052    catchBlock = (Block) block;
053    makeParentOf(catchBlock);
054    catchBlock.getReferenceTable().add(Builders.localRef(exceptionId).synthetic());
055    return this;
056  }
057
058  public Block getFinallyBlock() {
059    return finallyBlock;
060  }
061
062  public TryCatchFinally finalizing(Object block) {
063    finallyBlock = (Block) block;
064    makeParentOf(finallyBlock);
065    return this;
066  }
067
068  public boolean hasFinallyBlock() {
069    return finallyBlock != null;
070  }
071
072  public boolean hasCatchBlock() {
073    return catchBlock != null;
074  }
075
076  public boolean isTryCatchFinally() {
077    return hasCatchBlock() && hasFinallyBlock();
078  }
079
080  public boolean isTryCatch() {
081    return hasCatchBlock() && !hasFinallyBlock();
082  }
083
084  public boolean isTryFinally() {
085    return !hasCatchBlock() && hasFinallyBlock();
086  }
087
088  @Override
089  public void accept(GoloIrVisitor visitor) {
090    visitor.visitTryCatchFinally(this);
091  }
092
093  @Override
094  public void walk(GoloIrVisitor visitor) {
095    tryBlock.accept(visitor);
096    if (catchBlock != null) {
097      catchBlock.accept(visitor);
098    }
099    if (finallyBlock != null) {
100      finallyBlock.accept(visitor);
101    }
102  }
103
104  @Override
105  protected void replaceElement(GoloElement original, GoloElement newElement) {
106    if (Objects.equals(original, tryBlock)) {
107      trying(newElement);
108    } else if (Objects.equals(original, catchBlock)) {
109      catching(newElement);
110    } else if (Objects.equals(original, finallyBlock)) {
111      finalizing(newElement);
112    } else {
113      throw cantReplace(original, newElement);
114    }
115  }
116}