001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.js.ast;
017:
018: import java.util.ArrayList;
019: import java.util.List;
020:
021: /**
022: * Represents a JavaScript function expression.
023: */
024: public class JsFunction extends JsExpression implements HasName {
025:
026: protected JsBlock body;
027: protected final List<JsParameter> params = new ArrayList<JsParameter>();
028: protected final JsScope scope;
029: private boolean executeOnce;
030: private boolean fromJava;
031: private JsFunction impliedExecute;
032: private JsName name;
033:
034: /**
035: * Creates an anonymous function.
036: */
037: public JsFunction(JsScope parent) {
038: this (parent, null, false);
039: }
040:
041: /**
042: * Creates a function that is not derived from Java source.
043: */
044: public JsFunction(JsScope parent, JsName name) {
045: this (parent, name, false);
046: }
047:
048: /**
049: * Creates a named function, possibly derived from Java source.
050: */
051: public JsFunction(JsScope parent, JsName name, boolean fromJava) {
052: assert (parent != null);
053: this .fromJava = fromJava;
054: setName(name);
055: String scopeName = (name == null) ? "<anonymous>" : name
056: .getIdent();
057: scopeName = "function " + scopeName;
058: this .scope = new JsScope(parent, scopeName);
059: }
060:
061: public JsBlock getBody() {
062: return body;
063: }
064:
065: /**
066: * If true, this indicates that only the first invocation of the function will
067: * have any effects. Subsequent invocations may be considered to be no-op
068: * calls whose return value is ignored.
069: */
070: public boolean getExecuteOnce() {
071: return executeOnce;
072: }
073:
074: public JsFunction getImpliedExecute() {
075: return impliedExecute;
076: }
077:
078: public JsName getName() {
079: return name;
080: }
081:
082: public List<JsParameter> getParameters() {
083: return params;
084: }
085:
086: public JsScope getScope() {
087: return scope;
088: }
089:
090: public boolean isFromJava() {
091: return fromJava;
092: }
093:
094: public void setBody(JsBlock body) {
095: this .body = body;
096: }
097:
098: public void setExecuteOnce(boolean executeOnce) {
099: this .executeOnce = executeOnce;
100: }
101:
102: public void setFromJava(boolean fromJava) {
103: this .fromJava = fromJava;
104: }
105:
106: public void setImpliedExecute(JsFunction impliedExecute) {
107: this .impliedExecute = impliedExecute;
108: }
109:
110: public void setName(JsName name) {
111: this .name = name;
112: if (name != null) {
113: if (isFromJava()) {
114: name.setStaticRef(this );
115: }
116: }
117: }
118:
119: public void traverse(JsVisitor v, JsContext<JsExpression> ctx) {
120: if (v.visit(this, ctx)) {
121: v.acceptWithInsertRemove(params);
122: body = v.accept(body);
123: }
124: v.endVisit(this, ctx);
125: }
126: }
|