@Override public Pair<FIRST, SECOND> coerce( BuildRuleResolver buildRuleResolver, Path pathRelativeToProjectRoot, Object object) throws CoerceFailedException { if (object instanceof Collection) { Collection<?> collection = (Collection<?>) object; if (collection.size() != 2) { throw CoerceFailedException.simple( pathRelativeToProjectRoot, object, getOutputClass(), "input collection should have 2 elements"); } Iterator<?> iterator = collection.iterator(); FIRST first = firstTypeCoercer.coerce(buildRuleResolver, pathRelativeToProjectRoot, iterator.next()); SECOND second = secondTypeCoercer.coerce(buildRuleResolver, pathRelativeToProjectRoot, iterator.next()); return new Pair<>(first, second); } else { throw CoerceFailedException.simple( pathRelativeToProjectRoot, object, getOutputClass(), "input object should be a 2-element collection"); } }
@Override public SourceWithFlags coerce( CellPathResolver cellRoots, ProjectFilesystem filesystem, Path pathRelativeToProjectRoot, Object object) throws CoerceFailedException { if (object instanceof SourceWithFlags) { return (SourceWithFlags) object; } // We're expecting one of two types here. They can be differentiated pretty easily. if (object instanceof String) { return SourceWithFlags.of( sourcePathTypeCoercer.coerce(cellRoots, filesystem, pathRelativeToProjectRoot, object)); } // If we get this far, we're dealing with a Pair of a SourcePath and a String. if (object instanceof Collection<?> && ((Collection<?>) object).size() == 2) { Pair<SourcePath, ImmutableList<String>> sourcePathWithFlags = sourcePathWithFlagsTypeCoercer.coerce( cellRoots, filesystem, pathRelativeToProjectRoot, object); return SourceWithFlags.of(sourcePathWithFlags.getFirst(), sourcePathWithFlags.getSecond()); } throw CoerceFailedException.simple( object, getOutputClass(), "input should be either a source path or a pair of a source path and a list of flags"); }
@Override public NeededCoverageSpec coerce( CellPathResolver cellRoots, ProjectFilesystem filesystem, Path pathRelativeToProjectRoot, Object object) throws CoerceFailedException { if (object instanceof NeededCoverageSpec) { return (NeededCoverageSpec) object; } if (object instanceof Collection<?>) { Collection<?> collection = (Collection<?>) object; if (collection.size() == 2 || collection.size() == 3) { Iterator<?> iter = collection.iterator(); Float neededRatio = floatTypeCoercer.coerce(cellRoots, filesystem, pathRelativeToProjectRoot, iter.next()); if (neededRatio < 0 || neededRatio > 1) { throw CoerceFailedException.simple( object, getOutputClass(), "the needed coverage ratio should be in range [0; 1]"); } BuildTarget buildTarget = buildTargetTypeCoercer.coerce( cellRoots, filesystem, pathRelativeToProjectRoot, iter.next()); Optional<String> pathName = Optional.absent(); if (iter.hasNext()) { pathName = Optional.of( pathNameTypeCoercer.coerce( cellRoots, filesystem, pathRelativeToProjectRoot, iter.next())); } return NeededCoverageSpec.of(neededRatio, buildTarget, pathName); } } throw CoerceFailedException.simple( object, getOutputClass(), "input should be a tuple of needed coverage ratio, a build target, and optionally a path"); }
/** Helper method to add coerced elements to the builder. */ protected void fill( CellPathResolver cellRoots, ProjectFilesystem filesystem, Path pathRelativeToProjectRoot, C.Builder<T> builder, Object object) throws CoerceFailedException { if (object instanceof Collection) { for (Object element : (Iterable<?>) object) { // if any element failed, the entire collection fails T coercedElement = elementTypeCoercer.coerce(cellRoots, filesystem, pathRelativeToProjectRoot, element); builder.add(coercedElement); } } else { throw CoerceFailedException.simple(object, getOutputClass()); } }