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 org.jetbrains.annotations.NotNull;
009    
010    /**
011     * Represents a JavaScript catch clause.
012     */
013    public class JsCatch extends SourceInfoAwareJsNode implements HasCondition {
014    
015        protected final JsCatchScope scope;
016        private JsBlock body;
017        private JsExpression condition;
018        private JsParameter param;
019    
020        public JsCatch(JsScope parent, @NotNull String ident) {
021            super();
022            assert (parent != null);
023            scope = new JsCatchScope(parent, ident);
024            param = new JsParameter(scope.findName(ident));
025        }
026    
027        public JsCatch(JsScope parent, @NotNull String ident, @NotNull JsStatement catchBody) {
028            this(parent, ident);
029            if (catchBody instanceof JsBlock) {
030                body = (JsBlock) catchBody;
031            } else {
032                body = new JsBlock(catchBody);
033            }
034        }
035    
036        public JsBlock getBody() {
037            return body;
038        }
039    
040        @Override
041        public JsExpression getCondition() {
042            return condition;
043        }
044    
045        public JsParameter getParameter() {
046            return param;
047        }
048    
049        public JsScope getScope() {
050            return scope;
051        }
052    
053        public void setBody(JsBlock body) {
054            this.body = body;
055        }
056    
057        @Override
058        public void setCondition(JsExpression condition) {
059            this.condition = condition;
060        }
061    
062        @Override
063        public void accept(JsVisitor v) {
064            v.visitCatch(this);
065        }
066    
067        @Override
068        public void acceptChildren(JsVisitor visitor) {
069            visitor.accept(param);
070            if (condition != null) {
071                visitor.accept(condition);
072            }
073            visitor.accept(body);
074        }
075    
076        @Override
077        public void traverse(JsVisitorWithContext v, JsContext ctx) {
078            if (v.visit(this, ctx)) {
079                param = v.accept(param);
080                if (condition != null) {
081                    condition = v.accept(condition);
082                }
083                body = v.accept(body);
084            }
085            v.endVisit(this, ctx);
086        }
087    
088        @NotNull
089        @Override
090        public JsCatch deepCopy() {
091            JsCatchScope scopeCopy = scope.copy();
092            JsBlock bodyCopy = AstUtil.deepCopy(body);
093            JsExpression conditionCopy = AstUtil.deepCopy(condition);
094            JsParameter paramCopy = AstUtil.deepCopy(param);
095    
096            return new JsCatch(scopeCopy, bodyCopy, conditionCopy, paramCopy).withMetadataFrom(this);
097        }
098    
099        private JsCatch(JsCatchScope scope, JsBlock body, JsExpression condition, JsParameter param) {
100            this.scope = scope;
101            this.body = body;
102            this.condition = condition;
103            this.param = param;
104        }
105    }