@vue/language-server
Advanced tools
Comparing version
#!/usr/bin/env node | ||
// @ts-check | ||
if (process.argv.includes('--version')) { | ||
console.log(require('../package.json').version); | ||
return; | ||
} | ||
else { | ||
require('../node.js'); | ||
} | ||
require('../index.js'); |
@@ -1,3 +0,1 @@ | ||
export * from './lib/types'; | ||
export * from '@volar/language-server/lib/types'; | ||
export * from '@vue/language-service/lib/types'; | ||
export {}; |
328
index.js
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const language_server_1 = require("@volar/language-server"); | ||
const simpleProject_1 = require("@volar/language-server/lib/project/simpleProject"); | ||
const node_1 = require("@volar/language-server/node"); | ||
const language_core_1 = require("@vue/language-core"); | ||
const language_service_1 = require("@vue/language-service"); | ||
const ts = require("typescript"); | ||
const vscode_uri_1 = require("vscode-uri"); | ||
const reactionsAnalyze_1 = require("./lib/reactionsAnalyze"); | ||
const reactionsAnalyzeLS_1 = require("./lib/reactionsAnalyzeLS"); | ||
const connection = (0, node_1.createConnection)(); | ||
const server = (0, node_1.createServer)(connection); | ||
connection.listen(); | ||
connection.onInitialize(params => { | ||
const tsconfigProjects = (0, language_service_1.createUriMap)(); | ||
const file2ProjectInfo = new Map(); | ||
server.fileWatcher.onDidChangeWatchedFiles(({ changes }) => { | ||
for (const change of changes) { | ||
const changeUri = vscode_uri_1.URI.parse(change.uri); | ||
if (tsconfigProjects.has(changeUri)) { | ||
tsconfigProjects.get(changeUri).dispose(); | ||
tsconfigProjects.delete(changeUri); | ||
file2ProjectInfo.clear(); | ||
} | ||
} | ||
}); | ||
let simpleLs; | ||
let tsserverRequestId = 0; | ||
const tsserverRequestHandlers = new Map(); | ||
connection.onNotification('tsserver/response', ([id, res]) => { | ||
tsserverRequestHandlers.get(id)?.(res); | ||
tsserverRequestHandlers.delete(id); | ||
}); | ||
return server.initialize(params, { | ||
setup() { }, | ||
async getLanguageService(uri) { | ||
if (uri.scheme === 'file') { | ||
const fileName = uri.fsPath.replace(/\\/g, '/'); | ||
let projectInfoPromise = file2ProjectInfo.get(fileName); | ||
if (!projectInfoPromise) { | ||
projectInfoPromise = sendTsRequest(ts.server.protocol.CommandTypes.ProjectInfo, { | ||
file: fileName, | ||
needFileNameList: false, | ||
}); | ||
file2ProjectInfo.set(fileName, projectInfoPromise); | ||
} | ||
const projectInfo = await projectInfoPromise; | ||
if (projectInfo) { | ||
const { configFileName } = projectInfo; | ||
let ls = tsconfigProjects.get(vscode_uri_1.URI.file(configFileName)); | ||
if (!ls) { | ||
ls = createLs(server, configFileName); | ||
tsconfigProjects.set(vscode_uri_1.URI.file(configFileName), ls); | ||
} | ||
return ls; | ||
} | ||
} | ||
return simpleLs ??= createLs(server, undefined); | ||
}, | ||
getExistingLanguageServices() { | ||
return Promise.all([ | ||
...tsconfigProjects.values(), | ||
simpleLs, | ||
].filter(promise => !!promise)); | ||
}, | ||
reload() { | ||
for (const ls of tsconfigProjects.values()) { | ||
ls.dispose(); | ||
} | ||
tsconfigProjects.clear(); | ||
if (simpleLs) { | ||
simpleLs.dispose(); | ||
simpleLs = undefined; | ||
} | ||
}, | ||
}, (0, language_service_1.createVueLanguageServicePlugins)(ts, { | ||
collectExtractProps(...args) { | ||
return sendTsRequest('vue:collectExtractProps', args); | ||
}, | ||
getComponentDirectives(...args) { | ||
return sendTsRequest('vue:getComponentDirectives', args); | ||
}, | ||
getComponentEvents(...args) { | ||
return sendTsRequest('vue:getComponentEvents', args); | ||
}, | ||
getComponentNames(...args) { | ||
return sendTsRequest('vue:getComponentNames', args); | ||
}, | ||
getComponentProps(...args) { | ||
return sendTsRequest('vue:getComponentProps', args); | ||
}, | ||
getElementAttrs(...args) { | ||
return sendTsRequest('vue:getElementAttrs', args); | ||
}, | ||
getElementNames(...args) { | ||
return sendTsRequest('vue:getElementNames', args); | ||
}, | ||
getImportPathForFile(...args) { | ||
return sendTsRequest('vue:getImportPathForFile', args); | ||
}, | ||
getPropertiesAtLocation(...args) { | ||
return sendTsRequest('vue:getPropertiesAtLocation', args); | ||
}, | ||
getDocumentHighlights(fileName, position) { | ||
return sendTsRequest('documentHighlights-full', // internal command | ||
{ | ||
file: fileName, | ||
...{ position }, | ||
filesToSearch: [fileName], | ||
}); | ||
}, | ||
async getQuickInfoAtPosition(fileName, { line, character }) { | ||
const result = await sendTsRequest(ts.server.protocol.CommandTypes.Quickinfo, { | ||
file: fileName, | ||
line: line + 1, | ||
offset: character + 1, | ||
}); | ||
return ts.displayPartsToString(result?.displayParts ?? []); | ||
}, | ||
})); | ||
async function sendTsRequest(command, args) { | ||
return await new Promise(resolve => { | ||
const requestId = ++tsserverRequestId; | ||
tsserverRequestHandlers.set(requestId, resolve); | ||
connection.sendNotification('tsserver/request', [requestId, command, args]); | ||
}); | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./lib/types"), exports); | ||
// export types of parent package | ||
__exportStar(require("@volar/language-server/lib/types"), exports); | ||
// only export types of depend packages | ||
__exportStar(require("@vue/language-service/lib/types"), exports); | ||
function createLs(server, tsconfig) { | ||
const commonLine = tsconfig | ||
? (0, language_core_1.createParsedCommandLine)(ts, ts.sys, tsconfig) | ||
: { | ||
options: ts.getDefaultCompilerOptions(), | ||
vueOptions: (0, language_core_1.getDefaultCompilerOptions)(), | ||
}; | ||
const language = (0, language_core_1.createLanguage)([ | ||
{ | ||
getLanguageId: uri => server.documents.get(uri)?.languageId, | ||
}, | ||
(0, language_core_1.createVueLanguagePlugin)(ts, commonLine.options, commonLine.vueOptions, uri => uri.fsPath.replace(/\\/g, '/')), | ||
], (0, language_service_1.createUriMap)(), uri => { | ||
const document = server.documents.get(uri); | ||
if (document) { | ||
language.scripts.set(uri, document.getSnapshot(), document.languageId); | ||
} | ||
else { | ||
language.scripts.delete(uri); | ||
} | ||
}); | ||
return (0, language_service_1.createLanguageService)(language, server.languageServicePlugins, (0, simpleProject_1.createLanguageServiceEnvironment)(server, [...server.workspaceFolders.all]), { vue: { compilerOptions: commonLine.vueOptions } }); | ||
} | ||
}); | ||
connection.onInitialized(server.initialized); | ||
connection.onShutdown(server.shutdown); | ||
connection.onRequest('vue/parseSfc', (params) => { | ||
const document = server.documents.get(vscode_uri_1.URI.parse(params.textDocument.uri)); | ||
if (document) { | ||
return (0, language_core_1.parse)(document.getText()); | ||
} | ||
}); | ||
connection.onRequest('vue/interpolationRanges', async (params) => { | ||
const uri = vscode_uri_1.URI.parse(params.textDocument.uri); | ||
const languageService = await server.project.getLanguageService(uri); | ||
if (languageService) { | ||
const sourceFile = languageService.context.language.scripts.get(uri); | ||
if (sourceFile?.generated) { | ||
const ranges = []; | ||
for (const code of (0, language_core_1.forEachEmbeddedCode)(sourceFile.generated.root)) { | ||
const codeText = code.snapshot.getText(0, code.snapshot.getLength()); | ||
if ((code.id.startsWith('template_inline_ts_') | ||
&& codeText.startsWith('0 +') | ||
&& codeText.endsWith('+ 0;')) | ||
|| (code.id.startsWith('style_') && code.id.endsWith('_inline_ts'))) { | ||
for (const mapping of code.mappings) { | ||
for (let i = 0; i < mapping.sourceOffsets.length; i++) { | ||
ranges.push([ | ||
mapping.sourceOffsets[i], | ||
mapping.sourceOffsets[i] + mapping.lengths[i], | ||
]); | ||
} | ||
} | ||
} | ||
} | ||
return ranges; | ||
} | ||
} | ||
return []; | ||
}); | ||
const cacheDocuments = new Map(); | ||
connection.onRequest('vue/reactionsAnalyze', async (params) => { | ||
if (params.syncDocument) { | ||
const document = language_server_1.TextDocument.create(params.textDocument.uri, params.syncDocument.languageId, 0, params.syncDocument.content); | ||
const snapshot = ts.ScriptSnapshot.fromString(params.syncDocument.content); | ||
cacheDocuments.set(params.textDocument.uri, [document, snapshot]); | ||
} | ||
const uri = vscode_uri_1.URI.parse(params.textDocument.uri); | ||
const languageService = await server.project.getLanguageService(uri); | ||
const sourceScript = languageService.context.language.scripts.get(uri); | ||
let document; | ||
let snapshot; | ||
if (sourceScript) { | ||
document = languageService.context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot); | ||
snapshot = sourceScript.snapshot; | ||
} | ||
else if (cacheDocuments.has(params.textDocument.uri)) { | ||
const [doc, snap] = cacheDocuments.get(params.textDocument.uri); | ||
document = doc; | ||
snapshot = snap; | ||
} | ||
if (!document || !snapshot) { | ||
return; | ||
} | ||
let offset = document.offsetAt(params.position); | ||
if (sourceScript?.generated) { | ||
const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root); | ||
if (!serviceScript) { | ||
return; | ||
} | ||
const map = languageService.context.language.maps.get(serviceScript.code, sourceScript); | ||
let embeddedOffset; | ||
for (const [mapped, mapping] of map.toGeneratedLocation(offset)) { | ||
if ((0, language_core_1.isReferencesEnabled)(mapping.data)) { | ||
embeddedOffset = mapped; | ||
break; | ||
} | ||
} | ||
if (embeddedOffset === undefined) { | ||
return; | ||
} | ||
offset = embeddedOffset; | ||
const embeddedUri = languageService.context.encodeEmbeddedDocumentUri(sourceScript.id, serviceScript.code.id); | ||
document = languageService.context.documents.get(embeddedUri, serviceScript.code.languageId, serviceScript.code.snapshot); | ||
snapshot = serviceScript.code.snapshot; | ||
} | ||
const { languageService: tsLs, fileName } = (0, reactionsAnalyzeLS_1.getLanguageService)(ts, snapshot, document.languageId); | ||
const result = (0, reactionsAnalyze_1.analyze)(ts, tsLs, fileName, offset); | ||
if (!result) { | ||
return; | ||
} | ||
const subscribers = []; | ||
const dependencies = []; | ||
if (sourceScript?.generated) { | ||
const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(sourceScript.generated.root); | ||
if (!serviceScript) { | ||
return; | ||
} | ||
const docs = [ | ||
languageService.context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot), | ||
document, | ||
languageService.context.language.maps.get(serviceScript.code, sourceScript), | ||
]; | ||
for (const dependency of result.dependencies) { | ||
let start = document.positionAt(dependency.getStart(result.sourceFile)); | ||
let end = document.positionAt(dependency.getEnd()); | ||
if (ts.isBlock(dependency) && dependency.statements.length) { | ||
const { statements } = dependency; | ||
start = document.positionAt(statements[0].getStart(result.sourceFile)); | ||
end = document.positionAt(statements[statements.length - 1].getEnd()); | ||
} | ||
const sourceRange = (0, language_service_1.getSourceRange)(docs, { start, end }); | ||
if (sourceRange) { | ||
dependencies.push(sourceRange); | ||
} | ||
} | ||
for (const subscriber of result.subscribers) { | ||
if (!subscriber.sideEffectInfo) { | ||
continue; | ||
} | ||
let start = document.positionAt(subscriber.sideEffectInfo.handler.getStart(result.sourceFile)); | ||
let end = document.positionAt(subscriber.sideEffectInfo.handler.getEnd()); | ||
if (ts.isBlock(subscriber.sideEffectInfo.handler) && subscriber.sideEffectInfo.handler.statements.length) { | ||
const { statements } = subscriber.sideEffectInfo.handler; | ||
start = document.positionAt(statements[0].getStart(result.sourceFile)); | ||
end = document.positionAt(statements[statements.length - 1].getEnd()); | ||
} | ||
const sourceRange = (0, language_service_1.getSourceRange)(docs, { start, end }); | ||
if (sourceRange) { | ||
subscribers.push(sourceRange); | ||
} | ||
} | ||
} | ||
else { | ||
for (const dependency of result.dependencies) { | ||
let start = document.positionAt(dependency.getStart(result.sourceFile)); | ||
let end = document.positionAt(dependency.getEnd()); | ||
if (ts.isBlock(dependency) && dependency.statements.length) { | ||
const { statements } = dependency; | ||
start = document.positionAt(statements[0].getStart(result.sourceFile)); | ||
end = document.positionAt(statements[statements.length - 1].getEnd()); | ||
} | ||
dependencies.push({ start, end }); | ||
} | ||
for (const subscriber of result.subscribers) { | ||
if (!subscriber.sideEffectInfo) { | ||
continue; | ||
} | ||
let start = document.positionAt(subscriber.sideEffectInfo.handler.getStart(result.sourceFile)); | ||
let end = document.positionAt(subscriber.sideEffectInfo.handler.getEnd()); | ||
if (ts.isBlock(subscriber.sideEffectInfo.handler) && subscriber.sideEffectInfo.handler.statements.length) { | ||
const { statements } = subscriber.sideEffectInfo.handler; | ||
start = document.positionAt(statements[0].getStart(result.sourceFile)); | ||
end = document.positionAt(statements[statements.length - 1].getEnd()); | ||
} | ||
subscribers.push({ start, end }); | ||
} | ||
} | ||
return { | ||
subscribers, | ||
dependencies, | ||
}; | ||
}); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@vue/language-server", | ||
"version": "3.0.0-alpha.10", | ||
"version": "3.0.0-beta.1", | ||
"license": "MIT", | ||
@@ -19,9 +19,5 @@ "files": [ | ||
"dependencies": { | ||
"@volar/language-core": "~2.4.13", | ||
"@volar/language-server": "~2.4.13", | ||
"@volar/test-utils": "~2.4.13", | ||
"@vue/language-core": "3.0.0-alpha.10", | ||
"@vue/language-service": "3.0.0-alpha.10", | ||
"@vue/typescript-plugin": "3.0.0-alpha.10", | ||
"vscode-languageserver-protocol": "^3.17.5", | ||
"@volar/language-server": "2.4.14", | ||
"@vue/language-core": "3.0.0-beta.1", | ||
"@vue/language-service": "3.0.0-beta.1", | ||
"vscode-uri": "^3.0.8" | ||
@@ -33,5 +29,6 @@ }, | ||
"devDependencies": { | ||
"@typescript/server-harness": "latest" | ||
"@typescript/server-harness": "latest", | ||
"@volar/test-utils": "2.4.14" | ||
}, | ||
"gitHead": "28308b4f76cc80c7632f39ae7e0944f1889661a2" | ||
"gitHead": "7a2ea48123679387d7095a81ac49cfc667aeeabb" | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
39519
82.7%5
-44.44%839
98.35%2
100%9
-40%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed