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    }