tsc-ts 0.0.9 → 0.1.0
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 +2 -2
- package/bin/tsc-ts.js +70 -1
- package/dist/api/compiler/ast-utilities.d.ts +19 -1
- package/dist/api/compiler/ast-utilities.js +180 -95
- package/dist/api/compiler/ast.d.ts +22 -15
- package/dist/api/compiler/ast.js +1026 -995
- package/dist/api/compiler/astnav.js +15 -15
- package/dist/api/compiler/binder-utilities.js +186 -186
- package/dist/api/compiler/binder.js +290 -263
- package/dist/api/compiler/character-codes.js +2 -2
- package/dist/api/compiler/checker-calls.js +178 -124
- package/dist/api/compiler/checker-classes.d.ts +14 -3
- package/dist/api/compiler/checker-classes.js +134 -90
- package/dist/api/compiler/checker-contextual.js +64 -61
- package/dist/api/compiler/checker-declaration-order.js +79 -79
- package/dist/api/compiler/checker-declarations.d.ts +1 -0
- package/dist/api/compiler/checker-declarations.js +160 -136
- package/dist/api/compiler/checker-declared-types.js +67 -65
- package/dist/api/compiler/checker-decorators.js +77 -77
- package/dist/api/compiler/checker-deprecation.d.ts +8 -3
- package/dist/api/compiler/checker-deprecation.js +76 -55
- package/dist/api/compiler/checker-destructuring.js +47 -45
- package/dist/api/compiler/checker-elaboration.js +24 -24
- package/dist/api/compiler/checker-emit-helpers.js +4 -4
- package/dist/api/compiler/checker-emit-resolver.d.ts +4 -2
- package/dist/api/compiler/checker-emit-resolver.js +25 -13
- package/dist/api/compiler/checker-evaluator.js +9 -9
- package/dist/api/compiler/checker-expressions.js +244 -211
- package/dist/api/compiler/checker-functions.js +113 -107
- package/dist/api/compiler/checker-generated-code.d.ts +0 -11
- package/dist/api/compiler/checker-generated-code.js +28 -52
- package/dist/api/compiler/checker-grammar.d.ts +1 -0
- package/dist/api/compiler/checker-grammar.js +472 -440
- package/dist/api/compiler/checker-heritage.js +91 -93
- package/dist/api/compiler/checker-inference.d.ts +77 -5
- package/dist/api/compiler/checker-inference.js +487 -107
- package/dist/api/compiler/checker-iteration.d.ts +0 -10
- package/dist/api/compiler/checker-iteration.js +35 -52
- package/dist/api/compiler/checker-javascript.js +14 -14
- package/dist/api/compiler/checker-jsdoc.d.ts +8 -10
- package/dist/api/compiler/checker-jsdoc.js +67 -58
- package/dist/api/compiler/checker-jsx.js +105 -88
- package/dist/api/compiler/checker-members.d.ts +9 -2
- package/dist/api/compiler/checker-members.js +212 -75
- package/dist/api/compiler/checker-modules.d.ts +15 -6
- package/dist/api/compiler/checker-modules.js +469 -309
- package/dist/api/compiler/checker-narrowing.js +273 -189
- package/dist/api/compiler/checker-object-literals.js +25 -22
- package/dist/api/compiler/checker-operators.js +126 -118
- package/dist/api/compiler/checker-overloads.js +27 -27
- package/dist/api/compiler/checker-property-access.js +59 -55
- package/dist/api/compiler/checker-services.d.ts +1 -0
- package/dist/api/compiler/checker-services.js +222 -210
- package/dist/api/compiler/checker-signatures.js +65 -49
- package/dist/api/compiler/checker-source-file.d.ts +5 -0
- package/dist/api/compiler/checker-source-file.js +154 -130
- package/dist/api/compiler/checker-statements.js +33 -32
- package/dist/api/compiler/checker-super.js +50 -50
- package/dist/api/compiler/checker-symbol-types.js +109 -93
- package/dist/api/compiler/checker-symbols.d.ts +13 -1
- package/dist/api/compiler/checker-symbols.js +264 -149
- package/dist/api/compiler/checker-type-factory.d.ts +5 -0
- package/dist/api/compiler/checker-type-factory.js +145 -36
- package/dist/api/compiler/checker-type-nodes.d.ts +1 -0
- package/dist/api/compiler/checker-type-nodes.js +179 -141
- package/dist/api/compiler/checker-type-operators.d.ts +2 -0
- package/dist/api/compiler/checker-type-operators.js +110 -63
- package/dist/api/compiler/checker-types.d.ts +80 -3
- package/dist/api/compiler/checker-types.js +121 -2
- package/dist/api/compiler/checker-unused.js +114 -118
- package/dist/api/compiler/checker-utilities.js +11 -11
- package/dist/api/compiler/checker.d.ts +104 -31
- package/dist/api/compiler/checker.js +181 -33
- package/dist/api/compiler/command-line.d.ts +1 -3
- package/dist/api/compiler/command-line.js +47 -44
- package/dist/api/compiler/compile-program.d.ts +42 -3
- package/dist/api/compiler/compile-program.js +139 -27
- package/dist/api/compiler/diagnostic-messages.d.ts +1849 -1774
- package/dist/api/compiler/diagnostic-messages.js +128 -122
- package/dist/api/compiler/diagnostics.d.ts +22 -0
- package/dist/api/compiler/diagnostics.js +93 -11
- package/dist/api/compiler/emitter.d.ts +7 -1
- package/dist/api/compiler/emitter.js +53 -11
- package/dist/api/compiler/file-include.d.ts +2 -1
- package/dist/api/compiler/file-include.js +11 -7
- package/dist/api/compiler/file-loader.d.ts +21 -1
- package/dist/api/compiler/file-loader.js +201 -48
- package/dist/api/compiler/instantiation.d.ts +7 -0
- package/dist/api/compiler/instantiation.js +101 -49
- package/dist/api/compiler/jsdoc.js +23 -23
- package/dist/api/compiler/link-tables.d.ts +48 -18
- package/dist/api/compiler/link-tables.js +80 -37
- package/dist/api/compiler/locales/cs-CZ.d.ts +1 -1
- package/dist/api/compiler/locales/cs-CZ.js +1 -1
- package/dist/api/compiler/locales/de-DE.d.ts +1 -1
- package/dist/api/compiler/locales/de-DE.js +1 -1
- package/dist/api/compiler/locales/es-ES.d.ts +1 -1
- package/dist/api/compiler/locales/es-ES.js +1 -1
- package/dist/api/compiler/locales/fr-FR.d.ts +1 -1
- package/dist/api/compiler/locales/fr-FR.js +1 -1
- package/dist/api/compiler/locales/it-IT.d.ts +1 -1
- package/dist/api/compiler/locales/it-IT.js +1 -1
- package/dist/api/compiler/locales/ja-JP.d.ts +1 -1
- package/dist/api/compiler/locales/ja-JP.js +1 -1
- package/dist/api/compiler/locales/ko-KR.d.ts +1 -1
- package/dist/api/compiler/locales/ko-KR.js +1 -1
- package/dist/api/compiler/locales/pl-PL.d.ts +1 -1
- package/dist/api/compiler/locales/pl-PL.js +1 -1
- package/dist/api/compiler/locales/pt-BR.d.ts +1 -1
- package/dist/api/compiler/locales/pt-BR.js +1 -1
- package/dist/api/compiler/locales/ru-RU.d.ts +1 -1
- package/dist/api/compiler/locales/ru-RU.js +1 -1
- package/dist/api/compiler/locales/tr-TR.d.ts +1 -1
- package/dist/api/compiler/locales/tr-TR.js +1 -1
- package/dist/api/compiler/locales/zh-CN.d.ts +1 -1
- package/dist/api/compiler/locales/zh-CN.js +1 -1
- package/dist/api/compiler/locales/zh-TW.d.ts +1 -1
- package/dist/api/compiler/locales/zh-TW.js +1 -1
- package/dist/api/compiler/module-resolution-types.js +6 -6
- package/dist/api/compiler/module-resolution.d.ts +10 -1
- package/dist/api/compiler/module-resolution.js +115 -84
- package/dist/api/compiler/module-specifiers.d.ts +15 -0
- package/dist/api/compiler/module-specifiers.js +24 -18
- package/dist/api/compiler/name-resolver.js +74 -65
- package/dist/api/compiler/node-builder-names.d.ts +11 -3
- package/dist/api/compiler/node-builder-names.js +210 -90
- package/dist/api/compiler/node-builder-pseudo.js +29 -31
- package/dist/api/compiler/node-builder-reuse.js +23 -22
- package/dist/api/compiler/node-builder.d.ts +18 -1
- package/dist/api/compiler/node-builder.js +191 -102
- package/dist/api/compiler/option-declarations.d.ts +2 -6
- package/dist/api/compiler/option-declarations.js +315 -375
- package/dist/api/compiler/options.d.ts +15 -33
- package/dist/api/compiler/options.js +21 -54
- package/dist/api/compiler/output-paths.d.ts +4 -1
- package/dist/api/compiler/output-paths.js +6 -11
- package/dist/api/compiler/package-json.d.ts +3 -3
- package/dist/api/compiler/package-json.js +11 -10
- package/dist/api/compiler/parallel-parse.d.ts +3 -2
- package/dist/api/compiler/parallel-parse.js +17 -5
- package/dist/api/compiler/parser.d.ts +40 -19
- package/dist/api/compiler/parser.js +308 -216
- package/dist/api/compiler/path.d.ts +9 -0
- package/dist/api/compiler/path.js +20 -3
- package/dist/api/compiler/printer/emit-context.d.ts +5 -1
- package/dist/api/compiler/printer/emit-context.js +20 -1
- package/dist/api/compiler/printer/factory-base.d.ts +2 -2
- package/dist/api/compiler/printer/factory-base.js +7 -3
- package/dist/api/compiler/printer/factory.js +3 -1
- package/dist/api/compiler/printer/helpers.js +10 -1
- package/dist/api/compiler/printer/name-generator.d.ts +1 -1
- package/dist/api/compiler/printer/name-generator.js +35 -16
- package/dist/api/compiler/printer/printer.d.ts +49 -2
- package/dist/api/compiler/printer/printer.js +539 -293
- package/dist/api/compiler/printer/utilities.js +149 -147
- package/dist/api/compiler/program-checker.d.ts +12 -2
- package/dist/api/compiler/program-checker.js +88 -34
- package/dist/api/compiler/program-utilities.d.ts +3 -1
- package/dist/api/compiler/program-utilities.js +28 -15
- package/dist/api/compiler/program.d.ts +4 -6
- package/dist/api/compiler/program.js +74 -87
- package/dist/api/compiler/pseudo-bigint.d.ts +2 -0
- package/dist/api/compiler/pseudo-bigint.js +18 -0
- package/dist/api/compiler/regexp-checker.d.ts +1 -1
- package/dist/api/compiler/regexp-checker.js +93 -76
- package/dist/api/compiler/relations.d.ts +27 -4
- package/dist/api/compiler/relations.js +347 -180
- package/dist/api/compiler/reparser.js +60 -56
- package/dist/api/compiler/scanner.d.ts +19 -2
- package/dist/api/compiler/scanner.js +123 -108
- package/dist/api/compiler/shared-results.d.ts +463 -0
- package/dist/api/compiler/shared-results.js +2128 -0
- package/dist/api/compiler/sourcemap.js +2 -2
- package/dist/api/compiler/symbol-accessibility.js +87 -74
- package/dist/api/compiler/symbol.d.ts +23 -14
- package/dist/api/compiler/symbol.js +23 -11
- package/dist/api/compiler/syntax-kind.d.ts +198 -197
- package/dist/api/compiler/transformers/alias-references.js +247 -139
- package/dist/api/compiler/transformers/async-utilities.js +25 -25
- package/dist/api/compiler/transformers/async.d.ts +0 -1
- package/dist/api/compiler/transformers/async.js +64 -77
- package/dist/api/compiler/transformers/class-fields.d.ts +1 -0
- package/dist/api/compiler/transformers/class-fields.js +81 -78
- package/dist/api/compiler/transformers/commonjs-module.js +18 -15
- package/dist/api/compiler/transformers/const-enum-inliner.js +1 -1
- package/dist/api/compiler/transformers/declarations-diagnostics.js +247 -244
- package/dist/api/compiler/transformers/declarations-pseudo.js +100 -100
- package/dist/api/compiler/transformers/declarations-resolver.d.ts +0 -3
- package/dist/api/compiler/transformers/declarations-syntactic.d.ts +1 -2
- package/dist/api/compiler/transformers/declarations-syntactic.js +134 -156
- package/dist/api/compiler/transformers/declarations-tracker.js +18 -18
- package/dist/api/compiler/transformers/declarations.d.ts +4 -1
- package/dist/api/compiler/transformers/declarations.js +305 -238
- package/dist/api/compiler/transformers/decorator-metadata.d.ts +1 -1
- package/dist/api/compiler/transformers/decorator-metadata.js +53 -45
- package/dist/api/compiler/transformers/decorator-utilities.js +24 -24
- package/dist/api/compiler/transformers/destructuring.js +19 -18
- package/dist/api/compiler/transformers/emit-resolver.js +1 -1
- package/dist/api/compiler/transformers/es-decorators.js +55 -55
- package/dist/api/compiler/transformers/external-module-info.js +3 -3
- package/dist/api/compiler/transformers/for-await.js +25 -25
- package/dist/api/compiler/transformers/import-elision.js +14 -14
- package/dist/api/compiler/transformers/jsx.js +12 -12
- package/dist/api/compiler/transformers/legacy-decorators.js +17 -17
- package/dist/api/compiler/transformers/module.js +8 -8
- package/dist/api/compiler/transformers/named-evaluation.js +4 -4
- package/dist/api/compiler/transformers/object-rest-spread.js +20 -20
- package/dist/api/compiler/transformers/optional-chain.js +10 -10
- package/dist/api/compiler/transformers/reference-resolver.d.ts +12 -1
- package/dist/api/compiler/transformers/reference-resolver.js +131 -69
- package/dist/api/compiler/transformers/runtime-syntax.js +35 -31
- package/dist/api/compiler/transformers/subtree-facts.js +47 -47
- package/dist/api/compiler/transformers/syntax-facts.js +56 -58
- package/dist/api/compiler/transformers/type-eraser.js +73 -66
- package/dist/api/compiler/transformers/type-serialization.js +24 -24
- package/dist/api/compiler/transformers/using.js +12 -12
- package/dist/api/compiler/transformers/utilities.js +77 -77
- package/dist/api/compiler/transformers/visitor-base.js +172 -172
- package/dist/api/compiler/transformers/visitor-hooks.js +6 -2
- package/dist/api/compiler/tsconfig.d.ts +10 -2
- package/dist/api/compiler/tsconfig.js +136 -48
- package/dist/api/compiler/type-printer.js +40 -3
- package/dist/api/compiler/types.d.ts +2 -1
- package/dist/api/library/ast.generated.d.ts +42 -39
- package/dist/api/library/ast.generated.js +1 -1
- package/dist/api/library/compiler-options.generated.d.ts +111 -100
- package/dist/api/library/compiler-options.generated.js +1 -1
- package/dist/api/library/disk.js +12 -1
- package/dist/api/library/enums.generated.d.ts +206 -206
- package/dist/api/library/enums.generated.js +206 -206
- package/dist/api/library/nodes.js +26 -26
- package/package.json +9 -9
- package/src/compiler/ast-utilities.ts +99 -7
- package/src/compiler/ast.ts +58 -26
- package/src/compiler/binder.ts +39 -4
- package/src/compiler/character-codes.ts +2 -2
- package/src/compiler/checker-calls.ts +79 -9
- package/src/compiler/checker-classes.ts +78 -24
- package/src/compiler/checker-contextual.ts +6 -1
- package/src/compiler/checker-declarations.ts +31 -4
- package/src/compiler/checker-declared-types.ts +8 -5
- package/src/compiler/checker-decorators.ts +1 -1
- package/src/compiler/checker-deprecation.ts +29 -8
- package/src/compiler/checker-destructuring.ts +10 -3
- package/src/compiler/checker-emit-helpers.ts +1 -0
- package/src/compiler/checker-emit-resolver.ts +16 -6
- package/src/compiler/checker-expressions.ts +79 -46
- package/src/compiler/checker-functions.ts +21 -6
- package/src/compiler/checker-generated-code.ts +2 -22
- package/src/compiler/checker-grammar.ts +136 -62
- package/src/compiler/checker-heritage.ts +22 -21
- package/src/compiler/checker-inference.ts +514 -82
- package/src/compiler/checker-iteration.ts +18 -31
- package/src/compiler/checker-javascript.ts +1 -1
- package/src/compiler/checker-jsdoc.ts +50 -27
- package/src/compiler/checker-jsx.ts +26 -4
- package/src/compiler/checker-members.ts +200 -56
- package/src/compiler/checker-modules.ts +332 -65
- package/src/compiler/checker-narrowing.ts +98 -19
- package/src/compiler/checker-object-literals.ts +3 -0
- package/src/compiler/checker-operators.ts +11 -4
- package/src/compiler/checker-property-access.ts +7 -2
- package/src/compiler/checker-services.ts +39 -12
- package/src/compiler/checker-signatures.ts +15 -1
- package/src/compiler/checker-source-file.ts +39 -13
- package/src/compiler/checker-statements.ts +3 -2
- package/src/compiler/checker-symbol-types.ts +29 -6
- package/src/compiler/checker-symbols.ts +158 -15
- package/src/compiler/checker-type-factory.ts +124 -23
- package/src/compiler/checker-type-nodes.ts +46 -3
- package/src/compiler/checker-type-operators.ts +83 -26
- package/src/compiler/checker-types.ts +147 -4
- package/src/compiler/checker-unused.ts +9 -14
- package/src/compiler/checker.ts +203 -39
- package/src/compiler/command-line.ts +28 -28
- package/src/compiler/compile-program.ts +167 -27
- package/src/compiler/decoder.ts +13 -4
- package/src/compiler/diagnostic-messages.ts +1973 -1892
- package/src/compiler/diagnostics.ts +84 -3
- package/src/compiler/emitter.ts +57 -8
- package/src/compiler/encoder.ts +23 -8
- package/src/compiler/file-include.ts +9 -3
- package/src/compiler/file-loader.ts +197 -38
- package/src/compiler/help.ts +10 -14
- package/src/compiler/incremental.ts +165 -30
- package/src/compiler/init.ts +2 -7
- package/src/compiler/instantiation.ts +77 -22
- package/src/compiler/jsdoc.ts +3 -1
- package/src/compiler/link-tables.ts +82 -37
- package/src/compiler/locales/cs-CZ.ts +1 -1
- package/src/compiler/locales/de-DE.ts +1 -1
- package/src/compiler/locales/es-ES.ts +1 -1
- package/src/compiler/locales/fr-FR.ts +1 -1
- package/src/compiler/locales/it-IT.ts +1 -1
- package/src/compiler/locales/ja-JP.ts +1 -1
- package/src/compiler/locales/ko-KR.ts +1 -1
- package/src/compiler/locales/pl-PL.ts +1 -1
- package/src/compiler/locales/pt-BR.ts +1 -1
- package/src/compiler/locales/ru-RU.ts +1 -1
- package/src/compiler/locales/tr-TR.ts +1 -1
- package/src/compiler/locales/zh-CN.ts +1 -1
- package/src/compiler/locales/zh-TW.ts +1 -1
- package/src/compiler/module-resolution.ts +44 -8
- package/src/compiler/module-specifiers.ts +62 -20
- package/src/compiler/name-resolver.ts +9 -1
- package/src/compiler/node-builder-names.ts +236 -54
- package/src/compiler/node-builder-pseudo.ts +4 -7
- package/src/compiler/node-builder-reuse.ts +5 -4
- package/src/compiler/node-builder.ts +130 -31
- package/src/compiler/option-declarations.ts +33 -103
- package/src/compiler/options.ts +23 -62
- package/src/compiler/output-paths.ts +5 -18
- package/src/compiler/package-entrypoints.ts +345 -0
- package/src/compiler/package-json.ts +4 -4
- package/src/compiler/parallel-check.ts +326 -52
- package/src/compiler/parallel-emit.ts +320 -0
- package/src/compiler/parallel-parse.ts +16 -5
- package/src/compiler/parse-thread.ts +3 -0
- package/src/compiler/parser.ts +156 -39
- package/src/compiler/path.ts +22 -2
- package/src/compiler/printer/emit-context.ts +21 -0
- package/src/compiler/printer/factory-base.ts +10 -3
- package/src/compiler/printer/factory.ts +4 -1
- package/src/compiler/printer/helpers.ts +10 -1
- package/src/compiler/printer/name-generator.ts +24 -2
- package/src/compiler/printer/printer.ts +266 -30
- package/src/compiler/printer/utilities.ts +8 -2
- package/src/compiler/program-checker.ts +57 -5
- package/src/compiler/program-utilities.ts +23 -10
- package/src/compiler/program.ts +18 -26
- package/src/compiler/pseudo-bigint.ts +17 -0
- package/src/compiler/regexp-checker.ts +63 -30
- package/src/compiler/relations.ts +240 -77
- package/src/compiler/reparser.ts +7 -2
- package/src/compiler/scanner.ts +109 -79
- package/src/compiler/shared-results.ts +2414 -0
- package/src/compiler/show-config.ts +18 -1
- package/src/compiler/sourcemap.ts +2 -2
- package/src/compiler/symbol-accessibility.ts +26 -3
- package/src/compiler/symbol.ts +46 -24
- package/src/compiler/syntax-kind.ts +188 -187
- package/src/compiler/thread-entry.ts +64 -4
- package/src/compiler/transformers/alias-references.ts +123 -4
- package/src/compiler/transformers/async.ts +2 -17
- package/src/compiler/transformers/class-fields.ts +13 -12
- package/src/compiler/transformers/commonjs-module.ts +11 -7
- package/src/compiler/transformers/declarations-diagnostics.ts +5 -3
- package/src/compiler/transformers/declarations-pseudo.ts +2 -4
- package/src/compiler/transformers/declarations-resolver.ts +0 -3
- package/src/compiler/transformers/declarations-syntactic.ts +1 -21
- package/src/compiler/transformers/declarations.ts +134 -48
- package/src/compiler/transformers/decorator-metadata.ts +9 -1
- package/src/compiler/transformers/destructuring.ts +4 -3
- package/src/compiler/transformers/external-module-info.ts +1 -1
- package/src/compiler/transformers/jsx.ts +2 -1
- package/src/compiler/transformers/reference-resolver.ts +83 -19
- package/src/compiler/transformers/runtime-syntax.ts +6 -1
- package/src/compiler/transformers/syntax-facts.ts +2 -7
- package/src/compiler/transformers/type-eraser.ts +10 -1
- package/src/compiler/transformers/type-serialization.ts +3 -2
- package/src/compiler/transformers/visitor-base.ts +2 -1
- package/src/compiler/transformers/visitor-hooks.ts +9 -4
- package/src/compiler/tsc-build.ts +66 -9
- package/src/compiler/tsc-cli.ts +7 -0
- package/src/compiler/tsc-compile.ts +284 -4
- package/src/compiler/tsc-watch.ts +74 -45
- package/src/compiler/tsconfig.ts +176 -19
- package/src/compiler/type-printer.ts +36 -2
- package/src/compiler/types.ts +2 -1
- package/src/library/ast.generated.ts +57 -41
- package/src/library/compiler-options.generated.ts +117 -103
- package/src/library/disk.ts +10 -1
- package/src/library/enums.generated.ts +196 -196
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type TypeParameterDeclaration,
|
|
13
13
|
type ConditionalTypeNode,
|
|
14
14
|
} from './ast.js';
|
|
15
|
+
import { isInJSFile } from './ast-utilities.js';
|
|
15
16
|
import { hasSyntacticModifier } from './binder-utilities.js';
|
|
16
17
|
import { SyntaxKind } from './syntax-kind.js';
|
|
17
18
|
import type { Checker } from './checker.js';
|
|
@@ -50,6 +51,7 @@ import {
|
|
|
50
51
|
newTypeMapper,
|
|
51
52
|
SimpleTypeMapper,
|
|
52
53
|
emptyTypes,
|
|
54
|
+
getNonDistributedTypeParameter,
|
|
53
55
|
} from './checker-types.js';
|
|
54
56
|
import {
|
|
55
57
|
UnionReduction,
|
|
@@ -88,6 +90,7 @@ import {
|
|
|
88
90
|
someType,
|
|
89
91
|
tupleTargetOf,
|
|
90
92
|
typesOf,
|
|
93
|
+
compareTypes,
|
|
91
94
|
} from './checker-type-factory.js';
|
|
92
95
|
import {
|
|
93
96
|
getDeclaredTypeOfClassOrInterface,
|
|
@@ -124,6 +127,7 @@ import {
|
|
|
124
127
|
isNoInferType,
|
|
125
128
|
isTypeMatchedByTemplateLiteralType,
|
|
126
129
|
shouldDeferIndexType,
|
|
130
|
+
type TemplateTypeComparer,
|
|
127
131
|
} from './checker-type-operators.js';
|
|
128
132
|
import {
|
|
129
133
|
getApparentType,
|
|
@@ -180,7 +184,9 @@ import {
|
|
|
180
184
|
getUnmatchedProperty,
|
|
181
185
|
getVariances,
|
|
182
186
|
isUnmatchedProperty,
|
|
187
|
+
isDeeplyNestedStackEntry,
|
|
183
188
|
isDeeplyNestedType,
|
|
189
|
+
type RecursionId,
|
|
184
190
|
setStackEntry,
|
|
185
191
|
isObjectTypeWithInferableIndex,
|
|
186
192
|
isTypeAssignableTo,
|
|
@@ -190,7 +196,12 @@ import {
|
|
|
190
196
|
} from './relations.js';
|
|
191
197
|
import { maybeTypeOfKind } from './checker-utilities.js';
|
|
192
198
|
import { getTypeFromTypeNode } from './checker-type-nodes.js';
|
|
193
|
-
import {
|
|
199
|
+
import {
|
|
200
|
+
findResolutionCycleStartIndex,
|
|
201
|
+
getMergedSymbol,
|
|
202
|
+
getSymbolOfDeclaration,
|
|
203
|
+
TypeSystemPropertyName,
|
|
204
|
+
} from './checker-symbols.js';
|
|
194
205
|
import { parsePseudoBigInt } from './pseudo-bigint.js';
|
|
195
206
|
import { getContextualTypeForInference } from './checker-contextual.js';
|
|
196
207
|
import {
|
|
@@ -211,6 +222,8 @@ export const enum InferenceFlags {
|
|
|
211
222
|
AnyDefault = 1 << 1,
|
|
212
223
|
/** A generic function was skipped during inference. */
|
|
213
224
|
SkippedGenericFunction = 1 << 2,
|
|
225
|
+
/** Inferences other than pure return type inferences are not filtered by their constraints. */
|
|
226
|
+
NoConstraintChecks = 1 << 3,
|
|
214
227
|
}
|
|
215
228
|
|
|
216
229
|
export const enum InferencePriority {
|
|
@@ -247,14 +260,12 @@ const enum ExpandingFlags {
|
|
|
247
260
|
// Shared empty candidate lists: an InferenceInfo gets its own on its first candidate, as tsgo's nil
|
|
248
261
|
// slices do. Never changed.
|
|
249
262
|
const noCandidates: Type[] = [];
|
|
250
|
-
const noCandidateDepths: number[] = [];
|
|
251
263
|
|
|
252
264
|
/** Inferences for one type parameter. */
|
|
253
265
|
export class InferenceInfo {
|
|
254
266
|
readonly typeParameter: Type;
|
|
255
|
-
/** Covariant candidates
|
|
267
|
+
/** Covariant candidates. */
|
|
256
268
|
candidates: Type[] = noCandidates;
|
|
257
|
-
candidateDepths: number[] = noCandidateDepths;
|
|
258
269
|
contraCandidates: Type[] = noCandidates;
|
|
259
270
|
inferredType: Type | undefined = undefined;
|
|
260
271
|
priority: InferencePriority = InferencePriority.MaxValue;
|
|
@@ -269,10 +280,7 @@ export class InferenceInfo {
|
|
|
269
280
|
|
|
270
281
|
clone(): InferenceInfo {
|
|
271
282
|
const info = new InferenceInfo(this.typeParameter);
|
|
272
|
-
if (this.candidates.length !== 0)
|
|
273
|
-
info.candidates = this.candidates.slice();
|
|
274
|
-
info.candidateDepths = this.candidateDepths.slice();
|
|
275
|
-
}
|
|
283
|
+
if (this.candidates.length !== 0) info.candidates = this.candidates.slice();
|
|
276
284
|
if (this.contraCandidates.length !== 0) info.contraCandidates = this.contraCandidates.slice();
|
|
277
285
|
info.inferredType = this.inferredType;
|
|
278
286
|
info.priority = this.priority;
|
|
@@ -488,10 +496,268 @@ export function inferTypes(
|
|
|
488
496
|
state.inferFromTypes(source, target);
|
|
489
497
|
}
|
|
490
498
|
|
|
499
|
+
/** Whether no inference has a candidate or an inferred type, or is fixed, as in a new context. */
|
|
500
|
+
function isUnstarted(inferences: readonly InferenceInfo[]): boolean {
|
|
501
|
+
for (const i of inferences)
|
|
502
|
+
if (i.candidates.length !== 0 || i.contraCandidates.length !== 0 || i.inferredType !== undefined || i.isFixed)
|
|
503
|
+
return false;
|
|
504
|
+
return true;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const enum UnstartedInferenceState {
|
|
508
|
+
/** Walked once, which may have resolved the types the walk reaches. Nothing is kept. */
|
|
509
|
+
Seen,
|
|
510
|
+
/** Walked twice; the second walk created no types and left `inferences`. */
|
|
511
|
+
Walked,
|
|
512
|
+
/** A third walk did the same as the second, so later walks are skipped. */
|
|
513
|
+
Confirmed,
|
|
514
|
+
/** Always walked: walks differed or created types, or one reported a diagnostic or met a circularity. */
|
|
515
|
+
Unusable,
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/** A memoized `inferTypesFromUnstarted` walk. */
|
|
519
|
+
export class UnstartedInference {
|
|
520
|
+
readonly state: UnstartedInferenceState;
|
|
521
|
+
readonly inferences: InferenceInfo[];
|
|
522
|
+
/** The instantiations the walk does, which a skipped walk adds to the counts. */
|
|
523
|
+
readonly instantiations: number;
|
|
524
|
+
/** The instantiation depth the confirming walk started at: a walk starting deeper might reach the limit. */
|
|
525
|
+
readonly depth: number;
|
|
526
|
+
/** The variance reliability flags the walk reports. */
|
|
527
|
+
readonly reliabilityFlags: number;
|
|
528
|
+
/** The unions and intersections the walk searched before their properties were resolved. */
|
|
529
|
+
readonly searched: readonly Type[];
|
|
530
|
+
|
|
531
|
+
constructor(
|
|
532
|
+
state: UnstartedInferenceState,
|
|
533
|
+
inferences: InferenceInfo[],
|
|
534
|
+
instantiations: number,
|
|
535
|
+
depth: number,
|
|
536
|
+
reliabilityFlags: number,
|
|
537
|
+
searched: readonly Type[],
|
|
538
|
+
) {
|
|
539
|
+
this.state = state;
|
|
540
|
+
this.inferences = inferences;
|
|
541
|
+
this.instantiations = instantiations;
|
|
542
|
+
this.depth = depth;
|
|
543
|
+
this.reliabilityFlags = reliabilityFlags;
|
|
544
|
+
this.searched = searched;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const verifyUnstartedInferences = process.env['TSC_TS_VERIFY_INFERENCE_MEMO'] === '1';
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* `inferTypes` into the inferences for `signature`'s type parameters, to `target`, which is
|
|
552
|
+
* determined by `signature` (its return type). When no inference has started, the walk depends only
|
|
553
|
+
* on `signature`, `source` and `priority`, so it is memoized per checker. Contextual return type
|
|
554
|
+
* inference repeats the same walk for calls of a generic function with the same contextual type at
|
|
555
|
+
* different call sites.
|
|
556
|
+
*
|
|
557
|
+
* A walk is skipped only when it would add nothing but the inferences:
|
|
558
|
+
* - Once a second and a third walk have both created no types or signatures and done the same. The
|
|
559
|
+
* first walk resolves the types it reaches; only walks that repeat keep their inferences.
|
|
560
|
+
* - With the instantiation count and depth replayed. The walk is skipped only where it could not
|
|
561
|
+
* reach the instantiation limits.
|
|
562
|
+
* - With the variance reliability flags replayed.
|
|
563
|
+
* - Never when a walk reported a diagnostic or met a circularity. Never during a variance
|
|
564
|
+
* computation, where relations are not cached and circularities are found differently.
|
|
565
|
+
* - Only while the unions and intersections whose unresolved properties the walk searched
|
|
566
|
+
* (hasUnmatchedProperty) are still unresolved. Once they are resolved, the same walk creates the
|
|
567
|
+
* property types, so it is learned again.
|
|
568
|
+
*/
|
|
569
|
+
export function inferTypesFromUnstarted(
|
|
570
|
+
c: Checker,
|
|
571
|
+
signature: Signature,
|
|
572
|
+
inferences: InferenceInfo[],
|
|
573
|
+
source: Type,
|
|
574
|
+
target: Type,
|
|
575
|
+
priority: InferencePriority,
|
|
576
|
+
): void {
|
|
577
|
+
if (c.varianceStack.length !== 0 || !isUnstarted(inferences)) {
|
|
578
|
+
inferTypes(c, inferences, source, target, priority, false);
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const caches = c.inferenceCaches;
|
|
582
|
+
const memo = caches.unstartedInferences;
|
|
583
|
+
let bySource = memo.get(signature.id);
|
|
584
|
+
if (bySource === undefined) {
|
|
585
|
+
bySource = new Map<number, UnstartedInference>();
|
|
586
|
+
memo.set(signature.id, bySource);
|
|
587
|
+
}
|
|
588
|
+
const key = source.id * 4096 + priority;
|
|
589
|
+
let known = bySource.get(key);
|
|
590
|
+
if (known !== undefined && known.state === UnstartedInferenceState.Confirmed) {
|
|
591
|
+
if (havePropertiesResolved(c, known.searched)) {
|
|
592
|
+
// Learn the walk again for the resolved properties; each union's properties are resolved once.
|
|
593
|
+
bySource.delete(key);
|
|
594
|
+
known = undefined;
|
|
595
|
+
} else if (c.instantiationDepth <= known.depth && c.instantiationCount + known.instantiations < 5000000) {
|
|
596
|
+
if (verifyUnstartedInferences) verifyUnstartedInference(c, signature, known, source, target, priority);
|
|
597
|
+
copyInferences(inferences, known.inferences);
|
|
598
|
+
const outer = c.unresolvedPropertySearches;
|
|
599
|
+
if (outer !== undefined) for (const t of known.searched) outer.push(t);
|
|
600
|
+
c.instantiationCount += known.instantiations;
|
|
601
|
+
c.totalInstantiations += known.instantiations;
|
|
602
|
+
c.reliabilityFlags |= known.reliabilityFlags;
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
const reports = c.reports;
|
|
607
|
+
const cycles = c.resolutionCycleCount;
|
|
608
|
+
const outerSearches = c.unresolvedPropertySearches;
|
|
609
|
+
const searches: Type[] = [];
|
|
610
|
+
c.unresolvedPropertySearches = searches;
|
|
611
|
+
const types = c.typeCount;
|
|
612
|
+
const signatures = c.signatureCount;
|
|
613
|
+
const count = c.instantiationCount;
|
|
614
|
+
const total = c.totalInstantiations;
|
|
615
|
+
const depth = c.instantiationDepth;
|
|
616
|
+
const reliabilityFlags = c.reliabilityFlags;
|
|
617
|
+
// Nothing reads the flags before setting them, so the walk's own are those it leaves from zero.
|
|
618
|
+
c.reliabilityFlags = 0;
|
|
619
|
+
inferTypes(c, inferences, source, target, priority, false);
|
|
620
|
+
const walkFlags = c.reliabilityFlags;
|
|
621
|
+
c.reliabilityFlags = reliabilityFlags | walkFlags;
|
|
622
|
+
c.unresolvedPropertySearches = outerSearches;
|
|
623
|
+
// An enclosing walk depends on the searches of the walks within it.
|
|
624
|
+
if (outerSearches !== undefined) for (const t of searches) outerSearches.push(t);
|
|
625
|
+
const state = known === undefined ? undefined : known.state;
|
|
626
|
+
if (state === UnstartedInferenceState.Confirmed || state === UnstartedInferenceState.Unusable) return;
|
|
627
|
+
const instantiations = c.totalInstantiations - total;
|
|
628
|
+
if (c.reports !== reports || c.resolutionCycleCount !== cycles || c.instantiationCount - count !== instantiations) {
|
|
629
|
+
bySource.set(key, caches.alwaysWalked);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if (state === undefined) {
|
|
633
|
+
bySource.set(key, caches.seenOnce);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (c.typeCount !== types || c.signatureCount !== signatures) {
|
|
637
|
+
bySource.set(key, caches.alwaysWalked);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
const searched = searches.length === 0 ? searches : [...new Set(searches)];
|
|
641
|
+
if (state === UnstartedInferenceState.Seen) {
|
|
642
|
+
const snapshot: InferenceInfo[] = [];
|
|
643
|
+
for (const i of inferences) snapshot.push(i.clone());
|
|
644
|
+
bySource.set(
|
|
645
|
+
key,
|
|
646
|
+
new UnstartedInference(UnstartedInferenceState.Walked, snapshot, instantiations, depth, walkFlags, searched),
|
|
647
|
+
);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
bySource.set(
|
|
651
|
+
key,
|
|
652
|
+
sameInferences(inferences, known!.inferences) &&
|
|
653
|
+
instantiations === known!.instantiations &&
|
|
654
|
+
walkFlags === known!.reliabilityFlags
|
|
655
|
+
? new UnstartedInference(
|
|
656
|
+
UnstartedInferenceState.Confirmed,
|
|
657
|
+
known!.inferences,
|
|
658
|
+
instantiations,
|
|
659
|
+
depth,
|
|
660
|
+
walkFlags,
|
|
661
|
+
searched,
|
|
662
|
+
)
|
|
663
|
+
: caches.alwaysWalked,
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/** Whether the properties of any of `types` have been resolved. */
|
|
668
|
+
function havePropertiesResolved(c: Checker, types: readonly Type[]): boolean {
|
|
669
|
+
for (const t of types)
|
|
670
|
+
if (sideOf(c, t as UnionOrIntersectionType).membersOf?.resolvedProperties !== undefined) return true;
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function copyInferences(inferences: InferenceInfo[], from: readonly InferenceInfo[]): void {
|
|
675
|
+
for (let k = 0; k < inferences.length; k++) {
|
|
676
|
+
const info = inferences[k]!;
|
|
677
|
+
const known = from[k]!;
|
|
678
|
+
if (known.candidates.length !== 0) info.candidates = known.candidates.slice();
|
|
679
|
+
if (known.contraCandidates.length !== 0) info.contraCandidates = known.contraCandidates.slice();
|
|
680
|
+
info.inferredType = known.inferredType;
|
|
681
|
+
info.priority = known.priority;
|
|
682
|
+
info.topLevel = known.topLevel;
|
|
683
|
+
info.isFixed = known.isFixed;
|
|
684
|
+
info.impliedArity = known.impliedArity;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
function sameTypes(a: readonly Type[], b: readonly Type[]): boolean {
|
|
689
|
+
if (a.length !== b.length) return false;
|
|
690
|
+
for (let k = 0; k < a.length; k++) if (a[k] !== b[k]) return false;
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function sameInferences(a: readonly InferenceInfo[], b: readonly InferenceInfo[]): boolean {
|
|
695
|
+
for (let k = 0; k < a.length; k++) {
|
|
696
|
+
const x = a[k]!;
|
|
697
|
+
const y = b[k]!;
|
|
698
|
+
if (
|
|
699
|
+
!sameTypes(x.candidates, y.candidates) ||
|
|
700
|
+
!sameTypes(x.contraCandidates, y.contraCandidates) ||
|
|
701
|
+
x.inferredType !== y.inferredType ||
|
|
702
|
+
x.priority !== y.priority ||
|
|
703
|
+
x.topLevel !== y.topLevel ||
|
|
704
|
+
x.isFixed !== y.isFixed ||
|
|
705
|
+
x.impliedArity !== y.impliedArity
|
|
706
|
+
)
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/** With TSC_TS_VERIFY_INFERENCE_MEMO=1: walks anyway and reports how the skipped walk would have differed. */
|
|
713
|
+
function verifyUnstartedInference(
|
|
714
|
+
c: Checker,
|
|
715
|
+
signature: Signature,
|
|
716
|
+
known: UnstartedInference,
|
|
717
|
+
source: Type,
|
|
718
|
+
target: Type,
|
|
719
|
+
priority: InferencePriority,
|
|
720
|
+
): void {
|
|
721
|
+
const inferences: InferenceInfo[] = [];
|
|
722
|
+
for (const i of known.inferences) inferences.push(new InferenceInfo(i.typeParameter));
|
|
723
|
+
const types = c.typeCount;
|
|
724
|
+
const signatures = c.signatureCount;
|
|
725
|
+
const total = c.totalInstantiations;
|
|
726
|
+
const reports = c.reports;
|
|
727
|
+
const cycles = c.resolutionCycleCount;
|
|
728
|
+
const reliabilityFlags = c.reliabilityFlags;
|
|
729
|
+
const outerSearches = c.unresolvedPropertySearches;
|
|
730
|
+
c.reliabilityFlags = 0;
|
|
731
|
+
c.unresolvedPropertySearches = undefined;
|
|
732
|
+
inferTypes(c, inferences, source, target, priority, false);
|
|
733
|
+
const walkFlags = c.reliabilityFlags;
|
|
734
|
+
c.reliabilityFlags = reliabilityFlags;
|
|
735
|
+
c.unresolvedPropertySearches = outerSearches;
|
|
736
|
+
const instantiations = c.totalInstantiations - total;
|
|
737
|
+
// Undo the check walk's count so the run continues as without verification.
|
|
738
|
+
c.instantiationCount -= instantiations;
|
|
739
|
+
c.totalInstantiations -= instantiations;
|
|
740
|
+
const differences: string[] = [];
|
|
741
|
+
if (!sameInferences(inferences, known.inferences)) differences.push('inferences');
|
|
742
|
+
if (c.typeCount !== types) differences.push(`${c.typeCount - types} types`);
|
|
743
|
+
if (c.signatureCount !== signatures) differences.push(`${c.signatureCount - signatures} signatures`);
|
|
744
|
+
if (instantiations !== known.instantiations)
|
|
745
|
+
differences.push(`${instantiations} instantiations, not ${known.instantiations}`);
|
|
746
|
+
if (c.reports !== reports) differences.push(`${c.reports - reports} diagnostics`);
|
|
747
|
+
if (c.resolutionCycleCount !== cycles) differences.push('a circularity');
|
|
748
|
+
if (walkFlags !== known.reliabilityFlags) differences.push('reliability flags');
|
|
749
|
+
if (differences.length !== 0)
|
|
750
|
+
process.stderr.write(
|
|
751
|
+
`inference memo: signature ${signature.id} source ${source.id} priority ${priority}: ${differences.join(', ')}\n`,
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
|
|
491
755
|
const enum InferenceAction {
|
|
756
|
+
AliasTypeArguments,
|
|
492
757
|
ConditionalType,
|
|
493
758
|
GenericMappedTypes,
|
|
494
759
|
ObjectTypes,
|
|
760
|
+
ReferenceTypeArguments,
|
|
495
761
|
}
|
|
496
762
|
|
|
497
763
|
const enum MatchKind {
|
|
@@ -532,14 +798,27 @@ class InferenceState {
|
|
|
532
798
|
bivariant = false;
|
|
533
799
|
expandingFlags: ExpandingFlags = ExpandingFlags.None;
|
|
534
800
|
propagationType: Type | undefined = undefined;
|
|
535
|
-
/**
|
|
536
|
-
|
|
801
|
+
/**
|
|
802
|
+
* The statuses of the pairs invokeOnce finished, for each priority and variance of the walk (`visitMode`), by
|
|
803
|
+
* packed type ids (`visitKey`), or spelled when an id is too large to pack. The first pair with packed ids is in
|
|
804
|
+
* `firstVisitKey` instead: most walks finish at most one.
|
|
805
|
+
*/
|
|
806
|
+
visited: Map<number, Map<number, InferencePriority>> | undefined = undefined;
|
|
537
807
|
visitedSpelled: Map<string, InferencePriority> | undefined = undefined;
|
|
538
|
-
/**
|
|
539
|
-
|
|
540
|
-
|
|
808
|
+
/** The mode `visitedPairs` belongs to, or -1 before the first `visitedPairsOf`. */
|
|
809
|
+
visitedMode = -1;
|
|
810
|
+
/** `visited`'s map for `visitedMode`; a walk mostly stays in one mode. */
|
|
811
|
+
visitedPairs: Map<number, InferencePriority> | undefined = undefined;
|
|
812
|
+
/** The first finished pair with packed ids (-1 before it), its mode and its status. */
|
|
813
|
+
firstVisitKey = -1;
|
|
814
|
+
firstVisitMode = 0;
|
|
815
|
+
firstVisitStatus: InferencePriority = InferencePriority.MaxValue;
|
|
816
|
+
/**
|
|
817
|
+
* Where this walk's entries start on the checker's invokeOnce stacks (`InferenceCaches.invokeSourceStack`). The
|
|
818
|
+
* `stackDepth` entries from there are live: the pairs being visited.
|
|
819
|
+
*/
|
|
820
|
+
readonly stackBase: number;
|
|
541
821
|
stackDepth = 0;
|
|
542
|
-
depth = 0;
|
|
543
822
|
|
|
544
823
|
constructor(
|
|
545
824
|
c: Checker,
|
|
@@ -553,6 +832,7 @@ class InferenceState {
|
|
|
553
832
|
this.originalTarget = originalTarget;
|
|
554
833
|
this.priority = priority;
|
|
555
834
|
this.contravariant = contravariant;
|
|
835
|
+
this.stackBase = c.inferenceCaches.invokeStackDepth;
|
|
556
836
|
}
|
|
557
837
|
|
|
558
838
|
infoFor(t: Type): InferenceInfo | undefined {
|
|
@@ -573,18 +853,9 @@ class InferenceState {
|
|
|
573
853
|
const sourceAlias = source.alias;
|
|
574
854
|
const targetAlias = target.alias;
|
|
575
855
|
if (sourceAlias !== undefined && targetAlias !== undefined && sourceAlias.symbol === targetAlias.symbol) {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
const minParams = getMinTypeArgumentCount(c, params);
|
|
580
|
-
const sourceTypes = fillMissingTypeArguments(c, sourceAlias.typeArguments, params, minParams, false);
|
|
581
|
-
const targetTypes = fillMissingTypeArguments(c, targetAlias.typeArguments, params, minParams, false);
|
|
582
|
-
this.inferFromTypeArguments(
|
|
583
|
-
sourceTypes,
|
|
584
|
-
targetTypes,
|
|
585
|
-
someTypeCouldHoldInference(c, targetTypes) ? getAliasVariances(c, sourceAlias.symbol) : noVariances,
|
|
586
|
-
);
|
|
587
|
-
}
|
|
856
|
+
// Instantiations of the same alias infer between their type arguments, once for each pair of types, as tsc does.
|
|
857
|
+
if (sourceAlias.typeArguments.length !== 0 || targetAlias.typeArguments.length !== 0)
|
|
858
|
+
this.invokeOnce(source, target, InferenceAction.AliasTypeArguments);
|
|
588
859
|
return;
|
|
589
860
|
}
|
|
590
861
|
if (source === target && (source.flags & TypeFlags.UnionOrIntersection) !== 0) {
|
|
@@ -594,7 +865,7 @@ class InferenceState {
|
|
|
594
865
|
if ((target.flags & TypeFlags.Union) !== 0) {
|
|
595
866
|
const sourceTypes = (source.flags & TypeFlags.Union) !== 0 ? typesOf(source) : [source];
|
|
596
867
|
// Infer between identically matching constituents, then closely matching ones, removing them.
|
|
597
|
-
const temp = this.inferFromMatchingTypes(sourceTypes,
|
|
868
|
+
const temp = this.inferFromMatchingTypes(sourceTypes, typesOf(target), MatchKind.TypeOrBaseIdentical);
|
|
598
869
|
const matched = this.inferFromMatchingTypes(temp.sources, temp.targets, MatchKind.CloselyMatched);
|
|
599
870
|
if (matched.targets.length === 0) return;
|
|
600
871
|
target = getUnionType(c, matched.targets);
|
|
@@ -647,7 +918,7 @@ class InferenceState {
|
|
|
647
918
|
(referenceTarget(source) === referenceTarget(target) || (isArrayType(c, source) && isArrayType(c, target))) &&
|
|
648
919
|
!(referenceNode(source) !== undefined && referenceNode(target) !== undefined)
|
|
649
920
|
) {
|
|
650
|
-
this.
|
|
921
|
+
this.invokeOnce(source, target, InferenceAction.ReferenceTypeArguments);
|
|
651
922
|
} else if ((source.flags & TypeFlags.Index) !== 0 && (target.flags & TypeFlags.Index) !== 0) {
|
|
652
923
|
this.inferFromContravariantTypes((source as IndexType).target, (target as IndexType).target);
|
|
653
924
|
} else if (
|
|
@@ -706,7 +977,6 @@ class InferenceState {
|
|
|
706
977
|
if (candidate === c.blockedStringType) return;
|
|
707
978
|
if (this.priority < inference.priority) {
|
|
708
979
|
inference.candidates = noCandidates;
|
|
709
|
-
inference.candidateDepths = noCandidateDepths;
|
|
710
980
|
inference.contraCandidates = noCandidates;
|
|
711
981
|
inference.topLevel = true;
|
|
712
982
|
inference.priority = this.priority;
|
|
@@ -719,24 +989,10 @@ class InferenceState {
|
|
|
719
989
|
inference.contraCandidates.push(candidate);
|
|
720
990
|
clearCachedInferences(this.inferences);
|
|
721
991
|
}
|
|
722
|
-
} else {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
inference.candidates.splice(index, 1);
|
|
727
|
-
inference.candidateDepths.splice(index, 1);
|
|
728
|
-
}
|
|
729
|
-
if (inference.candidates === noCandidates) {
|
|
730
|
-
inference.candidates = [];
|
|
731
|
-
inference.candidateDepths = [];
|
|
732
|
-
}
|
|
733
|
-
// Keep candidates with the highest depth first.
|
|
734
|
-
index = 0;
|
|
735
|
-
while (index < inference.candidateDepths.length && inference.candidateDepths[index] >= this.depth) index++;
|
|
736
|
-
inference.candidates.splice(index, 0, candidate);
|
|
737
|
-
inference.candidateDepths.splice(index, 0, this.depth);
|
|
738
|
-
clearCachedInferences(this.inferences);
|
|
739
|
-
}
|
|
992
|
+
} else if (!inference.candidates.includes(candidate)) {
|
|
993
|
+
if (inference.candidates === noCandidates) inference.candidates = [];
|
|
994
|
+
inference.candidates.push(candidate);
|
|
995
|
+
clearCachedInferences(this.inferences);
|
|
740
996
|
}
|
|
741
997
|
}
|
|
742
998
|
if (
|
|
@@ -769,14 +1025,12 @@ class InferenceState {
|
|
|
769
1025
|
}
|
|
770
1026
|
|
|
771
1027
|
inferFromTypeArguments(sourceTypes: Type[], targetTypes: Type[], variances: VarianceFlags[]): void {
|
|
772
|
-
this.depth++;
|
|
773
1028
|
const count = Math.min(sourceTypes.length, targetTypes.length);
|
|
774
1029
|
for (let i = 0; i < count; i++) {
|
|
775
1030
|
if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant)
|
|
776
1031
|
this.inferFromContravariantTypes(sourceTypes[i]!, targetTypes[i]!);
|
|
777
1032
|
else this.inferFromTypes(sourceTypes[i]!, targetTypes[i]!);
|
|
778
1033
|
}
|
|
779
|
-
this.depth--;
|
|
780
1034
|
}
|
|
781
1035
|
|
|
782
1036
|
inferWithPriority(source: Type, target: Type, newPriority: InferencePriority): void {
|
|
@@ -807,27 +1061,38 @@ class InferenceState {
|
|
|
807
1061
|
|
|
808
1062
|
/** Runs `action` once per source and target pair, stopping at circularities. */
|
|
809
1063
|
invokeOnce(source: Type, target: Type, action: InferenceAction): void {
|
|
1064
|
+
// As in tsc, a pair is visited once for each priority and variance it is inferred with.
|
|
1065
|
+
const mode = visitMode(this.priority, this.contravariant, this.bivariant);
|
|
810
1066
|
const key = visitKey(source, target);
|
|
811
|
-
const status =
|
|
1067
|
+
const status = this.getVisited(source, target, key, mode);
|
|
812
1068
|
if (status !== undefined) {
|
|
813
1069
|
this.inferencePriority = Math.min(this.inferencePriority, status);
|
|
814
1070
|
return;
|
|
815
1071
|
}
|
|
816
|
-
this.setVisited(source, target, key, InferencePriority.Circularity);
|
|
817
1072
|
const saveInferencePriority = this.inferencePriority;
|
|
818
1073
|
this.inferencePriority = InferencePriority.MaxValue;
|
|
819
1074
|
// Duplicate recursion identities on both sides mean a circularity.
|
|
820
1075
|
const saveExpandingFlags = this.expandingFlags;
|
|
1076
|
+
const caches = this.c.inferenceCaches;
|
|
821
1077
|
const stackDepth = this.stackDepth;
|
|
822
|
-
|
|
823
|
-
|
|
1078
|
+
const start = this.stackBase;
|
|
1079
|
+
const end = start + stackDepth + 1;
|
|
1080
|
+
setStackEntry(caches.invokeSourceStack, end - 1, source);
|
|
1081
|
+
setStackEntry(caches.invokeTargetStack, end - 1, target);
|
|
1082
|
+
setNumberEntry(caches.invokeModeStack, end - 1, mode);
|
|
1083
|
+
setNumberEntry(caches.invokeSourceIdentities, end - 1, 0);
|
|
1084
|
+
setNumberEntry(caches.invokeTargetIdentities, end - 1, 0);
|
|
824
1085
|
this.stackDepth = stackDepth + 1;
|
|
825
|
-
|
|
1086
|
+
caches.invokeStackDepth = end;
|
|
1087
|
+
if (isDeeplyNestedStackEntry(this.c, caches.invokeSourceStack, caches.invokeSourceIdentities, start, end, 2))
|
|
826
1088
|
this.expandingFlags |= ExpandingFlags.Source;
|
|
827
|
-
if (
|
|
1089
|
+
if (isDeeplyNestedStackEntry(this.c, caches.invokeTargetStack, caches.invokeTargetIdentities, start, end, 2))
|
|
828
1090
|
this.expandingFlags |= ExpandingFlags.Target;
|
|
829
1091
|
if (this.expandingFlags !== ExpandingFlags.Both) {
|
|
830
1092
|
switch (action) {
|
|
1093
|
+
case InferenceAction.AliasTypeArguments:
|
|
1094
|
+
this.inferFromAliasTypeArguments(source, target);
|
|
1095
|
+
break;
|
|
831
1096
|
case InferenceAction.ConditionalType:
|
|
832
1097
|
this.inferToConditionalType(source, target as ConditionalType);
|
|
833
1098
|
break;
|
|
@@ -837,30 +1102,96 @@ class InferenceState {
|
|
|
837
1102
|
case InferenceAction.ObjectTypes:
|
|
838
1103
|
this.inferFromObjectTypes(source, target);
|
|
839
1104
|
break;
|
|
1105
|
+
case InferenceAction.ReferenceTypeArguments:
|
|
1106
|
+
this.inferFromReferenceTypeArguments(source, target);
|
|
1107
|
+
break;
|
|
840
1108
|
}
|
|
841
1109
|
} else this.inferencePriority = InferencePriority.Circularity;
|
|
842
1110
|
this.stackDepth = stackDepth;
|
|
1111
|
+
caches.invokeStackDepth = end - 1;
|
|
843
1112
|
this.expandingFlags = saveExpandingFlags;
|
|
844
|
-
this.setVisited(source, target, key, this.inferencePriority);
|
|
1113
|
+
this.setVisited(source, target, key, mode, this.inferencePriority);
|
|
845
1114
|
this.inferencePriority = Math.min(this.inferencePriority, saveInferencePriority);
|
|
846
1115
|
}
|
|
847
1116
|
|
|
848
|
-
|
|
1117
|
+
/**
|
|
1118
|
+
* The status of the pair in `mode`: its status once it is finished, Circularity while it is being visited, and
|
|
1119
|
+
* undefined before its first visit.
|
|
1120
|
+
*/
|
|
1121
|
+
getVisited(source: Type, target: Type, key: number, mode: number): InferencePriority | undefined {
|
|
849
1122
|
if (key >= 0) {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
this.visited = visited;
|
|
854
|
-
}
|
|
855
|
-
visited.set(key, status);
|
|
1123
|
+
if (key === this.firstVisitKey && mode === this.firstVisitMode) return this.firstVisitStatus;
|
|
1124
|
+
const status = this.visited !== undefined ? this.visitedPairsOf(mode)?.get(key) : undefined;
|
|
1125
|
+
if (status !== undefined) return status;
|
|
856
1126
|
} else {
|
|
1127
|
+
const status = this.visitedSpelled?.get(source.id + ',' + target.id + ',' + mode);
|
|
1128
|
+
if (status !== undefined) return status;
|
|
1129
|
+
}
|
|
1130
|
+
const caches = this.c.inferenceCaches;
|
|
1131
|
+
const targetStack = caches.invokeTargetStack;
|
|
1132
|
+
const end = this.stackBase + this.stackDepth;
|
|
1133
|
+
for (let i = this.stackBase; i < end; i++)
|
|
1134
|
+
if (targetStack[i] === target && caches.invokeSourceStack[i] === source && caches.invokeModeStack[i] === mode)
|
|
1135
|
+
return InferencePriority.Circularity;
|
|
1136
|
+
return undefined;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/** Records the status of a finished pair. */
|
|
1140
|
+
setVisited(source: Type, target: Type, key: number, mode: number, status: InferencePriority): void {
|
|
1141
|
+
if (key < 0) {
|
|
857
1142
|
let visited = this.visitedSpelled;
|
|
858
1143
|
if (visited === undefined) {
|
|
859
1144
|
visited = new Map<string, InferencePriority>();
|
|
860
1145
|
this.visitedSpelled = visited;
|
|
861
1146
|
}
|
|
862
|
-
visited.set(source.id + ',' + target.id, status);
|
|
1147
|
+
visited.set(source.id + ',' + target.id + ',' + mode, status);
|
|
1148
|
+
} else if (this.firstVisitKey < 0) {
|
|
1149
|
+
this.firstVisitKey = key;
|
|
1150
|
+
this.firstVisitMode = mode;
|
|
1151
|
+
this.firstVisitStatus = status;
|
|
1152
|
+
} else {
|
|
1153
|
+
let modes = this.visited;
|
|
1154
|
+
if (modes === undefined) {
|
|
1155
|
+
modes = new Map<number, Map<number, InferencePriority>>();
|
|
1156
|
+
this.visited = modes;
|
|
1157
|
+
}
|
|
1158
|
+
let pairs = this.visitedPairsOf(mode);
|
|
1159
|
+
if (pairs === undefined) {
|
|
1160
|
+
pairs = new Map<number, InferencePriority>();
|
|
1161
|
+
modes.set(mode, pairs);
|
|
1162
|
+
this.visitedMode = mode;
|
|
1163
|
+
this.visitedPairs = pairs;
|
|
1164
|
+
}
|
|
1165
|
+
pairs.set(key, status);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// Source and target are instantiations of the same type alias: infers between the type arguments, with defaults
|
|
1170
|
+
// applied.
|
|
1171
|
+
inferFromAliasTypeArguments(source: Type, target: Type): void {
|
|
1172
|
+
const c = this.c;
|
|
1173
|
+
const sourceAlias = source.alias!;
|
|
1174
|
+
const params = c.symbolLinks(sourceAlias.symbol).typeParameters ?? [];
|
|
1175
|
+
const minParams = getMinTypeArgumentCount(c, params);
|
|
1176
|
+
const isJavaScript = isInJSFile(sourceAlias.symbol.valueDeclaration);
|
|
1177
|
+
const sourceTypes = fillMissingTypeArguments(c, sourceAlias.typeArguments, params, minParams, isJavaScript);
|
|
1178
|
+
const targetTypes = fillMissingTypeArguments(c, target.alias!.typeArguments, params, minParams, isJavaScript);
|
|
1179
|
+
this.inferFromTypeArguments(
|
|
1180
|
+
sourceTypes,
|
|
1181
|
+
targetTypes,
|
|
1182
|
+
someTypeCouldHoldInference(c, targetTypes) ? getAliasVariances(c, sourceAlias.symbol) : noVariances,
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
/** `visited`'s map of the pairs finished in `mode`, if there is one. */
|
|
1187
|
+
visitedPairsOf(mode: number): Map<number, InferencePriority> | undefined {
|
|
1188
|
+
if (mode === this.visitedMode) return this.visitedPairs;
|
|
1189
|
+
const pairs = this.visited?.get(mode);
|
|
1190
|
+
if (pairs !== undefined) {
|
|
1191
|
+
this.visitedMode = mode;
|
|
1192
|
+
this.visitedPairs = pairs;
|
|
863
1193
|
}
|
|
1194
|
+
return pairs;
|
|
864
1195
|
}
|
|
865
1196
|
|
|
866
1197
|
inferFromMatchingTypes(sources: Type[], targets: Type[], kind: MatchKind): MatchedTypes {
|
|
@@ -870,10 +1201,19 @@ class InferenceState {
|
|
|
870
1201
|
for (const t of targets)
|
|
871
1202
|
for (const s of sources)
|
|
872
1203
|
if (typesMatch(c, s, t, kind)) {
|
|
873
|
-
this.inferFromTypes(s, t);
|
|
1204
|
+
if (kind !== MatchKind.CloselyMatched) this.inferFromTypes(s, t);
|
|
874
1205
|
if (!matchedSources.includes(s)) matchedSources.push(s);
|
|
875
1206
|
if (!matchedTargets.includes(t)) matchedTargets.push(t);
|
|
876
1207
|
}
|
|
1208
|
+
if (kind === MatchKind.CloselyMatched) {
|
|
1209
|
+
// Infer to closely matched targets in decreasing depth of generic instantiations: an inference
|
|
1210
|
+
// from a more deeply nested type argument has had more layers of instantiation stripped away. For
|
|
1211
|
+
// example, from `string[] | string[][]` to `T[] | T[][]`, relating `string[][]` to `T[][]` infers
|
|
1212
|
+
// `string`, a better inference than the `string[]` that relating `string[][]` to `T[]` infers.
|
|
1213
|
+
matchedTargets.sort((t1, t2) => compareTypesAndDepth(c, t1, t2));
|
|
1214
|
+
for (const t of matchedTargets)
|
|
1215
|
+
for (const s of matchedSources) if (typesMatch(c, s, t, kind)) this.inferFromTypes(s, t);
|
|
1216
|
+
}
|
|
877
1217
|
return new MatchedTypes(
|
|
878
1218
|
matchedSources.length !== 0 ? sources.filter((t) => !matchedSources.includes(t)) : sources,
|
|
879
1219
|
matchedTargets.length !== 0 ? targets.filter((t) => !matchedTargets.includes(t)) : targets,
|
|
@@ -957,10 +1297,17 @@ class InferenceState {
|
|
|
957
1297
|
const c = this.c;
|
|
958
1298
|
if ((source.flags & TypeFlags.Conditional) !== 0) {
|
|
959
1299
|
const s = source as ConditionalType;
|
|
960
|
-
|
|
961
|
-
this.inferFromTypes(s.
|
|
962
|
-
this.inferFromTypes(
|
|
963
|
-
this.inferFromTypes(
|
|
1300
|
+
// A source's distributed type parameters infer as the type parameters they were made from.
|
|
1301
|
+
this.inferFromTypes(getNonDistributedTypeParameter(s.checkType), target.checkType);
|
|
1302
|
+
this.inferFromTypes(getNonDistributedTypeParameter(s.extendsType), target.extendsType);
|
|
1303
|
+
this.inferFromTypes(
|
|
1304
|
+
getNonDistributedTypeParameter(getTrueTypeFromConditionalType(c, s)),
|
|
1305
|
+
getTrueTypeFromConditionalType(c, target),
|
|
1306
|
+
);
|
|
1307
|
+
this.inferFromTypes(
|
|
1308
|
+
getNonDistributedTypeParameter(getFalseTypeFromConditionalType(c, s)),
|
|
1309
|
+
getFalseTypeFromConditionalType(c, target),
|
|
1310
|
+
);
|
|
964
1311
|
} else {
|
|
965
1312
|
const savePriority = this.priority;
|
|
966
1313
|
this.priority |= this.contravariant ? InferencePriority.ContravariantConditional : 0;
|
|
@@ -1303,11 +1650,45 @@ class InferenceState {
|
|
|
1303
1650
|
// ---- Helpers
|
|
1304
1651
|
|
|
1305
1652
|
function getInferenceInfoForType(inferences: InferenceInfo[], t: Type): InferenceInfo | undefined {
|
|
1306
|
-
if ((t.flags & TypeFlags.TypeVariable) !== 0)
|
|
1307
|
-
|
|
1653
|
+
if ((t.flags & TypeFlags.TypeVariable) !== 0) {
|
|
1654
|
+
const typeVariable = getNonDistributedTypeParameter(t);
|
|
1655
|
+
for (const inference of inferences) if (typeVariable === inference.typeParameter) return inference;
|
|
1656
|
+
}
|
|
1308
1657
|
return undefined;
|
|
1309
1658
|
}
|
|
1310
1659
|
|
|
1660
|
+
/** Orders types by decreasing depth, then by the regular type ordering. */
|
|
1661
|
+
function compareTypesAndDepth(c: Checker, t1: Type, t2: Type): number {
|
|
1662
|
+
const d1 = getTypeDepth(c, t1, 3);
|
|
1663
|
+
const d2 = getTypeDepth(c, t2, 3);
|
|
1664
|
+
if (d1 !== d2) return d2 - d1;
|
|
1665
|
+
return compareTypes(c, t1, t2);
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* The depth of a type, up to `maxDepth`: one plus the largest type argument depth for generic aliased
|
|
1670
|
+
* types and type references, the largest constituent depth for unions and intersections, and zero
|
|
1671
|
+
* otherwise. The maximum keeps circular types from recursing forever.
|
|
1672
|
+
*/
|
|
1673
|
+
function getTypeDepth(c: Checker, t: Type, maxDepth: number): number {
|
|
1674
|
+
if (maxDepth !== 0) {
|
|
1675
|
+
if (t.alias !== undefined && t.alias.typeArguments.length !== 0)
|
|
1676
|
+
return getTypeListDepth(c, t.alias.typeArguments, maxDepth - 1) + 1;
|
|
1677
|
+
if ((t.objectFlags & ObjectFlags.Reference) !== 0) {
|
|
1678
|
+
const typeArguments = getTypeArguments(c, t);
|
|
1679
|
+
if (typeArguments.length !== 0) return getTypeListDepth(c, typeArguments, maxDepth - 1) + 1;
|
|
1680
|
+
}
|
|
1681
|
+
if ((t.flags & TypeFlags.UnionOrIntersection) !== 0) return getTypeListDepth(c, typesOf(t), maxDepth);
|
|
1682
|
+
}
|
|
1683
|
+
return 0;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
function getTypeListDepth(c: Checker, types: readonly Type[], maxDepth: number): number {
|
|
1687
|
+
let depth = 0;
|
|
1688
|
+
for (const t of types) depth = Math.max(depth, getTypeDepth(c, t, maxDepth));
|
|
1689
|
+
return depth;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1311
1692
|
function distributedTypes(t: Type): Type[] {
|
|
1312
1693
|
return (t.flags & TypeFlags.Union) !== 0 ? typesOf(t) : [t];
|
|
1313
1694
|
}
|
|
@@ -1330,15 +1711,21 @@ function someTypeCouldHoldInference(c: Checker, targets: readonly Type[]): boole
|
|
|
1330
1711
|
|
|
1331
1712
|
/**
|
|
1332
1713
|
* `couldContainTypeVariables` without two of its conservative answers: a deferred reference without an
|
|
1333
|
-
* alias
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1714
|
+
* alias holds type variables only through its type arguments, like any other reference; and the static
|
|
1715
|
+
* side of a class declared at the top level of a file or module holds none outside its generic
|
|
1716
|
+
* signatures, which inference erases. A deferred reference's type arguments are resolved here unless
|
|
1717
|
+
* they are being resolved already, where resolving them would report a circularity.
|
|
1336
1718
|
*/
|
|
1337
1719
|
function couldHoldInference(c: Checker, t: Type, depth: number): boolean {
|
|
1338
1720
|
if (!couldContainTypeVariables(c, t)) return false;
|
|
1339
1721
|
if (t.alias !== undefined || depth === 4) return true;
|
|
1340
1722
|
if ((t.objectFlags & ObjectFlags.Reference) !== 0) {
|
|
1341
|
-
const resolved =
|
|
1723
|
+
const resolved =
|
|
1724
|
+
(t as TypeReference).resolvedTypeArguments ??
|
|
1725
|
+
sideOf(c, t as TypeReference).resolvedTypeArguments ??
|
|
1726
|
+
(findResolutionCycleStartIndex(c, t, TypeSystemPropertyName.ResolvedTypeArguments) < 0
|
|
1727
|
+
? getTypeArguments(c, t)
|
|
1728
|
+
: undefined);
|
|
1342
1729
|
if (resolved === undefined) return true;
|
|
1343
1730
|
for (const a of resolved) if (couldHoldInference(c, a, depth + 1)) return true;
|
|
1344
1731
|
return false;
|
|
@@ -1486,6 +1873,7 @@ function hasUnmatchedProperty(c: Checker, source: Type, target: Type, matchDiscr
|
|
|
1486
1873
|
sideOf(c, t as UnionOrIntersectionType).membersOf?.resolvedProperties !== undefined
|
|
1487
1874
|
)
|
|
1488
1875
|
return getUnmatchedProperty(c, source, target, false, matchDiscriminantProperties) !== undefined;
|
|
1876
|
+
if (c.unresolvedPropertySearches !== undefined) c.unresolvedPropertySearches.push(t);
|
|
1489
1877
|
const containingType = t as UnionOrIntersectionType;
|
|
1490
1878
|
const isUnion = (t.flags & TypeFlags.Union) !== 0;
|
|
1491
1879
|
const checked = new Set<string>();
|
|
@@ -1554,7 +1942,8 @@ export function isConstTypeVariable(c: Checker, t: Type | undefined, depth: numb
|
|
|
1554
1942
|
export function isMutableArrayLikeType(c: Checker, t: Type): boolean {
|
|
1555
1943
|
return (
|
|
1556
1944
|
isMutableArrayOrTuple(c, t) ||
|
|
1557
|
-
((t.flags & (TypeFlags.Any | TypeFlags.Nullable)) === 0 &&
|
|
1945
|
+
((t.flags & (TypeFlags.Any | TypeFlags.Nullable | TypeFlags.Never)) === 0 &&
|
|
1946
|
+
isTypeAssignableTo(c, t, c.anyArrayType))
|
|
1558
1947
|
);
|
|
1559
1948
|
}
|
|
1560
1949
|
|
|
@@ -1722,10 +2111,15 @@ export function isUnmatchedTemplateLiteralKey(source: Type, target: TemplateLite
|
|
|
1722
2111
|
}
|
|
1723
2112
|
|
|
1724
2113
|
/** The types matched by `target`'s placeholders in `source`, or undefined if it doesn't match. */
|
|
2114
|
+
/**
|
|
2115
|
+
* The types that `source` gives the placeholders of `target`. A placeholder of a source template with the same
|
|
2116
|
+
* texts keeps its type where `compareTypes` (assignability by default) relates their base constraints.
|
|
2117
|
+
*/
|
|
1725
2118
|
export function inferTypesFromTemplateLiteralType(
|
|
1726
2119
|
c: Checker,
|
|
1727
2120
|
source: Type,
|
|
1728
2121
|
target: TemplateLiteralType,
|
|
2122
|
+
compareTypes?: TemplateTypeComparer,
|
|
1729
2123
|
): Type[] | undefined {
|
|
1730
2124
|
if ((source.flags & TypeFlags.StringLiteral) !== 0) {
|
|
1731
2125
|
// Most string literals fail the start and end text test; apply it before building the
|
|
@@ -1739,11 +2133,13 @@ export function inferTypesFromTemplateLiteralType(
|
|
|
1739
2133
|
const result: Type[] = [];
|
|
1740
2134
|
for (let i = 0; i < s.types.length; i++) {
|
|
1741
2135
|
const t = s.types[i]!;
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
2136
|
+
const sourceConstraint = getBaseConstraintOrType(c, t);
|
|
2137
|
+
const targetConstraint = getBaseConstraintOrType(c, target.types[i]!);
|
|
2138
|
+
const related =
|
|
2139
|
+
compareTypes !== undefined
|
|
2140
|
+
? compareTypes(sourceConstraint, targetConstraint)
|
|
2141
|
+
: isTypeAssignableTo(c, sourceConstraint, targetConstraint);
|
|
2142
|
+
result.push(related ? t : getStringLikeTypeForType(c, t));
|
|
1747
2143
|
}
|
|
1748
2144
|
return result;
|
|
1749
2145
|
}
|
|
@@ -2203,7 +2599,12 @@ export function getInferredType(c: Checker, context: InferenceContext, index: nu
|
|
|
2203
2599
|
const constraint = getConstraintOfTypeParameter(c, inference.typeParameter);
|
|
2204
2600
|
if (constraint !== undefined) {
|
|
2205
2601
|
const instantiatedConstraint = instantiateType(c, constraint, context.nonFixingMapper);
|
|
2206
|
-
|
|
2602
|
+
// A pure return type inference is still filtered in a recursive call resolution: its result can become
|
|
2603
|
+
// the type of the enclosing declaration.
|
|
2604
|
+
if (
|
|
2605
|
+
inferredType !== undefined &&
|
|
2606
|
+
((context.flags & InferenceFlags.NoConstraintChecks) === 0 || inference.priority === InferencePriority.ReturnType)
|
|
2607
|
+
) {
|
|
2207
2608
|
const constraintWithThis = getTypeWithThisArgument(c, instantiatedConstraint, inferredType, false);
|
|
2208
2609
|
if (context.compareTypes.compare(inferredType, constraintWithThis, false) === Ternary.False) {
|
|
2209
2610
|
// A pure return type inference may still succeed without the constituents the constraint rejects.
|
|
@@ -2236,9 +2637,19 @@ function clearActiveMapperCaches(c: Checker): void {
|
|
|
2236
2637
|
for (const cache of c.activeMapperAliasCaches) if (cache !== undefined) cache.clear();
|
|
2237
2638
|
}
|
|
2238
2639
|
|
|
2640
|
+
function setNumberEntry(stack: number[], depth: number, value: number): void {
|
|
2641
|
+
if (depth < stack.length) stack[depth] = value;
|
|
2642
|
+
else stack.push(value);
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2239
2645
|
/** Type ids below this bound pack in pairs into one exact number. */
|
|
2240
2646
|
const VisitKeyIdLimit = 1 << 26;
|
|
2241
2647
|
|
|
2648
|
+
/** The priority and variance of an inference walk, packed. */
|
|
2649
|
+
function visitMode(priority: number, contravariant: boolean, bivariant: boolean): number {
|
|
2650
|
+
return priority * 4 + (contravariant ? 2 : 0) + (bivariant ? 1 : 0);
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2242
2653
|
/** invokeOnce's key for a pair of types: both ids in one number, or -1 when an id is too large. */
|
|
2243
2654
|
function visitKey(source: Type, target: Type): number {
|
|
2244
2655
|
const s = source.id;
|
|
@@ -2463,11 +2874,32 @@ export class InferenceCaches {
|
|
|
2463
2874
|
readonly contextFreeTypes = new Map<Node, Type>();
|
|
2464
2875
|
readonly reverseMapped = new Map<string, Type | undefined>();
|
|
2465
2876
|
readonly reverseHomomorphicMapped = new Map<string, Type | undefined>();
|
|
2877
|
+
/**
|
|
2878
|
+
* invokeOnce's recursion stacks, shared by the checker's inference walks, with the mode of each visit and the
|
|
2879
|
+
* recursion identities isDeeplyNestedStackEntry keeps for each entry. The first `invokeStackDepth` entries are live.
|
|
2880
|
+
* A walk's entries start where the live entries end when it starts (`InferenceState.stackBase`), so a walk started
|
|
2881
|
+
* during another one keeps the other's entries.
|
|
2882
|
+
*/
|
|
2883
|
+
readonly invokeSourceStack: Type[] = [];
|
|
2884
|
+
readonly invokeTargetStack: Type[] = [];
|
|
2885
|
+
readonly invokeModeStack: number[] = [];
|
|
2886
|
+
readonly invokeSourceIdentities: RecursionId[] = [];
|
|
2887
|
+
readonly invokeTargetIdentities: RecursionId[] = [];
|
|
2888
|
+
invokeStackDepth = 0;
|
|
2466
2889
|
/** inferReverseMappedType's recursion stacks; the first `reverseStackDepth` entries of each are live. */
|
|
2467
2890
|
readonly reverseSourceStack: Type[] = [];
|
|
2468
2891
|
readonly reverseTargetStack: Type[] = [];
|
|
2469
2892
|
reverseStackDepth = 0;
|
|
2470
2893
|
reverseExpandingFlags: number = ExpandingFlags.None;
|
|
2894
|
+
/**
|
|
2895
|
+
* What `inferTypesFromUnstarted` left in each inference, by signature id, then by source type id
|
|
2896
|
+
* times 4096 plus the priority.
|
|
2897
|
+
*/
|
|
2898
|
+
readonly unstartedInferences = new Map<number, Map<number, UnstartedInference>>();
|
|
2899
|
+
/** The `unstartedInferences` entry of a walk seen once. */
|
|
2900
|
+
readonly seenOnce = new UnstartedInference(UnstartedInferenceState.Seen, [], 0, 0, 0, []);
|
|
2901
|
+
/** The `unstartedInferences` entry of a walk that is never skipped. */
|
|
2902
|
+
readonly alwaysWalked = new UnstartedInference(UnstartedInferenceState.Unusable, [], 0, 0, 0, []);
|
|
2471
2903
|
}
|
|
2472
2904
|
|
|
2473
2905
|
// ---- Constraints of `infer` type parameters
|