1*f1fbf3c2SXin Li /* 2*f1fbf3c2SXin Li * Javassist, a Java-bytecode translator toolkit. 3*f1fbf3c2SXin Li * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. 4*f1fbf3c2SXin Li * 5*f1fbf3c2SXin Li * The contents of this file are subject to the Mozilla Public License Version 6*f1fbf3c2SXin Li * 1.1 (the "License"); you may not use this file except in compliance with 7*f1fbf3c2SXin Li * the License. Alternatively, the contents of this file may be used under 8*f1fbf3c2SXin Li * the terms of the GNU Lesser General Public License Version 2.1 or later, 9*f1fbf3c2SXin Li * or the Apache License Version 2.0. 10*f1fbf3c2SXin Li * 11*f1fbf3c2SXin Li * Software distributed under the License is distributed on an "AS IS" basis, 12*f1fbf3c2SXin Li * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13*f1fbf3c2SXin Li * for the specific language governing rights and limitations under the 14*f1fbf3c2SXin Li * License. 15*f1fbf3c2SXin Li */ 16*f1fbf3c2SXin Li 17*f1fbf3c2SXin Li package javassist; 18*f1fbf3c2SXin Li 19*f1fbf3c2SXin Li import javassist.bytecode.AccessFlag; 20*f1fbf3c2SXin Li import javassist.bytecode.BadBytecode; 21*f1fbf3c2SXin Li import javassist.bytecode.Bytecode; 22*f1fbf3c2SXin Li import javassist.bytecode.CodeAttribute; 23*f1fbf3c2SXin Li import javassist.bytecode.CodeIterator; 24*f1fbf3c2SXin Li import javassist.bytecode.ConstPool; 25*f1fbf3c2SXin Li import javassist.bytecode.Descriptor; 26*f1fbf3c2SXin Li import javassist.bytecode.MethodInfo; 27*f1fbf3c2SXin Li import javassist.bytecode.Opcode; 28*f1fbf3c2SXin Li 29*f1fbf3c2SXin Li /** 30*f1fbf3c2SXin Li * An instance of <code>CtMethod</code> represents a method. 31*f1fbf3c2SXin Li * 32*f1fbf3c2SXin Li * <p>See the super class <code>CtBehavior</code> since 33*f1fbf3c2SXin Li * a number of useful methods are in <code>CtBehavior</code>. 34*f1fbf3c2SXin Li * A number of useful factory methods are in <code>CtNewMethod</code>. 35*f1fbf3c2SXin Li * 36*f1fbf3c2SXin Li * @see CtClass#getDeclaredMethods() 37*f1fbf3c2SXin Li * @see CtNewMethod 38*f1fbf3c2SXin Li */ 39*f1fbf3c2SXin Li public final class CtMethod extends CtBehavior { 40*f1fbf3c2SXin Li protected String cachedStringRep; 41*f1fbf3c2SXin Li 42*f1fbf3c2SXin Li /** 43*f1fbf3c2SXin Li * @see #make(MethodInfo minfo, CtClass declaring) 44*f1fbf3c2SXin Li */ CtMethod(MethodInfo minfo, CtClass declaring)45*f1fbf3c2SXin Li CtMethod(MethodInfo minfo, CtClass declaring) { 46*f1fbf3c2SXin Li super(declaring, minfo); 47*f1fbf3c2SXin Li cachedStringRep = null; 48*f1fbf3c2SXin Li } 49*f1fbf3c2SXin Li 50*f1fbf3c2SXin Li /** 51*f1fbf3c2SXin Li * Creates a public abstract method. The created method must be 52*f1fbf3c2SXin Li * added to a class with <code>CtClass.addMethod()</code>. 53*f1fbf3c2SXin Li * 54*f1fbf3c2SXin Li * @param declaring the class to which the created method is added. 55*f1fbf3c2SXin Li * @param returnType the type of the returned value 56*f1fbf3c2SXin Li * @param mname the method name 57*f1fbf3c2SXin Li * @param parameters a list of the parameter types 58*f1fbf3c2SXin Li * 59*f1fbf3c2SXin Li * @see CtClass#addMethod(CtMethod) 60*f1fbf3c2SXin Li */ CtMethod(CtClass returnType, String mname, CtClass[] parameters, CtClass declaring)61*f1fbf3c2SXin Li public CtMethod(CtClass returnType, String mname, 62*f1fbf3c2SXin Li CtClass[] parameters, CtClass declaring) { 63*f1fbf3c2SXin Li this(null, declaring); 64*f1fbf3c2SXin Li ConstPool cp = declaring.getClassFile2().getConstPool(); 65*f1fbf3c2SXin Li String desc = Descriptor.ofMethod(returnType, parameters); 66*f1fbf3c2SXin Li methodInfo = new MethodInfo(cp, mname, desc); 67*f1fbf3c2SXin Li setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT); 68*f1fbf3c2SXin Li } 69*f1fbf3c2SXin Li 70*f1fbf3c2SXin Li /** 71*f1fbf3c2SXin Li * Creates a copy of a <code>CtMethod</code> object. 72*f1fbf3c2SXin Li * The created method must be 73*f1fbf3c2SXin Li * added to a class with <code>CtClass.addMethod()</code>. 74*f1fbf3c2SXin Li * 75*f1fbf3c2SXin Li * <p>All occurrences of class names in the created method 76*f1fbf3c2SXin Li * are replaced with names specified by 77*f1fbf3c2SXin Li * <code>map</code> if <code>map</code> is not <code>null</code>. 78*f1fbf3c2SXin Li * 79*f1fbf3c2SXin Li * <p>For example, suppose that a method <code>at()</code> is as 80*f1fbf3c2SXin Li * follows: 81*f1fbf3c2SXin Li * 82*f1fbf3c2SXin Li * <pre> 83*f1fbf3c2SXin Li * public X at(int i) { 84*f1fbf3c2SXin Li * return (X)super.elementAt(i); 85*f1fbf3c2SXin Li * }</pre> 86*f1fbf3c2SXin Li * 87*f1fbf3c2SXin Li * <p>(<code>X</code> is a class name.) If <code>map</code> substitutes 88*f1fbf3c2SXin Li * <code>String</code> for <code>X</code>, then the created method is: 89*f1fbf3c2SXin Li * 90*f1fbf3c2SXin Li * <pre> 91*f1fbf3c2SXin Li * public String at(int i) { 92*f1fbf3c2SXin Li * return (String)super.elementAt(i); 93*f1fbf3c2SXin Li * }</pre> 94*f1fbf3c2SXin Li * 95*f1fbf3c2SXin Li * <p>By default, all the occurrences of the names of the class 96*f1fbf3c2SXin Li * declaring <code>at()</code> and the superclass are replaced 97*f1fbf3c2SXin Li * with the name of the class and the superclass that the 98*f1fbf3c2SXin Li * created method is added to. 99*f1fbf3c2SXin Li * This is done whichever <code>map</code> is null or not. 100*f1fbf3c2SXin Li * To prevent this replacement, call <code>ClassMap.fix()</code> 101*f1fbf3c2SXin Li * or <code>put()</code> to explicitly specify replacement. 102*f1fbf3c2SXin Li * 103*f1fbf3c2SXin Li * <p><b>Note:</b> if the <code>.class</code> notation (for example, 104*f1fbf3c2SXin Li * <code>String.class</code>) is included in an expression, the 105*f1fbf3c2SXin Li * Javac compiler may produce a helper method. 106*f1fbf3c2SXin Li * Since this constructor never 107*f1fbf3c2SXin Li * copies this helper method, the programmers have the responsiblity of 108*f1fbf3c2SXin Li * copying it. Otherwise, use <code>Class.forName()</code> in the 109*f1fbf3c2SXin Li * expression. 110*f1fbf3c2SXin Li * 111*f1fbf3c2SXin Li * @param src the source method. 112*f1fbf3c2SXin Li * @param declaring the class to which the created method is added. 113*f1fbf3c2SXin Li * @param map the hashtable associating original class names 114*f1fbf3c2SXin Li * with substituted names. 115*f1fbf3c2SXin Li * It can be <code>null</code>. 116*f1fbf3c2SXin Li * 117*f1fbf3c2SXin Li * @see CtClass#addMethod(CtMethod) 118*f1fbf3c2SXin Li * @see ClassMap#fix(String) 119*f1fbf3c2SXin Li */ CtMethod(CtMethod src, CtClass declaring, ClassMap map)120*f1fbf3c2SXin Li public CtMethod(CtMethod src, CtClass declaring, ClassMap map) 121*f1fbf3c2SXin Li throws CannotCompileException 122*f1fbf3c2SXin Li { 123*f1fbf3c2SXin Li this(null, declaring); 124*f1fbf3c2SXin Li copy(src, false, map); 125*f1fbf3c2SXin Li } 126*f1fbf3c2SXin Li 127*f1fbf3c2SXin Li /** 128*f1fbf3c2SXin Li * Compiles the given source code and creates a method. 129*f1fbf3c2SXin Li * This method simply delegates to <code>make()</code> in 130*f1fbf3c2SXin Li * <code>CtNewMethod</code>. See it for more details. 131*f1fbf3c2SXin Li * <code>CtNewMethod</code> has a number of useful factory methods. 132*f1fbf3c2SXin Li * 133*f1fbf3c2SXin Li * @param src the source text. 134*f1fbf3c2SXin Li * @param declaring the class to which the created method is added. 135*f1fbf3c2SXin Li * @see CtNewMethod#make(String, CtClass) 136*f1fbf3c2SXin Li */ make(String src, CtClass declaring)137*f1fbf3c2SXin Li public static CtMethod make(String src, CtClass declaring) 138*f1fbf3c2SXin Li throws CannotCompileException 139*f1fbf3c2SXin Li { 140*f1fbf3c2SXin Li return CtNewMethod.make(src, declaring); 141*f1fbf3c2SXin Li } 142*f1fbf3c2SXin Li 143*f1fbf3c2SXin Li /** 144*f1fbf3c2SXin Li * Creates a method from a <code>MethodInfo</code> object. 145*f1fbf3c2SXin Li * 146*f1fbf3c2SXin Li * @param declaring the class declaring the method. 147*f1fbf3c2SXin Li * @throws CannotCompileException if the the <code>MethodInfo</code> 148*f1fbf3c2SXin Li * object and the declaring class have different 149*f1fbf3c2SXin Li * <code>ConstPool</code> objects 150*f1fbf3c2SXin Li * @since 3.6 151*f1fbf3c2SXin Li */ make(MethodInfo minfo, CtClass declaring)152*f1fbf3c2SXin Li public static CtMethod make(MethodInfo minfo, CtClass declaring) 153*f1fbf3c2SXin Li throws CannotCompileException 154*f1fbf3c2SXin Li { 155*f1fbf3c2SXin Li if (declaring.getClassFile2().getConstPool() != minfo.getConstPool()) 156*f1fbf3c2SXin Li throw new CannotCompileException("bad declaring class"); 157*f1fbf3c2SXin Li 158*f1fbf3c2SXin Li return new CtMethod(minfo, declaring); 159*f1fbf3c2SXin Li } 160*f1fbf3c2SXin Li 161*f1fbf3c2SXin Li /** 162*f1fbf3c2SXin Li * Returns a hash code value for the method. 163*f1fbf3c2SXin Li * If two methods have the same name and signature, then 164*f1fbf3c2SXin Li * the hash codes for the two methods are equal. 165*f1fbf3c2SXin Li */ 166*f1fbf3c2SXin Li @Override hashCode()167*f1fbf3c2SXin Li public int hashCode() { 168*f1fbf3c2SXin Li return getStringRep().hashCode(); 169*f1fbf3c2SXin Li } 170*f1fbf3c2SXin Li 171*f1fbf3c2SXin Li /** 172*f1fbf3c2SXin Li * This method is invoked when setName() or replaceClassName() 173*f1fbf3c2SXin Li * in CtClass is called. 174*f1fbf3c2SXin Li */ 175*f1fbf3c2SXin Li @Override nameReplaced()176*f1fbf3c2SXin Li void nameReplaced() { 177*f1fbf3c2SXin Li cachedStringRep = null; 178*f1fbf3c2SXin Li } 179*f1fbf3c2SXin Li 180*f1fbf3c2SXin Li /* This method is also called by CtClassType.getMethods0(). 181*f1fbf3c2SXin Li */ getStringRep()182*f1fbf3c2SXin Li final String getStringRep() { 183*f1fbf3c2SXin Li if (cachedStringRep == null) 184*f1fbf3c2SXin Li cachedStringRep = methodInfo.getName() 185*f1fbf3c2SXin Li + Descriptor.getParamDescriptor(methodInfo.getDescriptor()); 186*f1fbf3c2SXin Li 187*f1fbf3c2SXin Li return cachedStringRep; 188*f1fbf3c2SXin Li } 189*f1fbf3c2SXin Li 190*f1fbf3c2SXin Li /** 191*f1fbf3c2SXin Li * Indicates whether <code>obj</code> has the same name and the 192*f1fbf3c2SXin Li * same signature as this method. 193*f1fbf3c2SXin Li */ 194*f1fbf3c2SXin Li @Override equals(Object obj)195*f1fbf3c2SXin Li public boolean equals(Object obj) { 196*f1fbf3c2SXin Li return obj != null && obj instanceof CtMethod 197*f1fbf3c2SXin Li && ((CtMethod)obj).getStringRep().equals(getStringRep()); 198*f1fbf3c2SXin Li } 199*f1fbf3c2SXin Li 200*f1fbf3c2SXin Li /** 201*f1fbf3c2SXin Li * Returns the method name followed by parameter types 202*f1fbf3c2SXin Li * such as <code>javassist.CtMethod.setBody(String)</code>. 203*f1fbf3c2SXin Li * 204*f1fbf3c2SXin Li * @since 3.5 205*f1fbf3c2SXin Li */ 206*f1fbf3c2SXin Li @Override getLongName()207*f1fbf3c2SXin Li public String getLongName() { 208*f1fbf3c2SXin Li return getDeclaringClass().getName() + "." 209*f1fbf3c2SXin Li + getName() + Descriptor.toString(getSignature()); 210*f1fbf3c2SXin Li } 211*f1fbf3c2SXin Li 212*f1fbf3c2SXin Li /** 213*f1fbf3c2SXin Li * Obtains the name of this method. 214*f1fbf3c2SXin Li */ 215*f1fbf3c2SXin Li @Override getName()216*f1fbf3c2SXin Li public String getName() { 217*f1fbf3c2SXin Li return methodInfo.getName(); 218*f1fbf3c2SXin Li } 219*f1fbf3c2SXin Li 220*f1fbf3c2SXin Li /** 221*f1fbf3c2SXin Li * Changes the name of this method. 222*f1fbf3c2SXin Li */ setName(String newname)223*f1fbf3c2SXin Li public void setName(String newname) { 224*f1fbf3c2SXin Li declaringClass.checkModify(); 225*f1fbf3c2SXin Li methodInfo.setName(newname); 226*f1fbf3c2SXin Li } 227*f1fbf3c2SXin Li 228*f1fbf3c2SXin Li /** 229*f1fbf3c2SXin Li * Obtains the type of the returned value. 230*f1fbf3c2SXin Li */ getReturnType()231*f1fbf3c2SXin Li public CtClass getReturnType() throws NotFoundException { 232*f1fbf3c2SXin Li return getReturnType0(); 233*f1fbf3c2SXin Li } 234*f1fbf3c2SXin Li 235*f1fbf3c2SXin Li /** 236*f1fbf3c2SXin Li * Returns true if the method body is empty, that is, <code>{}</code>. 237*f1fbf3c2SXin Li * It also returns true if the method is an abstract method. 238*f1fbf3c2SXin Li */ 239*f1fbf3c2SXin Li @Override isEmpty()240*f1fbf3c2SXin Li public boolean isEmpty() { 241*f1fbf3c2SXin Li CodeAttribute ca = getMethodInfo2().getCodeAttribute(); 242*f1fbf3c2SXin Li if (ca == null) // abstract or native 243*f1fbf3c2SXin Li return (getModifiers() & Modifier.ABSTRACT) != 0; 244*f1fbf3c2SXin Li 245*f1fbf3c2SXin Li CodeIterator it = ca.iterator(); 246*f1fbf3c2SXin Li try { 247*f1fbf3c2SXin Li return it.hasNext() && it.byteAt(it.next()) == Opcode.RETURN 248*f1fbf3c2SXin Li && !it.hasNext(); 249*f1fbf3c2SXin Li } 250*f1fbf3c2SXin Li catch (BadBytecode e) {} 251*f1fbf3c2SXin Li return false; 252*f1fbf3c2SXin Li } 253*f1fbf3c2SXin Li 254*f1fbf3c2SXin Li /** 255*f1fbf3c2SXin Li * Copies a method body from another method. 256*f1fbf3c2SXin Li * If this method is abstract, the abstract modifier is removed 257*f1fbf3c2SXin Li * after the method body is copied. 258*f1fbf3c2SXin Li * 259*f1fbf3c2SXin Li * <p>All occurrences of the class names in the copied method body 260*f1fbf3c2SXin Li * are replaced with the names specified by 261*f1fbf3c2SXin Li * <code>map</code> if <code>map</code> is not <code>null</code>. 262*f1fbf3c2SXin Li * 263*f1fbf3c2SXin Li * @param src the method that the body is copied from. 264*f1fbf3c2SXin Li * @param map the hashtable associating original class names 265*f1fbf3c2SXin Li * with substituted names. 266*f1fbf3c2SXin Li * It can be <code>null</code>. 267*f1fbf3c2SXin Li */ setBody(CtMethod src, ClassMap map)268*f1fbf3c2SXin Li public void setBody(CtMethod src, ClassMap map) 269*f1fbf3c2SXin Li throws CannotCompileException 270*f1fbf3c2SXin Li { 271*f1fbf3c2SXin Li setBody0(src.declaringClass, src.methodInfo, 272*f1fbf3c2SXin Li declaringClass, methodInfo, map); 273*f1fbf3c2SXin Li } 274*f1fbf3c2SXin Li 275*f1fbf3c2SXin Li /** 276*f1fbf3c2SXin Li * Replace a method body with a new method body wrapping the 277*f1fbf3c2SXin Li * given method. 278*f1fbf3c2SXin Li * 279*f1fbf3c2SXin Li * @param mbody the wrapped method 280*f1fbf3c2SXin Li * @param constParam the constant parameter given to 281*f1fbf3c2SXin Li * the wrapped method 282*f1fbf3c2SXin Li * (maybe <code>null</code>). 283*f1fbf3c2SXin Li * 284*f1fbf3c2SXin Li * @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass) 285*f1fbf3c2SXin Li */ setWrappedBody(CtMethod mbody, ConstParameter constParam)286*f1fbf3c2SXin Li public void setWrappedBody(CtMethod mbody, ConstParameter constParam) 287*f1fbf3c2SXin Li throws CannotCompileException 288*f1fbf3c2SXin Li { 289*f1fbf3c2SXin Li declaringClass.checkModify(); 290*f1fbf3c2SXin Li 291*f1fbf3c2SXin Li CtClass clazz = getDeclaringClass(); 292*f1fbf3c2SXin Li CtClass[] params; 293*f1fbf3c2SXin Li CtClass retType; 294*f1fbf3c2SXin Li try { 295*f1fbf3c2SXin Li params = getParameterTypes(); 296*f1fbf3c2SXin Li retType = getReturnType(); 297*f1fbf3c2SXin Li } 298*f1fbf3c2SXin Li catch (NotFoundException e) { 299*f1fbf3c2SXin Li throw new CannotCompileException(e); 300*f1fbf3c2SXin Li } 301*f1fbf3c2SXin Li 302*f1fbf3c2SXin Li Bytecode code = CtNewWrappedMethod.makeBody(clazz, 303*f1fbf3c2SXin Li clazz.getClassFile2(), 304*f1fbf3c2SXin Li mbody, 305*f1fbf3c2SXin Li params, retType, 306*f1fbf3c2SXin Li constParam); 307*f1fbf3c2SXin Li CodeAttribute cattr = code.toCodeAttribute(); 308*f1fbf3c2SXin Li methodInfo.setCodeAttribute(cattr); 309*f1fbf3c2SXin Li methodInfo.setAccessFlags(methodInfo.getAccessFlags() 310*f1fbf3c2SXin Li & ~AccessFlag.ABSTRACT); 311*f1fbf3c2SXin Li // rebuilding a stack map table is not needed. 312*f1fbf3c2SXin Li } 313*f1fbf3c2SXin Li 314*f1fbf3c2SXin Li // inner classes 315*f1fbf3c2SXin Li 316*f1fbf3c2SXin Li /** 317*f1fbf3c2SXin Li * Instances of this class represent a constant parameter. 318*f1fbf3c2SXin Li * They are used to specify the parameter given to the methods 319*f1fbf3c2SXin Li * created by <code>CtNewMethod.wrapped()</code>. 320*f1fbf3c2SXin Li * 321*f1fbf3c2SXin Li * @see CtMethod#setWrappedBody(CtMethod,CtMethod.ConstParameter) 322*f1fbf3c2SXin Li * @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass) 323*f1fbf3c2SXin Li * @see CtNewConstructor#make(CtClass[],CtClass[],int,CtMethod,CtMethod.ConstParameter,CtClass) 324*f1fbf3c2SXin Li */ 325*f1fbf3c2SXin Li public static class ConstParameter { 326*f1fbf3c2SXin Li /** 327*f1fbf3c2SXin Li * Makes an integer constant. 328*f1fbf3c2SXin Li * 329*f1fbf3c2SXin Li * @param i the constant value. 330*f1fbf3c2SXin Li */ integer(int i)331*f1fbf3c2SXin Li public static ConstParameter integer(int i) { 332*f1fbf3c2SXin Li return new IntConstParameter(i); 333*f1fbf3c2SXin Li } 334*f1fbf3c2SXin Li 335*f1fbf3c2SXin Li /** 336*f1fbf3c2SXin Li * Makes a long integer constant. 337*f1fbf3c2SXin Li * 338*f1fbf3c2SXin Li * @param i the constant value. 339*f1fbf3c2SXin Li */ integer(long i)340*f1fbf3c2SXin Li public static ConstParameter integer(long i) { 341*f1fbf3c2SXin Li return new LongConstParameter(i); 342*f1fbf3c2SXin Li } 343*f1fbf3c2SXin Li 344*f1fbf3c2SXin Li /** 345*f1fbf3c2SXin Li * Makes an <code>String</code> constant. 346*f1fbf3c2SXin Li * 347*f1fbf3c2SXin Li * @param s the constant value. 348*f1fbf3c2SXin Li */ string(String s)349*f1fbf3c2SXin Li public static ConstParameter string(String s) { 350*f1fbf3c2SXin Li return new StringConstParameter(s); 351*f1fbf3c2SXin Li } 352*f1fbf3c2SXin Li ConstParameter()353*f1fbf3c2SXin Li ConstParameter() {} 354*f1fbf3c2SXin Li 355*f1fbf3c2SXin Li /** 356*f1fbf3c2SXin Li * @return the size of the stack consumption. 357*f1fbf3c2SXin Li */ compile(Bytecode code)358*f1fbf3c2SXin Li int compile(Bytecode code) throws CannotCompileException { 359*f1fbf3c2SXin Li return 0; 360*f1fbf3c2SXin Li } 361*f1fbf3c2SXin Li descriptor()362*f1fbf3c2SXin Li String descriptor() { 363*f1fbf3c2SXin Li return defaultDescriptor(); 364*f1fbf3c2SXin Li } 365*f1fbf3c2SXin Li 366*f1fbf3c2SXin Li /** 367*f1fbf3c2SXin Li * @see CtNewWrappedMethod 368*f1fbf3c2SXin Li */ defaultDescriptor()369*f1fbf3c2SXin Li static String defaultDescriptor() { 370*f1fbf3c2SXin Li return "([Ljava/lang/Object;)Ljava/lang/Object;"; 371*f1fbf3c2SXin Li } 372*f1fbf3c2SXin Li 373*f1fbf3c2SXin Li /** 374*f1fbf3c2SXin Li * Returns the descriptor for constructors. 375*f1fbf3c2SXin Li * 376*f1fbf3c2SXin Li * @see CtNewWrappedConstructor 377*f1fbf3c2SXin Li */ constDescriptor()378*f1fbf3c2SXin Li String constDescriptor() { 379*f1fbf3c2SXin Li return defaultConstDescriptor(); 380*f1fbf3c2SXin Li } 381*f1fbf3c2SXin Li 382*f1fbf3c2SXin Li /** 383*f1fbf3c2SXin Li * Returns the default descriptor for constructors. 384*f1fbf3c2SXin Li */ defaultConstDescriptor()385*f1fbf3c2SXin Li static String defaultConstDescriptor() { 386*f1fbf3c2SXin Li return "([Ljava/lang/Object;)V"; 387*f1fbf3c2SXin Li } 388*f1fbf3c2SXin Li } 389*f1fbf3c2SXin Li 390*f1fbf3c2SXin Li static class IntConstParameter extends ConstParameter { 391*f1fbf3c2SXin Li int param; 392*f1fbf3c2SXin Li IntConstParameter(int i)393*f1fbf3c2SXin Li IntConstParameter(int i) { 394*f1fbf3c2SXin Li param = i; 395*f1fbf3c2SXin Li } 396*f1fbf3c2SXin Li 397*f1fbf3c2SXin Li @Override compile(Bytecode code)398*f1fbf3c2SXin Li int compile(Bytecode code) throws CannotCompileException { 399*f1fbf3c2SXin Li code.addIconst(param); 400*f1fbf3c2SXin Li return 1; 401*f1fbf3c2SXin Li } 402*f1fbf3c2SXin Li 403*f1fbf3c2SXin Li @Override descriptor()404*f1fbf3c2SXin Li String descriptor() { 405*f1fbf3c2SXin Li return "([Ljava/lang/Object;I)Ljava/lang/Object;"; 406*f1fbf3c2SXin Li } 407*f1fbf3c2SXin Li 408*f1fbf3c2SXin Li @Override constDescriptor()409*f1fbf3c2SXin Li String constDescriptor() { 410*f1fbf3c2SXin Li return "([Ljava/lang/Object;I)V"; 411*f1fbf3c2SXin Li } 412*f1fbf3c2SXin Li } 413*f1fbf3c2SXin Li 414*f1fbf3c2SXin Li static class LongConstParameter extends ConstParameter { 415*f1fbf3c2SXin Li long param; 416*f1fbf3c2SXin Li LongConstParameter(long l)417*f1fbf3c2SXin Li LongConstParameter(long l) { 418*f1fbf3c2SXin Li param = l; 419*f1fbf3c2SXin Li } 420*f1fbf3c2SXin Li 421*f1fbf3c2SXin Li @Override compile(Bytecode code)422*f1fbf3c2SXin Li int compile(Bytecode code) throws CannotCompileException { 423*f1fbf3c2SXin Li code.addLconst(param); 424*f1fbf3c2SXin Li return 2; 425*f1fbf3c2SXin Li } 426*f1fbf3c2SXin Li 427*f1fbf3c2SXin Li @Override descriptor()428*f1fbf3c2SXin Li String descriptor() { 429*f1fbf3c2SXin Li return "([Ljava/lang/Object;J)Ljava/lang/Object;"; 430*f1fbf3c2SXin Li } 431*f1fbf3c2SXin Li 432*f1fbf3c2SXin Li @Override constDescriptor()433*f1fbf3c2SXin Li String constDescriptor() { 434*f1fbf3c2SXin Li return "([Ljava/lang/Object;J)V"; 435*f1fbf3c2SXin Li } 436*f1fbf3c2SXin Li } 437*f1fbf3c2SXin Li 438*f1fbf3c2SXin Li static class StringConstParameter extends ConstParameter { 439*f1fbf3c2SXin Li String param; 440*f1fbf3c2SXin Li StringConstParameter(String s)441*f1fbf3c2SXin Li StringConstParameter(String s) { 442*f1fbf3c2SXin Li param = s; 443*f1fbf3c2SXin Li } 444*f1fbf3c2SXin Li 445*f1fbf3c2SXin Li @Override compile(Bytecode code)446*f1fbf3c2SXin Li int compile(Bytecode code) throws CannotCompileException { 447*f1fbf3c2SXin Li code.addLdc(param); 448*f1fbf3c2SXin Li return 1; 449*f1fbf3c2SXin Li } 450*f1fbf3c2SXin Li 451*f1fbf3c2SXin Li @Override descriptor()452*f1fbf3c2SXin Li String descriptor() { 453*f1fbf3c2SXin Li return "([Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;"; 454*f1fbf3c2SXin Li } 455*f1fbf3c2SXin Li 456*f1fbf3c2SXin Li @Override constDescriptor()457*f1fbf3c2SXin Li String constDescriptor() { 458*f1fbf3c2SXin Li return "([Ljava/lang/Object;Ljava/lang/String;)V"; 459*f1fbf3c2SXin Li } 460*f1fbf3c2SXin Li } 461*f1fbf3c2SXin Li } 462