Esempio n. 1
0
 @Test
 public void testDatatypeMutability() throws Exception {
   assertTrue(EvalUtils.isImmutable("foo"));
   assertTrue(EvalUtils.isImmutable(3));
   assertTrue(EvalUtils.isImmutable(Tuple.of(1, 2, 3)));
   assertFalse(EvalUtils.isImmutable(MutableList.of(null, 1, 2, 3)));
   assertFalse(EvalUtils.isImmutable(makeDict()));
 }
Esempio n. 2
0
 protected String getObjectTypeString() {
   Class<?> clazz = getObjectType();
   if (clazz == null) {
     return "";
   }
   return EvalUtils.getDataTypeNameFromClass(clazz, false) + ".";
 }
Esempio n. 3
0
  /** check types and convert as required */
  protected void canonicalizeArguments(Object[] arguments, Location loc) throws EvalException {
    // TODO(bazel-team): maybe link syntax.SkylarkType and package.Type,
    // so we can simultaneously typecheck and convert?
    // Note that a BuiltinFunction already does typechecking of simple types.

    List<SkylarkType> types = getEnforcedArgumentTypes();

    // Check types, if supplied
    if (types == null) {
      return;
    }
    List<String> names = signature.getSignature().getNames();
    int length = types.size();
    for (int i = 0; i < length; i++) {
      Object value = arguments[i];
      SkylarkType type = types.get(i);
      if (value != null && type != null && !type.contains(value)) {
        throw new EvalException(
            loc,
            String.format(
                "expected %s for '%s' while calling %s but got %s instead: %s",
                type, names.get(i), getName(), EvalUtils.getDataTypeName(value, true), value));
      }
    }
  }
Esempio n. 4
0
 // The precondition ensures generic type safety
 @SuppressWarnings("unchecked")
 public <T> NestedSet<T> getSet(Class<T> type) {
   // Empty sets don't need have to have a type since they don't have items
   if (set.isEmpty()) {
     return (NestedSet<T>) set;
   }
   Preconditions.checkArgument(
       contentType.canBeCastTo(type),
       String.format(
           "Expected a set of '%s' but got a set of '%s'",
           EvalUtils.getDataTypeNameFromClass(type), contentType));
   return (NestedSet<T>) set;
 }
Esempio n. 5
0
 @Test
 public void testDataTypeNames() throws Exception {
   assertEquals("string", EvalUtils.getDataTypeName("foo"));
   assertEquals("int", EvalUtils.getDataTypeName(3));
   assertEquals("tuple", EvalUtils.getDataTypeName(Tuple.of(1, 2, 3)));
   assertEquals("list", EvalUtils.getDataTypeName(MutableList.of(null, 1, 2, 3)));
   assertEquals("dict", EvalUtils.getDataTypeName(makeDict()));
   assertEquals("NoneType", EvalUtils.getDataTypeName(Runtime.NONE));
 }
Esempio n. 6
0
  /**
   * Prints the types of the first {@code howManyArgsToPrint} given arguments as "(type1, type2,
   * ...)"
   */
  protected String printTypeString(Object[] args, int howManyArgsToPrint) {
    StringBuilder builder = new StringBuilder();
    builder.append("(");

    int start = hasSelfArgument() ? 1 : 0;
    for (int pos = start; pos < howManyArgsToPrint; ++pos) {
      builder.append(EvalUtils.getDataTypeName(args[pos]));

      if (pos < howManyArgsToPrint - 1) {
        builder.append(", ");
      }
    }
    builder.append(")");
    return builder.toString();
  }
