methodaccess.java

来自「JDK1.4编译器后端」· Java 代码 · 共 808 行 · 第 1/2 页

JAVA
808
字号

package AST;
import java.util.HashSet;import java.util.LinkedHashSet;import java.io.FileNotFoundException;import java.io.File;import java.util.*;import beaver.*;import java.util.ArrayList;import java.util.zip.*;import java.io.*;public class MethodAccess extends Access implements Cloneable {
    public void flushCache() {        super.flushCache();        computeDAbefore_int_Variable_values = null;        exceptionCollection_computed = false;        exceptionCollection_value = null;        decls_computed = false;        decls_value = null;        decl_computed = false;        decl_value = null;        type_computed = false;        type_value = null;    }     @SuppressWarnings({"unchecked", "cast"})  public MethodAccess clone() throws CloneNotSupportedException {        MethodAccess node = (MethodAccess)super.clone();        node.computeDAbefore_int_Variable_values = null;        node.exceptionCollection_computed = false;        node.exceptionCollection_value = null;        node.decls_computed = false;        node.decls_value = null;        node.decl_computed = false;        node.decl_value = null;        node.type_computed = false;        node.type_value = null;        node.in$Circle(false);        node.is$Final(false);    return node;    }     @SuppressWarnings({"unchecked", "cast"})  public MethodAccess copy() {      try {          MethodAccess node = (MethodAccess)clone();          if(children != null) node.children = (ASTNode[])children.clone();          return node;      } catch (CloneNotSupportedException e) {      }      System.err.println("Error: Could not clone node of type " + getClass().getName() + "!");      return null;    }     @SuppressWarnings({"unchecked", "cast"})  public MethodAccess fullCopy() {        MethodAccess res = (MethodAccess)copy();        for(int i = 0; i < getNumChildNoTransform(); i++) {          ASTNode node = getChildNoTransform(i);          if(node != null) node = node.fullCopy();          res.setChild(node, i);        }        return res;    }    // Declared in AnonymousClasses.jrag at line 149  protected void collectExceptions(Collection c, ASTNode target) {    super.collectExceptions(c, target);    for(int i = 0; i < decl().getNumException(); i++)      c.add(decl().getException(i).type());  }    // Declared in ExceptionHandling.jrag at line 43    public void exceptionHandling() {    for(Iterator iter = exceptionCollection().iterator(); iter.hasNext(); ) {      TypeDecl exceptionType = (TypeDecl)iter.next();      if(!handlesException(exceptionType))        error("" + decl().hostType().fullName() + "." + this + " invoked in " + hostType().fullName() + " may throw uncaught exception " + exceptionType.fullName());    }  }    // Declared in ExceptionHandling.jrag at line 225  protected boolean reachedException(TypeDecl catchType) {    for(Iterator iter = exceptionCollection().iterator(); iter.hasNext(); ) {      TypeDecl exceptionType = (TypeDecl)iter.next();      if(catchType.mayCatch(exceptionType))        return true;    }    return super.reachedException(catchType);  }    // Declared in LookupMethod.jrag at line 113  private static SimpleSet removeInstanceMethods(SimpleSet c) {    SimpleSet set = SimpleSet.emptySet;    for(Iterator iter = c.iterator(); iter.hasNext(); ) {      MethodDecl m = (MethodDecl)iter.next();      if(m.isStatic())        set = set.add(m);    }    return set;  }    // Declared in LookupMethod.jrag at line 152    public boolean applicable(MethodDecl decl) {    if(getNumArg() != decl.getNumParameter())      return false;    if(!name().equals(decl.name()))      return false;    for(int i = 0; i < getNumArg(); i++) {      if(!getArg(i).type().instanceOf(decl.getParameter(i).type()))        return false;    }    return true;  }    // Declared in NodeConstructors.jrag at line 56  public MethodAccess(String name, List args, int start, int end) {    this(name, args);    setStart(start);    setEnd(end);  }    // Declared in PrettyPrint.jadd at line 473  public void toString(StringBuffer s) {    s.append(name());    s.append("(");    if(getNumArg() > 0) {      getArg(0).toString(s);      for(int i = 1; i < getNumArg(); i++) {        s.append(", ");        getArg(i).toString(s);      }    }    s.append(")");  }    // Declared in TypeCheck.jrag at line 124  // 5.3 Method Invocation Conversion  public void typeCheck() {    for(int i = 0; i < decl().getNumParameter(); i++) {      TypeDecl exprType = getArg(i).type();      TypeDecl parmType = decl().getParameter(i).type();      if(!exprType.methodInvocationConversionTo(parmType) && !exprType.isUnknown() && !parmType.isUnknown()) {        error("The type " + exprType.typeName() + " of expr " +            getArg(i) + " is not compatible with the method parameter " +            decl().getParameter(i));      }    }  }    // Declared in TypeHierarchyCheck.jrag at line 23    public void nameCheck() {    if(isQualified() && qualifier().isPackageAccess() && !qualifier().isUnknown())      error("The method " + decl().signature() +           " can not be qualified by a package name.");    if(isQualified() && decl().isAbstract() && qualifier().isSuperAccess())      error("may not access abstract methods in superclass");    if(decls().isEmpty() && (!isQualified() || !qualifier().isUnknown())) {      StringBuffer s = new StringBuffer();      s.append("no method named " + name());      s.append("(");      for(int i = 0; i < getNumArg(); i++) {        if(i != 0)          s.append(", ");        s.append(getArg(i).type().typeName());      }      s.append(")" + " in " + methodHost() + " matches.");      if(singleCandidateDecl() != null)        s.append(" However, there is a method " + singleCandidateDecl().signature());      error(s.toString());    }    if(decls().size() > 1) {      boolean allAbstract = true;      for(Iterator iter = decls().iterator(); iter.hasNext() && allAbstract; ) {         MethodDecl m = (MethodDecl)iter.next();        if(!m.isAbstract() && !m.hostType().isObject())          allAbstract = false;      }      if(!allAbstract && validArgs()) {        StringBuffer s = new StringBuffer();        s.append("several most specific methods for " + this + "\n");        for(Iterator iter = decls().iterator(); iter.hasNext(); ) {          MethodDecl m = (MethodDecl)iter.next();          s.append("    " + m.signature() + " in " + m.hostType().typeName() + "\n");        }        error(s.toString());      }           }  }    // Declared in CreateBCode.jrag at line 492  public void createBCode(CodeGeneration gen) {    createLoadQualifier(gen);    if(decl().type().isUnknown()) {      System.err.println("Could not bind " + this);      for (int i = 0; i < getNumArg(); ++i) {        System.err.println("Argument " + getArg(i) + " is of type " + getArg(i).type().typeName());        if(getArg(i).varDecl() != null) System.err.println(getArg(i).varDecl() + " in " + getArg(i).varDecl().hostType().typeName());      }      if(isQualified())        System.err.println("Qualifier " + qualifier() + " is of type " + qualifier().type().typeName());      throw new Error("Could not bind " + this);    }    if(decl().getNumParameter() != getNumArg()) {      System.out.println(this + " does not have the same number of arguments as " + decl());    }    for (int i = 0; i < getNumArg(); ++i) {      getArg(i).createBCode(gen);      getArg(i).type().emitCastTo(gen, decl().getParameter(i).type()); // MethodInvocationConversion    }    /*    if(decl().isPrivate() && !hostType().hasMethod(name())) {      decl().emitInvokeMethodAccessor(gen, methodQualifierType());    }        else*/ {      if(!decl().isStatic() && isQualified() && prevExpr().isSuperAccess()) {        if(!hostType().instanceOf(prevExpr().type()))          decl().createSuperAccessor(superAccessorTarget()).emitInvokeMethod(gen, superAccessorTarget());        else          decl().emitInvokeSpecialMethod(gen, methodQualifierType());      }      else        decl().emitInvokeMethod(gen, methodQualifierType());    }  }    // Declared in CreateBCode.jrag at line 528  protected void createLoadQualifier(CodeGeneration gen) {    MethodDecl m = decl();    if(hasPrevExpr()) {      // load explicit qualifier      prevExpr().createBCode(gen);      // pop qualifier stack element for class variables      // this qualifier must be computed to ensure side effects      if(m.isStatic() && !prevExpr().isTypeAccess())        prevExpr().type().emitPop(gen);    }    else if(!m.isStatic()) {      // load implicit this qualifier      emitThis(gen, methodQualifierType());    }  }    // Declared in InnerClasses.jrag at line 48  private TypeDecl methodQualifierType() {    if(hasPrevExpr())      return prevExpr().type();    TypeDecl typeDecl = hostType();    while(typeDecl != null && !typeDecl.hasMethod(name()))      typeDecl = typeDecl.enclosingType();    if(typeDecl != null)      return typeDecl;    return decl().hostType();  }    // Declared in InnerClasses.jrag at line 110  public TypeDecl superAccessorTarget() {    TypeDecl targetDecl = prevExpr().type();    TypeDecl enclosing = hostType();    do {      enclosing = enclosing.enclosingType();    } while (!enclosing.instanceOf(targetDecl));    return enclosing;  }    // Declared in Transformations.jrag at line 69    /*  public void Dot.transformation() {    if(leftSide().isTypeAccess() && rightSide() instanceof ThisAccess) {      System.out.println("Replacing " + this);      Access a = new ThisAccess("this");      TypeDecl targetType = rightSide().type();      TypeDecl typeDecl = hostType();      while(typeDecl != null && typeDecl != targetType) {        a = a.qualifiesAccess(new VarAccess("this$0"));        typeDecl = typeDecl.enclosingType();      }      ASTNode result = replace(this).with(qualifyTailWith(a));      result.transformation();      return;    }    super.transformation();  }*/  // remote collection / demand driven creation of accessor  public void transformation() {    MethodDecl m = decl();    /*if(!isQualified() && !m.isStatic()) {      TypeDecl typeDecl = hostType();      while(typeDecl != null && !typeDecl.hasMethod(name()))        typeDecl = typeDecl.enclosingType();      ASTNode result = replace(this).with(typeDecl.createQualifiedAccess().qualifiesAccess(new ThisAccess("this")).qualifiesAccess(new MethodAccess(name(), getArgList())));      result.transformation();      return;    }*/        if(m.isPrivate() && m.hostType() != hostType()/*.hasMethod(name()*/) {      /* Access to private methods in enclosing types:      The original MethodAccess is replaced with an access to an accessor method      built by createAccessor(). This method is built lazily and differs from      normal MethodDeclarations in the following ways:      1) The method in the class file should always be static and the signature         is thus changed to include a possible this reference as the first argument.       2) The method is always invoked using INVOKESTATIC      3) The flags must indicate that the method is static and package private      */      replace(this).with(decl().createAccessor(methodQualifierType()).createBoundAccess(getArgList()));      return;    }    else if(!m.isStatic() && isQualified() && prevExpr().isSuperAccess() && !hostType().instanceOf(prevExpr().type())) {      decl().createSuperAccessor(superAccessorTarget());    }    super.transformation();  }    // Declared in java.ast at line 3    // Declared in java.ast line 17
    public MethodAccess() {        super();
        setChild(new List(), 0);

    }    // Declared in java.ast at line 11
    // Declared in java.ast line 17    public MethodAccess(String p0, List<Expr> p1) {        setID(p0);        setChild(p1, 0);    }    // Declared in java.ast at line 17    // Declared in java.ast line 17    public MethodAccess(beaver.Symbol p0, List<Expr> p1) {        setID(p0);        setChild(p1, 0);    }    // Declared in java.ast at line 22  protected int numChildren() {
    return 1;
  }    // Declared in java.ast at line 25
  public boolean mayHaveRewrite() { return false; }    // Declared in java.ast at line 2    // Declared in java.ast line 17    private String tokenString_ID;    // Declared in java.ast at line 3    public void setID(String value) {        tokenString_ID = value;    }    // Declared in java.ast at line 6    public int IDstart;    // Declared in java.ast at line 7    public int IDend;    // Declared in java.ast at line 8    public void setID(beaver.Symbol symbol) {        if(symbol.value != null && !(symbol.value instanceof String))          throw new UnsupportedOperationException("setID is only valid for String lexemes");        tokenString_ID = (String)symbol.value;        IDstart = symbol.getStart();        IDend = symbol.getEnd();    }    // Declared in java.ast at line 15    public String getID() {        return tokenString_ID != null ? tokenString_ID : "";

⌨️ 快捷键说明

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