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.math.BigInteger;
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: /**
023: * A JavaScript program.
024: */
025: public final class JsProgram extends JsNode<JsProgram> {
026:
027: private final JsStatement debuggerStmt = new JsDebugger();
028:
029: private final Map<String, JsDecimalLiteral> decimalLiteralMap = new HashMap<String, JsDecimalLiteral>();
030:
031: private final JsEmpty emptyStmt = new JsEmpty();
032:
033: private final JsBooleanLiteral falseLiteral = new JsBooleanLiteral(
034: false);
035:
036: private final JsGlobalBlock globalBlock;
037:
038: private final Map<BigInteger, JsIntegralLiteral> integralLiteralMap = new HashMap<BigInteger, JsIntegralLiteral>();
039:
040: private final JsNullLiteral nullLiteral = new JsNullLiteral();
041:
042: private final JsScope objectScope;
043:
044: private final JsRootScope rootScope;
045:
046: private final Map<String, JsStringLiteral> stringLiteralMap = new HashMap<String, JsStringLiteral>();
047:
048: private final JsScope topScope;
049:
050: private final JsBooleanLiteral trueLiteral = new JsBooleanLiteral(
051: true);
052:
053: /**
054: * Constructs a JavaScript program object.
055: */
056: public JsProgram() {
057: rootScope = new JsRootScope(this );
058: globalBlock = new JsGlobalBlock();
059: topScope = new JsScope(rootScope, "Global");
060: objectScope = new JsScope(rootScope, "Object");
061: }
062:
063: /**
064: * Gets the {@link JsStatement} to use whenever parsed source include a
065: * <code>debugger</code> statement.
066: *
067: * @see #setDebuggerStmt(JsStatement)
068: */
069: public JsStatement getDebuggerStmt() {
070: return debuggerStmt;
071: }
072:
073: public JsDecimalLiteral getDecimalLiteral(String value) {
074: JsDecimalLiteral lit = decimalLiteralMap.get(value);
075: if (lit == null) {
076: lit = new JsDecimalLiteral(value);
077: decimalLiteralMap.put(value, lit);
078: }
079: return lit;
080: }
081:
082: public JsEmpty getEmptyStmt() {
083: return emptyStmt;
084: }
085:
086: public JsBooleanLiteral getFalseLiteral() {
087: return falseLiteral;
088: }
089:
090: /**
091: * Gets the one and only global block.
092: */
093: public JsBlock getGlobalBlock() {
094: return globalBlock;
095: }
096:
097: public JsIntegralLiteral getIntegralLiteral(BigInteger value) {
098: JsIntegralLiteral lit = integralLiteralMap.get(value);
099: if (lit == null) {
100: lit = new JsIntegralLiteral(value);
101: integralLiteralMap.put(value, lit);
102: }
103: return lit;
104: }
105:
106: public JsNullLiteral getNullLiteral() {
107: return nullLiteral;
108: }
109:
110: public JsScope getObjectScope() {
111: return objectScope;
112: }
113:
114: /**
115: * Gets the quasi-mythical root scope. This is not the same as the top scope;
116: * all unresolvable identifiers wind up here, because they are considered
117: * external to the program.
118: */
119: public JsRootScope getRootScope() {
120: return rootScope;
121: }
122:
123: /**
124: * Gets the top level scope. This is the scope of all the statements in the
125: * main program.
126: */
127: public JsScope getScope() {
128: return topScope;
129: }
130:
131: public JsStringLiteral getStringLiteral(String value) {
132: JsStringLiteral lit = stringLiteralMap.get(value);
133: if (lit == null) {
134: lit = new JsStringLiteral(value);
135: stringLiteralMap.put(value, lit);
136: }
137: return lit;
138: }
139:
140: public JsBooleanLiteral getTrueLiteral() {
141: return trueLiteral;
142: }
143:
144: public JsNameRef getUndefinedLiteral() {
145: return rootScope.findExistingName("undefined").makeRef();
146: }
147:
148: public void traverse(JsVisitor v, JsContext<JsProgram> ctx) {
149: if (v.visit(this, ctx)) {
150: v.accept(globalBlock);
151: }
152: v.endVisit(this, ctx);
153: }
154: }
|