tsc-ts 0.0.4 → 0.0.5
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/README.md +33 -1
- package/dist/api/compiler/ast-utilities.d.ts +82 -0
- package/dist/api/compiler/ast-utilities.js +462 -0
- package/dist/api/compiler/ast.d.ts +2350 -0
- package/dist/api/compiler/ast.js +11206 -0
- package/dist/api/compiler/astnav.d.ts +37 -0
- package/dist/api/compiler/astnav.js +767 -0
- package/dist/api/compiler/binder-utilities.d.ts +182 -0
- package/dist/api/compiler/binder-utilities.js +1240 -0
- package/dist/api/compiler/binder.d.ts +33 -0
- package/dist/api/compiler/binder.js +2358 -0
- package/dist/api/compiler/character-codes.d.ts +161 -0
- package/dist/api/compiler/character-codes.js +160 -0
- package/dist/api/compiler/checker-calls.d.ts +46 -0
- package/dist/api/compiler/checker-calls.js +1640 -0
- package/dist/api/compiler/checker-classes.d.ts +30 -0
- package/dist/api/compiler/checker-classes.js +582 -0
- package/dist/api/compiler/checker-contextual.d.ts +77 -0
- package/dist/api/compiler/checker-contextual.js +1136 -0
- package/dist/api/compiler/checker-declaration-order.d.ts +12 -0
- package/dist/api/compiler/checker-declaration-order.js +356 -0
- package/dist/api/compiler/checker-declarations.d.ts +33 -0
- package/dist/api/compiler/checker-declarations.js +888 -0
- package/dist/api/compiler/checker-declared-types.d.ts +48 -0
- package/dist/api/compiler/checker-declared-types.js +787 -0
- package/dist/api/compiler/checker-decorators.d.ts +26 -0
- package/dist/api/compiler/checker-decorators.js +562 -0
- package/dist/api/compiler/checker-deprecation.d.ts +33 -0
- package/dist/api/compiler/checker-deprecation.js +315 -0
- package/dist/api/compiler/checker-destructuring.d.ts +34 -0
- package/dist/api/compiler/checker-destructuring.js +584 -0
- package/dist/api/compiler/checker-elaboration.d.ts +15 -0
- package/dist/api/compiler/checker-elaboration.js +290 -0
- package/dist/api/compiler/checker-emit-helpers.d.ts +58 -0
- package/dist/api/compiler/checker-emit-helpers.js +154 -0
- package/dist/api/compiler/checker-emit-resolver.d.ts +75 -0
- package/dist/api/compiler/checker-emit-resolver.js +579 -0
- package/dist/api/compiler/checker-evaluator.d.ts +27 -0
- package/dist/api/compiler/checker-evaluator.js +188 -0
- package/dist/api/compiler/checker-expressions.d.ts +67 -0
- package/dist/api/compiler/checker-expressions.js +1351 -0
- package/dist/api/compiler/checker-features.d.ts +6 -0
- package/dist/api/compiler/checker-features.js +354 -0
- package/dist/api/compiler/checker-flow.d.ts +86 -0
- package/dist/api/compiler/checker-flow.js +169 -0
- package/dist/api/compiler/checker-functions.d.ts +43 -0
- package/dist/api/compiler/checker-functions.js +1002 -0
- package/dist/api/compiler/checker-generated-code.d.ts +25 -0
- package/dist/api/compiler/checker-generated-code.js +168 -0
- package/dist/api/compiler/checker-globals.d.ts +14 -0
- package/dist/api/compiler/checker-globals.js +37 -0
- package/dist/api/compiler/checker-grammar.d.ts +35 -0
- package/dist/api/compiler/checker-grammar.js +2573 -0
- package/dist/api/compiler/checker-heritage.d.ts +28 -0
- package/dist/api/compiler/checker-heritage.js +900 -0
- package/dist/api/compiler/checker-inference.d.ts +179 -0
- package/dist/api/compiler/checker-inference.js +2105 -0
- package/dist/api/compiler/checker-iteration.d.ts +115 -0
- package/dist/api/compiler/checker-iteration.js +857 -0
- package/dist/api/compiler/checker-javascript.d.ts +42 -0
- package/dist/api/compiler/checker-javascript.js +441 -0
- package/dist/api/compiler/checker-jsdoc.d.ts +30 -0
- package/dist/api/compiler/checker-jsdoc.js +320 -0
- package/dist/api/compiler/checker-jsx.d.ts +94 -0
- package/dist/api/compiler/checker-jsx.js +1433 -0
- package/dist/api/compiler/checker-literals.d.ts +6 -0
- package/dist/api/compiler/checker-literals.js +43 -0
- package/dist/api/compiler/checker-members.d.ts +198 -0
- package/dist/api/compiler/checker-members.js +2126 -0
- package/dist/api/compiler/checker-modules.d.ts +85 -0
- package/dist/api/compiler/checker-modules.js +2141 -0
- package/dist/api/compiler/checker-narrowing.d.ts +120 -0
- package/dist/api/compiler/checker-narrowing.js +2797 -0
- package/dist/api/compiler/checker-object-literals.d.ts +14 -0
- package/dist/api/compiler/checker-object-literals.js +479 -0
- package/dist/api/compiler/checker-operators.d.ts +33 -0
- package/dist/api/compiler/checker-operators.js +1040 -0
- package/dist/api/compiler/checker-overloads.d.ts +7 -0
- package/dist/api/compiler/checker-overloads.js +270 -0
- package/dist/api/compiler/checker-property-access.d.ts +34 -0
- package/dist/api/compiler/checker-property-access.js +672 -0
- package/dist/api/compiler/checker-services.d.ts +49 -0
- package/dist/api/compiler/checker-services.js +995 -0
- package/dist/api/compiler/checker-signatures.d.ts +55 -0
- package/dist/api/compiler/checker-signatures.js +788 -0
- package/dist/api/compiler/checker-source-file.d.ts +27 -0
- package/dist/api/compiler/checker-source-file.js +619 -0
- package/dist/api/compiler/checker-statements.d.ts +18 -0
- package/dist/api/compiler/checker-statements.js +226 -0
- package/dist/api/compiler/checker-super.d.ts +13 -0
- package/dist/api/compiler/checker-super.js +241 -0
- package/dist/api/compiler/checker-symbol-types.d.ts +67 -0
- package/dist/api/compiler/checker-symbol-types.js +1885 -0
- package/dist/api/compiler/checker-symbols.d.ts +181 -0
- package/dist/api/compiler/checker-symbols.js +1782 -0
- package/dist/api/compiler/checker-type-factory.d.ts +142 -0
- package/dist/api/compiler/checker-type-factory.js +2501 -0
- package/dist/api/compiler/checker-type-nodes.d.ts +26 -0
- package/dist/api/compiler/checker-type-nodes.js +828 -0
- package/dist/api/compiler/checker-type-operators.d.ts +109 -0
- package/dist/api/compiler/checker-type-operators.js +1842 -0
- package/dist/api/compiler/checker-types.d.ts +1027 -0
- package/dist/api/compiler/checker-types.js +1697 -0
- package/dist/api/compiler/checker-unused.d.ts +19 -0
- package/dist/api/compiler/checker-unused.js +524 -0
- package/dist/api/compiler/checker-utilities.d.ts +33 -0
- package/dist/api/compiler/checker-utilities.js +141 -0
- package/dist/api/compiler/checker.d.ts +491 -0
- package/dist/api/compiler/checker.js +912 -0
- package/dist/api/compiler/command-line.d.ts +32 -0
- package/dist/api/compiler/command-line.js +383 -0
- package/dist/api/compiler/compile-program.d.ts +118 -0
- package/dist/api/compiler/compile-program.js +384 -0
- package/dist/api/compiler/diagnostic-locales.d.ts +22 -0
- package/dist/api/compiler/diagnostic-locales.js +64 -0
- package/dist/api/compiler/diagnostic-messages.d.ts +2166 -0
- package/dist/api/compiler/diagnostic-messages.js +184 -0
- package/dist/api/compiler/diagnostics.d.ts +167 -0
- package/dist/api/compiler/diagnostics.js +820 -0
- package/dist/api/compiler/emitter.d.ts +71 -0
- package/dist/api/compiler/emitter.js +327 -0
- package/dist/api/compiler/file-include.d.ts +117 -0
- package/dist/api/compiler/file-include.js +536 -0
- package/dist/api/compiler/file-loader.d.ts +261 -0
- package/dist/api/compiler/file-loader.js +1257 -0
- package/dist/api/compiler/file-system.d.ts +51 -0
- package/dist/api/compiler/file-system.js +132 -0
- package/dist/api/compiler/flow.d.ts +60 -0
- package/dist/api/compiler/flow.js +45 -0
- package/dist/api/compiler/instantiation.d.ts +74 -0
- package/dist/api/compiler/instantiation.js +799 -0
- package/dist/api/compiler/jsdoc.d.ts +75 -0
- package/dist/api/compiler/jsdoc.js +1229 -0
- package/dist/api/compiler/link-tables.d.ts +36 -0
- package/dist/api/compiler/link-tables.js +83 -0
- package/dist/api/compiler/locale-data.d.ts +24 -0
- package/dist/api/compiler/locale-data.js +183 -0
- package/dist/api/compiler/locale.d.ts +4 -0
- package/dist/api/compiler/locale.js +317 -0
- package/dist/api/compiler/locales/cs-CZ.d.ts +2 -0
- package/dist/api/compiler/locales/cs-CZ.js +3 -0
- package/dist/api/compiler/locales/de-DE.d.ts +2 -0
- package/dist/api/compiler/locales/de-DE.js +3 -0
- package/dist/api/compiler/locales/es-ES.d.ts +2 -0
- package/dist/api/compiler/locales/es-ES.js +3 -0
- package/dist/api/compiler/locales/fr-FR.d.ts +2 -0
- package/dist/api/compiler/locales/fr-FR.js +3 -0
- package/dist/api/compiler/locales/it-IT.d.ts +2 -0
- package/dist/api/compiler/locales/it-IT.js +3 -0
- package/dist/api/compiler/locales/ja-JP.d.ts +2 -0
- package/dist/api/compiler/locales/ja-JP.js +3 -0
- package/dist/api/compiler/locales/ko-KR.d.ts +2 -0
- package/dist/api/compiler/locales/ko-KR.js +3 -0
- package/dist/api/compiler/locales/pl-PL.d.ts +2 -0
- package/dist/api/compiler/locales/pl-PL.js +3 -0
- package/dist/api/compiler/locales/pt-BR.d.ts +2 -0
- package/dist/api/compiler/locales/pt-BR.js +3 -0
- package/dist/api/compiler/locales/ru-RU.d.ts +2 -0
- package/dist/api/compiler/locales/ru-RU.js +3 -0
- package/dist/api/compiler/locales/tr-TR.d.ts +2 -0
- package/dist/api/compiler/locales/tr-TR.js +3 -0
- package/dist/api/compiler/locales/zh-CN.d.ts +2 -0
- package/dist/api/compiler/locales/zh-CN.js +3 -0
- package/dist/api/compiler/locales/zh-TW.d.ts +2 -0
- package/dist/api/compiler/locales/zh-TW.js +3 -0
- package/dist/api/compiler/module-resolution-types.d.ts +83 -0
- package/dist/api/compiler/module-resolution-types.js +176 -0
- package/dist/api/compiler/module-resolution.d.ts +71 -0
- package/dist/api/compiler/module-resolution.js +1598 -0
- package/dist/api/compiler/module-specifiers.d.ts +64 -0
- package/dist/api/compiler/module-specifiers.js +1101 -0
- package/dist/api/compiler/name-resolver.d.ts +43 -0
- package/dist/api/compiler/name-resolver.js +509 -0
- package/dist/api/compiler/node-builder-names.d.ts +32 -0
- package/dist/api/compiler/node-builder-names.js +854 -0
- package/dist/api/compiler/node-builder-pseudo.d.ts +36 -0
- package/dist/api/compiler/node-builder-pseudo.js +744 -0
- package/dist/api/compiler/node-builder-reuse.d.ts +4 -0
- package/dist/api/compiler/node-builder-reuse.js +647 -0
- package/dist/api/compiler/node-builder.d.ts +270 -0
- package/dist/api/compiler/node-builder.js +2645 -0
- package/dist/api/compiler/option-declarations.d.ts +90 -0
- package/dist/api/compiler/option-declarations.js +1460 -0
- package/dist/api/compiler/options.d.ts +289 -0
- package/dist/api/compiler/options.js +1197 -0
- package/dist/api/compiler/output-paths.d.ts +42 -0
- package/dist/api/compiler/output-paths.js +195 -0
- package/dist/api/compiler/package-json.d.ts +175 -0
- package/dist/api/compiler/package-json.js +1015 -0
- package/dist/api/compiler/parallel-parse.d.ts +219 -0
- package/dist/api/compiler/parallel-parse.js +537 -0
- package/dist/api/compiler/parser.d.ts +587 -0
- package/dist/api/compiler/parser.js +6407 -0
- package/dist/api/compiler/path.d.ts +91 -0
- package/dist/api/compiler/path.js +705 -0
- package/dist/api/compiler/printer/async-helpers.d.ts +22 -0
- package/dist/api/compiler/printer/async-helpers.js +91 -0
- package/dist/api/compiler/printer/auto-generate.d.ts +13 -0
- package/dist/api/compiler/printer/auto-generate.js +20 -0
- package/dist/api/compiler/printer/decorator-helpers.d.ts +24 -0
- package/dist/api/compiler/printer/decorator-helpers.js +118 -0
- package/dist/api/compiler/printer/emit-context.d.ts +154 -0
- package/dist/api/compiler/printer/emit-context.js +576 -0
- package/dist/api/compiler/printer/emit-flags.d.ts +60 -0
- package/dist/api/compiler/printer/emit-flags.js +2 -0
- package/dist/api/compiler/printer/factory-base.d.ts +171 -0
- package/dist/api/compiler/printer/factory-base.js +1505 -0
- package/dist/api/compiler/printer/factory.d.ts +147 -0
- package/dist/api/compiler/printer/factory.js +542 -0
- package/dist/api/compiler/printer/helpers.d.ts +27 -0
- package/dist/api/compiler/printer/helpers.js +164 -0
- package/dist/api/compiler/printer/name-generator.d.ts +41 -0
- package/dist/api/compiler/printer/name-generator.js +283 -0
- package/dist/api/compiler/printer/printer.d.ts +411 -0
- package/dist/api/compiler/printer/printer.js +4517 -0
- package/dist/api/compiler/printer/text-writer.d.ts +46 -0
- package/dist/api/compiler/printer/text-writer.js +172 -0
- package/dist/api/compiler/printer/utilities.d.ts +82 -0
- package/dist/api/compiler/printer/utilities.js +817 -0
- package/dist/api/compiler/program-checker.d.ts +156 -0
- package/dist/api/compiler/program-checker.js +526 -0
- package/dist/api/compiler/program-utilities.d.ts +52 -0
- package/dist/api/compiler/program-utilities.js +365 -0
- package/dist/api/compiler/program.d.ts +180 -0
- package/dist/api/compiler/program.js +1011 -0
- package/dist/api/compiler/pseudo-bigint.d.ts +5 -0
- package/dist/api/compiler/pseudo-bigint.js +61 -0
- package/dist/api/compiler/regexp-checker.d.ts +38 -0
- package/dist/api/compiler/regexp-checker.js +942 -0
- package/dist/api/compiler/relations.d.ts +263 -0
- package/dist/api/compiler/relations.js +4002 -0
- package/dist/api/compiler/reparser.d.ts +48 -0
- package/dist/api/compiler/reparser.js +1323 -0
- package/dist/api/compiler/scanner.d.ts +256 -0
- package/dist/api/compiler/scanner.js +2853 -0
- package/dist/api/compiler/side-state.d.ts +16 -0
- package/dist/api/compiler/side-state.js +89 -0
- package/dist/api/compiler/sourcemap.d.ts +55 -0
- package/dist/api/compiler/sourcemap.js +340 -0
- package/dist/api/compiler/spelling.d.ts +14 -0
- package/dist/api/compiler/spelling.js +128 -0
- package/dist/api/compiler/symbol-accessibility.d.ts +57 -0
- package/dist/api/compiler/symbol-accessibility.js +894 -0
- package/dist/api/compiler/symbol.d.ts +240 -0
- package/dist/api/compiler/symbol.js +228 -0
- package/dist/api/compiler/symlinks.d.ts +32 -0
- package/dist/api/compiler/symlinks.js +114 -0
- package/dist/api/compiler/syntax-kind.d.ts +389 -0
- package/dist/api/compiler/syntax-kind.js +2 -0
- package/dist/api/compiler/timeline.d.ts +9 -0
- package/dist/api/compiler/timeline.js +54 -0
- package/dist/api/compiler/transformers/alias-references.d.ts +39 -0
- package/dist/api/compiler/transformers/alias-references.js +676 -0
- package/dist/api/compiler/transformers/async-utilities.d.ts +51 -0
- package/dist/api/compiler/transformers/async-utilities.js +260 -0
- package/dist/api/compiler/transformers/async.d.ts +53 -0
- package/dist/api/compiler/transformers/async.js +645 -0
- package/dist/api/compiler/transformers/class-fields.d.ts +206 -0
- package/dist/api/compiler/transformers/class-fields.js +2418 -0
- package/dist/api/compiler/transformers/class-utilities.d.ts +46 -0
- package/dist/api/compiler/transformers/class-utilities.js +261 -0
- package/dist/api/compiler/transformers/commonjs-module.d.ts +103 -0
- package/dist/api/compiler/transformers/commonjs-module.js +1180 -0
- package/dist/api/compiler/transformers/const-enum-inliner.d.ts +11 -0
- package/dist/api/compiler/transformers/const-enum-inliner.js +36 -0
- package/dist/api/compiler/transformers/declarations-diagnostics.d.ts +52 -0
- package/dist/api/compiler/transformers/declarations-diagnostics.js +538 -0
- package/dist/api/compiler/transformers/declarations-pseudo.d.ts +160 -0
- package/dist/api/compiler/transformers/declarations-pseudo.js +797 -0
- package/dist/api/compiler/transformers/declarations-resolver.d.ts +152 -0
- package/dist/api/compiler/transformers/declarations-resolver.js +35 -0
- package/dist/api/compiler/transformers/declarations-syntactic.d.ts +119 -0
- package/dist/api/compiler/transformers/declarations-syntactic.js +1582 -0
- package/dist/api/compiler/transformers/declarations-tracker.d.ts +46 -0
- package/dist/api/compiler/transformers/declarations-tracker.js +197 -0
- package/dist/api/compiler/transformers/declarations.d.ts +175 -0
- package/dist/api/compiler/transformers/declarations.js +2380 -0
- package/dist/api/compiler/transformers/decorator-metadata.d.ts +54 -0
- package/dist/api/compiler/transformers/decorator-metadata.js +554 -0
- package/dist/api/compiler/transformers/decorator-utilities.d.ts +38 -0
- package/dist/api/compiler/transformers/decorator-utilities.js +238 -0
- package/dist/api/compiler/transformers/destructuring.d.ts +25 -0
- package/dist/api/compiler/transformers/destructuring.js +626 -0
- package/dist/api/compiler/transformers/downlevel.d.ts +6 -0
- package/dist/api/compiler/transformers/downlevel.js +45 -0
- package/dist/api/compiler/transformers/emit-resolver.d.ts +61 -0
- package/dist/api/compiler/transformers/emit-resolver.js +197 -0
- package/dist/api/compiler/transformers/es-decorators.d.ts +118 -0
- package/dist/api/compiler/transformers/es-decorators.js +1901 -0
- package/dist/api/compiler/transformers/exponentiation.d.ts +11 -0
- package/dist/api/compiler/transformers/exponentiation.js +76 -0
- package/dist/api/compiler/transformers/external-module-info.d.ts +35 -0
- package/dist/api/compiler/transformers/external-module-info.js +351 -0
- package/dist/api/compiler/transformers/for-await.d.ts +43 -0
- package/dist/api/compiler/transformers/for-await.js +469 -0
- package/dist/api/compiler/transformers/import-elision.d.ts +16 -0
- package/dist/api/compiler/transformers/import-elision.js +124 -0
- package/dist/api/compiler/transformers/jsx-entities.d.ts +1 -0
- package/dist/api/compiler/transformers/jsx-entities.js +256 -0
- package/dist/api/compiler/transformers/jsx.d.ts +71 -0
- package/dist/api/compiler/transformers/jsx.js +700 -0
- package/dist/api/compiler/transformers/legacy-decorators.d.ts +56 -0
- package/dist/api/compiler/transformers/legacy-decorators.js +564 -0
- package/dist/api/compiler/transformers/logical-assignment.d.ts +14 -0
- package/dist/api/compiler/transformers/logical-assignment.js +62 -0
- package/dist/api/compiler/transformers/module-utilities.d.ts +9 -0
- package/dist/api/compiler/transformers/module-utilities.js +36 -0
- package/dist/api/compiler/transformers/module.d.ts +49 -0
- package/dist/api/compiler/transformers/module.js +296 -0
- package/dist/api/compiler/transformers/named-evaluation.d.ts +26 -0
- package/dist/api/compiler/transformers/named-evaluation.js +266 -0
- package/dist/api/compiler/transformers/nullish-coalescing.d.ts +9 -0
- package/dist/api/compiler/transformers/nullish-coalescing.js +26 -0
- package/dist/api/compiler/transformers/object-rest-spread.d.ts +34 -0
- package/dist/api/compiler/transformers/object-rest-spread.js +411 -0
- package/dist/api/compiler/transformers/optional-catch.d.ts +9 -0
- package/dist/api/compiler/transformers/optional-catch.js +20 -0
- package/dist/api/compiler/transformers/optional-chain.d.ts +14 -0
- package/dist/api/compiler/transformers/optional-chain.js +188 -0
- package/dist/api/compiler/transformers/reference-resolver.d.ts +128 -0
- package/dist/api/compiler/transformers/reference-resolver.js +1155 -0
- package/dist/api/compiler/transformers/runtime-syntax.d.ts +71 -0
- package/dist/api/compiler/transformers/runtime-syntax.js +753 -0
- package/dist/api/compiler/transformers/subtree-facts.d.ts +9 -0
- package/dist/api/compiler/transformers/subtree-facts.js +203 -0
- package/dist/api/compiler/transformers/syntax-facts.d.ts +51 -0
- package/dist/api/compiler/transformers/syntax-facts.js +254 -0
- package/dist/api/compiler/transformers/tagged-template.d.ts +17 -0
- package/dist/api/compiler/transformers/tagged-template.js +148 -0
- package/dist/api/compiler/transformers/transformer.d.ts +17 -0
- package/dist/api/compiler/transformers/transformer.js +54 -0
- package/dist/api/compiler/transformers/type-eraser.d.ts +21 -0
- package/dist/api/compiler/transformers/type-eraser.js +346 -0
- package/dist/api/compiler/transformers/type-serialization.d.ts +20 -0
- package/dist/api/compiler/transformers/type-serialization.js +347 -0
- package/dist/api/compiler/transformers/using.d.ts +56 -0
- package/dist/api/compiler/transformers/using.js +453 -0
- package/dist/api/compiler/transformers/utilities.d.ts +50 -0
- package/dist/api/compiler/transformers/utilities.js +347 -0
- package/dist/api/compiler/transformers/visitor-base.d.ts +6 -0
- package/dist/api/compiler/transformers/visitor-base.js +817 -0
- package/dist/api/compiler/transformers/visitor-hooks.d.ts +29 -0
- package/dist/api/compiler/transformers/visitor-hooks.js +189 -0
- package/dist/api/compiler/tsconfig.d.ts +177 -0
- package/dist/api/compiler/tsconfig.js +1311 -0
- package/dist/api/compiler/type-printer.d.ts +15 -0
- package/dist/api/compiler/type-printer.js +74 -0
- package/dist/api/compiler/types.d.ts +87 -0
- package/dist/api/compiler/types.js +23 -0
- package/dist/api/compiler/unicode-identifiers.d.ts +2 -0
- package/dist/api/compiler/unicode-identifiers.js +209 -0
- package/dist/api/compiler/unicode-properties.d.ts +8 -0
- package/dist/api/compiler/unicode-properties.js +531 -0
- package/dist/api/compiler/vfs-match.d.ts +24 -0
- package/dist/api/compiler/vfs-match.js +587 -0
- package/dist/api/library/ast.d.ts +3 -2
- package/dist/api/library/ast.generated.d.ts +127 -139
- package/dist/api/library/checker.d.ts +51 -0
- package/dist/api/library/checker.js +318 -0
- package/dist/api/library/diagnostics.d.ts +13 -0
- package/dist/api/library/diagnostics.js +50 -0
- package/dist/api/library/disk.d.ts +13 -0
- package/dist/api/library/disk.js +66 -0
- package/dist/api/library/errors.d.ts +13 -0
- package/dist/api/library/errors.js +24 -0
- package/dist/api/library/host.d.ts +24 -0
- package/dist/api/library/host.js +52 -0
- package/dist/api/library/index.d.ts +5 -1
- package/dist/api/library/index.js +4 -0
- package/dist/api/library/nodes.d.ts +51 -0
- package/dist/api/library/nodes.js +196 -0
- package/dist/api/library/options.d.ts +144 -0
- package/dist/api/library/options.js +308 -0
- package/dist/api/library/parse.d.ts +19 -0
- package/dist/api/library/parse.js +41 -0
- package/dist/api/library/program.d.ts +21 -0
- package/dist/api/library/program.js +234 -0
- package/dist/api/library/types.d.ts +14 -1
- package/package.json +12 -8
- package/src/compiler/ast-utilities.ts +548 -0
- package/src/compiler/ast.ts +12862 -0
- package/src/compiler/astnav.ts +799 -0
- package/src/compiler/binder-utilities.ts +1392 -0
- package/src/compiler/binder.ts +2703 -0
- package/src/compiler/build-info.ts +1197 -0
- package/src/compiler/character-codes.ts +323 -0
- package/src/compiler/checker-calls.ts +2155 -0
- package/src/compiler/checker-classes.ts +706 -0
- package/src/compiler/checker-contextual.ts +1457 -0
- package/src/compiler/checker-declaration-order.ts +438 -0
- package/src/compiler/checker-declarations.ts +1194 -0
- package/src/compiler/checker-declared-types.ts +919 -0
- package/src/compiler/checker-decorators.ts +694 -0
- package/src/compiler/checker-deprecation.ts +359 -0
- package/src/compiler/checker-destructuring.ts +805 -0
- package/src/compiler/checker-elaboration.ts +477 -0
- package/src/compiler/checker-emit-helpers.ts +224 -0
- package/src/compiler/checker-emit-resolver.ts +769 -0
- package/src/compiler/checker-evaluator.ts +243 -0
- package/src/compiler/checker-expressions.ts +1831 -0
- package/src/compiler/checker-features.ts +361 -0
- package/src/compiler/checker-flow.ts +394 -0
- package/src/compiler/checker-functions.ts +1296 -0
- package/src/compiler/checker-generated-code.ts +227 -0
- package/src/compiler/checker-globals.ts +52 -0
- package/src/compiler/checker-grammar.ts +3584 -0
- package/src/compiler/checker-heritage.ts +1233 -0
- package/src/compiler/checker-inference.ts +2576 -0
- package/src/compiler/checker-iteration.ts +1206 -0
- package/src/compiler/checker-javascript.ts +502 -0
- package/src/compiler/checker-jsdoc.ts +360 -0
- package/src/compiler/checker-jsx.ts +1924 -0
- package/src/compiler/checker-literals.ts +61 -0
- package/src/compiler/checker-members.ts +2436 -0
- package/src/compiler/checker-modules.ts +2886 -0
- package/src/compiler/checker-narrowing.ts +3230 -0
- package/src/compiler/checker-object-literals.ts +575 -0
- package/src/compiler/checker-operators.ts +1422 -0
- package/src/compiler/checker-overloads.ts +328 -0
- package/src/compiler/checker-property-access.ts +906 -0
- package/src/compiler/checker-services.ts +1149 -0
- package/src/compiler/checker-signatures.ts +1032 -0
- package/src/compiler/checker-source-file.ts +732 -0
- package/src/compiler/checker-statements.ts +292 -0
- package/src/compiler/checker-super.ts +261 -0
- package/src/compiler/checker-symbol-types.ts +2107 -0
- package/src/compiler/checker-symbols.ts +2150 -0
- package/src/compiler/checker-type-factory.ts +2579 -0
- package/src/compiler/checker-type-nodes.ts +1033 -0
- package/src/compiler/checker-type-operators.ts +2502 -0
- package/src/compiler/checker-types.ts +2340 -0
- package/src/compiler/checker-unused.ts +642 -0
- package/src/compiler/checker-utilities.ts +161 -0
- package/src/compiler/checker.ts +1116 -0
- package/src/compiler/command-line.ts +436 -0
- package/src/compiler/compile-program.ts +439 -0
- package/src/compiler/decoder.ts +1209 -0
- package/src/compiler/diagnostic-locales.ts +86 -0
- package/src/compiler/diagnostic-messages.ts +2349 -0
- package/src/compiler/diagnostics.ts +897 -0
- package/src/compiler/emitter.ts +434 -0
- package/src/compiler/encoder.ts +1945 -0
- package/src/compiler/file-include.ts +673 -0
- package/src/compiler/file-loader.ts +1528 -0
- package/src/compiler/file-system.ts +143 -0
- package/src/compiler/flow.ts +89 -0
- package/src/compiler/help.ts +473 -0
- package/src/compiler/incremental.ts +2784 -0
- package/src/compiler/init.ts +141 -0
- package/src/compiler/instantiation.ts +894 -0
- package/src/compiler/jsdoc.ts +1386 -0
- package/src/compiler/link-tables.ts +98 -0
- package/src/compiler/locale-data.ts +203 -0
- package/src/compiler/locale.ts +307 -0
- package/src/compiler/locales/cs-CZ.ts +5 -0
- package/src/compiler/locales/de-DE.ts +5 -0
- package/src/compiler/locales/es-ES.ts +5 -0
- package/src/compiler/locales/fr-FR.ts +5 -0
- package/src/compiler/locales/it-IT.ts +5 -0
- package/src/compiler/locales/ja-JP.ts +5 -0
- package/src/compiler/locales/ko-KR.ts +5 -0
- package/src/compiler/locales/pl-PL.ts +5 -0
- package/src/compiler/locales/pt-BR.ts +5 -0
- package/src/compiler/locales/ru-RU.ts +5 -0
- package/src/compiler/locales/tr-TR.ts +5 -0
- package/src/compiler/locales/zh-CN.ts +5 -0
- package/src/compiler/locales/zh-TW.ts +5 -0
- package/src/compiler/module-resolution-types.ts +243 -0
- package/src/compiler/module-resolution.ts +2072 -0
- package/src/compiler/module-specifiers.ts +1491 -0
- package/src/compiler/name-resolver.ts +646 -0
- package/src/compiler/node-builder-names.ts +1069 -0
- package/src/compiler/node-builder-pseudo.ts +892 -0
- package/src/compiler/node-builder-reuse.ts +764 -0
- package/src/compiler/node-builder.ts +3425 -0
- package/src/compiler/option-declarations.ts +1560 -0
- package/src/compiler/options.ts +1576 -0
- package/src/compiler/output-paths.ts +334 -0
- package/src/compiler/package-json.ts +1083 -0
- package/src/compiler/parallel-check.ts +1951 -0
- package/src/compiler/parallel-parse.ts +590 -0
- package/src/compiler/parse-thread.ts +140 -0
- package/src/compiler/parser.ts +7716 -0
- package/src/compiler/path.ts +717 -0
- package/src/compiler/printer/async-helpers.ts +183 -0
- package/src/compiler/printer/auto-generate.ts +27 -0
- package/src/compiler/printer/decorator-helpers.ts +218 -0
- package/src/compiler/printer/emit-context.ts +679 -0
- package/src/compiler/printer/emit-flags.ts +64 -0
- package/src/compiler/printer/factory-base.ts +2577 -0
- package/src/compiler/printer/factory.ts +764 -0
- package/src/compiler/printer/helpers.ts +291 -0
- package/src/compiler/printer/name-generator.ts +372 -0
- package/src/compiler/printer/printer.ts +5072 -0
- package/src/compiler/printer/text-writer.ts +183 -0
- package/src/compiler/printer/utilities.ts +884 -0
- package/src/compiler/program-checker.ts +592 -0
- package/src/compiler/program-utilities.ts +435 -0
- package/src/compiler/program.ts +1419 -0
- package/src/compiler/pseudo-bigint.ts +62 -0
- package/src/compiler/regexp-checker.ts +1142 -0
- package/src/compiler/relations.ts +5149 -0
- package/src/compiler/reparser.ts +1566 -0
- package/src/compiler/scanner.ts +2951 -0
- package/src/compiler/show-config.ts +239 -0
- package/src/compiler/side-state.ts +125 -0
- package/src/compiler/sourcemap.ts +366 -0
- package/src/compiler/spelling.ts +122 -0
- package/src/compiler/symbol-accessibility.ts +1071 -0
- package/src/compiler/symbol.ts +439 -0
- package/src/compiler/symlinks.ts +137 -0
- package/src/compiler/syntax-kind.ts +391 -0
- package/src/compiler/thread-entry.ts +191 -0
- package/src/compiler/timeline.ts +53 -0
- package/src/compiler/transformers/alias-references.ts +757 -0
- package/src/compiler/transformers/async-utilities.ts +335 -0
- package/src/compiler/transformers/async.ts +838 -0
- package/src/compiler/transformers/class-fields.ts +2967 -0
- package/src/compiler/transformers/class-utilities.ts +324 -0
- package/src/compiler/transformers/commonjs-module.ts +1621 -0
- package/src/compiler/transformers/const-enum-inliner.ts +50 -0
- package/src/compiler/transformers/declarations-diagnostics.ts +832 -0
- package/src/compiler/transformers/declarations-pseudo.ts +966 -0
- package/src/compiler/transformers/declarations-resolver.ts +249 -0
- package/src/compiler/transformers/declarations-syntactic.ts +1859 -0
- package/src/compiler/transformers/declarations-tracker.ts +269 -0
- package/src/compiler/transformers/declarations.ts +3120 -0
- package/src/compiler/transformers/decorator-metadata.ts +697 -0
- package/src/compiler/transformers/decorator-utilities.ts +283 -0
- package/src/compiler/transformers/destructuring.ts +708 -0
- package/src/compiler/transformers/downlevel.ts +50 -0
- package/src/compiler/transformers/emit-resolver.ts +258 -0
- package/src/compiler/transformers/es-decorators.ts +2682 -0
- package/src/compiler/transformers/exponentiation.ts +80 -0
- package/src/compiler/transformers/external-module-info.ts +412 -0
- package/src/compiler/transformers/for-await.ts +687 -0
- package/src/compiler/transformers/import-elision.ts +152 -0
- package/src/compiler/transformers/jsx-entities.ts +256 -0
- package/src/compiler/transformers/jsx.ts +824 -0
- package/src/compiler/transformers/legacy-decorators.ts +726 -0
- package/src/compiler/transformers/logical-assignment.ts +75 -0
- package/src/compiler/transformers/module-utilities.ts +42 -0
- package/src/compiler/transformers/module.ts +474 -0
- package/src/compiler/transformers/named-evaluation.ts +389 -0
- package/src/compiler/transformers/nullish-coalescing.ts +35 -0
- package/src/compiler/transformers/object-rest-spread.ts +577 -0
- package/src/compiler/transformers/optional-catch.ts +29 -0
- package/src/compiler/transformers/optional-chain.ts +246 -0
- package/src/compiler/transformers/reference-resolver.ts +1201 -0
- package/src/compiler/transformers/runtime-syntax.ts +942 -0
- package/src/compiler/transformers/subtree-facts.ts +245 -0
- package/src/compiler/transformers/syntax-facts.ts +353 -0
- package/src/compiler/transformers/tagged-template.ts +167 -0
- package/src/compiler/transformers/transformer.ts +56 -0
- package/src/compiler/transformers/type-eraser.ts +520 -0
- package/src/compiler/transformers/type-serialization.ts +374 -0
- package/src/compiler/transformers/using.ts +613 -0
- package/src/compiler/transformers/utilities.ts +419 -0
- package/src/compiler/transformers/visitor-base.ts +1601 -0
- package/src/compiler/transformers/visitor-hooks.ts +252 -0
- package/src/compiler/tsc-build.ts +1418 -0
- package/src/compiler/tsc-cli.ts +666 -0
- package/src/compiler/tsc-compile.ts +437 -0
- package/src/compiler/tsc-watch.ts +854 -0
- package/src/compiler/tsconfig.ts +1574 -0
- package/src/compiler/type-printer.ts +110 -0
- package/src/compiler/types.ts +115 -0
- package/src/compiler/unicode-identifiers.ts +212 -0
- package/src/compiler/unicode-properties.ts +537 -0
- package/src/compiler/vfs-match.ts +597 -0
- package/src/compiler/xxh3.ts +650 -0
- package/src/library/ast.generated.ts +141 -167
- package/src/library/ast.ts +4 -1
- package/src/library/checker.ts +384 -0
- package/src/library/diagnostics.ts +72 -0
- package/src/library/disk.ts +73 -0
- package/src/library/errors.ts +26 -0
- package/src/library/host.ts +63 -0
- package/src/library/index.ts +21 -0
- package/src/library/nodes.ts +232 -0
- package/src/library/options.ts +449 -0
- package/src/library/parse.ts +63 -0
- package/src/library/program.ts +293 -0
- package/src/library/types.ts +14 -1
|
@@ -0,0 +1,2072 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module and type reference resolution for `node16`, `nodenext` and `bundler`.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* const resolver = new Resolver(host, options);
|
|
6
|
+
* const traces: MessageWithArgs[] = [];
|
|
7
|
+
* const resolved = resolver.resolveModuleName('pkg', '/app/src/index.ts', ModuleKind.ESNext, undefined, traces);
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
createDiagnostic,
|
|
13
|
+
Diagnostics,
|
|
14
|
+
messageWithArgs,
|
|
15
|
+
type Diagnostic,
|
|
16
|
+
type DiagnosticMessage,
|
|
17
|
+
type MessageWithArgs,
|
|
18
|
+
} from './diagnostics.js';
|
|
19
|
+
import {
|
|
20
|
+
ModuleKind,
|
|
21
|
+
ModuleResolutionHost,
|
|
22
|
+
ModuleResolutionKind,
|
|
23
|
+
comparePatternKeys,
|
|
24
|
+
getConditions,
|
|
25
|
+
getEffectiveTypeRoots,
|
|
26
|
+
inferredTypesContainingFile,
|
|
27
|
+
mangleScopedPackageName,
|
|
28
|
+
moduleResolutionKindName,
|
|
29
|
+
packageIdToString,
|
|
30
|
+
parseNodeModuleFromPath,
|
|
31
|
+
parsePackageName,
|
|
32
|
+
type PackageId,
|
|
33
|
+
type ResolutionMode,
|
|
34
|
+
type ResolvedModule,
|
|
35
|
+
type ResolvedProjectReference,
|
|
36
|
+
type ResolvedTypeReferenceDirective,
|
|
37
|
+
} from './module-resolution-types.js';
|
|
38
|
+
import {
|
|
39
|
+
JsonObjectKind,
|
|
40
|
+
PackageJsonInfoCache,
|
|
41
|
+
isApplicableVersionedTypesKey,
|
|
42
|
+
isFalsyJson,
|
|
43
|
+
parsePackageJson,
|
|
44
|
+
typeScriptVersion,
|
|
45
|
+
withPackageDirectory,
|
|
46
|
+
type Expected,
|
|
47
|
+
type JsonObject,
|
|
48
|
+
type JsonValue,
|
|
49
|
+
type PackageJsonInfo,
|
|
50
|
+
type VersionPaths,
|
|
51
|
+
} from './package-json.js';
|
|
52
|
+
import { getAllowJS, getModuleResolutionKind, getResolveJsonModule, type CompilerOptions } from './options.js';
|
|
53
|
+
import {
|
|
54
|
+
changeExtension,
|
|
55
|
+
combinePaths,
|
|
56
|
+
comparePaths,
|
|
57
|
+
containsPath,
|
|
58
|
+
ensureTrailingDirectorySeparator,
|
|
59
|
+
extensionIsTs,
|
|
60
|
+
fileExtensionIs,
|
|
61
|
+
getBaseFileName,
|
|
62
|
+
getDirectoryPath,
|
|
63
|
+
getNormalizedAbsolutePath,
|
|
64
|
+
getPathComponents,
|
|
65
|
+
getPossibleOriginalInputExtensionForExtension,
|
|
66
|
+
getRelativePathFromDirectory,
|
|
67
|
+
getRootLength,
|
|
68
|
+
hasImplementationTSFileExtension,
|
|
69
|
+
hasTrailingDirectorySeparator,
|
|
70
|
+
isDeclarationFileName,
|
|
71
|
+
isExternalModuleNameRelative,
|
|
72
|
+
isRootedDiskPath,
|
|
73
|
+
normalizePath,
|
|
74
|
+
normalizeSlashes,
|
|
75
|
+
pathIsRelative,
|
|
76
|
+
removeExtension,
|
|
77
|
+
removeFileExtension,
|
|
78
|
+
removeTrailingDirectorySeparator,
|
|
79
|
+
removeTrailingDirectorySeparators,
|
|
80
|
+
supportedTSExtensionsWithJsonFlat,
|
|
81
|
+
tryExtractTSExtension,
|
|
82
|
+
tryGetExtensionFromPath,
|
|
83
|
+
} from './path.js';
|
|
84
|
+
|
|
85
|
+
export * from './module-resolution-types.js';
|
|
86
|
+
|
|
87
|
+
/** File kinds a lookup accepts. */
|
|
88
|
+
const enum Extensions {
|
|
89
|
+
TypeScript = 1,
|
|
90
|
+
JavaScript = 2,
|
|
91
|
+
Declaration = 4,
|
|
92
|
+
Json = 8,
|
|
93
|
+
ImplementationFiles = TypeScript | JavaScript,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const enum Features {
|
|
97
|
+
None = 0,
|
|
98
|
+
Imports = 1,
|
|
99
|
+
SelfName = 2,
|
|
100
|
+
Exports = 4,
|
|
101
|
+
ExportsPatternTrailers = 8,
|
|
102
|
+
/** `#/` keys in `imports`. */
|
|
103
|
+
ImportsPatternRoot = 16,
|
|
104
|
+
Node16Default = Imports | SelfName | Exports | ExportsPatternTrailers,
|
|
105
|
+
NodeNextDefault = Imports | SelfName | Exports | ExportsPatternTrailers | ImportsPatternRoot,
|
|
106
|
+
BundlerDefault = Imports | SelfName | Exports | ExportsPatternTrailers | ImportsPatternRoot,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function extensionsToString(extensions: number): string {
|
|
110
|
+
let result = '';
|
|
111
|
+
if ((extensions & Extensions.TypeScript) !== 0) result = 'TypeScript';
|
|
112
|
+
if ((extensions & Extensions.JavaScript) !== 0) result += result === '' ? 'JavaScript' : ', JavaScript';
|
|
113
|
+
if ((extensions & Extensions.Declaration) !== 0) result += result === '' ? 'Declaration' : ', Declaration';
|
|
114
|
+
if ((extensions & Extensions.Json) !== 0) result += result === '' ? 'JSON' : ', JSON';
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Whether `extension` is one of `extensions`. */
|
|
119
|
+
function extensionIsOk(extensions: number, extension: string): boolean {
|
|
120
|
+
return (
|
|
121
|
+
((extensions & Extensions.JavaScript) !== 0 &&
|
|
122
|
+
(extension === '.js' || extension === '.jsx' || extension === '.mjs' || extension === '.cjs')) ||
|
|
123
|
+
((extensions & Extensions.TypeScript) !== 0 &&
|
|
124
|
+
(extension === '.ts' || extension === '.tsx' || extension === '.mts' || extension === '.cts')) ||
|
|
125
|
+
((extensions & Extensions.Declaration) !== 0 &&
|
|
126
|
+
(extension === '.d.ts' || extension === '.d.mts' || extension === '.d.cts')) ||
|
|
127
|
+
((extensions & Extensions.Json) !== 0 && extension === '.json')
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* A lookup result. `undefined` means "keep searching"; a result with an empty `path` stops the search unresolved.
|
|
133
|
+
*/
|
|
134
|
+
interface Resolved {
|
|
135
|
+
path: string;
|
|
136
|
+
extension: string;
|
|
137
|
+
packageId: PackageId | undefined;
|
|
138
|
+
originalPath: string;
|
|
139
|
+
resolvedUsingTsExtension: boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function resolvedFile(path: string, extension: string, resolvedUsingTsExtension: boolean): Resolved {
|
|
143
|
+
return { path, extension, packageId: undefined, originalPath: '', resolvedUsingTsExtension };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function unresolved(): Resolved {
|
|
147
|
+
return resolvedFile('', '', false);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** A `paths` or `typesVersions` pattern: `text` with an optional `*` at `starIndex`. */
|
|
151
|
+
export interface Pattern {
|
|
152
|
+
readonly text: string;
|
|
153
|
+
readonly starIndex: number;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface ParsedPatterns {
|
|
157
|
+
readonly exact: ReadonlySet<string>;
|
|
158
|
+
readonly patterns: readonly Pattern[];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function parsePatterns(paths: ReadonlyMap<string, readonly string[] | undefined>): ParsedPatterns {
|
|
162
|
+
const exact = new Set<string>();
|
|
163
|
+
const patterns: Pattern[] = [];
|
|
164
|
+
for (const key of paths.keys()) {
|
|
165
|
+
const star = key.indexOf('*');
|
|
166
|
+
if (star === -1) exact.add(key);
|
|
167
|
+
else if (key.indexOf('*', star + 1) === -1) patterns.push({ text: key, starIndex: star });
|
|
168
|
+
}
|
|
169
|
+
return { exact, patterns };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function patternMatches(pattern: Pattern, candidate: string): boolean {
|
|
173
|
+
return (
|
|
174
|
+
candidate.length >= pattern.text.length - 1 &&
|
|
175
|
+
candidate.startsWith(pattern.text.slice(0, pattern.starIndex)) &&
|
|
176
|
+
candidate.endsWith(pattern.text.slice(pattern.starIndex + 1))
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** The exact key equal to `candidate`, else the matching pattern with the longest prefix. */
|
|
181
|
+
export function matchPatternOrExact(parsed: ParsedPatterns, candidate: string): Pattern | undefined {
|
|
182
|
+
if (parsed.exact.has(candidate)) return { text: candidate, starIndex: -1 };
|
|
183
|
+
let best: Pattern | undefined;
|
|
184
|
+
let longestPrefix = -1;
|
|
185
|
+
for (const pattern of parsed.patterns) {
|
|
186
|
+
if (pattern.starIndex > longestPrefix && patternMatches(pattern, candidate)) {
|
|
187
|
+
best = pattern;
|
|
188
|
+
longestPrefix = pattern.starIndex;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return best;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function matchedText(pattern: Pattern, candidate: string): string {
|
|
195
|
+
if (pattern.starIndex === -1) return '';
|
|
196
|
+
return candidate.slice(pattern.starIndex, candidate.length - pattern.text.length + pattern.starIndex + 1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function replaceFirstStar(text: string, replacement: string): string {
|
|
200
|
+
const star = text.indexOf('*');
|
|
201
|
+
return star === -1 ? text : text.slice(0, star) + replacement + text.slice(star + 1);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function replaceAllStars(text: string, replacement: string): string {
|
|
205
|
+
let star = text.indexOf('*');
|
|
206
|
+
if (star === -1) return text;
|
|
207
|
+
let result = '';
|
|
208
|
+
let start = 0;
|
|
209
|
+
while (star !== -1) {
|
|
210
|
+
result += text.slice(start, star) + replacement;
|
|
211
|
+
start = star + 1;
|
|
212
|
+
star = text.indexOf('*', start);
|
|
213
|
+
}
|
|
214
|
+
return result + text.slice(start);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Whether a `/`-separated segment of `path` after `start` is `.`, `..` or `node_modules`. */
|
|
218
|
+
function hasInvalidTargetSegment(path: string, start: number): boolean {
|
|
219
|
+
while (start <= path.length) {
|
|
220
|
+
let end = path.indexOf('/', start);
|
|
221
|
+
if (end === -1) end = path.length;
|
|
222
|
+
const length = end - start;
|
|
223
|
+
if (
|
|
224
|
+
(length === 1 && path.charCodeAt(start) === 0x2e) ||
|
|
225
|
+
(length === 2 && path.startsWith('..', start)) ||
|
|
226
|
+
(length === 12 && path.startsWith('node_modules', start))
|
|
227
|
+
) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
start = end + 1;
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function matchesPatternWithTrailer(target: string, name: string): boolean {
|
|
236
|
+
if (target.endsWith('*')) return false;
|
|
237
|
+
const star = target.indexOf('*');
|
|
238
|
+
if (star === -1) return false;
|
|
239
|
+
return name.startsWith(target.slice(0, star)) && name.endsWith(target.slice(star + 1));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* `.` and `..` at the end of a relative name mean a directory, so they normalize to a trailing `/`.
|
|
244
|
+
*/
|
|
245
|
+
function normalizePathForCJSResolution(containingDirectory: string, moduleName: string): string {
|
|
246
|
+
const combined = combinePaths(containingDirectory, moduleName);
|
|
247
|
+
const rootLength = getRootLength(combined);
|
|
248
|
+
let end = combined.length;
|
|
249
|
+
if (end > rootLength && combined.charCodeAt(end - 1) === 0x2f) end--;
|
|
250
|
+
let isDotSegment = false;
|
|
251
|
+
if (end > rootLength) {
|
|
252
|
+
const start = Math.max(rootLength, combined.lastIndexOf('/', end - 1) + 1);
|
|
253
|
+
const length = end - start;
|
|
254
|
+
isDotSegment = (length === 1 || length === 2) && combined.startsWith(length === 1 ? '.' : '..', start);
|
|
255
|
+
}
|
|
256
|
+
return isDotSegment ? ensureTrailingDirectorySeparator(normalizePath(combined)) : normalizePath(combined);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** How a `paths`/`typesVersions` substitution is loaded. */
|
|
260
|
+
type PathsLoader =
|
|
261
|
+
| { readonly kind: 'relative' }
|
|
262
|
+
| { readonly kind: 'package'; readonly rest: string; readonly packageInfo: PackageJsonInfo | undefined }
|
|
263
|
+
| { readonly kind: 'directory'; readonly packageFile: string; readonly packageInfo: PackageJsonInfo | undefined };
|
|
264
|
+
|
|
265
|
+
const RELATIVE_LOADER: PathsLoader = { kind: 'relative' };
|
|
266
|
+
|
|
267
|
+
const NO_DIAGNOSTICS: readonly Diagnostic[] = [];
|
|
268
|
+
|
|
269
|
+
function unresolvedModule(diagnostics: readonly Diagnostic[]): ResolvedModule {
|
|
270
|
+
return {
|
|
271
|
+
resolvedFileName: '',
|
|
272
|
+
originalPath: '',
|
|
273
|
+
extension: '',
|
|
274
|
+
resolvedUsingTsExtension: false,
|
|
275
|
+
packageId: undefined,
|
|
276
|
+
isExternalLibraryImport: false,
|
|
277
|
+
alternateResult: '',
|
|
278
|
+
resolutionDiagnostics: diagnostics,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// The results each resolver shared with other threads (and so immutable) did not have yet when it was
|
|
283
|
+
// shared, as this thread resolved them.
|
|
284
|
+
const threadModuleCaches = new Map<Resolver, Map<string, ResolvedModule>>();
|
|
285
|
+
const threadTypeReferenceCaches = new Map<Resolver, Map<string, ResolvedTypeReferenceDirective>>();
|
|
286
|
+
|
|
287
|
+
export class Resolver {
|
|
288
|
+
readonly packageJsonInfoCache: PackageJsonInfoCache;
|
|
289
|
+
private readonly moduleCache = new Map<string, ResolvedModule>();
|
|
290
|
+
private readonly typeReferenceCache = new Map<string, ResolvedTypeReferenceDirective>();
|
|
291
|
+
private pathPatterns: ParsedPatterns | undefined;
|
|
292
|
+
private shared = false;
|
|
293
|
+
|
|
294
|
+
constructor(
|
|
295
|
+
readonly host: ModuleResolutionHost,
|
|
296
|
+
readonly options: CompilerOptions,
|
|
297
|
+
/** Global typings cache for automatic type acquisition, or `''`. */
|
|
298
|
+
readonly typingsLocation = '',
|
|
299
|
+
readonly projectName = '',
|
|
300
|
+
packageJsonInfoCache?: PackageJsonInfoCache,
|
|
301
|
+
) {
|
|
302
|
+
this.packageJsonInfoCache =
|
|
303
|
+
packageJsonInfoCache ?? new PackageJsonInfoCache(host.getCurrentDirectory(), host.useCaseSensitiveFileNames());
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Called before the resolver is shared with other threads, which makes it immutable
|
|
308
|
+
* (parallel-check.ts): from then on, each thread caches the results and `package.json` lookups the
|
|
309
|
+
* resolver did not have yet in tables of its own.
|
|
310
|
+
*/
|
|
311
|
+
prepareForSharing(): void {
|
|
312
|
+
this.getPathPatterns();
|
|
313
|
+
this.packageJsonInfoCache.prepareForSharing();
|
|
314
|
+
this.shared = true;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
private cachedModule(key: string): ResolvedModule | undefined {
|
|
318
|
+
const cached = this.moduleCache.get(key);
|
|
319
|
+
if (cached !== undefined || !this.shared) return cached;
|
|
320
|
+
return threadModuleCaches.get(this)?.get(key);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private cacheModule(key: string, resolved: ResolvedModule): void {
|
|
324
|
+
if (this.cachedModule(key) !== undefined) return;
|
|
325
|
+
if (!this.shared) {
|
|
326
|
+
this.moduleCache.set(key, resolved);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
let cache = threadModuleCaches.get(this);
|
|
330
|
+
if (cache === undefined) {
|
|
331
|
+
cache = new Map<string, ResolvedModule>();
|
|
332
|
+
threadModuleCaches.set(this, cache);
|
|
333
|
+
}
|
|
334
|
+
cache.set(key, resolved);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private cachedTypeReference(key: string): ResolvedTypeReferenceDirective | undefined {
|
|
338
|
+
const cached = this.typeReferenceCache.get(key);
|
|
339
|
+
if (cached !== undefined || !this.shared) return cached;
|
|
340
|
+
return threadTypeReferenceCaches.get(this)?.get(key);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
private cacheTypeReference(key: string, resolved: ResolvedTypeReferenceDirective): void {
|
|
344
|
+
if (!this.shared) {
|
|
345
|
+
this.typeReferenceCache.set(key, resolved);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
let cache = threadTypeReferenceCaches.get(this);
|
|
349
|
+
if (cache === undefined) {
|
|
350
|
+
cache = new Map<string, ResolvedTypeReferenceDirective>();
|
|
351
|
+
threadTypeReferenceCaches.set(this, cache);
|
|
352
|
+
}
|
|
353
|
+
cache.set(key, resolved);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** Parsed `paths` of the resolver's own options. */
|
|
357
|
+
getPathPatterns(): ParsedPatterns {
|
|
358
|
+
if (this.pathPatterns === undefined) this.pathPatterns = parsePatterns(this.options.paths ?? new Map());
|
|
359
|
+
return this.pathPatterns;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Resolves an import specifier. With `traceResolution` set, trace messages are appended to `traces` and the
|
|
364
|
+
* result cache is bypassed.
|
|
365
|
+
*/
|
|
366
|
+
resolveModuleName(
|
|
367
|
+
moduleName: string,
|
|
368
|
+
containingFile: string,
|
|
369
|
+
mode: ResolutionMode,
|
|
370
|
+
redirect?: ResolvedProjectReference,
|
|
371
|
+
traces?: MessageWithArgs[],
|
|
372
|
+
): ResolvedModule {
|
|
373
|
+
const containingDirectory = getDirectoryPath(containingFile);
|
|
374
|
+
const tracer = this.options.traceResolution === true ? (traces ?? []) : undefined;
|
|
375
|
+
const cacheKey = mode + '|' + (redirect?.configName ?? '') + '|' + containingDirectory + '|' + moduleName;
|
|
376
|
+
if (tracer === undefined) {
|
|
377
|
+
const cached = this.cachedModule(cacheKey);
|
|
378
|
+
if (cached !== undefined) return cached;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const options = optionsWithRedirect(this.options, redirect);
|
|
382
|
+
tracer?.push(messageWithArgs(Diagnostics.Resolving_module_0_from_1, moduleName, containingFile));
|
|
383
|
+
if (tracer !== undefined) traceRedirect(tracer, redirect);
|
|
384
|
+
|
|
385
|
+
const kind = getModuleResolutionKind(options);
|
|
386
|
+
tracer?.push(
|
|
387
|
+
options.moduleResolution !== kind
|
|
388
|
+
? messageWithArgs(Diagnostics.Module_resolution_kind_is_not_specified_using_0, moduleResolutionKindName(kind))
|
|
389
|
+
: messageWithArgs(
|
|
390
|
+
Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0,
|
|
391
|
+
moduleResolutionKindName(kind),
|
|
392
|
+
),
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
const state = new ResolutionState(this, tracer, moduleName, containingDirectory, false, mode, options);
|
|
396
|
+
const result = state.resolveNodeLike();
|
|
397
|
+
|
|
398
|
+
if (tracer !== undefined) {
|
|
399
|
+
if (result.resolvedFileName === '') {
|
|
400
|
+
tracer.push(messageWithArgs(Diagnostics.Module_name_0_was_not_resolved, moduleName));
|
|
401
|
+
} else if (result.packageId !== undefined) {
|
|
402
|
+
tracer.push(
|
|
403
|
+
messageWithArgs(
|
|
404
|
+
Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2,
|
|
405
|
+
moduleName,
|
|
406
|
+
result.resolvedFileName,
|
|
407
|
+
packageIdToString(result.packageId),
|
|
408
|
+
),
|
|
409
|
+
);
|
|
410
|
+
} else {
|
|
411
|
+
tracer.push(
|
|
412
|
+
messageWithArgs(
|
|
413
|
+
Diagnostics.Module_name_0_was_successfully_resolved_to_1,
|
|
414
|
+
moduleName,
|
|
415
|
+
result.resolvedFileName,
|
|
416
|
+
),
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const final = this.tryResolveFromTypingsLocation(moduleName, containingDirectory, result, tracer);
|
|
422
|
+
this.cacheModule(cacheKey, final);
|
|
423
|
+
return final;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** Resolves a `/// <reference types>` directive or an entry of `types`. */
|
|
427
|
+
resolveTypeReferenceDirective(
|
|
428
|
+
name: string,
|
|
429
|
+
containingFile: string,
|
|
430
|
+
mode: ResolutionMode,
|
|
431
|
+
redirect?: ResolvedProjectReference,
|
|
432
|
+
traces?: MessageWithArgs[],
|
|
433
|
+
): ResolvedTypeReferenceDirective {
|
|
434
|
+
const containingDirectory = getDirectoryPath(containingFile);
|
|
435
|
+
const tracer = this.options.traceResolution === true ? (traces ?? []) : undefined;
|
|
436
|
+
const fromInferredTypes = containingFile.endsWith(inferredTypesContainingFile);
|
|
437
|
+
const cacheKey =
|
|
438
|
+
mode +
|
|
439
|
+
'|' +
|
|
440
|
+
(fromInferredTypes ? '1' : '0') +
|
|
441
|
+
(redirect?.configName ?? '') +
|
|
442
|
+
'|' +
|
|
443
|
+
containingDirectory +
|
|
444
|
+
'|' +
|
|
445
|
+
name;
|
|
446
|
+
if (tracer === undefined) {
|
|
447
|
+
const cached = this.cachedTypeReference(cacheKey);
|
|
448
|
+
if (cached !== undefined) return cached;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const options = optionsWithRedirect(this.options, redirect);
|
|
452
|
+
const typeRoots = getEffectiveTypeRoots(options, this.host.getCurrentDirectory());
|
|
453
|
+
const fromConfig = options.typeRoots !== undefined;
|
|
454
|
+
if (tracer !== undefined) {
|
|
455
|
+
tracer.push(
|
|
456
|
+
messageWithArgs(
|
|
457
|
+
Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2,
|
|
458
|
+
name,
|
|
459
|
+
containingFile,
|
|
460
|
+
typeRoots.join(','),
|
|
461
|
+
),
|
|
462
|
+
);
|
|
463
|
+
traceRedirect(tracer, redirect);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const state = new ResolutionState(this, tracer, name, containingDirectory, true, mode, options);
|
|
467
|
+
const result = state.resolveTypeReferenceDirective(typeRoots, fromConfig, fromInferredTypes);
|
|
468
|
+
|
|
469
|
+
if (tracer !== undefined) {
|
|
470
|
+
if (result.resolvedFileName === '') {
|
|
471
|
+
tracer.push(messageWithArgs(Diagnostics.Type_reference_directive_0_was_not_resolved, name));
|
|
472
|
+
} else if (result.packageId !== undefined) {
|
|
473
|
+
tracer.push(
|
|
474
|
+
messageWithArgs(
|
|
475
|
+
Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3,
|
|
476
|
+
name,
|
|
477
|
+
result.resolvedFileName,
|
|
478
|
+
packageIdToString(result.packageId),
|
|
479
|
+
String(result.primary),
|
|
480
|
+
),
|
|
481
|
+
);
|
|
482
|
+
} else {
|
|
483
|
+
tracer.push(
|
|
484
|
+
messageWithArgs(
|
|
485
|
+
Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2,
|
|
486
|
+
name,
|
|
487
|
+
result.resolvedFileName,
|
|
488
|
+
String(result.primary),
|
|
489
|
+
),
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
this.cacheTypeReference(cacheKey, result);
|
|
495
|
+
return result;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/** Finds the directory of package `moduleName` in the nearest `node_modules`, without loading files. */
|
|
499
|
+
resolvePackageDirectory(
|
|
500
|
+
moduleName: string,
|
|
501
|
+
containingFile: string,
|
|
502
|
+
mode: ResolutionMode,
|
|
503
|
+
redirect?: ResolvedProjectReference,
|
|
504
|
+
): ResolvedModule | undefined {
|
|
505
|
+
const options = optionsWithRedirect(this.options, redirect);
|
|
506
|
+
const state = new ResolutionState(
|
|
507
|
+
this,
|
|
508
|
+
undefined,
|
|
509
|
+
moduleName,
|
|
510
|
+
getDirectoryPath(containingFile),
|
|
511
|
+
false,
|
|
512
|
+
mode,
|
|
513
|
+
options,
|
|
514
|
+
);
|
|
515
|
+
state.resolvePackageDirectoryOnly = true;
|
|
516
|
+
const result = state.loadModuleFromNearestNodeModulesDirectory(false);
|
|
517
|
+
if (result !== undefined && result.path !== '') return state.createResolvedModuleHandlingSymlink(result);
|
|
518
|
+
return undefined;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/** The nearest `package.json` at or above `directory`. */
|
|
522
|
+
getPackageScopeForPath(directory: string): PackageJsonInfo | undefined {
|
|
523
|
+
const state = new ResolutionState(this, undefined, '', directory, false, ModuleKind.None, this.options);
|
|
524
|
+
return state.getPackageScopeForPath(directory);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/** Resolves an `extends` specifier of a tsconfig file. */
|
|
528
|
+
resolveConfig(moduleName: string, containingFile: string): ResolvedModule {
|
|
529
|
+
const state = new ResolutionState(
|
|
530
|
+
this,
|
|
531
|
+
undefined,
|
|
532
|
+
moduleName,
|
|
533
|
+
getDirectoryPath(containingFile),
|
|
534
|
+
false,
|
|
535
|
+
ModuleKind.CommonJS,
|
|
536
|
+
this.options,
|
|
537
|
+
);
|
|
538
|
+
state.isConfigLookup = true;
|
|
539
|
+
state.extensions = Extensions.Json;
|
|
540
|
+
return state.resolveNodeLike();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
private tryResolveFromTypingsLocation(
|
|
544
|
+
moduleName: string,
|
|
545
|
+
containingDirectory: string,
|
|
546
|
+
original: ResolvedModule,
|
|
547
|
+
tracer: MessageWithArgs[] | undefined,
|
|
548
|
+
): ResolvedModule {
|
|
549
|
+
if (
|
|
550
|
+
this.typingsLocation === '' ||
|
|
551
|
+
isExternalModuleNameRelative(moduleName) ||
|
|
552
|
+
(original.resolvedFileName !== '' && supportedTSExtensionsWithJsonFlat.includes(original.extension))
|
|
553
|
+
) {
|
|
554
|
+
return original;
|
|
555
|
+
}
|
|
556
|
+
const state = new ResolutionState(
|
|
557
|
+
this,
|
|
558
|
+
tracer,
|
|
559
|
+
moduleName,
|
|
560
|
+
containingDirectory,
|
|
561
|
+
false,
|
|
562
|
+
ModuleKind.None,
|
|
563
|
+
this.options,
|
|
564
|
+
);
|
|
565
|
+
tracer?.push(
|
|
566
|
+
messageWithArgs(
|
|
567
|
+
Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2,
|
|
568
|
+
this.projectName,
|
|
569
|
+
moduleName,
|
|
570
|
+
this.typingsLocation,
|
|
571
|
+
),
|
|
572
|
+
);
|
|
573
|
+
const global = state.loadModuleFromImmediateNodeModulesDirectory(
|
|
574
|
+
Extensions.Declaration,
|
|
575
|
+
this.typingsLocation,
|
|
576
|
+
false,
|
|
577
|
+
);
|
|
578
|
+
if (global === undefined) return original;
|
|
579
|
+
const result = state.createResolvedModule(global, true);
|
|
580
|
+
result.resolutionDiagnostics = original.resolutionDiagnostics.concat(result.resolutionDiagnostics);
|
|
581
|
+
return result;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function optionsWithRedirect(
|
|
586
|
+
options: CompilerOptions,
|
|
587
|
+
redirect: ResolvedProjectReference | undefined,
|
|
588
|
+
): CompilerOptions {
|
|
589
|
+
return redirect?.options ?? options;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function traceRedirect(tracer: MessageWithArgs[], redirect: ResolvedProjectReference | undefined): void {
|
|
593
|
+
if (redirect !== undefined && redirect.options !== undefined) {
|
|
594
|
+
tracer.push(
|
|
595
|
+
messageWithArgs(Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirect.configName),
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/** Resolves an `extends` specifier of a tsconfig file with `nodenext` rules. */
|
|
601
|
+
export function resolveConfig(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModule {
|
|
602
|
+
return new Resolver(host, { moduleResolution: ModuleResolutionKind.NodeNext }).resolveConfig(
|
|
603
|
+
moduleName,
|
|
604
|
+
containingFile,
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/** The `types` entries to include automatically, expanding `*` to every package in the type roots. */
|
|
609
|
+
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] {
|
|
610
|
+
const types = options.types ?? [];
|
|
611
|
+
if (!types.includes('*')) return types.slice();
|
|
612
|
+
const wildcardMatches: string[] = [];
|
|
613
|
+
for (const root of getEffectiveTypeRoots(options, host.getCurrentDirectory())) {
|
|
614
|
+
if (!host.directoryExists(root)) continue;
|
|
615
|
+
for (const directory of host.getDirectories(root)) {
|
|
616
|
+
const normalized = normalizePath(directory);
|
|
617
|
+
const packageJsonPath = combinePaths(combinePaths(root, normalized), 'package.json');
|
|
618
|
+
// types-publisher writes `"typings": null` for packages that ship their own types.
|
|
619
|
+
let isNotNeeded = false;
|
|
620
|
+
if (host.fileExists(packageJsonPath)) {
|
|
621
|
+
isNotNeeded = parsePackageJson(host.readFile(packageJsonPath) ?? '').typings.isNull;
|
|
622
|
+
}
|
|
623
|
+
if (isNotNeeded) continue;
|
|
624
|
+
const base = getBaseFileName(normalized);
|
|
625
|
+
if (!base.startsWith('.')) wildcardMatches.push(base);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
const result: string[] = [];
|
|
629
|
+
const seen = new Set<string>();
|
|
630
|
+
for (const type of types) {
|
|
631
|
+
if (type === '*') {
|
|
632
|
+
for (const match of wildcardMatches) {
|
|
633
|
+
if (!seen.has(match)) {
|
|
634
|
+
seen.add(match);
|
|
635
|
+
result.push(match);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
} else if (!seen.has(type)) {
|
|
639
|
+
seen.add(type);
|
|
640
|
+
result.push(type);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return result;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/** One resolution request: the name being resolved plus the knobs that change along the way. */
|
|
647
|
+
class ResolutionState {
|
|
648
|
+
readonly host: ModuleResolutionHost;
|
|
649
|
+
isConfigLookup = false;
|
|
650
|
+
features: number = Features.None;
|
|
651
|
+
esmMode = false;
|
|
652
|
+
conditions: readonly string[] = [];
|
|
653
|
+
extensions: number;
|
|
654
|
+
resolvePackageDirectoryOnly = false;
|
|
655
|
+
/**
|
|
656
|
+
* Set while the candidate's extension comes from configuration (package.json, `paths`, wildcard
|
|
657
|
+
* substitutions) rather than the specifier, which suppresses `resolvedUsingTsExtension`.
|
|
658
|
+
*/
|
|
659
|
+
candidateEndingIsFromConfig = false;
|
|
660
|
+
resolvedPackageDirectory = false;
|
|
661
|
+
diagnostics: Diagnostic[] = [];
|
|
662
|
+
private pathPatterns: ParsedPatterns | undefined;
|
|
663
|
+
|
|
664
|
+
constructor(
|
|
665
|
+
readonly resolver: Resolver,
|
|
666
|
+
readonly traces: MessageWithArgs[] | undefined,
|
|
667
|
+
public name: string,
|
|
668
|
+
public containingDirectory: string,
|
|
669
|
+
isTypeReferenceDirective: boolean,
|
|
670
|
+
mode: ResolutionMode,
|
|
671
|
+
readonly options: CompilerOptions,
|
|
672
|
+
) {
|
|
673
|
+
this.host = resolver.host;
|
|
674
|
+
if (isTypeReferenceDirective) this.extensions = Extensions.Declaration;
|
|
675
|
+
else if (options.noDtsResolution === true) this.extensions = Extensions.ImplementationFiles;
|
|
676
|
+
else this.extensions = Extensions.TypeScript | Extensions.JavaScript | Extensions.Declaration;
|
|
677
|
+
if (!isTypeReferenceDirective && getResolveJsonModule(options)) this.extensions |= Extensions.Json;
|
|
678
|
+
|
|
679
|
+
switch (getModuleResolutionKind(options)) {
|
|
680
|
+
case ModuleResolutionKind.Node16:
|
|
681
|
+
this.features = Features.Node16Default;
|
|
682
|
+
this.esmMode = mode === ModuleKind.ESNext;
|
|
683
|
+
this.conditions = getConditions(options, mode);
|
|
684
|
+
break;
|
|
685
|
+
case ModuleResolutionKind.NodeNext:
|
|
686
|
+
this.features = Features.NodeNextDefault;
|
|
687
|
+
this.esmMode = mode === ModuleKind.ESNext;
|
|
688
|
+
this.conditions = getConditions(options, mode);
|
|
689
|
+
break;
|
|
690
|
+
case ModuleResolutionKind.Bundler:
|
|
691
|
+
this.features = bundlerFeatures(options);
|
|
692
|
+
this.conditions = getConditions(options, mode);
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
private trace(message: DiagnosticMessage, ...args: string[]): void {
|
|
698
|
+
this.traces?.push({ message, args });
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
//// Type reference directives
|
|
702
|
+
|
|
703
|
+
resolveTypeReferenceDirective(
|
|
704
|
+
typeRoots: readonly string[],
|
|
705
|
+
fromConfig: boolean,
|
|
706
|
+
fromInferredTypes: boolean,
|
|
707
|
+
): ResolvedTypeReferenceDirective {
|
|
708
|
+
const traces = this.traces;
|
|
709
|
+
if (typeRoots.length > 0) {
|
|
710
|
+
if (traces !== undefined) this.trace(Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(', '));
|
|
711
|
+
for (const typeRoot of typeRoots) {
|
|
712
|
+
const candidate = this.getCandidateFromTypeRoot(typeRoot);
|
|
713
|
+
if (!this.host.directoryExists(typeRoot)) {
|
|
714
|
+
if (traces !== undefined)
|
|
715
|
+
this.trace(Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, typeRoot);
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
718
|
+
if (fromConfig) {
|
|
719
|
+
// Configured type roots resolve as files or directories, like modules.
|
|
720
|
+
const fromFile = this.loadModuleFromFile(Extensions.Declaration, candidate);
|
|
721
|
+
if (fromFile !== undefined) {
|
|
722
|
+
this.setPackageIdFromNodeModulesPath(fromFile);
|
|
723
|
+
return this.createResolvedTypeReferenceDirective(fromFile, true);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
const fromDirectory = this.loadNodeModuleFromDirectory(Extensions.Declaration, candidate, true);
|
|
727
|
+
if (fromDirectory !== undefined) return this.createResolvedTypeReferenceDirective(fromDirectory, true);
|
|
728
|
+
}
|
|
729
|
+
} else if (traces !== undefined) {
|
|
730
|
+
this.trace(Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
let resolved: Resolved | undefined;
|
|
734
|
+
if (!fromConfig || !fromInferredTypes) {
|
|
735
|
+
if (traces !== undefined)
|
|
736
|
+
this.trace(Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, this.containingDirectory);
|
|
737
|
+
if (!isExternalModuleNameRelative(this.name)) {
|
|
738
|
+
resolved = this.loadModuleFromNearestNodeModulesDirectory(false);
|
|
739
|
+
} else {
|
|
740
|
+
const candidate = normalizePathForCJSResolution(this.containingDirectory, this.name);
|
|
741
|
+
resolved = this.nodeLoadModuleByRelativeName(Extensions.Declaration, candidate, true);
|
|
742
|
+
}
|
|
743
|
+
} else if (traces !== undefined) {
|
|
744
|
+
this.trace(
|
|
745
|
+
Diagnostics.Resolving_type_reference_directive_for_program_that_specifies_custom_typeRoots_skipping_lookup_in_node_modules_folder,
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
return this.createResolvedTypeReferenceDirective(resolved, false);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
private setPackageIdFromNodeModulesPath(resolved: Resolved): void {
|
|
752
|
+
const packageDirectory = parseNodeModuleFromPath(resolved.path, false);
|
|
753
|
+
if (packageDirectory !== '') {
|
|
754
|
+
resolved.packageId = this.getPackageId(resolved.path, this.getPackageJsonInfo(packageDirectory));
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
private getCandidateFromTypeRoot(typeRoot: string): string {
|
|
759
|
+
const name =
|
|
760
|
+
typeRoot.endsWith('/node_modules/@types') || typeRoot.endsWith('/node_modules/@types/')
|
|
761
|
+
? this.mangleScopedPackageName(this.name)
|
|
762
|
+
: this.name;
|
|
763
|
+
return combinePaths(typeRoot, name);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
private mangleScopedPackageName(name: string): string {
|
|
767
|
+
const mangled = mangleScopedPackageName(name);
|
|
768
|
+
if (this.traces !== undefined && mangled !== name)
|
|
769
|
+
this.trace(Diagnostics.Scoped_package_detected_looking_in_0, mangled);
|
|
770
|
+
return mangled;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/** Falls back to configured `typeRoots` for declaration lookups of bare names. */
|
|
774
|
+
private resolveFromTypeRoot(): Resolved | undefined {
|
|
775
|
+
const typeRoots = this.options.typeRoots;
|
|
776
|
+
if (typeRoots === undefined) return undefined;
|
|
777
|
+
for (const typeRoot of typeRoots) {
|
|
778
|
+
const candidate = this.getCandidateFromTypeRoot(typeRoot);
|
|
779
|
+
if (!this.host.directoryExists(typeRoot)) {
|
|
780
|
+
if (this.traces !== undefined)
|
|
781
|
+
this.trace(Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, typeRoot);
|
|
782
|
+
continue;
|
|
783
|
+
}
|
|
784
|
+
const fromFile = this.loadModuleFromFile(Extensions.Declaration, candidate);
|
|
785
|
+
if (fromFile !== undefined) {
|
|
786
|
+
this.setPackageIdFromNodeModulesPath(fromFile);
|
|
787
|
+
return fromFile;
|
|
788
|
+
}
|
|
789
|
+
const fromDirectory = this.loadNodeModuleFromDirectory(Extensions.Declaration, candidate, true);
|
|
790
|
+
if (fromDirectory !== undefined) return fromDirectory;
|
|
791
|
+
}
|
|
792
|
+
return undefined;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
getPackageScopeForPath(directory: string): PackageJsonInfo | undefined {
|
|
796
|
+
const stop = this.resolver.typingsLocation;
|
|
797
|
+
for (;;) {
|
|
798
|
+
const result = this.getPackageJsonInfo(directory);
|
|
799
|
+
if (result !== undefined || directory === stop) return result;
|
|
800
|
+
const parent = getDirectoryPath(directory);
|
|
801
|
+
if (parent === directory) return undefined;
|
|
802
|
+
directory = parent;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
//// Module names
|
|
807
|
+
|
|
808
|
+
resolveNodeLike(): ResolvedModule {
|
|
809
|
+
if (this.traces !== undefined) {
|
|
810
|
+
const conditions = this.conditions.map((c) => "'" + c + "'").join(', ');
|
|
811
|
+
this.trace(Diagnostics.Resolving_in_0_mode_with_conditions_1, this.esmMode ? 'ESM' : 'CJS', conditions);
|
|
812
|
+
}
|
|
813
|
+
const result = this.resolveNodeLikeWorker();
|
|
814
|
+
if (
|
|
815
|
+
this.resolvedPackageDirectory &&
|
|
816
|
+
!this.isConfigLookup &&
|
|
817
|
+
(this.features & Features.Exports) !== 0 &&
|
|
818
|
+
(this.extensions & (Extensions.TypeScript | Extensions.Declaration)) !== 0 &&
|
|
819
|
+
!isExternalModuleNameRelative(this.name) &&
|
|
820
|
+
result.resolvedFileName !== '' &&
|
|
821
|
+
result.isExternalLibraryImport &&
|
|
822
|
+
!extensionIsOk(Extensions.TypeScript | Extensions.Declaration, result.extension) &&
|
|
823
|
+
this.conditions.includes('import')
|
|
824
|
+
) {
|
|
825
|
+
// Find out whether the package would resolve to types without `exports`, to suggest a fix.
|
|
826
|
+
if (this.traces !== undefined) {
|
|
827
|
+
this.trace(
|
|
828
|
+
Diagnostics.Resolution_of_non_relative_name_failed_trying_with_modern_Node_resolution_features_disabled_to_see_if_npm_library_needs_configuration_update,
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
this.features &= ~Features.Exports;
|
|
832
|
+
this.extensions &= Extensions.TypeScript | Extensions.Declaration;
|
|
833
|
+
const diagnosticsCount = this.diagnostics.length;
|
|
834
|
+
const alternate = this.resolveNodeLikeWorker();
|
|
835
|
+
if (alternate.resolvedFileName !== '' && alternate.isExternalLibraryImport) {
|
|
836
|
+
result.alternateResult = alternate.resolvedFileName;
|
|
837
|
+
}
|
|
838
|
+
// Results share the array, so truncate a copy.
|
|
839
|
+
if (this.diagnostics.length !== diagnosticsCount) this.diagnostics = this.diagnostics.slice(0, diagnosticsCount);
|
|
840
|
+
}
|
|
841
|
+
return result;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
private resolveNodeLikeWorker(): ResolvedModule {
|
|
845
|
+
const fromSettings = this.tryLoadModuleUsingOptionalResolutionSettings();
|
|
846
|
+
if (fromSettings !== undefined) return this.createResolvedModuleHandlingSymlink(fromSettings);
|
|
847
|
+
|
|
848
|
+
if (isExternalModuleNameRelative(this.name)) {
|
|
849
|
+
const candidate = normalizePathForCJSResolution(this.containingDirectory, this.name);
|
|
850
|
+
const resolved = this.nodeLoadModuleByRelativeName(this.extensions, candidate, true);
|
|
851
|
+
return this.createResolvedModule(resolved, resolved !== undefined && resolved.path.includes('/node_modules/'));
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if ((this.features & Features.Imports) !== 0 && this.name.startsWith('#')) {
|
|
855
|
+
const resolved = this.loadModuleFromImports();
|
|
856
|
+
if (resolved !== undefined) return this.createResolvedModuleHandlingSymlink(resolved);
|
|
857
|
+
}
|
|
858
|
+
if ((this.features & Features.SelfName) !== 0) {
|
|
859
|
+
const resolved = this.loadModuleFromSelfNameReference();
|
|
860
|
+
if (resolved !== undefined) return this.createResolvedModuleHandlingSymlink(resolved);
|
|
861
|
+
}
|
|
862
|
+
if (this.name.includes(':')) {
|
|
863
|
+
if (this.traces !== undefined) {
|
|
864
|
+
this.trace(
|
|
865
|
+
Diagnostics.Skipping_module_0_that_looks_like_an_absolute_URI_target_file_types_Colon_1,
|
|
866
|
+
this.name,
|
|
867
|
+
extensionsToString(this.extensions),
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
return this.createResolvedModule(undefined, false);
|
|
871
|
+
}
|
|
872
|
+
if (this.traces !== undefined) {
|
|
873
|
+
this.trace(
|
|
874
|
+
Diagnostics.Loading_module_0_from_node_modules_folder_target_file_types_Colon_1,
|
|
875
|
+
this.name,
|
|
876
|
+
extensionsToString(this.extensions),
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
const fromNodeModules = this.loadModuleFromNearestNodeModulesDirectory(false);
|
|
880
|
+
if (fromNodeModules !== undefined) return this.createResolvedModuleHandlingSymlink(fromNodeModules);
|
|
881
|
+
if ((this.extensions & Extensions.Declaration) !== 0) {
|
|
882
|
+
const fromTypeRoot = this.resolveFromTypeRoot();
|
|
883
|
+
if (fromTypeRoot !== undefined) return this.createResolvedModuleHandlingSymlink(fromTypeRoot);
|
|
884
|
+
}
|
|
885
|
+
return this.createResolvedModule(undefined, false);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
private loadModuleFromSelfNameReference(): Resolved | undefined {
|
|
889
|
+
const directory = getNormalizedAbsolutePath(this.containingDirectory, this.host.getCurrentDirectory());
|
|
890
|
+
const scope = this.getPackageScopeForPath(directory);
|
|
891
|
+
const contents = scope?.contents;
|
|
892
|
+
if (scope === undefined || contents === undefined || isFalsyJson(contents.exports)) return undefined;
|
|
893
|
+
const name = contents.name.value;
|
|
894
|
+
if (name === undefined) return undefined;
|
|
895
|
+
// Cheap rejection before the component-wise comparison.
|
|
896
|
+
if (
|
|
897
|
+
!this.name.includes('\\') &&
|
|
898
|
+
!name.includes('\\') &&
|
|
899
|
+
!this.name.startsWith(removeTrailingDirectorySeparators(name))
|
|
900
|
+
) {
|
|
901
|
+
return undefined;
|
|
902
|
+
}
|
|
903
|
+
const parts = getPathComponents(this.name);
|
|
904
|
+
const nameParts = getPathComponents(name);
|
|
905
|
+
if (parts.length < nameParts.length) return undefined;
|
|
906
|
+
for (let i = 0; i < nameParts.length; i++) if (parts[i] !== nameParts[i]) return undefined;
|
|
907
|
+
let subpath = '.';
|
|
908
|
+
for (let i = nameParts.length; i < parts.length; i++) subpath = combinePaths(subpath, parts[i]);
|
|
909
|
+
// Two passes keep @types packages higher in the tree ahead of untyped implementations, as in
|
|
910
|
+
// node_modules lookups. With allowJs, one pass lets self-names map back to input JS files.
|
|
911
|
+
if (getAllowJS(this.options) && !this.containingDirectory.includes('/node_modules/')) {
|
|
912
|
+
return this.loadModuleFromExports(scope, this.extensions, subpath);
|
|
913
|
+
}
|
|
914
|
+
const priority = this.extensions & (Extensions.TypeScript | Extensions.Declaration);
|
|
915
|
+
const secondary = this.extensions & ~(Extensions.TypeScript | Extensions.Declaration);
|
|
916
|
+
return (
|
|
917
|
+
this.loadModuleFromExports(scope, priority, subpath) ?? this.loadModuleFromExports(scope, secondary, subpath)
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
private loadModuleFromImports(): Resolved | undefined {
|
|
922
|
+
if (this.name === '#' || (this.name.startsWith('#/') && (this.features & Features.ImportsPatternRoot) === 0)) {
|
|
923
|
+
if (this.traces !== undefined)
|
|
924
|
+
this.trace(Diagnostics.Invalid_import_specifier_0_has_no_possible_resolutions, this.name);
|
|
925
|
+
return undefined;
|
|
926
|
+
}
|
|
927
|
+
const directory = getNormalizedAbsolutePath(this.containingDirectory, this.host.getCurrentDirectory());
|
|
928
|
+
const scope = this.getPackageScopeForPath(directory);
|
|
929
|
+
const contents = scope?.contents;
|
|
930
|
+
if (scope === undefined || contents === undefined) {
|
|
931
|
+
if (this.traces !== undefined) {
|
|
932
|
+
this.trace(Diagnostics.Directory_0_has_no_containing_package_json_scope_Imports_will_not_resolve, directory);
|
|
933
|
+
}
|
|
934
|
+
return undefined;
|
|
935
|
+
}
|
|
936
|
+
const imports = contents.imports;
|
|
937
|
+
if (imports === undefined || imports.type !== 'object') {
|
|
938
|
+
if (this.traces !== undefined)
|
|
939
|
+
this.trace(Diagnostics.X_package_json_scope_0_has_no_imports_defined, scope.packageDirectory);
|
|
940
|
+
return undefined;
|
|
941
|
+
}
|
|
942
|
+
const result = this.loadModuleFromExportsOrImports(this.extensions, this.name, imports, scope, true);
|
|
943
|
+
if (result !== undefined) return result;
|
|
944
|
+
if (this.traces !== undefined) {
|
|
945
|
+
this.trace(
|
|
946
|
+
Diagnostics.Import_specifier_0_does_not_exist_in_package_json_scope_at_path_1,
|
|
947
|
+
this.name,
|
|
948
|
+
scope.packageDirectory,
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
return undefined;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
private loadModuleFromExports(scope: PackageJsonInfo, extensions: number, subpath: string): Resolved | undefined {
|
|
955
|
+
const exports = scope.contents?.exports;
|
|
956
|
+
if (exports === undefined || isFalsyJson(exports)) return undefined;
|
|
957
|
+
if (subpath === '.') {
|
|
958
|
+
let mainExport: JsonValue | undefined;
|
|
959
|
+
if (exports.type === 'string' || exports.type === 'array') mainExport = exports;
|
|
960
|
+
else if (exports.type === 'object') {
|
|
961
|
+
mainExport = exports.kind === JsonObjectKind.Conditions ? exports : exports.entries.get('.');
|
|
962
|
+
}
|
|
963
|
+
if (mainExport !== undefined) {
|
|
964
|
+
return this.loadModuleFromTargetExportOrImport(extensions, subpath, scope, false, mainExport, '', false, '.');
|
|
965
|
+
}
|
|
966
|
+
} else if (exports.type === 'object' && exports.kind === JsonObjectKind.Subpaths) {
|
|
967
|
+
const result = this.loadModuleFromExportsOrImports(extensions, subpath, exports, scope, false);
|
|
968
|
+
if (result !== undefined) return result;
|
|
969
|
+
}
|
|
970
|
+
if (this.traces !== undefined) {
|
|
971
|
+
this.trace(
|
|
972
|
+
Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1,
|
|
973
|
+
subpath,
|
|
974
|
+
scope.packageDirectory,
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
return undefined;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
private loadModuleFromExportsOrImports(
|
|
981
|
+
extensions: number,
|
|
982
|
+
moduleName: string,
|
|
983
|
+
lookupTable: JsonObject,
|
|
984
|
+
scope: PackageJsonInfo,
|
|
985
|
+
isImports: boolean,
|
|
986
|
+
): Resolved | undefined {
|
|
987
|
+
const entries = lookupTable.entries;
|
|
988
|
+
if (!moduleName.endsWith('/') && !moduleName.includes('*')) {
|
|
989
|
+
const target = entries.get(moduleName);
|
|
990
|
+
if (target !== undefined) {
|
|
991
|
+
return this.loadModuleFromTargetExportOrImport(
|
|
992
|
+
extensions,
|
|
993
|
+
moduleName,
|
|
994
|
+
scope,
|
|
995
|
+
isImports,
|
|
996
|
+
target,
|
|
997
|
+
'',
|
|
998
|
+
false,
|
|
999
|
+
moduleName,
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
const expandingKeys: string[] = [];
|
|
1004
|
+
for (const key of entries.keys()) {
|
|
1005
|
+
const star = key.indexOf('*');
|
|
1006
|
+
if ((star !== -1 && key.indexOf('*', star + 1) === -1) || key.endsWith('/')) expandingKeys.push(key);
|
|
1007
|
+
}
|
|
1008
|
+
expandingKeys.sort(comparePatternKeys);
|
|
1009
|
+
for (const key of expandingKeys) {
|
|
1010
|
+
const target = entries.get(key);
|
|
1011
|
+
if (target === undefined) continue;
|
|
1012
|
+
if ((this.features & Features.ExportsPatternTrailers) !== 0 && matchesPatternWithTrailer(key, moduleName)) {
|
|
1013
|
+
const star = key.indexOf('*');
|
|
1014
|
+
const subpath = moduleName.slice(star, moduleName.length - (key.length - 1 - star));
|
|
1015
|
+
return this.loadModuleFromTargetExportOrImport(
|
|
1016
|
+
extensions,
|
|
1017
|
+
moduleName,
|
|
1018
|
+
scope,
|
|
1019
|
+
isImports,
|
|
1020
|
+
target,
|
|
1021
|
+
subpath,
|
|
1022
|
+
true,
|
|
1023
|
+
key,
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
if (key.endsWith('*') && moduleName.startsWith(key.slice(0, -1))) {
|
|
1027
|
+
const subpath = moduleName.slice(key.length - 1);
|
|
1028
|
+
return this.loadModuleFromTargetExportOrImport(
|
|
1029
|
+
extensions,
|
|
1030
|
+
moduleName,
|
|
1031
|
+
scope,
|
|
1032
|
+
isImports,
|
|
1033
|
+
target,
|
|
1034
|
+
subpath,
|
|
1035
|
+
true,
|
|
1036
|
+
key,
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1039
|
+
if (moduleName.startsWith(key)) {
|
|
1040
|
+
const subpath = moduleName.slice(key.length);
|
|
1041
|
+
return this.loadModuleFromTargetExportOrImport(
|
|
1042
|
+
extensions,
|
|
1043
|
+
moduleName,
|
|
1044
|
+
scope,
|
|
1045
|
+
isImports,
|
|
1046
|
+
target,
|
|
1047
|
+
subpath,
|
|
1048
|
+
false,
|
|
1049
|
+
key,
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return undefined;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
private invalidTarget(scope: PackageJsonInfo, moduleName: string): undefined {
|
|
1057
|
+
if (this.traces !== undefined) {
|
|
1058
|
+
this.trace(
|
|
1059
|
+
Diagnostics.X_package_json_scope_0_has_invalid_type_for_target_of_specifier_1,
|
|
1060
|
+
scope.packageDirectory,
|
|
1061
|
+
moduleName,
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
return undefined;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
private loadModuleFromTargetExportOrImport(
|
|
1068
|
+
extensions: number,
|
|
1069
|
+
moduleName: string,
|
|
1070
|
+
scope: PackageJsonInfo,
|
|
1071
|
+
isImports: boolean,
|
|
1072
|
+
target: JsonValue,
|
|
1073
|
+
subpath: string,
|
|
1074
|
+
isPattern: boolean,
|
|
1075
|
+
key: string,
|
|
1076
|
+
): Resolved | undefined {
|
|
1077
|
+
const traces = this.traces;
|
|
1078
|
+
switch (target.type) {
|
|
1079
|
+
case 'string': {
|
|
1080
|
+
const targetString = target.value;
|
|
1081
|
+
const normalizedTarget = normalizeSlashes(targetString);
|
|
1082
|
+
if (!isPattern && subpath.length > 0 && !targetString.endsWith('/'))
|
|
1083
|
+
return this.invalidTarget(scope, moduleName);
|
|
1084
|
+
if (!targetString.startsWith('./')) {
|
|
1085
|
+
if (
|
|
1086
|
+
isImports &&
|
|
1087
|
+
!targetString.startsWith('../') &&
|
|
1088
|
+
!targetString.startsWith('/') &&
|
|
1089
|
+
!isRootedDiskPath(targetString)
|
|
1090
|
+
) {
|
|
1091
|
+
return this.resolveImportsTargetAsModule(targetString, subpath, isPattern, scope, key);
|
|
1092
|
+
}
|
|
1093
|
+
return this.invalidTarget(scope, moduleName);
|
|
1094
|
+
}
|
|
1095
|
+
if (hasInvalidTargetSegment(normalizedTarget, 2)) return this.invalidTarget(scope, moduleName);
|
|
1096
|
+
const resolvedTarget = combinePaths(scope.packageDirectory, targetString);
|
|
1097
|
+
const normalizedSubpath = normalizeSlashes(subpath);
|
|
1098
|
+
if (hasInvalidTargetSegment(normalizedSubpath, getRootLength(normalizedSubpath))) {
|
|
1099
|
+
return this.invalidTarget(scope, moduleName);
|
|
1100
|
+
}
|
|
1101
|
+
if (traces !== undefined) {
|
|
1102
|
+
this.trace(
|
|
1103
|
+
Diagnostics.Using_0_subpath_1_with_target_2,
|
|
1104
|
+
isImports ? 'imports' : 'exports',
|
|
1105
|
+
key,
|
|
1106
|
+
isPattern ? replaceAllStars(targetString, subpath) : targetString + subpath,
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
const finalPath = getNormalizedAbsolutePath(
|
|
1110
|
+
isPattern ? replaceAllStars(resolvedTarget, subpath) : resolvedTarget + subpath,
|
|
1111
|
+
this.host.getCurrentDirectory(),
|
|
1112
|
+
);
|
|
1113
|
+
const inputLink = this.tryLoadInputFileForPath(
|
|
1114
|
+
finalPath,
|
|
1115
|
+
subpath,
|
|
1116
|
+
combinePaths(scope.packageDirectory, 'package.json'),
|
|
1117
|
+
isImports,
|
|
1118
|
+
);
|
|
1119
|
+
if (inputLink !== undefined) {
|
|
1120
|
+
inputLink.packageId = this.getPackageId(inputLink.path, scope);
|
|
1121
|
+
return inputLink;
|
|
1122
|
+
}
|
|
1123
|
+
const result = this.loadFileNameFromPackageJsonField(extensions, finalPath, targetString);
|
|
1124
|
+
if (result !== undefined) {
|
|
1125
|
+
result.packageId = this.getPackageId(result.path, scope);
|
|
1126
|
+
return result;
|
|
1127
|
+
}
|
|
1128
|
+
return undefined;
|
|
1129
|
+
}
|
|
1130
|
+
case 'object': {
|
|
1131
|
+
if (traces !== undefined) this.trace(Diagnostics.Entering_conditional_exports);
|
|
1132
|
+
for (const [condition, subTarget] of target.entries) {
|
|
1133
|
+
if (!this.conditionMatches(condition)) {
|
|
1134
|
+
if (traces !== undefined) this.trace(Diagnostics.Saw_non_matching_condition_0, condition);
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
if (traces !== undefined)
|
|
1138
|
+
this.trace(Diagnostics.Matched_0_condition_1, isImports ? 'imports' : 'exports', condition);
|
|
1139
|
+
const result = this.loadModuleFromTargetExportOrImport(
|
|
1140
|
+
extensions,
|
|
1141
|
+
moduleName,
|
|
1142
|
+
scope,
|
|
1143
|
+
isImports,
|
|
1144
|
+
subTarget,
|
|
1145
|
+
subpath,
|
|
1146
|
+
isPattern,
|
|
1147
|
+
key,
|
|
1148
|
+
);
|
|
1149
|
+
if (result !== undefined) {
|
|
1150
|
+
if (traces !== undefined) {
|
|
1151
|
+
if (result.path !== '') this.trace(Diagnostics.Resolved_under_condition_0, condition);
|
|
1152
|
+
this.trace(Diagnostics.Exiting_conditional_exports);
|
|
1153
|
+
}
|
|
1154
|
+
return result;
|
|
1155
|
+
}
|
|
1156
|
+
if (traces !== undefined) this.trace(Diagnostics.Failed_to_resolve_under_condition_0, condition);
|
|
1157
|
+
}
|
|
1158
|
+
if (traces !== undefined) this.trace(Diagnostics.Exiting_conditional_exports);
|
|
1159
|
+
return undefined;
|
|
1160
|
+
}
|
|
1161
|
+
case 'array':
|
|
1162
|
+
if (target.items.length === 0) return this.invalidTarget(scope, moduleName);
|
|
1163
|
+
for (const item of target.items) {
|
|
1164
|
+
const result = this.loadModuleFromTargetExportOrImport(
|
|
1165
|
+
extensions,
|
|
1166
|
+
moduleName,
|
|
1167
|
+
scope,
|
|
1168
|
+
isImports,
|
|
1169
|
+
item,
|
|
1170
|
+
subpath,
|
|
1171
|
+
isPattern,
|
|
1172
|
+
key,
|
|
1173
|
+
);
|
|
1174
|
+
if (result !== undefined) return result;
|
|
1175
|
+
}
|
|
1176
|
+
return this.invalidTarget(scope, moduleName);
|
|
1177
|
+
case 'null':
|
|
1178
|
+
if (traces !== undefined) {
|
|
1179
|
+
this.trace(
|
|
1180
|
+
Diagnostics.X_package_json_scope_0_explicitly_maps_specifier_1_to_null,
|
|
1181
|
+
scope.packageDirectory,
|
|
1182
|
+
moduleName,
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
1185
|
+
return unresolved();
|
|
1186
|
+
default:
|
|
1187
|
+
return this.invalidTarget(scope, moduleName);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/** An `imports` target naming a package resolves as a module from the scope's directory. */
|
|
1192
|
+
private resolveImportsTargetAsModule(
|
|
1193
|
+
targetString: string,
|
|
1194
|
+
subpath: string,
|
|
1195
|
+
isPattern: boolean,
|
|
1196
|
+
scope: PackageJsonInfo,
|
|
1197
|
+
key: string,
|
|
1198
|
+
): Resolved | undefined {
|
|
1199
|
+
const combinedLookup = isPattern ? replaceAllStars(targetString, subpath) : targetString + subpath;
|
|
1200
|
+
const scopeDirectory = ensureTrailingDirectorySeparator(scope.packageDirectory);
|
|
1201
|
+
if (this.traces !== undefined) {
|
|
1202
|
+
this.trace(Diagnostics.Using_0_subpath_1_with_target_2, 'imports', key, combinedLookup);
|
|
1203
|
+
this.trace(Diagnostics.Resolving_module_0_from_1, combinedLookup, scopeDirectory);
|
|
1204
|
+
}
|
|
1205
|
+
const name = this.name;
|
|
1206
|
+
const containingDirectory = this.containingDirectory;
|
|
1207
|
+
this.name = combinedLookup;
|
|
1208
|
+
this.containingDirectory = scopeDirectory;
|
|
1209
|
+
const result = this.resolveNodeLike();
|
|
1210
|
+
this.name = name;
|
|
1211
|
+
this.containingDirectory = containingDirectory;
|
|
1212
|
+
if (result.resolvedFileName === '') return undefined;
|
|
1213
|
+
return {
|
|
1214
|
+
path: result.resolvedFileName,
|
|
1215
|
+
extension: result.extension,
|
|
1216
|
+
packageId: result.packageId,
|
|
1217
|
+
originalPath: result.originalPath,
|
|
1218
|
+
resolvedUsingTsExtension: result.resolvedUsingTsExtension,
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/** Maps a path into `outDir`/`declarationDir` back to the input file, so self-names work before a build. */
|
|
1223
|
+
private tryLoadInputFileForPath(
|
|
1224
|
+
finalPath: string,
|
|
1225
|
+
entry: string,
|
|
1226
|
+
packagePath: string,
|
|
1227
|
+
isImports: boolean,
|
|
1228
|
+
): Resolved | undefined {
|
|
1229
|
+
const options = this.options;
|
|
1230
|
+
const outDir = options.outDir ?? '';
|
|
1231
|
+
const declarationDir = options.declarationDir ?? '';
|
|
1232
|
+
const configFilePath = options.configFilePath ?? '';
|
|
1233
|
+
const caseSensitive = this.host.useCaseSensitiveFileNames();
|
|
1234
|
+
const currentDirectory = this.host.getCurrentDirectory();
|
|
1235
|
+
if (
|
|
1236
|
+
this.isConfigLookup ||
|
|
1237
|
+
(declarationDir === '' && outDir === '') ||
|
|
1238
|
+
finalPath.includes('/node_modules/') ||
|
|
1239
|
+
(configFilePath !== '' &&
|
|
1240
|
+
!containsPath(getDirectoryPath(packagePath), configFilePath, caseSensitive, currentDirectory))
|
|
1241
|
+
) {
|
|
1242
|
+
return undefined;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// Unlike tsc 5.x, no guessing: the root comes from `rootDir` or the config file location.
|
|
1246
|
+
let rootDir: string;
|
|
1247
|
+
if (options.rootDir !== undefined && options.rootDir !== '') {
|
|
1248
|
+
rootDir = options.rootDir;
|
|
1249
|
+
} else if (configFilePath !== '') {
|
|
1250
|
+
rootDir = getDirectoryPath(configFilePath);
|
|
1251
|
+
} else {
|
|
1252
|
+
this.diagnostics.push(
|
|
1253
|
+
createDiagnostic(
|
|
1254
|
+
undefined,
|
|
1255
|
+
0,
|
|
1256
|
+
0,
|
|
1257
|
+
isImports
|
|
1258
|
+
? Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_import_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate
|
|
1259
|
+
: Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_export_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate,
|
|
1260
|
+
entry === '' ? '.' : entry,
|
|
1261
|
+
packagePath,
|
|
1262
|
+
),
|
|
1263
|
+
);
|
|
1264
|
+
return unresolved();
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// Output paths in a config are relative to the current directory; otherwise to the root.
|
|
1268
|
+
const base = configFilePath !== '' ? currentDirectory : rootDir;
|
|
1269
|
+
const candidateDirectories: string[] = [];
|
|
1270
|
+
if (declarationDir !== '') {
|
|
1271
|
+
candidateDirectories.push(getNormalizedAbsolutePath(combinePaths(base, declarationDir), currentDirectory));
|
|
1272
|
+
}
|
|
1273
|
+
if (outDir !== '' && outDir !== declarationDir) {
|
|
1274
|
+
candidateDirectories.push(getNormalizedAbsolutePath(combinePaths(base, outDir), currentDirectory));
|
|
1275
|
+
}
|
|
1276
|
+
for (const candidateDirectory of candidateDirectories) {
|
|
1277
|
+
if (!containsPath(candidateDirectory, finalPath, caseSensitive, currentDirectory)) continue;
|
|
1278
|
+
const fragment =
|
|
1279
|
+
finalPath.length > candidateDirectory.length ? finalPath.slice(candidateDirectory.length + 1) : '';
|
|
1280
|
+
const possibleInputBase = combinePaths(rootDir, fragment);
|
|
1281
|
+
for (const ext of OUTPUT_EXTENSIONS) {
|
|
1282
|
+
if (!fileExtensionIs(possibleInputBase, ext)) continue;
|
|
1283
|
+
for (const inputExt of getPossibleOriginalInputExtensionForExtension(possibleInputBase)) {
|
|
1284
|
+
if (!extensionIsOk(this.extensions, inputExt)) continue;
|
|
1285
|
+
const input = changeExtension(possibleInputBase, inputExt);
|
|
1286
|
+
if (this.host.fileExists(input)) {
|
|
1287
|
+
const resolved = this.loadFileNameFromPackageJsonField(this.extensions, input, '');
|
|
1288
|
+
if (resolved !== undefined) return resolved;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
return undefined;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
//// node_modules
|
|
1297
|
+
|
|
1298
|
+
loadModuleFromNearestNodeModulesDirectory(typesScopeOnly: boolean): Resolved | undefined {
|
|
1299
|
+
// First TS/DTS in implementation packages and @types in every ancestor, then JS in every ancestor.
|
|
1300
|
+
const priority = this.extensions & (Extensions.TypeScript | Extensions.Declaration);
|
|
1301
|
+
const secondary = this.extensions & ~(Extensions.TypeScript | Extensions.Declaration);
|
|
1302
|
+
if (priority !== 0) {
|
|
1303
|
+
if (this.traces !== undefined) {
|
|
1304
|
+
this.trace(
|
|
1305
|
+
Diagnostics.Searching_all_ancestor_node_modules_directories_for_preferred_extensions_Colon_0,
|
|
1306
|
+
extensionsToString(priority),
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
const result = this.loadModuleFromAncestorNodeModules(priority, typesScopeOnly);
|
|
1310
|
+
if (result !== undefined) return result;
|
|
1311
|
+
}
|
|
1312
|
+
if (secondary !== 0 && !typesScopeOnly) {
|
|
1313
|
+
if (this.traces !== undefined) {
|
|
1314
|
+
this.trace(
|
|
1315
|
+
Diagnostics.Searching_all_ancestor_node_modules_directories_for_fallback_extensions_Colon_0,
|
|
1316
|
+
extensionsToString(secondary),
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
return this.loadModuleFromAncestorNodeModules(secondary, typesScopeOnly);
|
|
1320
|
+
}
|
|
1321
|
+
return undefined;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
private loadModuleFromAncestorNodeModules(extensions: number, typesScopeOnly: boolean): Resolved | undefined {
|
|
1325
|
+
let directory = this.containingDirectory;
|
|
1326
|
+
for (;;) {
|
|
1327
|
+
if (getBaseFileName(directory) !== 'node_modules') {
|
|
1328
|
+
const result = this.loadModuleFromImmediateNodeModulesDirectory(extensions, directory, typesScopeOnly);
|
|
1329
|
+
if (result !== undefined) return result;
|
|
1330
|
+
}
|
|
1331
|
+
const parent = getDirectoryPath(directory);
|
|
1332
|
+
if (parent === directory) return undefined;
|
|
1333
|
+
directory = parent;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
loadModuleFromImmediateNodeModulesDirectory(
|
|
1338
|
+
extensions: number,
|
|
1339
|
+
directory: string,
|
|
1340
|
+
typesScopeOnly: boolean,
|
|
1341
|
+
): Resolved | undefined {
|
|
1342
|
+
const nodeModules = combinePaths(directory, 'node_modules');
|
|
1343
|
+
if (!this.host.directoryExists(nodeModules)) {
|
|
1344
|
+
if (this.traces !== undefined)
|
|
1345
|
+
this.trace(Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModules);
|
|
1346
|
+
return undefined;
|
|
1347
|
+
}
|
|
1348
|
+
if (!typesScopeOnly) {
|
|
1349
|
+
const result = this.loadModuleFromSpecificNodeModulesDirectory(extensions, this.name, nodeModules);
|
|
1350
|
+
if (result !== undefined) return result;
|
|
1351
|
+
}
|
|
1352
|
+
if ((extensions & Extensions.Declaration) !== 0) {
|
|
1353
|
+
const atTypes = combinePaths(nodeModules, '@types');
|
|
1354
|
+
if (!this.host.directoryExists(atTypes)) {
|
|
1355
|
+
if (this.traces !== undefined)
|
|
1356
|
+
this.trace(Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, atTypes);
|
|
1357
|
+
return undefined;
|
|
1358
|
+
}
|
|
1359
|
+
return this.loadModuleFromSpecificNodeModulesDirectory(
|
|
1360
|
+
Extensions.Declaration,
|
|
1361
|
+
this.mangleScopedPackageName(this.name),
|
|
1362
|
+
atTypes,
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1365
|
+
return undefined;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
private loadModuleFromSpecificNodeModulesDirectory(
|
|
1369
|
+
extensions: number,
|
|
1370
|
+
moduleName: string,
|
|
1371
|
+
nodeModulesDirectory: string,
|
|
1372
|
+
): Resolved | undefined {
|
|
1373
|
+
// Without the trailing separator, `pkg/` and `pkg` share their candidate and package directory.
|
|
1374
|
+
const candidate = removeTrailingDirectorySeparator(normalizePath(combinePaths(nodeModulesDirectory, moduleName)));
|
|
1375
|
+
const { packageName, rest } = parsePackageName(moduleName);
|
|
1376
|
+
const packageDirectory = packageName === '' ? candidate : combinePaths(nodeModulesDirectory, packageName);
|
|
1377
|
+
|
|
1378
|
+
if (this.resolvePackageDirectoryOnly) {
|
|
1379
|
+
return this.host.directoryExists(packageDirectory) ? resolvedFile(packageDirectory, '', false) : undefined;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
// A nested package.json (`node_modules/foo/bar/package.json`) applies unless the root has `exports`.
|
|
1383
|
+
let rootPackageInfo: PackageJsonInfo | undefined;
|
|
1384
|
+
let packageInfo = this.getPackageJsonInfo(candidate);
|
|
1385
|
+
if (rest !== '' && packageInfo !== undefined) {
|
|
1386
|
+
if ((this.features & Features.Exports) !== 0) rootPackageInfo = this.getPackageJsonInfo(packageDirectory);
|
|
1387
|
+
if (rootPackageInfo === undefined || rootPackageInfo.contents?.exports === undefined) {
|
|
1388
|
+
const fromFile = this.loadModuleFromFile(extensions, candidate);
|
|
1389
|
+
if (fromFile !== undefined) return fromFile;
|
|
1390
|
+
const fromDirectory = this.loadNodeModuleFromDirectoryWorker(extensions, candidate, packageInfo);
|
|
1391
|
+
if (fromDirectory !== undefined) {
|
|
1392
|
+
fromDirectory.packageId = this.getPackageId(fromDirectory.path, packageInfo);
|
|
1393
|
+
return fromDirectory;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
if (rest !== '') packageInfo = rootPackageInfo ?? this.getPackageJsonInfo(packageDirectory);
|
|
1399
|
+
const contents = packageInfo?.contents;
|
|
1400
|
+
if (packageInfo !== undefined) {
|
|
1401
|
+
this.resolvedPackageDirectory = true;
|
|
1402
|
+
// `exports` takes priority over files, directories and typesVersions, and blocks them.
|
|
1403
|
+
// A top-level `"exports": null` does not block them.
|
|
1404
|
+
if ((this.features & Features.Exports) !== 0 && contents !== undefined && !isFalsyJson(contents.exports)) {
|
|
1405
|
+
return this.loadModuleFromExports(packageInfo, extensions, combinePaths('.', rest));
|
|
1406
|
+
}
|
|
1407
|
+
if (rest !== '' && contents !== undefined) {
|
|
1408
|
+
const versionPaths = contents.getVersionPaths(this.traces);
|
|
1409
|
+
if (versionPaths !== undefined) {
|
|
1410
|
+
if (this.traces !== undefined) {
|
|
1411
|
+
this.trace(
|
|
1412
|
+
Diagnostics.X_package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2,
|
|
1413
|
+
versionPaths.version,
|
|
1414
|
+
typeScriptVersion,
|
|
1415
|
+
rest,
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
const fromPaths = this.tryLoadModuleUsingPaths(
|
|
1419
|
+
extensions,
|
|
1420
|
+
rest,
|
|
1421
|
+
packageDirectory,
|
|
1422
|
+
versionPaths.paths,
|
|
1423
|
+
parsePatterns(versionPaths.paths),
|
|
1424
|
+
{ kind: 'package', rest, packageInfo },
|
|
1425
|
+
);
|
|
1426
|
+
if (fromPaths !== undefined) return fromPaths;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return this.loadFromNodeModulesPackage(extensions, candidate, rest, packageInfo);
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
/** Loads `candidate` inside a `node_modules` package as a file, then as a directory. */
|
|
1434
|
+
private loadFromNodeModulesPackage(
|
|
1435
|
+
extensions: number,
|
|
1436
|
+
candidate: string,
|
|
1437
|
+
rest: string,
|
|
1438
|
+
packageInfo: PackageJsonInfo | undefined,
|
|
1439
|
+
): Resolved | undefined {
|
|
1440
|
+
if (rest !== '' || !this.esmMode) {
|
|
1441
|
+
const fromFile = this.loadModuleFromFile(extensions, candidate);
|
|
1442
|
+
if (fromFile !== undefined) {
|
|
1443
|
+
fromFile.packageId = this.getPackageId(fromFile.path, packageInfo);
|
|
1444
|
+
return fromFile;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
const fromDirectory = this.loadNodeModuleFromDirectoryWorker(extensions, candidate, packageInfo);
|
|
1448
|
+
if (fromDirectory !== undefined) {
|
|
1449
|
+
fromDirectory.packageId = this.getPackageId(fromDirectory.path, packageInfo);
|
|
1450
|
+
return fromDirectory;
|
|
1451
|
+
}
|
|
1452
|
+
const contents = packageInfo?.contents;
|
|
1453
|
+
if (
|
|
1454
|
+
rest === '' &&
|
|
1455
|
+
contents !== undefined &&
|
|
1456
|
+
(contents.exports === undefined || contents.exports.type === 'null') &&
|
|
1457
|
+
this.esmMode
|
|
1458
|
+
) {
|
|
1459
|
+
// ESM skips index lookups, but a package without `main` or `exports` still defaults to `index.js`.
|
|
1460
|
+
const index = this.loadModuleFromFile(extensions, combinePaths(candidate, 'index.js'));
|
|
1461
|
+
if (index !== undefined) {
|
|
1462
|
+
index.packageId = this.getPackageId(index.path, packageInfo);
|
|
1463
|
+
return index;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
return undefined;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
createResolvedModuleHandlingSymlink(resolved: Resolved | undefined): ResolvedModule {
|
|
1470
|
+
const isExternalLibraryImport = resolved !== undefined && resolved.path.includes('/node_modules/');
|
|
1471
|
+
if (
|
|
1472
|
+
resolved !== undefined &&
|
|
1473
|
+
this.options.preserveSymlinks !== true &&
|
|
1474
|
+
isExternalLibraryImport &&
|
|
1475
|
+
resolved.originalPath === '' &&
|
|
1476
|
+
!isExternalModuleNameRelative(this.name)
|
|
1477
|
+
) {
|
|
1478
|
+
const real = this.realPathIfDifferent(resolved.path);
|
|
1479
|
+
if (real !== '') {
|
|
1480
|
+
resolved.originalPath = resolved.path;
|
|
1481
|
+
resolved.path = real;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
return this.createResolvedModule(resolved, isExternalLibraryImport);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
/** The real path of `path`, or `''` if it is the same path. */
|
|
1488
|
+
private realPathIfDifferent(path: string): string {
|
|
1489
|
+
const real = this.realPath(path);
|
|
1490
|
+
// A real path differing only in case keeps the original spelling for forceConsistentCasingInFileNames.
|
|
1491
|
+
const caseSensitive = this.host.useCaseSensitiveFileNames();
|
|
1492
|
+
return comparePaths(path, real, caseSensitive, this.host.getCurrentDirectory()) !== 0 ? real : '';
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
createResolvedModule(resolved: Resolved | undefined, isExternalLibraryImport: boolean): ResolvedModule {
|
|
1496
|
+
const diagnostics = this.diagnostics.length === 0 ? NO_DIAGNOSTICS : this.diagnostics;
|
|
1497
|
+
if (resolved === undefined) return unresolvedModule(diagnostics);
|
|
1498
|
+
return {
|
|
1499
|
+
resolvedFileName: resolved.path,
|
|
1500
|
+
originalPath: resolved.originalPath,
|
|
1501
|
+
extension: resolved.extension,
|
|
1502
|
+
resolvedUsingTsExtension: resolved.resolvedUsingTsExtension,
|
|
1503
|
+
packageId: resolved.packageId,
|
|
1504
|
+
isExternalLibraryImport,
|
|
1505
|
+
alternateResult: '',
|
|
1506
|
+
resolutionDiagnostics: diagnostics,
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
private createResolvedTypeReferenceDirective(
|
|
1511
|
+
resolved: Resolved | undefined,
|
|
1512
|
+
primary: boolean,
|
|
1513
|
+
): ResolvedTypeReferenceDirective {
|
|
1514
|
+
const result: ResolvedTypeReferenceDirective = {
|
|
1515
|
+
resolvedFileName: '',
|
|
1516
|
+
originalPath: '',
|
|
1517
|
+
primary: false,
|
|
1518
|
+
packageId: undefined,
|
|
1519
|
+
isExternalLibraryImport: false,
|
|
1520
|
+
resolutionDiagnostics: this.diagnostics.length === 0 ? NO_DIAGNOSTICS : this.diagnostics,
|
|
1521
|
+
};
|
|
1522
|
+
if (resolved === undefined || resolved.path === '') return result;
|
|
1523
|
+
if (!extensionIsTs(resolved.extension)) throw new Error('expected a TypeScript file extension');
|
|
1524
|
+
result.resolvedFileName = resolved.path;
|
|
1525
|
+
result.primary = primary;
|
|
1526
|
+
result.packageId = resolved.packageId;
|
|
1527
|
+
result.isExternalLibraryImport = resolved.path.includes('/node_modules/');
|
|
1528
|
+
if (this.options.preserveSymlinks !== true) {
|
|
1529
|
+
const real = this.realPathIfDifferent(resolved.path);
|
|
1530
|
+
if (real !== '') {
|
|
1531
|
+
result.resolvedFileName = real;
|
|
1532
|
+
result.originalPath = resolved.path;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
return result;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
//// paths and rootDirs
|
|
1539
|
+
|
|
1540
|
+
private tryLoadModuleUsingOptionalResolutionSettings(): Resolved | undefined {
|
|
1541
|
+
const fromPaths = this.tryLoadModuleUsingPathsIfEligible();
|
|
1542
|
+
if (fromPaths !== undefined) return fromPaths;
|
|
1543
|
+
// baseUrl lookups were removed; rootDirs only apply to relative names.
|
|
1544
|
+
return isExternalModuleNameRelative(this.name) ? this.tryLoadModuleUsingRootDirs() : undefined;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
private getPathPatterns(): ParsedPatterns {
|
|
1548
|
+
if (this.options === this.resolver.options) return this.resolver.getPathPatterns();
|
|
1549
|
+
if (this.pathPatterns === undefined) this.pathPatterns = parsePatterns(this.options.paths ?? new Map());
|
|
1550
|
+
return this.pathPatterns;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
private tryLoadModuleUsingPathsIfEligible(): Resolved | undefined {
|
|
1554
|
+
const paths = this.options.paths;
|
|
1555
|
+
if (paths === undefined || paths.size === 0 || pathIsRelative(this.name)) return undefined;
|
|
1556
|
+
if (this.traces !== undefined) {
|
|
1557
|
+
this.trace(Diagnostics.X_paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, this.name);
|
|
1558
|
+
}
|
|
1559
|
+
const baseDirectory =
|
|
1560
|
+
this.options.pathsBasePath !== undefined && this.options.pathsBasePath !== ''
|
|
1561
|
+
? this.options.pathsBasePath
|
|
1562
|
+
: this.host.getCurrentDirectory();
|
|
1563
|
+
return this.tryLoadModuleUsingPaths(
|
|
1564
|
+
this.extensions,
|
|
1565
|
+
this.name,
|
|
1566
|
+
baseDirectory,
|
|
1567
|
+
paths,
|
|
1568
|
+
this.getPathPatterns(),
|
|
1569
|
+
RELATIVE_LOADER,
|
|
1570
|
+
);
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
private tryLoadModuleUsingPaths(
|
|
1574
|
+
extensions: number,
|
|
1575
|
+
moduleName: string,
|
|
1576
|
+
containingDirectory: string,
|
|
1577
|
+
paths: ReadonlyMap<string, readonly string[] | undefined>,
|
|
1578
|
+
patterns: ParsedPatterns,
|
|
1579
|
+
loader: PathsLoader,
|
|
1580
|
+
): Resolved | undefined {
|
|
1581
|
+
const pattern = matchPatternOrExact(patterns, moduleName);
|
|
1582
|
+
if (pattern === undefined) return undefined;
|
|
1583
|
+
const star = matchedText(pattern, moduleName);
|
|
1584
|
+
if (this.traces !== undefined) this.trace(Diagnostics.Module_name_0_matched_pattern_1, moduleName, pattern.text);
|
|
1585
|
+
for (const substitution of paths.get(pattern.text) ?? []) {
|
|
1586
|
+
const path = replaceFirstStar(substitution, star);
|
|
1587
|
+
const candidate = normalizePath(combinePaths(containingDirectory, path));
|
|
1588
|
+
if (this.traces !== undefined) {
|
|
1589
|
+
this.trace(Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, substitution, path);
|
|
1590
|
+
}
|
|
1591
|
+
// A substitution may name a file with its extension.
|
|
1592
|
+
const extension = tryGetExtensionFromPath(substitution);
|
|
1593
|
+
if (extension !== '') {
|
|
1594
|
+
const found = this.tryFile(candidate);
|
|
1595
|
+
if (found !== undefined) return resolvedFile(found, extension, false);
|
|
1596
|
+
}
|
|
1597
|
+
const saved = this.candidateEndingIsFromConfig;
|
|
1598
|
+
if (extension !== '') this.candidateEndingIsFromConfig = true;
|
|
1599
|
+
const resolved = this.runLoader(loader, extensions, candidate);
|
|
1600
|
+
this.candidateEndingIsFromConfig = saved;
|
|
1601
|
+
if (resolved !== undefined) return resolved;
|
|
1602
|
+
}
|
|
1603
|
+
return undefined;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
private runLoader(loader: PathsLoader, extensions: number, candidate: string): Resolved | undefined {
|
|
1607
|
+
switch (loader.kind) {
|
|
1608
|
+
case 'relative':
|
|
1609
|
+
return this.nodeLoadModuleByRelativeName(extensions, candidate, true);
|
|
1610
|
+
case 'package':
|
|
1611
|
+
return this.loadFromNodeModulesPackage(extensions, candidate, loader.rest, loader.packageInfo);
|
|
1612
|
+
case 'directory':
|
|
1613
|
+
return this.loadFromPackageJsonEntry(extensions, candidate, loader.packageFile, loader.packageInfo);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
private tryLoadModuleUsingRootDirs(): Resolved | undefined {
|
|
1618
|
+
const rootDirs = this.options.rootDirs;
|
|
1619
|
+
if (rootDirs === undefined || rootDirs.length === 0) return undefined;
|
|
1620
|
+
const traces = this.traces;
|
|
1621
|
+
if (traces !== undefined)
|
|
1622
|
+
this.trace(Diagnostics.X_rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, this.name);
|
|
1623
|
+
|
|
1624
|
+
const candidate = normalizePath(combinePaths(this.containingDirectory, this.name));
|
|
1625
|
+
let matchedRootDir = '';
|
|
1626
|
+
let matchedPrefix = '';
|
|
1627
|
+
for (const rootDir of rootDirs) {
|
|
1628
|
+
const normalizedRoot = ensureTrailingDirectorySeparator(normalizePath(rootDir));
|
|
1629
|
+
const isLongest =
|
|
1630
|
+
candidate.startsWith(normalizedRoot) && (matchedPrefix === '' || matchedPrefix.length < normalizedRoot.length);
|
|
1631
|
+
if (traces !== undefined) {
|
|
1632
|
+
this.trace(
|
|
1633
|
+
Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2,
|
|
1634
|
+
normalizedRoot,
|
|
1635
|
+
candidate,
|
|
1636
|
+
String(isLongest),
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1639
|
+
if (isLongest) {
|
|
1640
|
+
matchedPrefix = normalizedRoot;
|
|
1641
|
+
matchedRootDir = rootDir;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
if (matchedPrefix === '') return undefined;
|
|
1645
|
+
|
|
1646
|
+
if (traces !== undefined) this.trace(Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedPrefix);
|
|
1647
|
+
const suffix = candidate.slice(matchedPrefix.length);
|
|
1648
|
+
if (traces !== undefined)
|
|
1649
|
+
this.trace(Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedPrefix, candidate);
|
|
1650
|
+
const initial = this.nodeLoadModuleByRelativeName(this.extensions, candidate, true);
|
|
1651
|
+
if (initial !== undefined) return initial;
|
|
1652
|
+
|
|
1653
|
+
if (traces !== undefined) this.trace(Diagnostics.Trying_other_entries_in_rootDirs);
|
|
1654
|
+
for (const rootDir of rootDirs) {
|
|
1655
|
+
if (rootDir === matchedRootDir) continue;
|
|
1656
|
+
const other = combinePaths(normalizePath(rootDir), suffix);
|
|
1657
|
+
if (traces !== undefined)
|
|
1658
|
+
this.trace(Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, other);
|
|
1659
|
+
const resolved = this.nodeLoadModuleByRelativeName(this.extensions, other, true);
|
|
1660
|
+
if (resolved !== undefined) return resolved;
|
|
1661
|
+
}
|
|
1662
|
+
if (traces !== undefined) this.trace(Diagnostics.Module_resolution_using_rootDirs_has_failed);
|
|
1663
|
+
return undefined;
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
//// Files and directories
|
|
1667
|
+
|
|
1668
|
+
private nodeLoadModuleByRelativeName(
|
|
1669
|
+
extensions: number,
|
|
1670
|
+
candidate: string,
|
|
1671
|
+
considerPackageJson: boolean,
|
|
1672
|
+
): Resolved | undefined {
|
|
1673
|
+
if (this.traces !== undefined) {
|
|
1674
|
+
this.trace(
|
|
1675
|
+
Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_types_Colon_1,
|
|
1676
|
+
candidate,
|
|
1677
|
+
extensionsToString(extensions),
|
|
1678
|
+
);
|
|
1679
|
+
}
|
|
1680
|
+
if (!hasTrailingDirectorySeparator(candidate)) {
|
|
1681
|
+
const parent = getDirectoryPath(candidate);
|
|
1682
|
+
if (!this.host.directoryExists(parent)) {
|
|
1683
|
+
if (this.traces !== undefined)
|
|
1684
|
+
this.trace(Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parent);
|
|
1685
|
+
return undefined;
|
|
1686
|
+
}
|
|
1687
|
+
const fromFile = this.loadModuleFromFile(extensions, candidate);
|
|
1688
|
+
if (fromFile !== undefined) {
|
|
1689
|
+
if (considerPackageJson) this.setPackageIdFromNodeModulesPath(fromFile);
|
|
1690
|
+
return fromFile;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
if (!this.host.directoryExists(candidate)) {
|
|
1694
|
+
if (this.traces !== undefined)
|
|
1695
|
+
this.trace(Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate);
|
|
1696
|
+
return undefined;
|
|
1697
|
+
}
|
|
1698
|
+
// ESM relative imports do no directory lookups (neither package.json nor index files).
|
|
1699
|
+
return this.esmMode ? undefined : this.loadNodeModuleFromDirectory(extensions, candidate, considerPackageJson);
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
private loadModuleFromFile(extensions: number, candidate: string): Resolved | undefined {
|
|
1703
|
+
// ./foo.js -> ./foo.ts
|
|
1704
|
+
const replaced = this.loadModuleFromFileNoImplicitExtensions(extensions, candidate);
|
|
1705
|
+
if (replaced !== undefined) return replaced;
|
|
1706
|
+
// ./foo -> ./foo.ts
|
|
1707
|
+
return this.esmMode ? undefined : this.tryAddingExtensions(candidate, extensions, '');
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
private loadModuleFromFileNoImplicitExtensions(extensions: number, candidate: string): Resolved | undefined {
|
|
1711
|
+
// Extensionless files are not supported.
|
|
1712
|
+
if (!getBaseFileName(candidate).includes('.')) return undefined;
|
|
1713
|
+
let extensionless = removeFileExtension(candidate);
|
|
1714
|
+
// Unknown extensions map to declaration files such as `.d.css.ts`.
|
|
1715
|
+
if (extensionless === candidate) extensionless = candidate.slice(0, candidate.lastIndexOf('.'));
|
|
1716
|
+
const extension = candidate.slice(extensionless.length);
|
|
1717
|
+
if (this.traces !== undefined)
|
|
1718
|
+
this.trace(Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
|
|
1719
|
+
return this.tryAddingExtensions(extensionless, extensions, extension);
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
private tryAddingExtensions(
|
|
1723
|
+
extensionless: string,
|
|
1724
|
+
extensions: number,
|
|
1725
|
+
originalExtension: string,
|
|
1726
|
+
): Resolved | undefined {
|
|
1727
|
+
const directory = getDirectoryPath(extensionless);
|
|
1728
|
+
if (directory !== '' && !this.host.directoryExists(directory)) return undefined;
|
|
1729
|
+
const ts = (extensions & Extensions.TypeScript) !== 0;
|
|
1730
|
+
const dts = (extensions & Extensions.Declaration) !== 0;
|
|
1731
|
+
const js = (extensions & Extensions.JavaScript) !== 0;
|
|
1732
|
+
switch (originalExtension) {
|
|
1733
|
+
case '.mjs':
|
|
1734
|
+
case '.mts':
|
|
1735
|
+
case '.d.mts': {
|
|
1736
|
+
const usingTs = originalExtension === '.mts' || originalExtension === '.d.mts';
|
|
1737
|
+
return (
|
|
1738
|
+
(ts ? this.tryExtension('.mts', extensionless, usingTs) : undefined) ??
|
|
1739
|
+
(dts ? this.tryExtension('.d.mts', extensionless, usingTs) : undefined) ??
|
|
1740
|
+
(js ? this.tryExtension('.mjs', extensionless, false) : undefined)
|
|
1741
|
+
);
|
|
1742
|
+
}
|
|
1743
|
+
case '.cjs':
|
|
1744
|
+
case '.cts':
|
|
1745
|
+
case '.d.cts': {
|
|
1746
|
+
const usingTs = originalExtension === '.cts' || originalExtension === '.d.cts';
|
|
1747
|
+
return (
|
|
1748
|
+
(ts ? this.tryExtension('.cts', extensionless, usingTs) : undefined) ??
|
|
1749
|
+
(dts ? this.tryExtension('.d.cts', extensionless, usingTs) : undefined) ??
|
|
1750
|
+
(js ? this.tryExtension('.cjs', extensionless, false) : undefined)
|
|
1751
|
+
);
|
|
1752
|
+
}
|
|
1753
|
+
case '.json':
|
|
1754
|
+
return (
|
|
1755
|
+
(dts ? this.tryExtension('.d.json.ts', extensionless, false) : undefined) ??
|
|
1756
|
+
((extensions & Extensions.Json) !== 0 ? this.tryExtension('.json', extensionless, false) : undefined)
|
|
1757
|
+
);
|
|
1758
|
+
case '.tsx':
|
|
1759
|
+
case '.jsx': {
|
|
1760
|
+
// Prefer an exact .tsx/.jsx match before the .ts/.js file.
|
|
1761
|
+
const usingTs = originalExtension === '.tsx';
|
|
1762
|
+
return (
|
|
1763
|
+
(ts
|
|
1764
|
+
? (this.tryExtension('.tsx', extensionless, usingTs) ?? this.tryExtension('.ts', extensionless, usingTs))
|
|
1765
|
+
: undefined) ??
|
|
1766
|
+
(dts ? this.tryExtension('.d.ts', extensionless, usingTs) : undefined) ??
|
|
1767
|
+
(js
|
|
1768
|
+
? (this.tryExtension('.jsx', extensionless, false) ?? this.tryExtension('.js', extensionless, false))
|
|
1769
|
+
: undefined)
|
|
1770
|
+
);
|
|
1771
|
+
}
|
|
1772
|
+
case '.ts':
|
|
1773
|
+
case '.d.ts':
|
|
1774
|
+
case '.js':
|
|
1775
|
+
case '': {
|
|
1776
|
+
const usingTs = originalExtension === '.ts' || originalExtension === '.d.ts';
|
|
1777
|
+
return (
|
|
1778
|
+
(ts
|
|
1779
|
+
? (this.tryExtension('.ts', extensionless, usingTs) ?? this.tryExtension('.tsx', extensionless, usingTs))
|
|
1780
|
+
: undefined) ??
|
|
1781
|
+
(dts ? this.tryExtension('.d.ts', extensionless, usingTs) : undefined) ??
|
|
1782
|
+
(js
|
|
1783
|
+
? (this.tryExtension('.js', extensionless, false) ?? this.tryExtension('.jsx', extensionless, false))
|
|
1784
|
+
: undefined) ??
|
|
1785
|
+
(this.isConfigLookup ? this.tryExtension('.json', extensionless, false) : undefined)
|
|
1786
|
+
);
|
|
1787
|
+
}
|
|
1788
|
+
default:
|
|
1789
|
+
if (dts && !isDeclarationFileName(extensionless + originalExtension)) {
|
|
1790
|
+
return this.tryExtension('.d' + originalExtension + '.ts', extensionless, false);
|
|
1791
|
+
}
|
|
1792
|
+
return undefined;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
private tryExtension(
|
|
1797
|
+
extension: string,
|
|
1798
|
+
extensionless: string,
|
|
1799
|
+
resolvedUsingTsExtension: boolean,
|
|
1800
|
+
): Resolved | undefined {
|
|
1801
|
+
const path = this.tryFile(extensionless + extension);
|
|
1802
|
+
if (path === undefined) return undefined;
|
|
1803
|
+
return resolvedFile(path, extension, !this.candidateEndingIsFromConfig && resolvedUsingTsExtension);
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
/** The existing file for `fileName`, trying each of `moduleSuffixes`. */
|
|
1807
|
+
private tryFile(fileName: string): string | undefined {
|
|
1808
|
+
const suffixes = this.options.moduleSuffixes;
|
|
1809
|
+
if (suffixes === undefined || suffixes.length === 0) return this.tryFileLookup(fileName) ? fileName : undefined;
|
|
1810
|
+
const extension = tryGetExtensionFromPath(fileName);
|
|
1811
|
+
const withoutExtension = removeExtension(fileName, extension);
|
|
1812
|
+
for (const suffix of suffixes) {
|
|
1813
|
+
const path = withoutExtension + suffix + extension;
|
|
1814
|
+
if (this.tryFileLookup(path)) return path;
|
|
1815
|
+
}
|
|
1816
|
+
return undefined;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
private tryFileLookup(fileName: string): boolean {
|
|
1820
|
+
if (this.host.fileExists(fileName)) {
|
|
1821
|
+
if (this.traces !== undefined) this.trace(Diagnostics.File_0_exists_use_it_as_a_name_resolution_result, fileName);
|
|
1822
|
+
return true;
|
|
1823
|
+
}
|
|
1824
|
+
if (this.traces !== undefined) this.trace(Diagnostics.File_0_does_not_exist, fileName);
|
|
1825
|
+
return false;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
private loadNodeModuleFromDirectory(
|
|
1829
|
+
extensions: number,
|
|
1830
|
+
candidate: string,
|
|
1831
|
+
considerPackageJson: boolean,
|
|
1832
|
+
): Resolved | undefined {
|
|
1833
|
+
const packageInfo = considerPackageJson ? this.getPackageJsonInfo(candidate) : undefined;
|
|
1834
|
+
return this.loadNodeModuleFromDirectoryWorker(extensions, candidate, packageInfo);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
private loadNodeModuleFromDirectoryWorker(
|
|
1838
|
+
extensions: number,
|
|
1839
|
+
candidate: string,
|
|
1840
|
+
packageInfo: PackageJsonInfo | undefined,
|
|
1841
|
+
): Resolved | undefined {
|
|
1842
|
+
let packageFile = '';
|
|
1843
|
+
let versionPaths: VersionPaths | undefined;
|
|
1844
|
+
const contents = packageInfo?.contents;
|
|
1845
|
+
if (packageInfo !== undefined && contents !== undefined) {
|
|
1846
|
+
versionPaths = contents.getVersionPaths(this.traces);
|
|
1847
|
+
if (comparePaths(candidate, packageInfo.packageDirectory, this.host.useCaseSensitiveFileNames()) === 0) {
|
|
1848
|
+
packageFile = this.getPackageFile(extensions, packageInfo);
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
const indexPath = combinePaths(candidate, this.isConfigLookup ? 'tsconfig' : 'index');
|
|
1852
|
+
|
|
1853
|
+
if (versionPaths !== undefined && (packageFile === '' || containsPath(candidate, packageFile, false))) {
|
|
1854
|
+
const moduleName = getRelativePathFromDirectory(candidate, packageFile !== '' ? packageFile : indexPath, false);
|
|
1855
|
+
if (this.traces !== undefined) {
|
|
1856
|
+
this.trace(
|
|
1857
|
+
Diagnostics.X_package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2,
|
|
1858
|
+
versionPaths.version,
|
|
1859
|
+
typeScriptVersion,
|
|
1860
|
+
moduleName,
|
|
1861
|
+
);
|
|
1862
|
+
}
|
|
1863
|
+
const result = this.tryLoadModuleUsingPaths(
|
|
1864
|
+
extensions,
|
|
1865
|
+
moduleName,
|
|
1866
|
+
candidate,
|
|
1867
|
+
versionPaths.paths,
|
|
1868
|
+
parsePatterns(versionPaths.paths),
|
|
1869
|
+
{ kind: 'directory', packageFile, packageInfo },
|
|
1870
|
+
);
|
|
1871
|
+
if (result !== undefined) return result;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
if (packageFile !== '') {
|
|
1875
|
+
const result = this.loadFromPackageJsonEntry(extensions, packageFile, packageFile, packageInfo);
|
|
1876
|
+
if (result !== undefined) return result;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
// ESM resolutions do no index lookups.
|
|
1880
|
+
if (this.esmMode || !this.host.directoryExists(candidate)) return undefined;
|
|
1881
|
+
return this.loadModuleFromFile(extensions, indexPath);
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
/** Loads a `main`/`types` entry (or a typesVersions substitution for it). */
|
|
1885
|
+
private loadFromPackageJsonEntry(
|
|
1886
|
+
extensions: number,
|
|
1887
|
+
candidate: string,
|
|
1888
|
+
packageFile: string,
|
|
1889
|
+
packageInfo: PackageJsonInfo | undefined,
|
|
1890
|
+
): Resolved | undefined {
|
|
1891
|
+
const fromFile = this.loadFileNameFromPackageJsonField(extensions, candidate, packageFile);
|
|
1892
|
+
if (fromFile !== undefined) return fromFile;
|
|
1893
|
+
// `types` may point at a .ts file even for declaration-only lookups.
|
|
1894
|
+
const expanded =
|
|
1895
|
+
extensions === Extensions.Declaration ? Extensions.TypeScript | Extensions.Declaration : extensions;
|
|
1896
|
+
// CommonJS packages may omit extensions in `main`, even from ESM importers.
|
|
1897
|
+
const savedEsmMode = this.esmMode;
|
|
1898
|
+
const savedEnding = this.candidateEndingIsFromConfig;
|
|
1899
|
+
this.candidateEndingIsFromConfig = true;
|
|
1900
|
+
if (packageInfo?.contents !== undefined && packageInfo.contents.type.value !== 'module') this.esmMode = false;
|
|
1901
|
+
const result = this.nodeLoadModuleByRelativeName(expanded, candidate, false);
|
|
1902
|
+
this.esmMode = savedEsmMode;
|
|
1903
|
+
this.candidateEndingIsFromConfig = savedEnding;
|
|
1904
|
+
return result;
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
/**
|
|
1908
|
+
* Loads a path written in package.json. TS extensions are allowed as is; JS extensions are also tried as their
|
|
1909
|
+
* TS counterparts.
|
|
1910
|
+
*/
|
|
1911
|
+
private loadFileNameFromPackageJsonField(
|
|
1912
|
+
extensions: number,
|
|
1913
|
+
candidate: string,
|
|
1914
|
+
packageJsonValue: string,
|
|
1915
|
+
): Resolved | undefined {
|
|
1916
|
+
if (
|
|
1917
|
+
((extensions & Extensions.TypeScript) !== 0 && hasImplementationTSFileExtension(candidate)) ||
|
|
1918
|
+
((extensions & Extensions.Declaration) !== 0 && isDeclarationFileName(candidate))
|
|
1919
|
+
) {
|
|
1920
|
+
const path = this.tryFile(candidate);
|
|
1921
|
+
if (path === undefined) return undefined;
|
|
1922
|
+
const extension = tryExtractTSExtension(path);
|
|
1923
|
+
// True when a trailing `*` matched a TS extension written in the specifier.
|
|
1924
|
+
return resolvedFile(path, extension, packageJsonValue.endsWith('*') && extension !== '');
|
|
1925
|
+
}
|
|
1926
|
+
if (this.isConfigLookup && (extensions & Extensions.Json) !== 0 && fileExtensionIs(candidate, '.json')) {
|
|
1927
|
+
const path = this.tryFile(candidate);
|
|
1928
|
+
if (path !== undefined) return resolvedFile(path, '.json', false);
|
|
1929
|
+
}
|
|
1930
|
+
return this.loadModuleFromFileNoImplicitExtensions(extensions, candidate);
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
private getPackageFile(extensions: number, packageInfo: PackageJsonInfo): string {
|
|
1934
|
+
const contents = packageInfo.contents;
|
|
1935
|
+
if (contents === undefined) return '';
|
|
1936
|
+
const directory = packageInfo.packageDirectory;
|
|
1937
|
+
if (this.isConfigLookup) return this.getPackageJsonPathField('tsconfig', contents.tsconfig, directory);
|
|
1938
|
+
if ((extensions & Extensions.Declaration) !== 0) {
|
|
1939
|
+
const typings = this.getPackageJsonPathField('typings', contents.typings, directory);
|
|
1940
|
+
if (typings !== '') return typings;
|
|
1941
|
+
const types = this.getPackageJsonPathField('types', contents.types, directory);
|
|
1942
|
+
if (types !== '') return types;
|
|
1943
|
+
}
|
|
1944
|
+
if ((extensions & (Extensions.ImplementationFiles | Extensions.Declaration)) !== 0) {
|
|
1945
|
+
return this.getPackageJsonPathField('main', contents.main, directory);
|
|
1946
|
+
}
|
|
1947
|
+
return '';
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
//// package.json
|
|
1951
|
+
|
|
1952
|
+
private getPackageJsonInfo(packageDirectory: string): PackageJsonInfo | undefined {
|
|
1953
|
+
const packageJsonPath = combinePaths(packageDirectory, 'package.json');
|
|
1954
|
+
const cache = this.resolver.packageJsonInfoCache;
|
|
1955
|
+
const existing = cache.get(packageJsonPath);
|
|
1956
|
+
if (existing !== undefined) {
|
|
1957
|
+
if (existing.contents !== undefined) {
|
|
1958
|
+
if (this.traces !== undefined)
|
|
1959
|
+
this.trace(Diagnostics.File_0_exists_according_to_earlier_cached_lookups, packageJsonPath);
|
|
1960
|
+
return withPackageDirectory(existing, packageDirectory);
|
|
1961
|
+
}
|
|
1962
|
+
if (existing.directoryExists && this.traces !== undefined) {
|
|
1963
|
+
this.trace(Diagnostics.File_0_does_not_exist_according_to_earlier_cached_lookups, packageJsonPath);
|
|
1964
|
+
}
|
|
1965
|
+
return undefined;
|
|
1966
|
+
}
|
|
1967
|
+
const directoryExists = this.host.directoryExists(packageDirectory);
|
|
1968
|
+
if (directoryExists && this.host.fileExists(packageJsonPath)) {
|
|
1969
|
+
const contents = parsePackageJson(this.host.readFile(packageJsonPath) ?? '');
|
|
1970
|
+
if (this.traces !== undefined) this.trace(Diagnostics.Found_package_json_at_0, packageJsonPath);
|
|
1971
|
+
const stored = cache.set(packageJsonPath, { packageDirectory, directoryExists: true, contents });
|
|
1972
|
+
return withPackageDirectory(stored, packageDirectory);
|
|
1973
|
+
}
|
|
1974
|
+
if (directoryExists && this.traces !== undefined) this.trace(Diagnostics.File_0_does_not_exist, packageJsonPath);
|
|
1975
|
+
cache.set(packageJsonPath, { packageDirectory, directoryExists, contents: undefined });
|
|
1976
|
+
return undefined;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
private getPackageId(resolvedFileName: string, packageInfo: PackageJsonInfo | undefined): PackageId | undefined {
|
|
1980
|
+
const contents = packageInfo?.contents;
|
|
1981
|
+
if (packageInfo === undefined || contents === undefined) return undefined;
|
|
1982
|
+
const name = contents.name.value;
|
|
1983
|
+
const version = contents.version.value;
|
|
1984
|
+
if (name === undefined || version === undefined) return undefined;
|
|
1985
|
+
const directory = packageInfo.packageDirectory;
|
|
1986
|
+
return {
|
|
1987
|
+
name,
|
|
1988
|
+
version,
|
|
1989
|
+
subModuleName: resolvedFileName.length > directory.length ? resolvedFileName.slice(directory.length + 1) : '',
|
|
1990
|
+
peerDependencies: this.readPeerDependencies(packageInfo),
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
private readPeerDependencies(packageInfo: PackageJsonInfo): string {
|
|
1995
|
+
const field = packageInfo.contents?.peerDependencies;
|
|
1996
|
+
if (field === undefined || !this.validatePackageJsonField('peerDependencies', field, 'object')) return '';
|
|
1997
|
+
const peers = field.value;
|
|
1998
|
+
if (peers === undefined || peers.size === 0) return '';
|
|
1999
|
+
if (this.traces !== undefined) this.trace(Diagnostics.X_package_json_has_a_peerDependencies_field);
|
|
2000
|
+
const packageDirectory = this.realPath(packageInfo.packageDirectory);
|
|
2001
|
+
const index = packageDirectory.lastIndexOf('/node_modules');
|
|
2002
|
+
if (index === -1) return '';
|
|
2003
|
+
const nodeModules = packageDirectory.slice(0, index + 13) + '/';
|
|
2004
|
+
const names = [...peers.keys()].sort();
|
|
2005
|
+
let result = '';
|
|
2006
|
+
for (const name of names) {
|
|
2007
|
+
const peer = this.getPackageJsonInfo(nodeModules + name);
|
|
2008
|
+
const peerContents = peer?.contents;
|
|
2009
|
+
if (peerContents !== undefined) {
|
|
2010
|
+
const version = peerContents.version.value ?? '';
|
|
2011
|
+
result += '+' + name + '@' + version;
|
|
2012
|
+
if (this.traces !== undefined) this.trace(Diagnostics.Found_peerDependency_0_with_1_version, name, version);
|
|
2013
|
+
} else if (this.traces !== undefined) {
|
|
2014
|
+
this.trace(Diagnostics.Failed_to_find_peerDependency_0, name);
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
return result;
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
private realPath(path: string): string {
|
|
2021
|
+
const real = normalizePath(this.host.realpath(path));
|
|
2022
|
+
if (this.traces !== undefined) this.trace(Diagnostics.Resolving_real_path_for_0_result_1, path, real);
|
|
2023
|
+
return real;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
private validatePackageJsonField<T>(fieldName: string, field: Expected<T>, expectedType: string): boolean {
|
|
2027
|
+
if (field.actualType !== undefined) {
|
|
2028
|
+
if (field.value !== undefined) return true;
|
|
2029
|
+
if (this.traces !== undefined) {
|
|
2030
|
+
this.trace(
|
|
2031
|
+
Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2,
|
|
2032
|
+
fieldName,
|
|
2033
|
+
expectedType,
|
|
2034
|
+
field.actualType,
|
|
2035
|
+
);
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
if (this.traces !== undefined) this.trace(Diagnostics.X_package_json_does_not_have_a_0_field, fieldName);
|
|
2039
|
+
return false;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
/** The normalized path a string field points at, or `''`. */
|
|
2043
|
+
private getPackageJsonPathField(fieldName: string, field: Expected<string>, directory: string): string {
|
|
2044
|
+
if (!this.validatePackageJsonField(fieldName, field, 'string')) return '';
|
|
2045
|
+
const value = field.value ?? '';
|
|
2046
|
+
if (value === '') {
|
|
2047
|
+
if (this.traces !== undefined) this.trace(Diagnostics.X_package_json_had_a_falsy_0_field, fieldName);
|
|
2048
|
+
return '';
|
|
2049
|
+
}
|
|
2050
|
+
const path = normalizePath(combinePaths(directory, value));
|
|
2051
|
+
if (this.traces !== undefined)
|
|
2052
|
+
this.trace(Diagnostics.X_package_json_has_0_field_1_that_references_2, fieldName, value, path);
|
|
2053
|
+
return path;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
private conditionMatches(condition: string): boolean {
|
|
2057
|
+
if (condition === 'default' || this.conditions.includes(condition)) return true;
|
|
2058
|
+
// Versioned types conditions only apply along with `types`.
|
|
2059
|
+
return this.conditions.includes('types') && isApplicableVersionedTypesKey(condition);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
const OUTPUT_EXTENSIONS: readonly string[] = ['.mjs', '.cjs', '.js', '.json', '.d.mts', '.d.cts', '.d.ts'];
|
|
2064
|
+
|
|
2065
|
+
function bundlerFeatures(options: CompilerOptions): number {
|
|
2066
|
+
let features: number = Features.BundlerDefault;
|
|
2067
|
+
if (options.resolvePackageJsonExports === true) features |= Features.Exports;
|
|
2068
|
+
else if (options.resolvePackageJsonExports === false) features &= ~Features.Exports;
|
|
2069
|
+
if (options.resolvePackageJsonImports === true) features |= Features.Imports;
|
|
2070
|
+
else if (options.resolvePackageJsonImports === false) features &= ~Features.Imports;
|
|
2071
|
+
return features;
|
|
2072
|
+
}
|