Expose `cc_helper.tokenize` and optionally use it in `java_helper.tokenize_javacopts` For large option sets, such as those involved in java compilation, `ctx.tokenize()` is up to 100x faster than the pure Starlark implementation. We should resort to using the slow path only in the cases where `ctx` is unavailable (such as when performing a `map_each` in `args.add_all`). PiperOrigin-RevId: 585977311 Change-Id: I547c6dbc1a37ef15494a9b398a597a4246c08ea9
diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl index e3376fc..6e8e360 100644 --- a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl
@@ -1266,4 +1266,5 @@ proto_output_root = _proto_output_root, cc_toolchain_build_variables = _cc_toolchain_build_variables, package_source_root = _package_source_root, + tokenize = _tokenize, )
diff --git a/src/main/starlark/builtins_bzl/common/java/java_helper.bzl b/src/main/starlark/builtins_bzl/common/java/java_helper.bzl index 7f71e33..617b360 100644 --- a/src/main/starlark/builtins_bzl/common/java/java_helper.bzl +++ b/src/main/starlark/builtins_bzl/common/java/java_helper.bzl
@@ -377,25 +377,39 @@ return "'" + s.replace("'", "'\\''") + "'" return s -def _tokenize_javacopts(ctx, opts): +def _tokenize_javacopts(ctx = None, opts = []): """Tokenizes a list or depset of options to a list. Iff opts is a depset, we reverse the flattened list to ensure right-most duplicates are preserved in their correct position. + If the ctx parameter is omitted, a slow, but pure Starlark, implementation + of shell tokenization is used. Otherwise, tokenization is performed using + ctx.tokenize() which has significantly better performance (up to 100x for + large options lists). + Args: - ctx: (RuleContext) the rule context + ctx: (RuleContext|None) the rule context opts: (depset[str]|[str]) the javac options to tokenize Returns: [str] list of tokenized options """ if hasattr(opts, "to_list"): opts = reversed(opts.to_list()) - return [ - token - for opt in opts - for token in ctx.tokenize(opt) - ] + if ctx: + return [ + token + for opt in opts + for token in ctx.tokenize(opt) + ] + else: + # slow, but pure Starlark implementation + result = [] + for opt in opts: + tokens = [] + cc_helper.tokenize(tokens, opt) + result.extend(tokens) + return result def _detokenize_javacopts(opts): """Detokenizes a list of options to a depset.