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:
Heejae Chang 2023-01-04 14:07:31 -08:00 committed by GitHub
parent ca078abc07
commit b78a9e4bd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1541 additions and 667 deletions

536
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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",

View File

@ -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",

View File

@ -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;
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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: {

View File

@ -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 };

View File

@ -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;

View File

@ -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);

View File

@ -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;

View 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',
},
],
},
});
});

View File

@ -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 });

View File

@ -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,

View File

@ -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));
}

View 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' });
});

View File

@ -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', () => {

View 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) {

View File

@ -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).

View File

@ -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",

View File

@ -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"

View File

@ -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",

View File

@ -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",