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.google.dart.compiler.util.AstUtil; 009 import com.intellij.util.SmartList; 010 import org.jetbrains.annotations.NotNull; 011 import org.jetbrains.annotations.Nullable; 012 013 import java.util.List; 014 015 public final class JsFunction extends JsLiteral implements HasName { 016 @NotNull 017 private JsBlock body; 018 private List<JsParameter> params; 019 @NotNull 020 private final JsFunctionScope scope; 021 private JsName name; 022 023 public JsFunction(@NotNull JsScope parentScope, @NotNull String description) { 024 this(parentScope, description, null); 025 } 026 027 public JsFunction(@NotNull JsScope parentScope, @NotNull JsBlock body, @NotNull String description) { 028 this(parentScope, description, null); 029 this.body = body; 030 } 031 032 private JsFunction(@NotNull JsScope parentScope, @NotNull String description, @Nullable JsName name) { 033 this.name = name; 034 scope = new JsFunctionScope(parentScope, name == null ? description : name.getIdent()); 035 } 036 037 @NotNull 038 public JsBlock getBody() { 039 return body; 040 } 041 042 @Override 043 public JsName getName() { 044 return name; 045 } 046 047 @Override 048 public Symbol getSymbol() { 049 return name; 050 } 051 052 @NotNull 053 public List<JsParameter> getParameters() { 054 if (params == null) { 055 params = new SmartList<JsParameter>(); 056 } 057 return params; 058 } 059 060 @NotNull 061 public JsFunctionScope getScope() { 062 return scope; 063 } 064 065 public void setBody(@NotNull JsBlock body) { 066 this.body = body; 067 } 068 069 public void setName(@Nullable JsName name) { 070 this.name = name; 071 } 072 073 @Override 074 public void accept(JsVisitor v) { 075 v.visitFunction(this); 076 } 077 078 @Override 079 public void acceptChildren(JsVisitor visitor) { 080 visitor.acceptWithInsertRemove(getParameters()); 081 visitor.accept(body); 082 } 083 084 @Override 085 public void traverse(JsVisitorWithContext v, JsContext ctx) { 086 if (v.visit(this, ctx)) { 087 v.acceptList(getParameters()); 088 body = v.acceptStatement(body); 089 } 090 v.endVisit(this, ctx); 091 } 092 093 @NotNull 094 @Override 095 public JsFunction deepCopy() { 096 JsFunction functionCopy = new JsFunction(scope.getParent(), scope.getDescription(), name); 097 functionCopy.getScope().copyOwnNames(scope); 098 functionCopy.setBody(body.deepCopy()); 099 functionCopy.params = AstUtil.deepCopy(params); 100 101 return functionCopy.withMetadataFrom(this); 102 } 103 }