001    // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
002    // for details. All rights reserved. Use of this source code is governed by a
003    // BSD-style license that can be found in the LICENSE file.
004    
005    package com.google.dart.compiler.backend.js.ast;
006    
007    import com.google.dart.compiler.util.AstUtil;
008    import com.intellij.util.SmartList;
009    import org.jetbrains.annotations.NotNull;
010    import org.jetbrains.annotations.Nullable;
011    
012    import java.util.List;
013    
014    /**
015     * A JavaScript <code>try</code> statement.
016     */
017    public class JsTry extends SourceInfoAwareJsNode implements JsStatement {
018        private final List<JsCatch> catches;
019        private JsBlock finallyBlock;
020        private JsBlock tryBlock;
021    
022        public JsTry() {
023            catches = new SmartList<JsCatch>();
024        }
025    
026        public JsTry(JsBlock tryBlock, List<JsCatch> catches, @Nullable JsBlock finallyBlock) {
027            this.tryBlock = tryBlock;
028            this.catches = catches;
029            this.finallyBlock = finallyBlock;
030        }
031    
032        public JsTry(JsBlock tryBlock, @Nullable JsCatch jsCatch, @Nullable JsBlock finallyBlock) {
033            this(tryBlock, new SmartList<JsCatch>(), finallyBlock);
034    
035            if (jsCatch != null) {
036                catches.add(jsCatch);
037            }
038        }
039    
040        public List<JsCatch> getCatches() {
041            return catches;
042        }
043    
044        public JsBlock getFinallyBlock() {
045            return finallyBlock;
046        }
047    
048        public JsBlock getTryBlock() {
049            return tryBlock;
050        }
051    
052        public void setFinallyBlock(JsBlock block) {
053            finallyBlock = block;
054        }
055    
056        public void setTryBlock(JsBlock block) {
057            tryBlock = block;
058        }
059    
060        @Override
061        public void accept(JsVisitor v) {
062            v.visitTry(this);
063        }
064    
065        @Override
066        public void acceptChildren(JsVisitor visitor) {
067            visitor.accept(tryBlock);
068            visitor.acceptWithInsertRemove(catches);
069            if (finallyBlock != null) {
070               visitor.accept(finallyBlock);
071            }
072        }
073    
074        @Override
075        public void traverse(JsVisitorWithContext v, JsContext ctx) {
076            if (v.visit(this, ctx)) {
077                tryBlock = v.accept(tryBlock);
078                v.acceptList(catches);
079                if (finallyBlock != null) {
080                    finallyBlock = v.accept(finallyBlock);
081                }
082            }
083            v.endVisit(this, ctx);
084        }
085    
086        @NotNull
087        @Override
088        public JsTry deepCopy() {
089            JsBlock tryCopy = AstUtil.deepCopy(tryBlock);
090            List<JsCatch> catchCopy = AstUtil.deepCopy(catches);
091            JsBlock finallyCopy = AstUtil.deepCopy(finallyBlock);
092    
093            return new JsTry(tryCopy, catchCopy, finallyCopy).withMetadataFrom(this);
094        }
095    }