javamethod.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 543 行

JAVA
543
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.bytecode;import com.caucho.log.Log;import java.io.ByteArrayInputStream;import java.io.IOException;import java.lang.reflect.*;import java.util.ArrayList;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a java field. */public class JavaMethod extends JMethod {  static private final Logger log = Log.open(JavaMethod.class);  private static final JClass []NULL_CLASS = new JClass[0];  private JavaClassLoader _loader;  private JavaClass _jClass;  private int _accessFlags;  private String _name;  private String _descriptor;  private JClass []_exceptions = NULL_CLASS;  private int _line = -1;  private ArrayList<Attribute> _attributes = new ArrayList<Attribute>();  private JavaAnnotation []_annotations;  private boolean _isWrite;  public JavaMethod(JavaClassLoader loader)  {    _loader = loader;  }  public JavaMethod()  {  }  /**   * Sets the JavaClass.   */  public void setJavaClass(JavaClass jClass)  {    _jClass = jClass;  }  public void setWrite(boolean isWrite)  {    _isWrite = isWrite;  }  /**   * Sets the name.   */  public void setName(String name)  {    _name = name;    if (_jClass != null)      _jClass.getConstantPool().addUTF8(name);  }  /**   * Gets the name.   */  public String getName()  {    return _name;  }  /**   * Returns the line number.   */  public int getLine()  {    if (_line >= 0)      return _line;    Attribute attr = getAttribute("LineNumberTable");    if (attr == null) {      _line = 0;      return _line;    }    _line = 0;    return _line;  }  /**   * Returns the class loader.   */  public JavaClassLoader getClassLoader()  {    return _loader;  }  /**   * Sets the access flags   */  public void setAccessFlags(int flags)  {    _accessFlags = flags;  }  /**   * Gets the access flags   */  public int getAccessFlags()  {    return _accessFlags;  }  /**   * Returns true for a final method   */  public boolean isFinal()  {    return Modifier.isFinal(getAccessFlags());  }  /**   * Returns true for a public method   */  public boolean isPublic()  {    return Modifier.isPublic(getAccessFlags());  }  /**   * Returns true for a protected method   */  public boolean isProtected()  {    return Modifier.isProtected(getAccessFlags());  }  /**   * Returns true for a private method   */  public boolean isPrivate()  {    return Modifier.isPrivate(getAccessFlags());  }  /**   * Returns true for an abstract method   */  public boolean isAbstract()  {    return Modifier.isAbstract(getAccessFlags());  }  /**   * Returns true for a static method   */  public boolean isStatic()  {    return Modifier.isStatic(getAccessFlags());  }  /**   * Sets the descriptor.   */  public void setDescriptor(String descriptor)  {    _descriptor = descriptor;    if (_jClass != null)      _jClass.getConstantPool().addUTF8(descriptor);  }  /**   * Gets the descriptor.   */  public String getDescriptor()  {    return _descriptor;  }  /**   * Returns the declaring class.   */  public JClass getDeclaringClass()  {    return _jClass;  }  /**   * Returns the return types.   */  public JClass getReturnType()  {    String descriptor = getDescriptor();    int i = descriptor.lastIndexOf(')');    return getClassLoader().descriptorToClass(descriptor, i + 1);  }  /**   * Returns the return type.   */  public JType getGenericReturnType()  {    SignatureAttribute sigAttr = (SignatureAttribute) getAttribute("Signature");    if (sigAttr != null) {      String sig = sigAttr.getSignature();      int t = sig.lastIndexOf(')');      return _loader.parseParameterizedType(sig.substring(t + 1));    }    return getReturnType();  }  /**   * Returns the parameter types.   */  public JClass []getParameterTypes()  {    String descriptor = getDescriptor();    ArrayList<JClass> typeList = new ArrayList<JClass>();    int i = 0;    while ((i = nextDescriptor(descriptor, i)) >= 0) {      typeList.add(getClassLoader().descriptorToClass(descriptor, i));    }    JClass []types = new JClass[typeList.size()];    typeList.toArray(types);    return types;  }  private int nextDescriptor(String name, int i)  {    switch (name.charAt(i)) {    case ')':      return -1;    case '(':    case 'V':    case 'Z':    case 'C':    case 'B':    case 'S':    case 'I':    case 'J':    case 'F':    case 'D':      i += 1;      break;    case '[':      return nextDescriptor(name, i + 1);    case 'L':      {  int tail = name.indexOf( ';', i);  if (tail < 0)    throw new IllegalStateException();  i = tail + 1;      }      break;    default:      throw new UnsupportedOperationException(name.substring(i));    }    if (name.length() <= i)      return -1;    else if (name.charAt(i) == ')')      return -1;    else      return i;  }  /**   * Sets the exception types   */  public void setExceptionTypes(JClass []exceptions)  {    _exceptions = exceptions;  }  /**   * Returns the exception types.   */  public JClass []getExceptionTypes()  {    return _exceptions;  }  /**   * Adds an attribute.   */  public void addAttribute(Attribute attr)  {    _attributes.add(attr);  }  public CodeWriterAttribute createCodeWriter()  {    CodeWriterAttribute code = new CodeWriterAttribute(_jClass);    _attributes.add(code);    return code;  }  /**   * Removes an attribute.   */  public Attribute removeAttribute(String name)  {    for (int i = _attributes.size() - 1; i >= 0; i--) {      Attribute attr = _attributes.get(i);      if (attr.getName().equals(name)) {	_attributes.remove(i);	return attr;      }    }    return null;  }  /**   * Returns the attribute.   */  public ArrayList<Attribute> getAttributes()  {    return _attributes;  }  /**   * Returns the attribute.   */  public Attribute getAttribute(String name)  {    for (int i = _attributes.size() - 1; i >= 0; i--) {      Attribute attr = _attributes.get(i);      if (attr.getName().equals(name))	return attr;    }    return null;  }  /**   * Returns the declared annotations.   */  public JAnnotation []getDeclaredAnnotations()  {    if (_annotations == null) {      Attribute attr = getAttribute("RuntimeVisibleAnnotations");      if (attr instanceof OpaqueAttribute) {	byte []buffer = ((OpaqueAttribute) attr).getValue();	try {	  ByteArrayInputStream is = new ByteArrayInputStream(buffer);	  ConstantPool cp = _jClass.getConstantPool();	  _annotations = JavaAnnotation.parseAnnotations(is, cp,							 getClassLoader());	} catch (IOException e) {	  log.log(Level.FINER, e.toString(), e);	}      }      if (_annotations == null) {	_annotations = new JavaAnnotation[0];      }    }    return _annotations;  }  /**   * Returns the code attribute.   */  public CodeAttribute getCode()  {    for (int i = 0; i < _attributes.size(); i++) {      Attribute attr = _attributes.get(i);      if (attr instanceof CodeAttribute)	return (CodeAttribute) attr;    }    return null;  }  /**   * Create the code attribute.   */  public CodeAttribute createCode()  {    CodeAttribute code = new CodeAttribute();        for (int i = 0; i < _attributes.size(); i++) {      Attribute attr = _attributes.get(i);      if (attr instanceof CodeAttribute)	return (CodeAttribute) attr;    }    return null;  }  /**   * Writes the field to the output.   */  public void write(ByteCodeWriter out)    throws IOException  {    out.writeShort(_accessFlags);    out.writeUTF8Const(_name);    out.writeUTF8Const(_descriptor);    out.writeShort(_attributes.size());    for (int i = 0; i < _attributes.size(); i++) {      Attribute attr = _attributes.get(i);      attr.write(out);    }  }  /**   * exports the method.   */  public JavaMethod export(JavaClass source, JavaClass target)  {    JavaMethod method = new JavaMethod(_loader);    method.setName(_name);    method.setDescriptor(_descriptor);    method.setAccessFlags(_accessFlags);    target.getConstantPool().addUTF8(_name);    target.getConstantPool().addUTF8(_descriptor);    for (int i = 0; i < _attributes.size(); i++) {      Attribute attr = _attributes.get(i);      method.addAttribute(attr.export(source, target));    }    return method;  }  /**   * Concatenates the method.   */  public void concatenate(JavaMethod tail)  {    CodeAttribute codeAttr = getCode();    CodeAttribute tailCodeAttr = tail.getCode();    byte []code = codeAttr.getCode();    byte []tailCode = tailCodeAttr.getCode();    int codeLength = code.length;    if ((code[codeLength - 1] & 0xff) == CodeVisitor.RETURN)      codeLength = codeLength - 1;    byte []newCode = new byte[codeLength + tailCode.length];    System.arraycopy(code, 0, newCode, 0, codeLength);    System.arraycopy(tailCode, 0, newCode, codeLength, tailCode.length);    codeAttr.setCode(newCode);    if (codeAttr.getMaxStack() < tailCodeAttr.getMaxStack())      codeAttr.setMaxStack(tailCodeAttr.getMaxStack());    if (codeAttr.getMaxLocals() < tailCodeAttr.getMaxLocals())      codeAttr.setMaxLocals(tailCodeAttr.getMaxLocals());    ArrayList<CodeAttribute.ExceptionItem> exns = tailCodeAttr.getExceptions();    for (int i = 0; i < exns.size();  i++) {      CodeAttribute.ExceptionItem exn = exns.get(i);      CodeAttribute.ExceptionItem newExn = new CodeAttribute.ExceptionItem();      newExn.setType(exn.getType());      newExn.setStart(exn.getStart() + codeLength);      newExn.setEnd(exn.getEnd() + codeLength);      newExn.setHandler(exn.getHandler() + codeLength);    }  }  public String toString()  {    return "JavaMethod[" + _name + "]";  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?