UNPKG

svelte-language-server

Version:
332 lines 18.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TypeScriptPlugin = void 0; const typescript_1 = __importDefault(require("typescript")); const vscode_languageserver_1 = require("vscode-languageserver"); const documents_1 = require("../../lib/documents"); const utils_1 = require("../../utils"); const SnapshotManager_1 = require("./SnapshotManager"); const CodeActionsProvider_1 = require("./features/CodeActionsProvider"); const CompletionProvider_1 = require("./features/CompletionProvider"); const DiagnosticsProvider_1 = require("./features/DiagnosticsProvider"); const FindComponentReferencesProvider_1 = require("./features/FindComponentReferencesProvider"); const FindFileReferencesProvider_1 = require("./features/FindFileReferencesProvider"); const FindReferencesProvider_1 = require("./features/FindReferencesProvider"); const FoldingRangeProvider_1 = require("./features/FoldingRangeProvider"); const HoverProvider_1 = require("./features/HoverProvider"); const ImplementationProvider_1 = require("./features/ImplementationProvider"); const InlayHintProvider_1 = require("./features/InlayHintProvider"); const RenameProvider_1 = require("./features/RenameProvider"); const SelectionRangeProvider_1 = require("./features/SelectionRangeProvider"); const SemanticTokensProvider_1 = require("./features/SemanticTokensProvider"); const SignatureHelpProvider_1 = require("./features/SignatureHelpProvider"); const TypeDefinitionProvider_1 = require("./features/TypeDefinitionProvider"); const UpdateImportsProvider_1 = require("./features/UpdateImportsProvider"); const getDirectiveCommentCompletions_1 = require("./features/getDirectiveCommentCompletions"); const utils_2 = require("./features/utils"); const DocumentHighlightProvider_1 = require("./features/DocumentHighlightProvider"); const svelte_ast_utils_1 = require("./svelte-ast-utils"); const utils_3 = require("./utils"); const CallHierarchyProvider_1 = require("./features/CallHierarchyProvider"); const CodeLensProvider_1 = require("./features/CodeLensProvider"); const WorkspaceSymbolProvider_1 = require("./features/WorkspaceSymbolProvider"); class TypeScriptPlugin { constructor(configManager, lsAndTsDocResolver, workspaceUris, documentManager) { this.__name = 'ts'; this.configManager = configManager; this.documentManager = documentManager; this.lsAndTsDocResolver = lsAndTsDocResolver; this.completionProvider = new CompletionProvider_1.CompletionsProviderImpl(this.lsAndTsDocResolver, this.configManager); this.codeActionsProvider = new CodeActionsProvider_1.CodeActionsProviderImpl(this.lsAndTsDocResolver, this.completionProvider, configManager); this.updateImportsProvider = new UpdateImportsProvider_1.UpdateImportsProviderImpl(this.lsAndTsDocResolver, typescript_1.default.sys.useCaseSensitiveFileNames); this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.lsAndTsDocResolver, configManager); this.renameProvider = new RenameProvider_1.RenameProviderImpl(this.lsAndTsDocResolver, configManager); this.hoverProvider = new HoverProvider_1.HoverProviderImpl(this.lsAndTsDocResolver); this.findFileReferencesProvider = new FindFileReferencesProvider_1.FindFileReferencesProviderImpl(this.lsAndTsDocResolver); this.findComponentReferencesProvider = new FindComponentReferencesProvider_1.FindComponentReferencesProviderImpl(this.lsAndTsDocResolver); this.findReferencesProvider = new FindReferencesProvider_1.FindReferencesProviderImpl(this.lsAndTsDocResolver, this.findComponentReferencesProvider); this.selectionRangeProvider = new SelectionRangeProvider_1.SelectionRangeProviderImpl(this.lsAndTsDocResolver); this.signatureHelpProvider = new SignatureHelpProvider_1.SignatureHelpProviderImpl(this.lsAndTsDocResolver); this.semanticTokensProvider = new SemanticTokensProvider_1.SemanticTokensProviderImpl(this.lsAndTsDocResolver); this.implementationProvider = new ImplementationProvider_1.ImplementationProviderImpl(this.lsAndTsDocResolver); this.typeDefinitionProvider = new TypeDefinitionProvider_1.TypeDefinitionProviderImpl(this.lsAndTsDocResolver); this.inlayHintProvider = new InlayHintProvider_1.InlayHintProviderImpl(this.lsAndTsDocResolver); this.callHierarchyProvider = new CallHierarchyProvider_1.CallHierarchyProviderImpl(this.lsAndTsDocResolver, workspaceUris); this.foldingRangeProvider = new FoldingRangeProvider_1.FoldingRangeProviderImpl(this.lsAndTsDocResolver, configManager); this.codLensProvider = new CodeLensProvider_1.CodeLensProviderImpl(this.lsAndTsDocResolver, this.findReferencesProvider, this.implementationProvider, this.configManager); this.documentHeightProvider = new DocumentHighlightProvider_1.DocumentHighlightProviderImpl(this.lsAndTsDocResolver); this.workspaceSymbolsProvider = new WorkspaceSymbolProvider_1.WorkspaceSymbolsProviderImpl(this.lsAndTsDocResolver, configManager); } async getDiagnostics(document, cancellationToken) { if (!this.featureEnabled('diagnostics')) { return []; } return this.diagnosticsProvider.getDiagnostics(document, cancellationToken); } async doHover(document, position) { if (!this.featureEnabled('hover')) { return null; } return this.hoverProvider.doHover(document, position); } async getDocumentSymbols(document, cancellationToken) { if (!this.featureEnabled('documentSymbols')) { return []; } const { lang, tsDoc } = await this.lsAndTsDocResolver.getLsForSyntheticOperations(document); if (cancellationToken?.isCancellationRequested) { return []; } const navTree = lang.getNavigationTree(tsDoc.filePath); const symbols = []; collectSymbols(navTree, undefined, (symbol) => symbols.push(symbol)); const topContainerName = symbols[0].name; const result = []; for (let symbol of symbols.slice(1)) { if (symbol.containerName === topContainerName) { symbol.containerName = 'script'; } symbol = (0, documents_1.mapSymbolInformationToOriginal)(tsDoc, symbol); if (symbol.location.range.start.line < 0 || symbol.location.range.end.line < 0 || (0, utils_1.isZeroLengthRange)(symbol.location.range) || symbol.name.startsWith('__sveltets_')) { continue; } if ((symbol.kind === vscode_languageserver_1.SymbolKind.Property || symbol.kind === vscode_languageserver_1.SymbolKind.Method) && !(0, utils_3.isInScript)(symbol.location.range.start, document)) { if (symbol.name === 'props' && document.getText().charAt(document.offsetAt(symbol.location.range.start)) !== 'p') { // This is the "props" of a generated component constructor continue; } const node = tsDoc.svelteNodeAt(symbol.location.range.start); if ((node && ((0, svelte_ast_utils_1.isAttributeName)(node) || (0, svelte_ast_utils_1.isAttributeShorthand)(node))) || (0, svelte_ast_utils_1.isEventHandler)(node)) { // This is a html or component property, they are not treated as a new symbol // in JSX and so we do the same for the new transformation. continue; } } if (symbol.name === '<function>') { let name = (0, documents_1.getTextInRange)(symbol.location.range, document.getText()).trimLeft(); if (name.length > 50) { name = name.substring(0, 50) + '...'; } symbol.name = name; } if (symbol.name.startsWith('$$_')) { if (!symbol.name.includes('$on')) { continue; } // on:foo={() => ''} -> $on("foo") callback symbol.name = symbol.name.substring(symbol.name.indexOf('$on')); } result.push(symbol); } return result; function collectSymbols(tree, container, cb) { const start = tree.spans[0]; const end = tree.spans[tree.spans.length - 1]; if (start && end) { cb(vscode_languageserver_1.SymbolInformation.create(tree.text, (0, utils_3.symbolKindFromString)(tree.kind), vscode_languageserver_1.Range.create(tsDoc.positionAt(start.start), tsDoc.positionAt(end.start + end.length)), tsDoc.getURL(), container)); } if (tree.childItems) { for (const child of tree.childItems) { collectSymbols(child, tree.text, cb); } } } } async getCompletions(document, position, completionContext, cancellationToken) { if (!this.featureEnabled('completions')) { return null; } const tsDirectiveCommentCompletions = (0, getDirectiveCommentCompletions_1.getDirectiveCommentCompletions)(position, document, completionContext); const completions = await this.completionProvider.getCompletions(document, position, completionContext, cancellationToken); if (completions && tsDirectiveCommentCompletions) { return vscode_languageserver_1.CompletionList.create(completions.items.concat(tsDirectiveCommentCompletions.items), completions.isIncomplete); } return completions ?? tsDirectiveCommentCompletions; } async resolveCompletion(document, completionItem, cancellationToken) { return this.completionProvider.resolveCompletion(document, completionItem, cancellationToken); } async getDefinitions(document, position) { const { lang, tsDoc, lsContainer } = await this.lsAndTsDocResolver.getLSAndTSDoc(document); const defs = lang.getDefinitionAndBoundSpan(tsDoc.filePath, tsDoc.offsetAt(tsDoc.getGeneratedPosition(position))); if (!defs || !defs.definitions) { return []; } const snapshots = new utils_2.SnapshotMap(this.lsAndTsDocResolver, lsContainer); snapshots.set(tsDoc.filePath, tsDoc); const result = await Promise.all(defs.definitions.map(async (def) => { if ((0, utils_3.isSvelte2tsxShimFile)(def.fileName)) { return; } let snapshot = await snapshots.retrieve(def.fileName); // Go from generated $store to store if user wants to find definition for $store if ((0, utils_2.isTextSpanInGeneratedCode)(snapshot.getFullText(), def.textSpan)) { if (!(0, utils_2.is$storeVariableIn$storeDeclaration)(snapshot.getFullText(), def.textSpan.start)) { return; } // there will be exactly one definition, the store def = lang.getDefinitionAndBoundSpan(tsDoc.filePath, tsDoc.getFullText().indexOf(');', def.textSpan.start) - 1).definitions[0]; snapshot = await snapshots.retrieve(def.fileName); } const defLocation = (0, utils_3.convertToLocationForReferenceOrDefinition)(snapshot, def.textSpan); return vscode_languageserver_1.LocationLink.create(defLocation.uri, defLocation.range, defLocation.range, (0, utils_3.convertToLocationRange)(tsDoc, defs.textSpan)); })); return result.filter(utils_1.isNotNullOrUndefined); } async prepareRename(document, position) { return this.renameProvider.prepareRename(document, position); } async rename(document, position, newName) { return this.renameProvider.rename(document, position, newName); } async getCodeActions(document, range, context, cancellationToken) { if (!this.featureEnabled('codeActions')) { return []; } return this.codeActionsProvider.getCodeActions(document, range, context, cancellationToken); } async resolveCodeAction(document, codeAction, cancellationToken) { return this.codeActionsProvider.resolveCodeAction(document, codeAction, cancellationToken); } async executeCommand(document, command, args) { if (!this.featureEnabled('codeActions')) { return null; } return this.codeActionsProvider.executeCommand(document, command, args); } async updateImports(fileRename) { if (!(this.configManager.enabled('svelte.enable') && this.configManager.enabled('svelte.rename.enable'))) { return null; } return this.updateImportsProvider.updateImports(fileRename); } async findReferences(document, position, context) { return this.findReferencesProvider.findReferences(document, position, context); } async fileReferences(uri) { return this.findFileReferencesProvider.fileReferences(uri); } async findComponentReferences(uri) { return this.findComponentReferencesProvider.findComponentReferences(uri); } async onWatchFileChanges(onWatchFileChangesParas) { const newFiles = []; for (const { fileName, changeType } of onWatchFileChangesParas) { const pathParts = fileName.split(/\/|\\/); const dirPathParts = pathParts.slice(0, pathParts.length - 1); const declarationExtensions = [typescript_1.default.Extension.Dcts, typescript_1.default.Extension.Dts, typescript_1.default.Extension.Dmts]; const canSafelyIgnore = declarationExtensions.every((ext) => !fileName.endsWith(ext)) && SnapshotManager_1.ignoredBuildDirectories.some((dir) => { const index = dirPathParts.indexOf(dir); return ( // Files in .svelte-kit/types should always come through index > 0 && (dir !== '.svelte-kit' || dirPathParts[index + 1] !== 'types')); }); if (canSafelyIgnore) { continue; } const isSvelteFile = (0, utils_3.isSvelteFilePath)(fileName); const isClientSvelteFile = isSvelteFile && this.documentManager.get((0, utils_1.pathToUrl)(fileName))?.openedByClient; if (changeType === vscode_languageserver_1.FileChangeType.Deleted) { if (!isClientSvelteFile) { await this.lsAndTsDocResolver.deleteSnapshot(fileName); } continue; } if (changeType === vscode_languageserver_1.FileChangeType.Created) { newFiles.push(fileName); continue; } if (isSvelteFile) { if (!isClientSvelteFile) { await this.lsAndTsDocResolver.updateExistingSvelteFile(fileName); } continue; } await this.lsAndTsDocResolver.updateExistingTsOrJsFile(fileName); } if (newFiles.length) { await this.lsAndTsDocResolver.updateProjectFiles(newFiles); await this.lsAndTsDocResolver.invalidateModuleCache(newFiles); } } async updateTsOrJsFile(fileName, changes) { await this.lsAndTsDocResolver.updateExistingTsOrJsFile(fileName, changes); } async getSelectionRange(document, position) { if (!this.featureEnabled('selectionRange')) { return null; } return this.selectionRangeProvider.getSelectionRange(document, position); } async getSignatureHelp(document, position, context, cancellationToken) { if (!this.featureEnabled('signatureHelp')) { return null; } return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken); } async getSemanticTokens(textDocument, range, cancellationToken) { if (!this.featureEnabled('semanticTokens')) { return { data: [] }; } return this.semanticTokensProvider.getSemanticTokens(textDocument, range, cancellationToken); } async getImplementation(document, position, cancellationToken) { return this.implementationProvider.getImplementation(document, position, cancellationToken); } async getTypeDefinition(document, position) { return this.typeDefinitionProvider.getTypeDefinition(document, position); } async getInlayHints(document, range, cancellationToken) { if (!this.configManager.enabled('typescript.enable')) { return null; } return this.inlayHintProvider.getInlayHints(document, range, cancellationToken); } prepareCallHierarchy(document, position, cancellationToken) { return this.callHierarchyProvider.prepareCallHierarchy(document, position, cancellationToken); } getIncomingCalls(item, cancellationToken) { return this.callHierarchyProvider.getIncomingCalls(item, cancellationToken); } async getOutgoingCalls(item, cancellationToken) { return this.callHierarchyProvider.getOutgoingCalls(item, cancellationToken); } async getFoldingRanges(document) { return this.foldingRangeProvider.getFoldingRanges(document); } getCodeLens(document) { return this.codLensProvider.getCodeLens(document); } resolveCodeLens(document, codeLensToResolve, cancellationToken) { return this.codLensProvider.resolveCodeLens(document, codeLensToResolve, cancellationToken); } async findDocumentHighlight(document, position) { return this.documentHeightProvider.findDocumentHighlight(document, position); } async getWorkspaceSymbols(query, cancellationToken) { if (!this.featureEnabled('workspaceSymbols')) { return null; } return this.workspaceSymbolsProvider.getWorkspaceSymbols(query, cancellationToken); } featureEnabled(feature) { return (this.configManager.enabled('typescript.enable') && this.configManager.enabled(`typescript.${feature}.enable`)); } } exports.TypeScriptPlugin = TypeScriptPlugin; //# sourceMappingURL=TypeScriptPlugin.js.map