typescript 7.0.1-rc → 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/README.md +39 -14
- package/dist/api/async/api.d.ts +827 -123
- package/dist/api/async/api.d.ts.map +1 -1
- package/dist/api/async/api.js +2367 -340
- package/dist/api/async/api.js.map +1 -1
- package/dist/api/async/client.d.ts +35 -2
- package/dist/api/async/client.d.ts.map +1 -1
- package/dist/api/async/client.js +317 -59
- package/dist/api/async/client.js.map +1 -1
- package/dist/api/async/types.d.ts +199 -53
- 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 +21 -33
- 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 +3 -3
- package/dist/api/node/msgpack.js.map +1 -1
- package/dist/api/node/node.d.ts +43 -10
- package/dist/api/node/node.d.ts.map +1 -1
- package/dist/api/node/node.generated.d.ts +20 -2
- package/dist/api/node/node.generated.d.ts.map +1 -1
- package/dist/api/node/node.generated.js +122 -52
- package/dist/api/node/node.generated.js.map +1 -1
- package/dist/api/node/node.infrastructure.d.ts +16 -3
- 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 +269 -30
- 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 +10 -0
- package/dist/api/node/wtf8.d.ts.map +1 -0
- package/dist/api/node/wtf8.js +130 -0
- package/dist/api/node/wtf8.js.map +1 -0
- package/dist/api/options.d.ts +26 -6
- 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 -164
- 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 -0
- 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 +1553 -179
- package/dist/api/sync/api.d.ts.map +1 -1
- package/dist/api/sync/api.js +5086 -758
- package/dist/api/sync/api.js.map +1 -1
- package/dist/api/sync/client.d.ts +25 -2
- package/dist/api/sync/client.d.ts.map +1 -1
- package/dist/api/sync/client.js +132 -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 +341 -68
- package/dist/api/sync/types.d.ts.map +1 -1
- package/dist/api/syncChannel.d.ts +7 -1
- package/dist/api/syncChannel.d.ts.map +1 -1
- package/dist/api/syncChannel.js +41 -3
- package/dist/api/syncChannel.js.map +1 -1
- package/dist/api/timing.d.ts +175 -0
- package/dist/api/timing.d.ts.map +1 -0
- package/dist/api/timing.js +149 -0
- package/dist/api/timing.js.map +1 -0
- 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 +125 -8
- package/dist/ast/ast.d.ts.map +1 -1
- package/dist/ast/ast.generated.d.ts +48 -42
- 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 +12 -150
- package/dist/ast/factory.generated.d.ts.map +1 -1
- package/dist/ast/factory.generated.js +2736 -8
- package/dist/ast/factory.generated.js.map +1 -1
- package/dist/ast/index.d.ts +7 -0
- package/dist/ast/index.d.ts.map +1 -1
- package/dist/ast/index.js +7 -0
- package/dist/ast/index.js.map +1 -1
- package/dist/ast/is.d.ts +3 -12
- package/dist/ast/is.d.ts.map +1 -1
- package/dist/ast/is.generated.d.ts +890 -2
- package/dist/ast/is.generated.d.ts.map +1 -1
- package/dist/ast/is.generated.js +303 -7
- package/dist/ast/is.generated.js.map +1 -1
- package/dist/ast/is.js +231 -1
- package/dist/ast/is.js.map +1 -1
- package/dist/ast/jsdoc.d.ts +12 -0
- package/dist/ast/jsdoc.d.ts.map +1 -0
- package/dist/ast/jsdoc.js +208 -0
- package/dist/ast/jsdoc.js.map +1 -0
- 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 +25 -0
- package/dist/ast/utils.d.ts.map +1 -1
- package/dist/ast/utils.js +291 -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.d.ts +2 -0
- package/dist/enums/internalSymbolName.d.ts.map +1 -0
- package/dist/enums/internalSymbolName.enum.d.ts +23 -0
- package/dist/enums/internalSymbolName.enum.d.ts.map +1 -0
- package/dist/enums/internalSymbolName.enum.js +25 -0
- package/dist/enums/internalSymbolName.enum.js.map +1 -0
- package/dist/enums/internalSymbolName.js +25 -0
- package/dist/enums/internalSymbolName.js.map +1 -0
- 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.d.ts +2 -0
- package/dist/enums/jsxEmit.d.ts.map +1 -0
- package/dist/enums/jsxEmit.enum.d.ts +9 -0
- package/dist/enums/jsxEmit.enum.d.ts.map +1 -0
- package/dist/enums/jsxEmit.enum.js +11 -0
- package/dist/enums/jsxEmit.enum.js.map +1 -0
- package/dist/enums/jsxEmit.js +11 -0
- package/dist/enums/jsxEmit.js.map +1 -0
- 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.d.ts +2 -0
- package/dist/enums/moduleDetectionKind.d.ts.map +1 -0
- package/dist/enums/moduleDetectionKind.enum.d.ts +7 -0
- package/dist/enums/moduleDetectionKind.enum.d.ts.map +1 -0
- package/dist/enums/moduleDetectionKind.enum.js +9 -0
- package/dist/enums/moduleDetectionKind.enum.js.map +1 -0
- package/dist/enums/moduleDetectionKind.js +9 -0
- package/dist/enums/moduleDetectionKind.js.map +1 -0
- package/dist/enums/moduleKind.d.ts +2 -0
- package/dist/enums/moduleKind.d.ts.map +1 -0
- package/dist/enums/moduleKind.enum.d.ts +17 -0
- package/dist/enums/moduleKind.enum.d.ts.map +1 -0
- package/dist/enums/moduleKind.enum.js +19 -0
- package/dist/enums/moduleKind.enum.js.map +1 -0
- package/dist/enums/moduleKind.js +19 -0
- package/dist/enums/moduleKind.js.map +1 -0
- package/dist/enums/moduleResolutionKind.d.ts +2 -0
- package/dist/enums/moduleResolutionKind.d.ts.map +1 -0
- package/dist/enums/moduleResolutionKind.enum.d.ts +9 -0
- package/dist/enums/moduleResolutionKind.enum.d.ts.map +1 -0
- package/dist/enums/moduleResolutionKind.enum.js +11 -0
- package/dist/enums/moduleResolutionKind.enum.js.map +1 -0
- package/dist/enums/moduleResolutionKind.js +11 -0
- package/dist/enums/moduleResolutionKind.js.map +1 -0
- package/dist/enums/newLineKind.d.ts +2 -0
- package/dist/enums/newLineKind.d.ts.map +1 -0
- package/dist/enums/newLineKind.enum.d.ts +6 -0
- package/dist/enums/newLineKind.enum.d.ts.map +1 -0
- package/dist/enums/newLineKind.enum.js +8 -0
- package/dist/enums/newLineKind.enum.js.map +1 -0
- package/dist/enums/newLineKind.js +8 -0
- package/dist/enums/newLineKind.js.map +1 -0
- 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.d.ts +5 -1
- package/dist/enums/outerExpressionKinds.enum.d.ts.map +1 -1
- package/dist/enums/outerExpressionKinds.enum.js +5 -1
- package/dist/enums/outerExpressionKinds.enum.js.map +1 -1
- package/dist/enums/outerExpressionKinds.js +5 -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.d.ts +23 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/dist/internal/utils.js +25 -0
- package/dist/internal/utils.js.map +1 -0
- 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 +8 -5
- package/lib/tsc.js +1 -1
- package/lib/version.cjs +3 -0
- package/lib/version.d.cts +2 -0
- package/package.json +48 -41
- 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/objectRegistry.d.ts +0 -40
- package/dist/api/objectRegistry.d.ts.map +0 -1
- package/dist/api/objectRegistry.js +0 -61
- package/dist/api/objectRegistry.js.map +0 -1
package/dist/api/async/api.js
CHANGED
|
@@ -1,36 +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";
|
|
8
|
+
import { ModuleKind } from "#enums/moduleKind";
|
|
9
|
+
import { ModuleResolutionKind } from "#enums/moduleResolutionKind";
|
|
10
|
+
import { NewLineKind } from "#enums/newLineKind";
|
|
5
11
|
import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";
|
|
6
12
|
import { ObjectFlags } from "#enums/objectFlags";
|
|
13
|
+
import { ScriptKind } from "#enums/scriptKind";
|
|
7
14
|
import { SignatureFlags } from "#enums/signatureFlags";
|
|
8
15
|
import { SignatureKind } from "#enums/signatureKind";
|
|
9
16
|
import { SymbolFlags } from "#enums/symbolFlags";
|
|
17
|
+
import { SymbolOwnerKind } from "#enums/symbolOwnerKind";
|
|
10
18
|
import { TypeFlags } from "#enums/typeFlags";
|
|
19
|
+
import { TypeFormatFlags } from "#enums/typeFormatFlags";
|
|
11
20
|
import { TypePredicateKind } from "#enums/typePredicateKind";
|
|
12
|
-
import { ModifierFlags, } from "../../ast/index.js";
|
|
21
|
+
import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
|
|
22
|
+
import { assertNever } from "../../internal/utils.js";
|
|
13
23
|
import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
|
|
14
|
-
import { decodeNode, getNodeId,
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
24
|
+
import { decodeNode, getNodeId, parseNodeHandleFromCompiler, readParseOptionsKey, readSourceFileHash, readSourceFileLease, RemoteNode, RemoteSourceFile, } from "../node/node.js";
|
|
25
|
+
import { Wtf8Decoder } from "../node/wtf8.js";
|
|
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";
|
|
19
30
|
import { Client, } from "./client.js";
|
|
20
|
-
export {
|
|
31
|
+
export { formatDiagnostics, formatDiagnosticsWithColorAndContext } from "../diagnosticFormatter.js";
|
|
21
32
|
export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
|
|
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
|
|
22
55
|
export class API {
|
|
56
|
+
/** @internal */
|
|
23
57
|
client;
|
|
58
|
+
/** @internal */
|
|
24
59
|
sourceFileCache;
|
|
25
60
|
toPath;
|
|
61
|
+
decoder = new Wtf8Decoder();
|
|
62
|
+
currentDirectory;
|
|
63
|
+
caseSensitivity;
|
|
26
64
|
initialized = false;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
65
|
+
initializing;
|
|
66
|
+
activeSnapshots = new Map();
|
|
67
|
+
activeBuildOrchestrators = new Set();
|
|
68
|
+
activeSourceFileLeases = new Map();
|
|
69
|
+
printer;
|
|
70
|
+
debug;
|
|
71
|
+
constructor(options = {}) {
|
|
31
72
|
this.client = new Client(options);
|
|
32
73
|
this.sourceFileCache = new SourceFileCache();
|
|
33
|
-
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;
|
|
34
122
|
}
|
|
35
123
|
/**
|
|
36
124
|
* Create an API instance from an existing LSP connection's API session.
|
|
@@ -41,64 +129,437 @@ export class API {
|
|
|
41
129
|
await api.ensureInitialized();
|
|
42
130
|
return api;
|
|
43
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
|
|
44
142
|
async ensureInitialized() {
|
|
45
|
-
if (
|
|
143
|
+
if (this.initialized)
|
|
144
|
+
return;
|
|
145
|
+
return this.initializing ??= this.initializeWorker();
|
|
146
|
+
}
|
|
147
|
+
async initializeWorker() {
|
|
148
|
+
try {
|
|
46
149
|
const response = await this.client.apiRequest("initialize", null);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
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);
|
|
50
153
|
this.initialized = true;
|
|
51
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;
|
|
52
194
|
}
|
|
53
195
|
async parseConfigFile(file) {
|
|
54
196
|
await this.ensureInitialized();
|
|
55
197
|
return this.client.apiRequest("parseConfigFile", { file });
|
|
56
198
|
}
|
|
57
|
-
async
|
|
199
|
+
async parseCommandLine(commandLine) {
|
|
58
200
|
await this.ensureInitialized();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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");
|
|
70
220
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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),
|
|
76
314
|
});
|
|
77
|
-
|
|
78
|
-
|
|
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);
|
|
79
325
|
return snapshot;
|
|
80
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),
|
|
373
|
+
});
|
|
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);
|
|
382
|
+
return snapshot;
|
|
383
|
+
}
|
|
384
|
+
async [globalThis.Symbol.asyncDispose]() {
|
|
385
|
+
await this.close(); // @sync: this.close();
|
|
386
|
+
}
|
|
81
387
|
async close() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
388
|
+
await this.initializing?.catch(() => { }); // @sync-skip
|
|
389
|
+
try {
|
|
390
|
+
for (const retained of [...this.activeSourceFileLeases.values()]) {
|
|
391
|
+
await retained.dispose();
|
|
392
|
+
}
|
|
85
393
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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;
|
|
90
425
|
}
|
|
91
|
-
await this.client.close();
|
|
92
|
-
this.sourceFileCache.clear();
|
|
93
426
|
}
|
|
94
427
|
clearSourceFileCache() {
|
|
95
428
|
this.sourceFileCache.clear();
|
|
96
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
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Returns a snapshot of collected timing information for requests made
|
|
451
|
+
* through this API instance: client-measured round-trip latency and bytes
|
|
452
|
+
* transferred, folded together with the server's own per-request processing
|
|
453
|
+
* time and an estimated transport overhead (round-trip minus server time).
|
|
454
|
+
*
|
|
455
|
+
* Fetching the snapshot issues a lightweight request to the server to
|
|
456
|
+
* retrieve its timing collection. Collection must be enabled via the
|
|
457
|
+
* `collectTiming` option or `TS_API_TIMING_DIR` environment variable; when
|
|
458
|
+
* it is not, the returned snapshot has `enabled: false` and zeroed totals.
|
|
459
|
+
*/
|
|
460
|
+
getTimingInfo() {
|
|
461
|
+
return this.client.getTimingInfo();
|
|
462
|
+
}
|
|
463
|
+
/** Clears all accumulated timing totals and recent-request history, on both the client and the server. */
|
|
464
|
+
resetTimingInfo() {
|
|
465
|
+
return this.client.resetTimingInfo();
|
|
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;
|
|
97
501
|
}
|
|
98
|
-
|
|
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
|
+
}
|
|
559
|
+
}
|
|
560
|
+
export class DebugHandlers {
|
|
99
561
|
client;
|
|
100
562
|
ensureInitialized;
|
|
101
|
-
/** @internal */
|
|
102
563
|
constructor(client, ensureInitialized) {
|
|
103
564
|
this.client = client;
|
|
104
565
|
this.ensureInitialized = ensureInitialized;
|
|
@@ -120,37 +581,70 @@ export class InternalAPI {
|
|
|
120
581
|
}
|
|
121
582
|
export class Snapshot {
|
|
122
583
|
id;
|
|
584
|
+
operation;
|
|
123
585
|
projectMap;
|
|
124
586
|
toPath;
|
|
125
|
-
|
|
126
|
-
objectRegistry;
|
|
587
|
+
api;
|
|
127
588
|
disposed = false;
|
|
589
|
+
disposePromise;
|
|
128
590
|
onDispose;
|
|
129
|
-
|
|
591
|
+
snapshotRegistry;
|
|
592
|
+
projectDataMap;
|
|
593
|
+
updateSnapshot;
|
|
594
|
+
get client() {
|
|
595
|
+
return this.api.client;
|
|
596
|
+
}
|
|
597
|
+
constructor(data, toPath, api, onDispose, updateSnapshot, baseSnapshot) {
|
|
130
598
|
this.id = data.snapshot;
|
|
131
|
-
this.
|
|
599
|
+
this.api = api;
|
|
132
600
|
this.toPath = toPath;
|
|
133
601
|
this.onDispose = onDispose;
|
|
134
|
-
this.
|
|
135
|
-
createSymbol: symbolData => new Symbol(symbolData, this.objectRegistry),
|
|
136
|
-
createType: typeData => new TypeObject(typeData, this.objectRegistry),
|
|
137
|
-
createSignature: sigData => new Signature(sigData, this.objectRegistry),
|
|
138
|
-
}, client, this.id);
|
|
139
|
-
// Create projects
|
|
602
|
+
this.updateSnapshot = updateSnapshot;
|
|
140
603
|
this.projectMap = new Map();
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
604
|
+
const projectDataMap = new Map(baseSnapshot?.projectDataMap);
|
|
605
|
+
for (const projectId of data.changes?.removedProjects ?? []) {
|
|
606
|
+
projectDataMap.delete(projectId);
|
|
144
607
|
}
|
|
608
|
+
for (const projectData of data.projects) {
|
|
609
|
+
projectDataMap.set(projectData.id, projectData);
|
|
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
|
+
};
|
|
145
621
|
}
|
|
146
622
|
getProjects() {
|
|
147
623
|
this.ensureNotDisposed();
|
|
148
624
|
return [...this.projectMap.values()];
|
|
149
625
|
}
|
|
150
|
-
|
|
626
|
+
getConfiguredProject(configFileName) {
|
|
151
627
|
this.ensureNotDisposed();
|
|
152
|
-
|
|
628
|
+
const id = this.toPath(configFileName);
|
|
629
|
+
return this.projectMap.get(id);
|
|
630
|
+
}
|
|
631
|
+
getProject(projectId) {
|
|
632
|
+
this.ensureNotDisposed();
|
|
633
|
+
return this.projectMap.get(projectId);
|
|
634
|
+
}
|
|
635
|
+
getProgram(projectId) {
|
|
636
|
+
return this.getProject(projectId)?.program;
|
|
153
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
|
+
*/
|
|
154
648
|
async getDefaultProjectForFile(file) {
|
|
155
649
|
this.ensureNotDisposed();
|
|
156
650
|
const data = await this.client.apiRequest("getDefaultProjectForFile", {
|
|
@@ -159,18 +653,29 @@ export class Snapshot {
|
|
|
159
653
|
});
|
|
160
654
|
if (!data)
|
|
161
655
|
return undefined;
|
|
162
|
-
return this.projectMap.get(
|
|
656
|
+
return this.projectMap.get(data.id);
|
|
163
657
|
}
|
|
164
|
-
[globalThis.Symbol.
|
|
165
|
-
this.dispose();
|
|
658
|
+
[globalThis.Symbol.asyncDispose]() {
|
|
659
|
+
return this.dispose(); // @sync: this.dispose();
|
|
166
660
|
}
|
|
167
|
-
|
|
661
|
+
dispose() {
|
|
662
|
+
return this.disposePromise ??= this.disposeWorker();
|
|
663
|
+
}
|
|
664
|
+
async disposeWorker() {
|
|
168
665
|
if (this.disposed)
|
|
169
666
|
return;
|
|
170
667
|
this.disposed = true;
|
|
171
|
-
this.
|
|
172
|
-
|
|
173
|
-
|
|
668
|
+
for (const project of this.projectMap.values()) {
|
|
669
|
+
project.dispose();
|
|
670
|
+
}
|
|
671
|
+
this.projectMap.clear();
|
|
672
|
+
this.snapshotRegistry.clear();
|
|
673
|
+
try {
|
|
674
|
+
await this.client.apiRequest("release", { snapshot: this.id });
|
|
675
|
+
}
|
|
676
|
+
finally {
|
|
677
|
+
this.onDispose();
|
|
678
|
+
}
|
|
174
679
|
}
|
|
175
680
|
isDisposed() {
|
|
176
681
|
return this.disposed;
|
|
@@ -180,39 +685,203 @@ export class Snapshot {
|
|
|
180
685
|
throw new Error("Snapshot is disposed");
|
|
181
686
|
}
|
|
182
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
|
+
}
|
|
183
695
|
}
|
|
184
|
-
class
|
|
696
|
+
export class ModuleResolver {
|
|
697
|
+
id;
|
|
185
698
|
client;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
699
|
+
disposeCallback;
|
|
700
|
+
disposed = false;
|
|
701
|
+
constructor(id, client, disposeCallback) {
|
|
702
|
+
this.id = id;
|
|
189
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
|
+
}
|
|
735
|
+
}
|
|
736
|
+
class SnapshotObjectRegistry {
|
|
737
|
+
symbols = new Map();
|
|
738
|
+
projectRegistries = new Map();
|
|
739
|
+
snapshotId;
|
|
740
|
+
constructor(snapshotId) {
|
|
190
741
|
this.snapshotId = snapshotId;
|
|
191
742
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
743
|
+
addProjectRegistry(registry) {
|
|
744
|
+
this.projectRegistries.set(registry.project.id, registry);
|
|
745
|
+
}
|
|
746
|
+
getOrCreateSymbol(data) {
|
|
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);
|
|
751
|
+
if (!symbol) {
|
|
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);
|
|
760
|
+
}
|
|
761
|
+
return symbol;
|
|
762
|
+
}
|
|
763
|
+
getSymbol(id) {
|
|
764
|
+
return this.symbols.get(id);
|
|
765
|
+
}
|
|
766
|
+
clear() {
|
|
767
|
+
this.symbols.clear();
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
class ProjectObjectRegistry {
|
|
771
|
+
snapshotId;
|
|
772
|
+
project;
|
|
773
|
+
snapshotRegistry;
|
|
774
|
+
types = new Map();
|
|
775
|
+
signatures = new Map();
|
|
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) {
|
|
784
|
+
this.snapshotId = snapshotId;
|
|
785
|
+
this.project = project;
|
|
786
|
+
this.snapshotRegistry = snapshotRegistry;
|
|
787
|
+
snapshotRegistry.addProjectRegistry(this);
|
|
788
|
+
}
|
|
789
|
+
getOrCreateSymbol(data) {
|
|
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
|
+
}));
|
|
801
|
+
}
|
|
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;
|
|
814
|
+
}
|
|
815
|
+
getOrCreateType(data) {
|
|
816
|
+
let type = this.types.get(data.id);
|
|
817
|
+
if (!type) {
|
|
818
|
+
type = new TypeObject(data, this);
|
|
819
|
+
this.types.set(data.id, type);
|
|
820
|
+
}
|
|
821
|
+
return type;
|
|
822
|
+
}
|
|
823
|
+
getType(id) {
|
|
824
|
+
return this.types.get(id);
|
|
825
|
+
}
|
|
826
|
+
createNodeHandle(handle) {
|
|
827
|
+
return new NodeHandle(handle, this.project);
|
|
828
|
+
}
|
|
829
|
+
getOrCreateSignature(data) {
|
|
830
|
+
let sig = this.signatures.get(data.id);
|
|
831
|
+
if (!sig) {
|
|
832
|
+
sig = new Signature(data, this.project, this);
|
|
833
|
+
this.signatures.set(data.id, sig);
|
|
834
|
+
}
|
|
835
|
+
return sig;
|
|
836
|
+
}
|
|
837
|
+
getSignature(id) {
|
|
838
|
+
return this.signatures.get(id);
|
|
839
|
+
}
|
|
840
|
+
clear() {
|
|
841
|
+
this.disposed = true;
|
|
842
|
+
this.types.clear();
|
|
843
|
+
this.signatures.clear();
|
|
844
|
+
}
|
|
845
|
+
ensureNotDisposed() {
|
|
846
|
+
if (this.disposed)
|
|
847
|
+
throw new Error("Project object registry is disposed");
|
|
848
|
+
}
|
|
849
|
+
async fetchOptionalType(source, method, handle) {
|
|
850
|
+
if (handle !== false) {
|
|
851
|
+
if (!handle)
|
|
852
|
+
return undefined;
|
|
853
|
+
const cached = this.getType(handle);
|
|
854
|
+
if (cached)
|
|
855
|
+
return cached;
|
|
856
|
+
}
|
|
198
857
|
const data = await this.client.apiRequest(method, {
|
|
199
858
|
snapshot: this.snapshotId,
|
|
859
|
+
project: this.project.id,
|
|
200
860
|
objectId: source.id,
|
|
201
861
|
});
|
|
202
862
|
if (!data)
|
|
203
|
-
|
|
863
|
+
return undefined;
|
|
204
864
|
return this.getOrCreateType(data);
|
|
205
865
|
}
|
|
206
|
-
async
|
|
207
|
-
|
|
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)
|
|
208
874
|
return undefined;
|
|
209
|
-
const cached = this.
|
|
875
|
+
const cached = this.getCachedSymbol(reference);
|
|
210
876
|
if (cached)
|
|
211
877
|
return cached;
|
|
212
|
-
const data =
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
+
});
|
|
216
885
|
if (!data)
|
|
217
886
|
throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
|
|
218
887
|
return this.getOrCreateSymbol(data);
|
|
@@ -225,6 +894,7 @@ class SnapshotObjectRegistry extends ObjectRegistry {
|
|
|
225
894
|
return cached;
|
|
226
895
|
const data = await this.client.apiRequest(method, {
|
|
227
896
|
snapshot: this.snapshotId,
|
|
897
|
+
project: this.project.id,
|
|
228
898
|
objectId: source.id,
|
|
229
899
|
});
|
|
230
900
|
if (!data)
|
|
@@ -248,6 +918,7 @@ class SnapshotObjectRegistry extends ObjectRegistry {
|
|
|
248
918
|
}
|
|
249
919
|
const typesData = await this.client.apiRequest(method, {
|
|
250
920
|
snapshot: this.snapshotId,
|
|
921
|
+
project: this.project.id,
|
|
251
922
|
objectId: source.id,
|
|
252
923
|
});
|
|
253
924
|
if (typesData == null)
|
|
@@ -255,134 +926,561 @@ class SnapshotObjectRegistry extends ObjectRegistry {
|
|
|
255
926
|
else
|
|
256
927
|
return typesData.map(data => this.getOrCreateType(data));
|
|
257
928
|
}
|
|
258
|
-
async fetchSymbols(source, method,
|
|
259
|
-
if (
|
|
260
|
-
const result = new Array(
|
|
261
|
-
let
|
|
262
|
-
|
|
263
|
-
const cached = this.getSymbol(handles[i]);
|
|
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]);
|
|
264
934
|
if (!cached) {
|
|
265
|
-
|
|
266
|
-
break;
|
|
935
|
+
return this.fetchSymbolsFromServer(source, method);
|
|
267
936
|
}
|
|
268
937
|
result[i] = cached;
|
|
269
938
|
}
|
|
270
|
-
|
|
271
|
-
|
|
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)) ?? [];
|
|
952
|
+
}
|
|
953
|
+
// getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
|
|
954
|
+
// so it cannot go through fetchTypes. This helper reuses that server method.
|
|
955
|
+
async fetchBaseTypes(source) {
|
|
956
|
+
const typesData = await this.client.apiRequest("getBaseTypes", {
|
|
957
|
+
snapshot: this.snapshotId,
|
|
958
|
+
project: this.project.id,
|
|
959
|
+
type: source.id,
|
|
960
|
+
});
|
|
961
|
+
if (typesData == null)
|
|
962
|
+
return [];
|
|
963
|
+
return typesData.map(data => this.getOrCreateType(data));
|
|
964
|
+
}
|
|
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;
|
|
1038
|
+
this.configFileName = data.configFileName;
|
|
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);
|
|
1049
|
+
}
|
|
1050
|
+
dispose() {
|
|
1051
|
+
this.checker.dispose();
|
|
1052
|
+
}
|
|
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
|
+
}
|
|
1169
|
+
export class Program {
|
|
1170
|
+
/** @internal */
|
|
1171
|
+
snapshotId;
|
|
1172
|
+
id;
|
|
1173
|
+
project;
|
|
1174
|
+
toPath;
|
|
1175
|
+
decoder = new Wtf8Decoder();
|
|
1176
|
+
sourceFileMetadataCache = new Map();
|
|
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) {
|
|
1186
|
+
this.snapshotId = snapshotId;
|
|
1187
|
+
this.id = project.id;
|
|
1188
|
+
this.project = project;
|
|
1189
|
+
this.toPath = toPath;
|
|
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
|
+
}
|
|
1216
|
+
getCompilerOptions() {
|
|
1217
|
+
return this.project.parsedCommandLine.options;
|
|
1218
|
+
}
|
|
1219
|
+
async getSourceFile(file) {
|
|
1220
|
+
const fileName = resolveFileName(file);
|
|
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) {
|
|
1233
|
+
// Check if we already have a retained cache entry for this (snapshot, project) pair
|
|
1234
|
+
const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
|
|
1235
|
+
if (retained) {
|
|
1236
|
+
return retained;
|
|
1237
|
+
}
|
|
1238
|
+
// Fetch from server
|
|
1239
|
+
const binaryData = await this.client.apiRequestBinary("getSourceFile", {
|
|
1240
|
+
snapshot: this.snapshotId,
|
|
1241
|
+
project: this.project.id,
|
|
1242
|
+
file,
|
|
1243
|
+
});
|
|
1244
|
+
if (!binaryData) {
|
|
1245
|
+
return undefined;
|
|
1246
|
+
}
|
|
1247
|
+
// Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
|
|
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;
|
|
1305
|
+
}
|
|
1306
|
+
async getSourceFileNames() {
|
|
1307
|
+
const data = await this.client.apiRequest("getSourceFileNames", {
|
|
1308
|
+
snapshot: this.snapshotId,
|
|
1309
|
+
project: this.project.id,
|
|
1310
|
+
});
|
|
1311
|
+
return data ?? [];
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Returns program-stored metadata for the given source file, or `undefined` if the file
|
|
1315
|
+
* is not part of the program. Metadata is fetched lazily per file and cached on this
|
|
1316
|
+
* `Program` instance.
|
|
1317
|
+
*/
|
|
1318
|
+
getSourceFileMetadata(file) {
|
|
1319
|
+
return this.getSourceFileMetadataByPath(this.pathKeyForFileName(resolveFileName(file)));
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Returns program-stored metadata for the source file at the given path, or `undefined`
|
|
1323
|
+
* if the file is not part of the program. Like {@link getSourceFileMetadata}, but skips
|
|
1324
|
+
* the file name to path conversion. Metadata is fetched lazily per file and cached on
|
|
1325
|
+
* this `Program` instance.
|
|
1326
|
+
*/
|
|
1327
|
+
getSourceFileMetadataByPath(path) {
|
|
1328
|
+
let metadata = this.sourceFileMetadataCache.get(path);
|
|
1329
|
+
if (metadata === undefined) {
|
|
1330
|
+
metadata = this.fetchSourceFileMetadata(path);
|
|
1331
|
+
this.sourceFileMetadataCache.set(path, metadata);
|
|
272
1332
|
}
|
|
273
|
-
|
|
1333
|
+
return metadata;
|
|
1334
|
+
}
|
|
1335
|
+
async fetchSourceFileMetadata(path) {
|
|
1336
|
+
// PathKey is serialized as a string; the server deliberately treats all
|
|
1337
|
+
// client-provided path text as untrusted input.
|
|
1338
|
+
const data = await this.client.apiRequest("getSourceFileMetadata", {
|
|
274
1339
|
snapshot: this.snapshotId,
|
|
275
|
-
|
|
1340
|
+
project: this.project.id,
|
|
1341
|
+
file: path,
|
|
276
1342
|
});
|
|
277
|
-
|
|
278
|
-
return [];
|
|
279
|
-
else
|
|
280
|
-
return symbolData.map(data => this.getOrCreateSymbol(data));
|
|
1343
|
+
return data ?? undefined;
|
|
281
1344
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
id;
|
|
285
|
-
configFileName;
|
|
286
|
-
compilerOptions;
|
|
287
|
-
rootFiles;
|
|
288
|
-
program;
|
|
289
|
-
checker;
|
|
290
|
-
emitter;
|
|
291
|
-
client;
|
|
292
|
-
constructor(data, snapshotId, client, objectRegistry, sourceFileCache, toPath) {
|
|
293
|
-
this.id = data.id;
|
|
294
|
-
this.configFileName = data.configFileName;
|
|
295
|
-
this.compilerOptions = data.compilerOptions;
|
|
296
|
-
this.rootFiles = data.rootFiles;
|
|
297
|
-
this.client = client;
|
|
298
|
-
this.program = new Program(snapshotId, this.id, client, sourceFileCache, toPath);
|
|
299
|
-
this.checker = new Checker(snapshotId, this.id, client, objectRegistry);
|
|
300
|
-
this.emitter = new Emitter(client);
|
|
1345
|
+
pathKeyForFileName(fileName) {
|
|
1346
|
+
return this.toPath(fileName, this.project.currentDirectory);
|
|
301
1347
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
constructor(snapshotId, projectId, client, sourceFileCache, toPath) {
|
|
311
|
-
this.snapshotId = snapshotId;
|
|
312
|
-
this.projectId = projectId;
|
|
313
|
-
this.client = client;
|
|
314
|
-
this.sourceFileCache = sourceFileCache;
|
|
315
|
-
this.toPath = toPath;
|
|
1348
|
+
/**
|
|
1349
|
+
* Returns whether the given source file was loaded as part of an external library
|
|
1350
|
+
* (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
|
|
1351
|
+
* fetched lazily per file and cached on this `Program` instance.
|
|
1352
|
+
*/
|
|
1353
|
+
async isSourceFileFromExternalLibrary(file) {
|
|
1354
|
+
const metadata = await this.getSourceFileMetadataByPath(file.path);
|
|
1355
|
+
return metadata?.isFromExternalLibrary ?? false;
|
|
316
1356
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
1357
|
+
/**
|
|
1358
|
+
* Returns whether the given source file is a default library file (e.g. `lib.d.ts`).
|
|
1359
|
+
* The underlying program metadata is fetched lazily per file and cached on this
|
|
1360
|
+
* `Program` instance.
|
|
1361
|
+
*/
|
|
1362
|
+
async isSourceFileDefaultLibrary(file) {
|
|
1363
|
+
const metadata = await this.getSourceFileMetadataByPath(file.path);
|
|
1364
|
+
return metadata?.isDefaultLibrary ?? false;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
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", {
|
|
327
1383
|
snapshot: this.snapshotId,
|
|
328
|
-
project: this.
|
|
1384
|
+
project: this.project.id,
|
|
329
1385
|
file,
|
|
330
1386
|
});
|
|
331
1387
|
if (!binaryData) {
|
|
332
1388
|
return undefined;
|
|
333
1389
|
}
|
|
334
|
-
|
|
335
|
-
const contentHash = readSourceFileHash(view);
|
|
336
|
-
const parseOptionsKey = readParseOptionsKey(view);
|
|
337
|
-
// Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
|
|
338
|
-
const sourceFile = new RemoteSourceFile(binaryData, this.decoder);
|
|
339
|
-
return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.projectId);
|
|
1390
|
+
return new RemoteSourceFile(binaryData, this.decoder, undefined, this.project.api);
|
|
340
1391
|
}
|
|
341
1392
|
/**
|
|
342
|
-
* Get syntactic (parse) diagnostics for
|
|
343
|
-
* @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
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.
|
|
344
1395
|
*/
|
|
345
1396
|
async getSyntacticDiagnostics(file) {
|
|
1397
|
+
const files = file === undefined ? undefined
|
|
1398
|
+
: Array.isArray(file) ? file
|
|
1399
|
+
: [file];
|
|
346
1400
|
const data = await this.client.apiRequest("getSyntacticDiagnostics", {
|
|
347
1401
|
snapshot: this.snapshotId,
|
|
348
|
-
project: this.
|
|
349
|
-
|
|
1402
|
+
project: this.project.id,
|
|
1403
|
+
files,
|
|
1404
|
+
});
|
|
1405
|
+
return data ?? [];
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
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.
|
|
1410
|
+
*/
|
|
1411
|
+
async getBindDiagnostics(file) {
|
|
1412
|
+
const files = file === undefined ? undefined
|
|
1413
|
+
: Array.isArray(file) ? file
|
|
1414
|
+
: [file];
|
|
1415
|
+
const data = await this.client.apiRequest("getBindDiagnostics", {
|
|
1416
|
+
snapshot: this.snapshotId,
|
|
1417
|
+
project: this.project.id,
|
|
1418
|
+
files,
|
|
350
1419
|
});
|
|
351
1420
|
return data ?? [];
|
|
352
1421
|
}
|
|
353
1422
|
/**
|
|
354
|
-
* Get semantic (type-check) diagnostics for
|
|
355
|
-
* @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.
|
|
356
1425
|
*/
|
|
357
1426
|
async getSemanticDiagnostics(file) {
|
|
1427
|
+
const files = file === undefined ? undefined
|
|
1428
|
+
: Array.isArray(file) ? file
|
|
1429
|
+
: [file];
|
|
358
1430
|
const data = await this.client.apiRequest("getSemanticDiagnostics", {
|
|
359
1431
|
snapshot: this.snapshotId,
|
|
360
|
-
project: this.
|
|
361
|
-
|
|
1432
|
+
project: this.project.id,
|
|
1433
|
+
files,
|
|
362
1434
|
});
|
|
363
1435
|
return data ?? [];
|
|
364
1436
|
}
|
|
365
1437
|
/**
|
|
366
|
-
* Get suggestion diagnostics for
|
|
367
|
-
* @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.
|
|
368
1440
|
*/
|
|
369
1441
|
async getSuggestionDiagnostics(file) {
|
|
1442
|
+
const files = file === undefined ? undefined
|
|
1443
|
+
: Array.isArray(file) ? file
|
|
1444
|
+
: [file];
|
|
370
1445
|
const data = await this.client.apiRequest("getSuggestionDiagnostics", {
|
|
371
1446
|
snapshot: this.snapshotId,
|
|
372
|
-
project: this.
|
|
373
|
-
|
|
1447
|
+
project: this.project.id,
|
|
1448
|
+
files,
|
|
374
1449
|
});
|
|
375
1450
|
return data ?? [];
|
|
376
1451
|
}
|
|
377
1452
|
/**
|
|
378
|
-
* Get declaration emit diagnostics for
|
|
379
|
-
* @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.
|
|
380
1455
|
*/
|
|
381
1456
|
async getDeclarationDiagnostics(file) {
|
|
1457
|
+
const files = file === undefined ? undefined
|
|
1458
|
+
: Array.isArray(file) ? file
|
|
1459
|
+
: [file];
|
|
382
1460
|
const data = await this.client.apiRequest("getDeclarationDiagnostics", {
|
|
383
1461
|
snapshot: this.snapshotId,
|
|
384
|
-
project: this.
|
|
385
|
-
|
|
1462
|
+
project: this.project.id,
|
|
1463
|
+
files,
|
|
1464
|
+
});
|
|
1465
|
+
return data ?? [];
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Get program-wide diagnostics for the project, including compiler options diagnostics.
|
|
1469
|
+
*/
|
|
1470
|
+
async getProgramDiagnostics() {
|
|
1471
|
+
const data = await this.client.apiRequest("getProgramDiagnostics", {
|
|
1472
|
+
snapshot: this.snapshotId,
|
|
1473
|
+
project: this.project.id,
|
|
1474
|
+
});
|
|
1475
|
+
return data ?? [];
|
|
1476
|
+
}
|
|
1477
|
+
/**
|
|
1478
|
+
* Get global (non-file-specific) semantic diagnostics for the project.
|
|
1479
|
+
*/
|
|
1480
|
+
async getGlobalDiagnostics() {
|
|
1481
|
+
const data = await this.client.apiRequest("getGlobalDiagnostics", {
|
|
1482
|
+
snapshot: this.snapshotId,
|
|
1483
|
+
project: this.project.id,
|
|
386
1484
|
});
|
|
387
1485
|
return data ?? [];
|
|
388
1486
|
}
|
|
@@ -392,34 +1490,222 @@ export class Program {
|
|
|
392
1490
|
async getConfigFileParsingDiagnostics() {
|
|
393
1491
|
const data = await this.client.apiRequest("getConfigFileParsingDiagnostics", {
|
|
394
1492
|
snapshot: this.snapshotId,
|
|
395
|
-
project: this.
|
|
1493
|
+
project: this.project.id,
|
|
396
1494
|
});
|
|
397
1495
|
return data ?? [];
|
|
398
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
|
+
};
|
|
399
1639
|
}
|
|
400
1640
|
export class Checker {
|
|
401
1641
|
snapshotId;
|
|
402
|
-
|
|
403
|
-
client;
|
|
1642
|
+
project;
|
|
404
1643
|
objectRegistry;
|
|
405
|
-
|
|
1644
|
+
wellKnownSymbols;
|
|
1645
|
+
wellKnownSignatures;
|
|
1646
|
+
get client() {
|
|
1647
|
+
return this.project.api.client;
|
|
1648
|
+
}
|
|
1649
|
+
constructor(snapshotId, project, objectRegistry) {
|
|
406
1650
|
this.snapshotId = snapshotId;
|
|
407
|
-
this.
|
|
408
|
-
this.client = client;
|
|
1651
|
+
this.project = project;
|
|
409
1652
|
this.objectRegistry = objectRegistry;
|
|
410
1653
|
}
|
|
1654
|
+
dispose() {
|
|
1655
|
+
this.objectRegistry.clear();
|
|
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
|
+
}
|
|
411
1697
|
async getSymbolAtLocation(nodeOrNodes) {
|
|
412
1698
|
if (Array.isArray(nodeOrNodes)) {
|
|
413
1699
|
const data = await this.client.apiRequest("getSymbolsAtLocations", {
|
|
414
1700
|
snapshot: this.snapshotId,
|
|
415
|
-
project: this.
|
|
1701
|
+
project: this.project.id,
|
|
416
1702
|
locations: nodeOrNodes.map(node => getNodeId(node)),
|
|
417
1703
|
});
|
|
418
1704
|
return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
|
|
419
1705
|
}
|
|
420
1706
|
const data = await this.client.apiRequest("getSymbolAtLocation", {
|
|
421
1707
|
snapshot: this.snapshotId,
|
|
422
|
-
project: this.
|
|
1708
|
+
project: this.project.id,
|
|
423
1709
|
location: getNodeId(nodeOrNodes),
|
|
424
1710
|
});
|
|
425
1711
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
@@ -428,7 +1714,7 @@ export class Checker {
|
|
|
428
1714
|
if (typeof positionOrPositions === "number") {
|
|
429
1715
|
const data = await this.client.apiRequest("getSymbolAtPosition", {
|
|
430
1716
|
snapshot: this.snapshotId,
|
|
431
|
-
project: this.
|
|
1717
|
+
project: this.project.id,
|
|
432
1718
|
file,
|
|
433
1719
|
position: positionOrPositions,
|
|
434
1720
|
});
|
|
@@ -436,126 +1722,117 @@ export class Checker {
|
|
|
436
1722
|
}
|
|
437
1723
|
const data = await this.client.apiRequest("getSymbolsAtPositions", {
|
|
438
1724
|
snapshot: this.snapshotId,
|
|
439
|
-
project: this.
|
|
1725
|
+
project: this.project.id,
|
|
440
1726
|
file,
|
|
441
1727
|
positions: positionOrPositions,
|
|
442
1728
|
});
|
|
443
1729
|
return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
|
|
444
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
|
+
}
|
|
445
1747
|
async getTypeOfSymbol(symbolOrSymbols) {
|
|
446
1748
|
if (Array.isArray(symbolOrSymbols)) {
|
|
447
1749
|
const data = await this.client.apiRequest("getTypesOfSymbols", {
|
|
448
1750
|
snapshot: this.snapshotId,
|
|
449
|
-
project: this.
|
|
450
|
-
symbols: symbolOrSymbols.map(
|
|
1751
|
+
project: this.project.id,
|
|
1752
|
+
symbols: symbolOrSymbols.map(symbol => symbol.reference),
|
|
451
1753
|
});
|
|
452
|
-
return data.map(d =>
|
|
1754
|
+
return data.map(d => this.objectRegistry.getOrCreateType(d));
|
|
453
1755
|
}
|
|
454
1756
|
const data = await this.client.apiRequest("getTypeOfSymbol", {
|
|
455
1757
|
snapshot: this.snapshotId,
|
|
456
|
-
project: this.
|
|
457
|
-
symbol: symbolOrSymbols.
|
|
1758
|
+
project: this.project.id,
|
|
1759
|
+
symbol: symbolOrSymbols.reference,
|
|
458
1760
|
});
|
|
459
|
-
return
|
|
1761
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
460
1762
|
}
|
|
1763
|
+
/**
|
|
1764
|
+
* Get the declared type of a symbol. Always returns a type; for symbols whose
|
|
1765
|
+
* declared type cannot be determined the checker yields the error type (use
|
|
1766
|
+
* {@link Type.isErrorType} to detect it).
|
|
1767
|
+
*/
|
|
461
1768
|
async getDeclaredTypeOfSymbol(symbol) {
|
|
462
1769
|
const data = await this.client.apiRequest("getDeclaredTypeOfSymbol", {
|
|
463
1770
|
snapshot: this.snapshotId,
|
|
464
|
-
project: this.
|
|
465
|
-
symbol: symbol.
|
|
466
|
-
});
|
|
467
|
-
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
468
|
-
}
|
|
469
|
-
async getReferencesToSymbolInFile(file, symbol) {
|
|
470
|
-
const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
|
|
471
|
-
snapshot: this.snapshotId,
|
|
472
|
-
project: this.projectId,
|
|
473
|
-
file,
|
|
474
|
-
symbol: symbol.id,
|
|
475
|
-
});
|
|
476
|
-
return (data ?? []).map(h => new NodeHandle(h));
|
|
477
|
-
}
|
|
478
|
-
async getReferencedSymbolsForNode(node, position) {
|
|
479
|
-
const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
|
|
480
|
-
snapshot: this.snapshotId,
|
|
481
|
-
project: this.projectId,
|
|
482
|
-
node: getNodeId(node),
|
|
483
|
-
position,
|
|
1771
|
+
project: this.project.id,
|
|
1772
|
+
symbol: symbol.reference,
|
|
484
1773
|
});
|
|
485
|
-
return (data
|
|
486
|
-
definition: new NodeHandle(entry.definition),
|
|
487
|
-
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
|
|
488
|
-
references: (entry.references ?? []).map(h => new NodeHandle(h)),
|
|
489
|
-
}));
|
|
1774
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
490
1775
|
}
|
|
491
|
-
|
|
492
|
-
|
|
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", {
|
|
493
1784
|
snapshot: this.snapshotId,
|
|
494
|
-
project: this.
|
|
495
|
-
|
|
1785
|
+
project: this.project.id,
|
|
1786
|
+
symbol: symbol.reference,
|
|
496
1787
|
});
|
|
497
|
-
return (data
|
|
498
|
-
name: new NodeHandle(entry.name),
|
|
499
|
-
call: entry.call ? new NodeHandle(entry.call) : undefined,
|
|
500
|
-
}));
|
|
1788
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
501
1789
|
}
|
|
502
|
-
async
|
|
503
|
-
const data = await this.client.apiRequest("
|
|
1790
|
+
async getReferencesToSymbolInFile(file, symbol) {
|
|
1791
|
+
const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
|
|
504
1792
|
snapshot: this.snapshotId,
|
|
505
|
-
project: this.
|
|
506
|
-
file
|
|
507
|
-
|
|
508
|
-
triggerCharacter: options?.triggerCharacter,
|
|
509
|
-
includeSymbol: options?.includeSymbol,
|
|
1793
|
+
project: this.project.id,
|
|
1794
|
+
file,
|
|
1795
|
+
symbol: symbol.reference,
|
|
510
1796
|
});
|
|
511
|
-
|
|
512
|
-
return undefined;
|
|
513
|
-
return {
|
|
514
|
-
isIncomplete: data.isIncomplete,
|
|
515
|
-
entries: data.entries.map(e => ({
|
|
516
|
-
...e,
|
|
517
|
-
symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
|
|
518
|
-
})),
|
|
519
|
-
};
|
|
1797
|
+
return (data ?? []).map(h => new NodeHandle(h, this.project));
|
|
520
1798
|
}
|
|
521
1799
|
async getTypeAtLocation(nodeOrNodes) {
|
|
522
1800
|
if (Array.isArray(nodeOrNodes)) {
|
|
523
1801
|
const data = await this.client.apiRequest("getTypeAtLocations", {
|
|
524
1802
|
snapshot: this.snapshotId,
|
|
525
|
-
project: this.
|
|
1803
|
+
project: this.project.id,
|
|
526
1804
|
locations: nodeOrNodes.map(node => getNodeId(node)),
|
|
527
1805
|
});
|
|
528
|
-
return data.map(d =>
|
|
1806
|
+
return data.map(d => this.objectRegistry.getOrCreateType(d));
|
|
529
1807
|
}
|
|
530
1808
|
const data = await this.client.apiRequest("getTypeAtLocation", {
|
|
531
1809
|
snapshot: this.snapshotId,
|
|
532
|
-
project: this.
|
|
1810
|
+
project: this.project.id,
|
|
533
1811
|
location: getNodeId(nodeOrNodes),
|
|
534
1812
|
});
|
|
535
|
-
return
|
|
1813
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
536
1814
|
}
|
|
537
1815
|
async getSignaturesOfType(type, kind) {
|
|
538
|
-
|
|
539
|
-
snapshot: this.snapshotId,
|
|
540
|
-
project: this.projectId,
|
|
541
|
-
type: type.id,
|
|
542
|
-
kind,
|
|
543
|
-
});
|
|
544
|
-
return data.map(d => this.objectRegistry.getOrCreateSignature(d));
|
|
1816
|
+
return kind === SignatureKind.Call ? type.getCallSignatures() : type.getConstructSignatures();
|
|
545
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
|
+
*/
|
|
546
1823
|
async getResolvedSignature(node) {
|
|
547
1824
|
const data = await this.client.apiRequest("getResolvedSignature", {
|
|
548
1825
|
snapshot: this.snapshotId,
|
|
549
|
-
project: this.
|
|
1826
|
+
project: this.project.id,
|
|
550
1827
|
location: getNodeId(node),
|
|
551
1828
|
});
|
|
552
|
-
return
|
|
1829
|
+
return this.objectRegistry.getOrCreateSignature(data);
|
|
553
1830
|
}
|
|
554
1831
|
async getTypeAtPosition(file, positionOrPositions) {
|
|
555
1832
|
if (typeof positionOrPositions === "number") {
|
|
556
1833
|
const data = await this.client.apiRequest("getTypeAtPosition", {
|
|
557
1834
|
snapshot: this.snapshotId,
|
|
558
|
-
project: this.
|
|
1835
|
+
project: this.project.id,
|
|
559
1836
|
file,
|
|
560
1837
|
position: positionOrPositions,
|
|
561
1838
|
});
|
|
@@ -563,7 +1840,7 @@ export class Checker {
|
|
|
563
1840
|
}
|
|
564
1841
|
const data = await this.client.apiRequest("getTypesAtPositions", {
|
|
565
1842
|
snapshot: this.snapshotId,
|
|
566
|
-
project: this.
|
|
1843
|
+
project: this.project.id,
|
|
567
1844
|
file,
|
|
568
1845
|
positions: positionOrPositions,
|
|
569
1846
|
});
|
|
@@ -574,7 +1851,7 @@ export class Checker {
|
|
|
574
1851
|
const isNode = location && "kind" in location;
|
|
575
1852
|
const data = await this.client.apiRequest("resolveName", {
|
|
576
1853
|
snapshot: this.snapshotId,
|
|
577
|
-
project: this.
|
|
1854
|
+
project: this.project.id,
|
|
578
1855
|
name,
|
|
579
1856
|
meaning,
|
|
580
1857
|
location: isNode ? getNodeId(location) : undefined,
|
|
@@ -584,6 +1861,22 @@ export class Checker {
|
|
|
584
1861
|
});
|
|
585
1862
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
586
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
|
+
}
|
|
587
1880
|
async getResolvedSymbol(node) {
|
|
588
1881
|
const text = node.text;
|
|
589
1882
|
if (!text)
|
|
@@ -593,63 +1886,87 @@ export class Checker {
|
|
|
593
1886
|
async getContextualType(node) {
|
|
594
1887
|
const data = await this.client.apiRequest("getContextualType", {
|
|
595
1888
|
snapshot: this.snapshotId,
|
|
596
|
-
project: this.
|
|
1889
|
+
project: this.project.id,
|
|
597
1890
|
location: getNodeId(node),
|
|
598
1891
|
});
|
|
599
1892
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
600
1893
|
}
|
|
601
|
-
async
|
|
602
|
-
const data = await this.client.apiRequest("
|
|
1894
|
+
async getContextualTypeForArgumentAtIndex(node, argIndex) {
|
|
1895
|
+
const data = await this.client.apiRequest("getContextualTypeForArgument", {
|
|
603
1896
|
snapshot: this.snapshotId,
|
|
604
|
-
project: this.
|
|
605
|
-
|
|
1897
|
+
project: this.project.id,
|
|
1898
|
+
location: getNodeId(node),
|
|
1899
|
+
index: argIndex,
|
|
606
1900
|
});
|
|
607
1901
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
608
1902
|
}
|
|
609
|
-
async
|
|
610
|
-
const data = await this.client.apiRequest("
|
|
1903
|
+
async getAwaitedType(type) {
|
|
1904
|
+
const data = await this.client.apiRequest("getAwaitedType", {
|
|
611
1905
|
snapshot: this.snapshotId,
|
|
612
|
-
project: this.
|
|
1906
|
+
project: this.project.id,
|
|
613
1907
|
type: type.id,
|
|
614
1908
|
});
|
|
615
1909
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
616
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
|
+
*/
|
|
617
1929
|
async getTypeFromTypeNode(node) {
|
|
618
1930
|
const data = await this.client.apiRequest("getTypeFromTypeNode", {
|
|
619
1931
|
snapshot: this.snapshotId,
|
|
620
|
-
project: this.
|
|
1932
|
+
project: this.project.id,
|
|
621
1933
|
location: getNodeId(node),
|
|
622
1934
|
});
|
|
623
|
-
return
|
|
1935
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
624
1936
|
}
|
|
1937
|
+
/** Get the widened type. Always returns a type. */
|
|
625
1938
|
async getWidenedType(type) {
|
|
626
1939
|
const data = await this.client.apiRequest("getWidenedType", {
|
|
627
1940
|
snapshot: this.snapshotId,
|
|
628
|
-
project: this.
|
|
1941
|
+
project: this.project.id,
|
|
629
1942
|
type: type.id,
|
|
630
1943
|
});
|
|
631
|
-
return
|
|
1944
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
632
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
|
+
*/
|
|
633
1950
|
async getParameterType(signature, index) {
|
|
634
1951
|
const data = await this.client.apiRequest("getParameterType", {
|
|
635
1952
|
snapshot: this.snapshotId,
|
|
636
|
-
project: this.
|
|
1953
|
+
project: this.project.id,
|
|
637
1954
|
signature: signature.id,
|
|
638
1955
|
index,
|
|
639
1956
|
});
|
|
640
|
-
return
|
|
1957
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
641
1958
|
}
|
|
642
1959
|
async isArrayLikeType(type) {
|
|
643
1960
|
return this.client.apiRequest("isArrayLikeType", {
|
|
644
1961
|
snapshot: this.snapshotId,
|
|
645
|
-
project: this.
|
|
1962
|
+
project: this.project.id,
|
|
646
1963
|
type: type.id,
|
|
647
1964
|
});
|
|
648
1965
|
}
|
|
649
1966
|
async isTypeAssignableTo(source, target) {
|
|
650
1967
|
return this.client.apiRequest("isTypeAssignableTo", {
|
|
651
1968
|
snapshot: this.snapshotId,
|
|
652
|
-
project: this.
|
|
1969
|
+
project: this.project.id,
|
|
653
1970
|
source: source.id,
|
|
654
1971
|
target: target.id,
|
|
655
1972
|
});
|
|
@@ -657,24 +1974,29 @@ export class Checker {
|
|
|
657
1974
|
async getShorthandAssignmentValueSymbol(node) {
|
|
658
1975
|
const data = await this.client.apiRequest("getShorthandAssignmentValueSymbol", {
|
|
659
1976
|
snapshot: this.snapshotId,
|
|
660
|
-
project: this.
|
|
1977
|
+
project: this.project.id,
|
|
661
1978
|
location: getNodeId(node),
|
|
662
1979
|
});
|
|
663
1980
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
664
1981
|
}
|
|
1982
|
+
/**
|
|
1983
|
+
* Get the type of a symbol as narrowed at a specific location. Always returns
|
|
1984
|
+
* a type; for symbols whose type cannot be determined the checker yields the
|
|
1985
|
+
* error type (use {@link Type.isErrorType} to detect it).
|
|
1986
|
+
*/
|
|
665
1987
|
async getTypeOfSymbolAtLocation(symbol, location) {
|
|
666
1988
|
const data = await this.client.apiRequest("getTypeOfSymbolAtLocation", {
|
|
667
1989
|
snapshot: this.snapshotId,
|
|
668
|
-
project: this.
|
|
669
|
-
symbol: symbol.
|
|
1990
|
+
project: this.project.id,
|
|
1991
|
+
symbol: symbol.reference,
|
|
670
1992
|
location: getNodeId(location),
|
|
671
1993
|
});
|
|
672
|
-
return
|
|
1994
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
673
1995
|
}
|
|
674
1996
|
async getIntrinsicType(method) {
|
|
675
1997
|
const data = await this.client.apiRequest(method, {
|
|
676
1998
|
snapshot: this.snapshotId,
|
|
677
|
-
project: this.
|
|
1999
|
+
project: this.project.id,
|
|
678
2000
|
});
|
|
679
2001
|
return this.objectRegistry.getOrCreateType(data);
|
|
680
2002
|
}
|
|
@@ -711,10 +2033,13 @@ export class Checker {
|
|
|
711
2033
|
async getESSymbolType() {
|
|
712
2034
|
return this.getIntrinsicType("getESSymbolType");
|
|
713
2035
|
}
|
|
2036
|
+
async getNonPrimitiveType() {
|
|
2037
|
+
return this.getIntrinsicType("getNonPrimitiveType");
|
|
2038
|
+
}
|
|
714
2039
|
async typeToTypeNode(type, enclosingDeclaration, flags) {
|
|
715
2040
|
const binaryData = await this.client.apiRequestBinary("typeToTypeNode", {
|
|
716
2041
|
snapshot: this.snapshotId,
|
|
717
|
-
project: this.
|
|
2042
|
+
project: this.project.id,
|
|
718
2043
|
type: type.id,
|
|
719
2044
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
720
2045
|
flags,
|
|
@@ -726,7 +2051,7 @@ export class Checker {
|
|
|
726
2051
|
async signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags) {
|
|
727
2052
|
const binaryData = await this.client.apiRequestBinary("signatureToSignatureDeclaration", {
|
|
728
2053
|
snapshot: this.snapshotId,
|
|
729
|
-
project: this.
|
|
2054
|
+
project: this.project.id,
|
|
730
2055
|
signature: signature.id,
|
|
731
2056
|
kind,
|
|
732
2057
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
@@ -737,41 +2062,73 @@ export class Checker {
|
|
|
737
2062
|
return decodeNode(binaryData);
|
|
738
2063
|
}
|
|
739
2064
|
async typeToString(type, enclosingDeclaration, flags) {
|
|
740
|
-
|
|
2065
|
+
const result = await this.client.apiRequest("typeToString", {
|
|
741
2066
|
snapshot: this.snapshotId,
|
|
742
|
-
project: this.
|
|
2067
|
+
project: this.project.id,
|
|
743
2068
|
type: type.id,
|
|
744
2069
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
745
2070
|
flags,
|
|
746
2071
|
});
|
|
2072
|
+
if (typeof result !== "string")
|
|
2073
|
+
throw new TypeError("typeToString returned a non-string result");
|
|
2074
|
+
return result;
|
|
747
2075
|
}
|
|
748
2076
|
async isContextSensitive(node) {
|
|
749
2077
|
return this.client.apiRequest("isContextSensitive", {
|
|
750
2078
|
snapshot: this.snapshotId,
|
|
751
|
-
project: this.
|
|
2079
|
+
project: this.project.id,
|
|
752
2080
|
location: getNodeId(node),
|
|
753
2081
|
});
|
|
754
2082
|
}
|
|
755
|
-
async
|
|
756
|
-
|
|
2083
|
+
async isArrayType(type) {
|
|
2084
|
+
return this.client.apiRequest("isArrayType", {
|
|
757
2085
|
snapshot: this.snapshotId,
|
|
758
|
-
project: this.
|
|
759
|
-
|
|
2086
|
+
project: this.project.id,
|
|
2087
|
+
type: type.id,
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
async isTupleType(type) {
|
|
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", {
|
|
2107
|
+
snapshot: this.snapshotId,
|
|
2108
|
+
project: this.project.id,
|
|
2109
|
+
symbol: symbol.reference,
|
|
760
2110
|
});
|
|
761
|
-
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
762
2111
|
}
|
|
2112
|
+
/** Get the return type of a signature. Always returns a type. */
|
|
2113
|
+
async getReturnTypeOfSignature(signature) {
|
|
2114
|
+
return signature.getReturnType();
|
|
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
|
+
*/
|
|
763
2120
|
async getRestTypeOfSignature(signature) {
|
|
764
2121
|
const data = await this.client.apiRequest("getRestTypeOfSignature", {
|
|
765
2122
|
snapshot: this.snapshotId,
|
|
766
|
-
project: this.
|
|
2123
|
+
project: this.project.id,
|
|
767
2124
|
signature: signature.id,
|
|
768
2125
|
});
|
|
769
|
-
return
|
|
2126
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
770
2127
|
}
|
|
771
2128
|
async getTypePredicateOfSignature(signature) {
|
|
772
2129
|
const data = await this.client.apiRequest("getTypePredicateOfSignature", {
|
|
773
2130
|
snapshot: this.snapshotId,
|
|
774
|
-
project: this.
|
|
2131
|
+
project: this.project.id,
|
|
775
2132
|
signature: signature.id,
|
|
776
2133
|
});
|
|
777
2134
|
if (!data)
|
|
@@ -783,55 +2140,266 @@ export class Checker {
|
|
|
783
2140
|
type: data.type ? this.objectRegistry.getOrCreateType(data.type) : undefined,
|
|
784
2141
|
};
|
|
785
2142
|
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Get the base types of a class or interface type. A type with no base types
|
|
2145
|
+
* yields an empty array.
|
|
2146
|
+
*/
|
|
786
2147
|
async getBaseTypes(type) {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
2148
|
+
return await type.getBaseTypes() ?? [];
|
|
2149
|
+
}
|
|
2150
|
+
/** Get the apparent type of a type. Always returns a type. */
|
|
2151
|
+
async getApparentType(type) {
|
|
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();
|
|
793
2157
|
}
|
|
794
2158
|
async getPropertiesOfType(type) {
|
|
795
|
-
|
|
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", {
|
|
796
2166
|
snapshot: this.snapshotId,
|
|
797
|
-
project: this.
|
|
2167
|
+
project: this.project.id,
|
|
798
2168
|
type: type.id,
|
|
2169
|
+
kind,
|
|
799
2170
|
});
|
|
800
|
-
return data ?
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
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;
|
|
2177
|
+
}
|
|
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", {
|
|
804
2183
|
snapshot: this.snapshotId,
|
|
805
|
-
project: this.
|
|
2184
|
+
project: this.project.id,
|
|
806
2185
|
type: type.id,
|
|
2186
|
+
name: propertyName,
|
|
807
2187
|
});
|
|
808
|
-
|
|
809
|
-
return [];
|
|
810
|
-
return data.map(d => ({
|
|
811
|
-
keyType: this.objectRegistry.getOrCreateType(d.keyType),
|
|
812
|
-
valueType: this.objectRegistry.getOrCreateType(d.valueType),
|
|
813
|
-
isReadonly: d.isReadonly ?? false,
|
|
814
|
-
declaration: d.declaration ? new NodeHandle(d.declaration) : undefined,
|
|
815
|
-
}));
|
|
2188
|
+
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
816
2189
|
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Get the constraint of a type parameter (the `T` in `<U extends T>`), or
|
|
2192
|
+
* undefined if it has none.
|
|
2193
|
+
*/
|
|
817
2194
|
async getConstraintOfTypeParameter(type) {
|
|
818
|
-
|
|
2195
|
+
return type.getConstraint();
|
|
2196
|
+
}
|
|
2197
|
+
async getDefaultFromTypeParameter(type) {
|
|
2198
|
+
return type.getDefault();
|
|
2199
|
+
}
|
|
2200
|
+
async getBaseConstraintOfType(type) {
|
|
2201
|
+
const data = await this.client.apiRequest("getBaseConstraintOfType", {
|
|
819
2202
|
snapshot: this.snapshotId,
|
|
820
|
-
project: this.
|
|
2203
|
+
project: this.project.id,
|
|
821
2204
|
type: type.id,
|
|
822
2205
|
});
|
|
823
2206
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
824
2207
|
}
|
|
2208
|
+
async getPropertyOfType(type, name) {
|
|
2209
|
+
const data = await this.client.apiRequest("getPropertyOfType", {
|
|
2210
|
+
snapshot: this.snapshotId,
|
|
2211
|
+
project: this.project.id,
|
|
2212
|
+
type: type.id,
|
|
2213
|
+
name,
|
|
2214
|
+
});
|
|
2215
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
2216
|
+
}
|
|
2217
|
+
async getConstantValue(node) {
|
|
2218
|
+
const data = await this.client.apiRequest("getConstantValue", {
|
|
2219
|
+
snapshot: this.snapshotId,
|
|
2220
|
+
project: this.project.id,
|
|
2221
|
+
location: getNodeId(node),
|
|
2222
|
+
});
|
|
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;
|
|
2236
|
+
}
|
|
2237
|
+
/** Get the signature of a function-like declaration. Always returns a signature. */
|
|
2238
|
+
async getSignatureFromDeclaration(node) {
|
|
2239
|
+
const data = await this.client.apiRequest("getSignatureFromDeclaration", {
|
|
2240
|
+
snapshot: this.snapshotId,
|
|
2241
|
+
project: this.project.id,
|
|
2242
|
+
location: getNodeId(node),
|
|
2243
|
+
});
|
|
2244
|
+
return this.objectRegistry.getOrCreateSignature(data);
|
|
2245
|
+
}
|
|
2246
|
+
async getExportSpecifierLocalTargetSymbol(node) {
|
|
2247
|
+
const data = await this.client.apiRequest("getExportSpecifierLocalTargetSymbol", {
|
|
2248
|
+
snapshot: this.snapshotId,
|
|
2249
|
+
project: this.project.id,
|
|
2250
|
+
location: getNodeId(node),
|
|
2251
|
+
});
|
|
2252
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Follow all aliases to get the original symbol. Always returns a symbol; for
|
|
2256
|
+
* an unresolved alias the checker yields the unknown symbol (use
|
|
2257
|
+
* {@link Checker.isUnknownSymbol} to detect it).
|
|
2258
|
+
*/
|
|
2259
|
+
async getAliasedSymbol(symbol) {
|
|
2260
|
+
const data = await this.client.apiRequest("getAliasedSymbol", {
|
|
2261
|
+
snapshot: this.snapshotId,
|
|
2262
|
+
project: this.project.id,
|
|
2263
|
+
symbol: symbol.reference,
|
|
2264
|
+
});
|
|
2265
|
+
return this.objectRegistry.getOrCreateSymbol(data);
|
|
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
|
+
}
|
|
2278
|
+
async getImmediateAliasedSymbol(symbol) {
|
|
2279
|
+
const data = await this.client.apiRequest("getImmediateAliasedSymbol", {
|
|
2280
|
+
snapshot: this.snapshotId,
|
|
2281
|
+
project: this.project.id,
|
|
2282
|
+
symbol: symbol.reference,
|
|
2283
|
+
});
|
|
2284
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
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
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Fetch (once, then cache) the handle ids of the per-checker singleton
|
|
2310
|
+
* symbols (unknown, undefined, arguments). These ids are stable for the life
|
|
2311
|
+
* of the project's checker, so identity checks against them are local after
|
|
2312
|
+
* the first call.
|
|
2313
|
+
*/
|
|
2314
|
+
getWellKnownSymbols() {
|
|
2315
|
+
return this.wellKnownSymbols ??= this.client.apiRequest("getWellKnownSymbols", {
|
|
2316
|
+
snapshot: this.snapshotId,
|
|
2317
|
+
project: this.project.id,
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* Returns `true` if the symbol is the checker's "unknown" symbol (e.g. the
|
|
2322
|
+
* result of {@link Checker.getAliasedSymbol} on an unresolved alias).
|
|
2323
|
+
*/
|
|
2324
|
+
async isUnknownSymbol(symbol) {
|
|
2325
|
+
return symbol.id === (await this.getWellKnownSymbols()).unknown;
|
|
2326
|
+
}
|
|
2327
|
+
/**
|
|
2328
|
+
* Returns `true` if the symbol is the checker's "undefined" symbol.
|
|
2329
|
+
*/
|
|
2330
|
+
async isUndefinedSymbol(symbol) {
|
|
2331
|
+
return symbol.id === (await this.getWellKnownSymbols()).undefined;
|
|
2332
|
+
}
|
|
2333
|
+
/**
|
|
2334
|
+
* Returns `true` if the symbol is the checker's "arguments" symbol.
|
|
2335
|
+
*/
|
|
2336
|
+
async isArgumentsSymbol(symbol) {
|
|
2337
|
+
return symbol.id === (await this.getWellKnownSymbols()).arguments;
|
|
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
|
+
}
|
|
2358
|
+
async getExportsOfModule(symbol) {
|
|
2359
|
+
const data = await this.client.apiRequest("getExportsOfModule", {
|
|
2360
|
+
snapshot: this.snapshotId,
|
|
2361
|
+
project: this.project.id,
|
|
2362
|
+
symbol: symbol.reference,
|
|
2363
|
+
});
|
|
2364
|
+
return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
|
|
2365
|
+
}
|
|
2366
|
+
async getMemberInModuleExports(symbol, name) {
|
|
2367
|
+
const data = await this.client.apiRequest("getMemberInModuleExports", {
|
|
2368
|
+
snapshot: this.snapshotId,
|
|
2369
|
+
project: this.project.id,
|
|
2370
|
+
symbol: symbol.reference,
|
|
2371
|
+
name,
|
|
2372
|
+
});
|
|
2373
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
2374
|
+
}
|
|
2375
|
+
async getJsDocTagsOfSymbol(symbol) {
|
|
2376
|
+
const data = await this.client.apiRequest("getJsDocTags", {
|
|
2377
|
+
snapshot: this.snapshotId,
|
|
2378
|
+
project: this.project.id,
|
|
2379
|
+
symbol: symbol.reference,
|
|
2380
|
+
});
|
|
2381
|
+
return data ?? [];
|
|
2382
|
+
}
|
|
2383
|
+
async getDocumentationCommentOfSymbol(symbol) {
|
|
2384
|
+
return this.client.apiRequest("getDocumentationComment", {
|
|
2385
|
+
snapshot: this.snapshotId,
|
|
2386
|
+
project: this.project.id,
|
|
2387
|
+
symbol: symbol.reference,
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
/**
|
|
2391
|
+
* Get the type arguments of a type reference (e.g. the `string` in `Array<string>`).
|
|
2392
|
+
*/
|
|
825
2393
|
async getTypeArguments(type) {
|
|
826
2394
|
const data = await this.client.apiRequest("getTypeArguments", {
|
|
827
2395
|
snapshot: this.snapshotId,
|
|
828
|
-
project: this.
|
|
2396
|
+
project: this.project.id,
|
|
829
2397
|
type: type.id,
|
|
830
2398
|
});
|
|
831
2399
|
return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
|
|
832
2400
|
}
|
|
833
2401
|
}
|
|
834
|
-
export class
|
|
2402
|
+
export class Printer {
|
|
835
2403
|
client;
|
|
836
2404
|
constructor(client) {
|
|
837
2405
|
this.client = client;
|
|
@@ -841,72 +2409,180 @@ export class Emitter {
|
|
|
841
2409
|
const base64 = uint8ArrayToBase64(encoded);
|
|
842
2410
|
return this.client.apiRequest("printNode", {
|
|
843
2411
|
data: base64,
|
|
844
|
-
|
|
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,
|
|
845
2425
|
});
|
|
846
2426
|
}
|
|
847
2427
|
}
|
|
848
2428
|
export class NodeHandle {
|
|
2429
|
+
/**
|
|
2430
|
+
* The project this handle was produced in, used as the default for {@link resolve}.
|
|
2431
|
+
* Node handles are only meaningful within a project's program, so the producing project
|
|
2432
|
+
* is remembered so callers don't have to pass it explicitly.
|
|
2433
|
+
*/
|
|
2434
|
+
canonicalProject;
|
|
2435
|
+
/** The owning source file of a file-owned symbol's declaration. */
|
|
2436
|
+
fileOwner;
|
|
849
2437
|
index;
|
|
850
2438
|
kind;
|
|
851
2439
|
path;
|
|
852
|
-
constructor(handle) {
|
|
853
|
-
const parsed =
|
|
2440
|
+
constructor(handle, canonicalProject, fileOwner) {
|
|
2441
|
+
const parsed = parseNodeHandleFromCompiler(handle);
|
|
854
2442
|
this.index = parsed.index;
|
|
855
2443
|
this.kind = parsed.kind;
|
|
856
2444
|
this.path = parsed.path;
|
|
2445
|
+
this.canonicalProject = canonicalProject;
|
|
2446
|
+
this.fileOwner = fileOwner;
|
|
857
2447
|
}
|
|
858
2448
|
/**
|
|
859
|
-
* Resolve this handle to the actual AST node by fetching the source file
|
|
860
|
-
*
|
|
2449
|
+
* Resolve this handle to the actual AST node by fetching the source file from a project
|
|
2450
|
+
* and looking up the node by index. If no project is passed, the project that produced
|
|
2451
|
+
* the handle is used. Declarations of file-owned symbols identify an exact source file and
|
|
2452
|
+
* resolve through it, independently of any project.
|
|
861
2453
|
*/
|
|
862
|
-
async resolve(project) {
|
|
863
|
-
|
|
2454
|
+
async resolve(project = this.canonicalProject) {
|
|
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);
|
|
864
2462
|
if (!sourceFile) {
|
|
865
2463
|
return undefined;
|
|
866
2464
|
}
|
|
867
2465
|
return sourceFile.getOrCreateNodeAtIndex(this.index);
|
|
868
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
|
+
}
|
|
869
2473
|
}
|
|
870
2474
|
export class Symbol {
|
|
871
|
-
|
|
872
|
-
id
|
|
2475
|
+
storage;
|
|
2476
|
+
get id() {
|
|
2477
|
+
return this.reference.id;
|
|
2478
|
+
}
|
|
2479
|
+
/** The escaped (`__String`) name, used as the key in member/export tables. */
|
|
2480
|
+
escapedName;
|
|
2481
|
+
/** The display name (escaped underscores removed). */
|
|
873
2482
|
name;
|
|
874
2483
|
flags;
|
|
875
2484
|
checkFlags;
|
|
2485
|
+
/** @internal */
|
|
2486
|
+
reference;
|
|
876
2487
|
declarations;
|
|
877
2488
|
valueDeclaration;
|
|
878
2489
|
parent;
|
|
879
2490
|
exportSymbol;
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
2491
|
+
membersCache;
|
|
2492
|
+
exportsCache;
|
|
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;
|
|
2498
|
+
this.escapedName = data.name;
|
|
2499
|
+
this.name = unescapeLeadingUnderscores(data.name);
|
|
884
2500
|
this.flags = data.flags;
|
|
885
2501
|
this.checkFlags = data.checkFlags;
|
|
886
|
-
|
|
887
|
-
|
|
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;
|
|
888
2509
|
if (data.parent !== undefined)
|
|
889
2510
|
this.parent = data.parent;
|
|
890
2511
|
if (data.exportSymbol !== undefined)
|
|
891
2512
|
this.exportSymbol = data.exportSymbol;
|
|
892
2513
|
}
|
|
893
2514
|
async getParent() {
|
|
894
|
-
|
|
2515
|
+
if (!this.parent)
|
|
2516
|
+
return undefined;
|
|
2517
|
+
return this.fetchSymbol("getParentOfSymbol", this.parent);
|
|
895
2518
|
}
|
|
896
|
-
|
|
897
|
-
|
|
2519
|
+
/**
|
|
2520
|
+
* Get this symbol's members keyed by escaped name. The result is cached on
|
|
2521
|
+
* the symbol, so repeated calls do not round-trip to the server.
|
|
2522
|
+
*/
|
|
2523
|
+
getMembers() {
|
|
2524
|
+
return this.membersCache ??= this.fetchSymbolTable("getMembersOfSymbol");
|
|
898
2525
|
}
|
|
899
|
-
|
|
900
|
-
|
|
2526
|
+
/**
|
|
2527
|
+
* Get this symbol's exports keyed by escaped name. The result is cached on
|
|
2528
|
+
* the symbol, so repeated calls do not round-trip to the server.
|
|
2529
|
+
*/
|
|
2530
|
+
getExports() {
|
|
2531
|
+
return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
|
|
2532
|
+
}
|
|
2533
|
+
async fetchSymbolTable(method) {
|
|
2534
|
+
const symbols = await this.fetchSymbols(method);
|
|
2535
|
+
const table = new Map();
|
|
2536
|
+
for (const symbol of symbols) {
|
|
2537
|
+
table.set(symbol.escapedName, symbol);
|
|
2538
|
+
}
|
|
2539
|
+
return table;
|
|
901
2540
|
}
|
|
902
2541
|
async getExportSymbol() {
|
|
903
2542
|
if (!this.exportSymbol)
|
|
904
2543
|
return this;
|
|
905
|
-
return this.
|
|
2544
|
+
return this.fetchSymbol("getExportSymbolOfSymbol", this.exportSymbol);
|
|
2545
|
+
}
|
|
2546
|
+
async getJsDocTags(checker) {
|
|
2547
|
+
return checker.getJsDocTagsOfSymbol(this);
|
|
2548
|
+
}
|
|
2549
|
+
async getDocumentationComment(checker) {
|
|
2550
|
+
return checker.getDocumentationCommentOfSymbol(this);
|
|
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 }));
|
|
906
2580
|
}
|
|
907
2581
|
}
|
|
908
2582
|
class TypeObject {
|
|
909
2583
|
objectRegistry;
|
|
2584
|
+
// Fields included in TypeResponse. References to other objects are stored as IDs
|
|
2585
|
+
// and resolved lazily via the object registry.
|
|
910
2586
|
id;
|
|
911
2587
|
flags;
|
|
912
2588
|
objectFlags;
|
|
@@ -917,14 +2593,17 @@ class TypeObject {
|
|
|
917
2593
|
freshType;
|
|
918
2594
|
regularType;
|
|
919
2595
|
target;
|
|
2596
|
+
tupleType;
|
|
920
2597
|
typeParameters;
|
|
921
2598
|
outerTypeParameters;
|
|
922
2599
|
localTypeParameters;
|
|
2600
|
+
thisType;
|
|
923
2601
|
aliasTypeArguments;
|
|
924
2602
|
aliasSymbol;
|
|
925
2603
|
elementFlags;
|
|
926
2604
|
fixedLength;
|
|
927
2605
|
readonly;
|
|
2606
|
+
labeledElementDeclarations;
|
|
928
2607
|
texts;
|
|
929
2608
|
objectType;
|
|
930
2609
|
indexType;
|
|
@@ -932,6 +2611,31 @@ class TypeObject {
|
|
|
932
2611
|
extendsType;
|
|
933
2612
|
baseType;
|
|
934
2613
|
substConstraint;
|
|
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;
|
|
935
2639
|
constructor(data, objectRegistry) {
|
|
936
2640
|
this.objectRegistry = objectRegistry;
|
|
937
2641
|
this.id = data.id;
|
|
@@ -940,8 +2644,29 @@ class TypeObject {
|
|
|
940
2644
|
this.objectFlags = data.objectFlags;
|
|
941
2645
|
if (data.symbol !== undefined)
|
|
942
2646
|
this.symbol = data.symbol;
|
|
943
|
-
if (data.value
|
|
944
|
-
|
|
2647
|
+
if (data.value != null) {
|
|
2648
|
+
// BigInt literal values are serialized as decimal strings (e.g. "-123") because
|
|
2649
|
+
// JSON cannot represent bigint. Decode them back into a real bigint here.
|
|
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
|
+
}
|
|
2669
|
+
}
|
|
945
2670
|
if (data.intrinsicName !== undefined)
|
|
946
2671
|
this.intrinsicName = data.intrinsicName;
|
|
947
2672
|
if (data.isThisType !== undefined)
|
|
@@ -952,18 +2677,24 @@ class TypeObject {
|
|
|
952
2677
|
this.regularType = data.regularType;
|
|
953
2678
|
if (data.target !== undefined)
|
|
954
2679
|
this.target = data.target;
|
|
2680
|
+
this.tupleType = data.isTupleType ?? false;
|
|
955
2681
|
this.typeParameters = data.typeParameters ?? [];
|
|
956
2682
|
this.outerTypeParameters = data.outerTypeParameters ?? [];
|
|
957
2683
|
this.localTypeParameters = data.localTypeParameters ?? [];
|
|
2684
|
+
if (data.thisType !== undefined)
|
|
2685
|
+
this.thisType = data.thisType;
|
|
958
2686
|
this.aliasTypeArguments = data.aliasTypeArguments ?? [];
|
|
959
2687
|
if (data.aliasSymbol !== undefined)
|
|
960
2688
|
this.aliasSymbol = data.aliasSymbol;
|
|
961
|
-
if (data.
|
|
962
|
-
this.elementFlags = data.elementFlags;
|
|
963
|
-
if (data.fixedLength !== undefined)
|
|
2689
|
+
if (data.fixedLength !== undefined) {
|
|
2690
|
+
this.elementFlags = data.elementFlags ?? [];
|
|
964
2691
|
this.fixedLength = data.fixedLength;
|
|
2692
|
+
}
|
|
965
2693
|
if (data.readonly !== undefined)
|
|
966
2694
|
this.readonly = data.readonly;
|
|
2695
|
+
if (data.labeledElementDeclarations !== undefined) {
|
|
2696
|
+
this.labeledElementDeclarations = data.labeledElementDeclarations.map(handle => handle ? objectRegistry.createNodeHandle(handle) : undefined);
|
|
2697
|
+
}
|
|
967
2698
|
if (data.texts !== undefined)
|
|
968
2699
|
this.texts = data.texts;
|
|
969
2700
|
if (data.objectType !== undefined)
|
|
@@ -978,10 +2709,102 @@ class TypeObject {
|
|
|
978
2709
|
this.baseType = data.baseType;
|
|
979
2710
|
if (data.substConstraint !== undefined)
|
|
980
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;
|
|
2720
|
+
this.trueType = false;
|
|
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;
|
|
981
2736
|
}
|
|
982
2737
|
async getSymbol() {
|
|
983
2738
|
return this.objectRegistry.fetchSymbol(this, "getSymbolOfType", this.symbol);
|
|
984
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
|
+
}
|
|
985
2808
|
async getAliasSymbol() {
|
|
986
2809
|
return this.objectRegistry.fetchSymbol(this, "getAliasSymbolOfType", this.aliasSymbol);
|
|
987
2810
|
}
|
|
@@ -989,13 +2812,22 @@ class TypeObject {
|
|
|
989
2812
|
return this.objectRegistry.fetchType(this, "getTargetOfType", this.target);
|
|
990
2813
|
}
|
|
991
2814
|
async getFreshType() {
|
|
992
|
-
return this.objectRegistry.
|
|
2815
|
+
return this.objectRegistry.fetchOptionalType(this, "getFreshTypeOfType", this.freshType);
|
|
993
2816
|
}
|
|
994
2817
|
async getRegularType() {
|
|
995
|
-
return this.objectRegistry.
|
|
2818
|
+
return this.objectRegistry.fetchOptionalType(this, "getRegularTypeOfType", this.regularType);
|
|
996
2819
|
}
|
|
997
2820
|
async getTypes() {
|
|
998
|
-
|
|
2821
|
+
// Only union, intersection, and template literal types have constituent
|
|
2822
|
+
// types; any other kind has none, so return undefined rather than sending
|
|
2823
|
+
// a request the server cannot satisfy.
|
|
2824
|
+
if (!(this.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral))) {
|
|
2825
|
+
return undefined;
|
|
2826
|
+
}
|
|
2827
|
+
if (this.types === false) {
|
|
2828
|
+
this.types = await this.objectRegistry.fetchTypes(this, "getTypesOfType");
|
|
2829
|
+
}
|
|
2830
|
+
return this.types;
|
|
999
2831
|
}
|
|
1000
2832
|
async getTypeParameters() {
|
|
1001
2833
|
return this.objectRegistry.fetchTypes(this, "getTypeParametersOfType", this.typeParameters);
|
|
@@ -1006,9 +2838,24 @@ class TypeObject {
|
|
|
1006
2838
|
async getLocalTypeParameters() {
|
|
1007
2839
|
return this.objectRegistry.fetchTypes(this, "getLocalTypeParametersOfType", this.localTypeParameters);
|
|
1008
2840
|
}
|
|
2841
|
+
async getThisType() {
|
|
2842
|
+
return this.objectRegistry.fetchOptionalType(this, "getThisTypeOfType", this.thisType);
|
|
2843
|
+
}
|
|
1009
2844
|
async getAliasTypeArguments() {
|
|
1010
2845
|
return this.objectRegistry.fetchTypes(this, "getAliasTypeArgumentsOfType", this.aliasTypeArguments);
|
|
1011
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
|
+
}
|
|
1012
2859
|
async getObjectType() {
|
|
1013
2860
|
return this.objectRegistry.fetchType(this, "getObjectTypeOfType", this.objectType);
|
|
1014
2861
|
}
|
|
@@ -1025,8 +2872,178 @@ class TypeObject {
|
|
|
1025
2872
|
return this.objectRegistry.fetchType(this, "getBaseTypeOfType", this.baseType);
|
|
1026
2873
|
}
|
|
1027
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
|
+
}
|
|
1028
2882
|
return this.objectRegistry.fetchType(this, "getConstraintOfType", this.substConstraint);
|
|
1029
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
|
+
}
|
|
2889
|
+
async getTrueType() {
|
|
2890
|
+
const result = await this.objectRegistry.fetchType(this, "getTrueTypeOfConditionalType", this.trueType);
|
|
2891
|
+
this.trueType = result.id;
|
|
2892
|
+
return result;
|
|
2893
|
+
}
|
|
2894
|
+
async getFalseType() {
|
|
2895
|
+
const result = await this.objectRegistry.fetchType(this, "getFalseTypeOfConditionalType", this.falseType);
|
|
2896
|
+
this.falseType = result.id;
|
|
2897
|
+
return result;
|
|
2898
|
+
}
|
|
2899
|
+
/**
|
|
2900
|
+
* Get the base types of this type. Returns `undefined` for any type that is
|
|
2901
|
+
* not a class or interface.
|
|
2902
|
+
*/
|
|
2903
|
+
async getBaseTypes() {
|
|
2904
|
+
if (!this.isClassOrInterface()) {
|
|
2905
|
+
return undefined;
|
|
2906
|
+
}
|
|
2907
|
+
if (this.baseTypes === false) {
|
|
2908
|
+
this.baseTypes = await this.objectRegistry.fetchBaseTypes(this);
|
|
2909
|
+
}
|
|
2910
|
+
return this.baseTypes;
|
|
2911
|
+
}
|
|
2912
|
+
isClassOrInterface() {
|
|
2913
|
+
return isClassOrInterfaceType(this);
|
|
2914
|
+
}
|
|
2915
|
+
isUnionType() {
|
|
2916
|
+
return isUnionType(this);
|
|
2917
|
+
}
|
|
2918
|
+
isIntersectionType() {
|
|
2919
|
+
return isIntersectionType(this);
|
|
2920
|
+
}
|
|
2921
|
+
isObjectType() {
|
|
2922
|
+
return isObjectType(this);
|
|
2923
|
+
}
|
|
2924
|
+
isIntrinsicType() {
|
|
2925
|
+
return isIntrinsicType(this);
|
|
2926
|
+
}
|
|
2927
|
+
isErrorType() {
|
|
2928
|
+
return isErrorType(this);
|
|
2929
|
+
}
|
|
2930
|
+
isLiteralType() {
|
|
2931
|
+
return isLiteralType(this);
|
|
2932
|
+
}
|
|
2933
|
+
isStringLiteralType() {
|
|
2934
|
+
return isStringLiteralType(this);
|
|
2935
|
+
}
|
|
2936
|
+
isNumberLiteralType() {
|
|
2937
|
+
return isNumberLiteralType(this);
|
|
2938
|
+
}
|
|
2939
|
+
isBigIntLiteralType() {
|
|
2940
|
+
return isBigIntLiteralType(this);
|
|
2941
|
+
}
|
|
2942
|
+
isBooleanLiteralType() {
|
|
2943
|
+
return isBooleanLiteralType(this);
|
|
2944
|
+
}
|
|
2945
|
+
isTypeReference() {
|
|
2946
|
+
return isTypeReference(this);
|
|
2947
|
+
}
|
|
2948
|
+
isTupleType() {
|
|
2949
|
+
return this.tupleType;
|
|
2950
|
+
}
|
|
2951
|
+
isTupleTypeTarget() {
|
|
2952
|
+
return this.fixedLength !== undefined;
|
|
2953
|
+
}
|
|
2954
|
+
isIndexType() {
|
|
2955
|
+
return isIndexType(this);
|
|
2956
|
+
}
|
|
2957
|
+
isIndexedAccessType() {
|
|
2958
|
+
return isIndexedAccessType(this);
|
|
2959
|
+
}
|
|
2960
|
+
isConditionalType() {
|
|
2961
|
+
return isConditionalType(this);
|
|
2962
|
+
}
|
|
2963
|
+
isSubstitutionType() {
|
|
2964
|
+
return isSubstitutionType(this);
|
|
2965
|
+
}
|
|
2966
|
+
isTemplateLiteralType() {
|
|
2967
|
+
return isTemplateLiteralType(this);
|
|
2968
|
+
}
|
|
2969
|
+
isStringMappingType() {
|
|
2970
|
+
return isStringMappingType(this);
|
|
2971
|
+
}
|
|
2972
|
+
isTypeParameter() {
|
|
2973
|
+
return isTypeParameter(this);
|
|
2974
|
+
}
|
|
2975
|
+
isMappedType() {
|
|
2976
|
+
return !!(this.flags & TypeFlags.Object) && !!(this.objectFlags & ObjectFlags.Mapped);
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
export function isUnionType(type) {
|
|
2980
|
+
return (type.flags & TypeFlags.Union) !== 0;
|
|
2981
|
+
}
|
|
2982
|
+
export function isIntersectionType(type) {
|
|
2983
|
+
return (type.flags & TypeFlags.Intersection) !== 0;
|
|
2984
|
+
}
|
|
2985
|
+
export function isObjectType(type) {
|
|
2986
|
+
return (type.flags & TypeFlags.Object) !== 0;
|
|
2987
|
+
}
|
|
2988
|
+
export function isClassOrInterfaceType(type) {
|
|
2989
|
+
return isObjectType(type) && (type.objectFlags & ObjectFlags.ClassOrInterface) !== 0;
|
|
2990
|
+
}
|
|
2991
|
+
export function isIntrinsicType(type) {
|
|
2992
|
+
return (type.flags & TypeFlags.Intrinsic) !== 0;
|
|
2993
|
+
}
|
|
2994
|
+
/**
|
|
2995
|
+
* Whether this is the error type — the placeholder the checker produces when a
|
|
2996
|
+
* type cannot be determined (e.g. an unresolved reference). It is an intrinsic
|
|
2997
|
+
* type named `"error"` (this covers both the singleton error type and the
|
|
2998
|
+
* per-alias error types manufactured for unresolved type alias references).
|
|
2999
|
+
*/
|
|
3000
|
+
export function isErrorType(type) {
|
|
3001
|
+
return isIntrinsicType(type) && type.intrinsicName === "error";
|
|
3002
|
+
}
|
|
3003
|
+
export function isLiteralType(type) {
|
|
3004
|
+
return (type.flags & TypeFlags.Literal) !== 0;
|
|
3005
|
+
}
|
|
3006
|
+
export function isStringLiteralType(type) {
|
|
3007
|
+
return (type.flags & TypeFlags.StringLiteral) !== 0;
|
|
3008
|
+
}
|
|
3009
|
+
export function isNumberLiteralType(type) {
|
|
3010
|
+
return (type.flags & TypeFlags.NumberLiteral) !== 0;
|
|
3011
|
+
}
|
|
3012
|
+
export function isBigIntLiteralType(type) {
|
|
3013
|
+
return (type.flags & TypeFlags.BigIntLiteral) !== 0;
|
|
3014
|
+
}
|
|
3015
|
+
export function isBooleanLiteralType(type) {
|
|
3016
|
+
return (type.flags & TypeFlags.BooleanLiteral) !== 0;
|
|
3017
|
+
}
|
|
3018
|
+
export function isTypeReference(type) {
|
|
3019
|
+
return isObjectType(type) && (type.objectFlags & ObjectFlags.Reference) !== 0;
|
|
3020
|
+
}
|
|
3021
|
+
export function isTupleType(type) {
|
|
3022
|
+
return type.isTupleType();
|
|
3023
|
+
}
|
|
3024
|
+
export function isTupleTypeTarget(type) {
|
|
3025
|
+
return type.isTupleTypeTarget();
|
|
3026
|
+
}
|
|
3027
|
+
export function isIndexType(type) {
|
|
3028
|
+
return (type.flags & TypeFlags.Index) !== 0;
|
|
3029
|
+
}
|
|
3030
|
+
export function isIndexedAccessType(type) {
|
|
3031
|
+
return (type.flags & TypeFlags.IndexedAccess) !== 0;
|
|
3032
|
+
}
|
|
3033
|
+
export function isConditionalType(type) {
|
|
3034
|
+
return (type.flags & TypeFlags.Conditional) !== 0;
|
|
3035
|
+
}
|
|
3036
|
+
export function isSubstitutionType(type) {
|
|
3037
|
+
return (type.flags & TypeFlags.Substitution) !== 0;
|
|
3038
|
+
}
|
|
3039
|
+
export function isTemplateLiteralType(type) {
|
|
3040
|
+
return (type.flags & TypeFlags.TemplateLiteral) !== 0;
|
|
3041
|
+
}
|
|
3042
|
+
export function isStringMappingType(type) {
|
|
3043
|
+
return (type.flags & TypeFlags.StringMapping) !== 0;
|
|
3044
|
+
}
|
|
3045
|
+
export function isTypeParameter(type) {
|
|
3046
|
+
return (type.flags & TypeFlags.TypeParameter) !== 0;
|
|
1030
3047
|
}
|
|
1031
3048
|
export class Signature {
|
|
1032
3049
|
flags;
|
|
@@ -1037,15 +3054,17 @@ export class Signature {
|
|
|
1037
3054
|
parameters;
|
|
1038
3055
|
thisParameter;
|
|
1039
3056
|
target;
|
|
1040
|
-
|
|
3057
|
+
returnType;
|
|
3058
|
+
constructor(data, project, objectRegistry) {
|
|
1041
3059
|
this.id = data.id;
|
|
1042
3060
|
this.flags = data.flags;
|
|
1043
3061
|
this.objectRegistry = objectRegistry;
|
|
1044
|
-
this.declaration = data.declaration ? new NodeHandle(data.declaration) : undefined;
|
|
3062
|
+
this.declaration = data.declaration ? new NodeHandle(data.declaration, project) : undefined;
|
|
1045
3063
|
this.typeParameters = data.typeParameters ?? [];
|
|
1046
3064
|
this.parameters = data.parameters ?? [];
|
|
1047
3065
|
this.thisParameter = data.thisParameter;
|
|
1048
3066
|
this.target = data.target;
|
|
3067
|
+
this.returnType = false;
|
|
1049
3068
|
}
|
|
1050
3069
|
async getTypeParameters() {
|
|
1051
3070
|
return this.objectRegistry.fetchTypes(this, "getTypeParametersOfSignature", this.typeParameters);
|
|
@@ -1059,6 +3078,14 @@ export class Signature {
|
|
|
1059
3078
|
async getTarget() {
|
|
1060
3079
|
return this.objectRegistry.fetchSignature(this, "getTargetOfSignature", this.target);
|
|
1061
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
|
+
}
|
|
1062
3089
|
get hasRestParameter() {
|
|
1063
3090
|
return (this.flags & SignatureFlags.HasRestParameter) !== 0;
|
|
1064
3091
|
}
|