示例#1
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;
  }