From 997635ac0d79a9f6e0cc45458c77a1e5ff0c7b07 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Fri, 8 Jun 2018 14:07:24 -0700 Subject: [PATCH 1/8] LS symbol providers --- src/client/activation/classic.ts | 6 +++++- src/client/extension.ts | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/client/activation/classic.ts b/src/client/activation/classic.ts index 17ca5c929047..72745cab86be 100644 --- a/src/client/activation/classic.ts +++ b/src/client/activation/classic.ts @@ -17,6 +17,7 @@ import { PythonRenameProvider } from '../providers/renameProvider'; import { PythonSignatureProvider } from '../providers/signatureProvider'; import { PythonSymbolProvider } from '../providers/symbolProvider'; import { IUnitTestManagementService } from '../unittests/types'; +import { WorkspaceSymbols } from '../workspaceSymbols/main'; import { IExtensionActivator } from './types'; @injectable() @@ -46,7 +47,10 @@ export class ClassicExtensionActivator implements IExtensionActivator { context.subscriptions.push(languages.registerCompletionItemProvider(this.documentSelector, new PythonCompletionItemProvider(jediFactory, this.serviceManager), '.')); context.subscriptions.push(languages.registerCodeLensProvider(this.documentSelector, this.serviceManager.get(IShebangCodeLensProvider))); - const symbolProvider = new PythonSymbolProvider(this.serviceManager.get(IServiceContainer), jediFactory); + const serviceContainer = this.serviceManager.get(IServiceContainer); + context.subscriptions.push(new WorkspaceSymbols(serviceContainer)); + + const symbolProvider = new PythonSymbolProvider(serviceContainer, jediFactory); context.subscriptions.push(languages.registerDocumentSymbolProvider(this.documentSelector, symbolProvider)); const pythonSettings = this.serviceManager.get(IConfigurationService).getSettings(); diff --git a/src/client/extension.ts b/src/client/extension.ts index 2228cca81495..43d42ac389a6 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -56,7 +56,6 @@ import { BlockFormatProviders } from './typeFormatters/blockFormatProvider'; import { OnEnterFormatter } from './typeFormatters/onEnterFormatter'; import { TEST_OUTPUT_CHANNEL } from './unittests/common/constants'; import { registerTypes as unitTestsRegisterTypes } from './unittests/serviceRegistry'; -import { WorkspaceSymbols } from './workspaceSymbols/main'; const activationDeferred = createDeferred(); export const activated = activationDeferred.promise; @@ -143,7 +142,6 @@ export async function activate(context: ExtensionContext) { context.subscriptions.push(new ReplProvider(serviceContainer)); context.subscriptions.push(new TerminalProvider(serviceContainer)); - context.subscriptions.push(new WorkspaceSymbols(serviceContainer)); type ConfigurationProvider = BaseConfigurationProvider; serviceContainer.getAll(IDebugConfigurationProvider).forEach(debugConfig => { From efb84ae153ee13fd40910ae33799c8081cb52783 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Thu, 21 Jun 2018 14:37:08 -0700 Subject: [PATCH 2/8] Typeshed paths --- package.json | 9 +++++++++ src/client/activation/analysis.ts | 4 +++- src/client/common/configSettings.ts | 3 ++- src/client/common/types.ts | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 854b86447122..4bd7fa61c640 100644 --- a/package.json +++ b/package.json @@ -1173,6 +1173,15 @@ "description": "Controls appearance of methods with double underscores in the completion list.", "scope": "resource" }, + "python.autoComplete.typeshedPaths": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "Specifies paths to local typeshed repository clone(s) for the Python language server.", + "scope": "resource" + }, "python.disableInstallationCheck": { "type": "boolean", "default": false, diff --git a/src/client/activation/analysis.ts b/src/client/activation/analysis.ts index 536530d74050..408a211fa2fd 100644 --- a/src/client/activation/analysis.ts +++ b/src/client/activation/analysis.ts @@ -190,7 +190,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { const interpreterDataService = new InterpreterDataService(this.context, this.services); interpreterData = await interpreterDataService.getInterpreterData(); } catch (ex) { - this.appShell.showErrorMessage('Unable to determine path to the Python interpreter. IntelliSense will be limited.'); + this.appShell.showWarningMessage('Unable to determine path to the Python interpreter. IntelliSense will be limited.'); } this.interpreterHash = interpreterData ? interpreterData.hash : ''; @@ -245,6 +245,8 @@ export class AnalysisExtensionActivator implements IExtensionActivator { trimDocumentationText: false, maxDocumentationTextLength: 0 }, + searchPaths, + typeshedPaths: settings.autoComplete.typeshedPaths, asyncStartup: true, excludeFiles: excludeFiles, testEnvironment: isTestExecution() diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts index d15bfefee183..4c55c4a2b3a3 100644 --- a/src/client/common/configSettings.ts +++ b/src/client/common/configSettings.ts @@ -233,7 +233,8 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { extraPaths: [], addBrackets: false, preloadModules: [], - showAdvancedMembers: false + showAdvancedMembers: false, + typeshedPaths: [] }; // tslint:disable-next-line:no-backbone-get-set-outside-model no-non-null-assertion diff --git a/src/client/common/types.ts b/src/client/common/types.ts index 733f0ffbee84..c671ae4e3bd5 100644 --- a/src/client/common/types.ts +++ b/src/client/common/types.ts @@ -221,6 +221,7 @@ export interface IAutoCompleteSettings { readonly extraPaths: string[]; readonly preloadModules: string[]; readonly showAdvancedMembers: boolean; + readonly typeshedPaths: string[]; } export interface IWorkspaceSymbolSettings { readonly enabled: boolean; @@ -237,6 +238,7 @@ export interface ITerminalSettings { } export interface IPythonAnalysisEngineSettings { readonly showAdvancedMembers: boolean; + readonly typeshedPaths: string[]; } export const IConfigurationService = Symbol('IConfigurationService'); From 69c7d5f532221665f384d44c5749ab7af5d2f0ac Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Thu, 21 Jun 2018 14:51:36 -0700 Subject: [PATCH 3/8] Typeshed submodule --- .gitmodules | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..e3e61d18b9c1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "typeshed"] + path = typeshed + url = https://github.com/python/typeshed + branch = master \ No newline at end of file From 5bf6f47cf9cb9ba2ad0f2752efedccbd6a8c4ebb Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Thu, 21 Jun 2018 16:08:17 -0700 Subject: [PATCH 4/8] Add submodule --- .gitmodules | 2 +- src/client/activation/analysis.ts | 17 ++++++++++++----- typeshed | 1 + 3 files changed, 14 insertions(+), 6 deletions(-) create mode 160000 typeshed diff --git a/.gitmodules b/.gitmodules index e3e61d18b9c1..a57bae098756 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "typeshed"] path = typeshed - url = https://github.com/python/typeshed + url = https://github.com/python/typeshed.git branch = master \ No newline at end of file diff --git a/src/client/activation/analysis.ts b/src/client/activation/analysis.ts index 408a211fa2fd..01d2e911e902 100644 --- a/src/client/activation/analysis.ts +++ b/src/client/activation/analysis.ts @@ -204,13 +204,16 @@ export class AnalysisExtensionActivator implements IExtensionActivator { properties['PrefixPath'] = interpreterData.prefix; } - let searchPaths = interpreterData ? interpreterData.searchPaths : ''; + let searchPathsString = interpreterData ? interpreterData.searchPaths : ''; + let typeshedPaths: string[] = []; + const settings = this.configuration.getSettings(); if (settings.autoComplete) { const extraPaths = settings.autoComplete.extraPaths; if (extraPaths && extraPaths.length > 0) { - searchPaths = `${searchPaths};${extraPaths.join(';')}`; + searchPathsString = `${searchPathsString};${extraPaths.join(';')}`; } + typeshedPaths = settings.autoComplete.typeshedPaths; } // tslint:disable-next-line:no-string-literal @@ -219,9 +222,13 @@ export class AnalysisExtensionActivator implements IExtensionActivator { // Make sure paths do not contain multiple slashes so file URIs // in VS Code (Node.js) and in the language server (.NET) match. // Note: for the language server paths separator is always ; - searchPaths = searchPaths.split(path.delimiter).map(p => path.normalize(p)).join(';'); + const searchPaths = searchPathsString.split(path.delimiter).map(p => path.normalize(p)); // tslint:disable-next-line:no-string-literal - properties['SearchPaths'] = `${searchPaths};${pythonPath}`; + properties['SearchPaths'] = `${searchPaths.join(';')};${pythonPath}`; + + if (!typeshedPaths || typeshedPaths.length === 0) { + typeshedPaths = [path.join(this.context.extensionPath, 'typeshed')]; + } const selector = [{ language: PYTHON, scheme: 'file' }]; const excludeFiles = this.getExcludedFiles(); @@ -246,7 +253,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { maxDocumentationTextLength: 0 }, searchPaths, - typeshedPaths: settings.autoComplete.typeshedPaths, + typeStubSearchPaths: typeshedPaths, asyncStartup: true, excludeFiles: excludeFiles, testEnvironment: isTestExecution() diff --git a/typeshed b/typeshed new file mode 160000 index 000000000000..95eff73ab209 --- /dev/null +++ b/typeshed @@ -0,0 +1 @@ +Subproject commit 95eff73ab2092f2c3158198d404a921447172418 From cdd44375cbdb0df864ae750d9556bbe1a5081fd5 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Tue, 26 Jun 2018 13:13:21 -0700 Subject: [PATCH 5/8] New settings --- package.json | 15 ++++++ src/client/activation/analysis.ts | 84 +++++++++++++++++------------ src/client/common/configSettings.ts | 10 ++++ src/client/common/types.ts | 6 +-- 4 files changed, 77 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 4bd7fa61c640..475fddd012fa 100644 --- a/package.json +++ b/package.json @@ -1275,6 +1275,21 @@ "description": "Path to directory containing the Jedi library (this path will contain the 'Jedi' sub directory).", "scope": "resource" }, + "python.analysis.openFilesOnly": { + "type": "boolean", + "default": false, + "description": "Only show errors and warnings for open files rather than for the entire workspace.", + "scope": "resource" + }, + "python.analysis.typeshedPaths": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "Paths to look for typeshed modules.", + "scope": "resource" + }, "python.linting.enabled": { "type": "boolean", "default": true, diff --git a/src/client/activation/analysis.ts b/src/client/activation/analysis.ts index 01d2e911e902..893e27e280be 100644 --- a/src/client/activation/analysis.ts +++ b/src/client/activation/analysis.ts @@ -6,12 +6,12 @@ import * as path from 'path'; import { OutputChannel, Uri } from 'vscode'; import { Disposable, LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient'; import { IApplicationShell, ICommandManager, IWorkspaceService } from '../common/application/types'; +import { PythonSettings } from '../common/configSettings'; import { isTestExecution, STANDARD_OUTPUT_CHANNEL } from '../common/constants'; import { createDeferred, Deferred } from '../common/helpers'; import { IFileSystem, IPlatformService } from '../common/platform/types'; import { StopWatch } from '../common/stopWatch'; import { IConfigurationService, IExtensionContext, IOutputChannel } from '../common/types'; -import { IInterpreterService } from '../interpreter/contracts'; import { IServiceContainer } from '../ioc/types'; import { PYTHON_ANALYSIS_ENGINE_DOWNLOADED, @@ -38,7 +38,6 @@ export class AnalysisExtensionActivator implements IExtensionActivator { private readonly fs: IFileSystem; private readonly sw = new StopWatch(); private readonly platformData: PlatformData; - private readonly interpreterService: IInterpreterService; private readonly startupCompleted: Deferred; private readonly disposables: Disposable[] = []; private readonly context: IExtensionContext; @@ -47,6 +46,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { private languageClient: LanguageClient | undefined; private interpreterHash: string = ''; + private excludedFiles: string[] = []; private loadExtensionArgs: {} | undefined; constructor(@inject(IServiceContainer) private readonly services: IServiceContainer) { @@ -56,7 +56,6 @@ export class AnalysisExtensionActivator implements IExtensionActivator { this.output = this.services.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); this.fs = this.services.get(IFileSystem); this.platformData = new PlatformData(services.get(IPlatformService), this.fs); - this.interpreterService = this.services.get(IInterpreterService); this.workspace = this.services.get(IWorkspaceService); // Currently only a single root. Multi-root support is future. @@ -76,6 +75,8 @@ export class AnalysisExtensionActivator implements IExtensionActivator { } } )); + + (this.configuration.getSettings() as PythonSettings).addListener('change', this.onSettingsChanged); } public async activate(): Promise { @@ -84,7 +85,6 @@ export class AnalysisExtensionActivator implements IExtensionActivator { if (!clientOptions) { return false; } - this.disposables.push(this.interpreterService.onDidChangeInterpreter(() => this.restartLanguageServer())); return this.startLanguageServer(clientOptions); } @@ -96,19 +96,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { for (const d of this.disposables) { d.dispose(); } - } - - private async restartLanguageServer(): Promise { - if (!this.context) { - return; - } - const ids = new InterpreterDataService(this.context, this.services); - const idata = await ids.getInterpreterData(); - if (!idata || idata.hash !== this.interpreterHash) { - this.interpreterHash = idata ? idata.hash : ''; - await this.deactivate(); - await this.activate(); - } + (this.configuration.getSettings() as PythonSettings).removeListener('change', this.onSettingsChanged); } private async startLanguageServer(clientOptions: LanguageClientOptions): Promise { @@ -190,7 +178,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { const interpreterDataService = new InterpreterDataService(this.context, this.services); interpreterData = await interpreterDataService.getInterpreterData(); } catch (ex) { - this.appShell.showWarningMessage('Unable to determine path to the Python interpreter. IntelliSense will be limited.'); + this.appShell.showErrorMessage('Unable to determine path to the Python interpreter. IntelliSense will be limited.'); } this.interpreterHash = interpreterData ? interpreterData.hash : ''; @@ -204,34 +192,30 @@ export class AnalysisExtensionActivator implements IExtensionActivator { properties['PrefixPath'] = interpreterData.prefix; } - let searchPathsString = interpreterData ? interpreterData.searchPaths : ''; - let typeshedPaths: string[] = []; + // tslint:disable-next-line:no-string-literal + properties['DatabasePath'] = path.join(this.context.extensionPath, analysisEngineFolder); + let searchPaths = interpreterData ? interpreterData.searchPaths.split(path.delimiter) : []; const settings = this.configuration.getSettings(); if (settings.autoComplete) { const extraPaths = settings.autoComplete.extraPaths; if (extraPaths && extraPaths.length > 0) { - searchPathsString = `${searchPathsString};${extraPaths.join(';')}`; + searchPaths.push(...extraPaths); } - typeshedPaths = settings.autoComplete.typeshedPaths; } - // tslint:disable-next-line:no-string-literal - properties['DatabasePath'] = path.join(this.context.extensionPath, analysisEngineFolder); - // Make sure paths do not contain multiple slashes so file URIs // in VS Code (Node.js) and in the language server (.NET) match. // Note: for the language server paths separator is always ; - const searchPaths = searchPathsString.split(path.delimiter).map(p => path.normalize(p)); - // tslint:disable-next-line:no-string-literal - properties['SearchPaths'] = `${searchPaths.join(';')};${pythonPath}`; + searchPaths.push(pythonPath); + searchPaths = searchPaths.map(p => path.normalize(p)); - if (!typeshedPaths || typeshedPaths.length === 0) { - typeshedPaths = [path.join(this.context.extensionPath, 'typeshed')]; - } + const typeStubSearchPaths = settings.analysis.typeshedPaths && settings.analysis.typeshedPaths.length > 0 + ? settings.analysis.typeshedPaths + : [path.join(this.context.extensionPath, 'typeshed')]; const selector = [{ language: PYTHON, scheme: 'file' }]; - const excludeFiles = this.getExcludedFiles(); + this.excludedFiles = this.getExcludedFiles(); // Options to control the language client return { @@ -253,9 +237,8 @@ export class AnalysisExtensionActivator implements IExtensionActivator { maxDocumentationTextLength: 0 }, searchPaths, - typeStubSearchPaths: typeshedPaths, - asyncStartup: true, - excludeFiles: excludeFiles, + typeStubSearchPaths, + excludeFiles: this.excludedFiles, testEnvironment: isTestExecution() } }; @@ -289,4 +272,35 @@ export class AnalysisExtensionActivator implements IExtensionActivator { .forEach(p => list.push(p)); } } + + private async onSettingsChanged(): Promise { + const ids = new InterpreterDataService(this.context, this.services); + const idata = await ids.getInterpreterData(); + if (!idata || idata.hash !== this.interpreterHash) { + this.interpreterHash = idata ? idata.hash : ''; + await this.restartLanguageServer(); + return; + } + + const excludedFiles = this.getExcludedFiles(); + if (this.excludedFiles.length !== excludedFiles.length) { + await this.restartLanguageServer(); + return; + } + + for (let i = 0; i < this.excludedFiles.length; i += 1) { + if (this.excludedFiles[i] !== excludedFiles[i]) { + await this.restartLanguageServer(); + return; + } + } + } + + private async restartLanguageServer(): Promise { + if (!this.context) { + return; + } + await this.deactivate(); + await this.activate(); + } } diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts index 4c55c4a2b3a3..fe3b4d570b7b 100644 --- a/src/client/common/configSettings.ts +++ b/src/client/common/configSettings.ts @@ -8,6 +8,7 @@ import { sendTelemetryEvent } from '../telemetry'; import { COMPLETION_ADD_BRACKETS, FORMAT_ON_TYPE } from '../telemetry/constants'; import { isTestExecution } from './constants'; import { + IAnalysisSettings, IAutoCompleteSettings, IFormattingSettings, ILintingSettings, @@ -44,6 +45,7 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { public workspaceSymbols!: IWorkspaceSymbolSettings; public disableInstallationChecks = false; public globalModuleInstallation = false; + public analysis!: IAnalysisSettings; private workspaceRoot: Uri; private disposables: Disposable[] = []; @@ -147,6 +149,14 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { this.linting = lintingSettings; } + // tslint:disable-next-line:no-backbone-get-set-outside-model no-non-null-assertion + const analysisSettings = systemVariables.resolveAny(pythonSettings.get('analysis'))!; + if (this.analysis) { + Object.assign(this.analysis, analysisSettings); + } else { + this.analysis = analysisSettings; + } + this.disableInstallationChecks = pythonSettings.get('disableInstallationCheck') === true; this.globalModuleInstallation = pythonSettings.get('globalModuleInstallation') === true; diff --git a/src/client/common/types.ts b/src/client/common/types.ts index c671ae4e3bd5..cb3f8575589e 100644 --- a/src/client/common/types.ts +++ b/src/client/common/types.ts @@ -133,6 +133,7 @@ export interface IPythonSettings { readonly envFile: string; readonly disableInstallationChecks: boolean; readonly globalModuleInstallation: boolean; + readonly analysis: IAnalysisSettings; } export interface ISortImportSettings { readonly path: string; @@ -236,13 +237,12 @@ export interface ITerminalSettings { readonly launchArgs: string[]; readonly activateEnvironment: boolean; } -export interface IPythonAnalysisEngineSettings { - readonly showAdvancedMembers: boolean; +export interface IAnalysisSettings { + readonly openFilesOnly: boolean; readonly typeshedPaths: string[]; } export const IConfigurationService = Symbol('IConfigurationService'); - export interface IConfigurationService { getSettings(resource?: Uri): IPythonSettings; isTestExecution(): boolean; From e34cebb53f93ae16717e453351deb51eabc03aaa Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Wed, 27 Jun 2018 15:29:45 -0700 Subject: [PATCH 6/8] Add diagnostics control settings --- package.json | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/package.json b/package.json index 475fddd012fa..41d150e6ea18 100644 --- a/package.json +++ b/package.json @@ -1290,6 +1290,42 @@ "description": "Paths to look for typeshed modules.", "scope": "resource" }, + "python.analysis.errors": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "List of diagnostics messages to be shown as errors.", + "scope": "resource" + }, + "python.analysis.warnings": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "List of diagnostics messages to be shown as warnings.", + "scope": "resource" + }, + "python.analysis.information": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "List of diagnostics messages to be shown as information.", + "scope": "resource" + }, + "python.analysis.disabled": { + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "description": "List of suppressed diagnostic messages.", + "scope": "resource" + }, "python.linting.enabled": { "type": "boolean", "default": true, From 117f7ee2f370b85287bb888ed4b390e3f43ce254 Mon Sep 17 00:00:00 2001 From: MikhailArkhipov Date: Wed, 27 Jun 2018 15:55:15 -0700 Subject: [PATCH 7/8] Add typeshed paths change check --- src/client/activation/analysis.ts | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/client/activation/analysis.ts b/src/client/activation/analysis.ts index 3c125ccd3431..3c50866ae56c 100644 --- a/src/client/activation/analysis.ts +++ b/src/client/activation/analysis.ts @@ -11,7 +11,7 @@ import { isTestExecution, STANDARD_OUTPUT_CHANNEL } from '../common/constants'; import { createDeferred, Deferred } from '../common/helpers'; import { IFileSystem, IPlatformService } from '../common/platform/types'; import { StopWatch } from '../common/stopWatch'; -import { IConfigurationService, IExtensionContext, IOutputChannel } from '../common/types'; +import { IConfigurationService, IExtensionContext, IOutputChannel, IPythonSettings } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { PYTHON_ANALYSIS_ENGINE_DOWNLOADED, @@ -47,6 +47,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { private languageClient: LanguageClient | undefined; private interpreterHash: string = ''; private excludedFiles: string[] = []; + private typeshedPaths: string[] = []; private loadExtensionArgs: {} | undefined; constructor(@inject(IServiceContainer) private readonly services: IServiceContainer) { @@ -210,12 +211,9 @@ export class AnalysisExtensionActivator implements IExtensionActivator { searchPaths.push(pythonPath); searchPaths = searchPaths.map(p => path.normalize(p)); - const typeStubSearchPaths = settings.analysis.typeshedPaths && settings.analysis.typeshedPaths.length > 0 - ? settings.analysis.typeshedPaths - : [path.join(this.context.extensionPath, 'typeshed')]; - const selector = [{ language: PYTHON, scheme: 'file' }]; this.excludedFiles = this.getExcludedFiles(); + this.typeshedPaths = this.getTypeshedPaths(settings); // Options to control the language client return { @@ -237,7 +235,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { maxDocumentationTextLength: 0 }, searchPaths, - typeStubSearchPaths, + typeStubSearchPaths: this.typeshedPaths, excludeFiles: this.excludedFiles, testEnvironment: isTestExecution() } @@ -273,6 +271,12 @@ export class AnalysisExtensionActivator implements IExtensionActivator { } } + private getTypeshedPaths(settings: IPythonSettings): string[] { + return settings.analysis.typeshedPaths && settings.analysis.typeshedPaths.length > 0 + ? settings.analysis.typeshedPaths + : [path.join(this.context.extensionPath, 'typeshed')]; + } + private async onSettingsChanged(): Promise { const ids = new InterpreterDataService(this.context, this.services); const idata = await ids.getInterpreterData(); @@ -283,13 +287,21 @@ export class AnalysisExtensionActivator implements IExtensionActivator { } const excludedFiles = this.getExcludedFiles(); - if (this.excludedFiles.length !== excludedFiles.length) { + await this.restartLanguageServerIfArrayChanged(this.excludedFiles, excludedFiles); + + const settings = this.configuration.getSettings(); + const typeshedPaths = this.getTypeshedPaths(settings); + await this.restartLanguageServerIfArrayChanged(this.typeshedPaths, typeshedPaths); + } + + private async restartLanguageServerIfArrayChanged(oldArray: string[], newArray: string[]): Promise { + if (newArray.length !== oldArray.length) { await this.restartLanguageServer(); return; } - for (let i = 0; i < this.excludedFiles.length; i += 1) { - if (this.excludedFiles[i] !== excludedFiles[i]) { + for (let i = 0; i < oldArray.length; i += 1) { + if (oldArray[i] !== newArray[i]) { await this.restartLanguageServer(); return; } From 781ccb943d6aa501d15d2cf0c3da7face9273721 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Thu, 28 Jun 2018 17:54:57 -0700 Subject: [PATCH 8/8] Exclude some typeshed files from packages --- .vscodeignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.vscodeignore b/.vscodeignore index f6ba7c39ff26..2bae3e5be984 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -46,5 +46,13 @@ scripts/** src/** test/** tmp/** +typeshed/tests/** +typeshed/.flake8 +typeshed/.git +typeshed/.gitignore +typeshed/.travis.yml +typeshed/CONTRIBUTING.md +typeshed/README.md +typeshed/*.txt typings/** vsc-extension-quickstart.md