tsc-ts 0.0.10 → 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 +1 -1
- 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 +20 -15
- package/dist/api/compiler/ast.js +1023 -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 +173 -123
- 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 +469 -438
- 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 -113
- 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 +210 -74
- 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 +137 -34
- 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 +93 -31
- package/dist/api/compiler/checker.js +143 -35
- 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 +19 -4
- package/dist/api/compiler/compile-program.js +45 -26
- package/dist/api/compiler/diagnostic-messages.d.ts +1849 -1774
- package/dist/api/compiler/diagnostic-messages.js +128 -122
- package/dist/api/compiler/diagnostics.js +7 -7
- 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 +10 -0
- package/dist/api/compiler/file-loader.js +138 -41
- 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/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 +3 -1
- package/dist/api/compiler/printer/emit-context.js +16 -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 +1 -0
- package/dist/api/compiler/printer/printer.js +303 -281
- package/dist/api/compiler/printer/utilities.js +149 -147
- package/dist/api/compiler/program-checker.d.ts +8 -2
- package/dist/api/compiler/program-checker.js +84 -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 +2 -0
- package/dist/api/compiler/program.js +69 -57
- 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 +337 -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 +22 -13
- package/dist/api/compiler/symbol.js +15 -1
- 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 +55 -26
- package/src/compiler/binder.ts +39 -4
- package/src/compiler/character-codes.ts +2 -2
- package/src/compiler/checker-calls.ts +76 -8
- 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 +133 -60
- package/src/compiler/checker-heritage.ts +22 -21
- package/src/compiler/checker-inference.ts +514 -87
- 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 +197 -55
- 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 +120 -21
- 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 +168 -41
- package/src/compiler/command-line.ts +28 -28
- package/src/compiler/compile-program.ts +51 -25
- package/src/compiler/decoder.ts +13 -4
- package/src/compiler/diagnostic-messages.ts +1973 -1892
- 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 +139 -32
- package/src/compiler/help.ts +10 -14
- package/src/compiler/incremental.ts +86 -18
- 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 +197 -8
- package/src/compiler/parallel-emit.ts +1 -1
- package/src/compiler/parser.ts +156 -39
- package/src/compiler/path.ts +22 -2
- package/src/compiler/printer/emit-context.ts +16 -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 +35 -14
- package/src/compiler/printer/utilities.ts +8 -2
- package/src/compiler/program-checker.ts +53 -5
- package/src/compiler/program-utilities.ts +23 -10
- package/src/compiler/program.ts +13 -1
- package/src/compiler/pseudo-bigint.ts +17 -0
- package/src/compiler/regexp-checker.ts +63 -30
- package/src/compiler/relations.ts +233 -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 +31 -14
- package/src/compiler/syntax-kind.ts +188 -187
- package/src/compiler/thread-entry.ts +19 -2
- 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 +3 -0
- package/src/compiler/tsc-cli.ts +2 -0
- package/src/compiler/tsc-compile.ts +7 -2
- 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,29 +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
|
-
if (index === inference.candidates.length) {
|
|
737
|
-
inference.candidates.push(candidate);
|
|
738
|
-
inference.candidateDepths.push(this.depth);
|
|
739
|
-
} else {
|
|
740
|
-
inference.candidates.splice(index, 0, candidate);
|
|
741
|
-
inference.candidateDepths.splice(index, 0, this.depth);
|
|
742
|
-
}
|
|
743
|
-
clearCachedInferences(this.inferences);
|
|
744
|
-
}
|
|
992
|
+
} else if (!inference.candidates.includes(candidate)) {
|
|
993
|
+
if (inference.candidates === noCandidates) inference.candidates = [];
|
|
994
|
+
inference.candidates.push(candidate);
|
|
995
|
+
clearCachedInferences(this.inferences);
|
|
745
996
|
}
|
|
746
997
|
}
|
|
747
998
|
if (
|
|
@@ -774,14 +1025,12 @@ class InferenceState {
|
|
|
774
1025
|
}
|
|
775
1026
|
|
|
776
1027
|
inferFromTypeArguments(sourceTypes: Type[], targetTypes: Type[], variances: VarianceFlags[]): void {
|
|
777
|
-
this.depth++;
|
|
778
1028
|
const count = Math.min(sourceTypes.length, targetTypes.length);
|
|
779
1029
|
for (let i = 0; i < count; i++) {
|
|
780
1030
|
if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant)
|
|
781
1031
|
this.inferFromContravariantTypes(sourceTypes[i]!, targetTypes[i]!);
|
|
782
1032
|
else this.inferFromTypes(sourceTypes[i]!, targetTypes[i]!);
|
|
783
1033
|
}
|
|
784
|
-
this.depth--;
|
|
785
1034
|
}
|
|
786
1035
|
|
|
787
1036
|
inferWithPriority(source: Type, target: Type, newPriority: InferencePriority): void {
|
|
@@ -812,27 +1061,38 @@ class InferenceState {
|
|
|
812
1061
|
|
|
813
1062
|
/** Runs `action` once per source and target pair, stopping at circularities. */
|
|
814
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);
|
|
815
1066
|
const key = visitKey(source, target);
|
|
816
|
-
const status =
|
|
1067
|
+
const status = this.getVisited(source, target, key, mode);
|
|
817
1068
|
if (status !== undefined) {
|
|
818
1069
|
this.inferencePriority = Math.min(this.inferencePriority, status);
|
|
819
1070
|
return;
|
|
820
1071
|
}
|
|
821
|
-
this.setVisited(source, target, key, InferencePriority.Circularity);
|
|
822
1072
|
const saveInferencePriority = this.inferencePriority;
|
|
823
1073
|
this.inferencePriority = InferencePriority.MaxValue;
|
|
824
1074
|
// Duplicate recursion identities on both sides mean a circularity.
|
|
825
1075
|
const saveExpandingFlags = this.expandingFlags;
|
|
1076
|
+
const caches = this.c.inferenceCaches;
|
|
826
1077
|
const stackDepth = this.stackDepth;
|
|
827
|
-
|
|
828
|
-
|
|
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);
|
|
829
1085
|
this.stackDepth = stackDepth + 1;
|
|
830
|
-
|
|
1086
|
+
caches.invokeStackDepth = end;
|
|
1087
|
+
if (isDeeplyNestedStackEntry(this.c, caches.invokeSourceStack, caches.invokeSourceIdentities, start, end, 2))
|
|
831
1088
|
this.expandingFlags |= ExpandingFlags.Source;
|
|
832
|
-
if (
|
|
1089
|
+
if (isDeeplyNestedStackEntry(this.c, caches.invokeTargetStack, caches.invokeTargetIdentities, start, end, 2))
|
|
833
1090
|
this.expandingFlags |= ExpandingFlags.Target;
|
|
834
1091
|
if (this.expandingFlags !== ExpandingFlags.Both) {
|
|
835
1092
|
switch (action) {
|
|
1093
|
+
case InferenceAction.AliasTypeArguments:
|
|
1094
|
+
this.inferFromAliasTypeArguments(source, target);
|
|
1095
|
+
break;
|
|
836
1096
|
case InferenceAction.ConditionalType:
|
|
837
1097
|
this.inferToConditionalType(source, target as ConditionalType);
|
|
838
1098
|
break;
|
|
@@ -842,32 +1102,98 @@ class InferenceState {
|
|
|
842
1102
|
case InferenceAction.ObjectTypes:
|
|
843
1103
|
this.inferFromObjectTypes(source, target);
|
|
844
1104
|
break;
|
|
1105
|
+
case InferenceAction.ReferenceTypeArguments:
|
|
1106
|
+
this.inferFromReferenceTypeArguments(source, target);
|
|
1107
|
+
break;
|
|
845
1108
|
}
|
|
846
1109
|
} else this.inferencePriority = InferencePriority.Circularity;
|
|
847
1110
|
this.stackDepth = stackDepth;
|
|
1111
|
+
caches.invokeStackDepth = end - 1;
|
|
848
1112
|
this.expandingFlags = saveExpandingFlags;
|
|
849
|
-
this.setVisited(source, target, key, this.inferencePriority);
|
|
1113
|
+
this.setVisited(source, target, key, mode, this.inferencePriority);
|
|
850
1114
|
this.inferencePriority = Math.min(this.inferencePriority, saveInferencePriority);
|
|
851
1115
|
}
|
|
852
1116
|
|
|
853
|
-
|
|
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 {
|
|
854
1122
|
if (key >= 0) {
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
this.visited = visited;
|
|
859
|
-
}
|
|
860
|
-
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;
|
|
861
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) {
|
|
862
1142
|
let visited = this.visitedSpelled;
|
|
863
1143
|
if (visited === undefined) {
|
|
864
1144
|
visited = new Map<string, InferencePriority>();
|
|
865
1145
|
this.visitedSpelled = visited;
|
|
866
1146
|
}
|
|
867
|
-
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);
|
|
868
1166
|
}
|
|
869
1167
|
}
|
|
870
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;
|
|
1193
|
+
}
|
|
1194
|
+
return pairs;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
871
1197
|
inferFromMatchingTypes(sources: Type[], targets: Type[], kind: MatchKind): MatchedTypes {
|
|
872
1198
|
const c = this.c;
|
|
873
1199
|
const matchedSources: Type[] = [];
|
|
@@ -875,10 +1201,19 @@ class InferenceState {
|
|
|
875
1201
|
for (const t of targets)
|
|
876
1202
|
for (const s of sources)
|
|
877
1203
|
if (typesMatch(c, s, t, kind)) {
|
|
878
|
-
this.inferFromTypes(s, t);
|
|
1204
|
+
if (kind !== MatchKind.CloselyMatched) this.inferFromTypes(s, t);
|
|
879
1205
|
if (!matchedSources.includes(s)) matchedSources.push(s);
|
|
880
1206
|
if (!matchedTargets.includes(t)) matchedTargets.push(t);
|
|
881
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
|
+
}
|
|
882
1217
|
return new MatchedTypes(
|
|
883
1218
|
matchedSources.length !== 0 ? sources.filter((t) => !matchedSources.includes(t)) : sources,
|
|
884
1219
|
matchedTargets.length !== 0 ? targets.filter((t) => !matchedTargets.includes(t)) : targets,
|
|
@@ -962,10 +1297,17 @@ class InferenceState {
|
|
|
962
1297
|
const c = this.c;
|
|
963
1298
|
if ((source.flags & TypeFlags.Conditional) !== 0) {
|
|
964
1299
|
const s = source as ConditionalType;
|
|
965
|
-
|
|
966
|
-
this.inferFromTypes(s.
|
|
967
|
-
this.inferFromTypes(
|
|
968
|
-
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
|
+
);
|
|
969
1311
|
} else {
|
|
970
1312
|
const savePriority = this.priority;
|
|
971
1313
|
this.priority |= this.contravariant ? InferencePriority.ContravariantConditional : 0;
|
|
@@ -1308,11 +1650,45 @@ class InferenceState {
|
|
|
1308
1650
|
// ---- Helpers
|
|
1309
1651
|
|
|
1310
1652
|
function getInferenceInfoForType(inferences: InferenceInfo[], t: Type): InferenceInfo | undefined {
|
|
1311
|
-
if ((t.flags & TypeFlags.TypeVariable) !== 0)
|
|
1312
|
-
|
|
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
|
+
}
|
|
1313
1657
|
return undefined;
|
|
1314
1658
|
}
|
|
1315
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
|
+
|
|
1316
1692
|
function distributedTypes(t: Type): Type[] {
|
|
1317
1693
|
return (t.flags & TypeFlags.Union) !== 0 ? typesOf(t) : [t];
|
|
1318
1694
|
}
|
|
@@ -1335,15 +1711,21 @@ function someTypeCouldHoldInference(c: Checker, targets: readonly Type[]): boole
|
|
|
1335
1711
|
|
|
1336
1712
|
/**
|
|
1337
1713
|
* `couldContainTypeVariables` without two of its conservative answers: a deferred reference without an
|
|
1338
|
-
* alias
|
|
1339
|
-
*
|
|
1340
|
-
*
|
|
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.
|
|
1341
1718
|
*/
|
|
1342
1719
|
function couldHoldInference(c: Checker, t: Type, depth: number): boolean {
|
|
1343
1720
|
if (!couldContainTypeVariables(c, t)) return false;
|
|
1344
1721
|
if (t.alias !== undefined || depth === 4) return true;
|
|
1345
1722
|
if ((t.objectFlags & ObjectFlags.Reference) !== 0) {
|
|
1346
|
-
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);
|
|
1347
1729
|
if (resolved === undefined) return true;
|
|
1348
1730
|
for (const a of resolved) if (couldHoldInference(c, a, depth + 1)) return true;
|
|
1349
1731
|
return false;
|
|
@@ -1491,6 +1873,7 @@ function hasUnmatchedProperty(c: Checker, source: Type, target: Type, matchDiscr
|
|
|
1491
1873
|
sideOf(c, t as UnionOrIntersectionType).membersOf?.resolvedProperties !== undefined
|
|
1492
1874
|
)
|
|
1493
1875
|
return getUnmatchedProperty(c, source, target, false, matchDiscriminantProperties) !== undefined;
|
|
1876
|
+
if (c.unresolvedPropertySearches !== undefined) c.unresolvedPropertySearches.push(t);
|
|
1494
1877
|
const containingType = t as UnionOrIntersectionType;
|
|
1495
1878
|
const isUnion = (t.flags & TypeFlags.Union) !== 0;
|
|
1496
1879
|
const checked = new Set<string>();
|
|
@@ -1559,7 +1942,8 @@ export function isConstTypeVariable(c: Checker, t: Type | undefined, depth: numb
|
|
|
1559
1942
|
export function isMutableArrayLikeType(c: Checker, t: Type): boolean {
|
|
1560
1943
|
return (
|
|
1561
1944
|
isMutableArrayOrTuple(c, t) ||
|
|
1562
|
-
((t.flags & (TypeFlags.Any | TypeFlags.Nullable)) === 0 &&
|
|
1945
|
+
((t.flags & (TypeFlags.Any | TypeFlags.Nullable | TypeFlags.Never)) === 0 &&
|
|
1946
|
+
isTypeAssignableTo(c, t, c.anyArrayType))
|
|
1563
1947
|
);
|
|
1564
1948
|
}
|
|
1565
1949
|
|
|
@@ -1727,10 +2111,15 @@ export function isUnmatchedTemplateLiteralKey(source: Type, target: TemplateLite
|
|
|
1727
2111
|
}
|
|
1728
2112
|
|
|
1729
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
|
+
*/
|
|
1730
2118
|
export function inferTypesFromTemplateLiteralType(
|
|
1731
2119
|
c: Checker,
|
|
1732
2120
|
source: Type,
|
|
1733
2121
|
target: TemplateLiteralType,
|
|
2122
|
+
compareTypes?: TemplateTypeComparer,
|
|
1734
2123
|
): Type[] | undefined {
|
|
1735
2124
|
if ((source.flags & TypeFlags.StringLiteral) !== 0) {
|
|
1736
2125
|
// Most string literals fail the start and end text test; apply it before building the
|
|
@@ -1744,11 +2133,13 @@ export function inferTypesFromTemplateLiteralType(
|
|
|
1744
2133
|
const result: Type[] = [];
|
|
1745
2134
|
for (let i = 0; i < s.types.length; i++) {
|
|
1746
2135
|
const t = s.types[i]!;
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
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));
|
|
1752
2143
|
}
|
|
1753
2144
|
return result;
|
|
1754
2145
|
}
|
|
@@ -2208,7 +2599,12 @@ export function getInferredType(c: Checker, context: InferenceContext, index: nu
|
|
|
2208
2599
|
const constraint = getConstraintOfTypeParameter(c, inference.typeParameter);
|
|
2209
2600
|
if (constraint !== undefined) {
|
|
2210
2601
|
const instantiatedConstraint = instantiateType(c, constraint, context.nonFixingMapper);
|
|
2211
|
-
|
|
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
|
+
) {
|
|
2212
2608
|
const constraintWithThis = getTypeWithThisArgument(c, instantiatedConstraint, inferredType, false);
|
|
2213
2609
|
if (context.compareTypes.compare(inferredType, constraintWithThis, false) === Ternary.False) {
|
|
2214
2610
|
// A pure return type inference may still succeed without the constituents the constraint rejects.
|
|
@@ -2241,9 +2637,19 @@ function clearActiveMapperCaches(c: Checker): void {
|
|
|
2241
2637
|
for (const cache of c.activeMapperAliasCaches) if (cache !== undefined) cache.clear();
|
|
2242
2638
|
}
|
|
2243
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
|
+
|
|
2244
2645
|
/** Type ids below this bound pack in pairs into one exact number. */
|
|
2245
2646
|
const VisitKeyIdLimit = 1 << 26;
|
|
2246
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
|
+
|
|
2247
2653
|
/** invokeOnce's key for a pair of types: both ids in one number, or -1 when an id is too large. */
|
|
2248
2654
|
function visitKey(source: Type, target: Type): number {
|
|
2249
2655
|
const s = source.id;
|
|
@@ -2468,11 +2874,32 @@ export class InferenceCaches {
|
|
|
2468
2874
|
readonly contextFreeTypes = new Map<Node, Type>();
|
|
2469
2875
|
readonly reverseMapped = new Map<string, Type | undefined>();
|
|
2470
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;
|
|
2471
2889
|
/** inferReverseMappedType's recursion stacks; the first `reverseStackDepth` entries of each are live. */
|
|
2472
2890
|
readonly reverseSourceStack: Type[] = [];
|
|
2473
2891
|
readonly reverseTargetStack: Type[] = [];
|
|
2474
2892
|
reverseStackDepth = 0;
|
|
2475
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, []);
|
|
2476
2903
|
}
|
|
2477
2904
|
|
|
2478
2905
|
// ---- Constraints of `infer` type parameters
|