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    public class JsForIn extends SourceInfoAwareJsNode implements JsStatement {
011        private JsStatement body;
012        private JsExpression iterExpression;
013        private JsExpression objectExpression;
014    
015        // Optional: the name of a new iterator variable to introduce
016        private final JsName iterVarName;
017    
018        public JsForIn() {
019            this(null);
020        }
021    
022        public JsForIn(JsName iterVarName) {
023            this.iterVarName = iterVarName;
024        }
025    
026        public JsForIn(JsName iterVarName, JsExpression iterExpression, JsExpression objectExpression, JsStatement body) {
027    
028            this.iterVarName = iterVarName;
029            this.iterExpression = iterExpression;
030            this.objectExpression = objectExpression;
031            this.body = body;
032        }
033    
034        public JsStatement getBody() {
035            return body;
036        }
037    
038        public JsExpression getIterExpression() {
039            return iterExpression;
040        }
041    
042        public JsName getIterVarName() {
043            return iterVarName;
044        }
045    
046        public JsExpression getObjectExpression() {
047            return objectExpression;
048        }
049    
050        public void setBody(JsStatement body) {
051            this.body = body;
052        }
053    
054        public void setIterExpression(JsExpression iterExpression) {
055            this.iterExpression = iterExpression;
056        }
057    
058        public void setObjectExpression(JsExpression objectExpression) {
059            this.objectExpression = objectExpression;
060        }
061    
062        @Override
063        public void accept(JsVisitor v) {
064            v.visitForIn(this);
065        }
066    
067        @Override
068        public void acceptChildren(JsVisitor visitor) {
069            if (iterExpression != null) {
070                visitor.acceptLvalue(iterExpression);
071            }
072            visitor.accept(objectExpression);
073            visitor.accept(body);
074        }
075    
076        @Override
077        public void traverse(JsVisitorWithContext v, JsContext ctx) {
078            if (v.visit(this, ctx)) {
079                if (iterExpression != null) {
080                    iterExpression = v.acceptLvalue(iterExpression);
081                }
082                objectExpression = v.accept(objectExpression);
083                body = v.acceptStatement(body);
084            }
085            v.endVisit(this, ctx);
086        }
087    
088        @NotNull
089        @Override
090        public JsForIn deepCopy() {
091            JsStatement bodyCopy = AstUtil.deepCopy(body);
092            JsExpression iterCopy = AstUtil.deepCopy(iterExpression);
093            JsExpression objectCopy = AstUtil.deepCopy(objectExpression);
094    
095            return new JsForIn(iterVarName, iterCopy, objectCopy, bodyCopy).withMetadataFrom(this);
096        }
097    }