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.JArrayType; 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.JInterfaceType; 23 import com.google.gwt.dev.jjs.ast.JMethod; 24 import com.google.gwt.dev.jjs.ast.JMethodCall; 25 import com.google.gwt.dev.jjs.ast.JModVisitor; 26 import com.google.gwt.dev.jjs.ast.JNullType; 27 import com.google.gwt.dev.jjs.ast.JProgram; 28 import com.google.gwt.dev.jjs.ast.JReferenceType; 29 import com.google.gwt.dev.jjs.ast.JType; 30 31 39 public class MethodCallTightener { 40 41 45 public class MethodCallTighteningVisitor extends JModVisitor { 46 47 public void endVisit(JMethodCall x, Context ctx) { 49 JMethod method = x.getTarget(); 50 JExpression instance = x.getInstance(); 51 52 if (!x.canBePolymorphic()) { 54 return; 55 } 56 57 JType instanceType = instance.getType(); 58 JReferenceType enclosingType = method.getEnclosingType(); 59 60 if (instanceType == enclosingType 61 || instanceType instanceof JInterfaceType) { 62 return; 65 } 66 67 if (instanceType instanceof JArrayType) { 68 return; 70 } 71 72 if (instanceType instanceof JNullType) { 73 return; 75 } 76 77 assert (instanceType instanceof JClassType); 78 79 83 JMethod foundMethod = null; 84 JClassType type; 85 outer : for (type = (JClassType) instanceType; type != null 86 && type != enclosingType; type = type.extnds) { 87 for (int i = 0; i < type.methods.size(); ++i) { 88 JMethod methodIt = (JMethod) type.methods.get(i); 89 if (JProgram.methodsDoMatch(method, methodIt)) { 90 foundMethod = methodIt; 91 break outer; 92 } 93 } 94 } 95 96 if (foundMethod == null) { 97 return; 98 } 99 100 104 JMethodCall call = new JMethodCall(program, x.getSourceInfo(), 105 x.getInstance(), foundMethod); 106 call.getArgs().addAll(x.getArgs()); 107 ctx.replaceMe(call); 108 } 109 } 110 111 public static boolean exec(JProgram program) { 112 return new MethodCallTightener(program).execImpl(); 113 } 114 115 private final JProgram program; 116 117 private MethodCallTightener(JProgram program) { 118 this.program = program; 119 } 120 121 private boolean execImpl() { 122 MethodCallTighteningVisitor tightener = new MethodCallTighteningVisitor(); 123 tightener.accept(program); 124 return tightener.didChange(); 125 } 126 127 } 128 | Popular Tags |