예제 #1
0
  protected Node typeCheckNullTarget(
      TypeChecker tc, List<Type> paramTypes, List<Type> explicitTypeArgs) throws SemanticException {
    JL5TypeSystem ts = (JL5TypeSystem) tc.typeSystem();
    JL5NodeFactory nf = (JL5NodeFactory) tc.nodeFactory();
    JL5Context c = (JL5Context) tc.context();

    // the target is null, and thus implicit
    // let's find the target, using the context, and
    // set the target appropriately, and then type check
    // the result
    JL5MethodInstance mi = c.findJL5Method(this.name(), paramTypes, explicitTypeArgs);

    Receiver r;
    if (mi.flags().isStatic()) {
      r = nf.CanonicalTypeNode(position(), mi.container()).type(mi.container());
    } else {
      // The method is non-static, so we must prepend with "this", but we
      // need to determine if the "this" should be qualified. Get the
      // enclosing class which brought the method into scope. This is
      // different from mi.container(). mi.container() returns a super
      // type
      // of the class we want.
      ClassType scope = c.findMethodScope(name);

      if (!ts.equals(scope, c.currentClass())) {
        r = nf.This(position(), nf.CanonicalTypeNode(position(), scope)).type(scope);
      } else {
        r = nf.This(position()).type(scope);
      }
    }

    // we call typeCheck on the reciever too.
    r = (Receiver) r.del().typeCheck(tc);
    return this.targetImplicit(true).target(r).del().typeCheck(tc);
  }
예제 #2
0
  public Node typeCheck(TypeChecker tc) throws SemanticException {
    JL5Call_c n = null;
    JL5TypeSystem ts = (JL5TypeSystem) tc.typeSystem();
    JL5Context c = (JL5Context) tc.context();
    ReferenceType targetType = null;
    List<Type> explicitTypeArgs = null;
    List<Type> paramTypes = new ArrayList<Type>();

    if (typeArguments != null && !typeArguments.isEmpty()) {
      explicitTypeArgs = new ArrayList<Type>();
      if (target() == null) {
        // should not actually happen. grammar doesn't allow it
        throw new SemanticException(
            "Explicit target required when using explicit type arguments", position());
      }
      for (Iterator it = typeArguments().iterator(); it.hasNext(); ) {
        explicitTypeArgs.add(((TypeNode) it.next()).type());
      }
    }

    for (Iterator i = this.arguments().iterator(); i.hasNext(); ) {
      Expr e = (Expr) i.next();
      paramTypes.add(e.type());
    }

    JL5MethodInstance mi;
    // JLS 15.12.1
    if (target == null) {
      return typeCheckNullTarget(tc, paramTypes, explicitTypeArgs);
    } else {
      targetType = this.findTargetType();
      mi = ts.findJL5Method(targetType, name, paramTypes, explicitTypeArgs, c);
    }

    boolean staticContext = (this.target instanceof TypeNode);

    if (staticContext && !mi.flags().isStatic()) {
      throw new SemanticException(
          "Cannot call non-static method "
              + this.name
              + " of "
              + targetType
              + " in static "
              + "context.",
          this.position());
    }

    if (this.target instanceof Special
        && ((Special) this.target).kind() == Special.SUPER
        && mi.flags().isAbstract()) {
      throw new SemanticException(
          "Cannot call an abstract method " + "of the super class", this.position());
    }

    n = (JL5Call_c) this.methodInstance(mi).type(mi.returnType());
    // n.checkConsistency(c);
    return n;
  }