Skip to content

Commit

Permalink
refactor: simplify ts_project macro conditional logic (#705)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbedard authored Sep 28, 2024
1 parent dd832db commit 0f52f92
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 58 deletions.
87 changes: 43 additions & 44 deletions ts/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)))
16 changes: 8 additions & 8 deletions ts/private/ts_lib.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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 = {
Expand All @@ -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 = {
Expand All @@ -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 = {
Expand Down
18 changes: 14 additions & 4 deletions ts/private/ts_project.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions ts/test/mock_transpiler.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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
)

0 comments on commit 0f52f92

Please sign in to comment.