Esempio n. 7
0
  // This is safe because of the type checking
  @SuppressWarnings("unchecked")
  private SkylarkNestedSet(
      Order order,
      SkylarkType contentType,
      Object item,
      Location loc,
      List<Object> items,
      List<NestedSet<Object>> transitiveItems)
      throws EvalException {

    // Adding the item
    if (item instanceof SkylarkNestedSet) {
      SkylarkNestedSet nestedSet = (SkylarkNestedSet) item;
      if (!nestedSet.isEmpty()) {
        contentType = checkType(contentType, nestedSet.contentType, loc);
        transitiveItems.add((NestedSet<Object>) nestedSet.set);
      }
    } else if (item instanceof SkylarkList) {
      // TODO(bazel-team): we should check ImmutableList here but it screws up genrule at line 43
      for (Object object : (SkylarkList) item) {
        contentType = checkType(contentType, SkylarkType.of(object.getClass()), loc);
        checkImmutable(object, loc);
        items.add(object);
      }
    } else {
      throw new EvalException(
          loc,
          String.format("cannot add value of type '%s' to a set", EvalUtils.getDataTypeName(item)));
    }
    this.contentType = Preconditions.checkNotNull(contentType, "type cannot be null");

    // Initializing the real nested set
    NestedSetBuilder<Object> builder = new NestedSetBuilder<>(order);
    builder.addAll(items);
    try {
      for (NestedSet<Object> nestedSet : transitiveItems) {
        builder.addTransitive(nestedSet);
      }
    } catch (IllegalStateException e) {
      throw new EvalException(loc, e.getMessage());
    }
    this.set = builder.build();
    this.items = ImmutableList.copyOf(items);
    this.transitiveItems = ImmutableList.copyOf(transitiveItems);
  }
Esempio n. 8
0
  @Override
  @Nullable
  public Object call(Object[] args, @Nullable FuncallExpression ast, @Nullable Environment env)
      throws EvalException, InterruptedException {
    final Location loc = (ast == null) ? location : ast.getLocation();

    // Add extra arguments, if needed
    if (extraArgs != null) {
      int i = args.length - extraArgs.length;
      for (BuiltinFunction.ExtraArgKind extraArg : extraArgs) {
        switch (extraArg) {
          case LOCATION:
            args[i] = loc;
            break;

          case SYNTAX_TREE:
            args[i] = ast;
            break;

          case ENVIRONMENT:
            args[i] = env;
            break;
        }
        i++;
      }
    }

    // Last but not least, actually make an inner call to the function with the resolved arguments.
    try {
      return invokeMethod.invoke(this, args);
    } catch (InvocationTargetException x) {
      Throwable e = x.getCause();
      if (e instanceof EvalException) {
        throw ((EvalException) e).ensureLocation(loc);
      } else if (e instanceof InterruptedException) {
        throw (InterruptedException) e;
      } else if (e instanceof ClassCastException
          || e instanceof ExecutionException
          || e instanceof IllegalStateException) {
        throw new EvalException(loc, "in call to " + getName(), e);
      } else if (e instanceof IllegalArgumentException) {
        throw new EvalException(loc, "Illegal argument in call to " + getName(), e);
      } else {
        throw badCallException(loc, e, args);
      }
    } catch (IllegalArgumentException e) {
      // Either this was thrown by Java itself, or it's a bug
      // To cover the first case, let's manually check the arguments.
      final int len = args.length - ((extraArgs == null) ? 0 : extraArgs.length);
      final Class<?>[] types = invokeMethod.getParameterTypes();
      for (int i = 0; i < args.length; i++) {
        if (args[i] != null && !types[i].isAssignableFrom(args[i].getClass())) {
          String paramName =
              i < len ? signature.getSignature().getNames().get(i) : extraArgs[i - len].name();
          int extraArgsCount = (extraArgs == null) ? 0 : extraArgs.length;
          throw new EvalException(
              loc,
              String.format(
                  "Method %s is not applicable for arguments %s: '%s' is %s, but should be %s",
                  getShortSignature(true),
                  printTypeString(args, args.length - extraArgsCount),
                  paramName,
                  EvalUtils.getDataTypeName(args[i]),
                  EvalUtils.getDataTypeNameFromClass(types[i])));
        }
      }
      throw badCallException(loc, e, args);
    } catch (IllegalAccessException e) {
      throw badCallException(loc, e, args);
    }
  }
