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.common.Symbol;
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    public final class JsFunction extends JsLiteral implements HasName {
015        @NotNull
016        private JsBlock body;
017        private List<JsParameter> params;
018        @NotNull
019        private final JsScope scope;
020        private JsName name;
021    
022        public JsFunction(JsScope parentScope) {
023            this(parentScope, (JsName) null);
024        }
025    
026        public JsFunction(JsScope parentScope, @NotNull JsBlock body) {
027            this(parentScope, (JsName) null);
028            this.body = body;
029        }
030    
031        private JsFunction(JsScope parentScope, @Nullable JsName name) {
032            this.name = name;
033            scope = new JsScope(parentScope, name == null ? null : name.getIdent());
034        }
035    
036        @NotNull
037        public JsBlock getBody() {
038            return body;
039        }
040    
041        @Override
042        public JsName getName() {
043            return name;
044        }
045    
046        @Override
047        public Symbol getSymbol() {
048            return name;
049        }
050    
051        @NotNull
052        public List<JsParameter> getParameters() {
053            if (params == null) {
054                params = new SmartList<JsParameter>();
055            }
056            return params;
057        }
058    
059        @NotNull
060        public JsScope getScope() {
061            return scope;
062        }
063    
064        public void setBody(@NotNull JsBlock body) {
065            this.body = body;
066        }
067    
068        public void setName(@Nullable JsName name) {
069            this.name = name;
070        }
071    
072        @Override
073        public void accept(JsVisitor v) {
074            v.visitFunction(this);
075        }
076    
077        @Override
078        public void acceptChildren(JsVisitor visitor) {
079            visitor.acceptWithInsertRemove(params);
080            visitor.accept(body);
081        }
082    }