typescript 7.0.2 → 7.1.0-beta
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/NOTICE.txt +5 -36
- package/dist/api/async/api.d.ts +597 -122
- package/dist/api/async/api.d.ts.map +1 -1
- package/dist/api/async/api.js +1775 -333
- package/dist/api/async/api.js.map +1 -1
- package/dist/api/async/client.d.ts +18 -2
- package/dist/api/async/client.d.ts.map +1 -1
- package/dist/api/async/client.js +255 -68
- package/dist/api/async/client.js.map +1 -1
- package/dist/api/async/types.d.ts +99 -34
- package/dist/api/async/types.d.ts.map +1 -1
- package/dist/api/compilerOptions.generated.d.ts +123 -0
- package/dist/api/compilerOptions.generated.d.ts.map +1 -0
- package/dist/api/compilerOptions.generated.js +8 -0
- package/dist/api/compilerOptions.generated.js.map +1 -0
- package/dist/api/diagnosticFormatter.d.ts +9 -0
- package/dist/api/diagnosticFormatter.d.ts.map +1 -0
- package/dist/api/diagnosticFormatter.js +169 -0
- package/dist/api/diagnosticFormatter.js.map +1 -0
- package/dist/api/fs.d.ts +68 -13
- package/dist/api/fs.d.ts.map +1 -1
- package/dist/api/fs.js +62 -101
- package/dist/api/fs.js.map +1 -1
- package/dist/api/fsCallbacks.d.ts +27 -0
- package/dist/api/fsCallbacks.d.ts.map +1 -0
- package/dist/api/fsCallbacks.js +111 -0
- package/dist/api/fsCallbacks.js.map +1 -0
- package/dist/api/node/encoder.d.ts +3 -0
- package/dist/api/node/encoder.d.ts.map +1 -1
- package/dist/api/node/encoder.generated.js +2 -2
- package/dist/api/node/encoder.generated.js.map +1 -1
- package/dist/api/node/encoder.js +20 -15
- package/dist/api/node/encoder.js.map +1 -1
- package/dist/api/node/msgpack.d.ts.map +1 -1
- package/dist/api/node/msgpack.js +2 -3
- package/dist/api/node/msgpack.js.map +1 -1
- package/dist/api/node/node.d.ts +28 -9
- package/dist/api/node/node.d.ts.map +1 -1
- package/dist/api/node/node.generated.d.ts +9 -2
- package/dist/api/node/node.generated.d.ts.map +1 -1
- package/dist/api/node/node.generated.js +55 -6
- package/dist/api/node/node.generated.js.map +1 -1
- package/dist/api/node/node.infrastructure.d.ts +6 -4
- package/dist/api/node/node.infrastructure.d.ts.map +1 -1
- package/dist/api/node/node.infrastructure.js +20 -40
- package/dist/api/node/node.infrastructure.js.map +1 -1
- package/dist/api/node/node.js +178 -23
- package/dist/api/node/node.js.map +1 -1
- package/dist/api/node/protocol.d.ts +5 -2
- package/dist/api/node/protocol.d.ts.map +1 -1
- package/dist/api/node/protocol.generated.js +2 -2
- package/dist/api/node/protocol.generated.js.map +1 -1
- package/dist/api/node/protocol.js +5 -2
- package/dist/api/node/protocol.js.map +1 -1
- package/dist/api/node/wtf8.d.ts +6 -2
- package/dist/api/node/wtf8.d.ts.map +1 -1
- package/dist/api/node/wtf8.js +71 -2
- package/dist/api/node/wtf8.js.map +1 -1
- package/dist/api/options.d.ts +19 -7
- package/dist/api/options.d.ts.map +1 -1
- package/dist/api/options.js +21 -0
- package/dist/api/options.js.map +1 -1
- package/dist/api/path.d.ts +49 -39
- package/dist/api/path.d.ts.map +1 -1
- package/dist/api/path.js +409 -33
- package/dist/api/path.js.map +1 -1
- package/dist/api/prepareCompilerOptions.generated.d.ts +5 -0
- package/dist/api/prepareCompilerOptions.generated.d.ts.map +1 -0
- package/dist/api/prepareCompilerOptions.generated.js +24 -0
- package/dist/api/prepareCompilerOptions.generated.js.map +1 -0
- package/dist/api/proto.d.ts +58 -217
- package/dist/api/proto.d.ts.map +1 -1
- package/dist/api/proto.generated.d.ts +1419 -0
- package/dist/api/proto.generated.d.ts.map +1 -0
- package/dist/api/proto.generated.js +21 -0
- package/dist/api/proto.generated.js.map +1 -0
- package/dist/api/proto.js +28 -15
- package/dist/api/proto.js.map +1 -1
- package/dist/api/sourceFileCache.d.ts +51 -20
- package/dist/api/sourceFileCache.d.ts.map +1 -1
- package/dist/api/sourceFileCache.js +168 -37
- package/dist/api/sourceFileCache.js.map +1 -1
- package/dist/api/sync/api.d.ts +1365 -220
- package/dist/api/sync/api.d.ts.map +1 -1
- package/dist/api/sync/api.js +4673 -930
- package/dist/api/sync/api.js.map +1 -1
- package/dist/api/sync/client.d.ts +8 -2
- package/dist/api/sync/client.d.ts.map +1 -1
- package/dist/api/sync/client.js +80 -30
- package/dist/api/sync/client.js.map +1 -1
- package/dist/api/sync/generatorSupport.d.ts +32 -0
- package/dist/api/sync/generatorSupport.d.ts.map +1 -0
- package/dist/api/sync/generatorSupport.js +338 -0
- package/dist/api/sync/generatorSupport.js.map +1 -0
- package/dist/api/sync/types.d.ts +248 -56
- package/dist/api/sync/types.d.ts.map +1 -1
- package/dist/api/syncChannel.d.ts +3 -0
- package/dist/api/syncChannel.d.ts.map +1 -1
- package/dist/api/syncChannel.js +20 -2
- package/dist/api/syncChannel.js.map +1 -1
- package/dist/api/timing.d.ts +2 -2
- package/dist/api/timing.d.ts.map +1 -1
- package/dist/api/timing.js +1 -1
- package/dist/api/timing.js.map +1 -1
- package/dist/api/timingDump.d.ts +13 -0
- package/dist/api/timingDump.d.ts.map +1 -0
- package/dist/api/timingDump.js +38 -0
- package/dist/api/timingDump.js.map +1 -0
- package/dist/api/typedPaths.d.ts +3 -0
- package/dist/api/typedPaths.d.ts.map +1 -0
- package/dist/api/typedPaths.js +2 -0
- package/dist/api/typedPaths.js.map +1 -0
- package/dist/api/userPreferences.generated.d.ts +195 -0
- package/dist/api/userPreferences.generated.d.ts.map +1 -0
- package/dist/api/userPreferences.generated.js +3 -0
- package/dist/api/userPreferences.generated.js.map +1 -0
- package/dist/ast/ast.d.ts +90 -7
- package/dist/ast/ast.d.ts.map +1 -1
- package/dist/ast/ast.generated.d.ts +45 -39
- package/dist/ast/ast.generated.d.ts.map +1 -1
- package/dist/ast/ast.generated.js +1 -1
- package/dist/ast/ast.generated.js.map +1 -1
- package/dist/ast/ast.js +1 -0
- package/dist/ast/ast.js.map +1 -1
- package/dist/ast/astnav.d.ts +3 -2
- package/dist/ast/astnav.d.ts.map +1 -1
- package/dist/ast/astnav.js +148 -3
- package/dist/ast/astnav.js.map +1 -1
- package/dist/ast/factory.generated.d.ts +8 -154
- package/dist/ast/factory.generated.d.ts.map +1 -1
- package/dist/ast/factory.generated.js +2701 -7
- package/dist/ast/factory.generated.js.map +1 -1
- package/dist/ast/index.d.ts +5 -0
- package/dist/ast/index.d.ts.map +1 -1
- package/dist/ast/index.js +5 -0
- package/dist/ast/index.js.map +1 -1
- package/dist/ast/is.d.ts +2 -12
- package/dist/ast/is.d.ts.map +1 -1
- package/dist/ast/is.generated.d.ts +889 -1
- package/dist/ast/is.generated.d.ts.map +1 -1
- package/dist/ast/is.generated.js +300 -3
- package/dist/ast/is.generated.js.map +1 -1
- package/dist/ast/is.js +224 -1
- package/dist/ast/is.js.map +1 -1
- package/dist/ast/jsdoc.d.ts +2 -1
- package/dist/ast/jsdoc.d.ts.map +1 -1
- package/dist/ast/jsdoc.js +14 -8
- package/dist/ast/jsdoc.js.map +1 -1
- package/dist/ast/modifiers.d.ts +4 -0
- package/dist/ast/modifiers.d.ts.map +1 -0
- package/dist/ast/modifiers.js +41 -0
- package/dist/ast/modifiers.js.map +1 -0
- package/dist/ast/scanner.d.ts.map +1 -1
- package/dist/ast/scanner.js +2 -1
- package/dist/ast/scanner.js.map +1 -1
- package/dist/ast/spanMap.d.ts +88 -0
- package/dist/ast/spanMap.d.ts.map +1 -0
- package/dist/ast/spanMap.js +417 -0
- package/dist/ast/spanMap.js.map +1 -0
- package/dist/ast/utils.d.ts +14 -1
- package/dist/ast/utils.d.ts.map +1 -1
- package/dist/ast/utils.js +251 -0
- package/dist/ast/utils.js.map +1 -1
- package/dist/ast/visitor.d.ts +2 -0
- package/dist/ast/visitor.d.ts.map +1 -1
- package/dist/ast/visitor.generated.d.ts.map +1 -1
- package/dist/ast/visitor.generated.js +5 -4
- package/dist/ast/visitor.generated.js.map +1 -1
- package/dist/ast/visitor.js +40 -0
- package/dist/ast/visitor.js.map +1 -1
- package/dist/enums/caseSensitivity.d.ts +2 -0
- package/dist/enums/caseSensitivity.d.ts.map +1 -0
- package/dist/enums/caseSensitivity.enum.d.ts +5 -0
- package/dist/enums/caseSensitivity.enum.d.ts.map +1 -0
- package/dist/enums/caseSensitivity.enum.js +7 -0
- package/dist/enums/caseSensitivity.enum.js.map +1 -0
- package/dist/enums/caseSensitivity.js +7 -0
- package/dist/enums/caseSensitivity.js.map +1 -0
- package/dist/enums/checkFlags.d.ts +2 -0
- package/dist/enums/checkFlags.d.ts.map +1 -0
- package/dist/enums/checkFlags.enum.d.ts +34 -0
- package/dist/enums/checkFlags.enum.d.ts.map +1 -0
- package/dist/enums/checkFlags.enum.js +36 -0
- package/dist/enums/checkFlags.enum.js.map +1 -0
- package/dist/enums/checkFlags.js +36 -0
- package/dist/enums/checkFlags.js.map +1 -0
- package/dist/enums/completionItemKind.enum.js +1 -1
- package/dist/enums/completionItemKind.enum.js.map +1 -1
- package/dist/enums/completionItemKind.js +1 -1
- package/dist/enums/completionItemKind.js.map +1 -1
- package/dist/enums/diagnosticCategory.enum.js +1 -1
- package/dist/enums/diagnosticCategory.enum.js.map +1 -1
- package/dist/enums/diagnosticCategory.js +1 -1
- package/dist/enums/diagnosticCategory.js.map +1 -1
- package/dist/enums/diagnosticDirectivePolicy.d.ts +2 -0
- package/dist/enums/diagnosticDirectivePolicy.d.ts.map +1 -0
- package/dist/enums/diagnosticDirectivePolicy.enum.d.ts +5 -0
- package/dist/enums/diagnosticDirectivePolicy.enum.d.ts.map +1 -0
- package/dist/enums/diagnosticDirectivePolicy.enum.js +7 -0
- package/dist/enums/diagnosticDirectivePolicy.enum.js.map +1 -0
- package/dist/enums/diagnosticDirectivePolicy.js +7 -0
- package/dist/enums/diagnosticDirectivePolicy.js.map +1 -0
- package/dist/enums/elementFlags.enum.js +1 -1
- package/dist/enums/elementFlags.enum.js.map +1 -1
- package/dist/enums/elementFlags.js +1 -1
- package/dist/enums/elementFlags.js.map +1 -1
- package/dist/enums/emitOnly.d.ts +2 -0
- package/dist/enums/emitOnly.d.ts.map +1 -0
- package/dist/enums/emitOnly.enum.d.ts +6 -0
- package/dist/enums/emitOnly.enum.d.ts.map +1 -0
- package/dist/enums/emitOnly.enum.js +8 -0
- package/dist/enums/emitOnly.enum.js.map +1 -0
- package/dist/enums/emitOnly.js +8 -0
- package/dist/enums/emitOnly.js.map +1 -0
- package/dist/enums/indexKind.d.ts +2 -0
- package/dist/enums/indexKind.d.ts.map +1 -0
- package/dist/enums/indexKind.enum.d.ts +5 -0
- package/dist/enums/indexKind.enum.d.ts.map +1 -0
- package/dist/enums/indexKind.enum.js +7 -0
- package/dist/enums/indexKind.enum.js.map +1 -0
- package/dist/enums/indexKind.js +7 -0
- package/dist/enums/indexKind.js.map +1 -0
- package/dist/enums/internalSymbolName.enum.js +1 -1
- package/dist/enums/internalSymbolName.enum.js.map +1 -1
- package/dist/enums/internalSymbolName.js +1 -1
- package/dist/enums/internalSymbolName.js.map +1 -1
- package/dist/enums/jsDeclarationKind.d.ts +2 -0
- package/dist/enums/jsDeclarationKind.d.ts.map +1 -0
- package/dist/enums/jsDeclarationKind.enum.d.ts +10 -0
- package/dist/enums/jsDeclarationKind.enum.d.ts.map +1 -0
- package/dist/enums/jsDeclarationKind.enum.js +12 -0
- package/dist/enums/jsDeclarationKind.enum.js.map +1 -0
- package/dist/enums/jsDeclarationKind.js +12 -0
- package/dist/enums/jsDeclarationKind.js.map +1 -0
- package/dist/enums/jsxEmit.enum.d.ts +2 -2
- package/dist/enums/jsxEmit.enum.d.ts.map +1 -1
- package/dist/enums/jsxEmit.enum.js +3 -3
- package/dist/enums/jsxEmit.enum.js.map +1 -1
- package/dist/enums/jsxEmit.js +3 -3
- package/dist/enums/jsxEmit.js.map +1 -1
- package/dist/enums/modifierFlags.enum.js +1 -1
- package/dist/enums/modifierFlags.enum.js.map +1 -1
- package/dist/enums/modifierFlags.js +1 -1
- package/dist/enums/modifierFlags.js.map +1 -1
- package/dist/enums/moduleDetectionKind.enum.js +1 -1
- package/dist/enums/moduleDetectionKind.enum.js.map +1 -1
- package/dist/enums/moduleDetectionKind.js +1 -1
- package/dist/enums/moduleDetectionKind.js.map +1 -1
- package/dist/enums/moduleKind.enum.js +1 -1
- package/dist/enums/moduleKind.enum.js.map +1 -1
- package/dist/enums/moduleKind.js +1 -1
- package/dist/enums/moduleKind.js.map +1 -1
- package/dist/enums/moduleResolutionKind.enum.js +1 -1
- package/dist/enums/moduleResolutionKind.enum.js.map +1 -1
- package/dist/enums/moduleResolutionKind.js +1 -1
- package/dist/enums/moduleResolutionKind.js.map +1 -1
- package/dist/enums/newLineKind.enum.js +1 -1
- package/dist/enums/newLineKind.enum.js.map +1 -1
- package/dist/enums/newLineKind.js +1 -1
- package/dist/enums/newLineKind.js.map +1 -1
- package/dist/enums/nodeBuilderFlags.enum.js +1 -1
- package/dist/enums/nodeBuilderFlags.enum.js.map +1 -1
- package/dist/enums/nodeBuilderFlags.js +1 -1
- package/dist/enums/nodeBuilderFlags.js.map +1 -1
- package/dist/enums/nodeFlags.enum.js +1 -1
- package/dist/enums/nodeFlags.enum.js.map +1 -1
- package/dist/enums/nodeFlags.js +1 -1
- package/dist/enums/nodeFlags.js.map +1 -1
- package/dist/enums/objectFlags.enum.d.ts +3 -2
- package/dist/enums/objectFlags.enum.d.ts.map +1 -1
- package/dist/enums/objectFlags.enum.js +4 -3
- package/dist/enums/objectFlags.enum.js.map +1 -1
- package/dist/enums/objectFlags.js +4 -3
- package/dist/enums/objectFlags.js.map +1 -1
- package/dist/enums/outerExpressionKinds.enum.js +1 -1
- package/dist/enums/outerExpressionKinds.enum.js.map +1 -1
- package/dist/enums/outerExpressionKinds.js +1 -1
- package/dist/enums/outerExpressionKinds.js.map +1 -1
- package/dist/enums/scriptKind.d.ts.map +1 -1
- package/dist/enums/scriptKind.enum.d.ts +1 -3
- package/dist/enums/scriptKind.enum.d.ts.map +1 -1
- package/dist/enums/scriptKind.enum.js +1 -2
- package/dist/enums/scriptKind.enum.js.map +1 -1
- package/dist/enums/scriptKind.js +1 -2
- package/dist/enums/scriptKind.js.map +1 -1
- package/dist/enums/scriptTarget.d.ts.map +1 -1
- package/dist/enums/scriptTarget.enum.d.ts +1 -0
- package/dist/enums/scriptTarget.enum.d.ts.map +1 -1
- package/dist/enums/scriptTarget.enum.js +2 -0
- package/dist/enums/scriptTarget.enum.js.map +1 -1
- package/dist/enums/scriptTarget.js +2 -0
- package/dist/enums/scriptTarget.js.map +1 -1
- package/dist/enums/signatureFlags.enum.js +1 -1
- package/dist/enums/signatureFlags.enum.js.map +1 -1
- package/dist/enums/signatureFlags.js +1 -1
- package/dist/enums/signatureFlags.js.map +1 -1
- package/dist/enums/signatureKind.enum.js +1 -1
- package/dist/enums/signatureKind.enum.js.map +1 -1
- package/dist/enums/signatureKind.js +1 -1
- package/dist/enums/signatureKind.js.map +1 -1
- package/dist/enums/spanMapFeature.d.ts +2 -0
- package/dist/enums/spanMapFeature.d.ts.map +1 -0
- package/dist/enums/spanMapFeature.enum.d.ts +25 -0
- package/dist/enums/spanMapFeature.enum.d.ts.map +1 -0
- package/dist/enums/spanMapFeature.enum.js +27 -0
- package/dist/enums/spanMapFeature.enum.js.map +1 -0
- package/dist/enums/spanMapFeature.js +27 -0
- package/dist/enums/spanMapFeature.js.map +1 -0
- package/dist/enums/spanMapFidelity.d.ts +2 -0
- package/dist/enums/spanMapFidelity.d.ts.map +1 -0
- package/dist/enums/spanMapFidelity.enum.d.ts +7 -0
- package/dist/enums/spanMapFidelity.enum.d.ts.map +1 -0
- package/dist/enums/spanMapFidelity.enum.js +9 -0
- package/dist/enums/spanMapFidelity.enum.js.map +1 -0
- package/dist/enums/spanMapFidelity.js +9 -0
- package/dist/enums/spanMapFidelity.js.map +1 -0
- package/dist/enums/spanMapKind.d.ts +2 -0
- package/dist/enums/spanMapKind.d.ts.map +1 -0
- package/dist/enums/spanMapKind.enum.d.ts +6 -0
- package/dist/enums/spanMapKind.enum.d.ts.map +1 -0
- package/dist/enums/spanMapKind.enum.js +8 -0
- package/dist/enums/spanMapKind.enum.js.map +1 -0
- package/dist/enums/spanMapKind.js +8 -0
- package/dist/enums/spanMapKind.js.map +1 -0
- package/dist/enums/symbolFlags.enum.d.ts +1 -2
- package/dist/enums/symbolFlags.enum.d.ts.map +1 -1
- package/dist/enums/symbolFlags.enum.js +2 -3
- package/dist/enums/symbolFlags.enum.js.map +1 -1
- package/dist/enums/symbolFlags.js +2 -3
- package/dist/enums/symbolFlags.js.map +1 -1
- package/dist/enums/symbolOwnerKind.d.ts +2 -0
- package/dist/enums/symbolOwnerKind.d.ts.map +1 -0
- package/dist/enums/symbolOwnerKind.enum.d.ts +5 -0
- package/dist/enums/symbolOwnerKind.enum.d.ts.map +1 -0
- package/dist/enums/symbolOwnerKind.enum.js +7 -0
- package/dist/enums/symbolOwnerKind.enum.js.map +1 -0
- package/dist/enums/symbolOwnerKind.js +7 -0
- package/dist/enums/symbolOwnerKind.js.map +1 -0
- package/dist/enums/syntaxKind.enum.d.ts +198 -197
- package/dist/enums/syntaxKind.enum.d.ts.map +1 -1
- package/dist/enums/syntaxKind.enum.js +199 -198
- package/dist/enums/syntaxKind.enum.js.map +1 -1
- package/dist/enums/syntaxKind.js +199 -198
- package/dist/enums/syntaxKind.js.map +1 -1
- package/dist/enums/tokenFlags.enum.js +1 -1
- package/dist/enums/tokenFlags.enum.js.map +1 -1
- package/dist/enums/tokenFlags.js +1 -1
- package/dist/enums/tokenFlags.js.map +1 -1
- package/dist/enums/typeFlags.enum.js +1 -1
- package/dist/enums/typeFlags.enum.js.map +1 -1
- package/dist/enums/typeFlags.js +1 -1
- package/dist/enums/typeFlags.js.map +1 -1
- package/dist/enums/typeFormatFlags.d.ts +2 -0
- package/dist/enums/typeFormatFlags.d.ts.map +1 -0
- package/dist/enums/typeFormatFlags.enum.d.ts +29 -0
- package/dist/enums/typeFormatFlags.enum.d.ts.map +1 -0
- package/dist/enums/typeFormatFlags.enum.js +31 -0
- package/dist/enums/typeFormatFlags.enum.js.map +1 -0
- package/dist/enums/typeFormatFlags.js +31 -0
- package/dist/enums/typeFormatFlags.js.map +1 -0
- package/dist/enums/typePredicateKind.enum.js +1 -1
- package/dist/enums/typePredicateKind.enum.js.map +1 -1
- package/dist/enums/typePredicateKind.js +1 -1
- package/dist/enums/typePredicateKind.js.map +1 -1
- package/dist/internal/utils.js.map +1 -1
- package/dist/vscode/extensionApi.d.ts +101 -0
- package/dist/vscode/extensionApi.d.ts.map +1 -0
- package/dist/vscode/extensionApi.js +2 -0
- package/dist/vscode/extensionApi.js.map +1 -0
- package/dist/vscode/moduleLoader.d.ts +14 -0
- package/dist/vscode/moduleLoader.d.ts.map +1 -0
- package/dist/vscode/moduleLoader.js +36 -0
- package/dist/vscode/moduleLoader.js.map +1 -0
- package/dist/vscode/protocol.generated.d.ts +2886 -0
- package/dist/vscode/protocol.generated.d.ts.map +1 -0
- package/dist/vscode/protocol.generated.js +4 -0
- package/dist/vscode/protocol.generated.js.map +1 -0
- package/lib/getExePath.js +2 -2
- package/lib/version.cjs +1 -1
- package/lib/version.d.cts +1 -1
- package/package.json +40 -34
- package/schemas/jsconfig.schema.json +2207 -0
- package/schemas/tsconfig.schema.json +2206 -0
- package/vendor/vscode-jsonrpc/lib/node/main.js +1 -1
- package/vendor/vscode-jsonrpc/package.json +1 -1
- package/dist/api/compilerOptions.d.ts +0 -109
- package/dist/api/compilerOptions.d.ts.map +0 -1
- package/dist/api/compilerOptions.js +0 -2
- package/dist/api/compilerOptions.js.map +0 -1
package/dist/api/async/api.js
CHANGED
|
@@ -1,37 +1,124 @@
|
|
|
1
|
-
|
|
1
|
+
import { CheckFlags } from "#enums/checkFlags";
|
|
2
2
|
import { CompletionItemKind } from "#enums/completionItemKind";
|
|
3
3
|
import { DiagnosticCategory } from "#enums/diagnosticCategory";
|
|
4
4
|
import { ElementFlags } from "#enums/elementFlags";
|
|
5
|
+
import { EmitOnly } from "#enums/emitOnly";
|
|
6
|
+
import { IndexKind } from "#enums/indexKind";
|
|
7
|
+
import { JsxEmit } from "#enums/jsxEmit";
|
|
5
8
|
import { ModuleKind } from "#enums/moduleKind";
|
|
9
|
+
import { ModuleResolutionKind } from "#enums/moduleResolutionKind";
|
|
10
|
+
import { NewLineKind } from "#enums/newLineKind";
|
|
6
11
|
import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";
|
|
7
12
|
import { ObjectFlags } from "#enums/objectFlags";
|
|
13
|
+
import { ScriptKind } from "#enums/scriptKind";
|
|
8
14
|
import { SignatureFlags } from "#enums/signatureFlags";
|
|
9
15
|
import { SignatureKind } from "#enums/signatureKind";
|
|
10
16
|
import { SymbolFlags } from "#enums/symbolFlags";
|
|
17
|
+
import { SymbolOwnerKind } from "#enums/symbolOwnerKind";
|
|
11
18
|
import { TypeFlags } from "#enums/typeFlags";
|
|
19
|
+
import { TypeFormatFlags } from "#enums/typeFormatFlags";
|
|
12
20
|
import { TypePredicateKind } from "#enums/typePredicateKind";
|
|
13
21
|
import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
|
|
22
|
+
import { assertNever } from "../../internal/utils.js";
|
|
14
23
|
import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
|
|
15
|
-
import { decodeNode, getNodeId,
|
|
24
|
+
import { decodeNode, getNodeId, parseNodeHandleFromCompiler, readParseOptionsKey, readSourceFileHash, readSourceFileLease, RemoteNode, RemoteSourceFile, } from "../node/node.js";
|
|
16
25
|
import { Wtf8Decoder } from "../node/wtf8.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
26
|
+
import { canonicalize, CaseSensitivity, pathKey, toRootedDirectoryPath, toRootedPath, } from "../path.js";
|
|
27
|
+
import { prepareCompilerOptions } from "../prepareCompilerOptions.generated.js";
|
|
28
|
+
import { resolveFileName, validateSymbolResponse, } from "../proto.js";
|
|
29
|
+
import { SourceFileCache, } from "../sourceFileCache.js";
|
|
20
30
|
import { Client, } from "./client.js";
|
|
31
|
+
export { formatDiagnostics, formatDiagnosticsWithColorAndContext } from "../diagnosticFormatter.js";
|
|
21
32
|
export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
|
|
22
|
-
export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, ModuleKind, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
|
|
33
|
+
export { CheckFlags, CompletionItemKind, DiagnosticCategory, ElementFlags, EmitOnly, IndexKind, JsxEmit, ModifierFlags, ModuleKind, ModuleResolutionKind, NodeBuilderFlags, ObjectFlags, ScriptKind, SignatureFlags, SignatureKind, SymbolFlags, SymbolOwnerKind, TypeFlags, TypeFormatFlags, TypePredicateKind };
|
|
34
|
+
let nextModuleResolutionCallbackId = 0;
|
|
35
|
+
function registerModuleResolutionCallback(client, callback, getSnapshot) {
|
|
36
|
+
const name = `resolveModuleName/${++nextModuleResolutionCallbackId}`;
|
|
37
|
+
const dispose = client.registerCallback(name, params => {
|
|
38
|
+
const { moduleName, containingDirectory, resolutionMode, snapshot: snapshotId, inProgressSnapshot } = params;
|
|
39
|
+
let snapshot = snapshotId === undefined ? undefined : getSnapshot(snapshotId);
|
|
40
|
+
if (snapshotId !== undefined && snapshot === undefined) {
|
|
41
|
+
throw new Error(`Snapshot ${snapshotId} is inactive`);
|
|
42
|
+
}
|
|
43
|
+
if (inProgressSnapshot !== undefined) {
|
|
44
|
+
snapshot = -inProgressSnapshot;
|
|
45
|
+
}
|
|
46
|
+
return callback(moduleName, containingDirectory, resolutionMode, { snapshot });
|
|
47
|
+
});
|
|
48
|
+
return { name, dispose };
|
|
49
|
+
}
|
|
50
|
+
// @sync-only-start
|
|
51
|
+
// export { all, defer, type APIRequestGenerator, type AnyAPIRequestGenerator, type AllAPIRequestGenerator, type DeferredAPIRequestGenerator, type ExecutedGeneratorsResults } from "./generatorSupport.ts";
|
|
52
|
+
// import {executeRequestGenerators, type ExecutedGeneratorsResults, type AnyAPIRequestGenerator} from "./generatorSupport.ts";
|
|
53
|
+
// import { sourceFileResponseToUint8Array } from "../node/encoder.ts";
|
|
54
|
+
// @sync-only-end
|
|
23
55
|
export class API {
|
|
56
|
+
/** @internal */
|
|
24
57
|
client;
|
|
58
|
+
/** @internal */
|
|
25
59
|
sourceFileCache;
|
|
26
60
|
toPath;
|
|
61
|
+
decoder = new Wtf8Decoder();
|
|
62
|
+
currentDirectory;
|
|
63
|
+
caseSensitivity;
|
|
27
64
|
initialized = false;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
65
|
+
initializing;
|
|
66
|
+
activeSnapshots = new Map();
|
|
67
|
+
activeBuildOrchestrators = new Set();
|
|
68
|
+
activeSourceFileLeases = new Map();
|
|
69
|
+
printer;
|
|
70
|
+
debug;
|
|
31
71
|
constructor(options = {}) {
|
|
32
72
|
this.client = new Client(options);
|
|
33
73
|
this.sourceFileCache = new SourceFileCache();
|
|
34
|
-
this.
|
|
74
|
+
this.printer = new Printer(this.client);
|
|
75
|
+
this.debug = new DebugHandlers(this.client, () => this.ensureInitialized()); // @sync: this.debug = new DebugHandlers(this.client, this.ensureInitialized);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Looks up a remote declaration's binder symbol. Throws for synthesized or configuration ASTs.
|
|
79
|
+
*/
|
|
80
|
+
async getSymbol(declaration) {
|
|
81
|
+
const file = getRemoteSourceFile(declaration);
|
|
82
|
+
if (!file)
|
|
83
|
+
throw new Error(`Source file not found for declaration`);
|
|
84
|
+
const record = file.symbolCache;
|
|
85
|
+
if (!record)
|
|
86
|
+
throw new Error(`Cached source file not found for declaration`);
|
|
87
|
+
const index = parseNodeHandleFromCompiler(getNodeId(declaration)).index;
|
|
88
|
+
const cached = record.symbolsByDeclarationNodeIndex.get(index);
|
|
89
|
+
if (cached)
|
|
90
|
+
return cached;
|
|
91
|
+
// @sync-only-start
|
|
92
|
+
// return this.fetchDeclarationSymbol(record, index);
|
|
93
|
+
// @sync-only-end
|
|
94
|
+
// @sync-skip-block-start
|
|
95
|
+
let request = record.declarationSymbolRequests.get(index);
|
|
96
|
+
if (!request) {
|
|
97
|
+
request = this.fetchDeclarationSymbol(record, index);
|
|
98
|
+
record.declarationSymbolRequests.set(index, request);
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
return await request;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
record.declarationSymbolRequests.delete(index);
|
|
105
|
+
}
|
|
106
|
+
// @sync-skip-block-end
|
|
107
|
+
}
|
|
108
|
+
async fetchDeclarationSymbol(record, index) {
|
|
109
|
+
const data = await this.client.apiRequest("getSymbolOfDeclaration", {
|
|
110
|
+
file: record.descriptor,
|
|
111
|
+
index,
|
|
112
|
+
});
|
|
113
|
+
validateSymbolResponse(data);
|
|
114
|
+
const reference = data.reference;
|
|
115
|
+
if (reference.kind !== SymbolOwnerKind.File) {
|
|
116
|
+
throw new Error(`Symbol ${reference.id} is not file-owned`);
|
|
117
|
+
}
|
|
118
|
+
const fileOwner = { record, api: this };
|
|
119
|
+
const symbol = this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
|
|
120
|
+
record.symbolsByDeclarationNodeIndex.set(index, symbol);
|
|
121
|
+
return symbol;
|
|
35
122
|
}
|
|
36
123
|
/**
|
|
37
124
|
* Create an API instance from an existing LSP connection's API session.
|
|
@@ -42,56 +129,323 @@ export class API {
|
|
|
42
129
|
await api.ensureInitialized();
|
|
43
130
|
return api;
|
|
44
131
|
}
|
|
132
|
+
// @sync-skip-block-start
|
|
133
|
+
batchContext() {
|
|
134
|
+
return this.client.batchContext();
|
|
135
|
+
}
|
|
136
|
+
// @sync-skip-block-end
|
|
137
|
+
// @sync-only-start
|
|
138
|
+
// batch<T extends readonly AnyAPIRequestGenerator[]>(...requestGenerators: T): ExecutedGeneratorsResults<T> {
|
|
139
|
+
// return executeRequestGenerators(requestGenerators, requests => this.client.batchRequests(requests).responses);
|
|
140
|
+
// }
|
|
141
|
+
// @sync-only-end
|
|
45
142
|
async ensureInitialized() {
|
|
46
|
-
if (
|
|
143
|
+
if (this.initialized)
|
|
144
|
+
return;
|
|
145
|
+
return this.initializing ??= this.initializeWorker();
|
|
146
|
+
}
|
|
147
|
+
async initializeWorker() {
|
|
148
|
+
try {
|
|
47
149
|
const response = await this.client.apiRequest("initialize", null);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.toPath = (fileName) =>
|
|
150
|
+
this.currentDirectory = response.currentDirectory;
|
|
151
|
+
this.caseSensitivity = response.caseSensitivity;
|
|
152
|
+
this.toPath = (fileName, basePath = response.currentDirectory) => pathKey(toRootedPath(fileName, toRootedDirectoryPath(basePath, response.currentDirectory)), response.caseSensitivity);
|
|
51
153
|
this.initialized = true;
|
|
52
154
|
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
this.initializing = undefined;
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
getCurrentDirectory() {
|
|
161
|
+
if (this.currentDirectory === undefined) {
|
|
162
|
+
throw new Error("API has not been initialized");
|
|
163
|
+
}
|
|
164
|
+
return this.currentDirectory;
|
|
165
|
+
}
|
|
166
|
+
getCanonicalFileName(fileName) {
|
|
167
|
+
return canonicalize(fileName, this.getCaseSensitivity());
|
|
168
|
+
}
|
|
169
|
+
getCaseSensitivity() {
|
|
170
|
+
if (this.caseSensitivity === undefined) {
|
|
171
|
+
throw new Error("API has not been initialized");
|
|
172
|
+
}
|
|
173
|
+
return this.caseSensitivity;
|
|
174
|
+
}
|
|
175
|
+
getNewLine() {
|
|
176
|
+
return "\n";
|
|
177
|
+
}
|
|
178
|
+
/** @internal */
|
|
179
|
+
async createBuildOrchestrator(rootNames, buildOrchestratorOptions) {
|
|
180
|
+
await this.ensureInitialized();
|
|
181
|
+
const orchestratorResponse = await this.client.apiRequest("createBuildOrchestrator", {
|
|
182
|
+
...buildOrchestratorOptions,
|
|
183
|
+
...buildOrchestratorOptions.overrideCompilerOptions,
|
|
184
|
+
cwd: buildOrchestratorOptions.cwd === undefined
|
|
185
|
+
? undefined
|
|
186
|
+
: toRootedDirectoryPath(buildOrchestratorOptions.cwd, this.getCurrentDirectory()),
|
|
187
|
+
rootNames,
|
|
188
|
+
});
|
|
189
|
+
const orchestrator = new BuildOrchestrator(this.client, orchestratorResponse, () => {
|
|
190
|
+
this.activeBuildOrchestrators.delete(orchestrator);
|
|
191
|
+
});
|
|
192
|
+
this.activeBuildOrchestrators.add(orchestrator);
|
|
193
|
+
return orchestrator;
|
|
53
194
|
}
|
|
54
195
|
async parseConfigFile(file) {
|
|
55
196
|
await this.ensureInitialized();
|
|
56
197
|
return this.client.apiRequest("parseConfigFile", { file });
|
|
57
198
|
}
|
|
58
|
-
async
|
|
199
|
+
async parseCommandLine(commandLine) {
|
|
59
200
|
await this.ensureInitialized();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
201
|
+
return this.client.apiRequest("parseCommandLine", { commandLine });
|
|
202
|
+
}
|
|
203
|
+
async readConfigFile(file) {
|
|
204
|
+
await this.ensureInitialized();
|
|
205
|
+
return this.client.apiRequest("readConfigFile", { file });
|
|
206
|
+
}
|
|
207
|
+
async parseJsonConfigFileContent(json, options) {
|
|
208
|
+
await this.ensureInitialized();
|
|
209
|
+
return this.client.apiRequest("parseJsonConfigFileContent", { json, ...options });
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Create and retain a source file independently of a program.
|
|
213
|
+
* Dispose the returned lease when the source file no longer needs to remain available remotely.
|
|
214
|
+
*/
|
|
215
|
+
async createSourceFile(fileName, sourceText, options = {}) {
|
|
216
|
+
await this.ensureInitialized();
|
|
217
|
+
const data = await this.client.apiRequestBinary("createSourceFile", { fileName, sourceText, options });
|
|
218
|
+
if (!data) {
|
|
219
|
+
throw new Error("createSourceFile returned no source file");
|
|
68
220
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
221
|
+
return this.retainSourceFileResponse(data);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Read, create, and retain a source file independently of a program.
|
|
225
|
+
* Dispose the returned lease when the source file no longer needs to remain available remotely.
|
|
226
|
+
*/
|
|
227
|
+
async createSourceFileFromFile(file, options = {}) {
|
|
228
|
+
await this.ensureInitialized();
|
|
229
|
+
const data = await this.client.apiRequestBinary("createSourceFileFromFile", { fileName: resolveFileName(file), options });
|
|
230
|
+
if (!data) {
|
|
231
|
+
throw new Error("createSourceFileFromFile returned no source file");
|
|
232
|
+
}
|
|
233
|
+
return this.retainSourceFileResponse(data);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Retain an ordinary remote source file independently of the snapshot or lease that produced it.
|
|
237
|
+
*/
|
|
238
|
+
async retainSourceFile(sourceFile) {
|
|
239
|
+
await this.ensureInitialized();
|
|
240
|
+
if (!(sourceFile instanceof RemoteSourceFile)) {
|
|
241
|
+
throw new TypeError("Only remote source files can be retained");
|
|
242
|
+
}
|
|
243
|
+
const cached = this.sourceFileCache.get(sourceFile);
|
|
244
|
+
if (cached && cached !== sourceFile) {
|
|
245
|
+
throw new Error("Source file is no longer the canonical cached instance");
|
|
246
|
+
}
|
|
247
|
+
const result = await this.client.apiRequest("retainSourceFile", { file: sourceFileDescriptor(sourceFile) });
|
|
248
|
+
return this.addSourceFileLease(sourceFile, result.lease);
|
|
249
|
+
}
|
|
250
|
+
retainSourceFileResponse(data) {
|
|
251
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
252
|
+
const lease = readSourceFileLease(view);
|
|
253
|
+
try {
|
|
254
|
+
const decoded = new RemoteSourceFile(data, this.decoder, this.client.getTimingCollector(), this);
|
|
255
|
+
return this.addSourceFileLease(decoded, lease);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
// @sync-skip-block-start
|
|
259
|
+
void this.client.apiRequest("releaseSourceFile", { lease }).catch(() => { });
|
|
260
|
+
// @sync-skip-block-end
|
|
261
|
+
// @sync-only-start
|
|
262
|
+
// try {
|
|
263
|
+
// this.client.apiRequest("releaseSourceFile", { lease });
|
|
264
|
+
// }
|
|
265
|
+
// catch {}
|
|
266
|
+
// @sync-only-end
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
addSourceFileLease(sourceFile, lease) {
|
|
271
|
+
const cached = this.sourceFileCache.setForLease(sourceFile, lease);
|
|
272
|
+
const retained = new RetainedSourceFile(cached, lease, () => {
|
|
273
|
+
this.activeSourceFileLeases.delete(lease);
|
|
274
|
+
this.sourceFileCache.releaseLease(lease);
|
|
275
|
+
});
|
|
276
|
+
this.activeSourceFileLeases.set(lease, retained);
|
|
277
|
+
return retained;
|
|
278
|
+
}
|
|
279
|
+
async transpileModule(input, options = {}) {
|
|
280
|
+
await this.ensureInitialized();
|
|
281
|
+
return this.client.apiRequest("transpileModule", { input, options });
|
|
282
|
+
}
|
|
283
|
+
async transpileModuleFromFile(file, options = {}) {
|
|
284
|
+
await this.ensureInitialized();
|
|
285
|
+
return this.client.apiRequest("transpileModuleFromFile", { fileName: resolveFileName(file), options });
|
|
286
|
+
}
|
|
287
|
+
async transpileDeclaration(input, options = {}) {
|
|
288
|
+
await this.ensureInitialized();
|
|
289
|
+
return this.client.apiRequest("transpileDeclaration", { input, options });
|
|
290
|
+
}
|
|
291
|
+
async transpileDeclarationFromFile(file, options = {}) {
|
|
292
|
+
await this.ensureInitialized();
|
|
293
|
+
return this.client.apiRequest("transpileDeclarationFromFile", { fileName: resolveFileName(file), options });
|
|
294
|
+
}
|
|
295
|
+
async createSnapshot(params) {
|
|
296
|
+
await this.ensureInitialized();
|
|
297
|
+
const requestParams = this.prepareCreateSnapshotParams(params);
|
|
298
|
+
const data = await this.client.apiRequest("createSnapshot", requestParams);
|
|
299
|
+
const snapshot = new Snapshot(data, this.toPath, this, () => {
|
|
300
|
+
this.activeSnapshots.delete(snapshot.id);
|
|
301
|
+
this.sourceFileCache.releaseSnapshot(snapshot.id);
|
|
302
|
+
}, this.createSnapshotUpdater(() => snapshot), undefined);
|
|
303
|
+
this.activeSnapshots.set(snapshot.id, snapshot);
|
|
304
|
+
return snapshot;
|
|
305
|
+
}
|
|
306
|
+
async updateSnapshot(baseSnapshot, params) {
|
|
307
|
+
await this.ensureInitialized();
|
|
308
|
+
if (this.activeSnapshots.get(baseSnapshot.id) !== baseSnapshot || baseSnapshot.isDisposed()) {
|
|
309
|
+
throw new Error("Cannot update an inactive snapshot");
|
|
310
|
+
}
|
|
311
|
+
const data = await this.client.apiRequest("updateSnapshot", {
|
|
312
|
+
snapshot: baseSnapshot.id,
|
|
313
|
+
changes: this.prepareCreateSnapshotParams(params),
|
|
314
|
+
});
|
|
315
|
+
if (data.snapshot === baseSnapshot.id) {
|
|
316
|
+
await this.client.apiRequest("release", { snapshot: data.snapshot });
|
|
317
|
+
return baseSnapshot;
|
|
318
|
+
}
|
|
319
|
+
this.sourceFileCache.retainForSnapshot(data.snapshot, baseSnapshot.id, data.changes);
|
|
320
|
+
const snapshot = new Snapshot(data, this.toPath, this, () => {
|
|
321
|
+
this.activeSnapshots.delete(snapshot.id);
|
|
322
|
+
this.sourceFileCache.releaseSnapshot(snapshot.id);
|
|
323
|
+
}, this.createSnapshotUpdater(() => snapshot), baseSnapshot);
|
|
324
|
+
this.activeSnapshots.set(snapshot.id, snapshot);
|
|
325
|
+
return snapshot;
|
|
326
|
+
}
|
|
327
|
+
prepareCreateSnapshotParams(params) {
|
|
328
|
+
params ??= {};
|
|
329
|
+
const prepareOptions = (options) => {
|
|
330
|
+
if (!options)
|
|
331
|
+
return undefined;
|
|
332
|
+
const { moduleResolver, projectReferences, ...rest } = options;
|
|
333
|
+
moduleResolver?.ensureNotDisposed();
|
|
334
|
+
return {
|
|
335
|
+
...rest,
|
|
336
|
+
moduleResolver: moduleResolver?.id,
|
|
337
|
+
projectReferences: projectReferences?.map(reference => ({
|
|
338
|
+
...reference,
|
|
339
|
+
path: toRootedPath(reference.path, this.getCurrentDirectory()),
|
|
340
|
+
})),
|
|
341
|
+
};
|
|
342
|
+
};
|
|
343
|
+
return {
|
|
344
|
+
...params,
|
|
345
|
+
createPrograms: params.createPrograms?.map(program => ({ ...program, options: prepareOptions(program.options) })),
|
|
346
|
+
reconfigurePrograms: params.reconfigurePrograms?.map(program => ({ ...program, options: prepareOptions(program.options) })),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
prepareLanguageServerSnapshotChanges(changes) {
|
|
350
|
+
if (!changes)
|
|
351
|
+
return undefined;
|
|
352
|
+
const prepared = this.prepareCreateSnapshotParams(changes);
|
|
353
|
+
return prepared;
|
|
354
|
+
}
|
|
355
|
+
createSnapshotUpdater(getSnapshot) {
|
|
356
|
+
const update = params => this.updateSnapshot(getSnapshot(), params); // @sync: const update = ((params: CreateSnapshotParams) => this.updateSnapshot(getSnapshot(), params)) as SnapshotUpdater;
|
|
357
|
+
// @sync-only-start
|
|
358
|
+
// const owner = this;
|
|
359
|
+
// update.gen = function* (params: CreateSnapshotParams) { return yield* owner.updateSnapshot.gen(getSnapshot(), params); };
|
|
360
|
+
// @sync-only-end
|
|
361
|
+
return update;
|
|
362
|
+
}
|
|
363
|
+
async getCurrentLanguageServerSnapshot(...args) {
|
|
364
|
+
await this.ensureInitialized();
|
|
365
|
+
const changes = args[0];
|
|
366
|
+
const baseSnapshot = args[1];
|
|
367
|
+
if (baseSnapshot && (this.activeSnapshots.get(baseSnapshot.id) !== baseSnapshot || baseSnapshot.isDisposed())) {
|
|
368
|
+
throw new Error("Cannot use an inactive snapshot as a response base");
|
|
369
|
+
}
|
|
370
|
+
const data = await this.client.apiRequest("getCurrentLanguageServerSnapshot", {
|
|
371
|
+
baseSnapshot: baseSnapshot?.id,
|
|
372
|
+
changes: this.prepareLanguageServerSnapshotChanges(changes),
|
|
74
373
|
});
|
|
75
|
-
|
|
76
|
-
|
|
374
|
+
if (baseSnapshot) {
|
|
375
|
+
this.sourceFileCache.retainForSnapshot(data.snapshot, baseSnapshot.id, data.changes);
|
|
376
|
+
}
|
|
377
|
+
const snapshot = new Snapshot(data, this.toPath, this, () => {
|
|
378
|
+
this.activeSnapshots.delete(snapshot.id);
|
|
379
|
+
this.sourceFileCache.releaseSnapshot(snapshot.id);
|
|
380
|
+
}, this.createSnapshotUpdater(() => snapshot), baseSnapshot);
|
|
381
|
+
this.activeSnapshots.set(snapshot.id, snapshot);
|
|
77
382
|
return snapshot;
|
|
78
383
|
}
|
|
384
|
+
async [globalThis.Symbol.asyncDispose]() {
|
|
385
|
+
await this.close(); // @sync: this.close();
|
|
386
|
+
}
|
|
79
387
|
async close() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
388
|
+
await this.initializing?.catch(() => { }); // @sync-skip
|
|
389
|
+
try {
|
|
390
|
+
for (const retained of [...this.activeSourceFileLeases.values()]) {
|
|
391
|
+
await retained.dispose();
|
|
392
|
+
}
|
|
83
393
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
394
|
+
finally {
|
|
395
|
+
try {
|
|
396
|
+
for (const orchestrator of [...this.activeBuildOrchestrators]) {
|
|
397
|
+
await orchestrator.dispose();
|
|
398
|
+
}
|
|
399
|
+
for (const snapshot of [...this.activeSnapshots.values()]) {
|
|
400
|
+
await snapshot.dispose();
|
|
401
|
+
}
|
|
402
|
+
this.sourceFileCache.clear();
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
await this.client.close(); // always close the underlying connection
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
async createModuleResolver(compilerOptions, options) {
|
|
410
|
+
await this.ensureInitialized();
|
|
411
|
+
const callback = options?.resolveModuleName
|
|
412
|
+
? registerModuleResolutionCallback(this.client, options.resolveModuleName, id => this.activeSnapshots.get(id))
|
|
413
|
+
: undefined;
|
|
414
|
+
try {
|
|
415
|
+
const id = await this.client.apiRequest("createModuleResolver", {
|
|
416
|
+
compilerOptions: prepareCompilerOptions(compilerOptions, this.getCurrentDirectory()),
|
|
417
|
+
moduleResolutions: options?.moduleResolutions,
|
|
418
|
+
resolveModuleNameCallback: callback?.name,
|
|
419
|
+
});
|
|
420
|
+
return new ModuleResolver(id, this.client, callback?.dispose);
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
callback?.dispose();
|
|
424
|
+
throw error;
|
|
88
425
|
}
|
|
89
|
-
await this.client.close();
|
|
90
|
-
this.sourceFileCache.clear();
|
|
91
426
|
}
|
|
92
427
|
clearSourceFileCache() {
|
|
93
428
|
this.sourceFileCache.clear();
|
|
94
429
|
}
|
|
430
|
+
async runWithTemporaryFileUpdate(baseSnapshot, file, newText, cb) {
|
|
431
|
+
await this.ensureInitialized();
|
|
432
|
+
if (this.activeSnapshots.get(baseSnapshot.id) !== baseSnapshot || baseSnapshot.isDisposed()) {
|
|
433
|
+
throw new Error("Cannot run a temporary file update on an inactive snapshot");
|
|
434
|
+
}
|
|
435
|
+
const snapshot = await baseSnapshot.update({
|
|
436
|
+
fileSystem: {
|
|
437
|
+
kind: "layer",
|
|
438
|
+
files: { [resolveFileName(file)]: newText },
|
|
439
|
+
},
|
|
440
|
+
ensurePrograms: true,
|
|
441
|
+
});
|
|
442
|
+
try {
|
|
443
|
+
await cb(snapshot);
|
|
444
|
+
}
|
|
445
|
+
finally {
|
|
446
|
+
await snapshot.dispose();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
95
449
|
/**
|
|
96
450
|
* Returns a snapshot of collected timing information for requests made
|
|
97
451
|
* through this API instance: client-measured round-trip latency and bytes
|
|
@@ -100,8 +454,8 @@ export class API {
|
|
|
100
454
|
*
|
|
101
455
|
* Fetching the snapshot issues a lightweight request to the server to
|
|
102
456
|
* retrieve its timing collection. Collection must be enabled via the
|
|
103
|
-
* `collectTiming` option
|
|
104
|
-
* `enabled: false` and zeroed totals.
|
|
457
|
+
* `collectTiming` option or `TS_API_TIMING_DIR` environment variable; when
|
|
458
|
+
* it is not, the returned snapshot has `enabled: false` and zeroed totals.
|
|
105
459
|
*/
|
|
106
460
|
getTimingInfo() {
|
|
107
461
|
return this.client.getTimingInfo();
|
|
@@ -110,11 +464,102 @@ export class API {
|
|
|
110
464
|
resetTimingInfo() {
|
|
111
465
|
return this.client.resetTimingInfo();
|
|
112
466
|
}
|
|
467
|
+
/** Creates a program from current filesystem state. */
|
|
468
|
+
async createProgram(rootFiles, compilerOptions, createProgramOptions) {
|
|
469
|
+
await this.ensureInitialized();
|
|
470
|
+
const snapshot = await this.createSnapshot({
|
|
471
|
+
createPrograms: [{ rootFiles, compilerOptions, options: createProgramOptions }],
|
|
472
|
+
});
|
|
473
|
+
const program = snapshot.operation.createdPrograms[0];
|
|
474
|
+
if (!program) {
|
|
475
|
+
await snapshot.dispose();
|
|
476
|
+
throw new Error("createProgram did not return a project");
|
|
477
|
+
}
|
|
478
|
+
program.setOwnedSnapshot(snapshot);
|
|
479
|
+
return program;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function sourceFileDescriptor(sourceFile) {
|
|
483
|
+
return {
|
|
484
|
+
fileName: sourceFile.fileName,
|
|
485
|
+
path: sourceFile.path,
|
|
486
|
+
contentHash: sourceFile.contentHash,
|
|
487
|
+
parseOptionsKey: sourceFile.parseOptionsKey,
|
|
488
|
+
scriptKind: sourceFile.scriptKind,
|
|
489
|
+
nodeId: sourceFile.nodeId,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
/** Returns whether a node is backed by a remote compiler response. */
|
|
493
|
+
export function isRemoteNode(node) {
|
|
494
|
+
return node instanceof RemoteNode;
|
|
495
|
+
}
|
|
496
|
+
function getRemoteSourceFile(node) {
|
|
497
|
+
if (!isRemoteNode(node))
|
|
498
|
+
return undefined;
|
|
499
|
+
const file = node.getSourceFile();
|
|
500
|
+
return file instanceof RemoteSourceFile && file.api ? file : undefined;
|
|
501
|
+
}
|
|
502
|
+
function getNodeAPI(node) {
|
|
503
|
+
const api = getRemoteSourceFile(node)?.api;
|
|
504
|
+
if (!api)
|
|
505
|
+
return undefined;
|
|
506
|
+
if (!(api instanceof API))
|
|
507
|
+
throw new Error("Source file does not belong to the async API"); // @sync: if (!(api instanceof API)) throw new Error("Source file does not belong to the sync API");
|
|
508
|
+
return api;
|
|
509
|
+
}
|
|
510
|
+
/** Looks up a remote declaration's binder symbol through its API. Throws for non-remote declarations. */
|
|
511
|
+
export async function getSymbol(declaration) {
|
|
512
|
+
const api = getNodeAPI(declaration);
|
|
513
|
+
if (!api)
|
|
514
|
+
throw new Error("Source file not found for declaration");
|
|
515
|
+
return api.getSymbol(declaration);
|
|
516
|
+
}
|
|
517
|
+
// @sync-only-start
|
|
518
|
+
// export declare namespace getSymbol {
|
|
519
|
+
// function gen(declaration: Declaration): Generator<ProtocolRequest, Symbol, ProtocolResponse["result"]>;
|
|
520
|
+
// }
|
|
521
|
+
// getSymbol.gen = function* (declaration: Declaration): Generator<ProtocolRequest, Symbol, ProtocolResponse["result"]> {
|
|
522
|
+
// const api = getNodeAPI(declaration);
|
|
523
|
+
// if (!api) throw new Error("Source file not found for declaration");
|
|
524
|
+
// return yield* api.getSymbol.gen(declaration);
|
|
525
|
+
// };
|
|
526
|
+
// @sync-only-end
|
|
527
|
+
/** An independently retained source file and its disposable remote-lifetime lease. */
|
|
528
|
+
export class RetainedSourceFile {
|
|
529
|
+
sourceFile;
|
|
530
|
+
lease;
|
|
531
|
+
onDispose;
|
|
532
|
+
disposed = false;
|
|
533
|
+
disposePromise;
|
|
534
|
+
constructor(sourceFile, lease, onDispose) {
|
|
535
|
+
this.sourceFile = sourceFile;
|
|
536
|
+
this.lease = lease;
|
|
537
|
+
this.onDispose = onDispose;
|
|
538
|
+
}
|
|
539
|
+
[globalThis.Symbol.asyncDispose]() {
|
|
540
|
+
return this.dispose(); // @sync: this.dispose();
|
|
541
|
+
}
|
|
542
|
+
dispose() {
|
|
543
|
+
return this.disposePromise ??= this.disposeWorker();
|
|
544
|
+
}
|
|
545
|
+
async disposeWorker() {
|
|
546
|
+
if (this.disposed)
|
|
547
|
+
return;
|
|
548
|
+
const api = getNodeAPI(this.sourceFile);
|
|
549
|
+
if (!api)
|
|
550
|
+
throw new Error("Retained source file has no owning API");
|
|
551
|
+
this.disposed = true;
|
|
552
|
+
try {
|
|
553
|
+
await api.client.apiRequest("releaseSourceFile", { lease: this.lease });
|
|
554
|
+
}
|
|
555
|
+
finally {
|
|
556
|
+
this.onDispose();
|
|
557
|
+
}
|
|
558
|
+
}
|
|
113
559
|
}
|
|
114
|
-
export class
|
|
560
|
+
export class DebugHandlers {
|
|
115
561
|
client;
|
|
116
562
|
ensureInitialized;
|
|
117
|
-
/** @internal */
|
|
118
563
|
constructor(client, ensureInitialized) {
|
|
119
564
|
this.client = client;
|
|
120
565
|
this.ensureInitialized = ensureInitialized;
|
|
@@ -136,32 +581,70 @@ export class InternalAPI {
|
|
|
136
581
|
}
|
|
137
582
|
export class Snapshot {
|
|
138
583
|
id;
|
|
584
|
+
operation;
|
|
139
585
|
projectMap;
|
|
140
586
|
toPath;
|
|
141
|
-
|
|
587
|
+
api;
|
|
142
588
|
disposed = false;
|
|
589
|
+
disposePromise;
|
|
143
590
|
onDispose;
|
|
144
591
|
snapshotRegistry;
|
|
145
|
-
|
|
592
|
+
projectDataMap;
|
|
593
|
+
updateSnapshot;
|
|
594
|
+
get client() {
|
|
595
|
+
return this.api.client;
|
|
596
|
+
}
|
|
597
|
+
constructor(data, toPath, api, onDispose, updateSnapshot, baseSnapshot) {
|
|
146
598
|
this.id = data.snapshot;
|
|
147
|
-
this.
|
|
599
|
+
this.api = api;
|
|
148
600
|
this.toPath = toPath;
|
|
149
601
|
this.onDispose = onDispose;
|
|
602
|
+
this.updateSnapshot = updateSnapshot;
|
|
150
603
|
this.projectMap = new Map();
|
|
151
|
-
|
|
152
|
-
for (const
|
|
153
|
-
|
|
154
|
-
|
|
604
|
+
const projectDataMap = new Map(baseSnapshot?.projectDataMap);
|
|
605
|
+
for (const projectId of data.changes?.removedProjects ?? []) {
|
|
606
|
+
projectDataMap.delete(projectId);
|
|
607
|
+
}
|
|
608
|
+
for (const projectData of data.projects) {
|
|
609
|
+
projectDataMap.set(projectData.id, projectData);
|
|
155
610
|
}
|
|
611
|
+
this.projectDataMap = new Map([...projectDataMap].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0));
|
|
612
|
+
this.snapshotRegistry = new SnapshotObjectRegistry(this.id);
|
|
613
|
+
for (const projData of this.projectDataMap.values()) {
|
|
614
|
+
const project = new Project(projData, this.id, toPath, api, this.snapshotRegistry);
|
|
615
|
+
this.projectMap.set(projData.id, project);
|
|
616
|
+
}
|
|
617
|
+
this.operation = {
|
|
618
|
+
createdPrograms: data.operation.createdPrograms?.map(projectId => this.requireProject(projectId).program),
|
|
619
|
+
openedFiles: data.operation.openedFiles?.map(result => ({ project: this.requireProject(result.project) })),
|
|
620
|
+
};
|
|
156
621
|
}
|
|
157
622
|
getProjects() {
|
|
158
623
|
this.ensureNotDisposed();
|
|
159
624
|
return [...this.projectMap.values()];
|
|
160
625
|
}
|
|
161
|
-
|
|
626
|
+
getConfiguredProject(configFileName) {
|
|
162
627
|
this.ensureNotDisposed();
|
|
163
|
-
|
|
628
|
+
const id = this.toPath(configFileName);
|
|
629
|
+
return this.projectMap.get(id);
|
|
164
630
|
}
|
|
631
|
+
getProject(projectId) {
|
|
632
|
+
this.ensureNotDisposed();
|
|
633
|
+
return this.projectMap.get(projectId);
|
|
634
|
+
}
|
|
635
|
+
getProgram(projectId) {
|
|
636
|
+
return this.getProject(projectId)?.program;
|
|
637
|
+
}
|
|
638
|
+
update(params) {
|
|
639
|
+
this.ensureNotDisposed();
|
|
640
|
+
return this.updateSnapshot(params);
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Gets the default project for a given file from the configured projects and
|
|
644
|
+
* inferred project already loaded in the snapshot. Synthetic projects are not
|
|
645
|
+
* considered. Files that have been opened with `openFiles` are guaranteed to
|
|
646
|
+
* have a result.
|
|
647
|
+
*/
|
|
165
648
|
async getDefaultProjectForFile(file) {
|
|
166
649
|
this.ensureNotDisposed();
|
|
167
650
|
const data = await this.client.apiRequest("getDefaultProjectForFile", {
|
|
@@ -170,12 +653,15 @@ export class Snapshot {
|
|
|
170
653
|
});
|
|
171
654
|
if (!data)
|
|
172
655
|
return undefined;
|
|
173
|
-
return this.projectMap.get(
|
|
656
|
+
return this.projectMap.get(data.id);
|
|
174
657
|
}
|
|
175
|
-
[globalThis.Symbol.
|
|
176
|
-
this.dispose();
|
|
658
|
+
[globalThis.Symbol.asyncDispose]() {
|
|
659
|
+
return this.dispose(); // @sync: this.dispose();
|
|
177
660
|
}
|
|
178
|
-
|
|
661
|
+
dispose() {
|
|
662
|
+
return this.disposePromise ??= this.disposeWorker();
|
|
663
|
+
}
|
|
664
|
+
async disposeWorker() {
|
|
179
665
|
if (this.disposed)
|
|
180
666
|
return;
|
|
181
667
|
this.disposed = true;
|
|
@@ -184,8 +670,12 @@ export class Snapshot {
|
|
|
184
670
|
}
|
|
185
671
|
this.projectMap.clear();
|
|
186
672
|
this.snapshotRegistry.clear();
|
|
187
|
-
|
|
188
|
-
|
|
673
|
+
try {
|
|
674
|
+
await this.client.apiRequest("release", { snapshot: this.id });
|
|
675
|
+
}
|
|
676
|
+
finally {
|
|
677
|
+
this.onDispose();
|
|
678
|
+
}
|
|
189
679
|
}
|
|
190
680
|
isDisposed() {
|
|
191
681
|
return this.disposed;
|
|
@@ -195,26 +685,78 @@ export class Snapshot {
|
|
|
195
685
|
throw new Error("Snapshot is disposed");
|
|
196
686
|
}
|
|
197
687
|
}
|
|
688
|
+
requireProject(projectId) {
|
|
689
|
+
const project = this.projectMap.get(projectId);
|
|
690
|
+
if (!project) {
|
|
691
|
+
throw new Error(`Snapshot operation returned unknown project '${projectId}'`);
|
|
692
|
+
}
|
|
693
|
+
return project;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
export class ModuleResolver {
|
|
697
|
+
id;
|
|
698
|
+
client;
|
|
699
|
+
disposeCallback;
|
|
700
|
+
disposed = false;
|
|
701
|
+
constructor(id, client, disposeCallback) {
|
|
702
|
+
this.id = id;
|
|
703
|
+
this.client = client;
|
|
704
|
+
this.disposeCallback = disposeCallback;
|
|
705
|
+
}
|
|
706
|
+
async resolveModuleName(moduleName, containingDirectory, resolutionMode, options) {
|
|
707
|
+
this.ensureNotDisposed();
|
|
708
|
+
if (options?.snapshot instanceof Snapshot && options.snapshot.isDisposed()) {
|
|
709
|
+
throw new Error("Snapshot is disposed");
|
|
710
|
+
}
|
|
711
|
+
return this.client.apiRequest("resolveModuleName", {
|
|
712
|
+
snapshot: options?.snapshot instanceof Snapshot ? options.snapshot.id : undefined,
|
|
713
|
+
inProgressSnapshot: typeof options?.snapshot === "number" ? -options.snapshot : undefined,
|
|
714
|
+
resolver: this.id,
|
|
715
|
+
moduleName,
|
|
716
|
+
containingDirectory,
|
|
717
|
+
resolutionMode,
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
[globalThis.Symbol.asyncDispose]() {
|
|
721
|
+
return this.dispose();
|
|
722
|
+
}
|
|
723
|
+
async dispose() {
|
|
724
|
+
if (this.disposed)
|
|
725
|
+
return;
|
|
726
|
+
await this.client.apiRequest("releaseModuleResolver", { resolver: this.id });
|
|
727
|
+
this.disposed = true;
|
|
728
|
+
this.disposeCallback?.();
|
|
729
|
+
}
|
|
730
|
+
/** @internal */
|
|
731
|
+
ensureNotDisposed() {
|
|
732
|
+
if (this.disposed)
|
|
733
|
+
throw new Error("ModuleResolver is disposed");
|
|
734
|
+
}
|
|
198
735
|
}
|
|
199
736
|
class SnapshotObjectRegistry {
|
|
200
737
|
symbols = new Map();
|
|
201
|
-
|
|
738
|
+
projectRegistries = new Map();
|
|
202
739
|
snapshotId;
|
|
203
|
-
|
|
204
|
-
constructor(client, snapshotId, resolveProject) {
|
|
205
|
-
this.client = client;
|
|
740
|
+
constructor(snapshotId) {
|
|
206
741
|
this.snapshotId = snapshotId;
|
|
207
|
-
this.resolveProject = resolveProject;
|
|
208
742
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return this.resolveProject(projectId);
|
|
743
|
+
addProjectRegistry(registry) {
|
|
744
|
+
this.projectRegistries.set(registry.project.id, registry);
|
|
212
745
|
}
|
|
213
746
|
getOrCreateSymbol(data) {
|
|
214
|
-
|
|
747
|
+
const reference = data.reference;
|
|
748
|
+
if (reference.kind !== SymbolOwnerKind.Snapshot)
|
|
749
|
+
throw new Error(`Symbol ${reference.id} is not snapshot-owned`);
|
|
750
|
+
let symbol = this.symbols.get(reference.id);
|
|
215
751
|
if (!symbol) {
|
|
216
|
-
|
|
217
|
-
|
|
752
|
+
if (reference.snapshot !== this.snapshotId) {
|
|
753
|
+
throw new Error(`Symbol ${reference.id} belongs to snapshot ${reference.snapshot}, not ${this.snapshotId}`);
|
|
754
|
+
}
|
|
755
|
+
const registry = this.projectRegistries.get(reference.project);
|
|
756
|
+
if (!registry)
|
|
757
|
+
throw new Error(`Symbol ${reference.id} references unknown project '${reference.project}'`);
|
|
758
|
+
symbol = new Symbol(data, { kind: SymbolOwnerKind.Snapshot, registry });
|
|
759
|
+
this.symbols.set(reference.id, symbol);
|
|
218
760
|
}
|
|
219
761
|
return symbol;
|
|
220
762
|
}
|
|
@@ -224,65 +766,51 @@ class SnapshotObjectRegistry {
|
|
|
224
766
|
clear() {
|
|
225
767
|
this.symbols.clear();
|
|
226
768
|
}
|
|
227
|
-
async fetchSymbol(source, method, handle, projectId) {
|
|
228
|
-
if (!handle)
|
|
229
|
-
return undefined;
|
|
230
|
-
const cached = this.getSymbol(handle);
|
|
231
|
-
if (cached)
|
|
232
|
-
return cached;
|
|
233
|
-
const data = await this.client.apiRequest(method, {
|
|
234
|
-
snapshot: this.snapshotId,
|
|
235
|
-
project: projectId,
|
|
236
|
-
objectId: source.id,
|
|
237
|
-
});
|
|
238
|
-
if (!data)
|
|
239
|
-
throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
|
|
240
|
-
return this.getOrCreateSymbol(data);
|
|
241
|
-
}
|
|
242
|
-
async fetchSymbols(source, method, handles, projectId) {
|
|
243
|
-
if (handles) {
|
|
244
|
-
const result = new Array(handles.length);
|
|
245
|
-
let allCached = true;
|
|
246
|
-
for (let i = 0; i < handles.length; i++) {
|
|
247
|
-
const cached = this.getSymbol(handles[i]);
|
|
248
|
-
if (!cached) {
|
|
249
|
-
allCached = false;
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
result[i] = cached;
|
|
253
|
-
}
|
|
254
|
-
if (allCached)
|
|
255
|
-
return result;
|
|
256
|
-
}
|
|
257
|
-
const symbolData = await this.client.apiRequest(method, {
|
|
258
|
-
snapshot: this.snapshotId,
|
|
259
|
-
project: projectId,
|
|
260
|
-
objectId: source.id,
|
|
261
|
-
});
|
|
262
|
-
if (symbolData == null)
|
|
263
|
-
return [];
|
|
264
|
-
else
|
|
265
|
-
return symbolData.map(data => this.getOrCreateSymbol(data));
|
|
266
|
-
}
|
|
267
769
|
}
|
|
268
770
|
class ProjectObjectRegistry {
|
|
269
|
-
client;
|
|
270
771
|
snapshotId;
|
|
271
772
|
project;
|
|
272
773
|
snapshotRegistry;
|
|
273
774
|
types = new Map();
|
|
274
775
|
signatures = new Map();
|
|
275
|
-
|
|
276
|
-
|
|
776
|
+
disposed = false;
|
|
777
|
+
get client() {
|
|
778
|
+
return this.project.api.client;
|
|
779
|
+
}
|
|
780
|
+
get sourceFileCache() {
|
|
781
|
+
return this.project.api.sourceFileCache;
|
|
782
|
+
}
|
|
783
|
+
constructor(snapshotId, project, snapshotRegistry) {
|
|
277
784
|
this.snapshotId = snapshotId;
|
|
278
785
|
this.project = project;
|
|
279
786
|
this.snapshotRegistry = snapshotRegistry;
|
|
787
|
+
snapshotRegistry.addProjectRegistry(this);
|
|
280
788
|
}
|
|
281
789
|
getOrCreateSymbol(data) {
|
|
282
|
-
|
|
790
|
+
this.ensureNotDisposed();
|
|
791
|
+
validateSymbolResponse(data);
|
|
792
|
+
const reference = data.reference;
|
|
793
|
+
if (reference.kind === SymbolOwnerKind.Snapshot) {
|
|
794
|
+
return this.snapshotRegistry.getOrCreateSymbol(data);
|
|
795
|
+
}
|
|
796
|
+
const record = this.sourceFileCache.getOrCreateRecord(reference.file, this.snapshotId, this.project.id);
|
|
797
|
+
return this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, {
|
|
798
|
+
kind: SymbolOwnerKind.File,
|
|
799
|
+
owner: { record, api: this.project.api },
|
|
800
|
+
}));
|
|
283
801
|
}
|
|
284
|
-
|
|
285
|
-
|
|
802
|
+
/** Find an already-interned symbol and retain its file record for this registry. */
|
|
803
|
+
getCachedSymbol(reference) {
|
|
804
|
+
this.ensureNotDisposed();
|
|
805
|
+
if (reference.file === undefined) {
|
|
806
|
+
return this.snapshotRegistry.getSymbol(reference.id);
|
|
807
|
+
}
|
|
808
|
+
const record = this.sourceFileCache.findRecord(reference.file);
|
|
809
|
+
const symbol = record?.symbolsById.get(reference.id);
|
|
810
|
+
if (record && symbol) {
|
|
811
|
+
this.sourceFileCache.retainRecord(record, this.snapshotId, this.project.id);
|
|
812
|
+
}
|
|
813
|
+
return symbol;
|
|
286
814
|
}
|
|
287
815
|
getOrCreateType(data) {
|
|
288
816
|
let type = this.types.get(data.id);
|
|
@@ -295,6 +823,9 @@ class ProjectObjectRegistry {
|
|
|
295
823
|
getType(id) {
|
|
296
824
|
return this.types.get(id);
|
|
297
825
|
}
|
|
826
|
+
createNodeHandle(handle) {
|
|
827
|
+
return new NodeHandle(handle, this.project);
|
|
828
|
+
}
|
|
298
829
|
getOrCreateSignature(data) {
|
|
299
830
|
let sig = this.signatures.get(data.id);
|
|
300
831
|
if (!sig) {
|
|
@@ -307,10 +838,15 @@ class ProjectObjectRegistry {
|
|
|
307
838
|
return this.signatures.get(id);
|
|
308
839
|
}
|
|
309
840
|
clear() {
|
|
841
|
+
this.disposed = true;
|
|
310
842
|
this.types.clear();
|
|
311
843
|
this.signatures.clear();
|
|
312
844
|
}
|
|
313
|
-
|
|
845
|
+
ensureNotDisposed() {
|
|
846
|
+
if (this.disposed)
|
|
847
|
+
throw new Error("Project object registry is disposed");
|
|
848
|
+
}
|
|
849
|
+
async fetchOptionalType(source, method, handle) {
|
|
314
850
|
if (handle !== false) {
|
|
315
851
|
if (!handle)
|
|
316
852
|
return undefined;
|
|
@@ -324,11 +860,31 @@ class ProjectObjectRegistry {
|
|
|
324
860
|
objectId: source.id,
|
|
325
861
|
});
|
|
326
862
|
if (!data)
|
|
327
|
-
|
|
863
|
+
return undefined;
|
|
328
864
|
return this.getOrCreateType(data);
|
|
329
865
|
}
|
|
330
|
-
async
|
|
331
|
-
|
|
866
|
+
async fetchType(source, method, handle) {
|
|
867
|
+
const result = await this.fetchOptionalType(source, method, handle);
|
|
868
|
+
if (result === undefined)
|
|
869
|
+
throw new Error(`${method} returned no type for ${source.constructor.name} ${source.id}`);
|
|
870
|
+
return result;
|
|
871
|
+
}
|
|
872
|
+
async fetchSymbol(source, method, reference) {
|
|
873
|
+
if (!reference)
|
|
874
|
+
return undefined;
|
|
875
|
+
const cached = this.getCachedSymbol(reference);
|
|
876
|
+
if (cached)
|
|
877
|
+
return cached;
|
|
878
|
+
const data = source instanceof Symbol
|
|
879
|
+
? await this.client.apiRequest(method, { symbol: source.reference })
|
|
880
|
+
: await this.client.apiRequest(method, {
|
|
881
|
+
snapshot: this.snapshotId,
|
|
882
|
+
project: this.project.id,
|
|
883
|
+
objectId: source.id,
|
|
884
|
+
});
|
|
885
|
+
if (!data)
|
|
886
|
+
throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
|
|
887
|
+
return this.getOrCreateSymbol(data);
|
|
332
888
|
}
|
|
333
889
|
async fetchSignature(source, method, handle) {
|
|
334
890
|
if (!handle)
|
|
@@ -370,8 +926,29 @@ class ProjectObjectRegistry {
|
|
|
370
926
|
else
|
|
371
927
|
return typesData.map(data => this.getOrCreateType(data));
|
|
372
928
|
}
|
|
373
|
-
async fetchSymbols(source, method,
|
|
374
|
-
|
|
929
|
+
async fetchSymbols(source, method, references) {
|
|
930
|
+
if (references) {
|
|
931
|
+
const result = new Array(references.length);
|
|
932
|
+
for (let i = 0; i < references.length; i++) {
|
|
933
|
+
const cached = this.getCachedSymbol(references[i]);
|
|
934
|
+
if (!cached) {
|
|
935
|
+
return this.fetchSymbolsFromServer(source, method);
|
|
936
|
+
}
|
|
937
|
+
result[i] = cached;
|
|
938
|
+
}
|
|
939
|
+
return result;
|
|
940
|
+
}
|
|
941
|
+
return this.fetchSymbolsFromServer(source, method);
|
|
942
|
+
}
|
|
943
|
+
async fetchSymbolsFromServer(source, method) {
|
|
944
|
+
const data = source instanceof Symbol
|
|
945
|
+
? await this.client.apiRequest(method, { symbol: source.reference })
|
|
946
|
+
: await this.client.apiRequest(method, {
|
|
947
|
+
snapshot: this.snapshotId,
|
|
948
|
+
project: this.project.id,
|
|
949
|
+
objectId: source.id,
|
|
950
|
+
});
|
|
951
|
+
return data?.map(symbol => this.getOrCreateSymbol(symbol)) ?? [];
|
|
375
952
|
}
|
|
376
953
|
// getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
|
|
377
954
|
// so it cannot go through fetchTypes. This helper reuses that server method.
|
|
@@ -385,52 +962,274 @@ class ProjectObjectRegistry {
|
|
|
385
962
|
return [];
|
|
386
963
|
return typesData.map(data => this.getOrCreateType(data));
|
|
387
964
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
965
|
+
async fetchPropertiesOfType(source) {
|
|
966
|
+
const data = await this.client.apiRequest("getPropertiesOfType", {
|
|
967
|
+
snapshot: this.snapshotId,
|
|
968
|
+
project: this.project.id,
|
|
969
|
+
type: source.id,
|
|
970
|
+
});
|
|
971
|
+
return data ? data.map(symbol => this.getOrCreateSymbol(symbol)) : [];
|
|
972
|
+
}
|
|
973
|
+
async fetchApparentPropertiesOfType(source) {
|
|
974
|
+
const data = await this.client.apiRequest("getApparentPropertiesOfType", {
|
|
975
|
+
snapshot: this.snapshotId,
|
|
976
|
+
project: this.project.id,
|
|
977
|
+
objectId: source.id,
|
|
978
|
+
});
|
|
979
|
+
return data ? data.map(symbol => this.getOrCreateSymbol(symbol)) : [];
|
|
980
|
+
}
|
|
981
|
+
async fetchPropertyOfType(source, name) {
|
|
982
|
+
const data = await this.client.apiRequest("getPropertyOfType", {
|
|
983
|
+
snapshot: this.snapshotId,
|
|
984
|
+
project: this.project.id,
|
|
985
|
+
type: source.id,
|
|
986
|
+
name,
|
|
987
|
+
});
|
|
988
|
+
return data ? this.getOrCreateSymbol(data) : undefined;
|
|
989
|
+
}
|
|
990
|
+
async fetchSignaturesOfType(source, kind) {
|
|
991
|
+
const data = await this.client.apiRequest("getSignaturesOfType", {
|
|
992
|
+
snapshot: this.snapshotId,
|
|
993
|
+
project: this.project.id,
|
|
994
|
+
type: source.id,
|
|
995
|
+
kind,
|
|
996
|
+
});
|
|
997
|
+
return data.map(signature => this.getOrCreateSignature(signature));
|
|
998
|
+
}
|
|
999
|
+
async fetchIndexInfosOfType(source) {
|
|
1000
|
+
const data = await this.client.apiRequest("getIndexInfosOfType", {
|
|
1001
|
+
snapshot: this.snapshotId,
|
|
1002
|
+
project: this.project.id,
|
|
1003
|
+
type: source.id,
|
|
1004
|
+
});
|
|
1005
|
+
if (!data)
|
|
1006
|
+
return [];
|
|
1007
|
+
return data.map(info => ({
|
|
1008
|
+
keyType: this.getOrCreateType(info.keyType),
|
|
1009
|
+
valueType: this.getOrCreateType(info.valueType),
|
|
1010
|
+
isReadonly: info.isReadonly ?? false,
|
|
1011
|
+
declaration: info.declaration ? new NodeHandle(info.declaration, this.project) : undefined,
|
|
1012
|
+
}));
|
|
1013
|
+
}
|
|
1014
|
+
async fetchTypeParameterAtPosition(source, pos) {
|
|
1015
|
+
const data = await this.client.apiRequest("getTypeParameterAtPosition", {
|
|
1016
|
+
snapshot: this.snapshotId,
|
|
1017
|
+
project: this.project.id,
|
|
1018
|
+
signature: source.id,
|
|
1019
|
+
index: pos,
|
|
1020
|
+
});
|
|
1021
|
+
return this.getOrCreateType(data);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
export class Project {
|
|
1025
|
+
/** @internal */
|
|
1026
|
+
api;
|
|
1027
|
+
id;
|
|
1028
|
+
configFileName;
|
|
1029
|
+
currentDirectory;
|
|
1030
|
+
dirty;
|
|
1031
|
+
parsedCommandLine;
|
|
1032
|
+
program;
|
|
1033
|
+
checker;
|
|
1034
|
+
languageService;
|
|
1035
|
+
constructor(data, snapshotId, toPath, api, snapshotRegistry) {
|
|
1036
|
+
this.id = data.id;
|
|
1037
|
+
this.api = api;
|
|
400
1038
|
this.configFileName = data.configFileName;
|
|
401
|
-
this.
|
|
402
|
-
this.
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
this.
|
|
407
|
-
this.
|
|
1039
|
+
this.currentDirectory = data.currentDirectory;
|
|
1040
|
+
this.dirty = data.dirty;
|
|
1041
|
+
if (!data.parsedCommandLine?.options) {
|
|
1042
|
+
throw new Error(`Project '${data.configFileName}' has no parsed command line`);
|
|
1043
|
+
}
|
|
1044
|
+
this.parsedCommandLine = data.parsedCommandLine;
|
|
1045
|
+
this.program = new Program(snapshotId, this, toPath);
|
|
1046
|
+
const objectRegistry = new ProjectObjectRegistry(snapshotId, this, snapshotRegistry);
|
|
1047
|
+
this.checker = new Checker(snapshotId, this, objectRegistry);
|
|
1048
|
+
this.languageService = new LanguageService(snapshotId, this, objectRegistry);
|
|
408
1049
|
}
|
|
409
1050
|
dispose() {
|
|
410
1051
|
this.checker.dispose();
|
|
411
1052
|
}
|
|
412
1053
|
}
|
|
1054
|
+
export class LanguageService {
|
|
1055
|
+
snapshotId;
|
|
1056
|
+
project;
|
|
1057
|
+
objectRegistry;
|
|
1058
|
+
get client() {
|
|
1059
|
+
return this.project.api.client;
|
|
1060
|
+
}
|
|
1061
|
+
constructor(snapshotId, project, objectRegistry) {
|
|
1062
|
+
this.snapshotId = snapshotId;
|
|
1063
|
+
this.project = project;
|
|
1064
|
+
this.objectRegistry = objectRegistry;
|
|
1065
|
+
}
|
|
1066
|
+
async getImportAdderEdits(file, actions) {
|
|
1067
|
+
const requestActions = actions.map(action => {
|
|
1068
|
+
switch (action.kind) {
|
|
1069
|
+
case "importSymbol":
|
|
1070
|
+
const importSymbolAction = {
|
|
1071
|
+
kind: "importSymbol",
|
|
1072
|
+
symbol: action.symbol.reference,
|
|
1073
|
+
};
|
|
1074
|
+
if (action.isValidTypeOnlyUseSite !== undefined) {
|
|
1075
|
+
importSymbolAction.isValidTypeOnlyUseSite = action.isValidTypeOnlyUseSite;
|
|
1076
|
+
}
|
|
1077
|
+
return importSymbolAction;
|
|
1078
|
+
default:
|
|
1079
|
+
return assertNever(action.kind);
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1082
|
+
const data = await this.client.apiRequest("getImportAdderEdits", {
|
|
1083
|
+
snapshot: this.snapshotId,
|
|
1084
|
+
project: this.project.id,
|
|
1085
|
+
file,
|
|
1086
|
+
actions: requestActions,
|
|
1087
|
+
});
|
|
1088
|
+
return data ?? [];
|
|
1089
|
+
}
|
|
1090
|
+
async getImportEditsForSymbols(file, symbols, options = {}) {
|
|
1091
|
+
return this.getImportAdderEdits(file, symbols.map((symbol) => {
|
|
1092
|
+
if (options.isValidTypeOnlyUseSite !== undefined) {
|
|
1093
|
+
return {
|
|
1094
|
+
kind: "importSymbol",
|
|
1095
|
+
symbol,
|
|
1096
|
+
isValidTypeOnlyUseSite: options.isValidTypeOnlyUseSite,
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
return {
|
|
1100
|
+
kind: "importSymbol",
|
|
1101
|
+
symbol,
|
|
1102
|
+
};
|
|
1103
|
+
}));
|
|
1104
|
+
}
|
|
1105
|
+
async getReferencedSymbolsForNode(node, position) {
|
|
1106
|
+
const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
|
|
1107
|
+
snapshot: this.snapshotId,
|
|
1108
|
+
project: this.project.id,
|
|
1109
|
+
node: getNodeId(node),
|
|
1110
|
+
position,
|
|
1111
|
+
});
|
|
1112
|
+
return (data ?? []).map(entry => ({
|
|
1113
|
+
definition: new NodeHandle(entry.definition, this.project),
|
|
1114
|
+
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
|
|
1115
|
+
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
|
|
1116
|
+
}));
|
|
1117
|
+
}
|
|
1118
|
+
async getSignatureUsage(signatureDecl) {
|
|
1119
|
+
const data = await this.client.apiRequest("getSignatureUsages", {
|
|
1120
|
+
snapshot: this.snapshotId,
|
|
1121
|
+
project: this.project.id,
|
|
1122
|
+
signatureDecl: getNodeId(signatureDecl),
|
|
1123
|
+
});
|
|
1124
|
+
return (data ?? []).map(entry => ({
|
|
1125
|
+
name: new NodeHandle(entry.name, this.project),
|
|
1126
|
+
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
|
|
1127
|
+
}));
|
|
1128
|
+
}
|
|
1129
|
+
async getCompletionsAtPosition(document, position, options) {
|
|
1130
|
+
const data = await this.client.apiRequest("getCompletionsAtPosition", {
|
|
1131
|
+
snapshot: this.snapshotId,
|
|
1132
|
+
project: this.project.id,
|
|
1133
|
+
file: document,
|
|
1134
|
+
position,
|
|
1135
|
+
triggerCharacter: options?.triggerCharacter,
|
|
1136
|
+
includeSymbol: options?.includeSymbol,
|
|
1137
|
+
});
|
|
1138
|
+
if (!data)
|
|
1139
|
+
return undefined;
|
|
1140
|
+
return {
|
|
1141
|
+
isIncomplete: data.isIncomplete,
|
|
1142
|
+
entries: data.entries.map(e => ({
|
|
1143
|
+
...e,
|
|
1144
|
+
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
|
|
1145
|
+
})),
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Format a synthesized node with the correct indentation for insertion at a
|
|
1150
|
+
* specific position in an existing source file.
|
|
1151
|
+
*
|
|
1152
|
+
* @param node The synthesized AST node to format.
|
|
1153
|
+
* @param file The target file where the node will be inserted.
|
|
1154
|
+
* @param position The UTF-16 code-unit offset in the target file for insertion.
|
|
1155
|
+
* @returns The formatted text of the node, indented for the insertion position.
|
|
1156
|
+
*/
|
|
1157
|
+
async formatNodeForInsertion(node, file, position) {
|
|
1158
|
+
const encoded = encodeNode(node);
|
|
1159
|
+
const base64 = uint8ArrayToBase64(encoded);
|
|
1160
|
+
return this.client.apiRequest("formatNodeForInsertion", {
|
|
1161
|
+
snapshot: this.snapshotId,
|
|
1162
|
+
project: this.project.id,
|
|
1163
|
+
file,
|
|
1164
|
+
position,
|
|
1165
|
+
data: base64,
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
413
1169
|
export class Program {
|
|
1170
|
+
/** @internal */
|
|
414
1171
|
snapshotId;
|
|
1172
|
+
id;
|
|
415
1173
|
project;
|
|
416
|
-
client;
|
|
417
|
-
sourceFileCache;
|
|
418
1174
|
toPath;
|
|
419
1175
|
decoder = new Wtf8Decoder();
|
|
420
1176
|
sourceFileMetadataCache = new Map();
|
|
421
|
-
|
|
1177
|
+
ownedSnapshot;
|
|
1178
|
+
disposePromise;
|
|
1179
|
+
get client() {
|
|
1180
|
+
return this.project.api.client;
|
|
1181
|
+
}
|
|
1182
|
+
get sourceFileCache() {
|
|
1183
|
+
return this.project.api.sourceFileCache;
|
|
1184
|
+
}
|
|
1185
|
+
constructor(snapshotId, project, toPath) {
|
|
422
1186
|
this.snapshotId = snapshotId;
|
|
1187
|
+
this.id = project.id;
|
|
423
1188
|
this.project = project;
|
|
424
|
-
this.client = client;
|
|
425
|
-
this.sourceFileCache = sourceFileCache;
|
|
426
1189
|
this.toPath = toPath;
|
|
427
1190
|
}
|
|
1191
|
+
getCurrentDirectory() {
|
|
1192
|
+
return this.project.currentDirectory;
|
|
1193
|
+
}
|
|
1194
|
+
getCanonicalFileName(fileName) {
|
|
1195
|
+
return this.project.api.getCanonicalFileName(fileName);
|
|
1196
|
+
}
|
|
1197
|
+
getNewLine() {
|
|
1198
|
+
return this.project.parsedCommandLine.options.newLine === NewLineKind.CRLF ? "\r\n" : "\n";
|
|
1199
|
+
}
|
|
1200
|
+
/** @internal */
|
|
1201
|
+
setOwnedSnapshot(snapshot) {
|
|
1202
|
+
this.ownedSnapshot = snapshot;
|
|
1203
|
+
}
|
|
1204
|
+
[globalThis.Symbol.asyncDispose]() {
|
|
1205
|
+
return this.dispose(); // @sync: this.dispose();
|
|
1206
|
+
}
|
|
1207
|
+
dispose() {
|
|
1208
|
+
return this.disposePromise ??= this.disposeWorker();
|
|
1209
|
+
}
|
|
1210
|
+
async disposeWorker() {
|
|
1211
|
+
const snapshot = this.ownedSnapshot;
|
|
1212
|
+
this.ownedSnapshot = undefined;
|
|
1213
|
+
if (snapshot)
|
|
1214
|
+
await snapshot.dispose();
|
|
1215
|
+
}
|
|
428
1216
|
getCompilerOptions() {
|
|
429
|
-
return this.project.
|
|
1217
|
+
return this.project.parsedCommandLine.options;
|
|
430
1218
|
}
|
|
431
1219
|
async getSourceFile(file) {
|
|
432
1220
|
const fileName = resolveFileName(file);
|
|
433
|
-
const path = this.
|
|
1221
|
+
const path = this.pathKeyForFileName(fileName);
|
|
1222
|
+
return this.getSourceFileWorker(file, path);
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Returns the source file for an already-canonical path.
|
|
1226
|
+
*/
|
|
1227
|
+
getSourceFileByPath(path) {
|
|
1228
|
+
// The wire format is a string, but the cache key remains the supplied
|
|
1229
|
+
// PathKey and is never treated as a RootedPath.
|
|
1230
|
+
return this.getSourceFileWorker(path, path);
|
|
1231
|
+
}
|
|
1232
|
+
async getSourceFileWorker(file, path) {
|
|
434
1233
|
// Check if we already have a retained cache entry for this (snapshot, project) pair
|
|
435
1234
|
const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
|
|
436
1235
|
if (retained) {
|
|
@@ -445,12 +1244,64 @@ export class Program {
|
|
|
445
1244
|
if (!binaryData) {
|
|
446
1245
|
return undefined;
|
|
447
1246
|
}
|
|
448
|
-
const view = new DataView(binaryData.buffer, binaryData.byteOffset, binaryData.byteLength);
|
|
449
|
-
const contentHash = readSourceFileHash(view);
|
|
450
|
-
const parseOptionsKey = readParseOptionsKey(view);
|
|
451
1247
|
// Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
|
|
452
|
-
const
|
|
453
|
-
return this.sourceFileCache.set(
|
|
1248
|
+
const decoded = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector(), this.project.api);
|
|
1249
|
+
return this.sourceFileCache.set(decoded, this.snapshotId, this.project.id);
|
|
1250
|
+
}
|
|
1251
|
+
async getResolvedModule(file, moduleName, mode) {
|
|
1252
|
+
const result = await this.client.apiRequest("getResolvedModule", {
|
|
1253
|
+
snapshot: this.snapshotId,
|
|
1254
|
+
project: this.project.id,
|
|
1255
|
+
file,
|
|
1256
|
+
moduleName,
|
|
1257
|
+
mode,
|
|
1258
|
+
});
|
|
1259
|
+
return result ?? undefined;
|
|
1260
|
+
}
|
|
1261
|
+
async getModeForUsageLocation(file, usage) {
|
|
1262
|
+
return this.client.apiRequest("getModeForUsageLocation", {
|
|
1263
|
+
snapshot: this.snapshotId,
|
|
1264
|
+
project: this.project.id,
|
|
1265
|
+
file,
|
|
1266
|
+
usage: getNodeId(usage),
|
|
1267
|
+
});
|
|
1268
|
+
}
|
|
1269
|
+
async getModeForResolutionAtIndex(file, index) {
|
|
1270
|
+
return this.client.apiRequest("getModeForResolutionAtIndex", {
|
|
1271
|
+
snapshot: this.snapshotId,
|
|
1272
|
+
project: this.project.id,
|
|
1273
|
+
file,
|
|
1274
|
+
index,
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
async getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile) {
|
|
1278
|
+
const result = await this.client.apiRequest("getResolvedModuleFromModuleSpecifier", {
|
|
1279
|
+
snapshot: this.snapshotId,
|
|
1280
|
+
project: this.project.id,
|
|
1281
|
+
moduleSpecifier: getNodeId(moduleSpecifier),
|
|
1282
|
+
sourceFile,
|
|
1283
|
+
});
|
|
1284
|
+
return result ?? undefined;
|
|
1285
|
+
}
|
|
1286
|
+
async getResolvedTypeReferenceDirective(file, typeDirectiveName, mode) {
|
|
1287
|
+
const result = await this.client.apiRequest("getResolvedTypeReferenceDirective", {
|
|
1288
|
+
snapshot: this.snapshotId,
|
|
1289
|
+
project: this.project.id,
|
|
1290
|
+
file,
|
|
1291
|
+
typeDirectiveName,
|
|
1292
|
+
mode,
|
|
1293
|
+
});
|
|
1294
|
+
return result ?? undefined;
|
|
1295
|
+
}
|
|
1296
|
+
async getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeReferenceDirective, sourceFile) {
|
|
1297
|
+
const result = await this.client.apiRequest("getResolvedTypeReferenceDirectiveFromTypeReferenceDirective", {
|
|
1298
|
+
snapshot: this.snapshotId,
|
|
1299
|
+
project: this.project.id,
|
|
1300
|
+
sourceFile,
|
|
1301
|
+
typeDirectiveName: typeReferenceDirective.fileName,
|
|
1302
|
+
resolutionMode: typeReferenceDirective.resolutionMode,
|
|
1303
|
+
});
|
|
1304
|
+
return result ?? undefined;
|
|
454
1305
|
}
|
|
455
1306
|
async getSourceFileNames() {
|
|
456
1307
|
const data = await this.client.apiRequest("getSourceFileNames", {
|
|
@@ -464,8 +1315,8 @@ export class Program {
|
|
|
464
1315
|
* is not part of the program. Metadata is fetched lazily per file and cached on this
|
|
465
1316
|
* `Program` instance.
|
|
466
1317
|
*/
|
|
467
|
-
getSourceFileMetadata(
|
|
468
|
-
return this.getSourceFileMetadataByPath(this.
|
|
1318
|
+
getSourceFileMetadata(file) {
|
|
1319
|
+
return this.getSourceFileMetadataByPath(this.pathKeyForFileName(resolveFileName(file)));
|
|
469
1320
|
}
|
|
470
1321
|
/**
|
|
471
1322
|
* Returns program-stored metadata for the source file at the given path, or `undefined`
|
|
@@ -482,6 +1333,8 @@ export class Program {
|
|
|
482
1333
|
return metadata;
|
|
483
1334
|
}
|
|
484
1335
|
async fetchSourceFileMetadata(path) {
|
|
1336
|
+
// PathKey is serialized as a string; the server deliberately treats all
|
|
1337
|
+
// client-provided path text as untrusted input.
|
|
485
1338
|
const data = await this.client.apiRequest("getSourceFileMetadata", {
|
|
486
1339
|
snapshot: this.snapshotId,
|
|
487
1340
|
project: this.project.id,
|
|
@@ -489,6 +1342,9 @@ export class Program {
|
|
|
489
1342
|
});
|
|
490
1343
|
return data ?? undefined;
|
|
491
1344
|
}
|
|
1345
|
+
pathKeyForFileName(fileName) {
|
|
1346
|
+
return this.toPath(fileName, this.project.currentDirectory);
|
|
1347
|
+
}
|
|
492
1348
|
/**
|
|
493
1349
|
* Returns whether the given source file was loaded as part of an external library
|
|
494
1350
|
* (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
|
|
@@ -508,62 +1364,103 @@ export class Program {
|
|
|
508
1364
|
return metadata?.isDefaultLibrary ?? false;
|
|
509
1365
|
}
|
|
510
1366
|
/**
|
|
511
|
-
* Get
|
|
512
|
-
*
|
|
1367
|
+
* Get all config source file names associated with this program's project config.
|
|
1368
|
+
* Includes the root config file and any extended config files.
|
|
1369
|
+
*/
|
|
1370
|
+
async getConfigFileNames() {
|
|
1371
|
+
const data = await this.client.apiRequest("getConfigFileNames", {
|
|
1372
|
+
snapshot: this.snapshotId,
|
|
1373
|
+
project: this.project.id,
|
|
1374
|
+
});
|
|
1375
|
+
return data ?? [];
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Get a config source file by file name/URI.
|
|
1379
|
+
* This can return the project's root tsconfig file or one of its extended config files.
|
|
1380
|
+
*/
|
|
1381
|
+
async getConfigSourceFile(file) {
|
|
1382
|
+
const binaryData = await this.client.apiRequestBinary("getConfigSourceFile", {
|
|
1383
|
+
snapshot: this.snapshotId,
|
|
1384
|
+
project: this.project.id,
|
|
1385
|
+
file,
|
|
1386
|
+
});
|
|
1387
|
+
if (!binaryData) {
|
|
1388
|
+
return undefined;
|
|
1389
|
+
}
|
|
1390
|
+
return new RemoteSourceFile(binaryData, this.decoder, undefined, this.project.api);
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Get syntactic (parse) diagnostics for specific files or all files.
|
|
1394
|
+
* @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
513
1395
|
*/
|
|
514
1396
|
async getSyntacticDiagnostics(file) {
|
|
1397
|
+
const files = file === undefined ? undefined
|
|
1398
|
+
: Array.isArray(file) ? file
|
|
1399
|
+
: [file];
|
|
515
1400
|
const data = await this.client.apiRequest("getSyntacticDiagnostics", {
|
|
516
1401
|
snapshot: this.snapshotId,
|
|
517
1402
|
project: this.project.id,
|
|
518
|
-
|
|
1403
|
+
files,
|
|
519
1404
|
});
|
|
520
1405
|
return data ?? [];
|
|
521
1406
|
}
|
|
522
1407
|
/**
|
|
523
|
-
* Get binder diagnostics for
|
|
524
|
-
* @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
1408
|
+
* Get binder diagnostics for specific files or all files.
|
|
1409
|
+
* @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
525
1410
|
*/
|
|
526
1411
|
async getBindDiagnostics(file) {
|
|
1412
|
+
const files = file === undefined ? undefined
|
|
1413
|
+
: Array.isArray(file) ? file
|
|
1414
|
+
: [file];
|
|
527
1415
|
const data = await this.client.apiRequest("getBindDiagnostics", {
|
|
528
1416
|
snapshot: this.snapshotId,
|
|
529
1417
|
project: this.project.id,
|
|
530
|
-
|
|
1418
|
+
files,
|
|
531
1419
|
});
|
|
532
1420
|
return data ?? [];
|
|
533
1421
|
}
|
|
534
1422
|
/**
|
|
535
|
-
* Get semantic (type-check) diagnostics for
|
|
536
|
-
* @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
1423
|
+
* Get semantic (type-check) diagnostics for specific files or all files.
|
|
1424
|
+
* @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
537
1425
|
*/
|
|
538
1426
|
async getSemanticDiagnostics(file) {
|
|
1427
|
+
const files = file === undefined ? undefined
|
|
1428
|
+
: Array.isArray(file) ? file
|
|
1429
|
+
: [file];
|
|
539
1430
|
const data = await this.client.apiRequest("getSemanticDiagnostics", {
|
|
540
1431
|
snapshot: this.snapshotId,
|
|
541
1432
|
project: this.project.id,
|
|
542
|
-
|
|
1433
|
+
files,
|
|
543
1434
|
});
|
|
544
1435
|
return data ?? [];
|
|
545
1436
|
}
|
|
546
1437
|
/**
|
|
547
|
-
* Get suggestion diagnostics for
|
|
548
|
-
* @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
1438
|
+
* Get suggestion diagnostics for specific files or all files.
|
|
1439
|
+
* @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
549
1440
|
*/
|
|
550
1441
|
async getSuggestionDiagnostics(file) {
|
|
1442
|
+
const files = file === undefined ? undefined
|
|
1443
|
+
: Array.isArray(file) ? file
|
|
1444
|
+
: [file];
|
|
551
1445
|
const data = await this.client.apiRequest("getSuggestionDiagnostics", {
|
|
552
1446
|
snapshot: this.snapshotId,
|
|
553
1447
|
project: this.project.id,
|
|
554
|
-
|
|
1448
|
+
files,
|
|
555
1449
|
});
|
|
556
1450
|
return data ?? [];
|
|
557
1451
|
}
|
|
558
1452
|
/**
|
|
559
|
-
* Get declaration emit diagnostics for
|
|
560
|
-
* @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
1453
|
+
* Get declaration emit diagnostics for specific files or all files.
|
|
1454
|
+
* @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
561
1455
|
*/
|
|
562
1456
|
async getDeclarationDiagnostics(file) {
|
|
1457
|
+
const files = file === undefined ? undefined
|
|
1458
|
+
: Array.isArray(file) ? file
|
|
1459
|
+
: [file];
|
|
563
1460
|
const data = await this.client.apiRequest("getDeclarationDiagnostics", {
|
|
564
1461
|
snapshot: this.snapshotId,
|
|
565
1462
|
project: this.project.id,
|
|
566
|
-
|
|
1463
|
+
files,
|
|
567
1464
|
});
|
|
568
1465
|
return data ?? [];
|
|
569
1466
|
}
|
|
@@ -597,22 +1494,206 @@ export class Program {
|
|
|
597
1494
|
});
|
|
598
1495
|
return data ?? [];
|
|
599
1496
|
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Emits files to the configured filesystem. Layer and host filesystems are
|
|
1499
|
+
* written through; full filesystems remain immutable and return emitted
|
|
1500
|
+
* files in {@link EmitResult.fileSystem}.
|
|
1501
|
+
*/
|
|
1502
|
+
async emit(emitOnly) {
|
|
1503
|
+
const response = await this.client.apiRequest("emit", {
|
|
1504
|
+
snapshot: this.snapshotId,
|
|
1505
|
+
project: this.project.id,
|
|
1506
|
+
emitOnly,
|
|
1507
|
+
});
|
|
1508
|
+
const fileSystem = response.emittedFilesContents.length
|
|
1509
|
+
? {
|
|
1510
|
+
kind: "layer",
|
|
1511
|
+
files: Object.fromEntries(response.emittedFiles.map((fileName, index) => [fileName, response.emittedFilesContents[index]])),
|
|
1512
|
+
}
|
|
1513
|
+
: undefined;
|
|
1514
|
+
return {
|
|
1515
|
+
emitSkipped: response.emitSkipped,
|
|
1516
|
+
diagnostics: response.diagnostics,
|
|
1517
|
+
emittedFiles: response.emittedFiles,
|
|
1518
|
+
fileSystem,
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Emits files and returns their contents without writing to the filesystem.
|
|
1523
|
+
*/
|
|
1524
|
+
async emitToString(emitOnly) {
|
|
1525
|
+
const response = await this.client.apiRequest("emitToString", {
|
|
1526
|
+
snapshot: this.snapshotId,
|
|
1527
|
+
project: this.project.id,
|
|
1528
|
+
emitOnly,
|
|
1529
|
+
});
|
|
1530
|
+
return toEmitOutput(response);
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* Gets JavaScript output for selected files regardless of project `noEmit`, `emitDeclarationOnly`, and `noEmitOnError` settings.
|
|
1534
|
+
*/
|
|
1535
|
+
async getJavaScriptEmit(files) {
|
|
1536
|
+
const response = await this.client.apiRequest("getJavaScriptEmit", {
|
|
1537
|
+
snapshot: this.snapshotId,
|
|
1538
|
+
project: this.project.id,
|
|
1539
|
+
files,
|
|
1540
|
+
});
|
|
1541
|
+
return toEmitOutput(response);
|
|
1542
|
+
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Gets declaration output for selected files regardless of project `noEmit`, `declaration`, `emitDeclarationOnly`, and `noEmitOnError` settings.
|
|
1545
|
+
*/
|
|
1546
|
+
async getDeclarationEmit(files) {
|
|
1547
|
+
const response = await this.client.apiRequest("getDeclarationEmit", {
|
|
1548
|
+
snapshot: this.snapshotId,
|
|
1549
|
+
project: this.project.id,
|
|
1550
|
+
files,
|
|
1551
|
+
});
|
|
1552
|
+
return toEmitOutput(response);
|
|
1553
|
+
}
|
|
1554
|
+
getProject() {
|
|
1555
|
+
return this.project;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
export class BuildOrchestrator {
|
|
1559
|
+
client;
|
|
1560
|
+
id;
|
|
1561
|
+
disposed = false;
|
|
1562
|
+
disposePromise;
|
|
1563
|
+
onDispose;
|
|
1564
|
+
constructor(client, orchestratorResponse, onDispose) {
|
|
1565
|
+
this.client = client;
|
|
1566
|
+
this.id = orchestratorResponse.buildOrchestratorID;
|
|
1567
|
+
this.onDispose = onDispose;
|
|
1568
|
+
}
|
|
1569
|
+
[globalThis.Symbol.asyncDispose]() {
|
|
1570
|
+
return this.dispose(); // @sync: this.dispose();
|
|
1571
|
+
}
|
|
1572
|
+
dispose() {
|
|
1573
|
+
return this.disposePromise ??= this.disposeWorker();
|
|
1574
|
+
}
|
|
1575
|
+
async disposeWorker() {
|
|
1576
|
+
if (this.disposed)
|
|
1577
|
+
return;
|
|
1578
|
+
this.disposed = true;
|
|
1579
|
+
try {
|
|
1580
|
+
await this.client.apiRequest("disposeBuildOrchestrator", {
|
|
1581
|
+
buildOrchestratorID: this.id,
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1584
|
+
finally {
|
|
1585
|
+
this.onDispose();
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
async build(project) {
|
|
1589
|
+
this.ensureNotDisposed();
|
|
1590
|
+
const response = await this.client.apiRequest("build", {
|
|
1591
|
+
buildOrchestratorID: this.id,
|
|
1592
|
+
...(project !== undefined ? { project } : {}),
|
|
1593
|
+
});
|
|
1594
|
+
return response;
|
|
1595
|
+
}
|
|
1596
|
+
async buildReferences(project) {
|
|
1597
|
+
this.ensureNotDisposed();
|
|
1598
|
+
const response = await this.client.apiRequest("buildReferences", {
|
|
1599
|
+
buildOrchestratorID: this.id,
|
|
1600
|
+
project,
|
|
1601
|
+
});
|
|
1602
|
+
return response;
|
|
1603
|
+
}
|
|
1604
|
+
async clean(project) {
|
|
1605
|
+
this.ensureNotDisposed();
|
|
1606
|
+
const response = await this.client.apiRequest("cleanBuild", {
|
|
1607
|
+
buildOrchestratorID: this.id,
|
|
1608
|
+
...(project !== undefined ? { project } : {}),
|
|
1609
|
+
});
|
|
1610
|
+
return response;
|
|
1611
|
+
}
|
|
1612
|
+
async cleanReferences(project) {
|
|
1613
|
+
this.ensureNotDisposed();
|
|
1614
|
+
const response = await this.client.apiRequest("cleanReferences", {
|
|
1615
|
+
buildOrchestratorID: this.id,
|
|
1616
|
+
...(project !== undefined ? { project } : {}),
|
|
1617
|
+
});
|
|
1618
|
+
return response;
|
|
1619
|
+
}
|
|
1620
|
+
isDisposed() {
|
|
1621
|
+
return this.disposed;
|
|
1622
|
+
}
|
|
1623
|
+
ensureNotDisposed() {
|
|
1624
|
+
if (this.disposed) {
|
|
1625
|
+
throw new Error("Build orchestrator is disposed");
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
function toEmitOutput(response) {
|
|
1630
|
+
const outputFiles = new Map();
|
|
1631
|
+
for (const { fileName, ...outputFile } of response.outputFiles) {
|
|
1632
|
+
outputFiles.set(fileName, outputFile);
|
|
1633
|
+
}
|
|
1634
|
+
return {
|
|
1635
|
+
emitSkipped: response.emitSkipped,
|
|
1636
|
+
diagnostics: response.diagnostics,
|
|
1637
|
+
outputFiles,
|
|
1638
|
+
};
|
|
600
1639
|
}
|
|
601
1640
|
export class Checker {
|
|
602
1641
|
snapshotId;
|
|
603
1642
|
project;
|
|
604
|
-
client;
|
|
605
1643
|
objectRegistry;
|
|
606
1644
|
wellKnownSymbols;
|
|
607
|
-
|
|
1645
|
+
wellKnownSignatures;
|
|
1646
|
+
get client() {
|
|
1647
|
+
return this.project.api.client;
|
|
1648
|
+
}
|
|
1649
|
+
constructor(snapshotId, project, objectRegistry) {
|
|
608
1650
|
this.snapshotId = snapshotId;
|
|
609
1651
|
this.project = project;
|
|
610
|
-
this.client = client;
|
|
611
1652
|
this.objectRegistry = objectRegistry;
|
|
612
1653
|
}
|
|
613
1654
|
dispose() {
|
|
614
1655
|
this.objectRegistry.clear();
|
|
615
1656
|
}
|
|
1657
|
+
/** Get the merged symbol, or the original symbol if it has not been merged. */
|
|
1658
|
+
async getMergedSymbol(symbol) {
|
|
1659
|
+
const data = await this.client.apiRequest("getMergedSymbol", {
|
|
1660
|
+
snapshot: this.snapshotId,
|
|
1661
|
+
project: this.project.id,
|
|
1662
|
+
symbol: symbol.reference,
|
|
1663
|
+
});
|
|
1664
|
+
return this.objectRegistry.getOrCreateSymbol(data);
|
|
1665
|
+
}
|
|
1666
|
+
/**
|
|
1667
|
+
* Get a node's merged symbol. For a declaration, prefer
|
|
1668
|
+
* {@link Checker.getSymbolOfDeclaration} for a non-nullable result.
|
|
1669
|
+
*/
|
|
1670
|
+
async getSymbolOfNode(node) {
|
|
1671
|
+
const data = await this.client.apiRequest("getSymbolOfNode", {
|
|
1672
|
+
snapshot: this.snapshotId,
|
|
1673
|
+
project: this.project.id,
|
|
1674
|
+
location: getNodeId(node),
|
|
1675
|
+
});
|
|
1676
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1677
|
+
}
|
|
1678
|
+
/** Get a declaration's merged symbol. */
|
|
1679
|
+
async getSymbolOfDeclaration(node) {
|
|
1680
|
+
const data = await this.client.apiRequest("getSymbolOfDeclarationForChecker", {
|
|
1681
|
+
snapshot: this.snapshotId,
|
|
1682
|
+
project: this.project.id,
|
|
1683
|
+
location: getNodeId(node),
|
|
1684
|
+
});
|
|
1685
|
+
// Declarations normally have symbols, but preserve unexpected null results at runtime.
|
|
1686
|
+
return (data && this.objectRegistry.getOrCreateSymbol(data));
|
|
1687
|
+
}
|
|
1688
|
+
/** Get a symbol's merged parent, if any. */
|
|
1689
|
+
async getParentOfSymbol(symbol) {
|
|
1690
|
+
const data = await this.client.apiRequest("getParentOfSymbolForChecker", {
|
|
1691
|
+
snapshot: this.snapshotId,
|
|
1692
|
+
project: this.project.id,
|
|
1693
|
+
symbol: symbol.reference,
|
|
1694
|
+
});
|
|
1695
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1696
|
+
}
|
|
616
1697
|
async getSymbolAtLocation(nodeOrNodes) {
|
|
617
1698
|
if (Array.isArray(nodeOrNodes)) {
|
|
618
1699
|
const data = await this.client.apiRequest("getSymbolsAtLocations", {
|
|
@@ -647,21 +1728,37 @@ export class Checker {
|
|
|
647
1728
|
});
|
|
648
1729
|
return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
|
|
649
1730
|
}
|
|
1731
|
+
async getSymbolOfSourceFile(fileOrFiles) {
|
|
1732
|
+
if (Array.isArray(fileOrFiles)) {
|
|
1733
|
+
const data = await this.client.apiRequest("getSymbolsOfSourceFiles", {
|
|
1734
|
+
snapshot: this.snapshotId,
|
|
1735
|
+
project: this.project.id,
|
|
1736
|
+
files: fileOrFiles,
|
|
1737
|
+
});
|
|
1738
|
+
return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
|
|
1739
|
+
}
|
|
1740
|
+
const data = await this.client.apiRequest("getSymbolOfSourceFile", {
|
|
1741
|
+
snapshot: this.snapshotId,
|
|
1742
|
+
project: this.project.id,
|
|
1743
|
+
file: fileOrFiles,
|
|
1744
|
+
});
|
|
1745
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1746
|
+
}
|
|
650
1747
|
async getTypeOfSymbol(symbolOrSymbols) {
|
|
651
1748
|
if (Array.isArray(symbolOrSymbols)) {
|
|
652
1749
|
const data = await this.client.apiRequest("getTypesOfSymbols", {
|
|
653
1750
|
snapshot: this.snapshotId,
|
|
654
1751
|
project: this.project.id,
|
|
655
|
-
symbols: symbolOrSymbols.map(
|
|
1752
|
+
symbols: symbolOrSymbols.map(symbol => symbol.reference),
|
|
656
1753
|
});
|
|
657
|
-
return data.map(d =>
|
|
1754
|
+
return data.map(d => this.objectRegistry.getOrCreateType(d));
|
|
658
1755
|
}
|
|
659
1756
|
const data = await this.client.apiRequest("getTypeOfSymbol", {
|
|
660
1757
|
snapshot: this.snapshotId,
|
|
661
1758
|
project: this.project.id,
|
|
662
|
-
symbol: symbolOrSymbols.
|
|
1759
|
+
symbol: symbolOrSymbols.reference,
|
|
663
1760
|
});
|
|
664
|
-
return
|
|
1761
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
665
1762
|
}
|
|
666
1763
|
/**
|
|
667
1764
|
* Get the declared type of a symbol. Always returns a type; for symbols whose
|
|
@@ -672,63 +1769,32 @@ export class Checker {
|
|
|
672
1769
|
const data = await this.client.apiRequest("getDeclaredTypeOfSymbol", {
|
|
673
1770
|
snapshot: this.snapshotId,
|
|
674
1771
|
project: this.project.id,
|
|
675
|
-
symbol: symbol.
|
|
1772
|
+
symbol: symbol.reference,
|
|
676
1773
|
});
|
|
677
|
-
if (!data)
|
|
678
|
-
throw new Error(`getDeclaredTypeOfSymbol returned no type for symbol ${symbol.id}`);
|
|
679
1774
|
return this.objectRegistry.getOrCreateType(data);
|
|
680
1775
|
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
async getReferencedSymbolsForNode(node, position) {
|
|
691
|
-
const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
|
|
692
|
-
snapshot: this.snapshotId,
|
|
693
|
-
project: this.project.id,
|
|
694
|
-
node: getNodeId(node),
|
|
695
|
-
position,
|
|
696
|
-
});
|
|
697
|
-
return (data ?? []).map(entry => ({
|
|
698
|
-
definition: new NodeHandle(entry.definition, this.project),
|
|
699
|
-
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
|
|
700
|
-
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
|
|
701
|
-
}));
|
|
702
|
-
}
|
|
703
|
-
async getSignatureUsage(signatureDecl) {
|
|
704
|
-
const data = await this.client.apiRequest("getSignatureUsages", {
|
|
1776
|
+
/**
|
|
1777
|
+
* Get the type of a symbol, excluding the missing type when
|
|
1778
|
+
* `exactOptionalPropertyTypes: true` is set; for symbols whose
|
|
1779
|
+
* type cannot be determined the checker yields the error type
|
|
1780
|
+
* (use {@link Type.isErrorType} to detect it).
|
|
1781
|
+
*/
|
|
1782
|
+
async getNonMissingTypeOfSymbol(symbol) {
|
|
1783
|
+
const data = await this.client.apiRequest("getNonMissingTypeOfSymbol", {
|
|
705
1784
|
snapshot: this.snapshotId,
|
|
706
1785
|
project: this.project.id,
|
|
707
|
-
|
|
1786
|
+
symbol: symbol.reference,
|
|
708
1787
|
});
|
|
709
|
-
return (data
|
|
710
|
-
name: new NodeHandle(entry.name, this.project),
|
|
711
|
-
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
|
|
712
|
-
}));
|
|
1788
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
713
1789
|
}
|
|
714
|
-
async
|
|
715
|
-
const data = await this.client.apiRequest("
|
|
1790
|
+
async getReferencesToSymbolInFile(file, symbol) {
|
|
1791
|
+
const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
|
|
716
1792
|
snapshot: this.snapshotId,
|
|
717
1793
|
project: this.project.id,
|
|
718
|
-
file
|
|
719
|
-
|
|
720
|
-
triggerCharacter: options?.triggerCharacter,
|
|
721
|
-
includeSymbol: options?.includeSymbol,
|
|
1794
|
+
file,
|
|
1795
|
+
symbol: symbol.reference,
|
|
722
1796
|
});
|
|
723
|
-
|
|
724
|
-
return undefined;
|
|
725
|
-
return {
|
|
726
|
-
isIncomplete: data.isIncomplete,
|
|
727
|
-
entries: data.entries.map(e => ({
|
|
728
|
-
...e,
|
|
729
|
-
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
|
|
730
|
-
})),
|
|
731
|
-
};
|
|
1797
|
+
return (data ?? []).map(h => new NodeHandle(h, this.project));
|
|
732
1798
|
}
|
|
733
1799
|
async getTypeAtLocation(nodeOrNodes) {
|
|
734
1800
|
if (Array.isArray(nodeOrNodes)) {
|
|
@@ -737,31 +1803,30 @@ export class Checker {
|
|
|
737
1803
|
project: this.project.id,
|
|
738
1804
|
locations: nodeOrNodes.map(node => getNodeId(node)),
|
|
739
1805
|
});
|
|
740
|
-
return data.map(d =>
|
|
1806
|
+
return data.map(d => this.objectRegistry.getOrCreateType(d));
|
|
741
1807
|
}
|
|
742
1808
|
const data = await this.client.apiRequest("getTypeAtLocation", {
|
|
743
1809
|
snapshot: this.snapshotId,
|
|
744
1810
|
project: this.project.id,
|
|
745
1811
|
location: getNodeId(nodeOrNodes),
|
|
746
1812
|
});
|
|
747
|
-
return
|
|
1813
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
748
1814
|
}
|
|
749
1815
|
async getSignaturesOfType(type, kind) {
|
|
750
|
-
|
|
751
|
-
snapshot: this.snapshotId,
|
|
752
|
-
project: this.project.id,
|
|
753
|
-
type: type.id,
|
|
754
|
-
kind,
|
|
755
|
-
});
|
|
756
|
-
return data.map(d => this.objectRegistry.getOrCreateSignature(d));
|
|
1816
|
+
return kind === SignatureKind.Call ? type.getCallSignatures() : type.getConstructSignatures();
|
|
757
1817
|
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Get the resolved signature of a call-like expression. Always returns a
|
|
1820
|
+
* signature; when a call cannot be resolved the checker yields the unknown
|
|
1821
|
+
* signature (use {@link Checker.isUnknownSignature} to detect it).
|
|
1822
|
+
*/
|
|
758
1823
|
async getResolvedSignature(node) {
|
|
759
1824
|
const data = await this.client.apiRequest("getResolvedSignature", {
|
|
760
1825
|
snapshot: this.snapshotId,
|
|
761
1826
|
project: this.project.id,
|
|
762
1827
|
location: getNodeId(node),
|
|
763
1828
|
});
|
|
764
|
-
return
|
|
1829
|
+
return this.objectRegistry.getOrCreateSignature(data);
|
|
765
1830
|
}
|
|
766
1831
|
async getTypeAtPosition(file, positionOrPositions) {
|
|
767
1832
|
if (typeof positionOrPositions === "number") {
|
|
@@ -796,6 +1861,22 @@ export class Checker {
|
|
|
796
1861
|
});
|
|
797
1862
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
798
1863
|
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Returns all symbols with the given meaning that are visible at `location`.
|
|
1866
|
+
*/
|
|
1867
|
+
async getSymbolsInScope(location, meaning) {
|
|
1868
|
+
// Distinguish Node (has `kind`) from DocumentPosition (has `document` and `position`)
|
|
1869
|
+
const isNode = "kind" in location;
|
|
1870
|
+
const data = await this.client.apiRequest("getSymbolsInScope", {
|
|
1871
|
+
snapshot: this.snapshotId,
|
|
1872
|
+
project: this.project.id,
|
|
1873
|
+
meaning,
|
|
1874
|
+
location: isNode ? getNodeId(location) : undefined,
|
|
1875
|
+
file: isNode ? undefined : location.document,
|
|
1876
|
+
position: isNode ? undefined : location.position,
|
|
1877
|
+
});
|
|
1878
|
+
return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
|
|
1879
|
+
}
|
|
799
1880
|
async getResolvedSymbol(node) {
|
|
800
1881
|
const text = node.text;
|
|
801
1882
|
if (!text)
|
|
@@ -810,38 +1891,62 @@ export class Checker {
|
|
|
810
1891
|
});
|
|
811
1892
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
812
1893
|
}
|
|
813
|
-
async
|
|
814
|
-
const data = await this.client.apiRequest("
|
|
1894
|
+
async getContextualTypeForArgumentAtIndex(node, argIndex) {
|
|
1895
|
+
const data = await this.client.apiRequest("getContextualTypeForArgument", {
|
|
815
1896
|
snapshot: this.snapshotId,
|
|
816
1897
|
project: this.project.id,
|
|
817
|
-
|
|
1898
|
+
location: getNodeId(node),
|
|
1899
|
+
index: argIndex,
|
|
818
1900
|
});
|
|
819
1901
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
820
1902
|
}
|
|
821
|
-
async
|
|
822
|
-
const data = await this.client.apiRequest("
|
|
1903
|
+
async getAwaitedType(type) {
|
|
1904
|
+
const data = await this.client.apiRequest("getAwaitedType", {
|
|
823
1905
|
snapshot: this.snapshotId,
|
|
824
1906
|
project: this.project.id,
|
|
825
1907
|
type: type.id,
|
|
826
1908
|
});
|
|
827
1909
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
828
1910
|
}
|
|
1911
|
+
/** Get the base type of a literal type (e.g. `number` for `42`). Always returns a type. */
|
|
1912
|
+
async getBaseTypeOfLiteralType(type) {
|
|
1913
|
+
const data = await this.client.apiRequest("getBaseTypeOfLiteralType", {
|
|
1914
|
+
snapshot: this.snapshotId,
|
|
1915
|
+
project: this.project.id,
|
|
1916
|
+
type: type.id,
|
|
1917
|
+
});
|
|
1918
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
1919
|
+
}
|
|
1920
|
+
/** Get the type with `null` and `undefined` removed. Always returns a type. */
|
|
1921
|
+
async getNonNullableType(type) {
|
|
1922
|
+
return type.getNonNullableType();
|
|
1923
|
+
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Get the type for a type node. Always returns a type; for type nodes whose
|
|
1926
|
+
* type cannot be determined the checker yields the error type (use
|
|
1927
|
+
* {@link Type.isErrorType} to detect it).
|
|
1928
|
+
*/
|
|
829
1929
|
async getTypeFromTypeNode(node) {
|
|
830
1930
|
const data = await this.client.apiRequest("getTypeFromTypeNode", {
|
|
831
1931
|
snapshot: this.snapshotId,
|
|
832
1932
|
project: this.project.id,
|
|
833
1933
|
location: getNodeId(node),
|
|
834
1934
|
});
|
|
835
|
-
return
|
|
1935
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
836
1936
|
}
|
|
1937
|
+
/** Get the widened type. Always returns a type. */
|
|
837
1938
|
async getWidenedType(type) {
|
|
838
1939
|
const data = await this.client.apiRequest("getWidenedType", {
|
|
839
1940
|
snapshot: this.snapshotId,
|
|
840
1941
|
project: this.project.id,
|
|
841
1942
|
type: type.id,
|
|
842
1943
|
});
|
|
843
|
-
return
|
|
1944
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
844
1945
|
}
|
|
1946
|
+
/**
|
|
1947
|
+
* Get the type of the parameter at the given index in a signature. Always
|
|
1948
|
+
* returns a type; an out-of-range index yields the `any` type.
|
|
1949
|
+
*/
|
|
845
1950
|
async getParameterType(signature, index) {
|
|
846
1951
|
const data = await this.client.apiRequest("getParameterType", {
|
|
847
1952
|
snapshot: this.snapshotId,
|
|
@@ -849,7 +1954,7 @@ export class Checker {
|
|
|
849
1954
|
signature: signature.id,
|
|
850
1955
|
index,
|
|
851
1956
|
});
|
|
852
|
-
return
|
|
1957
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
853
1958
|
}
|
|
854
1959
|
async isArrayLikeType(type) {
|
|
855
1960
|
return this.client.apiRequest("isArrayLikeType", {
|
|
@@ -883,11 +1988,9 @@ export class Checker {
|
|
|
883
1988
|
const data = await this.client.apiRequest("getTypeOfSymbolAtLocation", {
|
|
884
1989
|
snapshot: this.snapshotId,
|
|
885
1990
|
project: this.project.id,
|
|
886
|
-
symbol: symbol.
|
|
1991
|
+
symbol: symbol.reference,
|
|
887
1992
|
location: getNodeId(location),
|
|
888
1993
|
});
|
|
889
|
-
if (!data)
|
|
890
|
-
throw new Error(`getTypeOfSymbolAtLocation returned no type for symbol ${symbol.id}`);
|
|
891
1994
|
return this.objectRegistry.getOrCreateType(data);
|
|
892
1995
|
}
|
|
893
1996
|
async getIntrinsicType(method) {
|
|
@@ -930,6 +2033,9 @@ export class Checker {
|
|
|
930
2033
|
async getESSymbolType() {
|
|
931
2034
|
return this.getIntrinsicType("getESSymbolType");
|
|
932
2035
|
}
|
|
2036
|
+
async getNonPrimitiveType() {
|
|
2037
|
+
return this.getIntrinsicType("getNonPrimitiveType");
|
|
2038
|
+
}
|
|
933
2039
|
async typeToTypeNode(type, enclosingDeclaration, flags) {
|
|
934
2040
|
const binaryData = await this.client.apiRequestBinary("typeToTypeNode", {
|
|
935
2041
|
snapshot: this.snapshotId,
|
|
@@ -956,13 +2062,16 @@ export class Checker {
|
|
|
956
2062
|
return decodeNode(binaryData);
|
|
957
2063
|
}
|
|
958
2064
|
async typeToString(type, enclosingDeclaration, flags) {
|
|
959
|
-
|
|
2065
|
+
const result = await this.client.apiRequest("typeToString", {
|
|
960
2066
|
snapshot: this.snapshotId,
|
|
961
2067
|
project: this.project.id,
|
|
962
2068
|
type: type.id,
|
|
963
2069
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
964
2070
|
flags,
|
|
965
2071
|
});
|
|
2072
|
+
if (typeof result !== "string")
|
|
2073
|
+
throw new TypeError("typeToString returned a non-string result");
|
|
2074
|
+
return result;
|
|
966
2075
|
}
|
|
967
2076
|
async isContextSensitive(node) {
|
|
968
2077
|
return this.client.apiRequest("isContextSensitive", {
|
|
@@ -979,27 +2088,42 @@ export class Checker {
|
|
|
979
2088
|
});
|
|
980
2089
|
}
|
|
981
2090
|
async isTupleType(type) {
|
|
982
|
-
return
|
|
2091
|
+
return type.isTupleType();
|
|
2092
|
+
}
|
|
2093
|
+
async isTupleTypeTarget(type) {
|
|
2094
|
+
return type.isTupleTypeTarget();
|
|
2095
|
+
}
|
|
2096
|
+
/**
|
|
2097
|
+
* The following symbols are considered read-only:
|
|
2098
|
+
* - Properties with a `readonly` modifier
|
|
2099
|
+
* - Variables declared with `const`
|
|
2100
|
+
* - Get accessors without matching set accessors
|
|
2101
|
+
* - Enum members
|
|
2102
|
+
* - `Object.defineProperty` assignments with `writable: false` or no setter
|
|
2103
|
+
* - Unions and intersections of the above
|
|
2104
|
+
*/
|
|
2105
|
+
async isReadonlySymbol(symbol) {
|
|
2106
|
+
return this.client.apiRequest("isReadonlySymbol", {
|
|
983
2107
|
snapshot: this.snapshotId,
|
|
984
2108
|
project: this.project.id,
|
|
985
|
-
|
|
2109
|
+
symbol: symbol.reference,
|
|
986
2110
|
});
|
|
987
2111
|
}
|
|
2112
|
+
/** Get the return type of a signature. Always returns a type. */
|
|
988
2113
|
async getReturnTypeOfSignature(signature) {
|
|
989
|
-
|
|
990
|
-
snapshot: this.snapshotId,
|
|
991
|
-
project: this.project.id,
|
|
992
|
-
signature: signature.id,
|
|
993
|
-
});
|
|
994
|
-
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
2114
|
+
return signature.getReturnType();
|
|
995
2115
|
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Get the rest type of a signature. Always returns a type; a signature with
|
|
2118
|
+
* no rest parameter yields the `any` type.
|
|
2119
|
+
*/
|
|
996
2120
|
async getRestTypeOfSignature(signature) {
|
|
997
2121
|
const data = await this.client.apiRequest("getRestTypeOfSignature", {
|
|
998
2122
|
snapshot: this.snapshotId,
|
|
999
2123
|
project: this.project.id,
|
|
1000
2124
|
signature: signature.id,
|
|
1001
2125
|
});
|
|
1002
|
-
return
|
|
2126
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
1003
2127
|
}
|
|
1004
2128
|
async getTypePredicateOfSignature(signature) {
|
|
1005
2129
|
const data = await this.client.apiRequest("getTypePredicateOfSignature", {
|
|
@@ -1021,55 +2145,57 @@ export class Checker {
|
|
|
1021
2145
|
* yields an empty array.
|
|
1022
2146
|
*/
|
|
1023
2147
|
async getBaseTypes(type) {
|
|
1024
|
-
|
|
1025
|
-
snapshot: this.snapshotId,
|
|
1026
|
-
project: this.project.id,
|
|
1027
|
-
type: type.id,
|
|
1028
|
-
});
|
|
1029
|
-
return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
|
|
2148
|
+
return await type.getBaseTypes() ?? [];
|
|
1030
2149
|
}
|
|
2150
|
+
/** Get the apparent type of a type. Always returns a type. */
|
|
1031
2151
|
async getApparentType(type) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
2152
|
+
return type.getApparentType();
|
|
2153
|
+
}
|
|
2154
|
+
/** Get the reduced type of a type. Always returns a type. */
|
|
2155
|
+
async getReducedType(type) {
|
|
2156
|
+
return type.getReducedType();
|
|
1038
2157
|
}
|
|
1039
2158
|
async getPropertiesOfType(type) {
|
|
1040
|
-
|
|
2159
|
+
return type.getProperties();
|
|
2160
|
+
}
|
|
2161
|
+
async getIndexInfosOfType(type) {
|
|
2162
|
+
return type.getIndexInfos();
|
|
2163
|
+
}
|
|
2164
|
+
async getIndexInfoOfType(type, kind) {
|
|
2165
|
+
const data = await this.client.apiRequest("getIndexInfoOfType", {
|
|
1041
2166
|
snapshot: this.snapshotId,
|
|
1042
2167
|
project: this.project.id,
|
|
1043
2168
|
type: type.id,
|
|
2169
|
+
kind,
|
|
1044
2170
|
});
|
|
1045
|
-
return data ?
|
|
2171
|
+
return data ? {
|
|
2172
|
+
keyType: this.objectRegistry.getOrCreateType(data.keyType),
|
|
2173
|
+
valueType: this.objectRegistry.getOrCreateType(data.valueType),
|
|
2174
|
+
isReadonly: data.isReadonly ?? false,
|
|
2175
|
+
declaration: data.declaration ? new NodeHandle(data.declaration, this.project) : undefined,
|
|
2176
|
+
} : undefined;
|
|
1046
2177
|
}
|
|
1047
|
-
async
|
|
1048
|
-
|
|
2178
|
+
async getIndexTypeOfType(type, kind) {
|
|
2179
|
+
return kind === IndexKind.String ? type.getStringIndexType() : type.getNumberIndexType();
|
|
2180
|
+
}
|
|
2181
|
+
async getTypeOfPropertyOfType(type, propertyName) {
|
|
2182
|
+
const data = await this.client.apiRequest("getTypeOfPropertyOfType", {
|
|
1049
2183
|
snapshot: this.snapshotId,
|
|
1050
2184
|
project: this.project.id,
|
|
1051
2185
|
type: type.id,
|
|
2186
|
+
name: propertyName,
|
|
1052
2187
|
});
|
|
1053
|
-
|
|
1054
|
-
return [];
|
|
1055
|
-
return data.map(d => ({
|
|
1056
|
-
keyType: this.objectRegistry.getOrCreateType(d.keyType),
|
|
1057
|
-
valueType: this.objectRegistry.getOrCreateType(d.valueType),
|
|
1058
|
-
isReadonly: d.isReadonly ?? false,
|
|
1059
|
-
declaration: d.declaration ? new NodeHandle(d.declaration, this.project) : undefined,
|
|
1060
|
-
}));
|
|
2188
|
+
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
1061
2189
|
}
|
|
1062
2190
|
/**
|
|
1063
2191
|
* Get the constraint of a type parameter (the `T` in `<U extends T>`), or
|
|
1064
2192
|
* undefined if it has none.
|
|
1065
2193
|
*/
|
|
1066
2194
|
async getConstraintOfTypeParameter(type) {
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
});
|
|
1072
|
-
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
2195
|
+
return type.getConstraint();
|
|
2196
|
+
}
|
|
2197
|
+
async getDefaultFromTypeParameter(type) {
|
|
2198
|
+
return type.getDefault();
|
|
1073
2199
|
}
|
|
1074
2200
|
async getBaseConstraintOfType(type) {
|
|
1075
2201
|
const data = await this.client.apiRequest("getBaseConstraintOfType", {
|
|
@@ -1094,15 +2220,28 @@ export class Checker {
|
|
|
1094
2220
|
project: this.project.id,
|
|
1095
2221
|
location: getNodeId(node),
|
|
1096
2222
|
});
|
|
1097
|
-
|
|
2223
|
+
if (!data || (typeof data.value !== "string" && typeof data.value !== "number")) {
|
|
2224
|
+
return undefined;
|
|
2225
|
+
}
|
|
2226
|
+
if (data.isNumber && typeof data.value === "string") {
|
|
2227
|
+
if (data.value === "+Infinity") {
|
|
2228
|
+
return Infinity;
|
|
2229
|
+
}
|
|
2230
|
+
else if (data.value === "-Infinity") {
|
|
2231
|
+
return -Infinity;
|
|
2232
|
+
}
|
|
2233
|
+
return NaN;
|
|
2234
|
+
}
|
|
2235
|
+
return data.value;
|
|
1098
2236
|
}
|
|
2237
|
+
/** Get the signature of a function-like declaration. Always returns a signature. */
|
|
1099
2238
|
async getSignatureFromDeclaration(node) {
|
|
1100
2239
|
const data = await this.client.apiRequest("getSignatureFromDeclaration", {
|
|
1101
2240
|
snapshot: this.snapshotId,
|
|
1102
2241
|
project: this.project.id,
|
|
1103
2242
|
location: getNodeId(node),
|
|
1104
2243
|
});
|
|
1105
|
-
return
|
|
2244
|
+
return this.objectRegistry.getOrCreateSignature(data);
|
|
1106
2245
|
}
|
|
1107
2246
|
async getExportSpecifierLocalTargetSymbol(node) {
|
|
1108
2247
|
const data = await this.client.apiRequest("getExportSpecifierLocalTargetSymbol", {
|
|
@@ -1121,20 +2260,51 @@ export class Checker {
|
|
|
1121
2260
|
const data = await this.client.apiRequest("getAliasedSymbol", {
|
|
1122
2261
|
snapshot: this.snapshotId,
|
|
1123
2262
|
project: this.project.id,
|
|
1124
|
-
symbol: symbol.
|
|
2263
|
+
symbol: symbol.reference,
|
|
1125
2264
|
});
|
|
1126
|
-
if (!data)
|
|
1127
|
-
throw new Error(`getAliasedSymbol returned no symbol for symbol ${symbol.id}`);
|
|
1128
2265
|
return this.objectRegistry.getOrCreateSymbol(data);
|
|
1129
2266
|
}
|
|
2267
|
+
/**
|
|
2268
|
+
* Get the fully qualified name of a symbol, walking up its parent chain
|
|
2269
|
+
* (e.g. `"/path/to/module".Namespace.Name`).
|
|
2270
|
+
*/
|
|
2271
|
+
async getFullyQualifiedName(symbol) {
|
|
2272
|
+
return this.client.apiRequest("getFullyQualifiedName", {
|
|
2273
|
+
snapshot: this.snapshotId,
|
|
2274
|
+
project: this.project.id,
|
|
2275
|
+
symbol: symbol.reference,
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
1130
2278
|
async getImmediateAliasedSymbol(symbol) {
|
|
1131
2279
|
const data = await this.client.apiRequest("getImmediateAliasedSymbol", {
|
|
1132
2280
|
snapshot: this.snapshotId,
|
|
1133
2281
|
project: this.project.id,
|
|
1134
|
-
symbol: symbol.
|
|
2282
|
+
symbol: symbol.reference,
|
|
1135
2283
|
});
|
|
1136
2284
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1137
2285
|
}
|
|
2286
|
+
/**
|
|
2287
|
+
* Get the target symbol if instantiated, or the provided symbol otherwise.
|
|
2288
|
+
*/
|
|
2289
|
+
async getTargetSymbol(symbol) {
|
|
2290
|
+
if (symbol.checkFlags & CheckFlags.Instantiated) {
|
|
2291
|
+
const data = await this.client.apiRequest("getTargetSymbol", {
|
|
2292
|
+
snapshot: this.snapshotId,
|
|
2293
|
+
project: this.project.id,
|
|
2294
|
+
symbol: symbol.reference,
|
|
2295
|
+
});
|
|
2296
|
+
return this.objectRegistry.getOrCreateSymbol(data);
|
|
2297
|
+
}
|
|
2298
|
+
return symbol;
|
|
2299
|
+
}
|
|
2300
|
+
async getExportSymbolOfSymbol(symbol) {
|
|
2301
|
+
const data = await this.client.apiRequest("getExportSymbolOfSymbolForChecker", {
|
|
2302
|
+
snapshot: this.snapshotId,
|
|
2303
|
+
project: this.project.id,
|
|
2304
|
+
symbol: symbol.reference,
|
|
2305
|
+
});
|
|
2306
|
+
return this.objectRegistry.getOrCreateSymbol(data);
|
|
2307
|
+
}
|
|
1138
2308
|
/**
|
|
1139
2309
|
* Fetch (once, then cache) the handle ids of the per-checker singleton
|
|
1140
2310
|
* symbols (unknown, undefined, arguments). These ids are stable for the life
|
|
@@ -1166,11 +2336,30 @@ export class Checker {
|
|
|
1166
2336
|
async isArgumentsSymbol(symbol) {
|
|
1167
2337
|
return symbol.id === (await this.getWellKnownSymbols()).arguments;
|
|
1168
2338
|
}
|
|
2339
|
+
/**
|
|
2340
|
+
* Fetch (once, then cache) the handle id of the per-checker unknown
|
|
2341
|
+
* signature. This id is stable for the life of the project's checker, so
|
|
2342
|
+
* identity checks against it are local after the first call.
|
|
2343
|
+
*/
|
|
2344
|
+
getWellKnownSignatures() {
|
|
2345
|
+
return this.wellKnownSignatures ??= this.client.apiRequest("getWellKnownSignatures", {
|
|
2346
|
+
snapshot: this.snapshotId,
|
|
2347
|
+
project: this.project.id,
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2351
|
+
* Returns `true` if the signature is the checker's "unknown" signature (e.g.
|
|
2352
|
+
* the result of {@link Checker.getResolvedSignature} on a call that cannot be
|
|
2353
|
+
* resolved).
|
|
2354
|
+
*/
|
|
2355
|
+
async isUnknownSignature(signature) {
|
|
2356
|
+
return signature.id === (await this.getWellKnownSignatures()).unknown;
|
|
2357
|
+
}
|
|
1169
2358
|
async getExportsOfModule(symbol) {
|
|
1170
2359
|
const data = await this.client.apiRequest("getExportsOfModule", {
|
|
1171
2360
|
snapshot: this.snapshotId,
|
|
1172
2361
|
project: this.project.id,
|
|
1173
|
-
symbol: symbol.
|
|
2362
|
+
symbol: symbol.reference,
|
|
1174
2363
|
});
|
|
1175
2364
|
return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
|
|
1176
2365
|
}
|
|
@@ -1178,7 +2367,7 @@ export class Checker {
|
|
|
1178
2367
|
const data = await this.client.apiRequest("getMemberInModuleExports", {
|
|
1179
2368
|
snapshot: this.snapshotId,
|
|
1180
2369
|
project: this.project.id,
|
|
1181
|
-
symbol: symbol.
|
|
2370
|
+
symbol: symbol.reference,
|
|
1182
2371
|
name,
|
|
1183
2372
|
});
|
|
1184
2373
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
@@ -1187,7 +2376,7 @@ export class Checker {
|
|
|
1187
2376
|
const data = await this.client.apiRequest("getJsDocTags", {
|
|
1188
2377
|
snapshot: this.snapshotId,
|
|
1189
2378
|
project: this.project.id,
|
|
1190
|
-
symbol: symbol.
|
|
2379
|
+
symbol: symbol.reference,
|
|
1191
2380
|
});
|
|
1192
2381
|
return data ?? [];
|
|
1193
2382
|
}
|
|
@@ -1195,7 +2384,7 @@ export class Checker {
|
|
|
1195
2384
|
return this.client.apiRequest("getDocumentationComment", {
|
|
1196
2385
|
snapshot: this.snapshotId,
|
|
1197
2386
|
project: this.project.id,
|
|
1198
|
-
symbol: symbol.
|
|
2387
|
+
symbol: symbol.reference,
|
|
1199
2388
|
});
|
|
1200
2389
|
}
|
|
1201
2390
|
/**
|
|
@@ -1210,7 +2399,7 @@ export class Checker {
|
|
|
1210
2399
|
return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
|
|
1211
2400
|
}
|
|
1212
2401
|
}
|
|
1213
|
-
export class
|
|
2402
|
+
export class Printer {
|
|
1214
2403
|
client;
|
|
1215
2404
|
constructor(client) {
|
|
1216
2405
|
this.client = client;
|
|
@@ -1220,7 +2409,19 @@ export class Emitter {
|
|
|
1220
2409
|
const base64 = uint8ArrayToBase64(encoded);
|
|
1221
2410
|
return this.client.apiRequest("printNode", {
|
|
1222
2411
|
data: base64,
|
|
1223
|
-
|
|
2412
|
+
preserveSourceNewlines: options.preserveSourceNewlines,
|
|
2413
|
+
neverAsciiEscape: options.neverAsciiEscape,
|
|
2414
|
+
terminateUnterminatedLiterals: options.terminateUnterminatedLiterals,
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
async printFile(sourceFile, options = {}) {
|
|
2418
|
+
const encoded = encodeNode(sourceFile);
|
|
2419
|
+
const base64 = uint8ArrayToBase64(encoded);
|
|
2420
|
+
return this.client.apiRequest("printNode", {
|
|
2421
|
+
data: base64,
|
|
2422
|
+
preserveSourceNewlines: options.preserveSourceNewlines,
|
|
2423
|
+
neverAsciiEscape: options.neverAsciiEscape,
|
|
2424
|
+
terminateUnterminatedLiterals: options.terminateUnterminatedLiterals,
|
|
1224
2425
|
});
|
|
1225
2426
|
}
|
|
1226
2427
|
}
|
|
@@ -1231,71 +2432,89 @@ export class NodeHandle {
|
|
|
1231
2432
|
* is remembered so callers don't have to pass it explicitly.
|
|
1232
2433
|
*/
|
|
1233
2434
|
canonicalProject;
|
|
2435
|
+
/** The owning source file of a file-owned symbol's declaration. */
|
|
2436
|
+
fileOwner;
|
|
1234
2437
|
index;
|
|
1235
2438
|
kind;
|
|
1236
2439
|
path;
|
|
1237
|
-
constructor(handle, canonicalProject) {
|
|
1238
|
-
const parsed =
|
|
2440
|
+
constructor(handle, canonicalProject, fileOwner) {
|
|
2441
|
+
const parsed = parseNodeHandleFromCompiler(handle);
|
|
1239
2442
|
this.index = parsed.index;
|
|
1240
2443
|
this.kind = parsed.kind;
|
|
1241
2444
|
this.path = parsed.path;
|
|
1242
2445
|
this.canonicalProject = canonicalProject;
|
|
2446
|
+
this.fileOwner = fileOwner;
|
|
1243
2447
|
}
|
|
1244
2448
|
/**
|
|
1245
2449
|
* Resolve this handle to the actual AST node by fetching the source file from a project
|
|
1246
2450
|
* and looking up the node by index. If no project is passed, the project that produced
|
|
1247
|
-
* the handle is used.
|
|
2451
|
+
* the handle is used. Declarations of file-owned symbols identify an exact source file and
|
|
2452
|
+
* resolve through it, independently of any project.
|
|
1248
2453
|
*/
|
|
1249
2454
|
async resolve(project = this.canonicalProject) {
|
|
1250
|
-
|
|
2455
|
+
if (this.fileOwner) {
|
|
2456
|
+
const sourceFile = this.fileOwner.record.file ?? await this.fetchOwnerFile(this.fileOwner);
|
|
2457
|
+
return sourceFile.getOrCreateNodeAtIndex(this.index);
|
|
2458
|
+
}
|
|
2459
|
+
if (!project)
|
|
2460
|
+
throw new Error(`Node handle for '${this.path}' has no project context`);
|
|
2461
|
+
const sourceFile = await project.program.getSourceFileByPath(this.path);
|
|
1251
2462
|
if (!sourceFile) {
|
|
1252
2463
|
return undefined;
|
|
1253
2464
|
}
|
|
1254
2465
|
return sourceFile.getOrCreateNodeAtIndex(this.index);
|
|
1255
2466
|
}
|
|
2467
|
+
async fetchOwnerFile(fileOwner) {
|
|
2468
|
+
const data = await fileOwner.api.client.apiRequestBinary("getCachedSourceFile", { file: fileOwner.record.descriptor });
|
|
2469
|
+
if (!data)
|
|
2470
|
+
throw new Error(`Source file '${fileOwner.record.descriptor.fileName}' is not available`);
|
|
2471
|
+
return fileOwner.api.sourceFileCache.attachFile(fileOwner.record, new RemoteSourceFile(data, new Wtf8Decoder(), fileOwner.api.client.getTimingCollector(), fileOwner.api));
|
|
2472
|
+
}
|
|
1256
2473
|
}
|
|
1257
2474
|
export class Symbol {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
* snapshot-wide, so these lookups can otherwise be ambiguous about which project to use.
|
|
1263
|
-
*/
|
|
1264
|
-
canonicalProject;
|
|
1265
|
-
id;
|
|
2475
|
+
storage;
|
|
2476
|
+
get id() {
|
|
2477
|
+
return this.reference.id;
|
|
2478
|
+
}
|
|
1266
2479
|
/** The escaped (`__String`) name, used as the key in member/export tables. */
|
|
1267
2480
|
escapedName;
|
|
1268
2481
|
/** The display name (escaped underscores removed). */
|
|
1269
2482
|
name;
|
|
1270
2483
|
flags;
|
|
1271
2484
|
checkFlags;
|
|
2485
|
+
/** @internal */
|
|
2486
|
+
reference;
|
|
1272
2487
|
declarations;
|
|
1273
2488
|
valueDeclaration;
|
|
1274
2489
|
parent;
|
|
1275
2490
|
exportSymbol;
|
|
1276
2491
|
membersCache;
|
|
1277
2492
|
exportsCache;
|
|
1278
|
-
constructor(data,
|
|
1279
|
-
|
|
1280
|
-
|
|
2493
|
+
constructor(data, storage) {
|
|
2494
|
+
if (data.reference.kind !== storage.kind)
|
|
2495
|
+
throw new Error(`Symbol ${data.reference.id} has mismatched ownership and storage`);
|
|
2496
|
+
this.storage = storage;
|
|
2497
|
+
this.reference = data.reference;
|
|
1281
2498
|
this.escapedName = data.name;
|
|
1282
2499
|
this.name = unescapeLeadingUnderscores(data.name);
|
|
1283
2500
|
this.flags = data.flags;
|
|
1284
2501
|
this.checkFlags = data.checkFlags;
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
this.
|
|
1290
|
-
|
|
1291
|
-
|
|
2502
|
+
// A file-owned symbol has no canonical project; its declarations resolve through its file.
|
|
2503
|
+
const project = storage.kind === SymbolOwnerKind.Snapshot ? storage.registry.project : undefined;
|
|
2504
|
+
const fileOwner = storage.kind === SymbolOwnerKind.File ? storage.owner : undefined;
|
|
2505
|
+
this.declarations = (data.declarations ?? []).map(handle => new NodeHandle(handle, project, fileOwner));
|
|
2506
|
+
this.valueDeclaration = data.valueDeclaration
|
|
2507
|
+
? new NodeHandle(data.valueDeclaration, project, fileOwner)
|
|
2508
|
+
: undefined;
|
|
1292
2509
|
if (data.parent !== undefined)
|
|
1293
2510
|
this.parent = data.parent;
|
|
1294
2511
|
if (data.exportSymbol !== undefined)
|
|
1295
2512
|
this.exportSymbol = data.exportSymbol;
|
|
1296
2513
|
}
|
|
1297
2514
|
async getParent() {
|
|
1298
|
-
|
|
2515
|
+
if (!this.parent)
|
|
2516
|
+
return undefined;
|
|
2517
|
+
return this.fetchSymbol("getParentOfSymbol", this.parent);
|
|
1299
2518
|
}
|
|
1300
2519
|
/**
|
|
1301
2520
|
* Get this symbol's members keyed by escaped name. The result is cached on
|
|
@@ -1312,7 +2531,7 @@ export class Symbol {
|
|
|
1312
2531
|
return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
|
|
1313
2532
|
}
|
|
1314
2533
|
async fetchSymbolTable(method) {
|
|
1315
|
-
const symbols = await this.
|
|
2534
|
+
const symbols = await this.fetchSymbols(method);
|
|
1316
2535
|
const table = new Map();
|
|
1317
2536
|
for (const symbol of symbols) {
|
|
1318
2537
|
table.set(symbol.escapedName, symbol);
|
|
@@ -1322,7 +2541,7 @@ export class Symbol {
|
|
|
1322
2541
|
async getExportSymbol() {
|
|
1323
2542
|
if (!this.exportSymbol)
|
|
1324
2543
|
return this;
|
|
1325
|
-
return this.
|
|
2544
|
+
return this.fetchSymbol("getExportSymbolOfSymbol", this.exportSymbol);
|
|
1326
2545
|
}
|
|
1327
2546
|
async getJsDocTags(checker) {
|
|
1328
2547
|
return checker.getJsDocTagsOfSymbol(this);
|
|
@@ -1330,9 +2549,40 @@ export class Symbol {
|
|
|
1330
2549
|
async getDocumentationComment(checker) {
|
|
1331
2550
|
return checker.getDocumentationCommentOfSymbol(this);
|
|
1332
2551
|
}
|
|
2552
|
+
async fetchSymbol(method, reference) {
|
|
2553
|
+
if (this.storage.kind === SymbolOwnerKind.Snapshot) {
|
|
2554
|
+
return this.storage.registry.fetchSymbol(this, method, reference);
|
|
2555
|
+
}
|
|
2556
|
+
const fileOwner = this.storage.owner;
|
|
2557
|
+
// A file-owned symbol's relationships are always owned by the same file.
|
|
2558
|
+
const cached = reference.file === fileOwner.record.descriptor.nodeId ? fileOwner.record.symbolsById.get(reference.id) : undefined;
|
|
2559
|
+
if (cached)
|
|
2560
|
+
return cached;
|
|
2561
|
+
const data = await fileOwner.api.client.apiRequest(method, { symbol: this.reference });
|
|
2562
|
+
if (!data)
|
|
2563
|
+
throw new Error(`${method} returned null symbol for Symbol ${this.id}`);
|
|
2564
|
+
return this.internFileSymbol(fileOwner, data);
|
|
2565
|
+
}
|
|
2566
|
+
async fetchSymbols(method) {
|
|
2567
|
+
if (this.storage.kind === SymbolOwnerKind.Snapshot) {
|
|
2568
|
+
return this.storage.registry.fetchSymbols(this, method);
|
|
2569
|
+
}
|
|
2570
|
+
const fileOwner = this.storage.owner;
|
|
2571
|
+
const data = await fileOwner.api.client.apiRequest(method, { symbol: this.reference });
|
|
2572
|
+
return data?.map(symbol => this.internFileSymbol(fileOwner, symbol)) ?? [];
|
|
2573
|
+
}
|
|
2574
|
+
internFileSymbol(fileOwner, data) {
|
|
2575
|
+
validateSymbolResponse(data);
|
|
2576
|
+
const reference = data.reference;
|
|
2577
|
+
if (reference.kind !== SymbolOwnerKind.File)
|
|
2578
|
+
throw new Error(`Symbol ${reference.id} is not file-owned`);
|
|
2579
|
+
return fileOwner.api.sourceFileCache.getOrCreateSymbol(fileOwner.record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
|
|
2580
|
+
}
|
|
1333
2581
|
}
|
|
1334
2582
|
class TypeObject {
|
|
1335
2583
|
objectRegistry;
|
|
2584
|
+
// Fields included in TypeResponse. References to other objects are stored as IDs
|
|
2585
|
+
// and resolved lazily via the object registry.
|
|
1336
2586
|
id;
|
|
1337
2587
|
flags;
|
|
1338
2588
|
objectFlags;
|
|
@@ -1343,14 +2593,17 @@ class TypeObject {
|
|
|
1343
2593
|
freshType;
|
|
1344
2594
|
regularType;
|
|
1345
2595
|
target;
|
|
2596
|
+
tupleType;
|
|
1346
2597
|
typeParameters;
|
|
1347
2598
|
outerTypeParameters;
|
|
1348
2599
|
localTypeParameters;
|
|
2600
|
+
thisType;
|
|
1349
2601
|
aliasTypeArguments;
|
|
1350
2602
|
aliasSymbol;
|
|
1351
2603
|
elementFlags;
|
|
1352
2604
|
fixedLength;
|
|
1353
2605
|
readonly;
|
|
2606
|
+
labeledElementDeclarations;
|
|
1354
2607
|
texts;
|
|
1355
2608
|
objectType;
|
|
1356
2609
|
indexType;
|
|
@@ -1358,8 +2611,31 @@ class TypeObject {
|
|
|
1358
2611
|
extendsType;
|
|
1359
2612
|
baseType;
|
|
1360
2613
|
substConstraint;
|
|
1361
|
-
|
|
1362
|
-
|
|
2614
|
+
typeParameter;
|
|
2615
|
+
constraintType;
|
|
2616
|
+
nameType;
|
|
2617
|
+
templateType;
|
|
2618
|
+
// Cached results of lazy fetches, not included in TypeResponse
|
|
2619
|
+
// (typically because they require some amount of computation or
|
|
2620
|
+
// could cause an arbitrarily large number of types to be cached
|
|
2621
|
+
// on the server for ID-based lookup). `false` is a sentinel value
|
|
2622
|
+
// indicating a fetch has not yet occurred.
|
|
2623
|
+
trueType;
|
|
2624
|
+
falseType;
|
|
2625
|
+
constraint;
|
|
2626
|
+
default;
|
|
2627
|
+
nonNullableType;
|
|
2628
|
+
apparentType;
|
|
2629
|
+
reducedType;
|
|
2630
|
+
properties;
|
|
2631
|
+
apparentProperties;
|
|
2632
|
+
callSignatures;
|
|
2633
|
+
constructSignatures;
|
|
2634
|
+
indexInfos;
|
|
2635
|
+
baseTypes;
|
|
2636
|
+
types;
|
|
2637
|
+
stringIndexType;
|
|
2638
|
+
numberIndexType;
|
|
1363
2639
|
constructor(data, objectRegistry) {
|
|
1364
2640
|
this.objectRegistry = objectRegistry;
|
|
1365
2641
|
this.id = data.id;
|
|
@@ -1371,7 +2647,25 @@ class TypeObject {
|
|
|
1371
2647
|
if (data.value != null) {
|
|
1372
2648
|
// BigInt literal values are serialized as decimal strings (e.g. "-123") because
|
|
1373
2649
|
// JSON cannot represent bigint. Decode them back into a real bigint here.
|
|
1374
|
-
|
|
2650
|
+
const value = data.value;
|
|
2651
|
+
if (data.flags & TypeFlags.BigIntLiteral) {
|
|
2652
|
+
this.value = BigInt(value);
|
|
2653
|
+
}
|
|
2654
|
+
// JSON cannot represent infinities, so the API serializes them as strings.
|
|
2655
|
+
else if (data.flags & TypeFlags.NumberLiteral && typeof value === "string") {
|
|
2656
|
+
if (value === "+Infinity") {
|
|
2657
|
+
this.value = Infinity;
|
|
2658
|
+
}
|
|
2659
|
+
else if (value === "-Infinity") {
|
|
2660
|
+
this.value = -Infinity;
|
|
2661
|
+
}
|
|
2662
|
+
else {
|
|
2663
|
+
this.value = NaN;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
else {
|
|
2667
|
+
this.value = value;
|
|
2668
|
+
}
|
|
1375
2669
|
}
|
|
1376
2670
|
if (data.intrinsicName !== undefined)
|
|
1377
2671
|
this.intrinsicName = data.intrinsicName;
|
|
@@ -1383,18 +2677,24 @@ class TypeObject {
|
|
|
1383
2677
|
this.regularType = data.regularType;
|
|
1384
2678
|
if (data.target !== undefined)
|
|
1385
2679
|
this.target = data.target;
|
|
2680
|
+
this.tupleType = data.isTupleType ?? false;
|
|
1386
2681
|
this.typeParameters = data.typeParameters ?? [];
|
|
1387
2682
|
this.outerTypeParameters = data.outerTypeParameters ?? [];
|
|
1388
2683
|
this.localTypeParameters = data.localTypeParameters ?? [];
|
|
2684
|
+
if (data.thisType !== undefined)
|
|
2685
|
+
this.thisType = data.thisType;
|
|
1389
2686
|
this.aliasTypeArguments = data.aliasTypeArguments ?? [];
|
|
1390
2687
|
if (data.aliasSymbol !== undefined)
|
|
1391
2688
|
this.aliasSymbol = data.aliasSymbol;
|
|
1392
|
-
if (data.
|
|
1393
|
-
this.elementFlags = data.elementFlags;
|
|
1394
|
-
if (data.fixedLength !== undefined)
|
|
2689
|
+
if (data.fixedLength !== undefined) {
|
|
2690
|
+
this.elementFlags = data.elementFlags ?? [];
|
|
1395
2691
|
this.fixedLength = data.fixedLength;
|
|
2692
|
+
}
|
|
1396
2693
|
if (data.readonly !== undefined)
|
|
1397
2694
|
this.readonly = data.readonly;
|
|
2695
|
+
if (data.labeledElementDeclarations !== undefined) {
|
|
2696
|
+
this.labeledElementDeclarations = data.labeledElementDeclarations.map(handle => handle ? objectRegistry.createNodeHandle(handle) : undefined);
|
|
2697
|
+
}
|
|
1398
2698
|
if (data.texts !== undefined)
|
|
1399
2699
|
this.texts = data.texts;
|
|
1400
2700
|
if (data.objectType !== undefined)
|
|
@@ -1409,12 +2709,102 @@ class TypeObject {
|
|
|
1409
2709
|
this.baseType = data.baseType;
|
|
1410
2710
|
if (data.substConstraint !== undefined)
|
|
1411
2711
|
this.substConstraint = data.substConstraint;
|
|
2712
|
+
if (data.typeParameter !== undefined)
|
|
2713
|
+
this.typeParameter = data.typeParameter;
|
|
2714
|
+
if (data.constraintType !== undefined)
|
|
2715
|
+
this.constraintType = data.constraintType;
|
|
2716
|
+
if (data.nameType !== undefined)
|
|
2717
|
+
this.nameType = data.nameType;
|
|
2718
|
+
if (data.templateType !== undefined)
|
|
2719
|
+
this.templateType = data.templateType;
|
|
1412
2720
|
this.trueType = false;
|
|
1413
2721
|
this.falseType = false;
|
|
2722
|
+
this.constraint = false;
|
|
2723
|
+
this.default = false;
|
|
2724
|
+
this.nonNullableType = false;
|
|
2725
|
+
this.apparentType = false;
|
|
2726
|
+
this.reducedType = false;
|
|
2727
|
+
this.properties = false;
|
|
2728
|
+
this.apparentProperties = false;
|
|
2729
|
+
this.callSignatures = false;
|
|
2730
|
+
this.constructSignatures = false;
|
|
2731
|
+
this.indexInfos = false;
|
|
2732
|
+
this.baseTypes = false;
|
|
2733
|
+
this.types = false;
|
|
2734
|
+
this.stringIndexType = false;
|
|
2735
|
+
this.numberIndexType = false;
|
|
1414
2736
|
}
|
|
1415
2737
|
async getSymbol() {
|
|
1416
2738
|
return this.objectRegistry.fetchSymbol(this, "getSymbolOfType", this.symbol);
|
|
1417
2739
|
}
|
|
2740
|
+
async getProperties() {
|
|
2741
|
+
if (this.properties === false) {
|
|
2742
|
+
this.properties = await this.objectRegistry.fetchPropertiesOfType(this);
|
|
2743
|
+
}
|
|
2744
|
+
return this.properties;
|
|
2745
|
+
}
|
|
2746
|
+
getProperty(propertyName) {
|
|
2747
|
+
return this.objectRegistry.fetchPropertyOfType(this, propertyName);
|
|
2748
|
+
}
|
|
2749
|
+
async getApparentProperties() {
|
|
2750
|
+
if (this.apparentProperties === false) {
|
|
2751
|
+
this.apparentProperties = await this.objectRegistry.fetchApparentPropertiesOfType(this);
|
|
2752
|
+
}
|
|
2753
|
+
return this.apparentProperties;
|
|
2754
|
+
}
|
|
2755
|
+
async getCallSignatures() {
|
|
2756
|
+
if (this.callSignatures === false) {
|
|
2757
|
+
this.callSignatures = await this.objectRegistry.fetchSignaturesOfType(this, SignatureKind.Call);
|
|
2758
|
+
}
|
|
2759
|
+
return this.callSignatures;
|
|
2760
|
+
}
|
|
2761
|
+
async getConstructSignatures() {
|
|
2762
|
+
if (this.constructSignatures === false) {
|
|
2763
|
+
this.constructSignatures = await this.objectRegistry.fetchSignaturesOfType(this, SignatureKind.Construct);
|
|
2764
|
+
}
|
|
2765
|
+
return this.constructSignatures;
|
|
2766
|
+
}
|
|
2767
|
+
async getNonNullableType() {
|
|
2768
|
+
const result = await this.objectRegistry.fetchType(this, "getNonNullableType", this.nonNullableType);
|
|
2769
|
+
this.nonNullableType = result.id;
|
|
2770
|
+
return result;
|
|
2771
|
+
}
|
|
2772
|
+
async getStringIndexType() {
|
|
2773
|
+
if (this.stringIndexType === false) {
|
|
2774
|
+
this.stringIndexType = await this.getStringIndexTypeWorker();
|
|
2775
|
+
}
|
|
2776
|
+
return this.stringIndexType;
|
|
2777
|
+
}
|
|
2778
|
+
async getStringIndexTypeWorker() {
|
|
2779
|
+
const infos = await this.getIndexInfos();
|
|
2780
|
+
return infos.find(info => (info.keyType.flags & TypeFlags.String) !== 0)?.valueType;
|
|
2781
|
+
}
|
|
2782
|
+
async getNumberIndexType() {
|
|
2783
|
+
if (this.numberIndexType === false) {
|
|
2784
|
+
this.numberIndexType = await this.getNumberIndexTypeWorker();
|
|
2785
|
+
}
|
|
2786
|
+
return this.numberIndexType;
|
|
2787
|
+
}
|
|
2788
|
+
async getNumberIndexTypeWorker() {
|
|
2789
|
+
const infos = await this.getIndexInfos();
|
|
2790
|
+
return infos.find(info => (info.keyType.flags & TypeFlags.Number) !== 0)?.valueType;
|
|
2791
|
+
}
|
|
2792
|
+
async getApparentType() {
|
|
2793
|
+
const result = await this.objectRegistry.fetchType(this, "getApparentType", this.apparentType);
|
|
2794
|
+
this.apparentType = result.id;
|
|
2795
|
+
return result;
|
|
2796
|
+
}
|
|
2797
|
+
async getReducedType() {
|
|
2798
|
+
const result = await this.objectRegistry.fetchType(this, "getReducedType", this.reducedType);
|
|
2799
|
+
this.reducedType = result.id;
|
|
2800
|
+
return result;
|
|
2801
|
+
}
|
|
2802
|
+
async getIndexInfos() {
|
|
2803
|
+
if (this.indexInfos === false) {
|
|
2804
|
+
this.indexInfos = await this.objectRegistry.fetchIndexInfosOfType(this);
|
|
2805
|
+
}
|
|
2806
|
+
return this.indexInfos;
|
|
2807
|
+
}
|
|
1418
2808
|
async getAliasSymbol() {
|
|
1419
2809
|
return this.objectRegistry.fetchSymbol(this, "getAliasSymbolOfType", this.aliasSymbol);
|
|
1420
2810
|
}
|
|
@@ -1422,10 +2812,10 @@ class TypeObject {
|
|
|
1422
2812
|
return this.objectRegistry.fetchType(this, "getTargetOfType", this.target);
|
|
1423
2813
|
}
|
|
1424
2814
|
async getFreshType() {
|
|
1425
|
-
return this.objectRegistry.
|
|
2815
|
+
return this.objectRegistry.fetchOptionalType(this, "getFreshTypeOfType", this.freshType);
|
|
1426
2816
|
}
|
|
1427
2817
|
async getRegularType() {
|
|
1428
|
-
return this.objectRegistry.
|
|
2818
|
+
return this.objectRegistry.fetchOptionalType(this, "getRegularTypeOfType", this.regularType);
|
|
1429
2819
|
}
|
|
1430
2820
|
async getTypes() {
|
|
1431
2821
|
// Only union, intersection, and template literal types have constituent
|
|
@@ -1434,7 +2824,10 @@ class TypeObject {
|
|
|
1434
2824
|
if (!(this.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral))) {
|
|
1435
2825
|
return undefined;
|
|
1436
2826
|
}
|
|
1437
|
-
|
|
2827
|
+
if (this.types === false) {
|
|
2828
|
+
this.types = await this.objectRegistry.fetchTypes(this, "getTypesOfType");
|
|
2829
|
+
}
|
|
2830
|
+
return this.types;
|
|
1438
2831
|
}
|
|
1439
2832
|
async getTypeParameters() {
|
|
1440
2833
|
return this.objectRegistry.fetchTypes(this, "getTypeParametersOfType", this.typeParameters);
|
|
@@ -1445,9 +2838,24 @@ class TypeObject {
|
|
|
1445
2838
|
async getLocalTypeParameters() {
|
|
1446
2839
|
return this.objectRegistry.fetchTypes(this, "getLocalTypeParametersOfType", this.localTypeParameters);
|
|
1447
2840
|
}
|
|
2841
|
+
async getThisType() {
|
|
2842
|
+
return this.objectRegistry.fetchOptionalType(this, "getThisTypeOfType", this.thisType);
|
|
2843
|
+
}
|
|
1448
2844
|
async getAliasTypeArguments() {
|
|
1449
2845
|
return this.objectRegistry.fetchTypes(this, "getAliasTypeArgumentsOfType", this.aliasTypeArguments);
|
|
1450
2846
|
}
|
|
2847
|
+
async getTypeParameter() {
|
|
2848
|
+
return this.objectRegistry.fetchType(this, "getTypeParameterOfMappedType", this.typeParameter);
|
|
2849
|
+
}
|
|
2850
|
+
async getConstraintType() {
|
|
2851
|
+
return this.objectRegistry.fetchType(this, "getConstraintTypeOfMappedType", this.constraintType);
|
|
2852
|
+
}
|
|
2853
|
+
async getNameType() {
|
|
2854
|
+
return this.objectRegistry.fetchOptionalType(this, "getNameTypeOfMappedType", this.nameType);
|
|
2855
|
+
}
|
|
2856
|
+
async getTemplateType() {
|
|
2857
|
+
return this.objectRegistry.fetchType(this, "getTemplateTypeOfMappedType", this.templateType);
|
|
2858
|
+
}
|
|
1451
2859
|
async getObjectType() {
|
|
1452
2860
|
return this.objectRegistry.fetchType(this, "getObjectTypeOfType", this.objectType);
|
|
1453
2861
|
}
|
|
@@ -1464,8 +2872,20 @@ class TypeObject {
|
|
|
1464
2872
|
return this.objectRegistry.fetchType(this, "getBaseTypeOfType", this.baseType);
|
|
1465
2873
|
}
|
|
1466
2874
|
async getConstraint() {
|
|
2875
|
+
// Type parameters resolve their constraint lazily through the checker,
|
|
2876
|
+
// whereas substitution types carry a preloaded constraint handle.
|
|
2877
|
+
if (this.flags & TypeFlags.TypeParameter) {
|
|
2878
|
+
const result = await this.objectRegistry.fetchOptionalType(this, "getConstraintOfTypeParameter", this.constraint);
|
|
2879
|
+
this.constraint = result ? result.id : 0;
|
|
2880
|
+
return result;
|
|
2881
|
+
}
|
|
1467
2882
|
return this.objectRegistry.fetchType(this, "getConstraintOfType", this.substConstraint);
|
|
1468
2883
|
}
|
|
2884
|
+
async getDefault() {
|
|
2885
|
+
const result = await this.objectRegistry.fetchOptionalType(this, "getDefaultFromTypeParameter", this.default);
|
|
2886
|
+
this.default = result ? result.id : 0;
|
|
2887
|
+
return result;
|
|
2888
|
+
}
|
|
1469
2889
|
async getTrueType() {
|
|
1470
2890
|
const result = await this.objectRegistry.fetchType(this, "getTrueTypeOfConditionalType", this.trueType);
|
|
1471
2891
|
this.trueType = result.id;
|
|
@@ -1484,7 +2904,10 @@ class TypeObject {
|
|
|
1484
2904
|
if (!this.isClassOrInterface()) {
|
|
1485
2905
|
return undefined;
|
|
1486
2906
|
}
|
|
1487
|
-
|
|
2907
|
+
if (this.baseTypes === false) {
|
|
2908
|
+
this.baseTypes = await this.objectRegistry.fetchBaseTypes(this);
|
|
2909
|
+
}
|
|
2910
|
+
return this.baseTypes;
|
|
1488
2911
|
}
|
|
1489
2912
|
isClassOrInterface() {
|
|
1490
2913
|
return isClassOrInterfaceType(this);
|
|
@@ -1523,7 +2946,10 @@ class TypeObject {
|
|
|
1523
2946
|
return isTypeReference(this);
|
|
1524
2947
|
}
|
|
1525
2948
|
isTupleType() {
|
|
1526
|
-
return
|
|
2949
|
+
return this.tupleType;
|
|
2950
|
+
}
|
|
2951
|
+
isTupleTypeTarget() {
|
|
2952
|
+
return this.fixedLength !== undefined;
|
|
1527
2953
|
}
|
|
1528
2954
|
isIndexType() {
|
|
1529
2955
|
return isIndexType(this);
|
|
@@ -1546,6 +2972,9 @@ class TypeObject {
|
|
|
1546
2972
|
isTypeParameter() {
|
|
1547
2973
|
return isTypeParameter(this);
|
|
1548
2974
|
}
|
|
2975
|
+
isMappedType() {
|
|
2976
|
+
return !!(this.flags & TypeFlags.Object) && !!(this.objectFlags & ObjectFlags.Mapped);
|
|
2977
|
+
}
|
|
1549
2978
|
}
|
|
1550
2979
|
export function isUnionType(type) {
|
|
1551
2980
|
return (type.flags & TypeFlags.Union) !== 0;
|
|
@@ -1590,7 +3019,10 @@ export function isTypeReference(type) {
|
|
|
1590
3019
|
return isObjectType(type) && (type.objectFlags & ObjectFlags.Reference) !== 0;
|
|
1591
3020
|
}
|
|
1592
3021
|
export function isTupleType(type) {
|
|
1593
|
-
return
|
|
3022
|
+
return type.isTupleType();
|
|
3023
|
+
}
|
|
3024
|
+
export function isTupleTypeTarget(type) {
|
|
3025
|
+
return type.isTupleTypeTarget();
|
|
1594
3026
|
}
|
|
1595
3027
|
export function isIndexType(type) {
|
|
1596
3028
|
return (type.flags & TypeFlags.Index) !== 0;
|
|
@@ -1622,6 +3054,7 @@ export class Signature {
|
|
|
1622
3054
|
parameters;
|
|
1623
3055
|
thisParameter;
|
|
1624
3056
|
target;
|
|
3057
|
+
returnType;
|
|
1625
3058
|
constructor(data, project, objectRegistry) {
|
|
1626
3059
|
this.id = data.id;
|
|
1627
3060
|
this.flags = data.flags;
|
|
@@ -1631,6 +3064,7 @@ export class Signature {
|
|
|
1631
3064
|
this.parameters = data.parameters ?? [];
|
|
1632
3065
|
this.thisParameter = data.thisParameter;
|
|
1633
3066
|
this.target = data.target;
|
|
3067
|
+
this.returnType = false;
|
|
1634
3068
|
}
|
|
1635
3069
|
async getTypeParameters() {
|
|
1636
3070
|
return this.objectRegistry.fetchTypes(this, "getTypeParametersOfSignature", this.typeParameters);
|
|
@@ -1644,6 +3078,14 @@ export class Signature {
|
|
|
1644
3078
|
async getTarget() {
|
|
1645
3079
|
return this.objectRegistry.fetchSignature(this, "getTargetOfSignature", this.target);
|
|
1646
3080
|
}
|
|
3081
|
+
async getReturnType() {
|
|
3082
|
+
const result = await this.objectRegistry.fetchType(this, "getReturnTypeOfSignature", this.returnType);
|
|
3083
|
+
this.returnType = result.id;
|
|
3084
|
+
return result;
|
|
3085
|
+
}
|
|
3086
|
+
getTypeParameterAtPosition(pos) {
|
|
3087
|
+
return this.objectRegistry.fetchTypeParameterAtPosition(this, pos);
|
|
3088
|
+
}
|
|
1647
3089
|
get hasRestParameter() {
|
|
1648
3090
|
return (this.flags & SignatureFlags.HasRestParameter) !== 0;
|
|
1649
3091
|
}
|