Make ts_compile_actions callable from aspects.
This adds fallbacks for cases where a certain attribute isn't present on ctx:
- ctx.attr.compiler falls back to ctx.attr._compiler
- ctx.attr.generate_externs defaults to True
- ctx.attr.runtime defaults to "browser"
- ctx.attr.module_name defaults to None
It also defines an attribute dict for aspects that define a lot of the necessary attributes for compilation (similar to TS_LIB_DECL_ATTRIBUTES).
Finally, it allows callers of compile_ts or ts_compile_actions to define their own tsconfig output instead o getting it from ctx.outputs (since aspects cannot have outputs).
PiperOrigin-RevId: 256070225
diff --git a/internal/common/compilation.bzl b/internal/common/compilation.bzl
index d173ce7..511fcc0 100644
--- a/internal/common/compilation.bzl
+++ b/internal/common/compilation.bzl
@@ -24,6 +24,10 @@
module_mappings_aspect,
]
+_ADDITIONAL_D_TS = attr.label_list(
+ allow_files = True,
+)
+
# Attributes shared by any typescript-compatible rule (ts_library, ng_module)
COMMON_ATTRIBUTES = {
"data": attr.label_list(
@@ -48,9 +52,12 @@
providers = ["js"],
),
"deps": attr.label_list(aspects = DEPS_ASPECTS),
- "_additional_d_ts": attr.label_list(
- allow_files = True,
- ),
+ "_additional_d_ts": _ADDITIONAL_D_TS,
+}
+
+# Attributes shared by any typescript-compatible aspect.
+ASPECT_ATTRIBUTES = {
+ "_additional_d_ts": _ADDITIONAL_D_TS,
}
COMMON_OUTPUTS = {
@@ -145,6 +152,19 @@
type_blacklisted = depset(transitive = type_blacklisted_declarations),
)
+def _should_generate_externs(ctx):
+ """Whether externs should be generated.
+
+ If ctx has a generate_externs attribute, the value of that is returned.
+ Otherwise, this is true."""
+ return getattr(ctx.attr, "generate_externs", True)
+
+def _get_runtime(ctx):
+ """Gets the runtime for the rule.
+
+ Defaults to "browser" if the runtime attr isn't present."""
+ return getattr(ctx.attr, "runtime", "browser")
+
def _outputs(ctx, label, srcs_files = []):
"""Returns closure js, devmode js, and .d.ts output files.
@@ -205,6 +225,7 @@
devmode_compile_action = None,
jsx_factory = None,
tsc_wrapped_tsconfig = None,
+ tsconfig = None,
outputs = _outputs):
"""Creates actions to compile TypeScript code.
@@ -220,6 +241,7 @@
for devmode.
jsx_factory: optional string. Enables overriding jsx pragma.
tsc_wrapped_tsconfig: function that produces a tsconfig object.
+ tsconfig: The tsconfig file to output, if other than ctx.outputs.tsconfig.
outputs: function from a ctx to the expected compilation outputs.
Returns:
@@ -229,6 +251,7 @@
### Collect srcs and outputs.
srcs = srcs if srcs != None else ctx.attr.srcs
deps = deps if deps != None else ctx.attr.deps
+ tsconfig = tsconfig if tsconfig != None else ctx.outputs.tsconfig
srcs_files = [f for t in srcs for f in t.files.to_list()]
src_declarations = [] # d.ts found in inputs.
tsickle_externs = [] # externs.js generated by tsickle, if any.
@@ -267,14 +290,14 @@
transpiled_devmode_js = outs.devmode_js
gen_declarations = outs.declarations
- if has_sources and ctx.attr.runtime != "nodejs":
+ if has_sources and _get_runtime(ctx) != "nodejs":
# Note: setting this variable controls whether tsickle is run at all.
tsickle_externs = [ctx.actions.declare_file(ctx.label.name + ".externs.js")]
dep_declarations = _collect_dep_declarations(ctx, deps)
input_declarations = depset(src_declarations, transitive = [dep_declarations.transitive])
type_blacklisted_declarations = dep_declarations.type_blacklisted
- if not is_library and not ctx.attr.generate_externs:
+ if not is_library and not _should_generate_externs(ctx):
type_blacklisted_declarations += srcs_files
# The depsets of output files. These are the files that are always built
@@ -339,7 +362,7 @@
files_depsets.append(depset([perf_trace_file, profile_file]))
ctx.actions.write(
- output = ctx.outputs.tsconfig,
+ output = tsconfig,
content = json_marshal(tsconfig_es6),
)
@@ -348,12 +371,12 @@
replay_params = None
if has_sources:
- inputs = compilation_inputs + [ctx.outputs.tsconfig]
+ inputs = compilation_inputs + [tsconfig]
replay_params = compile_action(
ctx,
inputs,
outputs,
- ctx.outputs.tsconfig,
+ tsconfig,
node_profile_args,
)
@@ -460,7 +483,7 @@
# Expose the module_name so that packaging rules can access it.
# e.g. rollup_bundle under Bazel needs to convert this into a UMD global
# name in the Rollup configuration.
- "module_name": ctx.attr.module_name,
+ "module_name": getattr(ctx.attr, "module_name", None),
"output_groups": {
"es5_sources": es5_sources,
"es6_sources": es6_sources,
@@ -473,7 +496,7 @@
collect_data = True,
),
# Expose the tags so that a Skylark aspect can access them.
- "tags": ctx.attr.tags,
+ "tags": ctx.attr.tags if hasattr(ctx.attr, "tags") else ctx.rule.attr.tags,
# TODO(martinprobst): Prune transitive deps, only re-export what's needed.
"typescript": {
"declarations": depset(transitive = declarations_depsets),