diff --git a/ts/defs.bzl b/ts/defs.bzl index 9d44464f..73aedbd1 100644 --- a/ts/defs.bzl +++ b/ts/defs.bzl @@ -331,60 +331,42 @@ def ts_project( typings_out_dir = declaration_dir if declaration_dir else out_dir tsbuildinfo_path = ts_build_info_file if ts_build_info_file else name + ".tsbuildinfo" + # Flags for what is emitted and which tool is emitting them + emit_js = not no_emit and not emit_declaration_only + emit_dts = not no_emit and (declaration or emit_declaration_only) + emit_transpiler_js = emit_js and transpiler and transpiler != "tsc" + emit_transpiler_dts = emit_dts and declaration_transpiler + emit_tsc_js = emit_js and not emit_transpiler_js + emit_tsc_dts = emit_dts and not emit_transpiler_dts + # Target names for tsc, dts+js transpilers tsc_target_name = name declarations_target_name = None transpile_target_name = None - # typing outputs + # typing predeclared outputs tsc_typings_outs = [] tsc_typing_maps_outs = [] - if no_emit or not declaration_transpiler: - tsc_typings_outs = _lib.calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js, no_emit) - tsc_typing_maps_outs = _lib.calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js, no_emit) - elif declaration or emit_declaration_only: - declarations_target_name = "%s_declarations" % name - - if type(declaration_transpiler) == "function" or type(declaration_transpiler) == "rule": - declaration_transpiler( - name = declarations_target_name, - srcs = srcs, - **common_kwargs - ) - elif partial.is_instance(declaration_transpiler): - partial.call( - declaration_transpiler, - name = declarations_target_name, - srcs = srcs, - **common_kwargs - ) - else: - fail("declaration_transpiler attribute should be a rule/macro or a skylib partial. Got " + type(declaration_transpiler)) + if emit_tsc_dts: + tsc_typings_outs = _lib.calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js) + tsc_typing_maps_outs = _lib.calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js) - # js outputs + # js predeclared outputs tsc_js_outs = [] tsc_map_outs = [] - if no_emit or not transpiler or transpiler == "tsc": - tsc_js_outs = _lib.calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, no_emit, emit_declaration_only) - tsc_map_outs = _lib.calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, no_emit, emit_declaration_only) - elif not emit_declaration_only: - transpile_target_name = "%s_transpile" % name + if emit_tsc_js: + tsc_js_outs = _lib.calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, emit_declaration_only) + tsc_map_outs = _lib.calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_declaration_only) - if type(transpiler) == "function" or type(transpiler) == "rule": - transpiler( - name = transpile_target_name, - srcs = srcs, - **common_kwargs - ) - elif partial.is_instance(transpiler): - partial.call( - transpiler, - name = transpile_target_name, - srcs = srcs, - **common_kwargs - ) - else: - fail("transpiler attribute should be a rule/macro or a skylib partial. Got " + type(transpiler)) + # Custom typing transpiler + if emit_transpiler_dts: + declarations_target_name = "%s_declarations" % name + _invoke_custom_transpiler("declaration_transpiler", declaration_transpiler, declarations_target_name, srcs, common_kwargs) + + # Custom js transpiler + if emit_transpiler_js: + transpile_target_name = "%s_transpile" % name + _invoke_custom_transpiler("transpiler", transpiler, transpile_target_name, srcs, common_kwargs) # Default target produced by the macro gives the js, dts and map outs, # with the transitive dependencies. @@ -414,7 +396,7 @@ def ts_project( ) # If the primary target does not output dts files then type-checking has a separate target. - if no_emit or (transpiler and transpiler != "tsc") or declaration_transpiler: + if not emit_tsc_js or not emit_tsc_dts: types_target_name = "%s_types" % name typecheck_target_name = "%s_typecheck" % name test_target_name = "%s_typecheck_test" % name @@ -507,3 +489,20 @@ def ts_project( validator = validator, **kwargs ) + +def _invoke_custom_transpiler(type_str, transpiler, transpile_target_name, srcs, common_kwargs): + if type(transpiler) == "function" or type(transpiler) == "rule": + transpiler( + name = transpile_target_name, + srcs = srcs, + **common_kwargs + ) + elif partial.is_instance(transpiler): + partial.call( + transpiler, + name = transpile_target_name, + srcs = srcs, + **common_kwargs + ) + else: + fail("%s attribute should be a rule/macro or a skylib partial. Got %s" % (type_str, type(transpiler))) diff --git a/ts/private/ts_lib.bzl b/ts/private/ts_lib.bzl index 9ac0befe..052d30a7 100644 --- a/ts/private/ts_lib.bzl +++ b/ts/private/ts_lib.bzl @@ -245,8 +245,8 @@ def _validate_tsconfig_dirs(root_dir, out_dir, typings_out_dir): if typings_out_dir and typings_out_dir.find("../") != -1: fail("typings_out_dir cannot output to parent directory") -def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, no_emit, emit_declaration_only): - if no_emit or emit_declaration_only: +def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, emit_declaration_only): + if emit_declaration_only: return [] exts = { @@ -263,8 +263,8 @@ def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, p return _to_js_out_paths(srcs, out_dir, root_dir, allow_js, resolve_json_module, exts, ".js") -def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, no_emit, emit_declaration_only): - if no_emit or not source_map or emit_declaration_only: +def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_declaration_only): + if not source_map or emit_declaration_only: return [] exts = { @@ -278,8 +278,8 @@ def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, no_em return _to_js_out_paths(srcs, out_dir, root_dir, False, False, exts, ".js.map") -def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js, no_emit): - if no_emit or not (declaration or composite): +def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js): + if not (declaration or composite): return [] exts = { @@ -291,8 +291,8 @@ def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, compos return _to_js_out_paths(srcs, typings_out_dir, root_dir, allow_js, False, exts, ".d.ts") -def _calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js, no_emit): - if no_emit or not declaration_map: +def _calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js): + if not declaration_map: return [] exts = { diff --git a/ts/private/ts_project.bzl b/ts/private/ts_project.bzl index df88bc65..1ac7e35e 100644 --- a/ts/private/ts_project.bzl +++ b/ts/private/ts_project.bzl @@ -62,10 +62,20 @@ def _ts_project_impl(ctx): # However, it is not possible to evaluate files in outputs of other rules such as filegroup, therefore the outs are # recalculated here. typings_out_dir = ctx.attr.declaration_dir or ctx.attr.out_dir - js_outs = _lib.declare_outputs(ctx, [] if ctx.attr.transpile == 0 else _lib.calculate_js_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.allow_js, ctx.attr.resolve_json_module, ctx.attr.preserve_jsx, ctx.attr.no_emit, ctx.attr.emit_declaration_only)) - map_outs = _lib.declare_outputs(ctx, [] if ctx.attr.transpile == 0 else _lib.calculate_map_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.source_map, ctx.attr.preserve_jsx, ctx.attr.no_emit, ctx.attr.emit_declaration_only)) - typings_outs = _lib.declare_outputs(ctx, [] if ctx.attr.declaration_transpile else _lib.calculate_typings_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration, ctx.attr.composite, ctx.attr.allow_js, ctx.attr.no_emit)) - typing_maps_outs = _lib.declare_outputs(ctx, [] if ctx.attr.declaration_transpile else _lib.calculate_typing_maps_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration_map, ctx.attr.allow_js, ctx.attr.no_emit)) + + # js+map file outputs + js_outs = [] + map_outs = [] + if not ctx.attr.no_emit and ctx.attr.transpile != 0: + js_outs = _lib.declare_outputs(ctx, _lib.calculate_js_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.allow_js, ctx.attr.resolve_json_module, ctx.attr.preserve_jsx, ctx.attr.emit_declaration_only)) + map_outs = _lib.declare_outputs(ctx, _lib.calculate_map_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.source_map, ctx.attr.preserve_jsx, ctx.attr.emit_declaration_only)) + + # dts+map file outputs + typings_outs = [] + typing_maps_outs = [] + if not ctx.attr.no_emit and not ctx.attr.declaration_transpile: + typings_outs = _lib.declare_outputs(ctx, _lib.calculate_typings_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration, ctx.attr.composite, ctx.attr.allow_js)) + typing_maps_outs = _lib.declare_outputs(ctx, _lib.calculate_typing_maps_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration_map, ctx.attr.allow_js)) validation_outs = [] if ctx.attr.validate: diff --git a/ts/test/mock_transpiler.bzl b/ts/test/mock_transpiler.bzl index 37d041f2..5f141558 100644 --- a/ts/test/mock_transpiler.bzl +++ b/ts/test/mock_transpiler.bzl @@ -53,7 +53,7 @@ def mock(name, srcs, source_map = False, **kwargs): srcs = srcs, # Calculate pre-declared outputs so they can be referenced as targets. # This is an optional transpiler feature aligning with the default tsc transpiler. - js_outs = lib.calculate_js_outs(srcs, ".", ".", False, False, False, False, False), - map_outs = lib.calculate_map_outs(srcs, ".", ".", True, False, False, False) if source_map else [], + js_outs = lib.calculate_js_outs(srcs, ".", ".", False, False, False, False), + map_outs = lib.calculate_map_outs(srcs, ".", ".", True, False, False) if source_map else [], **kwargs )