001 package AST; 002 003 import java.util.HashSet; 004 import java.io.File; 005 import java.util.*; 006 import beaver.*; 007 import java.util.ArrayList; 008 import java.util.zip.*; 009 import java.io.*; 010 import java.io.FileNotFoundException; 011 import java.util.Collection; 012 /** 013 * @ast class 014 * 015 */ 016 public class MethodInfo extends java.lang.Object { 017 018 private BytecodeParser p; 019 020 021 String name; 022 023 024 int flags; 025 026 027 private MethodDescriptor methodDescriptor; 028 029 030 private Attributes.MethodAttributes attributes; 031 032 033 034 public MethodInfo(BytecodeParser parser) { 035 p = parser; 036 flags = p.u2(); 037 if(BytecodeParser.VERBOSE) 038 p.print(" Flags: " + Integer.toBinaryString(flags)); 039 int name_index = p.u2(); 040 CONSTANT_Info info = p.constantPool[name_index]; 041 if(info == null || !(info instanceof CONSTANT_Utf8_Info)) { 042 System.err.println("Expected CONSTANT_Utf8_Info but found: " + info.getClass().getName()); 043 //if(info instanceof CONSTANT_Class_Info) { 044 // System.err.println(" found CONSTANT_Class_Info: " + ((CONSTANT_Class_Info)info).name()); 045 // name = ((CONSTANT_Class_Info)info).name(); 046 //} 047 } 048 name = ((CONSTANT_Utf8_Info)info).string(); 049 methodDescriptor = new MethodDescriptor(p, name); 050 attributes = new Attributes.MethodAttributes(p); 051 } 052 053 054 public BodyDecl bodyDecl() { 055 Signatures.MethodSignature s = attributes.methodSignature; 056 Access returnType = (s != null && s.hasReturnType()) ? s.returnType() : methodDescriptor.type(); 057 List parameterList; 058 if(isConstructor() && p.isInnerClass) { 059 parameterList = methodDescriptor.parameterListSkipFirst(); 060 if(s != null) { 061 Iterator iter = s.parameterTypes().iterator(); 062 if(iter.hasNext()) iter.next(); 063 for(int i = 0; iter.hasNext(); i++) { 064 Access a = (Access)iter.next(); 065 ((ParameterDeclaration)parameterList.getChildNoTransform(i)).setTypeAccess(a); 066 } 067 } 068 } 069 else { 070 parameterList = methodDescriptor.parameterList(); 071 if(s != null) { 072 int i = 0; 073 for(Iterator iter = s.parameterTypes().iterator(); iter.hasNext(); i++) { 074 Access a = (Access)iter.next(); 075 ((ParameterDeclaration)parameterList.getChildNoTransform(i)).setTypeAccess(a); 076 } 077 } 078 } 079 if((flags & Flags.ACC_VARARGS) != 0) { 080 int lastIndex = parameterList.getNumChildNoTransform() - 1; 081 ParameterDeclaration p = (ParameterDeclaration)parameterList.getChildNoTransform(lastIndex); 082 parameterList.setChild( 083 new VariableArityParameterDeclaration( 084 p.getModifiersNoTransform(), 085 ((ArrayTypeAccess)p.getTypeAccessNoTransform()).getAccessNoTransform(), 086 p.getID() 087 ), 088 lastIndex 089 ); 090 } 091 List exceptionList = (s != null && s.hasExceptionList()) ? s.exceptionList() : attributes.exceptionList(); 092 093 if(attributes.parameterAnnotations != null) { 094 for(int i = 0; i < attributes.parameterAnnotations.length; i++) { 095 ParameterDeclaration p = (ParameterDeclaration)parameterList.getChildNoTransform(i); 096 for(Iterator iter = attributes.parameterAnnotations[i].iterator(); iter.hasNext(); ) { 097 Modifier m = (Modifier)iter.next(); 098 p.getModifiersNoTransform().addModifier(m); 099 } 100 } 101 } 102 103 BodyDecl b; 104 if(isConstructor()) { 105 b = new ConstructorDecl(BytecodeParser.modifiers(flags), name, parameterList, 106 exceptionList, new Opt(), new Block()); 107 } 108 else if(attributes.elementValue() != null) { 109 b = new AnnotationMethodDecl(BytecodeParser.modifiers(flags), returnType, name, 110 parameterList, exceptionList, 111 new Opt(new Block()), new Opt(attributes.elementValue())); 112 } 113 else if(s != null && s.hasFormalTypeParameters()) { 114 b = new GenericMethodDecl(BytecodeParser.modifiers(flags), returnType, name, parameterList, 115 exceptionList, new Opt(new Block()), s.typeParameters()); 116 } 117 else { 118 b = new MethodDecl(BytecodeParser.modifiers(flags), returnType, name, parameterList, 119 exceptionList, new Opt(new Block())); 120 } 121 if(attributes.annotations != null) { 122 for(Iterator iter = attributes.annotations.iterator(); iter.hasNext(); ) { 123 if(b instanceof MethodDecl) 124 ((MethodDecl)b).getModifiers().addModifier((Modifier)iter.next()); 125 else if(b instanceof ConstructorDecl) 126 ((ConstructorDecl)b).getModifiers().addModifier((Modifier)iter.next()); 127 } 128 } 129 return b; 130 } 131 132 133 134 private boolean isConstructor() { 135 return name.equals("<init>"); 136 } 137 138 139 140 public boolean isSynthetic() { 141 return attributes.isSynthetic() || (flags & 0x1000) != 0; 142 } 143 144 145 }