コード例 #1
0
  /**
   * This method is used to implement constructor invocation.
   *
   * @param c the declaring class of the constructor
   * @param cpd the parameter descriptor
   * @param args the arguments passed to this constructor
   * @return the arguments to give to the 'super' or 'this' constructor followed by the new values
   *     of the constructor arguments
   */
  protected Object[] interpretArguments(
      final Class c, final ConstructorParametersDescriptor cpd, final Object[] args) {
    if (cpd.variables == null) {
      cpd.importationManager.setClassLoader(this.classLoader);

      final Context ctx = new StaticContext(this, c, cpd.importationManager);
      ctx.setAdditionalClassLoaderContainer(this.classLoader);
      final Visitor nv = new NameVisitor(ctx);
      final Visitor tc = new TypeChecker(ctx);

      // Check the parameters
      if (cpd.parameters != null) {
        final ListIterator it = cpd.parameters.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(tc);
        }
      }

      if (cpd.arguments != null) {
        ListIterator it = cpd.arguments.listIterator();
        while (it.hasNext()) {
          final Node root = (Node) it.next();
          final Object res = root.acceptVisitor(nv);
          if (res != null) {
            it.set(res);
          }
        }

        it = cpd.arguments.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(tc);
        }
      }
      cpd.variables = ctx.getCurrentScopeVariables();
    }

    final Context ctx = new StaticContext(this, c, cpd.variables);
    ctx.setAdditionalClassLoaderContainer(this.classLoader);

    // Set the arguments values
    if (cpd.parameters != null) {
      final Iterator it = cpd.parameters.iterator();
      int i = 0;
      while (it.hasNext()) {
        ctx.set(((FormalParameter) it.next()).getName(), args[i++]);
      }
    }

    Object[] result = new Object[0];

    if (cpd.arguments != null) {
      final Visitor v = new EvaluationVisitor(ctx);
      final ListIterator it = cpd.arguments.listIterator();
      result = new Object[cpd.arguments.size()];
      int i = 0;
      while (it.hasNext()) {
        result[i++] = ((Node) it.next()).acceptVisitor(v);
      }
    }

    return result;
  }
コード例 #2
0
  /**
   * Interprets the body of a method
   *
   * @param c the declaring class of the method
   * @param md the method descriptor
   * @param obj the object (this)
   * @param params the arguments
   */
  protected Object interpretMethod(
      final Class c, final MethodDescriptor md, final Object obj, final Object[] params) {
    final MethodDeclaration meth = md.method;
    final List mparams = meth.getParameters();
    final List stmts = meth.getBody().getStatements();
    final String name = meth.getName();

    Context context = null;

    if (Modifier.isStatic(md.method.getAccessFlags())) {
      if (md.variables == null) {
        md.importationManager.setClassLoader(this.classLoader);

        // pass 1: names resolution
        Context ctx = new StaticContext(this, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        Visitor v = new NameVisitor(ctx);

        ListIterator it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          final Object o = ((Node) it.next()).acceptVisitor(v);
          if (o != null) {
            it.set(o);
          }
        }

        // pass 2: type checking
        ctx = new StaticContext(this, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        v = new TypeChecker(ctx);

        it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        md.variables = ctx.getCurrentScopeVariables();

        // Test of the additional context existence
        if (!name.equals("<clinit>") && !name.equals("<init>")) {
          try {
            md.contextField = c.getField("local$Variables$Reference$0");
          } catch (final NoSuchFieldException e) {
          }
        }
      }

      // pass 3: evaluation
      context = new StaticContext(this, c, md.variables);
    } else {
      if (md.variables == null) {
        md.importationManager.setClassLoader(this.classLoader);

        // pass 1: names resolution
        Context ctx = new MethodContext(this, c, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        Visitor v = new NameVisitor(ctx);

        Context ctx2 = new MethodContext(this, c, c, md.importationManager);
        ctx2.setAdditionalClassLoaderContainer(this.classLoader);
        Visitor v2 = new NameVisitor(ctx2);

        // Initializes the context with the outerclass variables
        Object[][] cc = null;
        try {
          final Field f = c.getField("local$Variables$Class$0");
          cc = (Object[][]) f.get(obj);
          for (int i = 0; i < cc.length; i++) {
            final Object[] cell = cc[i];
            if (!((String) cell[0]).equals("this")) {
              ctx.defineConstant((String) cell[0], cell[1]);
            }
          }
        } catch (final Exception e) {
        }

        // Visit the parameters and the body of the method
        ListIterator it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          final Node n = (Node) it.next();
          Object o = null;
          if (n.hasProperty(NodeProperties.INSTANCE_INITIALIZER)) {
            o = n.acceptVisitor(v2);
          } else {
            o = n.acceptVisitor(v);
          }
          if (o != null) {
            it.set(o);
          }
        }

        // pass 2: type checking
        ctx = new MethodContext(this, c, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        v = new TypeChecker(ctx);

        ctx2 = new MethodContext(this, c, c, md.importationManager);
        ctx2.setAdditionalClassLoaderContainer(this.classLoader);
        v2 = new TypeChecker(ctx2);

        // Initializes the context with outerclass variables
        if (cc != null) {
          for (int i = 0; i < cc.length; i++) {
            final Object[] cell = cc[i];
            if (!((String) cell[0]).equals("this")) {
              ctx.defineConstant((String) cell[0], cell[1]);
            }
          }
        }

        // Visit the parameters and the body of the method
        it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          final Node n = (Node) it.next();
          if (n.hasProperty(NodeProperties.INSTANCE_INITIALIZER)) {
            n.acceptVisitor(v2);
          } else {
            n.acceptVisitor(v);
          }
        }

        md.variables = ctx.getCurrentScopeVariables();

        // Test of the additional context existence
        if (!name.equals("<clinit>") && !name.equals("<init>")) {
          try {
            md.contextField = c.getField("local$Variables$Reference$0");
          } catch (final NoSuchFieldException e) {
          }
        }
      }

      // pass 3: evaluation
      context = new MethodContext(this, c, obj, md.variables);
    }

    context.setAdditionalClassLoaderContainer(this.classLoader);

    // Set the arguments values
    Iterator it = mparams.iterator();
    int i = 0;
    while (it.hasNext()) {
      context.set(((FormalParameter) it.next()).getName(), params[i++]);
    }

    // Set the final local variables values
    if (md.contextField != null) {
      Map vars = null;
      try {
        vars = (Map) md.contextField.get(obj);
      } catch (final IllegalAccessException e) {
      }
      if (vars != null) {
        it = vars.keySet().iterator();
        while (it.hasNext()) {
          final String s = (String) it.next();
          if (!s.equals("this")) {
            context.setConstant(s, vars.get(s));
          }
        }
      }
    }

    final Visitor v = new EvaluationVisitor(context);
    it = stmts.iterator();

    try {
      while (it.hasNext()) {
        ((Node) it.next()).acceptVisitor(v);
      }
    } catch (final ReturnException e) {
      return e.getValue();
    }
    return null;
  }