1 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.JArrayRef; 20 import com.google.gwt.dev.jjs.ast.JBinaryOperation; 21 import com.google.gwt.dev.jjs.ast.JCastOperation; 22 import com.google.gwt.dev.jjs.ast.JConditional; 23 import com.google.gwt.dev.jjs.ast.JExpression; 24 import com.google.gwt.dev.jjs.ast.JLocalDeclarationStatement; 25 import com.google.gwt.dev.jjs.ast.JMethod; 26 import com.google.gwt.dev.jjs.ast.JMethodCall; 27 import com.google.gwt.dev.jjs.ast.JModVisitor; 28 import com.google.gwt.dev.jjs.ast.JParameter; 29 import com.google.gwt.dev.jjs.ast.JProgram; 30 import com.google.gwt.dev.jjs.ast.JReferenceType; 31 import com.google.gwt.dev.jjs.ast.JReturnStatement; 32 import com.google.gwt.dev.jjs.ast.JType; 33 34 38 public class JavaScriptObjectCaster { 39 40 43 private class AssignmentVisitor extends JModVisitor { 44 45 private JMethod currentMethod; 46 47 public void endVisit(JBinaryOperation x, Context ctx) { 49 if (x.isAssignment()) { 50 JType lhsType = x.getLhs().getType(); 51 JExpression newRhs = checkAndReplaceJso(x.getRhs(), lhsType); 52 if (newRhs == x.getRhs()) { 53 if (x.getLhs() instanceof JArrayRef) { 56 newRhs = checkAndReplaceJsoArrayStore(newRhs, lhsType); 57 } 58 } 59 if (newRhs != x.getRhs()) { 60 JBinaryOperation asg = new JBinaryOperation(program, 61 x.getSourceInfo(), lhsType, x.getOp(), x.getLhs(), newRhs); 62 ctx.replaceMe(asg); 63 } 64 } 65 } 66 67 public void endVisit(JConditional x, Context ctx) { 69 JExpression newThen = checkAndReplaceJso(x.getThenExpr(), x.getType()); 70 JExpression newElse = checkAndReplaceJso(x.getElseExpr(), x.getType()); 71 if (newThen != x.getThenExpr() || newElse != x.getElseExpr()) { 72 JConditional newCond = new JConditional(program, x.getSourceInfo(), 73 x.getType(), x.getIfTest(), newThen, newElse); 74 ctx.replaceMe(newCond); 75 } 76 } 77 78 public void endVisit(JLocalDeclarationStatement x, Context ctx) { 80 JExpression newInst = x.getInitializer(); 81 if (newInst != null) { 82 newInst = checkAndReplaceJso(newInst, x.getLocalRef().getType()); 83 if (newInst != x.getInitializer()) { 84 JLocalDeclarationStatement newStmt = new JLocalDeclarationStatement( 85 program, x.getSourceInfo(), x.getLocalRef(), newInst); 86 ctx.replaceMe(newStmt); 87 } 88 } 89 } 90 91 public void endVisit(JMethod x, Context ctx) { 93 currentMethod = null; 94 } 95 96 public void endVisit(JMethodCall x, Context ctx) { 98 for (int i = 0; i < x.getTarget().params.size(); ++i) { 99 JParameter param = (JParameter) x.getTarget().params.get(i); 100 JExpression newArg = checkAndReplaceJso( 101 (JExpression) x.getArgs().get(i), param.getType()); 102 x.getArgs().set(i, newArg); 103 } 104 if (!x.getTarget().isStatic()) { 105 JExpression newInst = checkAndReplaceJso(x.getInstance(), 107 program.getTypeJavaLangObject()); 108 if (newInst != x.getInstance()) { 109 JMethodCall newCall = new JMethodCall(program, x.getSourceInfo(), 110 newInst, x.getTarget(), x.isStaticDispatchOnly()); 111 newCall.getArgs().addAll(x.getArgs()); 112 ctx.replaceMe(newCall); 113 } 114 } 115 } 116 117 public void endVisit(JReturnStatement x, Context ctx) { 119 if (x.getExpr() != null) { 120 JExpression newExpr = checkAndReplaceJso(x.getExpr(), 121 currentMethod.getType()); 122 if (newExpr != x.getExpr()) { 123 JReturnStatement newStmt = new JReturnStatement(program, 124 x.getSourceInfo(), newExpr); 125 ctx.replaceMe(newStmt); 126 } 127 } 128 } 129 130 public boolean visit(JMethod x, Context ctx) { 132 currentMethod = x; 133 return true; 134 } 135 136 139 private JExpression checkAndReplaceJso(JExpression arg, JType targetType) { 140 JType argType = arg.getType(); 141 if (argType == targetType) { 142 return arg; 143 } 144 if (!(targetType instanceof JReferenceType)) { 145 return arg; 146 } 147 if (!program.isJavaScriptObject(argType)) { 148 return arg; 149 } 150 JCastOperation cast = new JCastOperation(program, arg.getSourceInfo(), 152 argType, arg); 153 return cast; 154 } 155 156 160 private JExpression checkAndReplaceJsoArrayStore(JExpression arg, 161 JType targetType) { 162 if (!(targetType instanceof JReferenceType)) { 163 return arg; 164 } 165 if (((JReferenceType) targetType).isFinal()) { 166 return arg; 167 } 168 if (!program.isJavaScriptObject(arg.getType())) { 169 return arg; 170 } 171 JCastOperation cast = new JCastOperation(program, arg.getSourceInfo(), 173 targetType, arg); 174 return cast; 175 } 176 } 177 178 public static void exec(JProgram program) { 179 new JavaScriptObjectCaster(program).execImpl(); 180 } 181 182 private final JProgram program; 183 184 private JavaScriptObjectCaster(JProgram program) { 185 this.program = program; 186 } 187 188 private void execImpl() { 189 AssignmentVisitor visitor = new AssignmentVisitor(); 190 visitor.accept(program); 191 } 192 193 } 194 | Popular Tags |