01: /*
02: * Copyright 2007 Google Inc.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
05: * use this file except in compliance with the License. You may obtain a copy of
06: * the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13: * License for the specific language governing permissions and limitations under
14: * the License.
15: */
16: package com.google.gwt.dev.jjs.impl;
17:
18: import com.google.gwt.dev.jjs.ast.Context;
19: import com.google.gwt.dev.jjs.ast.JClassLiteral;
20: import com.google.gwt.dev.jjs.ast.JClassType;
21: import com.google.gwt.dev.jjs.ast.JExpression;
22: import com.google.gwt.dev.jjs.ast.JMethod;
23: import com.google.gwt.dev.jjs.ast.JMethodCall;
24: import com.google.gwt.dev.jjs.ast.JModVisitor;
25: import com.google.gwt.dev.jjs.ast.JNewInstance;
26: import com.google.gwt.dev.jjs.ast.JProgram;
27:
28: /**
29: * Replaces any "GWT.create()" calls with a new expression for the actual result
30: * of the deferred binding decision.
31: */
32: public class ReplaceRebinds {
33:
34: private class RebindVisitor extends JModVisitor {
35:
36: // @Override
37: public void endVisit(JMethodCall x, Context ctx) {
38: JMethod method = x.getTarget();
39: if (method == program.getRebindCreateMethod()) {
40: assert (x.getArgs().size() == 1);
41: JExpression arg = (JExpression) x.getArgs().get(0);
42: assert (arg instanceof JClassLiteral);
43: JClassLiteral classLiteral = (JClassLiteral) arg;
44: JClassType classType = program.rebind(classLiteral
45: .getRefType());
46:
47: /*
48: * Find the appropriate (noArg) constructor. In our AST, constructors
49: * are instance methods that should be qualified with a new expression.
50: */
51: JMethod noArgCtor = null;
52: for (int i = 0; i < classType.methods.size(); ++i) {
53: JMethod ctor = (JMethod) classType.methods.get(i);
54: if (ctor.getName().equals(classType.getShortName())) {
55: if (ctor.params.size() == 0) {
56: noArgCtor = ctor;
57: }
58: }
59: }
60: assert (noArgCtor != null);
61: // Call it, using a new expression as a qualifier
62: JNewInstance newInstance = new JNewInstance(program, x
63: .getSourceInfo(), classType);
64: JMethodCall call = new JMethodCall(program, x
65: .getSourceInfo(), newInstance, noArgCtor);
66: ctx.replaceMe(call);
67: }
68: }
69: }
70:
71: public static boolean exec(JProgram program) {
72: return new ReplaceRebinds(program).execImpl();
73: }
74:
75: private final JProgram program;
76:
77: private ReplaceRebinds(JProgram program) {
78: this .program = program;
79: }
80:
81: private boolean execImpl() {
82: RebindVisitor rebinder = new RebindVisitor();
83: rebinder.accept(program);
84: return rebinder.didChange();
85: }
86:
87: }
|