1 29 30 package com.caucho.loader.enhancer; 31 32 import com.caucho.bytecode.*; 33 import com.caucho.java.WorkDir; 34 import com.caucho.java.gen.JavaClassGenerator; 35 import com.caucho.loader.DynamicClassLoader; 36 import com.caucho.util.L10N; 37 import com.caucho.vfs.JarPath; 38 import com.caucho.vfs.Path; 39 import com.caucho.vfs.ReadStream; 40 import com.caucho.vfs.Vfs; 41 import com.caucho.vfs.WriteStream; 42 43 import java.net.URL ; 44 import java.util.ArrayList ; 45 import java.util.logging.Logger ; 46 47 55 public class EnhancerFixup { 56 private static final L10N L = new L10N(EnhancerFixup.class); 57 private static final Logger log = Logger.getLogger(EnhancerFixup.class.getName()); 58 59 private static final int ACC_PUBLIC = 0x1; 60 private static final int ACC_PRIVATE = 0x2; 61 private static final int ACC_PROTECTED = 0x4; 62 63 private JavaClassGenerator _javaGen = new JavaClassGenerator(); 64 65 private JavaClassLoader _jClassLoader; 66 private DynamicClassLoader _loader; 67 68 private Path _workPath; 69 70 private String _baseSuffix = ""; 71 private String _extSuffix = "__ResinExt"; 72 73 private ArrayList <ClassEnhancer> _enhancerList = 74 new ArrayList <ClassEnhancer>(); 75 76 private boolean _isParentStarted; 77 78 81 public void setClassLoader(DynamicClassLoader loader) 82 { 83 _loader = loader; 84 } 85 86 89 public void setJavaClassLoader(JavaClassLoader jClassLoader) 90 { 91 _jClassLoader = jClassLoader; 92 } 93 94 97 public JavaClassLoader getJavaClassLoader() 98 { 99 return _jClassLoader; 100 } 101 102 105 public Path getWorkPath() 106 { 107 if (_workPath != null) 108 return _workPath; 109 else 110 return WorkDir.getLocalWorkDir(); 111 } 112 113 116 public void setWorkPath(Path workPath) 117 { 118 _workPath = workPath; 119 } 120 121 124 public final Path getPreWorkPath() 125 { 126 return getWorkPath().lookup("pre-enhance"); 127 } 128 129 132 public final Path getPostWorkPath() 133 { 134 return getWorkPath().lookup("post-enhance"); 135 } 136 137 140 public void addEnhancer(ClassEnhancer enhancer) 141 { 142 _enhancerList.add(enhancer); 143 } 144 145 protected void fixup(String className, String extClassName) 146 throws Exception 147 { 148 Path prePath = getPreWorkPath(); 149 Path postPath = getPostWorkPath(); 150 151 Path source = getSource(className); 152 153 if (source == null || ! source.canRead()) 154 return; 155 156 Path ext = prePath.lookup(extClassName.replace('.', '/') + ".class"); 157 Path target = postPath.lookup(className.replace('.', '/') + ".class"); 158 159 try { 160 target.getParent().mkdirs(); 161 } catch (Throwable e) { 162 } 163 164 if (source != null) 165 mergeClasses(className, target, source, ext); 166 else 167 mergeClasses(className, target, ext); 168 169 int p = className.lastIndexOf('.'); 170 171 Path preTargetDir; 172 Path targetDir; 173 String classSuffix; 174 String prefix = ""; 175 176 if (p > 0) { 177 prefix = className.substring(0, p).replace('.', '/'); 178 preTargetDir = prePath.lookup(prefix); 179 targetDir = postPath.lookup(prefix); 180 classSuffix = className.substring(p + 1); 181 } 182 else { 183 preTargetDir = prePath; 184 targetDir = postPath; 185 classSuffix = className; 186 } 187 188 prefix = prefix.replace('/', '.'); 189 if (! prefix.equals("")) 190 prefix = prefix + "."; 191 192 String extSuffix; 193 p = extClassName.lastIndexOf('.'); 194 if (p > 0) 195 extSuffix = extClassName.substring(p + 1); 196 else 197 extSuffix = extClassName; 198 199 fixupPreSubClasses(preTargetDir, targetDir, 200 extSuffix, classSuffix); 201 202 fixupPostSubClasses(targetDir, prefix, classSuffix); 203 } 204 205 private void fixupPreSubClasses(Path preTargetDir, Path targetDir, 206 String extSuffix, String classSuffix) 207 throws Exception 208 { 209 String []list = preTargetDir.list(); 210 211 for (int i = 0; i < list.length; i++) { 212 String name = list[i]; 213 214 if (name.startsWith(extSuffix + '$') && 215 name.endsWith(".class")) { 216 int p = name.indexOf('$'); 217 String targetClass = (classSuffix + '$' + 218 name.substring(p + 1, name.length() - 6)); 219 220 Path subTarget = targetDir.lookup(targetClass + ".class"); 221 222 Path extPath = preTargetDir.lookup(name); 223 224 renameSubClass(classSuffix, subTarget, extPath); 225 226 } 229 else if (name.startsWith(extSuffix + '-') && 230 name.endsWith(".class")) { 231 int p = name.indexOf('-'); 232 String targetClass = (classSuffix + '-' + 233 name.substring(p + 1, name.length() - 6)); 234 235 Path subTarget = targetDir.lookup(targetClass + ".class"); 236 237 Path extPath = preTargetDir.lookup(name); 238 239 renameSubClass(classSuffix, subTarget, extPath); 240 241 } 244 } 245 } 246 247 private void fixupPostSubClasses(Path targetDir, 248 String prefix, 249 String classSuffix) 250 throws Exception 251 { 252 String []list = targetDir.list(); 253 254 for (int i = 0; i < list.length; i++) { 255 String name = list[i]; 256 257 if (! name.endsWith(".class")) 258 continue; 259 260 String className = name.substring(0, name.length() - ".class".length()); 261 262 if (name.startsWith(classSuffix + '$')) { 263 if (_loader != null) 264 _loader.addPathClass(prefix + className, targetDir.lookup(name)); 265 } 266 else if (name.startsWith(classSuffix + '-')) { 267 if (_loader != null) 268 _loader.addPathClass(prefix + className, targetDir.lookup(name)); 269 } 270 else if (name.startsWith(classSuffix + '+')) { 271 if (_loader != null) 272 _loader.addPathClass(prefix + className, targetDir.lookup(name)); 273 } 274 } 275 } 276 277 280 protected void renameSubClass(String className, 281 Path targetPath, 282 Path extPath) 283 throws Exception 284 { 285 JavaClass extClass = null; 286 287 ByteCodeParser parser = new ByteCodeParser(); 288 289 parser = new ByteCodeParser(); 290 parser.setClassLoader(new JavaClassLoader()); 291 292 ReadStream is = extPath.openRead(); 293 try { 294 extClass = parser.parse(is); 295 } finally { 296 if (is != null) 297 is.close(); 298 } 299 300 cleanExtConstantPool(className, extClass); 301 302 WriteStream os = targetPath.openWrite(); 303 try { 304 extClass.write(os); 305 } finally { 306 os.close(); 307 } 308 } 309 310 313 protected void renameExtSuperMethods(String className, 314 JavaClass baseClass, 315 JavaClass extClass) 316 throws Exception 317 { 318 ArrayList <ConstantPoolEntry> entries; 319 entries = extClass.getConstantPool().getEntries(); 320 321 className = className.replace('.', '/'); 322 String baseName = className + _baseSuffix; 323 String extName = className + "__ResinExt"; 324 325 for (int i = 0; i < entries.size(); i++) { 326 ConstantPoolEntry entry = entries.get(i); 327 328 if (entry instanceof MethodRefConstant) { 329 MethodRefConstant methodRef = (MethodRefConstant) entry; 330 331 if (! methodRef.getClassName().equals(baseName)) 332 continue; 333 334 String methodName = methodRef.getName(); 335 String type = methodRef.getType(); 336 337 if (findMethod(baseClass, methodName, type) == null) 338 continue; 339 340 if (findMethod(extClass, methodName, type) == null) 341 continue; 342 343 if (methodName.equals("<init>")) { 344 methodName = "__init__super"; 345 } 347 353 } 354 } 355 } 356 357 358 361 private void moveSuperMethods(String className, 362 JavaClass baseClass, 363 JavaClass extClass) 364 { 365 className = className.replace('.', '/'); 366 367 ArrayList <JavaMethod> methods = baseClass.getMethodList(); 368 369 ArrayList <JavaMethod> extMethods = extClass.getMethodList(); 371 for (int i = 0; i < extMethods.size(); i++) { 372 JavaMethod extMethod = extMethods.get(i); 373 374 fixupExtMethod(baseClass, extClass, extMethod); 375 376 String baseName = extMethod.getName(); 377 378 if (baseName.endsWith("__super")) 379 continue; 380 381 String superName = baseName + "__super"; 382 383 int j; 384 for (j = 0; j < methods.size(); j++) { 385 JavaMethod method = methods.get(j); 386 387 String type = method.getDescriptor(); 388 389 if (! method.getName().equals(baseName) || 390 ! method.getDescriptor().equals(extMethod.getDescriptor())) 391 continue; 392 393 if (baseName.equals("<init>")) { 394 baseClass.getConstantPool().addUTF8("__init__super"); 395 mergeInitMethods(baseClass, method, extClass, extMethod); 396 break; 397 } 398 399 if (baseName.equals("<clinit>")) { 400 concatenateMethods(baseClass, method, extClass, extMethod); 401 break; 402 } 403 404 baseClass.getConstantPool().addUTF8(superName); 405 method.setName(superName); 406 baseClass.getConstantPool().addUTF8(type); 407 method.setDescriptor(type); 408 409 int flags = method.getAccessFlags(); 411 flags = (flags & ~ACC_PUBLIC & ~ACC_PROTECTED) | ACC_PRIVATE; 412 method.setAccessFlags(flags); 413 break; 414 } 415 } 416 } 417 418 421 private void concatenateMethods(JavaClass baseClass, JavaMethod baseMethod, 422 JavaClass extClass, JavaMethod extMethod) 423 { 424 extMethod = extMethod.export(extClass, baseClass); 425 426 baseMethod.concatenate(extMethod); 427 } 428 429 432 private void mergeInitMethods(JavaClass baseClass, JavaMethod baseMethod, 433 JavaClass extClass, JavaMethod extMethod) 434 { 435 extMethod = extMethod.export(extClass, baseClass); 436 437 baseMethod.setName("__init__super"); 438 439 baseClass.getMethodList().add(extMethod); 440 441 try { 442 InitAnalyzer initAnalyzer = new InitAnalyzer(); 443 CodeEnhancer baseEnhancer = new CodeEnhancer(baseClass, baseMethod.getCode()); 444 baseEnhancer.analyze(initAnalyzer); 445 446 int offset = initAnalyzer.getOffset(); 447 byte []code = new byte[offset]; 448 byte []oldCode = baseEnhancer.getCode(); 449 System.arraycopy(oldCode, 0, code, 0, offset); 450 451 baseEnhancer.remove(0, offset); 452 baseEnhancer.update(); 453 454 CodeEnhancer extEnhancer = new CodeEnhancer(baseClass, extMethod.getCode()); 455 456 extEnhancer.add(0, code, 0, code.length); 457 458 ExtMethodAnalyzer extMethodAnalyzer 459 = new ExtMethodAnalyzer(baseClass, extMethod, offset); 460 extEnhancer.analyze(extMethodAnalyzer); 461 extEnhancer.update(); 462 463 CodeAttribute baseCode = baseMethod.getCode(); 464 CodeAttribute extCode = extMethod.getCode(); 465 466 if (extCode.getMaxStack() < baseCode.getMaxStack()) 467 extCode.setMaxStack(baseCode.getMaxStack()); 468 469 extCode.removeAttribute("LocalVariableTable"); 471 extCode.removeAttribute("LineNumberTable"); 472 baseCode.removeAttribute("LocalVariableTable"); 473 baseCode.removeAttribute("LineNumberTable"); 474 475 478 } catch (RuntimeException e) { 479 throw e; 480 } catch (Exception e) { 481 throw new RuntimeException (e); 482 } 483 } 484 485 488 private void fixupExtMethod(JavaClass baseClass, 489 JavaClass extClass, 490 JavaMethod extMethod) 491 { 492 try { 493 if (extMethod.getName().endsWith("__super")) 494 return; 495 496 CodeEnhancer extEnhancer 497 = new CodeEnhancer(extClass, extMethod.getCode()); 498 499 ExtMethodAnalyzer extMethodAnalyzer 500 = new ExtMethodAnalyzer(baseClass, extMethod, 0); 501 extEnhancer.analyze(extMethodAnalyzer); 502 extEnhancer.update(); 503 } catch (RuntimeException e) { 504 throw e; 505 } catch (Exception e) { 506 throw new RuntimeException (e); 507 } 508 } 509 510 513 private void addExtInterfaces(JavaClass baseClass, JavaClass extClass) 514 { 515 for (String name : extClass.getInterfaceNames()) { 516 baseClass.getConstantPool().addClass(name); 517 518 baseClass.addInterface(name); 519 } 520 } 521 522 525 private void addExtMethods(JavaClass baseClass, JavaClass extClass) 526 { 527 ArrayList <JavaMethod> methods = baseClass.getMethodList(); 528 ArrayList <JavaMethod> extMethods = extClass.getMethodList(); 529 530 for (int i = 0; i < extMethods.size(); i++) { 531 JavaMethod extMethod = extMethods.get(i); 532 533 if (extMethod.getName().equals("<clinit>") && 534 findMethod(baseClass, "<clinit>", 535 extMethod.getDescriptor()) != null) { 536 continue; 537 } 538 else if (extMethod.getName().equals("<init>")) 539 continue; 540 else if (extMethod.getName().endsWith("__super")) 541 continue; 542 543 log.finest("adding extension method: " + extClass.getThisClass() + ":" + extMethod.getName()); 544 545 JavaMethod method = extMethod.export(extClass, baseClass); 546 547 methods.add(method); 548 } 549 } 550 551 554 private void addExtClasses(JavaClass baseClass, JavaClass extClass) 555 { 556 580 } 581 582 585 private static JavaMethod findMethod(JavaClass cl, 586 String name, 587 String descriptor) 588 { 589 ArrayList <JavaMethod> methods = cl.getMethodList(); 590 591 int j; 592 for (j = 0; j < methods.size(); j++) { 593 JavaMethod method = methods.get(j); 594 595 if (method.getName().equals(name) && 596 method.getDescriptor().equals(descriptor)) 597 return method; 598 } 599 600 return null; 601 } 602 603 606 private void moveSuperFields(JavaClass baseClass, JavaClass extClass) 607 { 608 ArrayList <JavaField> fields = baseClass.getFieldList(); 609 ArrayList <JavaField> extFields = extClass.getFieldList(); 610 611 for (int i = 0; i < extFields.size(); i++) { 612 } 613 } 614 615 private Path getSource(String className) 616 { 617 ClassLoader loader = _loader; 618 if (loader == null) 619 loader = Thread.currentThread().getContextClassLoader(); 620 621 URL url = loader.getResource(className.replace('.', '/') + ".class"); 622 623 String s = url.toString(); 625 int index = s.indexOf("jar!/"); 626 if (index > 0) { 627 s = s.substring(9, index+3); 628 Path path = JarPath.create(Vfs.lookup(s)); 629 path = path.lookup(className.replace('.', '/') + ".class"); 630 return path; 631 } 632 633 return Vfs.lookup(url.toString()); 634 } 635 636 639 protected void mergeClasses(String className, 640 Path targetPath, 641 Path sourcePath, 642 Path extPath) 643 throws Exception 644 { 645 JavaClass baseClass = null; 646 JavaClass extClass = null; 647 648 ByteCodeParser parser = new ByteCodeParser(); 649 parser.setClassLoader(getJavaClassLoader()); 650 651 ReadStream is = sourcePath.openRead(); 652 try { 653 baseClass = parser.parse(is); 654 } finally { 655 if (is != null) 656 is.close(); 657 } 658 659 parser = new ByteCodeParser(); 660 parser.setClassLoader(getJavaClassLoader()); 661 662 is = extPath.openRead(); 663 try { 664 extClass = parser.parse(is); 665 } finally { 666 if (is != null) 667 is.close(); 668 } 669 670 fixupLocalVariableTable(extClass); 674 fixupLocalVariableTable(baseClass); 675 676 mergeClasses(className, baseClass, extClass); 678 679 postEnhance(baseClass); 680 681 WriteStream os = targetPath.openWrite(); 682 try { 683 baseClass.write(os); 684 } finally { 685 os.close(); 686 } 687 } 688 689 692 protected void mergeClasses(String className, 693 Path targetPath, 694 Path extPath) 695 throws Exception 696 { 697 JavaClass baseClass = null; 698 JavaClass extClass = null; 699 700 ByteCodeParser parser = new ByteCodeParser(); 701 parser.setClassLoader(getJavaClassLoader()); 702 703 ReadStream is = extPath.openRead(); 704 try { 705 extClass = parser.parse(is); 706 } finally { 707 if (is != null) 708 is.close(); 709 } 710 711 cleanExtConstantPool(className, extClass); 712 713 postEnhance(baseClass); 714 715 WriteStream os = targetPath.openWrite(); 716 try { 717 extClass.write(os); 718 } finally { 719 os.close(); 720 } 721 } 722 723 726 protected void postEnhance(JavaClass baseClass) 727 throws Exception 728 { 729 for (int i = 0; i < _enhancerList.size(); i++) { 730 _enhancerList.get(i).postEnhance(baseClass); 731 } 732 733 fixupJdk16Methods(baseClass); 734 } 735 736 739 protected void mergeClasses(String className, 740 JavaClass baseClass, 741 JavaClass extClass) 742 throws Exception 743 { 744 if (baseClass.getMajor() < extClass.getMajor()) { 745 baseClass.setMajor(extClass.getMajor()); 746 baseClass.setMinor(extClass.getMinor()); 747 } 748 749 cleanExtConstantPool(className, extClass); 750 renameExtSuperMethods(className, baseClass, extClass); 751 752 cleanExtConstantPool(className, baseClass); 753 754 addExtInterfaces(baseClass, extClass); 755 756 addExtFields(baseClass, extClass); 757 758 moveSuperMethods(className, baseClass, extClass); 759 760 addExtMethods(baseClass, extClass); 761 762 copyExtAnnotations(baseClass); 763 764 addExtClasses(baseClass, extClass); 765 } 766 767 770 protected void cleanExtConstantPool(String className, JavaClass extClass) 771 throws Exception 772 { 773 extClass.setThisClass(replaceString(className, extClass.getThisClass())); 774 extClass.setSuperClass(replaceString(className, extClass.getSuperClassName())); 775 776 ArrayList <ConstantPoolEntry> entries; 777 entries = extClass.getConstantPool().getEntries(); 778 779 int t = className.lastIndexOf('.'); 780 if (t > 0) 781 className = className.substring(t + 1); 782 783 String baseName = className + _baseSuffix; 784 String extName = className + "__ResinExt"; 785 786 for (int i = 0; i < entries.size(); i++) { 787 ConstantPoolEntry entry = entries.get(i); 788 789 if (entry instanceof Utf8Constant) { 790 Utf8Constant utf8 = (Utf8Constant) entry; 791 792 String string = utf8.getValue(); 793 794 string = replaceString(className, string); 795 796 utf8.setValue(string); 797 } 798 } 799 800 ArrayList <JavaField> fields = extClass.getFieldList(); 801 for (int i = 0; i < fields.size(); i++) { 802 JavaField field = fields.get(i); 803 804 field.setName(replaceString(className, field.getName())); 805 field.setDescriptor(replaceString(className, field.getDescriptor())); 806 } 807 808 ArrayList <JavaMethod> methods = extClass.getMethodList(); 809 for (int i = 0; i < methods.size(); i++) { 810 JavaMethod method = methods.get(i); 811 812 method.setName(replaceString(className, method.getName())); 813 method.setDescriptor(replaceString(className, method.getDescriptor())); 814 } 815 } 816 817 820 private void copyExtAnnotations(JavaClass baseClass) 821 { 822 for (JavaMethod method : baseClass.getMethodList()) { 823 if (method.getName().endsWith("__super")) { 824 Attribute ann = method.getAttribute("RuntimeVisibleAnnotations"); 825 826 if (ann != null) { 827 String name = method.getName(); 828 name = name.substring(0, name.length() - "__super".length()); 829 830 JavaMethod baseMethod; 831 baseMethod = findMethod(baseClass, name, method.getDescriptor()); 832 833 if (baseMethod != null) 834 baseMethod.addAttribute(ann); 835 } 836 } 837 } 838 } 839 840 843 private void addExtFields(JavaClass baseClass, JavaClass extClass) 844 { 845 ArrayList <JavaField> fields = baseClass.getFieldList(); 846 847 for (JavaField extField : extClass.getFieldList()) { 848 JavaField field = extField.export(extClass, baseClass); 849 850 if (! fields.contains(field)) 851 fields.add(field); 852 } 853 } 854 855 858 private void fixupJdk16Methods(JavaClass baseClass) 859 { 860 for (JavaMethod method : baseClass.getMethodList()) { 861 CodeAttribute code = method.getCode(); 862 863 code.removeAttribute("StackMapTable"); 864 } 865 } 866 867 870 private void fixupLocalVariableTable(JavaClass extClass) 871 { 872 for (JavaMethod method : extClass.getMethodList()) { 873 CodeAttribute code = method.getCode(); 874 875 code.removeAttribute("LocalVariableTable"); 876 code.removeAttribute("LocalVariableTypeTable"); 877 } 878 } 879 880 private String replaceString(String className, String string) 881 { 882 string = replaceStringInt(className.replace('.', '/'), string); 883 string = replaceStringInt(className.replace('.', '$'), string); 884 string = replaceStringInt(className.replace('.', '-'), string); 885 886 return string; 887 } 888 889 private String replaceStringInt(String className, String string) 890 { 891 int t = className.lastIndexOf('.'); 892 if (t > 0) 893 className = className.substring(t + 1); 894 895 String baseName = className + _baseSuffix; 896 String extName = "__ResinExt"; 898 899 int p; 900 if (! baseName.equals(className)) { 901 while ((p = string.indexOf(baseName)) >= 0) { 902 String prefix = string.substring(0, p); 903 String suffix = string.substring(p + baseName.length()); 904 905 string = prefix + className + suffix; 906 } 907 } 908 909 while ((p = string.indexOf(extName)) >= 0) { 910 String prefix = string.substring(0, p); 911 String suffix = string.substring(p + extName.length()); 912 913 string = prefix + suffix; 915 } 916 917 return string; 918 } 919 920 private static class InitAnalyzer extends Analyzer { 921 int _offset = -1; 922 923 926 public int getOffset() 927 { 928 return _offset; 929 } 930 931 934 public void analyze(CodeVisitor visitor) 935 throws Exception 936 { 937 if (_offset >= 0) 938 return; 939 940 switch (visitor.getOpcode()) { 941 case CodeVisitor.INVOKESPECIAL: 942 JavaClass javaClass = visitor.getJavaClass(); 943 ConstantPool cp = javaClass.getConstantPool(); 944 MethodRefConstant ref = cp.getMethodRef(visitor.getShortArg()); 945 946 if (ref.getName().equals("<init>") 949 && (ref.getClassName().equals(javaClass.getThisClass()) 950 || ref.getClassName().equals(javaClass.getSuperClassName()))) { 951 _offset = visitor.getOffset() + 3; 952 } 953 break; 954 } 955 } 956 } 957 958 private static class ExtMethodAnalyzer extends Analyzer { 962 JClass _baseClass; 963 JMethod _method; 964 int _startOffset; 965 boolean _isEnhanced; 966 967 ExtMethodAnalyzer(JClass baseClass, JMethod method, int length) 968 { 969 _baseClass = baseClass; 970 _method = method; 971 _startOffset = length; 972 } 973 974 977 public void analyze(CodeVisitor visitor) 978 throws Exception 979 { 980 if (_isEnhanced) 981 return; 982 983 if (visitor.getOffset() < _startOffset) 984 return; 985 986 switch (visitor.getOpcode()) { 987 case CodeVisitor.INVOKESPECIAL: 988 int index = visitor.getShortArg(); 989 990 JavaClass jClass = visitor.getJavaClass(); 991 ConstantPool cp = jClass.getConstantPool(); 992 MethodRefConstant ref; 993 ref = cp.getMethodRef(index); 994 995 if (ref.getName().endsWith("__super")) { 996 return; 997 } 998 else if (ref.getName().equals("<init>") 999 && (! ref.getClassName().equals(jClass.getSuperClassName()) 1000 || ! _method.getName().equals("<init>"))) { 1001 return; 1002 } 1003 else if (! ref.getName().equals("<init>")) { 1004 JMethod method = findMethod(jClass, 1007 ref.getName(), 1008 ref.getType()); 1009 1010 if (method != null && method.isPrivate()) 1011 return; 1012 } 1013 1014 String superName; 1015 if (ref.getName().equals("<init>")) 1016 superName = "__init__super"; 1017 else 1018 superName = ref.getName() + "__super"; 1019 1020 MethodRefConstant newRef; 1021 newRef = cp.addMethodRef(ref.getClassName(), 1022 superName, 1023 ref.getType()); 1024 1025 visitor.setShortArg(1, newRef.getIndex()); 1026 1027 _isEnhanced = true; 1028 break; 1029 } 1030 } 1031 } 1032} 1033 | Popular Tags |