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 @@ -8,6 +8,7 @@
import com.twitter.botmaker.Context;
import com.twitter.botmaker.compiler.ActionLevel;
import com.twitter.botmaker.compiler.BotMakerFunction;
import com.twitter.botmaker.compiler.exceptions.FunctionFailure;
import com.twitter.botmaker.compiler.exceptions.SemanticCheckFailure;
import com.twitter.botmaker.compiler.types.Type;
import com.twitter.botmaker.function.FunctionNode2;
Expand Down Expand Up @@ -55,7 +56,30 @@ protected CacheLevel getCacheLevel() {

@Override
protected Object apply(Context<Runtime> context, List<Object> list, Long index) {
return list.get(index.intValue());
if (list == null) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException("ElementAtIndex() called on null list"));
}
if (index == null) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException("ElementAtIndex() requires a non-null index"));
}
int i = index.intValue();
if (i < 0 || i >= list.size()) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException(
String.format(
"ElementAtIndex() index out of range: index=%d size=%d",
i,
list.size())));
}
return list.get(i);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.twitter.botmaker.Context;
import com.twitter.botmaker.compiler.ActionLevel;
import com.twitter.botmaker.compiler.BotMakerFunction;
import com.twitter.botmaker.compiler.exceptions.FunctionFailure;
import com.twitter.botmaker.compiler.exceptions.SemanticCheckFailure;
import com.twitter.botmaker.compiler.types.Type;
import com.twitter.botmaker.function.FunctionNode1;
Expand Down Expand Up @@ -46,6 +47,12 @@ protected CacheLevel getCacheLevel() {

@Override
public Object apply(Context<Runtime> context, List<Object> list) {
if (list == null || list.isEmpty()) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException("First() called on empty list"));
}
return list.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.twitter.botmaker.Context;
import com.twitter.botmaker.compiler.ActionLevel;
import com.twitter.botmaker.compiler.BotMakerFunction;
import com.twitter.botmaker.compiler.exceptions.FunctionFailure;
import com.twitter.botmaker.compiler.exceptions.SemanticCheckFailure;
import com.twitter.botmaker.compiler.types.Type;
import com.twitter.botmaker.function.FunctionNode2;
Expand Down Expand Up @@ -54,6 +55,14 @@ 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()));
if (list == null) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException("FirstN() called on null list"));
}
// Clamp negative n so subList(0, negative) cannot throw IndexOutOfBoundsException.
long count = Math.max(0L, n == null ? 0L : n.longValue());
return list.subList(0, (int) Math.min(count, list.size()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.twitter.botmaker.Context;
import com.twitter.botmaker.compiler.ActionLevel;
import com.twitter.botmaker.compiler.BotMakerFunction;
import com.twitter.botmaker.compiler.exceptions.FunctionFailure;
import com.twitter.botmaker.compiler.exceptions.SemanticCheckFailure;
import com.twitter.botmaker.compiler.types.Type;
import com.twitter.botmaker.function.FunctionNode1;
Expand Down Expand Up @@ -46,6 +47,12 @@ protected CacheLevel getCacheLevel() {

@Override
public Object apply(Context<Runtime> context, List<Object> list) {
if (list == null || list.isEmpty()) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException("Last() called on empty list"));
}
return list.get(list.size() - 1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.twitter.botmaker.Context;
import com.twitter.botmaker.compiler.ActionLevel;
import com.twitter.botmaker.compiler.BotMakerFunction;
import com.twitter.botmaker.compiler.exceptions.FunctionFailure;
import com.twitter.botmaker.compiler.exceptions.SemanticCheckFailure;
import com.twitter.botmaker.compiler.types.Type;
import com.twitter.botmaker.function.FunctionNode2O1;
Expand Down Expand Up @@ -73,6 +74,7 @@ private static ImmutableList<ASTNode> validateType(ImmutableList<ASTNode> childr
@Override
protected Object apply(
Context<Runtime> context, Object input, Long beginIndex, Long endIndex) {
validateSliceBounds(context, input, beginIndex, endIndex);
if (input instanceof String) {
return ((String) input).substring(beginIndex.intValue(), endIndex.intValue());
} else if (input instanceof List) {
Expand All @@ -96,6 +98,37 @@ protected Object apply(Context<Runtime> context, Object input, Long beginIndex)
}
}

private void validateSliceBounds(
Context<Runtime> context, Object input, Long beginIndex, Long endIndex) {
if (beginIndex == null || endIndex == null) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException("Slice() requires non-null begin and end indices"));
}
int begin = beginIndex.intValue();
int end = endIndex.intValue();
final int max;
if (input instanceof String) {
max = ((String) input).length();
} else if (input instanceof List) {
max = ((List<?>) input).size();
} else {
throw new IllegalArgumentException(mkErrorMessage(input.getClass()));
}
if (begin < 0 || end < 0 || begin > end || end > max) {
throw new FunctionFailure(
this,
context.getStackFrames(),
new IllegalArgumentException(
String.format(
"Slice() indices out of range: begin=%d end=%d length=%d",
begin,
end,
max)));
}
}

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