mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-05 20:38:25 +03:00
Push pylance changes to pyright (#4404)
Co-authored-by: Bill Schnurr <bschnurr@microsoft.com> Co-authored-by: HeeJae Chang <hechang@microsoft.com> Co-authored-by: Erik De Bonte <erikd@microsoft.com> Co-authored-by: Rich Chiodo <rchiodo@microsoft.com>
This commit is contained in:
parent
ca078abc07
commit
b78a9e4bd3
536
package-lock.json
generated
536
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -23,18 +23,18 @@
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/yargs": "^16.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^5.43.0",
|
||||
"@typescript-eslint/parser": "^5.43.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||
"@typescript-eslint/parser": "^5.48.0",
|
||||
"detect-indent": "^6.1.0",
|
||||
"eslint": "^8.27.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint": "^8.31.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"glob": "^7.2.3",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"lerna": "^5.6.2",
|
||||
"npm-check-updates": "^16.4.1",
|
||||
"npm-check-updates": "^16.6.2",
|
||||
"p-queue": "^6.6.2",
|
||||
"prettier": "2.7.1",
|
||||
"prettier": "2.8.1",
|
||||
"syncpack": "^5.8.15",
|
||||
"typescript": "~4.4.4",
|
||||
"yargs": "^16.2.0"
|
||||
|
106
packages/pyright-internal/package-lock.json
generated
106
packages/pyright-internal/package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iarna/toml": "2.2.5",
|
||||
"@yarnpkg/fslib": "2.9.0",
|
||||
"@yarnpkg/fslib": "2.10.0",
|
||||
"@yarnpkg/libzip": "2.2.4",
|
||||
"chalk": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
@ -20,11 +20,11 @@
|
||||
"source-map-support": "^0.5.21",
|
||||
"tmp": "^0.2.1",
|
||||
"typescript-char": "^0.0.0",
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageserver": "8.1.0-next.1",
|
||||
"vscode-languageserver-textdocument": "^1.0.7",
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageserver": "8.1.0-next.4",
|
||||
"vscode-languageserver-textdocument": "^1.0.8",
|
||||
"vscode-languageserver-types": "3.17.2",
|
||||
"vscode-uri": "^3.0.6"
|
||||
"vscode-uri": "^3.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/command-line-args": "^5.2.0",
|
||||
@ -1044,9 +1044,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@yarnpkg/fslib": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.9.0.tgz",
|
||||
"integrity": "sha512-PIdwI2z1HFl6aUkketbgUJK3FGRVWVwH1vgHltNe+snJzjlKHMavyIR0fipkAJuHVcac+hzWI1/eMr90rVyMHw==",
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.0.tgz",
|
||||
"integrity": "sha512-eHqvrVlzlhd4owKoLsMRaL4wTGer+r9BXi95u1omHYcAcEQbKnHH3PqYf3j7nxsc8apa09WyA1XNCiiIniFXLg==",
|
||||
"dependencies": {
|
||||
"@yarnpkg/libzip": "^2.2.4",
|
||||
"tslib": "^1.13.0"
|
||||
@ -4185,37 +4185,42 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-jsonrpc": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-FiPG+9TuMIga3t+kkalQytwqMtJu1djI+Pq+Ut2tvAJpcNHDJ0PYdjFv5mgEvTEJLujrYwjWHVkNe+XfHPBD/w==",
|
||||
"version": "8.1.0-next.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.5.tgz",
|
||||
"integrity": "sha512-9l9lB8gXW1kPECKLC5Goc41pFztSCfODY3dvGaNTJ0KfRgwKIUyIhEBSdlWT2IU4uL4Tcl/zcitpb+Lj6QP7aQ==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-u14Rk4JgXI+7iS6AEXI2pNc1dWh/5JEXtaqa4TeBECKJlN+5242mbGBBPaHMOE7sSI1Kh66XhEMZJhPYjUfjHw==",
|
||||
"version": "8.1.0-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.4.tgz",
|
||||
"integrity": "sha512-W+sdV5sgOTgE1bmEBdCrCpjfYIwD7f0ykwoPOTkvaNFdsgbMIvq4VZLjGMVnFR7U2tPa/w0Kn7lXodlSJudNmQ==",
|
||||
"dependencies": {
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
},
|
||||
"bin": {
|
||||
"installServerIntoExtension": "bin/installServerIntoExtension"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-protocol": {
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-vgjvPE0zox+1Fi4ljsSFJ+B3g8wGNbuAEEdulueVdv+R2VHtc06+dgxhWiG4LKPqXwjPDmiuxCnvd2xk3fzTTw==",
|
||||
"version": "3.17.3-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.4.tgz",
|
||||
"integrity": "sha512-G6XrjZGSe2LIo7uDa860JKX97sLKc1vQF4AU4SW8DI7NNVKxnCB+vEs8gYHmle7kD9v13PvFkDCBD5ApeONGNQ==",
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageserver-types": "3.17.2"
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageserver-types": "3.17.3-next.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-protocol/node_modules/vscode-languageserver-types": {
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-i7HXZs5CdNibVHXZORZw9m5Bm0mfXiGhD/tZv6f7arBtz4iatgiiHu2qInxn0fKeahhMJoBbp6irhsL9+E3UAA=="
|
||||
},
|
||||
"node_modules/vscode-languageserver-textdocument": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.7.tgz",
|
||||
"integrity": "sha512-bFJH7UQxlXT8kKeyiyu41r22jCZXG8kuuVVA33OEJn1diWOZK5n8zBSPZFHVBOu8kXZ6h0LIRhf5UnCo61J4Hg=="
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz",
|
||||
"integrity": "sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q=="
|
||||
},
|
||||
"node_modules/vscode-languageserver-types": {
|
||||
"version": "3.17.2",
|
||||
@ -4223,9 +4228,9 @@
|
||||
"integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA=="
|
||||
},
|
||||
"node_modules/vscode-uri": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz",
|
||||
"integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ=="
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz",
|
||||
"integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA=="
|
||||
},
|
||||
"node_modules/w3c-hr-time": {
|
||||
"version": "1.0.2",
|
||||
@ -5246,9 +5251,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@yarnpkg/fslib": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.9.0.tgz",
|
||||
"integrity": "sha512-PIdwI2z1HFl6aUkketbgUJK3FGRVWVwH1vgHltNe+snJzjlKHMavyIR0fipkAJuHVcac+hzWI1/eMr90rVyMHw==",
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.0.tgz",
|
||||
"integrity": "sha512-eHqvrVlzlhd4owKoLsMRaL4wTGer+r9BXi95u1omHYcAcEQbKnHH3PqYf3j7nxsc8apa09WyA1XNCiiIniFXLg==",
|
||||
"requires": {
|
||||
"@yarnpkg/libzip": "^2.2.4",
|
||||
"tslib": "^1.13.0"
|
||||
@ -7597,31 +7602,38 @@
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-FiPG+9TuMIga3t+kkalQytwqMtJu1djI+Pq+Ut2tvAJpcNHDJ0PYdjFv5mgEvTEJLujrYwjWHVkNe+XfHPBD/w=="
|
||||
"version": "8.1.0-next.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.5.tgz",
|
||||
"integrity": "sha512-9l9lB8gXW1kPECKLC5Goc41pFztSCfODY3dvGaNTJ0KfRgwKIUyIhEBSdlWT2IU4uL4Tcl/zcitpb+Lj6QP7aQ=="
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-u14Rk4JgXI+7iS6AEXI2pNc1dWh/5JEXtaqa4TeBECKJlN+5242mbGBBPaHMOE7sSI1Kh66XhEMZJhPYjUfjHw==",
|
||||
"version": "8.1.0-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.4.tgz",
|
||||
"integrity": "sha512-W+sdV5sgOTgE1bmEBdCrCpjfYIwD7f0ykwoPOTkvaNFdsgbMIvq4VZLjGMVnFR7U2tPa/w0Kn7lXodlSJudNmQ==",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-vgjvPE0zox+1Fi4ljsSFJ+B3g8wGNbuAEEdulueVdv+R2VHtc06+dgxhWiG4LKPqXwjPDmiuxCnvd2xk3fzTTw==",
|
||||
"version": "3.17.3-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.4.tgz",
|
||||
"integrity": "sha512-G6XrjZGSe2LIo7uDa860JKX97sLKc1vQF4AU4SW8DI7NNVKxnCB+vEs8gYHmle7kD9v13PvFkDCBD5ApeONGNQ==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageserver-types": "3.17.2"
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageserver-types": "3.17.3-next.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-i7HXZs5CdNibVHXZORZw9m5Bm0mfXiGhD/tZv6f7arBtz4iatgiiHu2qInxn0fKeahhMJoBbp6irhsL9+E3UAA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-textdocument": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.7.tgz",
|
||||
"integrity": "sha512-bFJH7UQxlXT8kKeyiyu41r22jCZXG8kuuVVA33OEJn1diWOZK5n8zBSPZFHVBOu8kXZ6h0LIRhf5UnCo61J4Hg=="
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz",
|
||||
"integrity": "sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q=="
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.17.2",
|
||||
@ -7629,9 +7641,9 @@
|
||||
"integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz",
|
||||
"integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ=="
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz",
|
||||
"integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA=="
|
||||
},
|
||||
"w3c-hr-time": {
|
||||
"version": "1.0.2",
|
||||
|
@ -16,7 +16,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "2.2.5",
|
||||
"@yarnpkg/fslib": "2.9.0",
|
||||
"@yarnpkg/fslib": "2.10.0",
|
||||
"@yarnpkg/libzip": "2.2.4",
|
||||
"chalk": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
@ -26,11 +26,11 @@
|
||||
"source-map-support": "^0.5.21",
|
||||
"tmp": "^0.2.1",
|
||||
"typescript-char": "^0.0.0",
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageserver": "8.1.0-next.1",
|
||||
"vscode-languageserver-textdocument": "^1.0.7",
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageserver": "8.1.0-next.4",
|
||||
"vscode-languageserver-textdocument": "^1.0.8",
|
||||
"vscode-languageserver-types": "3.17.2",
|
||||
"vscode-uri": "^3.0.6"
|
||||
"vscode-uri": "^3.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/command-line-args": "^5.2.0",
|
||||
|
@ -368,9 +368,9 @@ export class ImportResolver {
|
||||
sourceFilePath: string,
|
||||
execEnv: ExecutionEnvironment,
|
||||
moduleDescriptor: ImportedModuleDescriptor
|
||||
): Set<string> {
|
||||
): Map<string, string> {
|
||||
const importFailureInfo: string[] = [];
|
||||
const suggestions = new Set<string>();
|
||||
const suggestions = new Map<string, string>();
|
||||
|
||||
// Is it a relative import?
|
||||
if (moduleDescriptor.leadingDots > 0) {
|
||||
@ -707,6 +707,11 @@ export class ImportResolver {
|
||||
return this._getStdlibTypeshedPath(execEnv, unused);
|
||||
}
|
||||
|
||||
getTypeshedThirdPartyPath(execEnv: ExecutionEnvironment) {
|
||||
const unused: string[] = [];
|
||||
return this._getThirdPartyTypeshedPath(execEnv, unused);
|
||||
}
|
||||
|
||||
isStdlibModule(module: ImportedModuleDescriptor, execEnv: ExecutionEnvironment): boolean {
|
||||
if (!this._stdlibModules) {
|
||||
this._stdlibModules = this._buildStdlibCache(this.getTypeshedStdLibPath(execEnv));
|
||||
@ -1693,7 +1698,7 @@ export class ImportResolver {
|
||||
execEnv: ExecutionEnvironment,
|
||||
moduleDescriptor: ImportedModuleDescriptor,
|
||||
isStdLib: boolean,
|
||||
suggestions: Set<string>
|
||||
suggestions: Map<string, string>
|
||||
) {
|
||||
const importFailureInfo: string[] = [];
|
||||
|
||||
@ -2015,7 +2020,7 @@ export class ImportResolver {
|
||||
sourceFilePath: string,
|
||||
execEnv: ExecutionEnvironment,
|
||||
moduleDescriptor: ImportedModuleDescriptor,
|
||||
suggestions: Set<string>
|
||||
suggestions: Map<string, string>
|
||||
) {
|
||||
// Determine which search path this file is part of.
|
||||
const directory = getDirectoryLeadingDotsPointsTo(
|
||||
@ -2050,7 +2055,7 @@ export class ImportResolver {
|
||||
execEnv: ExecutionEnvironment,
|
||||
rootPath: string,
|
||||
moduleDescriptor: ImportedModuleDescriptor,
|
||||
suggestions: Set<string>,
|
||||
suggestions: Map<string, string>,
|
||||
strictOnly = true
|
||||
) {
|
||||
// Starting at the specified path, walk the file system to find the
|
||||
@ -2112,7 +2117,7 @@ export class ImportResolver {
|
||||
execEnv: ExecutionEnvironment,
|
||||
currentPath: string,
|
||||
filter: string,
|
||||
suggestions: Set<string>,
|
||||
suggestions: Map<string, string>,
|
||||
leadingDots: number,
|
||||
parentNameParts: string[],
|
||||
strictOnly: boolean
|
||||
@ -2153,7 +2158,7 @@ export class ImportResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
suggestions.add(fileWithoutExtension);
|
||||
suggestions.set(fileWithoutExtension, combinePaths(currentPath, file));
|
||||
}
|
||||
});
|
||||
|
||||
@ -2169,7 +2174,20 @@ export class ImportResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
suggestions.add(dir);
|
||||
const initPyiPath = combinePaths(currentPath, dir, '__init__.pyi');
|
||||
if (this.fileExistsCached(initPyiPath)) {
|
||||
suggestions.set(dir, initPyiPath);
|
||||
return;
|
||||
}
|
||||
|
||||
const initPyPath = combinePaths(currentPath, dir, '__init__.py');
|
||||
if (this.fileExistsCached(initPyPath)) {
|
||||
suggestions.set(dir, initPyPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// It is a namespace package. there is no corresponding module path.
|
||||
suggestions.set(dir, '');
|
||||
});
|
||||
}
|
||||
|
||||
@ -2202,7 +2220,7 @@ export class ImportResolver {
|
||||
return this._resolveImport(sourceFilePath, execEnv, moduleDescriptor).isImportFound;
|
||||
}
|
||||
|
||||
private _isUniqueValidSuggestion(suggestionToAdd: string, suggestions: Set<string>) {
|
||||
private _isUniqueValidSuggestion(suggestionToAdd: string, suggestions: Map<string, string>) {
|
||||
if (suggestions.has(suggestionToAdd)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -835,29 +835,7 @@ export class Program {
|
||||
let shadowFileInfo = this.getSourceFileInfo(shadowImplPath);
|
||||
|
||||
if (!shadowFileInfo) {
|
||||
const importName = this._getImportNameForFile(shadowImplPath);
|
||||
const sourceFile = new SourceFile(
|
||||
this._fs,
|
||||
shadowImplPath,
|
||||
importName,
|
||||
/* isThirdPartyImport */ false,
|
||||
/* isInPyTypedPackage */ false,
|
||||
this._console,
|
||||
this._logTracker
|
||||
);
|
||||
shadowFileInfo = {
|
||||
sourceFile,
|
||||
isTracked: false,
|
||||
isOpenByClient: false,
|
||||
isTypeshedFile: false,
|
||||
isThirdPartyImport: false,
|
||||
isThirdPartyPyTypedPresent: false,
|
||||
diagnosticsVersion: undefined,
|
||||
imports: [],
|
||||
importedBy: [],
|
||||
shadows: [],
|
||||
shadowedBy: [],
|
||||
};
|
||||
shadowFileInfo = this._createIntrimFileInfo(shadowImplPath);
|
||||
this._addToSourceFileListAndMap(shadowFileInfo);
|
||||
}
|
||||
|
||||
@ -872,6 +850,34 @@ export class Program {
|
||||
return shadowFileInfo.sourceFile;
|
||||
}
|
||||
|
||||
private _createIntrimFileInfo(filePath: string) {
|
||||
const importName = this._getImportNameForFile(filePath);
|
||||
const sourceFile = new SourceFile(
|
||||
this._fs,
|
||||
filePath,
|
||||
importName,
|
||||
/* isThirdPartyImport */ false,
|
||||
/* isInPyTypedPackage */ false,
|
||||
this._console,
|
||||
this._logTracker
|
||||
);
|
||||
const sourceFileInfo = {
|
||||
sourceFile,
|
||||
isTracked: false,
|
||||
isOpenByClient: false,
|
||||
isTypeshedFile: false,
|
||||
isThirdPartyImport: false,
|
||||
isThirdPartyPyTypedPresent: false,
|
||||
diagnosticsVersion: undefined,
|
||||
imports: [],
|
||||
importedBy: [],
|
||||
shadows: [],
|
||||
shadowedBy: [],
|
||||
};
|
||||
|
||||
return sourceFileInfo;
|
||||
}
|
||||
|
||||
private _createNewEvaluator() {
|
||||
if (this._evaluator) {
|
||||
// We shouldn't need to call this, but there appears to be a bug
|
||||
@ -2588,15 +2594,34 @@ export class Program {
|
||||
execEnv,
|
||||
this._evaluator!,
|
||||
(stubFilePath: string, implFilePath: string) => {
|
||||
const stubFileInfo = this.getSourceFileInfo(stubFilePath);
|
||||
let stubFileInfo = this.getSourceFileInfo(stubFilePath);
|
||||
if (!stubFileInfo) {
|
||||
return undefined;
|
||||
// Special case for import statement.
|
||||
// ex) import X.Y
|
||||
// SourceFile for X might not be in memory since import `X.Y` only brings in Y
|
||||
stubFileInfo = this._createIntrimFileInfo(stubFilePath);
|
||||
this._addToSourceFileListAndMap(stubFileInfo);
|
||||
}
|
||||
|
||||
this._addShadowedFile(stubFileInfo, implFilePath);
|
||||
return this.getBoundSourceFile(implFilePath);
|
||||
},
|
||||
(f) => this.getBoundSourceFileInfo(f),
|
||||
(f) => this.getSourceFileInfo(f),
|
||||
(f) => {
|
||||
let fileInfo = this.getBoundSourceFileInfo(f);
|
||||
if (!fileInfo) {
|
||||
// Special case for import statement.
|
||||
// ex) import X.Y
|
||||
// SourceFile for X might not be in memory since import `X.Y` only brings in Y
|
||||
fileInfo = this._createIntrimFileInfo(f);
|
||||
this._addToSourceFileListAndMap(fileInfo);
|
||||
|
||||
// Even though this file is not referenced by anything, make sure
|
||||
// we have parse tree for doc string.
|
||||
fileInfo.sourceFile.parse(this._configOptions, this._importResolver);
|
||||
}
|
||||
|
||||
return fileInfo;
|
||||
},
|
||||
mapCompiled ?? false,
|
||||
preferStubs ?? false,
|
||||
from,
|
||||
|
@ -39,6 +39,9 @@ export function getRegionComments(parseResults: ParseResults): RegionComment[] {
|
||||
return comments;
|
||||
}
|
||||
|
||||
const StartRegionRegx = /^\s*region(\s*)(.*)$/;
|
||||
const EndRegionRegex = /^\s*endregion(\s*)(.*)$/;
|
||||
|
||||
function getRegionCommentType(comment: Comment, parseResults: ParseResults): RegionCommentType | undefined {
|
||||
const hashOffset = comment.start - 1;
|
||||
const hashPosition = convertOffsetToPosition(hashOffset, parseResults.tokenizerOutput.lines);
|
||||
@ -53,11 +56,19 @@ function getRegionCommentType(comment: Comment, parseResults: ParseResults): Reg
|
||||
}
|
||||
}
|
||||
|
||||
const trimmedValue = comment.value.trimStart();
|
||||
if (trimmedValue.startsWith('region')) {
|
||||
return RegionCommentType.Region;
|
||||
} else if (trimmedValue.startsWith('endregion')) {
|
||||
return RegionCommentType.EndRegion;
|
||||
const startRegionMatch = StartRegionRegx.exec(comment.value);
|
||||
const endRegionMatch = EndRegionRegex.exec(comment.value);
|
||||
|
||||
// If the # region is followed by a space or has nothing after it, it's treated as a region.
|
||||
// Whereas, # regionfoo should not be a region.
|
||||
if (startRegionMatch && startRegionMatch.length > 2) {
|
||||
return startRegionMatch[1].length > 0 || (startRegionMatch[1].length === 0 && startRegionMatch[2].length === 0)
|
||||
? RegionCommentType.Region
|
||||
: undefined;
|
||||
} else if (endRegionMatch && endRegionMatch.length > 2) {
|
||||
return endRegionMatch[1].length > 0 || (endRegionMatch[1].length === 0 && endRegionMatch[2].length === 0)
|
||||
? RegionCommentType.EndRegion
|
||||
: undefined;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ export class SourceMapper {
|
||||
private _evaluator: TypeEvaluator,
|
||||
private _fileBinder: ShadowFileBinder,
|
||||
private _boundSourceGetter: BoundSourceGetter,
|
||||
private _sourceGetter: BoundSourceGetter,
|
||||
private _mapCompiled: boolean,
|
||||
private _preferStubs: boolean,
|
||||
private _fromFile: SourceFileInfo | undefined,
|
||||
@ -61,8 +60,18 @@ export class SourceMapper {
|
||||
) {}
|
||||
|
||||
findModules(stubFilePath: string): ModuleNode[] {
|
||||
const sourceFiles = this._getBoundSourceFilesFromStubFile(stubFilePath);
|
||||
return sourceFiles.map((sf) => sf.getParseResults()?.parseTree).filter(isDefined);
|
||||
const sourceFiles = this._isStubThatShouldBeMappedToImplementation(stubFilePath)
|
||||
? this._getBoundSourceFilesFromStubFile(stubFilePath)
|
||||
: [this._boundSourceGetter(stubFilePath)?.sourceFile];
|
||||
|
||||
return sourceFiles
|
||||
.filter(isDefined)
|
||||
.map((sf) => sf.getParseResults()?.parseTree)
|
||||
.filter(isDefined);
|
||||
}
|
||||
|
||||
getModuleNode(filePath: string): ModuleNode | undefined {
|
||||
return this._boundSourceGetter(filePath)?.sourceFile.getParseResults()?.parseTree;
|
||||
}
|
||||
|
||||
findDeclarations(stubDecl: Declaration): Declaration[] {
|
||||
@ -94,7 +103,7 @@ export class SourceMapper {
|
||||
}
|
||||
|
||||
isUserCode(path: string): boolean {
|
||||
return isUserCode(this._sourceGetter(path));
|
||||
return isUserCode(this._boundSourceGetter(path));
|
||||
}
|
||||
|
||||
getNextFileName(path: string) {
|
||||
|
@ -32,6 +32,7 @@ import {
|
||||
Type,
|
||||
TypeCategory,
|
||||
} from '../analyzer/types';
|
||||
import { addIfNotNull } from '../common/collectionUtils';
|
||||
import { ModuleNode, ParseNodeType } from '../parser/parseNodes';
|
||||
import { TypeEvaluator } from './typeEvaluatorTypes';
|
||||
import {
|
||||
@ -179,7 +180,7 @@ export function getVariableInStubFileDocStrings(decl: VariableDeclaration, sourc
|
||||
return docStrings;
|
||||
}
|
||||
|
||||
export function getModuleNodeDocString(modules: ModuleNode[]): string | undefined {
|
||||
export function getModuleDocStringFromModuleNodes(modules: ModuleNode[]): string | undefined {
|
||||
for (const module of modules) {
|
||||
if (module.statements) {
|
||||
const docString = ParseTreeUtils.getDocString(module.statements);
|
||||
@ -192,6 +193,19 @@ export function getModuleNodeDocString(modules: ModuleNode[]): string | undefine
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getModuleDocStringFromPaths(filePaths: string[], sourceMapper: SourceMapper) {
|
||||
const modules: ModuleNode[] = [];
|
||||
for (const filePath of filePaths) {
|
||||
if (isStubFile(filePath)) {
|
||||
addIfNotNull(modules, sourceMapper.getModuleNode(filePath));
|
||||
}
|
||||
|
||||
modules.push(...sourceMapper.findModules(filePath));
|
||||
}
|
||||
|
||||
return getModuleDocStringFromModuleNodes(modules);
|
||||
}
|
||||
|
||||
export function getModuleDocString(
|
||||
type: ModuleType,
|
||||
resolvedDecl: DeclarationBase | undefined,
|
||||
@ -199,10 +213,8 @@ export function getModuleDocString(
|
||||
) {
|
||||
let docString = type.docString;
|
||||
if (!docString) {
|
||||
if (resolvedDecl && isStubFile(resolvedDecl.path)) {
|
||||
const modules = sourceMapper.findModules(resolvedDecl.path);
|
||||
docString = getModuleNodeDocString(modules);
|
||||
}
|
||||
const filePath = resolvedDecl?.path ?? type.filePath;
|
||||
docString = getModuleDocStringFromPaths([filePath], sourceMapper);
|
||||
}
|
||||
|
||||
return docString;
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import { CancellationToken, ExecuteCommandParams } from 'vscode-languageserver';
|
||||
|
||||
import { convertTextEdits } from '../common/textEditUtils';
|
||||
import { convertEditActionsToWorkspaceEdit } from '../common/textEditUtils';
|
||||
import { LanguageServerInterface } from '../languageServerBase';
|
||||
import { ServerCommand } from './commandController';
|
||||
import { Commands } from './commands';
|
||||
@ -34,7 +34,7 @@ export class QuickActionCommand implements ServerCommand {
|
||||
token
|
||||
);
|
||||
|
||||
return convertTextEdits(docUri, editActions);
|
||||
return convertEditActionsToWorkspaceEdit(docUri, editActions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -377,3 +377,12 @@ export function getMapValues<K, V>(m: Map<K, V>, predicate: (k: K, v: V) => bool
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
export function addIfNotNull<T>(arr: T[], t: T): T[] {
|
||||
if (t === undefined) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
arr.push(t);
|
||||
return arr;
|
||||
}
|
||||
|
@ -24,18 +24,22 @@ import { isString } from './core';
|
||||
import { convertTextRangeToRange } from './positionUtils';
|
||||
import { doRangesIntersect, extendRange, Range, rangesAreEqual, TextRange } from './textRange';
|
||||
|
||||
export function convertTextEdits(uri: string, editActions: TextEditAction[] | undefined): WorkspaceEdit {
|
||||
export function convertEditActionsToTextEdits(editActions: TextEditAction[]): TextEdit[] {
|
||||
return editActions.map((editAction) => ({
|
||||
range: editAction.range,
|
||||
newText: editAction.replacementText,
|
||||
}));
|
||||
}
|
||||
|
||||
export function convertEditActionsToWorkspaceEdit(
|
||||
uri: string,
|
||||
editActions: TextEditAction[] | undefined
|
||||
): WorkspaceEdit {
|
||||
if (!editActions) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const edits: TextEdit[] = [];
|
||||
editActions.forEach((editAction) => {
|
||||
edits.push({
|
||||
range: editAction.range,
|
||||
newText: editAction.replacementText,
|
||||
});
|
||||
});
|
||||
const edits = convertEditActionsToTextEdits(editActions);
|
||||
|
||||
return {
|
||||
changes: {
|
||||
|
@ -41,6 +41,7 @@ import { Symbol, SymbolTable } from '../analyzer/symbol';
|
||||
import * as SymbolNameUtils from '../analyzer/symbolNameUtils';
|
||||
import { getLastTypedDeclaredForSymbol, isVisibleExternally } from '../analyzer/symbolUtils';
|
||||
import { getTypedDictMembersForClass } from '../analyzer/typedDicts';
|
||||
import { getModuleDocStringFromPaths } from '../analyzer/typeDocStringUtils';
|
||||
import { CallSignatureInfo, TypeEvaluator } from '../analyzer/typeEvaluatorTypes';
|
||||
import { printLiteralValue } from '../analyzer/typePrinter';
|
||||
import {
|
||||
@ -58,6 +59,7 @@ import {
|
||||
isUnknown,
|
||||
Type,
|
||||
TypeBase,
|
||||
TypeCategory,
|
||||
UnknownType,
|
||||
} from '../analyzer/types';
|
||||
import {
|
||||
@ -82,6 +84,7 @@ import { fromLSPAny, toLSPAny } from '../common/lspUtils';
|
||||
import { convertOffsetToPosition, convertPositionToOffset } from '../common/positionUtils';
|
||||
import { PythonVersion } from '../common/pythonVersion';
|
||||
import * as StringUtils from '../common/stringUtils';
|
||||
import { convertEditActionsToTextEdits } from '../common/textEditUtils';
|
||||
import { comparePositions, Position } from '../common/textRange';
|
||||
import { TextRange } from '../common/textRange';
|
||||
import { TextRangeCollection } from '../common/textRangeCollection';
|
||||
@ -224,6 +227,7 @@ export interface CompletionItemData {
|
||||
autoImportText?: string;
|
||||
symbolLabel?: string;
|
||||
funcParensDisabled?: boolean;
|
||||
modulePath?: string;
|
||||
}
|
||||
|
||||
// MemberAccessInfo attempts to gather info for unknown types
|
||||
@ -319,6 +323,7 @@ interface CompletionDetail extends CommonDetail {
|
||||
};
|
||||
sortText?: string;
|
||||
itemDetail?: string;
|
||||
modulePath?: string;
|
||||
}
|
||||
|
||||
export const autoImportDetail = 'Auto-import';
|
||||
@ -610,26 +615,49 @@ export class CompletionProvider {
|
||||
CompletionProvider._mostRecentCompletions.pop();
|
||||
}
|
||||
|
||||
if (completionItemData.symbolLabel) {
|
||||
this._itemToResolve = completionItem;
|
||||
if (!completionItemData.symbolLabel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!completionItemData.autoImportText) {
|
||||
// Rerun the completion lookup. It will fill in additional information
|
||||
// about the item to be resolved. We'll ignore the rest of the returned
|
||||
// list. This is a bit wasteful, but all of that information should be
|
||||
// cached, so it's not as bad as it might seem.
|
||||
this.getCompletionsForPosition();
|
||||
} else if (!completionItem.additionalTextEdits) {
|
||||
const completionMap = new CompletionMap();
|
||||
const completionResults = { completionMap };
|
||||
|
||||
this._addAutoImportCompletions(
|
||||
completionItemData.symbolLabel,
|
||||
/* similarityLimit */ 1,
|
||||
/* lazyEdit */ false,
|
||||
completionResults
|
||||
);
|
||||
if (completionItemData.modulePath) {
|
||||
const documentation = getModuleDocStringFromPaths([completionItemData.modulePath], this._sourceMapper);
|
||||
if (!documentation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._options.format === MarkupKind.Markdown) {
|
||||
const markdownString = convertDocStringToMarkdown(documentation);
|
||||
completionItem.documentation = {
|
||||
kind: MarkupKind.Markdown,
|
||||
value: markdownString,
|
||||
};
|
||||
} else if (this._options.format === MarkupKind.PlainText) {
|
||||
const plainTextString = convertDocStringToPlainText(documentation);
|
||||
completionItem.documentation = {
|
||||
kind: MarkupKind.PlainText,
|
||||
value: plainTextString,
|
||||
};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._itemToResolve = completionItem;
|
||||
if (!completionItemData.autoImportText) {
|
||||
// Rerun the completion lookup. It will fill in additional information
|
||||
// about the item to be resolved. We'll ignore the rest of the returned
|
||||
// list. This is a bit wasteful, but all of that information should be
|
||||
// cached, so it's not as bad as it might seem.
|
||||
this.getCompletionsForPosition();
|
||||
} else if (!completionItem.additionalTextEdits) {
|
||||
const completionMap = new CompletionMap();
|
||||
const completionResults = { completionMap };
|
||||
|
||||
this._addAutoImportCompletions(
|
||||
completionItemData.symbolLabel,
|
||||
/* similarityLimit */ 1,
|
||||
/* lazyEdit */ false,
|
||||
completionResults
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2441,7 +2469,9 @@ export class CompletionProvider {
|
||||
// Add the implicit imports.
|
||||
importInfo.implicitImports.forEach((implImport) => {
|
||||
if (!importFromNode.imports.find((imp) => imp.name.value === implImport.name)) {
|
||||
this._addNameToCompletions(implImport.name, CompletionItemKind.Module, priorWord, completionMap);
|
||||
this._addNameToCompletions(implImport.name, CompletionItemKind.Module, priorWord, completionMap, {
|
||||
modulePath: implImport.path,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -2606,165 +2636,108 @@ export class CompletionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if (primaryDecl) {
|
||||
let itemKind: CompletionItemKind = CompletionItemKind.Variable;
|
||||
primaryDecl = primaryDecl
|
||||
? this._evaluator.resolveAliasDeclaration(primaryDecl, /* resolveLocalNames */ true) ?? primaryDecl
|
||||
: undefined;
|
||||
|
||||
primaryDecl = this._evaluator.resolveAliasDeclaration(primaryDecl, /* resolveLocalNames */ true);
|
||||
if (primaryDecl) {
|
||||
itemKind = this._convertDeclarationTypeToItemKind(primaryDecl);
|
||||
const autoImportText = detail.autoImportSource
|
||||
? this._getAutoImportText(name, detail.autoImportSource, detail.autoImportAlias)
|
||||
: undefined;
|
||||
|
||||
// Handle enum members specially. Enum members normally look like
|
||||
// variables, but the are declared using assignment expressions
|
||||
// within an enum class.
|
||||
if (
|
||||
primaryDecl.type === DeclarationType.Variable &&
|
||||
detail.boundObjectOrClass &&
|
||||
isInstantiableClass(detail.boundObjectOrClass) &&
|
||||
ClassType.isEnumClass(detail.boundObjectOrClass) &&
|
||||
primaryDecl.node.parent?.nodeType === ParseNodeType.Assignment
|
||||
) {
|
||||
itemKind = CompletionItemKind.EnumMember;
|
||||
}
|
||||
// Are we resolving a completion item? If so, see if this symbol
|
||||
// is the one that we're trying to match.
|
||||
if (this._itemToResolve) {
|
||||
const completionItemData = fromLSPAny<CompletionItemData>(this._itemToResolve.data);
|
||||
|
||||
// Are we resolving a completion item? If so, see if this symbol
|
||||
// is the one that we're trying to match.
|
||||
if (this._itemToResolve) {
|
||||
const completionItemData = fromLSPAny<CompletionItemData>(this._itemToResolve.data);
|
||||
|
||||
if (completionItemData.symbolLabel === name && !completionItemData.autoImportText) {
|
||||
// This call can be expensive to perform on every completion item
|
||||
// that we return, so we do it lazily in the "resolve" callback.
|
||||
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
||||
if (type) {
|
||||
let typeDetail: string | undefined;
|
||||
let documentation: string | undefined;
|
||||
|
||||
switch (primaryDecl.type) {
|
||||
case DeclarationType.Intrinsic:
|
||||
case DeclarationType.Variable:
|
||||
case DeclarationType.Parameter:
|
||||
case DeclarationType.TypeParameter: {
|
||||
let expandTypeAlias = false;
|
||||
if (type && TypeBase.isInstantiable(type)) {
|
||||
const typeAliasInfo = getTypeAliasInfo(type);
|
||||
if (typeAliasInfo) {
|
||||
if (typeAliasInfo.name === name) {
|
||||
expandTypeAlias = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
typeDetail = name + ': ' + this._evaluator.printType(type, { expandTypeAlias });
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclarationType.Function: {
|
||||
const functionType =
|
||||
detail.boundObjectOrClass && (isFunction(type) || isOverloadedFunction(type))
|
||||
? this._evaluator.bindFunctionToClassOrObject(
|
||||
detail.boundObjectOrClass,
|
||||
type
|
||||
)
|
||||
: type;
|
||||
if (functionType) {
|
||||
if (
|
||||
isProperty(functionType) &&
|
||||
detail.boundObjectOrClass &&
|
||||
isClassInstance(detail.boundObjectOrClass)
|
||||
) {
|
||||
const propertyType =
|
||||
this._evaluator.getGetterTypeFromProperty(
|
||||
functionType as ClassType,
|
||||
/* inferTypeIfNeeded */ true
|
||||
) || UnknownType.create();
|
||||
typeDetail =
|
||||
name + ': ' + this._evaluator.printType(propertyType) + ' (property)';
|
||||
} else if (isOverloadedFunction(functionType)) {
|
||||
// 35 is completion tooltip's default width size
|
||||
typeDetail = getOverloadedFunctionTooltip(
|
||||
functionType,
|
||||
this._evaluator,
|
||||
/* columnThreshold */ 35
|
||||
);
|
||||
} else if (isFunction(functionType)) {
|
||||
typeDetail = name + this._evaluator.printType(functionType);
|
||||
} else {
|
||||
typeDetail = name + ': ' + this._evaluator.printType(functionType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclarationType.Class:
|
||||
case DeclarationType.SpecialBuiltInClass: {
|
||||
typeDetail = 'class ' + name + '()';
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclarationType.Alias: {
|
||||
typeDetail = name;
|
||||
if (primaryDecl.path) {
|
||||
const lookupResults = this._importLookup(primaryDecl.path);
|
||||
if (lookupResults) {
|
||||
documentation = lookupResults.docString;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
typeDetail = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
documentation = getDocumentationPartsForTypeAndDecl(
|
||||
this._sourceMapper,
|
||||
type,
|
||||
primaryDecl,
|
||||
this._evaluator,
|
||||
symbol,
|
||||
detail.boundObjectOrClass
|
||||
);
|
||||
|
||||
if (this._options.format === MarkupKind.Markdown) {
|
||||
let markdownString = '```python\n' + typeDetail + '\n```\n';
|
||||
|
||||
if (documentation) {
|
||||
markdownString += '---\n';
|
||||
markdownString += convertDocStringToMarkdown(documentation);
|
||||
}
|
||||
|
||||
markdownString = markdownString.trimEnd();
|
||||
|
||||
this._itemToResolve.documentation = {
|
||||
kind: MarkupKind.Markdown,
|
||||
value: markdownString,
|
||||
};
|
||||
} else if (this._options.format === MarkupKind.PlainText) {
|
||||
let plainTextString = typeDetail + '\n';
|
||||
|
||||
if (documentation) {
|
||||
plainTextString += '\n';
|
||||
plainTextString += convertDocStringToPlainText(documentation);
|
||||
}
|
||||
|
||||
plainTextString = plainTextString.trimEnd();
|
||||
|
||||
this._itemToResolve.documentation = {
|
||||
kind: MarkupKind.PlainText,
|
||||
value: plainTextString,
|
||||
};
|
||||
} else {
|
||||
fail(`Unsupported markup type: ${this._options.format}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (completionItemData.symbolLabel !== name) {
|
||||
// It's not what we are looking for.
|
||||
return;
|
||||
}
|
||||
|
||||
const autoImportText = detail.autoImportSource
|
||||
? this._getAutoImportText(name, detail.autoImportSource, detail.autoImportAlias)
|
||||
: undefined;
|
||||
if (completionItemData.autoImportText) {
|
||||
if (
|
||||
completionItemData.autoImportText === autoImportText?.importText &&
|
||||
detail.edits?.additionalTextEdits
|
||||
) {
|
||||
this._itemToResolve.additionalTextEdits = convertEditActionsToTextEdits(
|
||||
detail.edits.additionalTextEdits
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// This call can be expensive to perform on every completion item
|
||||
// that we return, so we do it lazily in the "resolve" callback.
|
||||
const type = this._evaluator.getEffectiveTypeOfSymbol(symbol);
|
||||
if (!type) {
|
||||
// Can't resolve. so bail out.
|
||||
return;
|
||||
}
|
||||
|
||||
const typeDetail = this._getTypeDetail(primaryDecl, type, name, detail);
|
||||
const documentation = getDocumentationPartsForTypeAndDecl(
|
||||
this._sourceMapper,
|
||||
type,
|
||||
primaryDecl,
|
||||
this._evaluator,
|
||||
{
|
||||
name,
|
||||
symbol,
|
||||
boundObjectOrClass: detail.boundObjectOrClass,
|
||||
}
|
||||
);
|
||||
|
||||
if (this._options.format === MarkupKind.Markdown) {
|
||||
let markdownString = '```python\n' + typeDetail + '\n```\n';
|
||||
|
||||
if (documentation) {
|
||||
markdownString += '---\n';
|
||||
markdownString += convertDocStringToMarkdown(documentation);
|
||||
}
|
||||
|
||||
markdownString = markdownString.trimEnd();
|
||||
|
||||
this._itemToResolve.documentation = {
|
||||
kind: MarkupKind.Markdown,
|
||||
value: markdownString,
|
||||
};
|
||||
} else if (this._options.format === MarkupKind.PlainText) {
|
||||
let plainTextString = typeDetail + '\n';
|
||||
|
||||
if (documentation) {
|
||||
plainTextString += '\n';
|
||||
plainTextString += convertDocStringToPlainText(documentation);
|
||||
}
|
||||
|
||||
plainTextString = plainTextString.trimEnd();
|
||||
|
||||
this._itemToResolve.documentation = {
|
||||
kind: MarkupKind.PlainText,
|
||||
value: plainTextString,
|
||||
};
|
||||
} else {
|
||||
fail(`Unsupported markup type: ${this._options.format}`);
|
||||
}
|
||||
|
||||
// Bail out. We don't need to add items to completion.
|
||||
return;
|
||||
}
|
||||
|
||||
if (primaryDecl) {
|
||||
let itemKind = this._convertDeclarationTypeToItemKind(primaryDecl);
|
||||
|
||||
// Handle enum members specially. Enum members normally look like
|
||||
// variables, but the are declared using assignment expressions
|
||||
// within an enum class.
|
||||
if (
|
||||
primaryDecl.type === DeclarationType.Variable &&
|
||||
detail.boundObjectOrClass &&
|
||||
isInstantiableClass(detail.boundObjectOrClass) &&
|
||||
ClassType.isEnumClass(detail.boundObjectOrClass) &&
|
||||
primaryDecl.node.parent?.nodeType === ParseNodeType.Assignment
|
||||
) {
|
||||
itemKind = CompletionItemKind.EnumMember;
|
||||
}
|
||||
|
||||
this._addNameToCompletions(detail.autoImportAlias ?? name, itemKind, priorWord, completionMap, {
|
||||
autoImportText,
|
||||
@ -2776,7 +2749,7 @@ export class CompletionProvider {
|
||||
// Does the symbol have no declaration but instead has a synthesized type?
|
||||
const synthesizedType = symbol.getSynthesizedType();
|
||||
if (synthesizedType) {
|
||||
const itemKind: CompletionItemKind = CompletionItemKind.Variable;
|
||||
const itemKind: CompletionItemKind = this._convertTypeToItemKind(synthesizedType);
|
||||
this._addNameToCompletions(name, itemKind, priorWord, completionMap, {
|
||||
extraCommitChars: detail.extraCommitChars,
|
||||
funcParensDisabled: detail.funcParensDisabled,
|
||||
@ -2786,6 +2759,86 @@ export class CompletionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private _getTypeDetail(primaryDecl: Declaration | undefined, type: Type, name: string, detail: SymbolDetail) {
|
||||
if (!primaryDecl) {
|
||||
if (isModule(type)) {
|
||||
// Special casing import modules.
|
||||
// submodule imported through `import` statement doesn't have
|
||||
// corresponding decls. so use given name as it is.
|
||||
//
|
||||
// ex) import X.Y
|
||||
// X.[Y]
|
||||
return name;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (primaryDecl.type) {
|
||||
case DeclarationType.Intrinsic:
|
||||
case DeclarationType.Variable:
|
||||
case DeclarationType.Parameter:
|
||||
case DeclarationType.TypeParameter: {
|
||||
let expandTypeAlias = false;
|
||||
if (type && TypeBase.isInstantiable(type)) {
|
||||
const typeAliasInfo = getTypeAliasInfo(type);
|
||||
if (typeAliasInfo) {
|
||||
if (typeAliasInfo.name === name) {
|
||||
expandTypeAlias = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name + ': ' + this._evaluator.printType(type, { expandTypeAlias });
|
||||
}
|
||||
|
||||
case DeclarationType.Function: {
|
||||
const functionType =
|
||||
detail.boundObjectOrClass && (isFunction(type) || isOverloadedFunction(type))
|
||||
? this._evaluator.bindFunctionToClassOrObject(detail.boundObjectOrClass, type)
|
||||
: type;
|
||||
if (!functionType) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
isProperty(functionType) &&
|
||||
detail.boundObjectOrClass &&
|
||||
isClassInstance(detail.boundObjectOrClass)
|
||||
) {
|
||||
const propertyType =
|
||||
this._evaluator.getGetterTypeFromProperty(
|
||||
functionType as ClassType,
|
||||
/* inferTypeIfNeeded */ true
|
||||
) || UnknownType.create();
|
||||
return name + ': ' + this._evaluator.printType(propertyType) + ' (property)';
|
||||
}
|
||||
|
||||
if (isOverloadedFunction(functionType)) {
|
||||
// 35 is completion tooltip's default width size
|
||||
return getOverloadedFunctionTooltip(functionType, this._evaluator, /* columnThreshold */ 35);
|
||||
} else if (isFunction(functionType)) {
|
||||
return name + this._evaluator.printType(functionType);
|
||||
} else {
|
||||
return name + ': ' + this._evaluator.printType(functionType);
|
||||
}
|
||||
}
|
||||
|
||||
case DeclarationType.Class:
|
||||
case DeclarationType.SpecialBuiltInClass: {
|
||||
return 'class ' + name + '()';
|
||||
}
|
||||
|
||||
case DeclarationType.Alias: {
|
||||
return name;
|
||||
}
|
||||
|
||||
default: {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _getAutoImportText(importName: string, importFrom?: string, importAlias?: string) {
|
||||
const autoImportText = getAutoImportText(importName, importFrom, importAlias);
|
||||
|
||||
@ -2840,6 +2893,10 @@ export class CompletionProvider {
|
||||
completionItemData.funcParensDisabled = true;
|
||||
}
|
||||
|
||||
if (detail?.modulePath) {
|
||||
completionItemData.modulePath = detail.modulePath;
|
||||
}
|
||||
|
||||
completionItem.data = toLSPAny(completionItemData);
|
||||
|
||||
if (detail?.sortText || detail?.itemDetail) {
|
||||
@ -2943,17 +3000,9 @@ export class CompletionProvider {
|
||||
}
|
||||
|
||||
if (detail?.edits?.additionalTextEdits) {
|
||||
completionItem.additionalTextEdits = detail.edits.additionalTextEdits.map((te) => {
|
||||
const textEdit: TextEdit = {
|
||||
range: {
|
||||
start: { line: te.range.start.line, character: te.range.start.character },
|
||||
end: { line: te.range.end.line, character: te.range.end.character },
|
||||
},
|
||||
newText: te.replacementText,
|
||||
};
|
||||
return textEdit;
|
||||
});
|
||||
completionItem.additionalTextEdits = convertEditActionsToTextEdits(detail.edits.additionalTextEdits);
|
||||
|
||||
// This is for auto import entries from indices which skip symbols.
|
||||
if (this._itemToResolve) {
|
||||
const data = fromLSPAny<CompletionItemData>(this._itemToResolve.data);
|
||||
if (data.autoImportText === completionItemData.autoImportText) {
|
||||
@ -3060,6 +3109,27 @@ export class CompletionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private _convertTypeToItemKind(type: Type): CompletionItemKind {
|
||||
switch (type.category) {
|
||||
case TypeCategory.Module:
|
||||
return CompletionItemKind.Module;
|
||||
case TypeCategory.Class:
|
||||
return CompletionItemKind.Class;
|
||||
case TypeCategory.Function:
|
||||
case TypeCategory.OverloadedFunction:
|
||||
if (isProperty(type)) {
|
||||
return CompletionItemKind.Property;
|
||||
}
|
||||
|
||||
return CompletionItemKind.Function;
|
||||
case TypeCategory.TypeVar:
|
||||
return CompletionItemKind.TypeParameter;
|
||||
|
||||
default:
|
||||
return CompletionItemKind.Variable;
|
||||
}
|
||||
}
|
||||
|
||||
private _getImportModuleCompletions(node: ModuleNameNode): CompletionResults {
|
||||
const moduleDescriptor: ImportedModuleDescriptor = {
|
||||
leadingDots: node.leadingDots,
|
||||
@ -3091,15 +3161,11 @@ export class CompletionProvider {
|
||||
completionMap.set(completionItem);
|
||||
}
|
||||
|
||||
completions.forEach((completionName) => {
|
||||
if (completionMap.has(completionName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const completionItem = CompletionItem.create(completionName);
|
||||
completionItem.kind = CompletionItemKind.Module;
|
||||
completionItem.sortText = this._makeSortText(SortCategory.ImportModuleName, completionName);
|
||||
completionMap.set(completionItem);
|
||||
completions.forEach((modulePath, completionName) => {
|
||||
this._addNameToCompletions(completionName, CompletionItemKind.Module, '', completionMap, {
|
||||
sortText: this._makeSortText(SortCategory.ImportModuleName, completionName),
|
||||
modulePath,
|
||||
});
|
||||
});
|
||||
|
||||
return { completionMap };
|
||||
|
@ -15,7 +15,6 @@ import { Declaration, DeclarationType } from '../analyzer/declaration';
|
||||
import { convertDocStringToMarkdown, convertDocStringToPlainText } from '../analyzer/docStringConversion';
|
||||
import * as ParseTreeUtils from '../analyzer/parseTreeUtils';
|
||||
import { SourceMapper } from '../analyzer/sourceMapper';
|
||||
import { getModuleNodeDocString } from '../analyzer/typeDocStringUtils';
|
||||
import { TypeEvaluator } from '../analyzer/typeEvaluatorTypes';
|
||||
import {
|
||||
ClassType,
|
||||
@ -117,7 +116,7 @@ export class HoverProvider {
|
||||
if (results.parts.length === 0) {
|
||||
const type = evaluator.getType(node) || UnknownType.create();
|
||||
|
||||
let typeText = '';
|
||||
let typeText: string;
|
||||
if (isModule(type)) {
|
||||
// Handle modules specially because submodules aren't associated with
|
||||
// declarations, but we want them to be presented in the same way as
|
||||
@ -300,7 +299,9 @@ export class HoverProvider {
|
||||
}
|
||||
|
||||
case DeclarationType.Alias: {
|
||||
this._addModuleParts(format, sourceMapper, parts, node.value, [resolvedDecl.path]);
|
||||
// First the 'module' header.
|
||||
this._addResultsPart(parts, '(module) ' + node.value, /* python */ true);
|
||||
this._addDocumentationPart(format, sourceMapper, parts, node, evaluator, resolvedDecl);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -494,40 +495,19 @@ export class HoverProvider {
|
||||
resolvedDecl: Declaration | undefined
|
||||
) {
|
||||
const type = evaluator.getType(node);
|
||||
if (type) {
|
||||
this._addDocumentationPartForType(format, sourceMapper, parts, type, resolvedDecl, evaluator);
|
||||
}
|
||||
}
|
||||
|
||||
private static _addModuleParts(
|
||||
format: MarkupKind,
|
||||
sourceMapper: SourceMapper,
|
||||
parts: HoverTextPart[],
|
||||
name: string,
|
||||
resolvedPaths: string[]
|
||||
) {
|
||||
// First the 'module' header.
|
||||
this._addResultsPart(parts, '(module) ' + name, /* python */ true);
|
||||
|
||||
// Parse the modules files and try to find the doc string.
|
||||
const modules = resolvedPaths.map((p) => sourceMapper.findModules(p)).flat();
|
||||
const docString = getModuleNodeDocString(modules);
|
||||
if (docString) {
|
||||
this._addDocumentationResultsPart(format, parts, docString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
this._addDocumentationPartForType(format, sourceMapper, parts, type, resolvedDecl, evaluator, node.value);
|
||||
}
|
||||
|
||||
private static _addDocumentationPartForType(
|
||||
format: MarkupKind,
|
||||
sourceMapper: SourceMapper,
|
||||
parts: HoverTextPart[],
|
||||
type: Type,
|
||||
type: Type | undefined,
|
||||
resolvedDecl: Declaration | undefined,
|
||||
evaluator: TypeEvaluator
|
||||
evaluator: TypeEvaluator,
|
||||
name?: string
|
||||
): boolean {
|
||||
const docString = getDocumentationPartsForTypeAndDecl(sourceMapper, type, resolvedDecl, evaluator);
|
||||
const docString = getDocumentationPartsForTypeAndDecl(sourceMapper, type, resolvedDecl, evaluator, { name });
|
||||
if (docString) {
|
||||
this._addDocumentationResultsPart(format, parts, docString);
|
||||
return true;
|
||||
|
@ -174,7 +174,7 @@ function _getIndentation(
|
||||
}
|
||||
|
||||
const suiteSpan = convertTextRangeToRange(suite, parseResults.tokenizerOutput.lines);
|
||||
if (preferDedent || suiteSpan.start.line === suiteSpan.end.line) {
|
||||
if (preferDedent || (suiteSpan.start.line === suiteSpan.end.line && suite.statements.length > 0)) {
|
||||
// Go one more level up.
|
||||
const outerContainer = getContainer(suite, /*includeSelf*/ false);
|
||||
return _getIndentationForNode(parseResults, offset, outerContainer ?? parseResults.parseTree, suite);
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
getClassDocString,
|
||||
getFunctionDocStringInherited,
|
||||
getModuleDocString,
|
||||
getModuleDocStringFromPaths,
|
||||
getOverloadedFunctionDocStringsInherited,
|
||||
getPropertyDocStringInherited,
|
||||
getVariableDocString,
|
||||
@ -32,6 +33,7 @@ import {
|
||||
Type,
|
||||
} from '../analyzer/types';
|
||||
import { isDefined } from '../common/core';
|
||||
import { ParseNodeType } from '../parser/parseNodes';
|
||||
|
||||
// 70 is vscode's default hover width size.
|
||||
export function getOverloadedFunctionTooltip(
|
||||
@ -91,7 +93,7 @@ export function getOverloadedFunctionDocStringsFromType(
|
||||
);
|
||||
}
|
||||
|
||||
function getDocumentationPartForAlias(
|
||||
function getDocumentationPartForTypeAlias(
|
||||
sourceMapper: SourceMapper,
|
||||
resolvedDecl: Declaration | undefined,
|
||||
evaluator: TypeEvaluator,
|
||||
@ -160,17 +162,48 @@ function getDocumentationPartForType(
|
||||
|
||||
export function getDocumentationPartsForTypeAndDecl(
|
||||
sourceMapper: SourceMapper,
|
||||
type: Type,
|
||||
type: Type | undefined,
|
||||
resolvedDecl: Declaration | undefined,
|
||||
evaluator: TypeEvaluator,
|
||||
symbol?: Symbol,
|
||||
boundObjectOrClass?: ClassType | undefined
|
||||
optional?: {
|
||||
name?: string;
|
||||
symbol?: Symbol;
|
||||
boundObjectOrClass?: ClassType | undefined;
|
||||
}
|
||||
): string | undefined {
|
||||
// Get the alias first
|
||||
const aliasDoc = getDocumentationPartForAlias(sourceMapper, resolvedDecl, evaluator, symbol);
|
||||
const aliasDoc = getDocumentationPartForTypeAlias(sourceMapper, resolvedDecl, evaluator, optional?.symbol);
|
||||
|
||||
// Combine this with the type doc
|
||||
const typeDoc = getDocumentationPartForType(sourceMapper, type, resolvedDecl, evaluator, boundObjectOrClass);
|
||||
let typeDoc: string | undefined;
|
||||
if (resolvedDecl?.type === DeclarationType.Alias) {
|
||||
// Handle another alias decl special case.
|
||||
// ex) import X.Y
|
||||
// [X].Y
|
||||
// Asking decl for X gives us "X.Y" rather than "X" since "X" is not actually a symbol.
|
||||
// We need to get corresponding module name to use special code in type eval for this case.
|
||||
if (
|
||||
resolvedDecl.type === DeclarationType.Alias &&
|
||||
resolvedDecl.node &&
|
||||
resolvedDecl.node.nodeType === ParseNodeType.ImportAs &&
|
||||
!!optional?.name &&
|
||||
!resolvedDecl.node.alias
|
||||
) {
|
||||
const name = resolvedDecl.node.module.nameParts.find((n) => n.value === optional.name);
|
||||
if (name) {
|
||||
const aliasDecls = evaluator.getDeclarationsForNameNode(name) ?? [resolvedDecl];
|
||||
resolvedDecl = aliasDecls.length > 0 ? aliasDecls[0] : resolvedDecl;
|
||||
}
|
||||
}
|
||||
|
||||
typeDoc = getModuleDocStringFromPaths([resolvedDecl.path], sourceMapper);
|
||||
}
|
||||
|
||||
typeDoc =
|
||||
typeDoc ??
|
||||
(type
|
||||
? getDocumentationPartForType(sourceMapper, type, resolvedDecl, evaluator, optional?.boundObjectOrClass)
|
||||
: undefined);
|
||||
|
||||
// Combine with a new line if they both exist
|
||||
return aliasDoc && typeDoc ? `${aliasDoc}\n\n${typeDoc}` : aliasDoc || typeDoc;
|
||||
|
360
packages/pyright-internal/src/tests/completions.test.ts
Normal file
360
packages/pyright-internal/src/tests/completions.test.ts
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* completions.test.ts
|
||||
*
|
||||
* completions tests.
|
||||
*/
|
||||
|
||||
import { CompletionItemKind, MarkupKind } from 'vscode-languageserver-types';
|
||||
|
||||
import { parseAndGetTestState } from './harness/fourslash/testState';
|
||||
|
||||
test('completion import statement tooltip', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import [|/*marker*/m|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'matplotlib',
|
||||
documentation: 'matplotlib',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion import statement tooltip - stub file', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import [|/*marker*/m|]
|
||||
|
||||
// @filename: matplotlib/__init__.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'matplotlib',
|
||||
documentation: 'matplotlib',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion import statement tooltip - doc in stub file', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import [|/*marker*/m|]
|
||||
|
||||
// @filename: matplotlib/__init__.pyi
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'matplotlib',
|
||||
documentation: 'matplotlib',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion import statement tooltip - sub modules', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import matplotlib.[|/*marker*/p|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'pyplot',
|
||||
documentation: 'pyplot',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion import reference tooltip', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import matplotlib
|
||||
//// [|/*marker*/m|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'matplotlib',
|
||||
documentation: '```python\nmatplotlib\n```\n---\nmatplotlib',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion import reference tooltip - first module', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import matplotlib.pyplot
|
||||
//// [|/*marker*/m|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'matplotlib',
|
||||
documentation: '```python\nmatplotlib\n```\n---\nmatplotlib',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion import reference tooltip - child module', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import matplotlib.pyplot
|
||||
//// matplotlib.[|/*marker*/p|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'pyplot',
|
||||
documentation: '```python\npyplot\n```\n---\npyplot',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion from import statement tooltip - first module', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// from [|/*marker*/m|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'matplotlib',
|
||||
documentation: 'matplotlib',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion from import statement tooltip - child module', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// from matplotlib.[|/*marker*/p|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'pyplot',
|
||||
documentation: 'pyplot',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('completion from import statement tooltip - implicit module', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// from matplotlib import [|/*marker*/p|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
await state.verifyCompletion('included', MarkupKind.Markdown, {
|
||||
marker: {
|
||||
completions: [
|
||||
{
|
||||
kind: CompletionItemKind.Module,
|
||||
label: 'pyplot',
|
||||
documentation: 'pyplot',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
@ -41,6 +41,21 @@ test('Folders', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Folders Recursive', () => {
|
||||
const cwd = normalizeSlashes('/');
|
||||
const fs = new vfs.TestFileSystem(/*ignoreCase*/ true, { cwd });
|
||||
|
||||
// no such dir exist
|
||||
assert.throws(() => {
|
||||
fs.chdir('a');
|
||||
});
|
||||
|
||||
const path = combinePaths('/', 'a', 'b', 'c');
|
||||
fs.mkdirSync(path, { recursive: true });
|
||||
|
||||
assert(fs.existsSync(path));
|
||||
});
|
||||
|
||||
test('Files', () => {
|
||||
const cwd = normalizeSlashes('/');
|
||||
const fs = new vfs.TestFileSystem(/*ignoreCase*/ true, { cwd });
|
||||
|
@ -990,7 +990,7 @@ export class TestState {
|
||||
this.verifyCompletionItem(expected, actual);
|
||||
|
||||
if (expected.documentation !== undefined) {
|
||||
if (actual.documentation === undefined) {
|
||||
if (actual.documentation === undefined && actual.data) {
|
||||
this.workspace.serviceInstance.resolveCompletionItem(
|
||||
filePath,
|
||||
actual,
|
||||
|
@ -10,7 +10,13 @@
|
||||
import { Dirent, ReadStream, WriteStream } from 'fs';
|
||||
import { URI } from 'vscode-uri';
|
||||
|
||||
import { FileSystem, FileWatcher, FileWatcherEventHandler, TmpfileOptions } from '../../../common/fileSystem';
|
||||
import {
|
||||
FileSystem,
|
||||
FileWatcher,
|
||||
FileWatcherEventHandler,
|
||||
MkDirOptions,
|
||||
TmpfileOptions,
|
||||
} from '../../../common/fileSystem';
|
||||
import * as pathUtil from '../../../common/pathUtils';
|
||||
import { bufferFrom, createIOError } from '../utils';
|
||||
import { closeIterator, getIterator, Metadata, nextResult, SortedMap } from './../utils';
|
||||
@ -614,11 +620,16 @@ export class TestFileSystem implements FileSystem {
|
||||
*
|
||||
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
||||
*/
|
||||
mkdirSync(path: string) {
|
||||
mkdirSync(path: string, options?: MkDirOptions) {
|
||||
if (this.isReadonly) {
|
||||
throw createIOError('EROFS');
|
||||
}
|
||||
|
||||
if (options?.recursive) {
|
||||
this.mkdirpSync(path);
|
||||
return;
|
||||
}
|
||||
|
||||
this._mkdir(this._walk(this._resolve(path), /*noFollow*/ true));
|
||||
}
|
||||
|
||||
|
269
packages/pyright-internal/src/tests/hoverProvider.test.ts
Normal file
269
packages/pyright-internal/src/tests/hoverProvider.test.ts
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* hoverProvider.test.ts
|
||||
*
|
||||
* hoverProvider tests.
|
||||
*/
|
||||
|
||||
import { parseAndGetTestState } from './harness/fourslash/testState';
|
||||
|
||||
test('import tooltip - import statement', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import [|/*marker1*/matplotlib|].[|/*marker2*/pyplot|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker1 = state.getMarkerByName('marker1');
|
||||
state.openFile(marker1.fileName);
|
||||
|
||||
state.verifyHover('markdown', {
|
||||
marker1: '```python\n(module) matplotlib\n```\n---\nmatplotlib',
|
||||
marker2: '```python\n(module) pyplot\n```\n---\npyplot',
|
||||
});
|
||||
});
|
||||
|
||||
test('import tooltip - import reference', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import matplotlib.pyplot
|
||||
//// [|/*marker1*/matplotlib|].[|/*marker2*/pyplot|]
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker1 = state.getMarkerByName('marker1');
|
||||
state.openFile(marker1.fileName);
|
||||
|
||||
state.verifyHover('markdown', {
|
||||
marker1: '```python\n(module) matplotlib\n```\n---\nmatplotlib',
|
||||
marker2: '```python\n(module) pyplot\n```\n---\npyplot',
|
||||
});
|
||||
});
|
||||
|
||||
test('import tooltip - import statement with stubs', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import [|/*marker1*/matplotlib|].[|/*marker2*/pyplot|]
|
||||
|
||||
// @filename: matplotlib/__init__.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/pyplot.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker1 = state.getMarkerByName('marker1');
|
||||
state.openFile(marker1.fileName);
|
||||
|
||||
state.verifyHover('markdown', {
|
||||
marker1: '```python\n(module) matplotlib\n```\n---\nmatplotlib',
|
||||
marker2: '```python\n(module) pyplot\n```\n---\npyplot',
|
||||
});
|
||||
});
|
||||
|
||||
test('import tooltip - import reference - stub files', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import matplotlib.pyplot
|
||||
//// [|/*marker1*/matplotlib|].[|/*marker2*/pyplot|]
|
||||
|
||||
// @filename: matplotlib/__init__.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/pyplot.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker1 = state.getMarkerByName('marker1');
|
||||
state.openFile(marker1.fileName);
|
||||
|
||||
state.verifyHover('markdown', {
|
||||
marker1: '```python\n(module) matplotlib\n```\n---\nmatplotlib',
|
||||
marker2: '```python\n(module) pyplot\n```\n---\npyplot',
|
||||
});
|
||||
});
|
||||
|
||||
test('import tooltip - import submodules statement', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import A.B.[|/*marker*/C|]
|
||||
|
||||
// @filename: A/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: A/B/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: A/B/C/__init__.py
|
||||
// @library: true
|
||||
//// """ C """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
state.verifyHover('markdown', { marker: '```python\n(module) C\n```\n---\nC' });
|
||||
});
|
||||
|
||||
test('import tooltip - import submodules reference', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// import A.B.C
|
||||
//// A.B.[|/*marker*/C|]
|
||||
|
||||
// @filename: A/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: A/B/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: A/B/C/__init__.py
|
||||
// @library: true
|
||||
//// """ C """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
state.verifyHover('markdown', { marker: '```python\n(module) C\n```\n---\nC' });
|
||||
});
|
||||
|
||||
test('import tooltip - from import statement with stubs', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// from [|/*marker1*/matplotlib|].[|/*marker2*/pyplot|] import *
|
||||
|
||||
// @filename: matplotlib/__init__.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/pyplot.pyi
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: matplotlib/__init__.py
|
||||
// @library: true
|
||||
//// """ matplotlib """
|
||||
|
||||
// @filename: matplotlib/pyplot.py
|
||||
// @library: true
|
||||
//// """ pyplot """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker1 = state.getMarkerByName('marker1');
|
||||
state.openFile(marker1.fileName);
|
||||
|
||||
state.verifyHover('markdown', {
|
||||
marker1: '```python\n(module) matplotlib\n```\n---\nmatplotlib',
|
||||
marker2: '```python\n(module) pyplot\n```\n---\npyplot',
|
||||
});
|
||||
});
|
||||
|
||||
test('import tooltip - from import submodules statement', async () => {
|
||||
const code = `
|
||||
// @filename: pyrightconfig.json
|
||||
//// {
|
||||
//// "useLibraryCodeForTypes": true
|
||||
//// }
|
||||
|
||||
// @filename: test.py
|
||||
//// from A.B.[|/*marker*/C|] import *
|
||||
|
||||
// @filename: A/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: A/B/__init__.py
|
||||
// @library: true
|
||||
//// # empty
|
||||
|
||||
// @filename: A/B/C/__init__.py
|
||||
// @library: true
|
||||
//// """ C """
|
||||
`;
|
||||
|
||||
const state = parseAndGetTestState(code).state;
|
||||
const marker = state.getMarkerByName('marker');
|
||||
state.openFile(marker.fileName);
|
||||
|
||||
state.verifyHover('markdown', { marker: '```python\n(module) C\n```\n---\nC' });
|
||||
});
|
@ -26,7 +26,7 @@ test('top level statement - function', () => {
|
||||
//// [|/*marker*/|]
|
||||
`;
|
||||
|
||||
testIndentation(code, 0);
|
||||
testIndentation(code, 4);
|
||||
});
|
||||
|
||||
test('function with open paren at end of file', () => {
|
||||
|
@ -45,7 +45,7 @@ test('first child indentation', () => {
|
||||
//// [|/*marker*/|]
|
||||
`;
|
||||
|
||||
testIndentation(code, 0);
|
||||
testIndentation(code, 4);
|
||||
});
|
||||
|
||||
test('nested first child indentation', () => {
|
||||
@ -55,7 +55,7 @@ test('nested first child indentation', () => {
|
||||
//// [|/*marker*/|]
|
||||
`;
|
||||
|
||||
testIndentation(code, 4);
|
||||
testIndentation(code, 8);
|
||||
});
|
||||
|
||||
test('nested sibling indentation', () => {
|
||||
@ -272,7 +272,7 @@ test('single line comment', () => {
|
||||
|
||||
`;
|
||||
|
||||
testIndentation(code, 0);
|
||||
testIndentation(code, 4);
|
||||
});
|
||||
|
||||
test('multiline string literals top', () => {
|
||||
@ -442,7 +442,7 @@ test('unfinished block', () => {
|
||||
//// return 1
|
||||
`;
|
||||
|
||||
testIndentation(code, 4);
|
||||
testIndentation(code, 8);
|
||||
});
|
||||
|
||||
function testIndentation(code: string, indentation: number, preferDedent?: boolean) {
|
||||
|
@ -77,9 +77,7 @@ export class WorkspaceMap extends Map<string, WorkspaceServiceInstance> {
|
||||
|
||||
// Wait for all workspaces to be initialized before attempting to find the best workspace. Otherwise
|
||||
// the list of files won't be complete and the `contains` check might fail.
|
||||
for (const workspace of this.values()) {
|
||||
await workspace.isInitialized.promise;
|
||||
}
|
||||
await Promise.all([...this.values()].map((w) => w.isInitialized.promise));
|
||||
|
||||
// The order of how we find the best matching workspace for the given file is
|
||||
// 1. The given file is the workspace itself (ex, a file being a virtual workspace itself).
|
||||
|
14
packages/pyright/package-lock.json
generated
14
packages/pyright/package-lock.json
generated
@ -18,7 +18,7 @@
|
||||
"copy-webpack-plugin": "^10.2.4",
|
||||
"esbuild-loader": "^2.20.0",
|
||||
"shx": "^0.3.4",
|
||||
"ts-loader": "^9.4.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "~4.4.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^4.10.0"
|
||||
@ -2242,9 +2242,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz",
|
||||
"integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==",
|
||||
"version": "9.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz",
|
||||
"integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
@ -4079,9 +4079,9 @@
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz",
|
||||
"integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==",
|
||||
"version": "9.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz",
|
||||
"integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
|
@ -28,7 +28,7 @@
|
||||
"copy-webpack-plugin": "^10.2.4",
|
||||
"esbuild-loader": "^2.20.0",
|
||||
"shx": "^0.3.4",
|
||||
"ts-loader": "^9.4.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "~4.4.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^4.10.0"
|
||||
|
98
packages/vscode-pyright/package-lock.json
generated
98
packages/vscode-pyright/package-lock.json
generated
@ -9,10 +9,10 @@
|
||||
"version": "1.1.287",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageclient": "8.1.0-next.1",
|
||||
"vscode-languageserver": "8.1.0-next.1",
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageclient": "8.1.0-next.4",
|
||||
"vscode-languageserver": "8.1.0-next.4",
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/copy-webpack-plugin": "^10.1.0",
|
||||
@ -21,7 +21,7 @@
|
||||
"copy-webpack-plugin": "^10.2.4",
|
||||
"detect-indent": "^6.1.0",
|
||||
"shx": "^0.3.4",
|
||||
"ts-loader": "^9.4.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "~4.4.4",
|
||||
"vsce": "^2.7.0",
|
||||
"webpack": "^5.75.0",
|
||||
@ -2819,9 +2819,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-loader": {
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz",
|
||||
"integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==",
|
||||
"version": "9.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz",
|
||||
"integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
@ -3027,21 +3027,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-jsonrpc": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-FiPG+9TuMIga3t+kkalQytwqMtJu1djI+Pq+Ut2tvAJpcNHDJ0PYdjFv5mgEvTEJLujrYwjWHVkNe+XfHPBD/w==",
|
||||
"version": "8.1.0-next.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.5.tgz",
|
||||
"integrity": "sha512-9l9lB8gXW1kPECKLC5Goc41pFztSCfODY3dvGaNTJ0KfRgwKIUyIhEBSdlWT2IU4uL4Tcl/zcitpb+Lj6QP7aQ==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageclient": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-lJraJ8IrqXr83ZciAs4dN32f9kEPuOb/FqAeUTgnW5cAxo0Qux0/EMgKyU33Qf9LdEI0I9iwRVxQWtawbyUUfg==",
|
||||
"version": "8.1.0-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0-next.4.tgz",
|
||||
"integrity": "sha512-dwo3Vf1aAb3o62mDhLHRGqYaLAYWN5RXAbHKL85Cs+yCJghxYzseuGGBvOUOH3BF5scnCU2BFrghekyP1xCUmQ==",
|
||||
"dependencies": {
|
||||
"minimatch": "^5.1.0",
|
||||
"semver": "^7.3.7",
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.67.0"
|
||||
@ -3067,29 +3067,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-u14Rk4JgXI+7iS6AEXI2pNc1dWh/5JEXtaqa4TeBECKJlN+5242mbGBBPaHMOE7sSI1Kh66XhEMZJhPYjUfjHw==",
|
||||
"version": "8.1.0-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.4.tgz",
|
||||
"integrity": "sha512-W+sdV5sgOTgE1bmEBdCrCpjfYIwD7f0ykwoPOTkvaNFdsgbMIvq4VZLjGMVnFR7U2tPa/w0Kn7lXodlSJudNmQ==",
|
||||
"dependencies": {
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
},
|
||||
"bin": {
|
||||
"installServerIntoExtension": "bin/installServerIntoExtension"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-protocol": {
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-vgjvPE0zox+1Fi4ljsSFJ+B3g8wGNbuAEEdulueVdv+R2VHtc06+dgxhWiG4LKPqXwjPDmiuxCnvd2xk3fzTTw==",
|
||||
"version": "3.17.3-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.4.tgz",
|
||||
"integrity": "sha512-G6XrjZGSe2LIo7uDa860JKX97sLKc1vQF4AU4SW8DI7NNVKxnCB+vEs8gYHmle7kD9v13PvFkDCBD5ApeONGNQ==",
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageserver-types": "3.17.2"
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageserver-types": "3.17.3-next.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-types": {
|
||||
"version": "3.17.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz",
|
||||
"integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA=="
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-i7HXZs5CdNibVHXZORZw9m5Bm0mfXiGhD/tZv6f7arBtz4iatgiiHu2qInxn0fKeahhMJoBbp6irhsL9+E3UAA=="
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "2.4.0",
|
||||
@ -5490,9 +5490,9 @@
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz",
|
||||
"integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==",
|
||||
"version": "9.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz",
|
||||
"integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
@ -5659,18 +5659,18 @@
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-FiPG+9TuMIga3t+kkalQytwqMtJu1djI+Pq+Ut2tvAJpcNHDJ0PYdjFv5mgEvTEJLujrYwjWHVkNe+XfHPBD/w=="
|
||||
"version": "8.1.0-next.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0-next.5.tgz",
|
||||
"integrity": "sha512-9l9lB8gXW1kPECKLC5Goc41pFztSCfODY3dvGaNTJ0KfRgwKIUyIhEBSdlWT2IU4uL4Tcl/zcitpb+Lj6QP7aQ=="
|
||||
},
|
||||
"vscode-languageclient": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-lJraJ8IrqXr83ZciAs4dN32f9kEPuOb/FqAeUTgnW5cAxo0Qux0/EMgKyU33Qf9LdEI0I9iwRVxQWtawbyUUfg==",
|
||||
"version": "8.1.0-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0-next.4.tgz",
|
||||
"integrity": "sha512-dwo3Vf1aAb3o62mDhLHRGqYaLAYWN5RXAbHKL85Cs+yCJghxYzseuGGBvOUOH3BF5scnCU2BFrghekyP1xCUmQ==",
|
||||
"requires": {
|
||||
"minimatch": "^5.1.0",
|
||||
"semver": "^7.3.7",
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
@ -5692,26 +5692,26 @@
|
||||
}
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "8.1.0-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.1.tgz",
|
||||
"integrity": "sha512-u14Rk4JgXI+7iS6AEXI2pNc1dWh/5JEXtaqa4TeBECKJlN+5242mbGBBPaHMOE7sSI1Kh66XhEMZJhPYjUfjHw==",
|
||||
"version": "8.1.0-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-8.1.0-next.4.tgz",
|
||||
"integrity": "sha512-W+sdV5sgOTgE1bmEBdCrCpjfYIwD7f0ykwoPOTkvaNFdsgbMIvq4VZLjGMVnFR7U2tPa/w0Kn7lXodlSJudNmQ==",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-vgjvPE0zox+1Fi4ljsSFJ+B3g8wGNbuAEEdulueVdv+R2VHtc06+dgxhWiG4LKPqXwjPDmiuxCnvd2xk3fzTTw==",
|
||||
"version": "3.17.3-next.4",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3-next.4.tgz",
|
||||
"integrity": "sha512-G6XrjZGSe2LIo7uDa860JKX97sLKc1vQF4AU4SW8DI7NNVKxnCB+vEs8gYHmle7kD9v13PvFkDCBD5ApeONGNQ==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageserver-types": "3.17.2"
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageserver-types": "3.17.3-next.1"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.17.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz",
|
||||
"integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA=="
|
||||
"version": "3.17.3-next.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3-next.1.tgz",
|
||||
"integrity": "sha512-i7HXZs5CdNibVHXZORZw9m5Bm0mfXiGhD/tZv6f7arBtz4iatgiiHu2qInxn0fKeahhMJoBbp6irhsL9+E3UAA=="
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "2.4.0",
|
||||
|
@ -929,10 +929,10 @@
|
||||
"webpack-dev": "npm run clean && webpack --mode development --watch --progress"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": "8.1.0-next.1",
|
||||
"vscode-languageclient": "8.1.0-next.1",
|
||||
"vscode-languageserver": "8.1.0-next.1",
|
||||
"vscode-languageserver-protocol": "3.17.3-next.1"
|
||||
"vscode-jsonrpc": "8.1.0-next.5",
|
||||
"vscode-languageclient": "8.1.0-next.4",
|
||||
"vscode-languageserver": "8.1.0-next.4",
|
||||
"vscode-languageserver-protocol": "3.17.3-next.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/copy-webpack-plugin": "^10.1.0",
|
||||
@ -941,7 +941,7 @@
|
||||
"copy-webpack-plugin": "^10.2.4",
|
||||
"detect-indent": "^6.1.0",
|
||||
"shx": "^0.3.4",
|
||||
"ts-loader": "^9.4.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "~4.4.4",
|
||||
"vsce": "^2.7.0",
|
||||
"webpack": "^5.75.0",
|
||||
|
Loading…
Reference in New Issue
Block a user