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),