Skip to content

Commit

Permalink
Add a Boolean() builtin to explicitly cast anything to a boolean.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 576240041
  • Loading branch information
nicholasyu-google authored and copybara-github committed Oct 24, 2023
1 parent 31854b0 commit fe76537
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions documentation/reference/coercions.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ There are a few ways to coerce a value to a boolean.

* use it in an [if-expression](control-flow#if)
* use it in a [ternary expression](expressions#ternary-operator)
* use the built-in function [`Boolean()`](functions#Boolean)

All values have a boolean coercion (sometimes referred to as a 'truthiness'
check), these mostly follow JavaScript semantics:
Expand Down
4 changes: 4 additions & 0 deletions documentation/reference/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ custom external functions, see

## Basic Functions

### `Boolean(value)` {#Boolean}

Explicitly coerces the argument to a boolean.

### `checkNotNull(value)` {#checkNotNull}

Throws a runtime exception if the given value is `null` and returns the value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ private BasicFunctions() {}
public static ImmutableList<SoySourceFunction> functions() {
return ImmutableList.of(
// go/keep-sorted start
new BooleanFunction(),
new CeilingFunction(),
new ConcatListsFunction(),
new ConcatMapsMethod(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,8 @@ private static int clampStrIndex(String str, NumberData position) {
public static boolean isFinite(SoyValue arg) {
return arg instanceof NumberData && Double.isFinite(arg.numberValue());
}

public static boolean booleanFunc(SoyValue value) {
return value != null && value.coerceToBoolean();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2009 Google Inc.
*
* 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 com.google.template.soy.basicfunctions;

import com.google.template.soy.data.SoyValue;
import com.google.template.soy.plugin.java.restricted.JavaPluginContext;
import com.google.template.soy.plugin.java.restricted.JavaValue;
import com.google.template.soy.plugin.java.restricted.JavaValueFactory;
import com.google.template.soy.plugin.java.restricted.SoyJavaSourceFunction;
import com.google.template.soy.plugin.javascript.restricted.JavaScriptPluginContext;
import com.google.template.soy.plugin.javascript.restricted.JavaScriptValue;
import com.google.template.soy.plugin.javascript.restricted.JavaScriptValueFactory;
import com.google.template.soy.plugin.javascript.restricted.SoyJavaScriptSourceFunction;
import com.google.template.soy.plugin.python.restricted.PythonPluginContext;
import com.google.template.soy.plugin.python.restricted.PythonValue;
import com.google.template.soy.plugin.python.restricted.PythonValueFactory;
import com.google.template.soy.plugin.python.restricted.SoyPythonSourceFunction;
import com.google.template.soy.shared.restricted.Signature;
import com.google.template.soy.shared.restricted.SoyFunctionSignature;
import com.google.template.soy.shared.restricted.SoyPureFunction;
import java.lang.reflect.Method;
import java.util.List;

/** Soy function that takes the ceiling of a number. */
@SoyPureFunction
@SoyFunctionSignature(
name = "Boolean",
value =
@Signature(
parameterTypes = {"?"},
returnType = "bool"))
final class BooleanFunction
implements SoyJavaSourceFunction, SoyJavaScriptSourceFunction, SoyPythonSourceFunction {

@Override
public JavaScriptValue applyForJavaScriptSource(
JavaScriptValueFactory factory, List<JavaScriptValue> args, JavaScriptPluginContext context) {
return factory.global("Boolean").invoke(args.get(0));
}

@Override
public PythonValue applyForPythonSource(
PythonValueFactory factory, List<PythonValue> args, PythonPluginContext context) {
return factory.global("bool").call(args.get(0));
}

// lazy singleton pattern, allows other backends to avoid the work.
private static final class Methods {
static final Method BOOLEAN_FN =
JavaValueFactory.createMethod(BasicFunctionsRuntime.class, "booleanFunc", SoyValue.class);
}

@Override
public JavaValue applyForJavaSource(
JavaValueFactory factory, List<JavaValue> args, JavaPluginContext context) {
return factory.callStaticMethod(Methods.BOOLEAN_FN, args.get(0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ public JavaScriptValueImpl invokeMethod(String methodName, JavaScriptValue... ar
impl.dotAccess(methodName).call(unwrapParams(Arrays.asList(args))));
}

@Override
public JavaScriptValueImpl invoke(JavaScriptValue... args) {
return new JavaScriptValueImpl(impl.call(unwrapParams(Arrays.asList(args))));
}

@Override
public JavaScriptValueImpl accessProperty(String ident) {
return new JavaScriptValueImpl(impl.dotAccess(ident));
Expand All @@ -281,5 +286,6 @@ public JavaScriptValueImpl accessProperty(String ident) {
public String toString() {
return impl.getCode(FormatOptions.JSSRC);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ default JavaScriptValue invokeMethod(String ident, Iterable<JavaScriptValue> arg
return invokeMethod(ident, Iterables.toArray(args, JavaScriptValue.class));
}

/** Generates a call on the symbol. */
JavaScriptValue invoke(JavaScriptValue... args);

/** Accesses a property on the given object. */
JavaScriptValue accessProperty(String ident);

}

0 comments on commit fe76537

Please sign in to comment.