Esempio n. 9
0
 private static void checkImmutable(Object o, Location loc) throws EvalException {
   if (!EvalUtils.isImmutable(o)) {
     throw new EvalException(loc, "sets cannot contain mutable items");
   }
 }
Esempio n. 10
0
 @Test
 public void testStringToIterable() throws Exception {
   assertThat(EvalUtils.toIterable("abc", null)).hasSize(3);
 }
Esempio n. 11
0
 @Test
 public void testEmptyStringToIterable() throws Exception {
   assertThat(EvalUtils.toIterable("", null)).isEmpty();
 }
Esempio n. 12
0
  /**
   * Print an official representation of object x. For regular data structures, the value should be
   * parsable back into an equal data structure.
   *
   * @param buffer the Appendable to write to.
   * @param o the string a representation of which to write.
   * @param quotationMark The quotation mark to be used (' or ")
   * @return the Appendable, in fluent style.
   */
  public static Appendable write(Appendable buffer, Object o, char quotationMark) {
    if (o == null) {
      throw new NullPointerException(); // Java null is not a build language value.

    } else if (o instanceof String) {
      writeString(buffer, (String) o, quotationMark);

    } else if (o instanceof Integer || o instanceof Double) {
      append(buffer, o.toString());

    } else if (o == Runtime.NONE) {
      append(buffer, "None");

    } else if (o == Boolean.TRUE) {
      append(buffer, "True");

    } else if (o == Boolean.FALSE) {
      append(buffer, "False");

    } else if (o instanceof List<?>) {
      List<?> seq = (List<?>) o;
      printList(buffer, seq, EvalUtils.isImmutable(seq), quotationMark);

    } else if (o instanceof SkylarkList) {
      SkylarkList list = (SkylarkList) o;
      printList(buffer, list.toList(), list.isTuple(), quotationMark);

    } else if (o instanceof Map<?, ?>) {
      Map<?, ?> dict = (Map<?, ?>) o;
      printList(buffer, getSortedEntrySet(dict), "{", ", ", "}", null, quotationMark);

    } else if (o instanceof Map.Entry<?, ?>) {
      Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
      write(buffer, entry.getKey(), quotationMark);
      append(buffer, ": ");
      write(buffer, entry.getValue(), quotationMark);

    } else if (o instanceof SkylarkNestedSet) {
      SkylarkNestedSet set = (SkylarkNestedSet) o;
      append(buffer, "set(");
      printList(buffer, set, "[", ", ", "]", null, quotationMark);
      Order order = set.getOrder();
      if (order != Order.STABLE_ORDER) {
        append(buffer, ", order = \"" + order.getName() + "\"");
      }
      append(buffer, ")");

    } else if (o instanceof BaseFunction) {
      BaseFunction func = (BaseFunction) o;
      append(buffer, "<function " + func.getName() + ">");

    } else if (o instanceof Label) {
      write(buffer, o.toString(), quotationMark);

    } else if (o instanceof FilesetEntry) {
      FilesetEntry entry = (FilesetEntry) o;
      append(buffer, "FilesetEntry(srcdir = ");
      write(buffer, entry.getSrcLabel().toString(), quotationMark);
      append(buffer, ", files = ");
      write(buffer, makeStringList(entry.getFiles()), quotationMark);
      append(buffer, ", excludes = ");
      write(buffer, makeList(entry.getExcludes()), quotationMark);
      append(buffer, ", destdir = ");
      write(buffer, entry.getDestDir().getPathString(), quotationMark);
      append(buffer, ", strip_prefix = ");
      write(buffer, entry.getStripPrefix(), quotationMark);
      append(buffer, ", symlinks = ");
      append(buffer, quotationMark);
      append(buffer, entry.getSymlinkBehavior().toString());
      append(buffer, quotationMark);
      append(buffer, ")");

    } else if (o instanceof PathFragment) {
      append(buffer, ((PathFragment) o).getPathString());

    } else {
      append(buffer, o.toString());
    }

    return buffer;
  }