Exemplo n.º 1
0
  private static Map<String, Long> getMessageSVUID(Type messageType)
      throws SJIOException,
          ClassNotFoundException // SJCompilerUtils has a simpler version of this routine.
      {
    HashMap<String, Long> ours = new HashMap<String, Long>();

    if (messageType
        instanceof
        SJSessionType) // Should come before ordinary class cases? (But SJSessionType shouldn't be a
                       // class type).
    {
      ours.putAll(getClassSVUIDs((SJSessionType) messageType));
    } else if (messageType.isPrimitive()) {
      // No SVUID needed for primitive types.
    } else if (messageType.isClass()) // Duplicated from above.
    {
      String className = messageType.toClass().fullName();
      Class<?> c = Class.forName(className);

      if (c.isInterface()) {
        // Interfaces don't have SVUIDs (so what should we do here?). // This encourages use of
        // abstract classes rather than interfaces for message types?
      } else {
        ObjectStreamClass osc = ObjectStreamClass.lookup(c);

        if (osc == null) {
          throw new SJIOException("Class not serializable: " + c);
        }

        ours.put(
            className,
            osc
                .getSerialVersionUID()); // Not possible to find a different SVUID for the same
                                         // (name) class here? // SVUIDs could be recorded in the
                                         // session type objects. // Put currently problems working
                                         // with these values at compilation time if the class
                                         // binary is not available a priori (SVUID value not built
                                         // yet?).
      }
    } else if (messageType.isArray()) {
      throw new SJIOException("Array types not done yet: " + messageType);
    }

    return ours;
  }
  public boolean callValid(Type thisType, List<Type> argTypes, Context context) {
    JL5TypeSystem ts = (JL5TypeSystem) typeSystem();
    List<Type> l1 = this.formalTypes();
    List<Type> l2 = argTypes;
    if ((l1.size() == 0) && (l2.size() != 0)) return false;

    Iterator<Type> itCallee = l1.iterator();
    Iterator<Type> itCaller = l2.iterator();

    // caller can either:
    // - have one argument less than callee (last argument of
    //   callee is a varargs and caller do not provide a value)
    // - have same number of args. The last arg being either
    //		- same type as the last arg of callee
    //		- or same type as the last arg of callee which is a varargs array
    //		- or an array of same type as the last arg of callee (which could be a varargs array)
    // - have more args, then:
    //		- last args of callee must be a varargs array
    //		- all extra args provided by the caller must match
    //        the varargs array type of the callee.

    while (itCallee.hasNext() && itCaller.hasNext()) {
      Type t1 = itCallee.next();
      Type t2 = itCaller.next();

      // Varargs can be used only in the final argument position
      // When we reach the final argument, we check if it is varargs array.
      if (!itCallee.hasNext() && t1.isArray() && ((JL5ArrayType) t1).isVarargs()) {
        JL5ArrayType vartype = (JL5ArrayType) t1;
        // Every arguments remaining in the second iterator must match the type
        // of the varargs array

        if (!itCaller.hasNext()) {
          // if we also reached the last element of the caller,
          // check if the type matches or if it is an array
          return ts.isImplicitCastValid(t2, vartype, context)
              || ts.isImplicitCastValid(t2, vartype.base(), context);
        } else {
          // There are several arguments left, they should all match the callee's varargs array
          // type.
          while (itCaller.hasNext()) { // eat up actual args
            if (!ts.isImplicitCastValid(t2, vartype.base(), context)) {
              return false;
            }
            t2 = itCaller.next();
          }
        }
      } else {
        if (!ts.isImplicitCastValid(t2, t1, context)) {
          return false;
        }
      }
    }
    // Caller provided less args than the callee has, which is legal
    // if callee is a variable arity method
    if (itCallee.hasNext() && isVariableArrity()) {
      itCallee.next();
    }

    // and we've reached callee's last arg.
    return !(itCallee.hasNext() || itCaller.hasNext());
  }