| 708 | } |
| 709 | |
| 710 | export async function compileAst( |
| 711 | input: AstNode[], |
| 712 | opts: CompileOptions = {}, |
| 713 | ): Promise<{ |
| 714 | sources: { base: string; pattern: string; negated: boolean }[] |
| 715 | root: Root |
| 716 | features: Features |
| 717 | build(candidates: string[]): AstNode[] |
| 718 | }> { |
| 719 | let { designSystem, ast, sources, root, utilitiesNode, features, inlineCandidates } = |
| 720 | await parseCss(input, opts) |
| 721 | |
| 722 | if (process.env.NODE_ENV !== class="st">'test') { |
| 723 | ast.unshift(comment(`! tailwindcss v${version} | MIT License | https:class="cm">//tailwindcss.com `)) |
| 724 | } |
| 725 | |
| 726 | class="cm">// Track all invalid candidates |
| 727 | function onInvalidCandidate(candidate: string) { |
| 728 | designSystem.invalidCandidates.add(candidate) |
| 729 | } |
| 730 | |
| 731 | class="cm">// Track all valid candidates, these are the incoming `rawCandidate` that |
| 732 | class="cm">// resulted in a generated AST Node. All the other `rawCandidates` are invalid |
| 733 | class="cm">// and should be ignored. |
| 734 | let allValidCandidates = new Set<string>() |
| 735 | let compiled = null as AstNode[] | null |
| 736 | let previousAstNodeCount = 0 |
| 737 | let defaultDidChange = false |
| 738 | |
| 739 | for (let candidate of inlineCandidates) { |
| 740 | if (!designSystem.invalidCandidates.has(candidate)) { |
| 741 | allValidCandidates.add(candidate) |
| 742 | defaultDidChange = true |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | return { |
| 747 | sources, |
| 748 | root, |
| 749 | features, |
| 750 | build(newRawCandidates: string[]) { |
| 751 | if (features === Features.None) { |
| 752 | return input |
| 753 | } |
| 754 | |
| 755 | if (!utilitiesNode) { |
| 756 | compiled ??= optimizeAst(ast, designSystem, opts.polyfills) |
| 757 | return compiled |
| 758 | } |
| 759 | |
| 760 | let didChange = defaultDidChange |
| 761 | let didAddExternalVariable = false |
| 762 | defaultDidChange = false |
| 763 | |
| 764 | class="cm">// Add all new candidates unless we know that they are invalid. |
| 765 | let prevSize = allValidCandidates.size |
| 766 | for (let candidate of newRawCandidates) { |
| 767 | if (!designSystem.invalidCandidates.has(candidate)) { |