Repository navigation
Expand file tree
/
Copy pathrules_typescript_providers.patch
More file actions
202 lines (187 loc) · 9.59 KB
/
Copy pathrules_typescript_providers.patch
File metadata and controls
202 lines (187 loc) · 9.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
diff --git a/internal/common/compilation.bzl b/internal/common/compilation.bzl
index 3155f0c..3c67ad3 100644
--- a/internal/common/compilation.bzl
+++ b/internal/common/compilation.bzl
@@ -18,8 +18,10 @@
load(":common/json_marshal.bzl", "json_marshal")
load(":common/module_mappings.bzl", "module_mappings_aspect")
load("@build_bazel_rules_nodejs//:declaration_provider.bzl", "DeclarationInfo")
+load("@build_bazel_rules_nodejs//:providers.bzl", "JSModuleInfo", "JSNamedModuleInfo", "JSEcmaScriptModuleInfo", "transitive_js_module_info", "transitive_js_named_module_info", "transitive_js_ecma_script_module_info")
_DEBUG = False
+_LEGACY_TYPESCRIPT_PROVIDER_SUPPORT = False
DEPS_ASPECTS = [
module_mappings_aspect,
@@ -72,10 +74,14 @@ def assert_js_or_typescript_deps(ctx, deps = None):
# Fallback to `ctx.attr.deps`.
deps = deps if deps != None else ctx.attr.deps
for dep in deps:
- if not hasattr(dep, "typescript") and not hasattr(dep, "js"):
- allowed_deps_msg = "Dependencies must be ts_library"
-
- fail("%s is neither a TypeScript nor a JS producing rule.\n%s\n" % (dep.label, allowed_deps_msg))
+ if _LEGACY_TYPESCRIPT_PROVIDER_SUPPORT:
+ if not JSModuleInfo in dep and not hasattr(dep, "typescript") and not hasattr(dep, "js"):
+ allowed_deps_msg = "Dependencies must provide JSModuleInfo or \"typescript\" or \"js\""
+ fail("%s is neither a TypeScript nor a JS producing rule.\n%s\n" % (dep.label, allowed_deps_msg))
+ else:
+ if not JSModuleInfo in dep:
+ allowed_deps_msg = "Dependencies must provide JSModuleInfo"
+ fail("%s is not JS producing rule.\n%s\n" % (dep.label, allowed_deps_msg))
_DEPSET_TYPE = type(depset())
@@ -83,6 +89,26 @@ def _check_ts_provider(dep):
"""Verifies the type shape of the typescript provider in dep, if it has one.
"""
+ # Under Bazel, some third parties may create typescript providers which may not be compatible.
+ # Rather than users getting an obscure error later, explicitly check them and point to the
+ # target that created the bad provider.
+ if DeclarationInfo in dep:
+ if type(dep[DeclarationInfo].declarations) != _DEPSET_TYPE:
+ fail("typescript provider in %s defined declarations as a %s rather than a depset" % (
+ dep.label,
+ type(dep[DeclarationInfo].declarations),
+ ))
+ if type(dep[DeclarationInfo].transitive_declarations) != _DEPSET_TYPE:
+ fail("typescript provider in %s defined transitive_declarations as a %s rather than a depset" % (
+ dep.label,
+ type(dep[DeclarationInfo].transitive_declarations),
+ ))
+ return dep
+
+def _check_legacy_ts_provider(dep):
+ """Verifies the type shape of the legacy typescript provider in dep, if it has one.
+ """
+
# Under Bazel, some third parties have created typescript providers which may not be compatible.
# Rather than users getting an obscure error later, explicitly check them and point to the
# target that created the bad provider.
@@ -116,41 +142,51 @@ def _collect_dep_declarations(ctx, deps):
A struct of depsets for direct, transitive and type-blacklisted declarations.
"""
- deps_and_helpers = [
- _check_ts_provider(dep)
- for dep in deps + getattr(ctx.attr, "_helpers", [])
- if hasattr(dep, "typescript")
- ]
+ deps_and_helpers = deps + getattr(ctx.attr, "_helpers", [])
+
+ direct_declarations_depsets = []
+ transitive_declarations_depsets = []
+ type_blacklisted_declarations_depsets = []
+
+ for dep in deps_and_helpers:
+ if DeclarationInfo in dep:
+ # modern DeclarationInfo provider
+ _check_ts_provider(dep)
+
+ # .d.ts files from direct dependencies, ok for strict deps
+ direct_declarations_depsets.append(dep[DeclarationInfo].declarations)
+
+ # all reachable .d.ts files from dependencies.
+ transitive_declarations_depsets.append(dep[DeclarationInfo].transitive_declarations)
+
+ elif _LEGACY_TYPESCRIPT_PROVIDER_SUPPORT and hasattr(dep, "typescript"):
+ # legacy "typescript" provider
+ _check_legacy_ts_provider(dep)
- # .d.ts files from direct dependencies, ok for strict deps
- direct_deps_declarations = [dep.typescript.declarations for dep in deps_and_helpers]
+ # .d.ts files from direct dependencies, ok for strict deps
+ direct_declarations_depsets.append(dep.typescript.declarations)
- # all reachable .d.ts files from dependencies.
- transitive_deps_declarations = [
- dep.typescript.transitive_declarations
- for dep in deps_and_helpers
- ]
+ # all reachable .d.ts files from dependencies.
+ transitive_declarations_depsets.append(dep.typescript.transitive_declarations)
- # all reachable .d.ts files from node_modules attribute (if it has a typescript provider)
- if hasattr(ctx.attr, "node_modules") and hasattr(ctx.attr.node_modules, "typescript"):
- transitive_deps_declarations += [ctx.attr.node_modules.typescript.transitive_declarations]
+ # .d.ts files whose types tsickle will not emit (used for ts_declaration(generate_externs=False).
+ type_blacklisted_declarations_depsets.append(dep.typescript.type_blacklisted_declarations)
- # .d.ts files whose types tsickle will not emit (used for ts_declaration(generate_externs=False).
- type_blacklisted_declarations = [
- dep.typescript.type_blacklisted_declarations
- for dep in deps_and_helpers
- ]
+ # all reachable .d.ts files from node_modules attribute (if it has a DeclarationInfo provider)
+ if hasattr(ctx.attr, "node_modules") and DeclarationInfo in ctx.attr.node_modules:
+ direct_declarations_depsets.append(ctx.attr.node_modules[DeclarationInfo].declarations)
+ transitive_declarations_depsets.append(ctx.attr.node_modules[DeclarationInfo].transitive_declarations)
# If a tool like github.com/angular/clutz can create .d.ts from type annotated .js
# its output will be collected here.
return struct(
- direct = depset(transitive = direct_deps_declarations),
+ direct = depset(transitive = direct_declarations_depsets),
transitive = depset(
[extra for extra in ctx.files._additional_d_ts],
- transitive = transitive_deps_declarations,
+ transitive = transitive_declarations_depsets,
),
- type_blacklisted = depset(transitive = type_blacklisted_declarations),
+ type_blacklisted = depset(transitive = type_blacklisted_declarations_depsets),
)
def _should_generate_externs(ctx):
@@ -266,7 +302,7 @@ def compile_ts(
# Sources can be in sub-folders, but not in sub-packages.
fail("Sources must be in the same package as the ts_library rule, " +
"but %s is not in %s" % (src.label, ctx.label.package), "srcs")
- if hasattr(src, "typescript"):
+ if hasattr(src, "typescript") or JSModuleInfo in src:
# Guard against users accidentally putting deps into srcs by
# rejecting all srcs values that have a TypeScript provider.
# TS rules produce a ".d.ts" file, which is a valid input in "srcs",
@@ -449,7 +485,11 @@ def compile_ts(
# Re-export sources from deps.
# TODO(b/30018387): introduce an "exports" attribute.
for dep in deps:
- if hasattr(dep, "typescript"):
+ if DeclarationInfo in dep:
+ # modern DeclarationInfo provider
+ declarations_depsets.append(dep[DeclarationInfo].declarations)
+ elif _LEGACY_TYPESCRIPT_PROVIDER_SUPPORT and hasattr(dep, "typescript"):
+ # legacy "typescript" provider
declarations_depsets.append(dep.typescript.declarations)
files_depsets.extend(declarations_depsets)
@@ -459,15 +499,6 @@ def compile_ts(
if not is_library:
files_depsets.append(depset(tsickle_externs))
- transitive_es6_sources = depset()
- for dep in deps:
- if hasattr(dep, "typescript"):
- transitive_es6_sources = depset(transitive = [
- transitive_es6_sources,
- dep.typescript.transitive_es6_sources,
- ])
- transitive_es6_sources = depset(transitive = [transitive_es6_sources, es6_sources])
-
return {
"providers": [
DefaultInfo(
@@ -489,6 +520,19 @@ def compile_ts(
declarations = depset(transitive = declarations_depsets),
transitive_declarations = transitive_decls,
),
+ transitive_js_module_info(
+ module_format = "umd",
+ sources = es5_sources,
+ deps = ctx.attr.deps,
+ ),
+ transitive_js_named_module_info(
+ sources = es5_sources,
+ deps = ctx.attr.deps,
+ ),
+ transitive_js_ecma_script_module_info(
+ sources = es6_sources,
+ deps = ctx.attr.deps,
+ ),
],
"instrumented_files": {
"dependency_attributes": ["deps", "runtime_deps"],
@@ -510,7 +554,6 @@ def compile_ts(
"replay_params": replay_params,
# TODO(b/139705078): remove when consumers migrated to DeclarationInfo
"transitive_declarations": transitive_decls,
- "transitive_es6_sources": transitive_es6_sources,
"tsickle_externs": tsickle_externs,
"type_blacklisted_declarations": type_blacklisted_declarations,
},