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}