/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.types.reflect; import polyglot.types.*; import java.util.*; import java.io.*; import java.lang.reflect.Modifier; /** * Method represents a method in a Java classfile. A method's name and * value (the types of its parameters and its return type) are modeled * as indices into it class's constant pool. A method has modifiers * that determine whether it is public, private, static, final, etc. * Methods have a number of attributes such as their Code and any * Exceptions they may throw. * * @see polyglot.types.reflect Code * @see polyglot.types.reflect Exceptions * * @author Nate Nystrom * (<a href="mailto:nystrom@cs.purdue.edu">nystrom@cs.purdue.edu</a>) */ public class Method { protected ClassFile clazz; protected DataInputStream in; protected int modifiers; protected int name; protected int type; protected Attribute[] attrs; protected Exceptions exceptions; protected Signature signature; protected boolean synthetic; /** * Constructor. Read a method from a class file. * * @param in * The data stream of the class file. * @param clazz * The class file containing the method. * @exception IOException * If an error occurs while reading. */ public Method(DataInputStream in, ClassFile clazz) { this.clazz = clazz; this.in = in; } private static final int SYNTHETIC = 0x00001000; public static boolean isSynthetic(int bits) { return (bits & Modifier.VOLATILE) != 0 || (bits & SYNTHETIC) != 0; } public void initialize() throws IOException { modifiers = in.readUnsignedShort(); if (isSynthetic(modifiers)) { synthetic = true; } name = in.readUnsignedShort(); type = in.readUnsignedShort(); int numAttributes = in.readUnsignedShort(); attrs = new Attribute[numAttributes]; for (int i = 0; i < numAttributes; i++) { int nameIndex = in.readUnsignedShort(); int length = in.readInt(); Constant name = clazz.getConstants()[nameIndex]; if (name != null) { if ("Exceptions".equals(name.value())) { exceptions = new Exceptions(clazz, in, nameIndex, length); attrs[i] = exceptions; } if ("Synthetic".equals(name.value())) { synthetic = true; } if ("Signature".equals(name.value())) { signature = new Signature(clazz, in, nameIndex, length); attrs[i] = signature; } } if (attrs[i] == null) { long n = in.skip(length); if (n != length) { throw new EOFException(); } } } } public boolean isSynthetic() { return synthetic; } public Attribute[] getAttrs() { return attrs; } public ClassFile getClazz() { return clazz; } public Exceptions getExceptions() { return exceptions; } public int getModifiers() { return modifiers; } public int getName() { return name; } public int getType() { return type; } public Signature getSignature() { return signature; } public String name() { return (String) clazz.getConstants()[this.name].value(); } public String signature() { if (this.signature != null) { return (String) clazz.getConstants()[this.signature.getSignature()].value(); } return (String) clazz.getConstants()[this.type].value(); } public String toString() { return Modifier.toString(modifiers)+"("+Integer.toHexString(modifiers)+") "+name()+signature(); } }