@macroforge/svelte-language-server 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +331 -0
- package/bin/server.js +5 -0
- package/dist/src/importPackage.d.ts +16 -0
- package/dist/src/importPackage.js +76 -0
- package/dist/src/importPackage.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +23 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/DiagnosticsManager.d.ts +20 -0
- package/dist/src/lib/DiagnosticsManager.js +71 -0
- package/dist/src/lib/DiagnosticsManager.js.map +1 -0
- package/dist/src/lib/FallbackWatcher.d.ts +15 -0
- package/dist/src/lib/FallbackWatcher.js +66 -0
- package/dist/src/lib/FallbackWatcher.js.map +1 -0
- package/dist/src/lib/documentHighlight/wordHighlight.d.ts +3 -0
- package/dist/src/lib/documentHighlight/wordHighlight.js +62 -0
- package/dist/src/lib/documentHighlight/wordHighlight.js.map +1 -0
- package/dist/src/lib/documents/Document.d.ts +63 -0
- package/dist/src/lib/documents/Document.js +138 -0
- package/dist/src/lib/documents/Document.js.map +1 -0
- package/dist/src/lib/documents/DocumentBase.d.ts +65 -0
- package/dist/src/lib/documents/DocumentBase.js +69 -0
- package/dist/src/lib/documents/DocumentBase.js.map +1 -0
- package/dist/src/lib/documents/DocumentManager.d.ts +28 -0
- package/dist/src/lib/documents/DocumentManager.js +122 -0
- package/dist/src/lib/documents/DocumentManager.js.map +1 -0
- package/dist/src/lib/documents/DocumentMapper.d.ts +88 -0
- package/dist/src/lib/documents/DocumentMapper.js +258 -0
- package/dist/src/lib/documents/DocumentMapper.js.map +1 -0
- package/dist/src/lib/documents/configLoader.d.ts +80 -0
- package/dist/src/lib/documents/configLoader.js +265 -0
- package/dist/src/lib/documents/configLoader.js.map +1 -0
- package/dist/src/lib/documents/fileCollection.d.ts +41 -0
- package/dist/src/lib/documents/fileCollection.js +87 -0
- package/dist/src/lib/documents/fileCollection.js.map +1 -0
- package/dist/src/lib/documents/index.d.ts +5 -0
- package/dist/src/lib/documents/index.js +22 -0
- package/dist/src/lib/documents/index.js.map +1 -0
- package/dist/src/lib/documents/parseHtml.d.ts +13 -0
- package/dist/src/lib/documents/parseHtml.js +160 -0
- package/dist/src/lib/documents/parseHtml.js.map +1 -0
- package/dist/src/lib/documents/utils.d.ts +105 -0
- package/dist/src/lib/documents/utils.js +410 -0
- package/dist/src/lib/documents/utils.js.map +1 -0
- package/dist/src/lib/foldingRange/indentFolding.d.ts +26 -0
- package/dist/src/lib/foldingRange/indentFolding.js +142 -0
- package/dist/src/lib/foldingRange/indentFolding.js.map +1 -0
- package/dist/src/lib/semanticToken/semanticTokenLegend.d.ts +33 -0
- package/dist/src/lib/semanticToken/semanticTokenLegend.js +37 -0
- package/dist/src/lib/semanticToken/semanticTokenLegend.js.map +1 -0
- package/dist/src/logger.d.ts +9 -0
- package/dist/src/logger.js +28 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/ls-config.d.ts +326 -0
- package/dist/src/ls-config.js +386 -0
- package/dist/src/ls-config.js.map +1 -0
- package/dist/src/plugins/PluginHost.d.ts +68 -0
- package/dist/src/plugins/PluginHost.js +447 -0
- package/dist/src/plugins/PluginHost.js.map +1 -0
- package/dist/src/plugins/css/CSSDocument.d.ts +46 -0
- package/dist/src/plugins/css/CSSDocument.js +78 -0
- package/dist/src/plugins/css/CSSDocument.js.map +1 -0
- package/dist/src/plugins/css/CSSPlugin.d.ts +35 -0
- package/dist/src/plugins/css/CSSPlugin.js +407 -0
- package/dist/src/plugins/css/CSSPlugin.js.map +1 -0
- package/dist/src/plugins/css/FileSystemProvider.d.ts +10 -0
- package/dist/src/plugins/css/FileSystemProvider.js +75 -0
- package/dist/src/plugins/css/FileSystemProvider.js.map +1 -0
- package/dist/src/plugins/css/StyleAttributeDocument.d.ts +41 -0
- package/dist/src/plugins/css/StyleAttributeDocument.js +65 -0
- package/dist/src/plugins/css/StyleAttributeDocument.js.map +1 -0
- package/dist/src/plugins/css/features/getIdClassCompletion.d.ts +19 -0
- package/dist/src/plugins/css/features/getIdClassCompletion.js +56 -0
- package/dist/src/plugins/css/features/getIdClassCompletion.js.map +1 -0
- package/dist/src/plugins/css/features/svelte-selectors.d.ts +2 -0
- package/dist/src/plugins/css/features/svelte-selectors.js +18 -0
- package/dist/src/plugins/css/features/svelte-selectors.js.map +1 -0
- package/dist/src/plugins/css/global-vars.d.ts +16 -0
- package/dist/src/plugins/css/global-vars.js +82 -0
- package/dist/src/plugins/css/global-vars.js.map +1 -0
- package/dist/src/plugins/css/service.d.ts +5 -0
- package/dist/src/plugins/css/service.js +66 -0
- package/dist/src/plugins/css/service.js.map +1 -0
- package/dist/src/plugins/documentContext.d.ts +3 -0
- package/dist/src/plugins/documentContext.js +36 -0
- package/dist/src/plugins/documentContext.js.map +1 -0
- package/dist/src/plugins/html/HTMLPlugin.d.ts +36 -0
- package/dist/src/plugins/html/HTMLPlugin.js +363 -0
- package/dist/src/plugins/html/HTMLPlugin.js.map +1 -0
- package/dist/src/plugins/html/dataProvider.d.ts +1 -0
- package/dist/src/plugins/html/dataProvider.js +481 -0
- package/dist/src/plugins/html/dataProvider.js.map +1 -0
- package/dist/src/plugins/index.d.ts +7 -0
- package/dist/src/plugins/index.js +24 -0
- package/dist/src/plugins/index.js.map +1 -0
- package/dist/src/plugins/interfaces.d.ts +132 -0
- package/dist/src/plugins/interfaces.js +3 -0
- package/dist/src/plugins/interfaces.js.map +1 -0
- package/dist/src/plugins/svelte/SvelteDocument.d.ts +98 -0
- package/dist/src/plugins/svelte/SvelteDocument.js +318 -0
- package/dist/src/plugins/svelte/SvelteDocument.js.map +1 -0
- package/dist/src/plugins/svelte/SveltePlugin.d.ts +24 -0
- package/dist/src/plugins/svelte/SveltePlugin.js +306 -0
- package/dist/src/plugins/svelte/SveltePlugin.js.map +1 -0
- package/dist/src/plugins/svelte/features/SvelteTags.d.ts +28 -0
- package/dist/src/plugins/svelte/features/SvelteTags.js +136 -0
- package/dist/src/plugins/svelte/features/SvelteTags.js.map +1 -0
- package/dist/src/plugins/svelte/features/getCodeActions/getQuickfixes.d.ts +11 -0
- package/dist/src/plugins/svelte/features/getCodeActions/getQuickfixes.js +140 -0
- package/dist/src/plugins/svelte/features/getCodeActions/getQuickfixes.js.map +1 -0
- package/dist/src/plugins/svelte/features/getCodeActions/getRefactorings.d.ts +9 -0
- package/dist/src/plugins/svelte/features/getCodeActions/getRefactorings.js +140 -0
- package/dist/src/plugins/svelte/features/getCodeActions/getRefactorings.js.map +1 -0
- package/dist/src/plugins/svelte/features/getCodeActions/index.d.ts +4 -0
- package/dist/src/plugins/svelte/features/getCodeActions/index.js +19 -0
- package/dist/src/plugins/svelte/features/getCodeActions/index.js.map +1 -0
- package/dist/src/plugins/svelte/features/getCompletions.d.ts +4 -0
- package/dist/src/plugins/svelte/features/getCompletions.js +184 -0
- package/dist/src/plugins/svelte/features/getCompletions.js.map +1 -0
- package/dist/src/plugins/svelte/features/getDiagnostics.d.ts +9 -0
- package/dist/src/plugins/svelte/features/getDiagnostics.js +284 -0
- package/dist/src/plugins/svelte/features/getDiagnostics.js.map +1 -0
- package/dist/src/plugins/svelte/features/getHoverInfo.d.ts +7 -0
- package/dist/src/plugins/svelte/features/getHoverInfo.js +93 -0
- package/dist/src/plugins/svelte/features/getHoverInfo.js.map +1 -0
- package/dist/src/plugins/svelte/features/getModifierData.d.ts +7 -0
- package/dist/src/plugins/svelte/features/getModifierData.js +56 -0
- package/dist/src/plugins/svelte/features/getModifierData.js.map +1 -0
- package/dist/src/plugins/svelte/features/getSelectionRanges.d.ts +3 -0
- package/dist/src/plugins/svelte/features/getSelectionRanges.js +46 -0
- package/dist/src/plugins/svelte/features/getSelectionRanges.js.map +1 -0
- package/dist/src/plugins/svelte/features/utils.d.ts +5 -0
- package/dist/src/plugins/svelte/features/utils.js +18 -0
- package/dist/src/plugins/svelte/features/utils.js.map +1 -0
- package/dist/src/plugins/typescript/ComponentInfoProvider.d.ts +27 -0
- package/dist/src/plugins/typescript/ComponentInfoProvider.js +116 -0
- package/dist/src/plugins/typescript/ComponentInfoProvider.js.map +1 -0
- package/dist/src/plugins/typescript/DocumentMapper.d.ts +10 -0
- package/dist/src/plugins/typescript/DocumentMapper.js +25 -0
- package/dist/src/plugins/typescript/DocumentMapper.js.map +1 -0
- package/dist/src/plugins/typescript/DocumentSnapshot.d.ts +173 -0
- package/dist/src/plugins/typescript/DocumentSnapshot.js +623 -0
- package/dist/src/plugins/typescript/DocumentSnapshot.js.map +1 -0
- package/dist/src/plugins/typescript/LSAndTSDocResolver.d.ts +100 -0
- package/dist/src/plugins/typescript/LSAndTSDocResolver.js +301 -0
- package/dist/src/plugins/typescript/LSAndTSDocResolver.js.map +1 -0
- package/dist/src/plugins/typescript/SnapshotManager.d.ts +59 -0
- package/dist/src/plugins/typescript/SnapshotManager.js +238 -0
- package/dist/src/plugins/typescript/SnapshotManager.js.map +1 -0
- package/dist/src/plugins/typescript/TypeScriptPlugin.d.ts +65 -0
- package/dist/src/plugins/typescript/TypeScriptPlugin.js +332 -0
- package/dist/src/plugins/typescript/TypeScriptPlugin.js.map +1 -0
- package/dist/src/plugins/typescript/features/CallHierarchyProvider.d.ts +24 -0
- package/dist/src/plugins/typescript/features/CallHierarchyProvider.js +325 -0
- package/dist/src/plugins/typescript/features/CallHierarchyProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/CodeActionsProvider.d.ts +72 -0
- package/dist/src/plugins/typescript/features/CodeActionsProvider.js +1030 -0
- package/dist/src/plugins/typescript/features/CodeActionsProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/CodeLensProvider.d.ts +28 -0
- package/dist/src/plugins/typescript/features/CodeLensProvider.js +205 -0
- package/dist/src/plugins/typescript/features/CodeLensProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/CompletionProvider.d.ts +57 -0
- package/dist/src/plugins/typescript/features/CompletionProvider.js +791 -0
- package/dist/src/plugins/typescript/features/CompletionProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/DiagnosticsProvider.d.ts +36 -0
- package/dist/src/plugins/typescript/features/DiagnosticsProvider.js +497 -0
- package/dist/src/plugins/typescript/features/DiagnosticsProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/DocumentHighlightProvider.d.ts +17 -0
- package/dist/src/plugins/typescript/features/DocumentHighlightProvider.js +211 -0
- package/dist/src/plugins/typescript/features/DocumentHighlightProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/FindComponentReferencesProvider.d.ts +9 -0
- package/dist/src/plugins/typescript/features/FindComponentReferencesProvider.js +66 -0
- package/dist/src/plugins/typescript/features/FindComponentReferencesProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/FindFileReferencesProvider.d.ts +9 -0
- package/dist/src/plugins/typescript/features/FindFileReferencesProvider.js +38 -0
- package/dist/src/plugins/typescript/features/FindFileReferencesProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/FindReferencesProvider.d.ts +20 -0
- package/dist/src/plugins/typescript/features/FindReferencesProvider.js +149 -0
- package/dist/src/plugins/typescript/features/FindReferencesProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/FoldingRangeProvider.d.ts +28 -0
- package/dist/src/plugins/typescript/features/FoldingRangeProvider.js +247 -0
- package/dist/src/plugins/typescript/features/FoldingRangeProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/HoverProvider.d.ts +11 -0
- package/dist/src/plugins/typescript/features/HoverProvider.js +75 -0
- package/dist/src/plugins/typescript/features/HoverProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/ImplementationProvider.d.ts +9 -0
- package/dist/src/plugins/typescript/features/ImplementationProvider.js +47 -0
- package/dist/src/plugins/typescript/features/ImplementationProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/InlayHintProvider.d.ts +22 -0
- package/dist/src/plugins/typescript/features/InlayHintProvider.js +225 -0
- package/dist/src/plugins/typescript/features/InlayHintProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/RenameProvider.d.ts +53 -0
- package/dist/src/plugins/typescript/features/RenameProvider.js +423 -0
- package/dist/src/plugins/typescript/features/RenameProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/SelectionRangeProvider.d.ts +18 -0
- package/dist/src/plugins/typescript/features/SelectionRangeProvider.js +62 -0
- package/dist/src/plugins/typescript/features/SelectionRangeProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/SemanticTokensProvider.d.ts +15 -0
- package/dist/src/plugins/typescript/features/SemanticTokensProvider.js +116 -0
- package/dist/src/plugins/typescript/features/SemanticTokensProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/SignatureHelpProvider.d.ts +22 -0
- package/dist/src/plugins/typescript/features/SignatureHelpProvider.js +110 -0
- package/dist/src/plugins/typescript/features/SignatureHelpProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/TypeDefinitionProvider.d.ts +9 -0
- package/dist/src/plugins/typescript/features/TypeDefinitionProvider.js +35 -0
- package/dist/src/plugins/typescript/features/TypeDefinitionProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/UpdateImportsProvider.d.ts +11 -0
- package/dist/src/plugins/typescript/features/UpdateImportsProvider.js +109 -0
- package/dist/src/plugins/typescript/features/UpdateImportsProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/WorkspaceSymbolProvider.d.ts +25 -0
- package/dist/src/plugins/typescript/features/WorkspaceSymbolProvider.js +176 -0
- package/dist/src/plugins/typescript/features/WorkspaceSymbolProvider.js.map +1 -0
- package/dist/src/plugins/typescript/features/getDirectiveCommentCompletions.d.ts +13 -0
- package/dist/src/plugins/typescript/features/getDirectiveCommentCompletions.js +58 -0
- package/dist/src/plugins/typescript/features/getDirectiveCommentCompletions.js.map +1 -0
- package/dist/src/plugins/typescript/features/getJsDocTemplateCompletion.d.ts +4 -0
- package/dist/src/plugins/typescript/features/getJsDocTemplateCompletion.js +57 -0
- package/dist/src/plugins/typescript/features/getJsDocTemplateCompletion.js.map +1 -0
- package/dist/src/plugins/typescript/features/utils.d.ts +81 -0
- package/dist/src/plugins/typescript/features/utils.js +331 -0
- package/dist/src/plugins/typescript/features/utils.js.map +1 -0
- package/dist/src/plugins/typescript/macroforgeAugmenter.d.ts +23 -0
- package/dist/src/plugins/typescript/macroforgeAugmenter.js +41 -0
- package/dist/src/plugins/typescript/macroforgeAugmenter.js.map +1 -0
- package/dist/src/plugins/typescript/module-loader.d.ts +28 -0
- package/dist/src/plugins/typescript/module-loader.js +254 -0
- package/dist/src/plugins/typescript/module-loader.js.map +1 -0
- package/dist/src/plugins/typescript/previewer.d.ts +7 -0
- package/dist/src/plugins/typescript/previewer.js +120 -0
- package/dist/src/plugins/typescript/previewer.js.map +1 -0
- package/dist/src/plugins/typescript/service.d.ts +105 -0
- package/dist/src/plugins/typescript/service.js +1073 -0
- package/dist/src/plugins/typescript/service.js.map +1 -0
- package/dist/src/plugins/typescript/serviceCache.d.ts +90 -0
- package/dist/src/plugins/typescript/serviceCache.js +50 -0
- package/dist/src/plugins/typescript/serviceCache.js.map +1 -0
- package/dist/src/plugins/typescript/svelte-ast-utils.d.ts +77 -0
- package/dist/src/plugins/typescript/svelte-ast-utils.js +100 -0
- package/dist/src/plugins/typescript/svelte-ast-utils.js.map +1 -0
- package/dist/src/plugins/typescript/svelte-sys.d.ts +9 -0
- package/dist/src/plugins/typescript/svelte-sys.js +79 -0
- package/dist/src/plugins/typescript/svelte-sys.js.map +1 -0
- package/dist/src/plugins/typescript/utils.d.ts +48 -0
- package/dist/src/plugins/typescript/utils.js +334 -0
- package/dist/src/plugins/typescript/utils.js.map +1 -0
- package/dist/src/server.d.ts +19 -0
- package/dist/src/server.js +434 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/svelte-check.d.ts +65 -0
- package/dist/src/svelte-check.js +288 -0
- package/dist/src/svelte-check.js.map +1 -0
- package/dist/src/utils.d.ts +111 -0
- package/dist/src/utils.js +337 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,1073 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.__resetCache = __resetCache;
|
|
7
|
+
exports.getService = getService;
|
|
8
|
+
exports.forAllServices = forAllServices;
|
|
9
|
+
exports.getServiceForTsconfig = getServiceForTsconfig;
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
12
|
+
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
|
|
13
|
+
const importPackage_1 = require("../../importPackage");
|
|
14
|
+
const configLoader_1 = require("../../lib/documents/configLoader");
|
|
15
|
+
const fileCollection_1 = require("../../lib/documents/fileCollection");
|
|
16
|
+
const logger_1 = require("../../logger");
|
|
17
|
+
const utils_1 = require("../../utils");
|
|
18
|
+
const DocumentSnapshot_1 = require("./DocumentSnapshot");
|
|
19
|
+
const module_loader_1 = require("./module-loader");
|
|
20
|
+
const SnapshotManager_1 = require("./SnapshotManager");
|
|
21
|
+
const utils_2 = require("./utils");
|
|
22
|
+
const serviceCache_1 = require("./serviceCache");
|
|
23
|
+
const svelte2tsx_1 = require("svelte2tsx");
|
|
24
|
+
const macroforgeAugmenter_1 = require("./macroforgeAugmenter");
|
|
25
|
+
var TsconfigSvelteDiagnostics;
|
|
26
|
+
(function (TsconfigSvelteDiagnostics) {
|
|
27
|
+
TsconfigSvelteDiagnostics[TsconfigSvelteDiagnostics["NO_SVELTE_INPUT"] = 100001] = "NO_SVELTE_INPUT";
|
|
28
|
+
})(TsconfigSvelteDiagnostics || (TsconfigSvelteDiagnostics = {}));
|
|
29
|
+
const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; // 20 MB
|
|
30
|
+
const TS_MACROS_PLUGIN_NAME = '@macroforge/typescript-plugin';
|
|
31
|
+
const services = new fileCollection_1.FileMap();
|
|
32
|
+
const serviceSizeMap = new fileCollection_1.FileMap();
|
|
33
|
+
const configWatchers = new fileCollection_1.FileMap();
|
|
34
|
+
const dependedConfigWatchers = new fileCollection_1.FileMap();
|
|
35
|
+
const configPathToDependedProject = new fileCollection_1.FileMap();
|
|
36
|
+
const configFileModifiedTime = new fileCollection_1.FileMap();
|
|
37
|
+
const configFileForOpenFiles = new fileCollection_1.FileMap();
|
|
38
|
+
const pendingReloads = new fileCollection_1.FileSet();
|
|
39
|
+
const documentRegistries = new Map();
|
|
40
|
+
const pendingForAllServices = new Set();
|
|
41
|
+
const parsedTsConfigInfo = new fileCollection_1.FileMap();
|
|
42
|
+
/**
|
|
43
|
+
* For testing only: Reset the cache for services.
|
|
44
|
+
* Try to refactor this some day so that this file provides
|
|
45
|
+
* a setup function which creates all this nicely instead.
|
|
46
|
+
*/
|
|
47
|
+
function __resetCache() {
|
|
48
|
+
services.clear();
|
|
49
|
+
parsedTsConfigInfo.clear();
|
|
50
|
+
serviceSizeMap.clear();
|
|
51
|
+
configFileForOpenFiles.clear();
|
|
52
|
+
}
|
|
53
|
+
async function getService(path, workspaceUris, docContext) {
|
|
54
|
+
const getCanonicalFileName = (0, utils_1.createGetCanonicalFileName)(docContext.tsSystem.useCaseSensitiveFileNames);
|
|
55
|
+
const fileExistsWithCache = (fileName) => {
|
|
56
|
+
return ((parsedTsConfigInfo.has(fileName) && !pendingReloads.has(fileName)) ||
|
|
57
|
+
docContext.tsSystem.fileExists(fileName));
|
|
58
|
+
};
|
|
59
|
+
let tsconfigPath = configFileForOpenFiles.get(path) ??
|
|
60
|
+
(0, utils_2.findTsConfigPath)(path, workspaceUris, fileExistsWithCache, getCanonicalFileName);
|
|
61
|
+
if (tsconfigPath) {
|
|
62
|
+
/**
|
|
63
|
+
* Prevent infinite loop when the project reference is circular
|
|
64
|
+
*/
|
|
65
|
+
const triedTsConfig = new Set();
|
|
66
|
+
const needAssign = !configFileForOpenFiles.has(path);
|
|
67
|
+
let service = await getConfiguredService(tsconfigPath);
|
|
68
|
+
if (!needAssign) {
|
|
69
|
+
return service;
|
|
70
|
+
}
|
|
71
|
+
// First try to find a service whose includes config matches our file
|
|
72
|
+
const defaultService = await findDefaultServiceForFile(service, triedTsConfig);
|
|
73
|
+
if (defaultService) {
|
|
74
|
+
configFileForOpenFiles.set(path, defaultService.tsconfigPath);
|
|
75
|
+
return defaultService;
|
|
76
|
+
}
|
|
77
|
+
// If no such service found, see if the file is part of any existing service indirectly.
|
|
78
|
+
// This can happen if the includes doesn't match the file but it was imported from one of the included files.
|
|
79
|
+
for (const configPath of triedTsConfig) {
|
|
80
|
+
const service = await getConfiguredService(configPath);
|
|
81
|
+
const ls = service.getService();
|
|
82
|
+
if (ls.getProgram()?.getSourceFile(path)) {
|
|
83
|
+
return service;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
tsconfigPath = '';
|
|
87
|
+
}
|
|
88
|
+
// Find closer boundary: workspace uri or node_modules
|
|
89
|
+
const nearestWorkspaceUri = (0, utils_2.getNearestWorkspaceUri)(workspaceUris, path, getCanonicalFileName);
|
|
90
|
+
const lastNodeModulesIdx = path.split('/').lastIndexOf('node_modules') + 2;
|
|
91
|
+
const nearestNodeModulesBoundary = lastNodeModulesIdx === 1
|
|
92
|
+
? undefined
|
|
93
|
+
: path.split('/').slice(0, lastNodeModulesIdx).join('/');
|
|
94
|
+
const nearestBoundary = (nearestNodeModulesBoundary?.length ?? 0) > (nearestWorkspaceUri?.length ?? 0)
|
|
95
|
+
? nearestNodeModulesBoundary
|
|
96
|
+
: nearestWorkspaceUri;
|
|
97
|
+
return getServiceForTsconfig(tsconfigPath, (nearestBoundary && (0, utils_1.urlToPath)(nearestBoundary)) ??
|
|
98
|
+
docContext.tsSystem.getCurrentDirectory(), docContext);
|
|
99
|
+
function getConfiguredService(tsconfigPath) {
|
|
100
|
+
return getServiceForTsconfig(tsconfigPath, (0, path_1.dirname)(tsconfigPath), docContext);
|
|
101
|
+
}
|
|
102
|
+
async function findDefaultServiceForFile(service, triedTsConfig) {
|
|
103
|
+
service.ensureProjectFileUpdates(path);
|
|
104
|
+
if (service.snapshotManager.isProjectFile(path)) {
|
|
105
|
+
return service;
|
|
106
|
+
}
|
|
107
|
+
if (triedTsConfig.has(service.tsconfigPath)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
triedTsConfig.add(service.tsconfigPath);
|
|
111
|
+
// TODO: maybe add support for ts 5.6's ancestor searching
|
|
112
|
+
return findDefaultFromProjectReferences(service, triedTsConfig);
|
|
113
|
+
}
|
|
114
|
+
async function findDefaultFromProjectReferences(service, triedTsConfig) {
|
|
115
|
+
const projectReferences = service.getResolvedProjectReferences();
|
|
116
|
+
if (projectReferences.length === 0) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
let possibleSubPaths = [];
|
|
120
|
+
for (const ref of projectReferences) {
|
|
121
|
+
if (ref.snapshotManager.isProjectFile(path)) {
|
|
122
|
+
return getConfiguredService(ref.configFilePath);
|
|
123
|
+
}
|
|
124
|
+
if (ref.parsedCommandLine.projectReferences?.length) {
|
|
125
|
+
possibleSubPaths.push(ref.configFilePath);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const ref of possibleSubPaths) {
|
|
129
|
+
const subService = await getConfiguredService(ref);
|
|
130
|
+
const defaultService = await findDefaultServiceForFile(subService, triedTsConfig);
|
|
131
|
+
if (defaultService) {
|
|
132
|
+
return defaultService;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function forAllServices(cb) {
|
|
138
|
+
const promise = forAllServicesWorker(cb);
|
|
139
|
+
pendingForAllServices.add(promise);
|
|
140
|
+
await promise;
|
|
141
|
+
pendingForAllServices.delete(promise);
|
|
142
|
+
}
|
|
143
|
+
async function forAllServicesWorker(cb) {
|
|
144
|
+
for (const service of services.values()) {
|
|
145
|
+
cb(await service);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @param tsconfigPath has to be absolute
|
|
150
|
+
* @param docContext
|
|
151
|
+
*/
|
|
152
|
+
async function getServiceForTsconfig(tsconfigPath, workspacePath, docContext) {
|
|
153
|
+
if (tsconfigPath) {
|
|
154
|
+
tsconfigPath = (0, utils_1.normalizePath)(tsconfigPath);
|
|
155
|
+
}
|
|
156
|
+
const tsconfigPathOrWorkspacePath = tsconfigPath || workspacePath;
|
|
157
|
+
const reloading = pendingReloads.has(tsconfigPath);
|
|
158
|
+
let service;
|
|
159
|
+
if (reloading || !services.has(tsconfigPathOrWorkspacePath)) {
|
|
160
|
+
if (reloading) {
|
|
161
|
+
logger_1.Logger.log('Reloading ts service at ', tsconfigPath, ' due to config updated');
|
|
162
|
+
parsedTsConfigInfo.delete(tsconfigPath);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
logger_1.Logger.log('Initialize new ts service at ', tsconfigPath);
|
|
166
|
+
}
|
|
167
|
+
pendingReloads.delete(tsconfigPath);
|
|
168
|
+
const newService = createLanguageService(tsconfigPath, workspacePath, docContext);
|
|
169
|
+
services.set(tsconfigPathOrWorkspacePath, newService);
|
|
170
|
+
service = await newService;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
service = await services.get(tsconfigPathOrWorkspacePath);
|
|
174
|
+
}
|
|
175
|
+
if (pendingForAllServices.size > 0) {
|
|
176
|
+
await Promise.all(pendingForAllServices);
|
|
177
|
+
}
|
|
178
|
+
return service;
|
|
179
|
+
}
|
|
180
|
+
async function createLanguageService(tsconfigPath, workspacePath, docContext) {
|
|
181
|
+
logger_1.Logger.log('createLanguageService: starting for', tsconfigPath);
|
|
182
|
+
const { tsSystem } = docContext;
|
|
183
|
+
const projectConfig = getParsedConfig();
|
|
184
|
+
logger_1.Logger.log('createLanguageService: parsed config');
|
|
185
|
+
const { options: compilerOptions, raw, errors: configErrors } = projectConfig;
|
|
186
|
+
const macroforgePluginSettings = raw?.compilerOptions?.plugins?.find((plugin) => plugin?.name === TS_MACROS_PLUGIN_NAME) ?? {};
|
|
187
|
+
const macroforgeConfig = (0, macroforgeAugmenter_1.createMacroforgeAugmentationConfig)(macroforgePluginSettings && Object.keys(macroforgePluginSettings).length > 0
|
|
188
|
+
? macroforgePluginSettings
|
|
189
|
+
: raw?.['typescript-plugin']);
|
|
190
|
+
ensureMacroforgesPlugin(compilerOptions, tsconfigPath ? (0, path_1.dirname)(tsconfigPath) : workspacePath || process.cwd());
|
|
191
|
+
const allowJs = compilerOptions.allowJs ?? !!compilerOptions.checkJs;
|
|
192
|
+
const virtualDocuments = new fileCollection_1.FileMap(tsSystem.useCaseSensitiveFileNames);
|
|
193
|
+
const getCanonicalFileName = (0, utils_1.createGetCanonicalFileName)(tsSystem.useCaseSensitiveFileNames);
|
|
194
|
+
watchWildCardDirectories(projectConfig);
|
|
195
|
+
logger_1.Logger.log('createLanguageService: creating snapshot manager');
|
|
196
|
+
const snapshotManager = createSnapshotManager(projectConfig, tsconfigPath);
|
|
197
|
+
// Load all configs within the tsconfig scope and the one above so that they are all loaded
|
|
198
|
+
// by the time they need to be accessed synchronously by DocumentSnapshots.
|
|
199
|
+
logger_1.Logger.log('createLanguageService: loading configs');
|
|
200
|
+
await configLoader_1.configLoader.loadConfigs(workspacePath);
|
|
201
|
+
logger_1.Logger.log('createLanguageService: loaded configs');
|
|
202
|
+
const svelteModuleLoader = (0, module_loader_1.createSvelteModuleLoader)(getSnapshot, compilerOptions, tsSystem, typescript_1.default, () => host?.getCompilerHost?.());
|
|
203
|
+
let svelteTsPath;
|
|
204
|
+
/**
|
|
205
|
+
* set and clear during program creation, shouldn't not be cached elsewhere
|
|
206
|
+
*/
|
|
207
|
+
let compilerHost;
|
|
208
|
+
try {
|
|
209
|
+
// For when svelte2tsx/svelte-check is part of node_modules, for example VS Code extension
|
|
210
|
+
svelteTsPath = (0, path_1.dirname)(require.resolve(docContext.ambientTypesSource));
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
// Fall back to dirname
|
|
214
|
+
svelteTsPath = __dirname;
|
|
215
|
+
}
|
|
216
|
+
const sveltePackageInfo = (0, importPackage_1.getPackageInfo)('svelte', tsconfigPath || workspacePath);
|
|
217
|
+
// Svelte 4 has some fixes with regards to parsing the generics attribute.
|
|
218
|
+
// Svelte 5 has new features, but we don't want to add the new compiler into language-tools. In the future it's probably
|
|
219
|
+
// best to shift more and more of this into user's node_modules for better handling of multiple Svelte versions.
|
|
220
|
+
const svelteCompiler = sveltePackageInfo.version.major >= 4
|
|
221
|
+
? (0, importPackage_1.importSvelte)(tsconfigPath || workspacePath)
|
|
222
|
+
: undefined;
|
|
223
|
+
const changedFilesForExportCache = new Set();
|
|
224
|
+
const svelteTsxFilesToOriginalCasing = getSvelteShimFiles();
|
|
225
|
+
let languageServiceReducedMode = false;
|
|
226
|
+
let projectVersion = 0;
|
|
227
|
+
let dirty = projectConfig.fileNames.length > 0;
|
|
228
|
+
let skipSvelteInputCheck = !tsconfigPath;
|
|
229
|
+
const host = {
|
|
230
|
+
log: (message) => logger_1.Logger.debug(`[ts] ${message}`),
|
|
231
|
+
getCompilationSettings: () => compilerOptions,
|
|
232
|
+
getScriptFileNames,
|
|
233
|
+
getScriptVersion: (fileName) => getSnapshotIfExists(fileName)?.version.toString() || '',
|
|
234
|
+
getScriptSnapshot: getSnapshotIfExists,
|
|
235
|
+
getCurrentDirectory: () => workspacePath,
|
|
236
|
+
getDefaultLibFileName: typescript_1.default.getDefaultLibFilePath,
|
|
237
|
+
fileExists: svelteModuleLoader.fileExists,
|
|
238
|
+
readFile: svelteModuleLoader.readFile,
|
|
239
|
+
resolveModuleNames: svelteModuleLoader.resolveModuleNames,
|
|
240
|
+
readDirectory: svelteModuleLoader.readDirectory,
|
|
241
|
+
realpath: tsSystem.realpath,
|
|
242
|
+
getDirectories: tsSystem.getDirectories,
|
|
243
|
+
getProjectReferences: () => projectConfig.projectReferences,
|
|
244
|
+
getParsedCommandLine,
|
|
245
|
+
useCaseSensitiveFileNames: () => tsSystem.useCaseSensitiveFileNames,
|
|
246
|
+
getScriptKind: (fileName) => getSnapshot(fileName).scriptKind,
|
|
247
|
+
getProjectVersion: () => projectVersion.toString(),
|
|
248
|
+
getNewLine: () => tsSystem.newLine,
|
|
249
|
+
resolveTypeReferenceDirectiveReferences: svelteModuleLoader.resolveTypeReferenceDirectiveReferences,
|
|
250
|
+
hasInvalidatedResolutions: svelteModuleLoader.mightHaveInvalidatedResolutions,
|
|
251
|
+
getModuleResolutionCache: svelteModuleLoader.getModuleResolutionCache,
|
|
252
|
+
useSourceOfProjectReferenceRedirect() {
|
|
253
|
+
return !languageServiceReducedMode;
|
|
254
|
+
},
|
|
255
|
+
setCompilerHost: (host) => (compilerHost = host),
|
|
256
|
+
getCompilerHost: () => compilerHost
|
|
257
|
+
};
|
|
258
|
+
const documentRegistry = getOrCreateDocumentRegistry(
|
|
259
|
+
// this should mostly be a singleton while host.getCurrentDirectory() might be the directory where the tsconfig is
|
|
260
|
+
tsSystem.getCurrentDirectory(), tsSystem.useCaseSensitiveFileNames);
|
|
261
|
+
const transformationConfig = {
|
|
262
|
+
parse: svelteCompiler?.parse,
|
|
263
|
+
version: svelteCompiler?.VERSION,
|
|
264
|
+
transformOnTemplateError: docContext.transformOnTemplateError,
|
|
265
|
+
typingsNamespace: raw?.svelteOptions?.namespace || 'svelteHTML'
|
|
266
|
+
};
|
|
267
|
+
const project = initLsCacheProject();
|
|
268
|
+
logger_1.Logger.log('createLanguageService: creating TS language service');
|
|
269
|
+
const languageService = typescript_1.default.createLanguageService(host, documentRegistry);
|
|
270
|
+
logger_1.Logger.log('createLanguageService: created TS language service');
|
|
271
|
+
docContext.globalSnapshotsManager.onChange(scheduleUpdate);
|
|
272
|
+
reduceLanguageServiceCapabilityIfFileSizeTooBig();
|
|
273
|
+
watchConfigFiles(projectConfig.extendedConfigPaths, projectConfig);
|
|
274
|
+
logger_1.Logger.log('createLanguageService: finished');
|
|
275
|
+
return {
|
|
276
|
+
tsconfigPath,
|
|
277
|
+
compilerOptions,
|
|
278
|
+
configErrors,
|
|
279
|
+
getService,
|
|
280
|
+
updateSnapshot,
|
|
281
|
+
deleteSnapshot,
|
|
282
|
+
scheduleProjectFileUpdate,
|
|
283
|
+
updateTsOrJsFile,
|
|
284
|
+
ensureProjectFileUpdates,
|
|
285
|
+
hasFile,
|
|
286
|
+
fileBelongsToProject,
|
|
287
|
+
snapshotManager,
|
|
288
|
+
invalidateModuleCache,
|
|
289
|
+
onAutoImportProviderSettingsChanged,
|
|
290
|
+
onPackageJsonChange,
|
|
291
|
+
getTsConfigSvelteOptions,
|
|
292
|
+
getResolvedProjectReferences,
|
|
293
|
+
openVirtualDocument,
|
|
294
|
+
isShimFiles,
|
|
295
|
+
getProjectConfig,
|
|
296
|
+
dispose
|
|
297
|
+
};
|
|
298
|
+
function createSnapshotManager(parsedCommandLine, configFileName) {
|
|
299
|
+
const cached = configFileName ? parsedTsConfigInfo.get(configFileName) : undefined;
|
|
300
|
+
if (cached?.snapshotManager) {
|
|
301
|
+
return cached.snapshotManager;
|
|
302
|
+
}
|
|
303
|
+
// raw is the tsconfig merged with extending config
|
|
304
|
+
// see: https://github.com/microsoft/TypeScript/blob/08e4f369fbb2a5f0c30dee973618d65e6f7f09f8/src/compiler/commandLineParser.ts#L2537
|
|
305
|
+
return new SnapshotManager_1.SnapshotManager(docContext.globalSnapshotsManager, parsedCommandLine.raw, configFileName ? (0, path_1.dirname)(configFileName) : workspacePath, tsSystem, parsedCommandLine.fileNames.map(utils_1.normalizePath), parsedCommandLine.wildcardDirectories);
|
|
306
|
+
}
|
|
307
|
+
function watchWildCardDirectories(parseCommandLine) {
|
|
308
|
+
const { wildcardDirectories } = parseCommandLine;
|
|
309
|
+
if (!wildcardDirectories || !docContext.watchDirectory) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const canonicalWorkspacePath = getCanonicalFileName(workspacePath);
|
|
313
|
+
const patterns = [];
|
|
314
|
+
Object.entries(wildcardDirectories).forEach(([dir, flags]) => {
|
|
315
|
+
if (
|
|
316
|
+
// already watched
|
|
317
|
+
getCanonicalFileName(dir).startsWith(canonicalWorkspacePath) ||
|
|
318
|
+
!tsSystem.directoryExists(dir)) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
patterns.push({
|
|
322
|
+
baseUri: (0, utils_1.pathToUrl)(dir),
|
|
323
|
+
pattern: (flags & typescript_1.default.WatchDirectoryFlags.Recursive ? `**/` : '') +
|
|
324
|
+
docContext.nonRecursiveWatchPattern
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
docContext.watchDirectory?.(patterns);
|
|
328
|
+
}
|
|
329
|
+
function getService(skipSynchronize) {
|
|
330
|
+
ensureProjectFileUpdates();
|
|
331
|
+
if (!skipSynchronize) {
|
|
332
|
+
updateIfDirty();
|
|
333
|
+
}
|
|
334
|
+
return languageService;
|
|
335
|
+
}
|
|
336
|
+
function deleteSnapshot(filePath) {
|
|
337
|
+
svelteModuleLoader.deleteFromModuleCache(filePath);
|
|
338
|
+
snapshotManager.delete(filePath);
|
|
339
|
+
configFileForOpenFiles.delete(filePath);
|
|
340
|
+
}
|
|
341
|
+
function invalidateModuleCache(filePaths) {
|
|
342
|
+
for (const filePath of filePaths) {
|
|
343
|
+
const normalizedPath = (0, utils_1.normalizePath)(filePath);
|
|
344
|
+
svelteModuleLoader.deleteFromModuleCache(normalizedPath);
|
|
345
|
+
svelteModuleLoader.scheduleResolutionFailedLocationCheck(normalizedPath);
|
|
346
|
+
scheduleUpdate(normalizedPath);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function updateSnapshot(documentOrFilePath) {
|
|
350
|
+
return typeof documentOrFilePath === 'string'
|
|
351
|
+
? updateSnapshotFromFilePath(documentOrFilePath)
|
|
352
|
+
: updateSnapshotFromDocument(documentOrFilePath);
|
|
353
|
+
}
|
|
354
|
+
function updateSnapshotFromDocument(document) {
|
|
355
|
+
const filePath = document.getFilePath() || '';
|
|
356
|
+
const prevSnapshot = snapshotManager.get(filePath);
|
|
357
|
+
if (prevSnapshot?.version === document.version &&
|
|
358
|
+
// In the test, there might be a new document instance with a different openedByClient
|
|
359
|
+
// In that case, Create a new snapshot otherwise the getClientFileNames won't include the new client file
|
|
360
|
+
prevSnapshot.isOpenedInClient() === document.openedByClient) {
|
|
361
|
+
return prevSnapshot;
|
|
362
|
+
}
|
|
363
|
+
const newSnapshot = DocumentSnapshot_1.DocumentSnapshot.fromDocument(document, transformationConfig, macroforgeConfig);
|
|
364
|
+
if (!prevSnapshot) {
|
|
365
|
+
svelteModuleLoader.scheduleResolutionFailedLocationCheck(filePath);
|
|
366
|
+
if (configFileForOpenFiles.get(filePath) === '' && services.size > 1) {
|
|
367
|
+
configFileForOpenFiles.delete(filePath);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
else if (prevSnapshot.scriptKind !== newSnapshot.scriptKind && !allowJs) {
|
|
371
|
+
// if allowJs is false, we need to invalid the cache so that js svelte files can be loaded through module resolution
|
|
372
|
+
svelteModuleLoader.deleteFromModuleCache(filePath);
|
|
373
|
+
configFileForOpenFiles.delete(filePath);
|
|
374
|
+
}
|
|
375
|
+
snapshotManager.set(filePath, newSnapshot);
|
|
376
|
+
return newSnapshot;
|
|
377
|
+
}
|
|
378
|
+
function updateSnapshotFromFilePath(filePath) {
|
|
379
|
+
const prevSnapshot = snapshotManager.get(filePath);
|
|
380
|
+
if (prevSnapshot) {
|
|
381
|
+
return prevSnapshot;
|
|
382
|
+
}
|
|
383
|
+
svelteModuleLoader.scheduleResolutionFailedLocationCheck(filePath);
|
|
384
|
+
return createSnapshot(filePath);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Deleted files will still be requested during the program update.
|
|
388
|
+
* Don't create snapshots for them.
|
|
389
|
+
* Otherwise, deleteUnresolvedResolutionsFromCache won't be called when the file is created again
|
|
390
|
+
*/
|
|
391
|
+
function getSnapshotIfExists(fileName) {
|
|
392
|
+
const svelteFileName = (0, utils_2.ensureRealSvelteFilePath)(fileName);
|
|
393
|
+
let doc = snapshotManager.get(fileName) ?? snapshotManager.get(svelteFileName);
|
|
394
|
+
if (doc) {
|
|
395
|
+
return doc;
|
|
396
|
+
}
|
|
397
|
+
if (!svelteModuleLoader.fileExists(fileName)) {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
// don't invalidate the module cache here
|
|
401
|
+
// this only get called if we already know the file exists
|
|
402
|
+
return createSnapshot(svelteModuleLoader.svelteFileExists(fileName) ? svelteFileName : fileName);
|
|
403
|
+
}
|
|
404
|
+
function getSnapshot(fileName) {
|
|
405
|
+
const svelteFileName = (0, utils_2.ensureRealSvelteFilePath)(fileName);
|
|
406
|
+
let doc = snapshotManager.get(fileName) ?? snapshotManager.get(svelteFileName);
|
|
407
|
+
if (doc) {
|
|
408
|
+
return doc;
|
|
409
|
+
}
|
|
410
|
+
// don't invalidate the module cache here
|
|
411
|
+
// this only get called if we already know the file exists
|
|
412
|
+
return createSnapshot(fileName);
|
|
413
|
+
}
|
|
414
|
+
function createSnapshot(fileName) {
|
|
415
|
+
const doc = DocumentSnapshot_1.DocumentSnapshot.fromFilePath(fileName, docContext.createDocument, transformationConfig, tsSystem, macroforgeConfig);
|
|
416
|
+
snapshotManager.set(fileName, doc);
|
|
417
|
+
return doc;
|
|
418
|
+
}
|
|
419
|
+
function scheduleProjectFileUpdate(watcherNewFiles) {
|
|
420
|
+
if (!snapshotManager.areIgnoredFromNewFileWatch(watcherNewFiles)) {
|
|
421
|
+
scheduleUpdate();
|
|
422
|
+
const info = parsedTsConfigInfo.get(tsconfigPath);
|
|
423
|
+
if (info) {
|
|
424
|
+
info.pendingProjectFileUpdate = true;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (!projectConfig.projectReferences) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
for (const ref of projectConfig.projectReferences) {
|
|
431
|
+
const config = parsedTsConfigInfo.get(ref.path);
|
|
432
|
+
if (config &&
|
|
433
|
+
// handled by the respective service
|
|
434
|
+
!services.has(config.configFilePath) &&
|
|
435
|
+
!config.snapshotManager.areIgnoredFromNewFileWatch(watcherNewFiles)) {
|
|
436
|
+
config.pendingProjectFileUpdate = true;
|
|
437
|
+
scheduleUpdate();
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function ensureProjectFileUpdates(newFile) {
|
|
442
|
+
const info = parsedTsConfigInfo.get(tsconfigPath);
|
|
443
|
+
if (!info) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (newFile &&
|
|
447
|
+
!info.pendingProjectFileUpdate &&
|
|
448
|
+
// no global snapshots yet when initial load pending
|
|
449
|
+
!snapshotManager.isProjectFile(newFile) &&
|
|
450
|
+
!docContext.globalSnapshotsManager.get(newFile)) {
|
|
451
|
+
scheduleProjectFileUpdate([newFile]);
|
|
452
|
+
}
|
|
453
|
+
if (!info.pendingProjectFileUpdate) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const projectFileCountBefore = snapshotManager.getProjectFileNames().length;
|
|
457
|
+
ensureFilesForConfigUpdates(info);
|
|
458
|
+
const projectFileCountAfter = snapshotManager.getProjectFileNames().length;
|
|
459
|
+
if (projectFileCountAfter > projectFileCountBefore) {
|
|
460
|
+
reduceLanguageServiceCapabilityIfFileSizeTooBig();
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
function getScriptFileNames() {
|
|
464
|
+
const projectFiles = languageServiceReducedMode
|
|
465
|
+
? []
|
|
466
|
+
: snapshotManager.getProjectFileNames();
|
|
467
|
+
const canonicalProjectFileNames = new Set(projectFiles.map(getCanonicalFileName));
|
|
468
|
+
// We only assign project files (i.e. those found through includes config) and virtual files to getScriptFileNames.
|
|
469
|
+
// We don't to include other client files otherwise they stay in the program and are never removed
|
|
470
|
+
const clientFiles = tsconfigPath
|
|
471
|
+
? Array.from(virtualDocuments.values())
|
|
472
|
+
.map((v) => v.getFilePath())
|
|
473
|
+
.filter(utils_1.isNotNullOrUndefined)
|
|
474
|
+
: snapshotManager.getClientFileNames();
|
|
475
|
+
return Array.from(new Set([
|
|
476
|
+
...projectFiles,
|
|
477
|
+
// project file is read from the file system so it's more likely to have
|
|
478
|
+
// the correct casing
|
|
479
|
+
...clientFiles.filter((file) => !canonicalProjectFileNames.has(getCanonicalFileName(file))),
|
|
480
|
+
// Use original casing here, too: people could have their VS Code extensions in a case insensitive
|
|
481
|
+
// folder but their project in a case sensitive one; and if we copy the shims into the case sensitive
|
|
482
|
+
// part it would break when canonicalizing it.
|
|
483
|
+
...svelteTsxFilesToOriginalCasing.values()
|
|
484
|
+
]));
|
|
485
|
+
}
|
|
486
|
+
function hasFile(filePath) {
|
|
487
|
+
return snapshotManager.has(filePath);
|
|
488
|
+
}
|
|
489
|
+
function fileBelongsToProject(filePath, isNew) {
|
|
490
|
+
filePath = (0, utils_1.normalizePath)(filePath);
|
|
491
|
+
if (hasFile(filePath)) {
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
if (!isNew) {
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
ensureProjectFileUpdates(filePath);
|
|
498
|
+
return snapshotManager.isProjectFile(filePath);
|
|
499
|
+
}
|
|
500
|
+
function updateTsOrJsFile(fileName, changes) {
|
|
501
|
+
if (!snapshotManager.has(fileName)) {
|
|
502
|
+
svelteModuleLoader.scheduleResolutionFailedLocationCheck(fileName);
|
|
503
|
+
}
|
|
504
|
+
snapshotManager.updateTsOrJsFile(fileName, changes);
|
|
505
|
+
}
|
|
506
|
+
function getParsedConfig() {
|
|
507
|
+
let compilerOptions;
|
|
508
|
+
let parsedConfig;
|
|
509
|
+
let extendedConfigPaths;
|
|
510
|
+
if (tsconfigPath) {
|
|
511
|
+
const info = ensureTsConfigInfoUpToDate(tsconfigPath);
|
|
512
|
+
// tsconfig is either found from file-system or passed from svelte-check
|
|
513
|
+
// so this is already be validated to exist
|
|
514
|
+
if (!info) {
|
|
515
|
+
throw new Error('Failed to get tsconfig: ' + tsconfigPath);
|
|
516
|
+
}
|
|
517
|
+
compilerOptions = info.parsedCommandLine.options;
|
|
518
|
+
parsedConfig = info.parsedCommandLine;
|
|
519
|
+
extendedConfigPaths = info.extendedConfigPaths;
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
const config = parseDefaultCompilerOptions();
|
|
523
|
+
compilerOptions = config.compilerOptions;
|
|
524
|
+
parsedConfig = config.parsedConfig;
|
|
525
|
+
}
|
|
526
|
+
if (!compilerOptions.moduleResolution ||
|
|
527
|
+
compilerOptions.moduleResolution === typescript_1.default.ModuleResolutionKind.Classic) {
|
|
528
|
+
compilerOptions.moduleResolution =
|
|
529
|
+
// NodeJS: up to 4.9, Node10: since 5.0
|
|
530
|
+
typescript_1.default.ModuleResolutionKind.NodeJs ?? typescript_1.default.ModuleResolutionKind.Node10;
|
|
531
|
+
}
|
|
532
|
+
if (!compilerOptions.module ||
|
|
533
|
+
[
|
|
534
|
+
typescript_1.default.ModuleKind.AMD,
|
|
535
|
+
typescript_1.default.ModuleKind.CommonJS,
|
|
536
|
+
typescript_1.default.ModuleKind.ES2015,
|
|
537
|
+
typescript_1.default.ModuleKind.None,
|
|
538
|
+
typescript_1.default.ModuleKind.System,
|
|
539
|
+
typescript_1.default.ModuleKind.UMD
|
|
540
|
+
].includes(compilerOptions.module)) {
|
|
541
|
+
compilerOptions.module = typescript_1.default.ModuleKind.ESNext;
|
|
542
|
+
}
|
|
543
|
+
if (!compilerOptions.target) {
|
|
544
|
+
compilerOptions.target = typescript_1.default.ScriptTarget.Latest;
|
|
545
|
+
}
|
|
546
|
+
else if (typescript_1.default.ScriptTarget.ES2015 > compilerOptions.target) {
|
|
547
|
+
compilerOptions.target = typescript_1.default.ScriptTarget.ES2015;
|
|
548
|
+
}
|
|
549
|
+
// detect which JSX namespace to use (svelte | svelteNative) if not specified or not compatible
|
|
550
|
+
if (!compilerOptions.jsxFactory || !compilerOptions.jsxFactory.startsWith('svelte')) {
|
|
551
|
+
//override if we detect svelte-native
|
|
552
|
+
if (workspacePath) {
|
|
553
|
+
try {
|
|
554
|
+
const svelteNativePkgInfo = (0, importPackage_1.getPackageInfo)('@nativescript-community/svelte-native', workspacePath) ||
|
|
555
|
+
(0, importPackage_1.getPackageInfo)('svelte-native', workspacePath);
|
|
556
|
+
if (svelteNativePkgInfo.path) {
|
|
557
|
+
// For backwards compatibility
|
|
558
|
+
parsedConfig.raw.svelteOptions = parsedConfig.raw.svelteOptions || {};
|
|
559
|
+
parsedConfig.raw.svelteOptions.namespace = 'svelteNative.JSX';
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
catch (e) {
|
|
563
|
+
//we stay regular svelte
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return {
|
|
568
|
+
...parsedConfig,
|
|
569
|
+
fileNames: parsedConfig.fileNames.map(utils_1.normalizePath),
|
|
570
|
+
options: compilerOptions,
|
|
571
|
+
extendedConfigPaths
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function checkSvelteInput(program, config) {
|
|
575
|
+
if (!tsconfigPath || config.raw.references || config.raw.files) {
|
|
576
|
+
return [];
|
|
577
|
+
}
|
|
578
|
+
const configFileName = (0, path_1.basename)(tsconfigPath);
|
|
579
|
+
// Only report to possible nearest config file since referenced project might not be a svelte project
|
|
580
|
+
if (configFileName !== 'tsconfig.json' && configFileName !== 'jsconfig.json') {
|
|
581
|
+
return [];
|
|
582
|
+
}
|
|
583
|
+
const hasSvelteFiles = config.fileNames.some(utils_2.isSvelteFilePath) ||
|
|
584
|
+
program?.getSourceFiles().some((file) => (0, utils_2.isSvelteFilePath)(file.fileName));
|
|
585
|
+
if (hasSvelteFiles) {
|
|
586
|
+
return [];
|
|
587
|
+
}
|
|
588
|
+
const { include, exclude } = config.raw;
|
|
589
|
+
const inputText = JSON.stringify(include);
|
|
590
|
+
const excludeText = JSON.stringify(exclude);
|
|
591
|
+
const svelteConfigDiagnostics = [
|
|
592
|
+
{
|
|
593
|
+
category: typescript_1.default.DiagnosticCategory.Warning,
|
|
594
|
+
code: TsconfigSvelteDiagnostics.NO_SVELTE_INPUT,
|
|
595
|
+
file: undefined,
|
|
596
|
+
start: undefined,
|
|
597
|
+
length: undefined,
|
|
598
|
+
messageText: `No svelte input files were found in config file '${tsconfigPath}'. ` +
|
|
599
|
+
`Did you forget to add svelte files to the 'include' in your ${(0, path_1.basename)(tsconfigPath)}? ` +
|
|
600
|
+
`Specified 'include' paths were '${inputText}' and 'exclude' paths were '${excludeText}'`,
|
|
601
|
+
source: 'svelte'
|
|
602
|
+
}
|
|
603
|
+
];
|
|
604
|
+
return svelteConfigDiagnostics;
|
|
605
|
+
}
|
|
606
|
+
function parseDefaultCompilerOptions() {
|
|
607
|
+
let configJson = {
|
|
608
|
+
compilerOptions: {
|
|
609
|
+
allowJs: true,
|
|
610
|
+
noEmit: true,
|
|
611
|
+
declaration: false,
|
|
612
|
+
skipLibCheck: true,
|
|
613
|
+
maxNodeModuleJsDepth: 2,
|
|
614
|
+
allowSyntheticDefaultImports: true
|
|
615
|
+
},
|
|
616
|
+
// Necessary to not flood the initial files
|
|
617
|
+
// with potentially completely unrelated .ts/.js files:
|
|
618
|
+
include: []
|
|
619
|
+
};
|
|
620
|
+
const parsedConfig = typescript_1.default.parseJsonConfigFileContent(configJson, tsSystem, workspacePath);
|
|
621
|
+
const compilerOptions = {
|
|
622
|
+
...parsedConfig.options,
|
|
623
|
+
target: typescript_1.default.ScriptTarget.Latest,
|
|
624
|
+
allowNonTsExtensions: true,
|
|
625
|
+
moduleResolution: typescript_1.default.ModuleResolutionKind.Node10
|
|
626
|
+
};
|
|
627
|
+
return { compilerOptions, parsedConfig };
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Disable usage of project files.
|
|
631
|
+
* running language service in a reduced mode for
|
|
632
|
+
* large projects with improperly excluded tsconfig.
|
|
633
|
+
*/
|
|
634
|
+
function reduceLanguageServiceCapabilityIfFileSizeTooBig() {
|
|
635
|
+
if (exceedsTotalSizeLimitForNonTsFiles(compilerOptions, tsconfigPath, snapshotManager, tsSystem)) {
|
|
636
|
+
languageService.cleanupSemanticCache();
|
|
637
|
+
languageServiceReducedMode = true;
|
|
638
|
+
if (project) {
|
|
639
|
+
project.languageServiceEnabled = false;
|
|
640
|
+
}
|
|
641
|
+
docContext.notifyExceedSizeLimit?.();
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function dispose() {
|
|
645
|
+
compilerHost = undefined;
|
|
646
|
+
languageService.dispose();
|
|
647
|
+
snapshotManager.dispose();
|
|
648
|
+
configWatchers.get(tsconfigPath)?.close();
|
|
649
|
+
configWatchers.delete(tsconfigPath);
|
|
650
|
+
configFileForOpenFiles.clear();
|
|
651
|
+
docContext.globalSnapshotsManager.removeChangeListener(scheduleUpdate);
|
|
652
|
+
}
|
|
653
|
+
function watchConfigFiles(extendedConfigPaths, parsedCommandLine) {
|
|
654
|
+
const tsconfigDependencies = Array.from(extendedConfigPaths ?? []).concat(parsedCommandLine.projectReferences?.map((r) => r.path) ?? []);
|
|
655
|
+
tsconfigDependencies.forEach((configPath) => {
|
|
656
|
+
let dependedTsConfig = configPathToDependedProject.get(configPath);
|
|
657
|
+
if (!dependedTsConfig) {
|
|
658
|
+
dependedTsConfig = new fileCollection_1.FileSet(tsSystem.useCaseSensitiveFileNames);
|
|
659
|
+
configPathToDependedProject.set(configPath, dependedTsConfig);
|
|
660
|
+
}
|
|
661
|
+
dependedTsConfig.add(tsconfigPath);
|
|
662
|
+
});
|
|
663
|
+
if (!tsSystem.watchFile || !docContext.watchTsConfig) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
if (!configWatchers.has(tsconfigPath) && tsconfigPath) {
|
|
667
|
+
configFileModifiedTime.set(tsconfigPath, tsSystem.getModifiedTime?.(tsconfigPath));
|
|
668
|
+
configWatchers.set(tsconfigPath,
|
|
669
|
+
// for some reason setting the polling interval is necessary, else some error in TS is thrown
|
|
670
|
+
tsSystem.watchFile(tsconfigPath, watchConfigCallback, 1000));
|
|
671
|
+
}
|
|
672
|
+
for (const config of tsconfigDependencies) {
|
|
673
|
+
if (dependedConfigWatchers.has(config)) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
configFileModifiedTime.set(config, tsSystem.getModifiedTime?.(config));
|
|
677
|
+
dependedConfigWatchers.set(config,
|
|
678
|
+
// for some reason setting the polling interval is necessary, else some error in TS is thrown
|
|
679
|
+
tsSystem.watchFile(config, createWatchDependedConfigCallback(docContext), 1000));
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
async function watchConfigCallback(fileName, kind, modifiedTime) {
|
|
683
|
+
if (kind === typescript_1.default.FileWatcherEventKind.Changed &&
|
|
684
|
+
!configFileModified(fileName, modifiedTime ?? tsSystem.getModifiedTime?.(fileName), docContext)) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
dispose();
|
|
688
|
+
if (kind === typescript_1.default.FileWatcherEventKind.Changed) {
|
|
689
|
+
scheduleReload(fileName);
|
|
690
|
+
}
|
|
691
|
+
else if (kind === typescript_1.default.FileWatcherEventKind.Deleted) {
|
|
692
|
+
services.delete(fileName);
|
|
693
|
+
configFileForOpenFiles.clear();
|
|
694
|
+
}
|
|
695
|
+
docContext.onProjectReloaded?.([fileName]);
|
|
696
|
+
docContext.reportConfigError?.({ uri: (0, utils_1.pathToUrl)(fileName), diagnostics: [] });
|
|
697
|
+
}
|
|
698
|
+
function updateIfDirty() {
|
|
699
|
+
if (!dirty) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
svelteModuleLoader.invalidateFailedLocationResolution();
|
|
703
|
+
const oldProgram = project?.program;
|
|
704
|
+
let program;
|
|
705
|
+
try {
|
|
706
|
+
program = languageService.getProgram();
|
|
707
|
+
}
|
|
708
|
+
finally {
|
|
709
|
+
// mark as clean even if the update fails, at least we can still try again next time there is a change
|
|
710
|
+
dirty = false;
|
|
711
|
+
compilerHost = undefined;
|
|
712
|
+
svelteModuleLoader.clearPendingInvalidations();
|
|
713
|
+
}
|
|
714
|
+
if (project) {
|
|
715
|
+
project.program = program;
|
|
716
|
+
}
|
|
717
|
+
if (!skipSvelteInputCheck) {
|
|
718
|
+
const svelteConfigDiagnostics = checkSvelteInput(program, projectConfig);
|
|
719
|
+
const codes = svelteConfigDiagnostics.map((d) => d.code);
|
|
720
|
+
if (!svelteConfigDiagnostics.length) {
|
|
721
|
+
// stop checking once it passed once
|
|
722
|
+
skipSvelteInputCheck = true;
|
|
723
|
+
}
|
|
724
|
+
// report even if empty to clear previous diagnostics
|
|
725
|
+
docContext.reportConfigError?.({
|
|
726
|
+
uri: (0, utils_1.pathToUrl)(tsconfigPath),
|
|
727
|
+
diagnostics: svelteConfigDiagnostics.map((d) => ({
|
|
728
|
+
message: d.messageText,
|
|
729
|
+
range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
|
|
730
|
+
severity: vscode_languageserver_protocol_1.DiagnosticSeverity.Warning,
|
|
731
|
+
source: 'svelte'
|
|
732
|
+
}))
|
|
733
|
+
});
|
|
734
|
+
const new_errors = projectConfig.errors
|
|
735
|
+
.filter((e) => !codes.includes(e.code))
|
|
736
|
+
.concat(svelteConfigDiagnostics);
|
|
737
|
+
projectConfig.errors.splice(0, projectConfig.errors.length, ...new_errors);
|
|
738
|
+
}
|
|
739
|
+
// https://github.com/microsoft/TypeScript/blob/23faef92703556567ddbcb9afb893f4ba638fc20/src/server/project.ts#L1624
|
|
740
|
+
// host.getCachedExportInfoMap will create the cache if it doesn't exist
|
|
741
|
+
// so we need to check the property instead
|
|
742
|
+
const exportMapCache = project?.exportMapCache;
|
|
743
|
+
if (!oldProgram || !exportMapCache || exportMapCache.isEmpty()) {
|
|
744
|
+
changedFilesForExportCache.clear();
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
exportMapCache.releaseSymbols();
|
|
748
|
+
// https://github.com/microsoft/TypeScript/blob/941d1543c201e40d87e63c9db04818493afdd9e7/src/server/project.ts#L1731
|
|
749
|
+
// if one file change results in clearing the cache
|
|
750
|
+
// don't continue to check other files, this will mark the cache as usable while it's empty
|
|
751
|
+
for (const fileName of changedFilesForExportCache) {
|
|
752
|
+
const oldFile = oldProgram.getSourceFile(fileName);
|
|
753
|
+
const newFile = program?.getSourceFile(fileName);
|
|
754
|
+
// file for another tsconfig
|
|
755
|
+
if (!oldFile && !newFile) {
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
if (!oldFile || !newFile) {
|
|
759
|
+
// new file or deleted file
|
|
760
|
+
exportMapCache.clear();
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
const cleared = exportMapCache.onFileChanged?.(oldFile, newFile, false);
|
|
764
|
+
if (cleared) {
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
changedFilesForExportCache.clear();
|
|
769
|
+
}
|
|
770
|
+
function scheduleUpdate(triggeredFile) {
|
|
771
|
+
if (triggeredFile) {
|
|
772
|
+
changedFilesForExportCache.add(triggeredFile);
|
|
773
|
+
}
|
|
774
|
+
if (dirty) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
projectVersion++;
|
|
778
|
+
dirty = true;
|
|
779
|
+
}
|
|
780
|
+
function initLsCacheProject() {
|
|
781
|
+
const projectService = docContext.projectService;
|
|
782
|
+
if (!projectService) {
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
// Used by typescript-auto-import-cache to create a lean language service for package.json auto-import.
|
|
786
|
+
const createLanguageServiceForAutoImportProvider = (host) => typescript_1.default.createLanguageService(host, documentRegistry);
|
|
787
|
+
return (0, serviceCache_1.createProject)(host, createLanguageServiceForAutoImportProvider, {
|
|
788
|
+
compilerOptions: compilerOptions,
|
|
789
|
+
projectService: projectService,
|
|
790
|
+
currentDirectory: workspacePath
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function onAutoImportProviderSettingsChanged() {
|
|
794
|
+
project?.onAutoImportProviderSettingsChanged();
|
|
795
|
+
}
|
|
796
|
+
function onPackageJsonChange(packageJsonPath) {
|
|
797
|
+
if (!project) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
if (project.packageJsonsForAutoImport?.has(packageJsonPath)) {
|
|
801
|
+
project.moduleSpecifierCache.clear();
|
|
802
|
+
if (project.autoImportProviderHost) {
|
|
803
|
+
project.autoImportProviderHost.markAsDirty();
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (packageJsonPath.includes('node_modules')) {
|
|
807
|
+
const dir = (0, path_1.dirname)(packageJsonPath);
|
|
808
|
+
const inProgram = project
|
|
809
|
+
.getCurrentProgram()
|
|
810
|
+
?.getSourceFiles()
|
|
811
|
+
.some((file) => file.fileName.includes(dir));
|
|
812
|
+
if (inProgram) {
|
|
813
|
+
host.getModuleSpecifierCache?.().clear();
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
function getTsConfigSvelteOptions() {
|
|
818
|
+
// if there's more options in the future, get it from raw.svelteOptions and normalize it
|
|
819
|
+
return {
|
|
820
|
+
namespace: transformationConfig.typingsNamespace
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
function ensureTsConfigInfoUpToDate(configFilePath) {
|
|
824
|
+
const cached = parsedTsConfigInfo.get(configFilePath);
|
|
825
|
+
if (cached !== undefined) {
|
|
826
|
+
ensureFilesForConfigUpdates(cached);
|
|
827
|
+
return cached;
|
|
828
|
+
}
|
|
829
|
+
const content = tsSystem.fileExists(configFilePath) && tsSystem.readFile(configFilePath);
|
|
830
|
+
if (!content) {
|
|
831
|
+
parsedTsConfigInfo.set(configFilePath, null);
|
|
832
|
+
return null;
|
|
833
|
+
}
|
|
834
|
+
const json = typescript_1.default.parseJsonText(configFilePath, content);
|
|
835
|
+
const extendedConfigPaths = new Set();
|
|
836
|
+
const { extendedConfigCache } = docContext;
|
|
837
|
+
const cacheMonitorProxy = {
|
|
838
|
+
...docContext.extendedConfigCache,
|
|
839
|
+
get(key) {
|
|
840
|
+
extendedConfigPaths.add(key);
|
|
841
|
+
return extendedConfigCache.get(key);
|
|
842
|
+
},
|
|
843
|
+
has(key) {
|
|
844
|
+
extendedConfigPaths.add(key);
|
|
845
|
+
return extendedConfigCache.has(key);
|
|
846
|
+
},
|
|
847
|
+
set(key, value) {
|
|
848
|
+
extendedConfigPaths.add(key);
|
|
849
|
+
return extendedConfigCache.set(key, value);
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
// TypeScript will throw if the parsedCommandLine doesn't include the sourceFile for the config file
|
|
853
|
+
// i.e. it must be directly parse from the json text instead of a javascript object like we do in getParsedConfig
|
|
854
|
+
const parsedCommandLine = typescript_1.default.parseJsonSourceFileConfigFileContent(json, tsSystem, (0, path_1.dirname)(configFilePath),
|
|
855
|
+
/*existingOptions*/ undefined, configFilePath,
|
|
856
|
+
/*resolutionStack*/ undefined, [
|
|
857
|
+
{
|
|
858
|
+
extension: 'svelte',
|
|
859
|
+
isMixedContent: true,
|
|
860
|
+
// Deferred was added in a later TS version, fall back to tsx
|
|
861
|
+
// If Deferred exists, this means that all Svelte files are included
|
|
862
|
+
// in parsedConfig.fileNames
|
|
863
|
+
scriptKind: typescript_1.default.ScriptKind.Deferred ?? typescript_1.default.ScriptKind.TS
|
|
864
|
+
}
|
|
865
|
+
], cacheMonitorProxy);
|
|
866
|
+
parsedCommandLine.options.allowNonTsExtensions = true;
|
|
867
|
+
const snapshotManager = createSnapshotManager(parsedCommandLine, configFilePath);
|
|
868
|
+
const tsconfigInfo = {
|
|
869
|
+
parsedCommandLine,
|
|
870
|
+
snapshotManager,
|
|
871
|
+
pendingProjectFileUpdate: false,
|
|
872
|
+
configFilePath,
|
|
873
|
+
extendedConfigPaths
|
|
874
|
+
};
|
|
875
|
+
parsedTsConfigInfo.set(configFilePath, tsconfigInfo);
|
|
876
|
+
watchConfigFiles(extendedConfigPaths, parsedCommandLine);
|
|
877
|
+
return tsconfigInfo;
|
|
878
|
+
}
|
|
879
|
+
function getParsedCommandLine(configFilePath) {
|
|
880
|
+
return ensureTsConfigInfoUpToDate(configFilePath)?.parsedCommandLine;
|
|
881
|
+
}
|
|
882
|
+
function ensureFilesForConfigUpdates(info) {
|
|
883
|
+
if (info?.pendingProjectFileUpdate) {
|
|
884
|
+
info.pendingProjectFileUpdate = false;
|
|
885
|
+
info.snapshotManager.updateProjectFiles();
|
|
886
|
+
info.parsedCommandLine.fileNames = info.snapshotManager.getProjectFileNames();
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
function getResolvedProjectReferences() {
|
|
890
|
+
if (!tsconfigPath || !projectConfig.projectReferences) {
|
|
891
|
+
return [];
|
|
892
|
+
}
|
|
893
|
+
return projectConfig.projectReferences
|
|
894
|
+
.map((ref) => ensureTsConfigInfoUpToDate((0, utils_1.normalizePath)(ref.path)))
|
|
895
|
+
.filter(utils_1.isNotNullOrUndefined);
|
|
896
|
+
}
|
|
897
|
+
function openVirtualDocument(document) {
|
|
898
|
+
const filePath = document.getFilePath();
|
|
899
|
+
if (!filePath) {
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
virtualDocuments.set(filePath, document);
|
|
903
|
+
configFileForOpenFiles.set(filePath, tsconfigPath || workspacePath);
|
|
904
|
+
updateSnapshot(document);
|
|
905
|
+
scheduleUpdate(filePath);
|
|
906
|
+
}
|
|
907
|
+
function getSvelteShimFiles() {
|
|
908
|
+
const svelteTsxFiles = svelte2tsx_1.internalHelpers.get_global_types(tsSystem, sveltePackageInfo.version.major === 3, sveltePackageInfo.path, svelteTsPath, docContext.isSvelteCheck ? undefined : tsconfigPath || workspacePath);
|
|
909
|
+
const pathToOriginalCasing = new Map();
|
|
910
|
+
for (const file of svelteTsxFiles) {
|
|
911
|
+
const normalizedPath = (0, utils_1.normalizePath)(file);
|
|
912
|
+
pathToOriginalCasing.set(getCanonicalFileName(normalizedPath), normalizedPath);
|
|
913
|
+
}
|
|
914
|
+
return pathToOriginalCasing;
|
|
915
|
+
}
|
|
916
|
+
function isShimFiles(filePath) {
|
|
917
|
+
return svelteTsxFilesToOriginalCasing.has(getCanonicalFileName((0, utils_1.normalizePath)(filePath)));
|
|
918
|
+
}
|
|
919
|
+
function getProjectConfig() {
|
|
920
|
+
return projectConfig;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
function ensureMacroforgesPlugin(compilerOptions, searchPath) {
|
|
924
|
+
const existing = compilerOptions.plugins;
|
|
925
|
+
const plugins = Array.isArray(existing)
|
|
926
|
+
? existing
|
|
927
|
+
: [];
|
|
928
|
+
if (!Array.isArray(existing)) {
|
|
929
|
+
compilerOptions.plugins = plugins;
|
|
930
|
+
}
|
|
931
|
+
if (plugins.some((plugin) => plugin.name === TS_MACROS_PLUGIN_NAME)) {
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
// Always register the plugin so tests and editor startup see it, even if the module
|
|
935
|
+
// resolution check would fail in this environment.
|
|
936
|
+
plugins.push({ name: TS_MACROS_PLUGIN_NAME });
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* adopted from https://github.com/microsoft/TypeScript/blob/3c8e45b304b8572094c5d7fbb9cd768dbf6417c0/src/server/editorServices.ts#L1955
|
|
940
|
+
*/
|
|
941
|
+
function exceedsTotalSizeLimitForNonTsFiles(compilerOptions, tsconfigPath, snapshotManager, tsSystem) {
|
|
942
|
+
if (compilerOptions.disableSizeLimit) {
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
let availableSpace = maxProgramSizeForNonTsFiles;
|
|
946
|
+
serviceSizeMap.set(tsconfigPath, 0);
|
|
947
|
+
serviceSizeMap.forEach((size) => {
|
|
948
|
+
availableSpace -= size;
|
|
949
|
+
});
|
|
950
|
+
let totalNonTsFileSize = 0;
|
|
951
|
+
const fileNames = snapshotManager.getProjectFileNames();
|
|
952
|
+
for (const fileName of fileNames) {
|
|
953
|
+
if ((0, utils_2.hasTsExtensions)(fileName)) {
|
|
954
|
+
continue;
|
|
955
|
+
}
|
|
956
|
+
totalNonTsFileSize += tsSystem.getFileSize?.(fileName) ?? 0;
|
|
957
|
+
if (totalNonTsFileSize > availableSpace) {
|
|
958
|
+
const top5LargestFiles = fileNames
|
|
959
|
+
.filter((name) => !(0, utils_2.hasTsExtensions)(name))
|
|
960
|
+
.map((name) => ({ name, size: tsSystem.getFileSize?.(name) ?? 0 }))
|
|
961
|
+
.sort((a, b) => b.size - a.size)
|
|
962
|
+
.slice(0, 5);
|
|
963
|
+
logger_1.Logger.log(`Non TS file size exceeded limit (${totalNonTsFileSize}). ` +
|
|
964
|
+
`Largest files: ${top5LargestFiles
|
|
965
|
+
.map((file) => `${file.name}:${file.size}`)
|
|
966
|
+
.join(', ')}`);
|
|
967
|
+
return true;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
serviceSizeMap.set(tsconfigPath, totalNonTsFileSize);
|
|
971
|
+
return false;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* shared watcher callback can't be within `createLanguageService`
|
|
975
|
+
* because it would reference the closure
|
|
976
|
+
* So that GC won't drop it and cause memory leaks
|
|
977
|
+
*/
|
|
978
|
+
function createWatchDependedConfigCallback(docContext) {
|
|
979
|
+
return async (fileName, kind, modifiedTime) => {
|
|
980
|
+
if (kind === typescript_1.default.FileWatcherEventKind.Changed &&
|
|
981
|
+
!configFileModified(fileName, modifiedTime ?? docContext.tsSystem.getModifiedTime?.(fileName), docContext)) {
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
const getCanonicalFileName = (0, utils_1.createGetCanonicalFileName)(docContext.tsSystem.useCaseSensitiveFileNames);
|
|
985
|
+
docContext.extendedConfigCache.delete(getCanonicalFileName(fileName));
|
|
986
|
+
// rely on TypeScript internal behavior so delete both just in case
|
|
987
|
+
docContext.extendedConfigCache.delete(fileName);
|
|
988
|
+
const reloadingConfigs = [];
|
|
989
|
+
const promises = Array.from(configPathToDependedProject.get(fileName) ?? []).map(async (config) => {
|
|
990
|
+
reloadingConfigs.push(config);
|
|
991
|
+
const oldService = services.get(config);
|
|
992
|
+
scheduleReload(config);
|
|
993
|
+
(await oldService)?.dispose();
|
|
994
|
+
});
|
|
995
|
+
await Promise.all(promises);
|
|
996
|
+
docContext.onProjectReloaded?.(reloadingConfigs);
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* check if file content is modified instead of attributes changed
|
|
1001
|
+
*/
|
|
1002
|
+
function configFileModified(fileName, modifiedTime, docContext) {
|
|
1003
|
+
const previousModifiedTime = configFileModifiedTime.get(fileName);
|
|
1004
|
+
if (!modifiedTime || !previousModifiedTime) {
|
|
1005
|
+
return true;
|
|
1006
|
+
}
|
|
1007
|
+
if (previousModifiedTime >= modifiedTime) {
|
|
1008
|
+
return false;
|
|
1009
|
+
}
|
|
1010
|
+
configFileModifiedTime.set(fileName, modifiedTime);
|
|
1011
|
+
const oldSourceFile = parsedTsConfigInfo.get(fileName)?.parsedCommandLine?.options.configFile ??
|
|
1012
|
+
docContext.extendedConfigCache.get(fileName)?.extendedResult;
|
|
1013
|
+
if (oldSourceFile &&
|
|
1014
|
+
typeof oldSourceFile === 'object' &&
|
|
1015
|
+
'kind' in oldSourceFile &&
|
|
1016
|
+
typeof oldSourceFile.text === 'string' &&
|
|
1017
|
+
oldSourceFile.text === docContext.tsSystem.readFile(fileName)) {
|
|
1018
|
+
return false;
|
|
1019
|
+
}
|
|
1020
|
+
return true;
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* schedule to the service reload to the next time the
|
|
1024
|
+
* service in requested
|
|
1025
|
+
* if there's still files opened it should be restarted
|
|
1026
|
+
* in the onProjectReloaded hooks
|
|
1027
|
+
*/
|
|
1028
|
+
function scheduleReload(fileName) {
|
|
1029
|
+
// don't delete service from map yet as it could result in a race condition
|
|
1030
|
+
// where a file update is received before the service is reloaded, swallowing the update
|
|
1031
|
+
pendingReloads.add(fileName);
|
|
1032
|
+
}
|
|
1033
|
+
function getOrCreateDocumentRegistry(currentDirectory, useCaseSensitiveFileNames) {
|
|
1034
|
+
// unless it's a multi root workspace, there's only one registry
|
|
1035
|
+
const key = [currentDirectory, useCaseSensitiveFileNames].join('|');
|
|
1036
|
+
let registry = documentRegistries.get(key);
|
|
1037
|
+
if (registry) {
|
|
1038
|
+
return registry;
|
|
1039
|
+
}
|
|
1040
|
+
registry = typescript_1.default.createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory);
|
|
1041
|
+
const acquireDocumentWithKey = registry.acquireDocumentWithKey;
|
|
1042
|
+
registry.acquireDocumentWithKey = (fileName, path, compilationSettingsOrHost, key, scriptSnapshot, version, scriptKind, sourceFileOptions) => {
|
|
1043
|
+
ensureImpliedNodeFormat(compilationSettingsOrHost, fileName, sourceFileOptions);
|
|
1044
|
+
return acquireDocumentWithKey(fileName, path, compilationSettingsOrHost, key, scriptSnapshot, version, scriptKind, sourceFileOptions);
|
|
1045
|
+
};
|
|
1046
|
+
const updateDocumentWithKey = registry.updateDocumentWithKey;
|
|
1047
|
+
registry.updateDocumentWithKey = (fileName, path, compilationSettingsOrHost, key, scriptSnapshot, version, scriptKind, sourceFileOptions) => {
|
|
1048
|
+
ensureImpliedNodeFormat(compilationSettingsOrHost, fileName, sourceFileOptions);
|
|
1049
|
+
return updateDocumentWithKey(fileName, path, compilationSettingsOrHost, key, scriptSnapshot, version, scriptKind, sourceFileOptions);
|
|
1050
|
+
};
|
|
1051
|
+
documentRegistries.set(key, registry);
|
|
1052
|
+
return registry;
|
|
1053
|
+
function ensureImpliedNodeFormat(compilationSettingsOrHost, fileName, sourceFileOptions) {
|
|
1054
|
+
const compilationSettings = getCompilationSettings(compilationSettingsOrHost);
|
|
1055
|
+
const host = compilationSettingsOrHost === compilationSettings
|
|
1056
|
+
? undefined
|
|
1057
|
+
: compilationSettingsOrHost;
|
|
1058
|
+
if (host &&
|
|
1059
|
+
(0, utils_2.isSvelteFilePath)(fileName) &&
|
|
1060
|
+
typeof sourceFileOptions === 'object' &&
|
|
1061
|
+
!sourceFileOptions.impliedNodeFormat) {
|
|
1062
|
+
const format = typescript_1.default.getImpliedNodeFormatForFile((0, utils_2.toVirtualSvelteFilePath)(fileName), host?.getCompilerHost?.()?.getModuleResolutionCache?.()?.getPackageJsonInfoCache(), host, compilationSettings);
|
|
1063
|
+
sourceFileOptions.impliedNodeFormat = format;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
function getCompilationSettings(settingsOrHost) {
|
|
1067
|
+
if (typeof settingsOrHost.getCompilationSettings === 'function') {
|
|
1068
|
+
return settingsOrHost.getCompilationSettings();
|
|
1069
|
+
}
|
|
1070
|
+
return settingsOrHost;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
//# sourceMappingURL=service.js.map
|