Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
arguments = {"the list"},
returnType = "T",
deprecated = false,
description = "The First element of the list",
description = "Returns the first element of a non-empty list.",
actionLevel = ActionLevel.NO_ACTION,
examples = {
"First(List(1))"
Expand Down Expand Up @@ -46,6 +46,9 @@ protected CacheLevel getCacheLevel() {

@Override
public Object apply(Context<Runtime> context, List<Object> list) {
if (list.isEmpty()) {
throw new IllegalArgumentException("First() requires a non-empty list");
}
return list.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
},
returnType = "List<T>",
deprecated = false,
description = "Returns the first n values of the list. if n > len(list) return list.",
description =
"Returns the first n values of the list."
+ " Returns an empty list if n is negative."
+ " Returns the whole list if n is greater than the length of the list.",
actionLevel = ActionLevel.NO_ACTION,
examples = {
"FirstN(List(\"asdf\", \"bas\", \"biz\"), 2)"
Expand Down Expand Up @@ -54,6 +57,7 @@ protected CacheLevel getCacheLevel() {

@Override
public Object apply(Context<Runtime> context, List<Object> list, Long n) {
return list.subList(0, Math.min(n.intValue(), list.size()));
long itemCount = Math.max(0L, Math.min(n.longValue(), (long) list.size()));
return list.subList(0, (int) itemCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
},
name = {"Slice", "Substring"},
returnType = "String",
description = "Returns a substring or a sublist",
description =
"Returns a substring or a sublist."
+ " Throws an exception if the requested range is invalid.",
actionLevel = ActionLevel.NO_ACTION,
examples = {
"Slice(\"teststringteststring\", 1)",
Expand Down Expand Up @@ -74,10 +76,14 @@ private static ImmutableList<ASTNode> validateType(ImmutableList<ASTNode> childr
protected Object apply(
Context<Runtime> context, Object input, Long beginIndex, Long endIndex) {
if (input instanceof String) {
return ((String) input).substring(beginIndex.intValue(), endIndex.intValue());
String string = (String) input;
validateRange(beginIndex, endIndex, string.length());
return string.substring(beginIndex.intValue(), endIndex.intValue());
} else if (input instanceof List) {
List list = (List) input;
validateRange(beginIndex, endIndex, list.size());
return Collections.unmodifiableList(new ArrayList<>(
((List) input).subList(beginIndex.intValue(), endIndex.intValue())));
list.subList(beginIndex.intValue(), endIndex.intValue())));
} else {
throw new IllegalArgumentException(mkErrorMessage(input.getClass()));
}
Expand All @@ -96,6 +102,16 @@ protected Object apply(Context<Runtime> context, Object input, Long beginIndex)
}
}

private static void validateRange(Long beginIndex, Long endIndex, int inputLength) {
if (beginIndex < 0 || endIndex < beginIndex || endIndex > inputLength) {
throw new IllegalArgumentException(String.format(
"invalid Slice() range [%d, %d) for input of length %d",
beginIndex,
endIndex,
inputLength));
}
}

private static String mkErrorMessage(Class<?> input) {
return String.format(
"expecting the input to be of String or List type but received: %s for %s",
Expand Down