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.jjs.impl;
017:
018: import com.google.gwt.dev.jjs.InternalCompilerException;
019: import com.google.gwt.dev.jjs.ast.Context;
020: import com.google.gwt.dev.jjs.ast.JAbsentArrayDimension;
021: import com.google.gwt.dev.jjs.ast.JArrayRef;
022: import com.google.gwt.dev.jjs.ast.JBinaryOperation;
023: import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
024: import com.google.gwt.dev.jjs.ast.JCastOperation;
025: import com.google.gwt.dev.jjs.ast.JCharLiteral;
026: import com.google.gwt.dev.jjs.ast.JClassLiteral;
027: import com.google.gwt.dev.jjs.ast.JConditional;
028: import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
029: import com.google.gwt.dev.jjs.ast.JExpression;
030: import com.google.gwt.dev.jjs.ast.JFieldRef;
031: import com.google.gwt.dev.jjs.ast.JFloatLiteral;
032: import com.google.gwt.dev.jjs.ast.JInstanceOf;
033: import com.google.gwt.dev.jjs.ast.JIntLiteral;
034: import com.google.gwt.dev.jjs.ast.JLocalRef;
035: import com.google.gwt.dev.jjs.ast.JLongLiteral;
036: import com.google.gwt.dev.jjs.ast.JMethodCall;
037: import com.google.gwt.dev.jjs.ast.JNewArray;
038: import com.google.gwt.dev.jjs.ast.JNewInstance;
039: import com.google.gwt.dev.jjs.ast.JNullLiteral;
040: import com.google.gwt.dev.jjs.ast.JParameterRef;
041: import com.google.gwt.dev.jjs.ast.JPostfixOperation;
042: import com.google.gwt.dev.jjs.ast.JPrefixOperation;
043: import com.google.gwt.dev.jjs.ast.JProgram;
044: import com.google.gwt.dev.jjs.ast.JStringLiteral;
045: import com.google.gwt.dev.jjs.ast.JThisRef;
046: import com.google.gwt.dev.jjs.ast.JVisitor;
047: import com.google.gwt.dev.jjs.ast.js.JClassSeed;
048: import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
049:
050: import java.util.ArrayList;
051:
052: /**
053: * A general purpose expression cloner.
054: */
055: public class CloneExpressionVisitor extends JVisitor {
056: private JExpression expression;
057: private JProgram program;
058:
059: public CloneExpressionVisitor(JProgram program) {
060: this .program = program;
061: }
062:
063: public JExpression cloneExpression(JExpression expr) {
064: if (expr == null) {
065: return null;
066: }
067:
068: this .accept(expr);
069:
070: if (expression == null) {
071: throw new InternalCompilerException(expr,
072: "Unable to clone expression", null);
073: }
074:
075: return expression;
076: }
077:
078: @Override
079: public boolean visit(JAbsentArrayDimension x, Context ctx) {
080: expression = x;
081: return false;
082: }
083:
084: @Override
085: public boolean visit(JArrayRef x, Context ctx) {
086: expression = new JArrayRef(program, x.getSourceInfo(),
087: cloneExpression(x.getInstance()), cloneExpression(x
088: .getIndexExpr()));
089: return false;
090: }
091:
092: @Override
093: public boolean visit(JBinaryOperation x, Context ctx) {
094: expression = new JBinaryOperation(program, x.getSourceInfo(), x
095: .getType(), x.getOp(), cloneExpression(x.getLhs()),
096: cloneExpression(x.getRhs()));
097: return false;
098: }
099:
100: @Override
101: public boolean visit(JBooleanLiteral x, Context ctx) {
102: expression = x;
103: return false;
104: }
105:
106: @Override
107: public boolean visit(JCastOperation x, Context ctx) {
108: expression = new JCastOperation(program, x.getSourceInfo(), x
109: .getCastType(), cloneExpression(x.getExpr()));
110: return false;
111: }
112:
113: @Override
114: public boolean visit(JCharLiteral x, Context ctx) {
115: expression = x;
116: return false;
117: }
118:
119: @Override
120: public boolean visit(JClassLiteral x, Context ctx) {
121: expression = x;
122: return false;
123: }
124:
125: @Override
126: public boolean visit(JClassSeed x, Context ctx) {
127: expression = new JClassSeed(program, x.getRefType());
128: return false;
129: }
130:
131: @Override
132: public boolean visit(JConditional x, Context ctx) {
133: expression = new JConditional(program, x.getSourceInfo(), x
134: .getType(), cloneExpression(x.getIfTest()),
135: cloneExpression(x.getThenExpr()), cloneExpression(x
136: .getElseExpr()));
137: return false;
138: }
139:
140: @Override
141: public boolean visit(JDoubleLiteral x, Context ctx) {
142: expression = x;
143: return false;
144: }
145:
146: @Override
147: public boolean visit(JFieldRef x, Context ctx) {
148: expression = new JFieldRef(program, x.getSourceInfo(),
149: cloneExpression(x.getInstance()), x.getField(), x
150: .getEnclosingType());
151: return false;
152: }
153:
154: @Override
155: public boolean visit(JFloatLiteral x, Context ctx) {
156: expression = x;
157: return false;
158: }
159:
160: @Override
161: public boolean visit(JInstanceOf x, Context ctx) {
162: expression = new JInstanceOf(program, x.getSourceInfo(), x
163: .getTestType(), cloneExpression(x.getExpr()));
164: return false;
165: }
166:
167: @Override
168: public boolean visit(JIntLiteral x, Context ctx) {
169: expression = x;
170: return false;
171: }
172:
173: @Override
174: public boolean visit(JLocalRef x, Context ctx) {
175: expression = new JLocalRef(program, x.getSourceInfo(), x
176: .getLocal());
177: return false;
178: }
179:
180: @Override
181: public boolean visit(JLongLiteral x, Context ctx) {
182: expression = x;
183: return false;
184: }
185:
186: @Override
187: public boolean visit(JMethodCall x, Context ctx) {
188: JMethodCall newMethodCall = new JMethodCall(program, x
189: .getSourceInfo(), cloneExpression(x.getInstance()), x
190: .getTarget());
191:
192: for (JExpression arg : x.getArgs()) {
193: newMethodCall.getArgs().add(cloneExpression(arg));
194: }
195:
196: expression = newMethodCall;
197: return false;
198: }
199:
200: @Override
201: public boolean visit(JMultiExpression x, Context ctx) {
202: JMultiExpression multi = new JMultiExpression(program, x
203: .getSourceInfo());
204: for (JExpression expr : x.exprs) {
205: multi.exprs.add(cloneExpression(expr));
206: }
207:
208: expression = multi;
209: return false;
210: }
211:
212: @Override
213: public boolean visit(JNewArray x, Context ctx) {
214: JNewArray newArray = new JNewArray(program, x.getSourceInfo(),
215: x.getArrayType());
216:
217: if (x.dims != null) {
218: newArray.dims = new ArrayList<JExpression>();
219: for (JExpression dim : x.dims) {
220: newArray.dims.add(cloneExpression(dim));
221: }
222: }
223: if (x.initializers != null) {
224: newArray.initializers = new ArrayList<JExpression>();
225: for (JExpression initializer : x.initializers) {
226: newArray.initializers.add(cloneExpression(initializer));
227: }
228: }
229:
230: expression = newArray;
231: return false;
232: }
233:
234: @Override
235: public boolean visit(JNewInstance x, Context ctx) {
236: expression = new JNewInstance(program, x.getSourceInfo(), x
237: .getClassType());
238: return false;
239: }
240:
241: @Override
242: public boolean visit(JNullLiteral x, Context ctx) {
243: expression = x;
244: return false;
245: }
246:
247: @Override
248: public boolean visit(JParameterRef x, Context ctx) {
249: expression = new JParameterRef(program, x.getSourceInfo(), x
250: .getParameter());
251: return false;
252: }
253:
254: @Override
255: public boolean visit(JPostfixOperation x, Context ctx) {
256: expression = new JPostfixOperation(program, x.getSourceInfo(),
257: x.getOp(), cloneExpression(x.getArg()));
258: return false;
259: }
260:
261: @Override
262: public boolean visit(JPrefixOperation x, Context ctx) {
263: expression = new JPrefixOperation(program, x.getSourceInfo(), x
264: .getOp(), cloneExpression(x.getArg()));
265: return false;
266: }
267:
268: @Override
269: public boolean visit(JStringLiteral x, Context ctx) {
270: expression = x;
271: return false;
272: }
273:
274: @Override
275: public boolean visit(JThisRef x, Context ctx) {
276: expression = program.getExprThisRef(x.getSourceInfo(), x
277: .getClassType());
278: return false;
279: }
280: }
|