@tamagui/compiler-core 0.0.0-bootstrap.0 → 3.0.0-beta.643.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -1
- package/dist/cjs/ast.cjs +95 -0
- package/dist/cjs/contracts.cjs +62 -0
- package/dist/cjs/diagnostics.cjs +69 -0
- package/dist/cjs/evaluate.cjs +351 -0
- package/dist/cjs/graph.cjs +279 -0
- package/dist/cjs/hash.cjs +49 -0
- package/dist/cjs/index.cjs +44 -0
- package/dist/cjs/ir.cjs +33 -0
- package/dist/cjs/lower.cjs +225 -0
- package/dist/cjs/materialize.cjs +200 -0
- package/dist/cjs/normalize.cjs +622 -0
- package/dist/cjs/output.cjs +149 -0
- package/dist/cjs/planCache.cjs +224 -0
- package/dist/cjs/session.cjs +119 -0
- package/dist/cjs/yuku.cjs +159 -0
- package/dist/cjs/zero.cjs +387 -0
- package/dist/esm/ast.mjs +65 -0
- package/dist/esm/ast.mjs.map +1 -0
- package/dist/esm/contracts.mjs +34 -0
- package/dist/esm/contracts.mjs.map +1 -0
- package/dist/esm/diagnostics.mjs +44 -0
- package/dist/esm/diagnostics.mjs.map +1 -0
- package/dist/esm/evaluate.mjs +327 -0
- package/dist/esm/evaluate.mjs.map +1 -0
- package/dist/esm/graph.mjs +256 -0
- package/dist/esm/graph.mjs.map +1 -0
- package/dist/esm/hash.mjs +26 -0
- package/dist/esm/hash.mjs.map +1 -0
- package/dist/esm/index.mjs +30 -0
- package/dist/esm/ir.mjs +12 -0
- package/dist/esm/ir.mjs.map +1 -0
- package/dist/esm/lower.mjs +202 -0
- package/dist/esm/lower.mjs.map +1 -0
- package/dist/esm/materialize.mjs +179 -0
- package/dist/esm/materialize.mjs.map +1 -0
- package/dist/esm/normalize.mjs +596 -0
- package/dist/esm/normalize.mjs.map +1 -0
- package/dist/esm/output.mjs +119 -0
- package/dist/esm/output.mjs.map +1 -0
- package/dist/esm/planCache.mjs +194 -0
- package/dist/esm/planCache.mjs.map +1 -0
- package/dist/esm/session.mjs +99 -0
- package/dist/esm/session.mjs.map +1 -0
- package/dist/esm/yuku.mjs +136 -0
- package/dist/esm/yuku.mjs.map +1 -0
- package/dist/esm/zero.mjs +352 -0
- package/dist/esm/zero.mjs.map +1 -0
- package/package.json +42 -4
- package/src/ast.ts +86 -0
- package/src/contracts.ts +148 -0
- package/src/diagnostics.ts +96 -0
- package/src/evaluate.ts +497 -0
- package/src/graph.ts +347 -0
- package/src/hash.ts +36 -0
- package/src/index.ts +15 -0
- package/src/ir.ts +154 -0
- package/src/lower.ts +418 -0
- package/src/materialize.ts +330 -0
- package/src/normalize.ts +846 -0
- package/src/output.ts +175 -0
- package/src/planCache.ts +327 -0
- package/src/session.ts +172 -0
- package/src/yuku.ts +189 -0
- package/src/zero.ts +598 -0
- package/types/ast.d.ts +10 -0
- package/types/ast.d.ts.map +1 -0
- package/types/contracts.d.ts +97 -0
- package/types/contracts.d.ts.map +1 -0
- package/types/diagnostics.d.ts +31 -0
- package/types/diagnostics.d.ts.map +1 -0
- package/types/evaluate.d.ts +36 -0
- package/types/evaluate.d.ts.map +1 -0
- package/types/graph.d.ts +37 -0
- package/types/graph.d.ts.map +1 -0
- package/types/hash.d.ts +8 -0
- package/types/hash.d.ts.map +1 -0
- package/types/index.d.ts +16 -0
- package/types/index.d.ts.map +1 -0
- package/types/ir.d.ts +118 -0
- package/types/ir.d.ts.map +1 -0
- package/types/lower.d.ts +99 -0
- package/types/lower.d.ts.map +1 -0
- package/types/materialize.d.ts +104 -0
- package/types/materialize.d.ts.map +1 -0
- package/types/normalize.d.ts +8 -0
- package/types/normalize.d.ts.map +1 -0
- package/types/output.d.ts +32 -0
- package/types/output.d.ts.map +1 -0
- package/types/planCache.d.ts +113 -0
- package/types/planCache.d.ts.map +1 -0
- package/types/session.d.ts +44 -0
- package/types/session.d.ts.map +1 -0
- package/types/yuku.d.ts +4 -0
- package/types/yuku.d.ts.map +1 -0
- package/types/zero.d.ts +98 -0
- package/types/zero.d.ts.map +1 -0
package/src/lower.ts
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import type { ResolvedModuleId, SourceSpan } from './contracts'
|
|
2
|
+
import { localBailout, type BailoutReason } from './diagnostics'
|
|
3
|
+
import type {
|
|
4
|
+
MaterializedElement,
|
|
5
|
+
MaterializedElementEntry,
|
|
6
|
+
MaterializedModule,
|
|
7
|
+
MaterializedStyledDefinition,
|
|
8
|
+
} from './materialize'
|
|
9
|
+
import {
|
|
10
|
+
sourceContentHash,
|
|
11
|
+
validateSourceEdits,
|
|
12
|
+
type ApplicableLoweredModulePlan,
|
|
13
|
+
type SourceEdit,
|
|
14
|
+
} from './output'
|
|
15
|
+
|
|
16
|
+
export const LOWERED_MODULE_PLAN_VERSION = 2
|
|
17
|
+
|
|
18
|
+
export type CompilerTarget = 'web' | 'native'
|
|
19
|
+
|
|
20
|
+
export interface LoweredModuleStats {
|
|
21
|
+
found: number
|
|
22
|
+
lowered: number
|
|
23
|
+
flattened: number
|
|
24
|
+
styled: number
|
|
25
|
+
bailed: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface LoweringComponent {
|
|
29
|
+
/** Canonical resolved module id plus export name, supplied by the host registry. */
|
|
30
|
+
key: string
|
|
31
|
+
canFlatten: boolean
|
|
32
|
+
staticConfig: unknown
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface LoweringCandidateInput {
|
|
36
|
+
id: ResolvedModuleId
|
|
37
|
+
source: string
|
|
38
|
+
target: CompilerTarget
|
|
39
|
+
module: MaterializedModule
|
|
40
|
+
element: MaterializedElement
|
|
41
|
+
styledDefinition: MaterializedStyledDefinition | null
|
|
42
|
+
component: LoweringComponent
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface CandidateImport {
|
|
46
|
+
content: string
|
|
47
|
+
origin: SourceSpan
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type LoweringCandidateResult =
|
|
51
|
+
| {
|
|
52
|
+
ok: true
|
|
53
|
+
edits: SourceEdit[]
|
|
54
|
+
css: string[]
|
|
55
|
+
imports: CandidateImport[]
|
|
56
|
+
dependencies?: ResolvedModuleId[]
|
|
57
|
+
diagnostics?: BailoutReason[]
|
|
58
|
+
flattened?: boolean
|
|
59
|
+
}
|
|
60
|
+
| { ok: false; bailout: BailoutReason }
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Tamagui's static adapter supplies stable style primitives and registry data. It does
|
|
64
|
+
* not traverse modules, apply edits, commit partial candidates, or choose a fallback.
|
|
65
|
+
*/
|
|
66
|
+
export interface CompilerLoweringHost {
|
|
67
|
+
resolveComponent(
|
|
68
|
+
element: MaterializedElement,
|
|
69
|
+
styledDefinition: MaterializedStyledDefinition | null
|
|
70
|
+
): LoweringComponent | null
|
|
71
|
+
isStyleProp(name: string, component: LoweringComponent): boolean
|
|
72
|
+
/** The host can retain this dynamic prop while committing other safe candidate edits. */
|
|
73
|
+
canLowerDynamicStyleProp?(
|
|
74
|
+
name: string,
|
|
75
|
+
component: LoweringComponent,
|
|
76
|
+
valueKind?: 'bailout' | 'conditional'
|
|
77
|
+
): boolean
|
|
78
|
+
lowerCandidate(input: LoweringCandidateInput): LoweringCandidateResult
|
|
79
|
+
/** Development-only source instrumentation for an existing component debug channel. */
|
|
80
|
+
developmentDebugInstrumentation?(
|
|
81
|
+
input: LoweringCandidateInput,
|
|
82
|
+
result: LoweringCandidateResult
|
|
83
|
+
): SourceEdit[] | undefined
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface LowerModuleOptions {
|
|
87
|
+
projectGeneration: string
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface StructuralModulePassResult {
|
|
91
|
+
module: MaterializedModule
|
|
92
|
+
edits: SourceEdit[]
|
|
93
|
+
imports: CandidateImport[]
|
|
94
|
+
diagnostics: BailoutReason[]
|
|
95
|
+
dependencies: ResolvedModuleId[]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface StructuralModulePass {
|
|
99
|
+
/** Stable implementation/data hash included in every lowerer cache identity. */
|
|
100
|
+
versionHash: string
|
|
101
|
+
transform(input: {
|
|
102
|
+
module: MaterializedModule
|
|
103
|
+
source: string
|
|
104
|
+
target: CompilerTarget
|
|
105
|
+
}): StructuralModulePassResult
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface LoweredModulePlan extends ApplicableLoweredModulePlan {
|
|
109
|
+
version: typeof LOWERED_MODULE_PLAN_VERSION
|
|
110
|
+
target: CompilerTarget
|
|
111
|
+
inputHash: string
|
|
112
|
+
projectGeneration: string
|
|
113
|
+
structuralPassHash: string
|
|
114
|
+
edits: SourceEdit[]
|
|
115
|
+
css: string
|
|
116
|
+
diagnostics: BailoutReason[]
|
|
117
|
+
dependencies: ResolvedModuleId[]
|
|
118
|
+
stats: LoweredModuleStats
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface LowerModuleInput {
|
|
122
|
+
module: MaterializedModule
|
|
123
|
+
source: string
|
|
124
|
+
target: CompilerTarget
|
|
125
|
+
host: CompilerLoweringHost
|
|
126
|
+
options: LowerModuleOptions
|
|
127
|
+
structuralPass?: StructuralModulePass
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function compareCodeUnits(left: string, right: string): number {
|
|
131
|
+
return left < right ? -1 : left > right ? 1 : 0
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* A diagnostic that stopped its candidate from lowering. Zero mode reports
|
|
136
|
+
* exactly these; the ones recorded next to a successful lowering describe a
|
|
137
|
+
* dropped prop and leave no runtime behind.
|
|
138
|
+
*/
|
|
139
|
+
function blocking(reason: BailoutReason): BailoutReason {
|
|
140
|
+
return { ...reason, blocking: true }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function diagnostic(
|
|
144
|
+
code: Extract<BailoutReason['code'], `local/${string}`>,
|
|
145
|
+
element: MaterializedElement,
|
|
146
|
+
message: string,
|
|
147
|
+
prop?: string
|
|
148
|
+
): BailoutReason {
|
|
149
|
+
return {
|
|
150
|
+
...localBailout(code, element.span, message),
|
|
151
|
+
component: element.component.name,
|
|
152
|
+
specifier: element.component.provenance?.specifier,
|
|
153
|
+
prop,
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function styledDefinitionFor(
|
|
158
|
+
module: MaterializedModule,
|
|
159
|
+
element: MaterializedElement
|
|
160
|
+
): MaterializedStyledDefinition | null {
|
|
161
|
+
const definition = element.component.definition
|
|
162
|
+
if (!definition) return null
|
|
163
|
+
return (
|
|
164
|
+
module.styledDefinitions.find(
|
|
165
|
+
(candidate) => candidate.id === definition.id && candidate.name === definition.name
|
|
166
|
+
) ?? null
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function unsafeEntry(
|
|
171
|
+
element: MaterializedElement,
|
|
172
|
+
entry: MaterializedElementEntry,
|
|
173
|
+
component: LoweringComponent,
|
|
174
|
+
host: CompilerLoweringHost
|
|
175
|
+
): BailoutReason | null {
|
|
176
|
+
if (entry.kind === 'spread' && entry.value.kind !== 'static') {
|
|
177
|
+
return diagnostic(
|
|
178
|
+
'local/unsafe-style-spread',
|
|
179
|
+
element,
|
|
180
|
+
'Unevaluated spread may change style and duplicate-prop precedence'
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
if (
|
|
184
|
+
entry.kind === 'prop' &&
|
|
185
|
+
host.isStyleProp(entry.name, component) &&
|
|
186
|
+
(entry.value.kind === 'bailout' || entry.value.kind === 'conditional') &&
|
|
187
|
+
!host.canLowerDynamicStyleProp?.(entry.name, component, entry.value.kind)
|
|
188
|
+
) {
|
|
189
|
+
return diagnostic(
|
|
190
|
+
'local/dynamic-style-value',
|
|
191
|
+
element,
|
|
192
|
+
`Style prop ${entry.name} could not be evaluated`,
|
|
193
|
+
entry.name
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
return null
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function editsAreCandidateLocal(
|
|
200
|
+
element: MaterializedElement,
|
|
201
|
+
edits: readonly SourceEdit[]
|
|
202
|
+
): boolean {
|
|
203
|
+
return edits.every(
|
|
204
|
+
(edit) =>
|
|
205
|
+
edit.origin.id === element.id &&
|
|
206
|
+
edit.start >= element.span.start &&
|
|
207
|
+
edit.end <= element.span.end
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function overlapsCommitted(
|
|
212
|
+
edits: readonly SourceEdit[],
|
|
213
|
+
committed: readonly SourceEdit[]
|
|
214
|
+
) {
|
|
215
|
+
return edits.some((edit) =>
|
|
216
|
+
committed.some((existing) => {
|
|
217
|
+
if (edit.start === edit.end) {
|
|
218
|
+
return edit.start > existing.start && edit.start < existing.end
|
|
219
|
+
}
|
|
220
|
+
if (existing.start === existing.end) {
|
|
221
|
+
return existing.start > edit.start && existing.start < edit.end
|
|
222
|
+
}
|
|
223
|
+
return edit.start < existing.end && existing.start < edit.end
|
|
224
|
+
})
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Builds one JSON-safe plan. Each recognized candidate commits all edits/CSS/imports or none. */
|
|
229
|
+
export function lowerModule({
|
|
230
|
+
module,
|
|
231
|
+
source,
|
|
232
|
+
target,
|
|
233
|
+
host,
|
|
234
|
+
options,
|
|
235
|
+
structuralPass,
|
|
236
|
+
}: LowerModuleInput): LoweredModulePlan {
|
|
237
|
+
const stats: LoweredModuleStats = {
|
|
238
|
+
found: 0,
|
|
239
|
+
lowered: 0,
|
|
240
|
+
flattened: 0,
|
|
241
|
+
styled: 0,
|
|
242
|
+
bailed: 0,
|
|
243
|
+
}
|
|
244
|
+
const structural = structuralPass
|
|
245
|
+
? structuralPass.transform({ module, source, target })
|
|
246
|
+
: {
|
|
247
|
+
module,
|
|
248
|
+
edits: [],
|
|
249
|
+
imports: [],
|
|
250
|
+
diagnostics: [],
|
|
251
|
+
dependencies: [],
|
|
252
|
+
}
|
|
253
|
+
if (structural.module.id !== module.id) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Structural pass changed module identity from ${module.id} to ${structural.module.id}`
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
if (structuralPass && !structuralPass.versionHash) {
|
|
259
|
+
throw new Error('Structural pass must provide a non-empty version hash')
|
|
260
|
+
}
|
|
261
|
+
module = structural.module
|
|
262
|
+
validateSourceEdits(source, structural.edits)
|
|
263
|
+
const edits: SourceEdit[] = [...structural.edits]
|
|
264
|
+
// One rule per identifier, first use wins, which is exactly what the runtime
|
|
265
|
+
// does: insertStyleRule's shouldInsertStyleRules skips an identifier already
|
|
266
|
+
// in the sheet (maxToInsert is 1) and appends the rest in first-use order.
|
|
267
|
+
// Emitting a rule once per element instead put the same
|
|
268
|
+
// `._t-1731853650{...}` into the output for every element that used it.
|
|
269
|
+
const css = new Set<string>()
|
|
270
|
+
const diagnostics = [...module.diagnostics, ...structural.diagnostics]
|
|
271
|
+
const dependencies = new Set([...module.dependencies, ...structural.dependencies])
|
|
272
|
+
const imports = new Map<string, CandidateImport>(
|
|
273
|
+
structural.imports.map((candidateImport) => [
|
|
274
|
+
candidateImport.content,
|
|
275
|
+
candidateImport,
|
|
276
|
+
])
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
for (const element of module.elements) {
|
|
280
|
+
const styledDefinition = styledDefinitionFor(module, element)
|
|
281
|
+
const component = host.resolveComponent(element, styledDefinition)
|
|
282
|
+
if (!component) continue
|
|
283
|
+
stats.found++
|
|
284
|
+
|
|
285
|
+
const input: LoweringCandidateInput = {
|
|
286
|
+
id: module.id,
|
|
287
|
+
source,
|
|
288
|
+
target,
|
|
289
|
+
module,
|
|
290
|
+
element,
|
|
291
|
+
styledDefinition,
|
|
292
|
+
component,
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const commitDevelopmentDebug = (result: LoweringCandidateResult) => {
|
|
296
|
+
const debugEdits = host.developmentDebugInstrumentation?.(input, result)
|
|
297
|
+
if (!debugEdits) return
|
|
298
|
+
validateSourceEdits(source, debugEdits)
|
|
299
|
+
if (
|
|
300
|
+
!editsAreCandidateLocal(element, debugEdits) ||
|
|
301
|
+
overlapsCommitted(debugEdits, edits)
|
|
302
|
+
) {
|
|
303
|
+
throw new Error('Development debug instrumentation must stay candidate-local')
|
|
304
|
+
}
|
|
305
|
+
edits.push(...debugEdits)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!element.complete || (styledDefinition && !styledDefinition.complete)) {
|
|
309
|
+
const reasons = [
|
|
310
|
+
...element.bailouts.map(blocking),
|
|
311
|
+
...(styledDefinition?.bailouts ?? []).map(blocking),
|
|
312
|
+
]
|
|
313
|
+
diagnostics.push(...reasons)
|
|
314
|
+
const reason = reasons[0]
|
|
315
|
+
if (reason) commitDevelopmentDebug({ ok: false, bailout: reason })
|
|
316
|
+
stats.bailed++
|
|
317
|
+
continue
|
|
318
|
+
}
|
|
319
|
+
const unsafe = element.entries
|
|
320
|
+
.map((entry) => unsafeEntry(element, entry, component, host))
|
|
321
|
+
.find((result): result is BailoutReason => result !== null)
|
|
322
|
+
if (unsafe) {
|
|
323
|
+
diagnostics.push(blocking(unsafe))
|
|
324
|
+
commitDevelopmentDebug({ ok: false, bailout: blocking(unsafe) })
|
|
325
|
+
stats.bailed++
|
|
326
|
+
continue
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
let result: LoweringCandidateResult
|
|
330
|
+
try {
|
|
331
|
+
result = host.lowerCandidate(input)
|
|
332
|
+
} catch (error) {
|
|
333
|
+
result = {
|
|
334
|
+
ok: false,
|
|
335
|
+
bailout: diagnostic(
|
|
336
|
+
'local/style-resolution-failed',
|
|
337
|
+
element,
|
|
338
|
+
`Style resolution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
339
|
+
),
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (!result.ok) {
|
|
343
|
+
diagnostics.push(blocking(result.bailout))
|
|
344
|
+
commitDevelopmentDebug(result)
|
|
345
|
+
stats.bailed++
|
|
346
|
+
continue
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
validateSourceEdits(source, result.edits)
|
|
350
|
+
} catch (error) {
|
|
351
|
+
const reason = blocking(
|
|
352
|
+
diagnostic(
|
|
353
|
+
'local/overlapping-edit',
|
|
354
|
+
element,
|
|
355
|
+
error instanceof Error ? error.message : String(error)
|
|
356
|
+
)
|
|
357
|
+
)
|
|
358
|
+
diagnostics.push(reason)
|
|
359
|
+
commitDevelopmentDebug({ ok: false, bailout: reason })
|
|
360
|
+
stats.bailed++
|
|
361
|
+
continue
|
|
362
|
+
}
|
|
363
|
+
if (
|
|
364
|
+
!editsAreCandidateLocal(element, result.edits) ||
|
|
365
|
+
overlapsCommitted(result.edits, edits)
|
|
366
|
+
) {
|
|
367
|
+
const reason = blocking(
|
|
368
|
+
diagnostic(
|
|
369
|
+
'local/overlapping-edit',
|
|
370
|
+
element,
|
|
371
|
+
'Candidate edits overlap another candidate or escape the element span'
|
|
372
|
+
)
|
|
373
|
+
)
|
|
374
|
+
diagnostics.push(reason)
|
|
375
|
+
commitDevelopmentDebug({ ok: false, bailout: reason })
|
|
376
|
+
stats.bailed++
|
|
377
|
+
continue
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
diagnostics.push(...(result.diagnostics ?? []))
|
|
381
|
+
edits.push(...result.edits)
|
|
382
|
+
commitDevelopmentDebug(result)
|
|
383
|
+
for (const rule of result.css) css.add(rule)
|
|
384
|
+
for (const candidateImport of result.imports) {
|
|
385
|
+
if (!imports.has(candidateImport.content)) {
|
|
386
|
+
imports.set(candidateImport.content, candidateImport)
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
for (const dependency of result.dependencies ?? []) dependencies.add(dependency)
|
|
390
|
+
stats.lowered++
|
|
391
|
+
if (result.flattened) stats.flattened++
|
|
392
|
+
if (styledDefinition) stats.styled++
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
for (const candidateImport of imports.values()) {
|
|
396
|
+
edits.push({
|
|
397
|
+
start: source.length,
|
|
398
|
+
end: source.length,
|
|
399
|
+
content: candidateImport.content,
|
|
400
|
+
origin: candidateImport.origin,
|
|
401
|
+
})
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return {
|
|
405
|
+
version: LOWERED_MODULE_PLAN_VERSION,
|
|
406
|
+
id: module.id,
|
|
407
|
+
target,
|
|
408
|
+
inputHash: module.inputHash,
|
|
409
|
+
sourceHash: sourceContentHash(source),
|
|
410
|
+
projectGeneration: options.projectGeneration,
|
|
411
|
+
structuralPassHash: structuralPass?.versionHash ?? `${target}-noop-v1`,
|
|
412
|
+
edits,
|
|
413
|
+
css: [...css].join(''),
|
|
414
|
+
diagnostics,
|
|
415
|
+
dependencies: [...dependencies].sort(compareCodeUnits),
|
|
416
|
+
stats,
|
|
417
|
+
}
|
|
418
|
+
}
|