diff --git a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunction.java b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunction.java index 2b4197b7..aeac7d5e 100644 --- a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunction.java +++ b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunction.java @@ -111,6 +111,22 @@ default void checkParameterCount(final List parameters) { } } + /** + * Returns a {@link ExpressionFunction} with the given parameters. + */ + default ExpressionFunction setParameters(final List> parameters) { + Objects.requireNonNull(parameters, "parameters"); + + return parameters.equals( + this.parameters(parameters.size()) + ) ? + this : + ExpressionFunctionParameterValuesParameters.with( + parameters, + this + ); + } + /** * The return type of this function */ diff --git a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValues.java b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValues.java index 00854383..24d567a7 100644 --- a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValues.java +++ b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValues.java @@ -21,7 +21,6 @@ import walkingkooka.tree.expression.ExpressionPurityContext; import walkingkooka.tree.expression.FunctionExpressionName; -import java.util.List; import java.util.Objects; import java.util.Optional; @@ -48,11 +47,6 @@ public final Optional name() { return this.function.name(); } - @Override - public final List> parameters(final int count) { - return this.function.parameters(count); - } - @Override public final Class returnType() { return this.function.returnType(); diff --git a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesFilter.java b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesFilter.java index 6cf30f22..2674d5c9 100644 --- a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesFilter.java +++ b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesFilter.java @@ -48,6 +48,11 @@ private ExpressionFunctionParameterValuesFilter(final BiPredicate fil this.filter = filter; } + @Override + public List> parameters(final int count) { + return this.function.parameters(count); + } + @Override public T apply(final List parameters, final C context) { diff --git a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesMapper.java b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesMapper.java index e6a18ad5..35e0e3b6 100644 --- a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesMapper.java +++ b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesMapper.java @@ -42,6 +42,11 @@ private ExpressionFunctionParameterValuesMapper(final BiFunction, C this.mapper = mapper; } + @Override + public List> parameters(final int count) { + return this.function.parameters(count); + } + @Override public T apply(final List parameters, final C context) { diff --git a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesParameters.java b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesParameters.java new file mode 100644 index 00000000..e73061b1 --- /dev/null +++ b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesParameters.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 Miroslav Pokorny (github.com/mP1) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package walkingkooka.tree.expression.function; + +import walkingkooka.tree.expression.ExpressionEvaluationContext; + +import java.util.List; +import java.util.Objects; + +/** + * Wraps an {@link ExpressionFunction} and has {@link ExpressionFunctionParameter} definitions different from those of the wrapped {@link ExpressionFunction}. + * This will result in a different preparation of parameter value before the wrapped {@link ExpressionFunction} is executed. + */ +final class ExpressionFunctionParameterValuesParameters extends ExpressionFunctionParameterValues { + + static ExpressionFunctionParameterValuesParameters with(final List> parameters, + final ExpressionFunction function) { + checkParameters(parameters); + checkFunction(function); + + return new ExpressionFunctionParameterValuesParameters<>(parameters, function); + } + + private static void checkParameters(final List> parameters) { + Objects.requireNonNull(parameters, "parameters"); + } + + private ExpressionFunctionParameterValuesParameters(final List> parameters, + final ExpressionFunction function) { + super(function); + this.parameters = parameters; + } + + @Override + public List> parameters(final int count) { + return this.parameters; + } + + @Override + public T apply(final List parameters, + final C context) { + return this.function.apply( + parameters, + context + ); + } + + /** + * The different/custom parameters definitions that will be used to preprocess parameter values before the wrapped {@link #function} is executed. + */ + private final List> parameters; + + @Override + public String toString() { + return this.function.toString(); + } +} diff --git a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionTesting.java b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionTesting.java index 343fa852..7f4e60e7 100644 --- a/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionTesting.java +++ b/src/main/java/walkingkooka/tree/expression/function/ExpressionFunctionTesting.java @@ -70,6 +70,26 @@ default void testSetNameSame() { ); } + @Test + default void testSetParametersNullFails() { + assertThrows( + NullPointerException.class, + () -> this.createBiFunction() + .setParameters(null) + ); + } + + @Test + default void testSetParametersSame() { + final F function = this.createBiFunction(); + assertSame( + function, + function.setParameters( + function.parameters(0) + ) + ); + } + @Test default void testParameterNamesUnique() { final F function = this.createBiFunction(); diff --git a/src/test/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesParametersTest.java b/src/test/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesParametersTest.java new file mode 100644 index 00000000..308cf8b2 --- /dev/null +++ b/src/test/java/walkingkooka/tree/expression/function/ExpressionFunctionParameterValuesParametersTest.java @@ -0,0 +1,163 @@ +/* + * Copyright 2020 Miroslav Pokorny (github.com/mP1) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package walkingkooka.tree.expression.function; + +import org.junit.jupiter.api.Test; +import walkingkooka.Cast; +import walkingkooka.collect.list.Lists; +import walkingkooka.tree.expression.ExpressionEvaluationContext; +import walkingkooka.tree.expression.ExpressionPurityContext; +import walkingkooka.tree.expression.FunctionExpressionName; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public final class ExpressionFunctionParameterValuesParametersTest extends ExpressionFunctionTestCase, Object> { + + private final static List> PARAMETERS = Lists.of( + ExpressionFunctionParameter.CHARACTER + ); + + private final static ExpressionFunction FUNCTION = new FakeExpressionFunction<>() { + + @Override + public Object apply(final List parameters, + final ExpressionEvaluationContext context) { + return parameters.stream() + .map(p -> p.toString().toUpperCase()) + .collect(Collectors.joining(",")); + } + + @Override + public boolean isPure(final ExpressionPurityContext context) { + return true; + } + + @Override + public Optional name() { + return NAME; + } + + @Override + public List> parameters(final int count) { + return Lists.of( + ExpressionFunctionParameterName.with("parameter1") + .required(String.class) + ); + } + }; + + private final static Optional NAME = Optional.of( + FunctionExpressionName.with("custom-namedFunction") + ); + + @Test + public void testWithNullParametersFails() { + assertThrows( + NullPointerException.class, + () -> ExpressionFunctionParameterValuesParameters.with( + null, + FUNCTION + ) + ); + } + + @Test + public void testWithNullFunctionFails() { + assertThrows( + NullPointerException.class, + () -> ExpressionFunctionParameterValuesParameters.with( + PARAMETERS, + null + ) + ); + } + + @Test + public void testApply() { + this.applyAndCheck( + Lists.of( + "aaa", // toUpperCase() + "bbb", + 3, + "ddd" + ), + "AAA,BBB,3,DDD" + ); + } + + @Test + public void testName() { + this.checkEquals( + NAME, + this.createBiFunction().name() + ); + } + + @Test + public void testSetParametersSame() { + final ExpressionFunctionParameterValuesParameters function = this.createBiFunction(); + + assertSame( + function, + function.setParameters( + PARAMETERS + ) + ); + } + + @Test + public void testParameters() { + assertSame( + PARAMETERS, + this.createBiFunction().parameters(0) + ); + } + + @Test + public void testToString() { + this.toStringAndCheck( + this.createBiFunction(), + FUNCTION.toString() + ); + } + + // helpers.......................................................................................................... + + @Override + public ExpressionFunctionParameterValuesParameters createBiFunction() { + return ExpressionFunctionParameterValuesParameters.with( + PARAMETERS, + FUNCTION + ); + } + + @Override + public int minimumParameterCount() { + return 1; + } + + @Override + public Class> type() { + return Cast.to(ExpressionFunctionParameterValuesParameters.class); + } +}