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
1 change: 1 addition & 0 deletions bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ java_library(
"//checker:standard_decl",
"//common:cel_function_decl",
"//common:cel_overload_decl",
"//common:cel_signature_utils",
"//common:cel_var_decl",
"//common:container",
"//common:options",
Expand Down
15 changes: 5 additions & 10 deletions bundle/src/main/java/dev/cel/bundle/TypeSpecifierParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
package dev.cel.bundle;

import static com.google.common.base.Preconditions.checkNotNull;
import static dev.cel.common.CelSignatureUtils.MAX_RECURSION_DEPTH;
import static dev.cel.common.CelSignatureUtils.isAlpha;
import static dev.cel.common.CelSignatureUtils.isAlphaNumeric;
import static dev.cel.common.CelSignatureUtils.isWhitespace;

import com.google.common.collect.ImmutableList;
import dev.cel.bundle.CelEnvironment.TypeDecl;
Expand All @@ -25,7 +29,6 @@
* {@code "int"}) into a {@link TypeDecl}.
*/
final class TypeSpecifierParser {
private static final int MAX_RECURSION_DEPTH = 64;
static final TypeDecl ERROR_TYPE_DECL = TypeDecl.create("*error*");

private final String text;
Expand Down Expand Up @@ -178,22 +181,14 @@ private String parseTypeParamIdent() {
private void skipWhitespace() {
while (pos < length) {
char c = text.charAt(pos);
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
if (isWhitespace(c)) {
pos++;
} else {
break;
}
}
}

private static boolean isAlpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}

private static boolean isAlphaNumeric(char c) {
return isAlpha(c) || (c >= '0' && c <= '9');
}

private static String formatQuoted(String s) {
return "\"" + s + "\"";
}
Expand Down
24 changes: 24 additions & 0 deletions checker/src/test/java/dev/cel/checker/CelOverloadDeclTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@

import dev.cel.expr.Decl.FunctionDecl.Overload;
import com.google.common.collect.ImmutableList;
import dev.cel.common.CelFunctionDecl;
import dev.cel.common.CelOverloadDecl;
import dev.cel.common.CelProtoDeclConverter;
import dev.cel.common.types.CelProtoTypes;
import dev.cel.common.types.ListType;
import dev.cel.common.types.SimpleType;
import dev.cel.common.types.TypeParamType;
import org.junit.Test;
Expand Down Expand Up @@ -105,4 +107,26 @@ public void setParameterTypes_doesNotDedupe() {
.containsExactly(SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.INT)
.inOrder();
}

@Test
public void newFunctionDeclaration_populatesEmptyOverloadIds() {
CelOverloadDecl globalOverload =
newGlobalOverload(SimpleType.INT, SimpleType.INT, SimpleType.INT);
CelOverloadDecl memberOverload =
newMemberOverload(
SimpleType.BOOL, ListType.create(TypeParamType.create("T")), TypeParamType.create("T"));
CelOverloadDecl explicitOverload =
newGlobalOverload("custom_id", SimpleType.STRING, SimpleType.STRING);

assertThat(globalOverload.overloadId()).isEmpty();
assertThat(memberOverload.overloadId()).isEmpty();

CelFunctionDecl functionDecl =
CelFunctionDecl.newFunctionDeclaration(
"myFunc", globalOverload, memberOverload, explicitOverload);

assertThat(functionDecl.overloads().stream().map(CelOverloadDecl::overloadId))
.containsExactly("myFunc(int,int)", "list<~T>.myFunc(~T)", "custom_id")
.inOrder();
}
}
12 changes: 12 additions & 0 deletions common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ cel_android_library(
exports = ["//common/src/main/java/dev/cel/common:cel_overload_decl_android"],
)

java_library(
name = "cel_signature_utils",
visibility = ["//:internal"],
exports = ["//common/src/main/java/dev/cel/common:cel_signature_utils"],
)

cel_android_library(
name = "cel_signature_utils_android",
visibility = ["//:internal"],
exports = ["//common/src/main/java/dev/cel/common:cel_signature_utils_android"],
)

java_library(
name = "cel_proto_decl_converter",
exports = ["//common/src/main/java/dev/cel/common:cel_proto_decl_converter"],
Expand Down
34 changes: 34 additions & 0 deletions common/src/main/java/dev/cel/common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ java_library(
],
deps = [
":cel_overload_decl",
":cel_signature_utils",
"//:auto_value",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_guava_guava",
Expand All @@ -76,12 +77,45 @@ cel_android_library(
],
deps = [
":cel_overload_decl_android",
":cel_signature_utils_android",
"//:auto_value",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven_android//:com_google_guava_guava",
],
)

java_library(
name = "cel_signature_utils",
srcs = ["CelSignatureUtils.java"],
tags = [
],
deps = [
"//:auto_value",
"//common/annotations",
"//common/types",
"//common/types:cel_types",
"//common/types:type_providers",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_guava_guava",
],
)

cel_android_library(
name = "cel_signature_utils_android",
srcs = ["CelSignatureUtils.java"],
tags = [
],
deps = [
"//:auto_value",
"//common/annotations",
"//common/types:cel_types_android",
"//common/types:type_providers_android",
"//common/types:types_android",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven_android//:com_google_guava_guava",
],
)

java_library(
name = "cel_overload_decl",
srcs = ["CelOverloadDecl.java"],
Expand Down
29 changes: 28 additions & 1 deletion common/src/main/java/dev/cel/common/CelFunctionDecl.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,36 @@ public Builder addOverloads(Iterable<CelOverloadDecl> overloads) {
return this;
}

@CheckReturnValue
abstract CelFunctionDecl autoBuild();

/** Builds a new instance of {@link CelFunctionDecl} */
@CheckReturnValue
public abstract CelFunctionDecl build();
public CelFunctionDecl build() {
CelFunctionDecl functionDecl = autoBuild();
boolean needsOverloadId = false;
for (CelOverloadDecl overload : functionDecl.overloads()) {
if (overload.overloadId().isEmpty()) {
needsOverloadId = true;
break;
}
}
if (!needsOverloadId) {
return functionDecl;
}
ImmutableSet.Builder<CelOverloadDecl> updatedOverloads = ImmutableSet.builder();
for (CelOverloadDecl overload : functionDecl.overloads()) {
if (overload.overloadId().isEmpty()) {
String generatedId =
CelSignatureUtils.makeOverloadSignature(
functionDecl.name(), overload.parameterTypes(), overload.isInstanceFunction());
updatedOverloads.add(overload.toBuilder().setOverloadId(generatedId).build());
} else {
updatedOverloads.add(overload);
}
}
return functionDecl.toBuilder().setOverloads(updatedOverloads.build()).autoBuild();
}
}

public abstract Builder toBuilder();
Expand Down
43 changes: 41 additions & 2 deletions common/src/main/java/dev/cel/common/CelOverloadDecl.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
@AutoValue
@Immutable
public abstract class CelOverloadDecl {
/** Required. Globally unique overload name. */
/**
* Globally unique overload name. If empty when building {@link CelFunctionDecl}, an overload ID
* is automatically generated from the function name and parameter types.
*/
public abstract String overloadId();

/**
Expand Down Expand Up @@ -79,7 +82,7 @@ public abstract class CelOverloadDecl {

/** Create a new builder to construct a {@link CelOverloadDecl} instance */
public static Builder newBuilder() {
return new AutoValue_CelOverloadDecl.Builder().setDoc("");
return new AutoValue_CelOverloadDecl.Builder().setOverloadId("").setDoc("");
}

/** Builder for configuring the {@link CelOverloadDecl}. */
Expand Down Expand Up @@ -153,6 +156,24 @@ public CelOverloadDecl build() {
}
}

/**
* Helper method for declaring a member function overload with an automatically generated overload
* ID.
*/
@CheckReturnValue
public static CelOverloadDecl newMemberOverload(CelType resultType, CelType... paramTypes) {
return newMemberOverload("", resultType, Arrays.asList(paramTypes));
}

/**
* Helper method for declaring a member function overload with an automatically generated overload
* ID.
*/
@CheckReturnValue
public static CelOverloadDecl newMemberOverload(CelType resultType, List<CelType> paramTypes) {
return newMemberOverload("", /* doc= */ "", resultType, paramTypes);
}

/** Helper method for declaring a member function overload */
@CheckReturnValue
public static CelOverloadDecl newMemberOverload(
Expand Down Expand Up @@ -181,6 +202,24 @@ public static CelOverloadDecl newMemberOverload(
return newOverload(overloadId, doc, resultType, paramTypes, /* isInstanceFunction= */ true);
}

/**
* Helper method for declaring a global function overload with an automatically generated overload
* ID.
*/
@CheckReturnValue
public static CelOverloadDecl newGlobalOverload(CelType resultType, CelType... paramTypes) {
return newGlobalOverload("", resultType, Arrays.asList(paramTypes));
}

/**
* Helper method for declaring a global function overload with an automatically generated overload
* ID.
*/
@CheckReturnValue
public static CelOverloadDecl newGlobalOverload(CelType resultType, List<CelType> paramTypes) {
return newGlobalOverload("", /* doc= */ "", resultType, paramTypes);
}

/** Helper method for declaring a global function overload */
@CheckReturnValue
public static CelOverloadDecl newGlobalOverload(
Expand Down
Loading
Loading