Skip to content

Commit

Permalink
LInter issues
Browse files Browse the repository at this point in the history
  • Loading branch information
DonJayamanne committed Jan 18, 2019
1 parent 38be335 commit c83a3a5
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 96 deletions.
2 changes: 1 addition & 1 deletion src/client/application/diagnostics/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export abstract class BaseDiagnosticsService implements IDiagnosticsService {
this.filterService = serviceContainer.get<IDiagnosticFilterService>(IDiagnosticFilterService);
}
public abstract diagnose(resource: Resource): Promise<IDiagnostic[]>;
public abstract onHandle(diagnostics: IDiagnostic[]): Promise<void>;
public async handle(diagnostics: IDiagnostic[]): Promise<void> {
if (diagnostics.length === 0) {
return;
Expand All @@ -61,6 +60,7 @@ export abstract class BaseDiagnosticsService implements IDiagnosticsService {
sendTelemetryEvent(EventName.DIAGNOSTICS_MESSAGE, undefined, { code: diagnostic.code });
return this.supportedDiagnosticCodes.filter(item => item === diagnostic.code).length > 0;
}
protected abstract onHandle(diagnostics: IDiagnostic[]): Promise<void>;
/**
* Returns a key used to keep track of whether a diagnostic was handled or not.
* So as to prevent handling/displaying messages multiple times for the same diagnostic.
Expand Down
25 changes: 16 additions & 9 deletions src/client/application/diagnostics/checks/envPathVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ import { DiagnosticCodes } from '../constants';
import { DiagnosticCommandPromptHandlerServiceId, MessageCommandPrompt } from '../promptHandler';
import { DiagnosticScope, IDiagnostic, IDiagnosticHandlerService } from '../types';

const InvalidEnvPathVariableMessage = 'The environment variable \'{0}\' seems to have some paths containing the \'"\' character.' +
const InvalidEnvPathVariableMessage =
'The environment variable \'{0}\' seems to have some paths containing the \'"\' character.' +
' The existence of such a character is known to have caused the {1} extension to not load. If the extension fails to load please modify your paths to remove this \'"\' character.';

export class InvalidEnvironmentPathVariableDiagnostic extends BaseDiagnostic {
constructor(message: string, resource: Resource) {
super(DiagnosticCodes.InvalidEnvironmentPathVariableDiagnostic,
message, DiagnosticSeverity.Warning, DiagnosticScope.Global, resource);
super(
DiagnosticCodes.InvalidEnvironmentPathVariableDiagnostic,
message,
DiagnosticSeverity.Warning,
DiagnosticScope.Global,
resource
);
}
}

Expand All @@ -35,20 +41,21 @@ export class EnvironmentPathVariableDiagnosticsService extends BaseDiagnosticsSe
constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) {
super([DiagnosticCodes.InvalidEnvironmentPathVariableDiagnostic], serviceContainer);
this.platform = this.serviceContainer.get<IPlatformService>(IPlatformService);
this.messageService = serviceContainer.get<IDiagnosticHandlerService<MessageCommandPrompt>>(IDiagnosticHandlerService, DiagnosticCommandPromptHandlerServiceId);
this.messageService = serviceContainer.get<IDiagnosticHandlerService<MessageCommandPrompt>>(
IDiagnosticHandlerService,
DiagnosticCommandPromptHandlerServiceId
);
}
public async diagnose(resource: Resource): Promise<IDiagnostic[]> {
if (this.platform.isWindows &&
this.doesPathVariableHaveInvalidEntries()) {
if (this.platform.isWindows && this.doesPathVariableHaveInvalidEntries()) {
const env = this.serviceContainer.get<IApplicationEnvironment>(IApplicationEnvironment);
const message = InvalidEnvPathVariableMessage
.format(this.platform.pathVariableName, env.extensionName);
const message = InvalidEnvPathVariableMessage.format(this.platform.pathVariableName, env.extensionName);
return [new InvalidEnvironmentPathVariableDiagnostic(message, resource)];
} else {
return [];
}
}
public async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
// This class can only handle one type of diagnostic, hence just use first item in list.
if (diagnostics.length === 0 || !this.canHandle(diagnostics[0])) {
return;
Expand Down
39 changes: 28 additions & 11 deletions src/client/application/diagnostics/checks/invalidDebuggerType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ import { DiagnosticCodes } from '../constants';
import { DiagnosticCommandPromptHandlerServiceId, MessageCommandPrompt } from '../promptHandler';
import { DiagnosticScope, IDiagnostic, IDiagnosticHandlerService } from '../types';

const InvalidDebuggerTypeMessage = 'Your launch.json file needs to be updated to change the "pythonExperimental" debug ' +
const InvalidDebuggerTypeMessage =
'Your launch.json file needs to be updated to change the "pythonExperimental" debug ' +
'configurations to use the "python" debugger type, otherwise Python debugging may ' +
'not work. Would you like to automatically update your launch.json file now?';

export class InvalidDebuggerTypeDiagnostic extends BaseDiagnostic {
constructor(message: string, resource: Resource) {
super(DiagnosticCodes.InvalidDebuggerTypeDiagnostic,
message, DiagnosticSeverity.Error, DiagnosticScope.WorkspaceFolder,
resource);
super(
DiagnosticCodes.InvalidDebuggerTypeDiagnostic,
message,
DiagnosticSeverity.Error,
DiagnosticScope.WorkspaceFolder,
resource
);
}
}

Expand All @@ -39,7 +44,10 @@ export class InvalidDebuggerTypeDiagnosticsService extends BaseDiagnosticsServic
protected readonly fs: IFileSystem;
constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) {
super([DiagnosticCodes.InvalidEnvironmentPathVariableDiagnostic], serviceContainer);
this.messageService = serviceContainer.get<IDiagnosticHandlerService<MessageCommandPrompt>>(IDiagnosticHandlerService, DiagnosticCommandPromptHandlerServiceId);
this.messageService = serviceContainer.get<IDiagnosticHandlerService<MessageCommandPrompt>>(
IDiagnosticHandlerService,
DiagnosticCommandPromptHandlerServiceId
);
const cmdManager = serviceContainer.get<ICommandManager>(ICommandManager);
this.fs = this.serviceContainer.get<IFileSystem>(IFileSystem);
cmdManager.registerCommand(CommandName, this.fixLaunchJson, this);
Expand All @@ -51,7 +59,7 @@ export class InvalidDebuggerTypeDiagnosticsService extends BaseDiagnosticsServic
return [];
}
}
public async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
// This class can only handle one type of diagnostic, hence just use first item in list.
if (diagnostics.length === 0 || !this.canHandle(diagnostics[0])) {
return;
Expand All @@ -61,7 +69,10 @@ export class InvalidDebuggerTypeDiagnosticsService extends BaseDiagnosticsServic
const options = [
{
prompt: 'Yes, update launch.json',
command: commandFactory.createCommand(diagnostic, { type: 'executeVSCCommand', options: 'python.debugger.replaceExperimental' })
command: commandFactory.createCommand(diagnostic, {
type: 'executeVSCCommand',
options: 'python.debugger.replaceExperimental'
})
},
{
prompt: 'No, I will do it later'
Expand All @@ -76,15 +87,19 @@ export class InvalidDebuggerTypeDiagnosticsService extends BaseDiagnosticsServic
return false;
}

const results = await Promise.all(workspaceService.workspaceFolders!.map(workspaceFolder => this.isExperimentalDebuggerUsedInWorkspace(workspaceFolder)));
const results = await Promise.all(
workspaceService.workspaceFolders!.map(workspaceFolder =>
this.isExperimentalDebuggerUsedInWorkspace(workspaceFolder)
)
);
return results.filter(used => used === true).length > 0;
}
private getLaunchJsonFile(workspaceFolder: WorkspaceFolder) {
return path.join(workspaceFolder.uri.fsPath, '.vscode', 'launch.json');
}
private async isExperimentalDebuggerUsedInWorkspace(workspaceFolder: WorkspaceFolder) {
const launchJson = this.getLaunchJsonFile(workspaceFolder);
if (!await this.fs.fileExists(launchJson)) {
if (!(await this.fs.fileExists(launchJson))) {
return false;
}

Expand All @@ -97,10 +112,12 @@ export class InvalidDebuggerTypeDiagnosticsService extends BaseDiagnosticsServic
return false;
}

await Promise.all(workspaceService.workspaceFolders!.map(workspaceFolder => this.fixLaunchJsonInWorkspace(workspaceFolder)));
await Promise.all(
workspaceService.workspaceFolders!.map(workspaceFolder => this.fixLaunchJsonInWorkspace(workspaceFolder))
);
}
private async fixLaunchJsonInWorkspace(workspaceFolder: WorkspaceFolder) {
if (!await this.isExperimentalDebuggerUsedInWorkspace(workspaceFolder)) {
if (!(await this.isExperimentalDebuggerUsedInWorkspace(workspaceFolder))) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,49 +19,64 @@ import { BaseDiagnostic, BaseDiagnosticsService } from '../base';
import { IDiagnosticsCommandFactory } from '../commands/types';
import { DiagnosticCodes } from '../constants';
import { DiagnosticCommandPromptHandlerServiceId, MessageCommandPrompt } from '../promptHandler';
import { DiagnosticScope, IDiagnostic, IDiagnosticCommand, IDiagnosticHandlerService, IInvalidPythonPathInDebuggerService } from '../types';
import {
DiagnosticScope,
IDiagnostic,
IDiagnosticCommand,
IDiagnosticHandlerService,
IInvalidPythonPathInDebuggerService
} from '../types';

export class InvalidPythonPathInDebuggerSettingsDiagnostic extends BaseDiagnostic {
constructor(resource: Resource) {
super(DiagnosticCodes.InvalidPythonPathInDebuggerSettingsDiagnostic,
Diagnostics.invalidPythonPathInDebuggerSettings(), DiagnosticSeverity.Error, DiagnosticScope.WorkspaceFolder,
resource);
super(
DiagnosticCodes.InvalidPythonPathInDebuggerSettingsDiagnostic,
Diagnostics.invalidPythonPathInDebuggerSettings(),
DiagnosticSeverity.Error,
DiagnosticScope.WorkspaceFolder,
resource
);
}
}

export class InvalidPythonPathInDebuggerLaunchDiagnostic extends BaseDiagnostic {
constructor(resource: Resource) {
super(DiagnosticCodes.InvalidPythonPathInDebuggerLaunchDiagnostic,
Diagnostics.invalidPythonPathInDebuggerLaunch(), DiagnosticSeverity.Error, DiagnosticScope.WorkspaceFolder,
resource);
super(
DiagnosticCodes.InvalidPythonPathInDebuggerLaunchDiagnostic,
Diagnostics.invalidPythonPathInDebuggerLaunch(),
DiagnosticSeverity.Error,
DiagnosticScope.WorkspaceFolder,
resource
);
}
}

export const InvalidPythonPathInDebuggerServiceId = 'InvalidPythonPathInDebuggerServiceId';

@injectable()
export class InvalidPythonPathInDebuggerService extends BaseDiagnosticsService implements IInvalidPythonPathInDebuggerService {
constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer,
export class InvalidPythonPathInDebuggerService extends BaseDiagnosticsService
implements IInvalidPythonPathInDebuggerService {
constructor(
@inject(IServiceContainer) serviceContainer: IServiceContainer,
@inject(IWorkspaceService) private readonly workspace: IWorkspaceService,
@inject(IDiagnosticsCommandFactory) private readonly commandFactory: IDiagnosticsCommandFactory,
@inject(IInterpreterHelper) private readonly interpreterHelper: IInterpreterHelper,
@inject(IConfigurationService) private readonly configService: IConfigurationService,
@inject(IDiagnosticHandlerService) @named(DiagnosticCommandPromptHandlerServiceId) protected readonly messageService: IDiagnosticHandlerService<MessageCommandPrompt>) {
super([DiagnosticCodes.InvalidPythonPathInDebuggerSettingsDiagnostic, DiagnosticCodes.InvalidPythonPathInDebuggerLaunchDiagnostic], serviceContainer);
@inject(IDiagnosticHandlerService)
@named(DiagnosticCommandPromptHandlerServiceId)
protected readonly messageService: IDiagnosticHandlerService<MessageCommandPrompt>
) {
super(
[
DiagnosticCodes.InvalidPythonPathInDebuggerSettingsDiagnostic,
DiagnosticCodes.InvalidPythonPathInDebuggerLaunchDiagnostic
],
serviceContainer
);
}
public async diagnose(_resource: Resource): Promise<IDiagnostic[]> {
return [];
}
public async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
// This class can only handle one type of diagnostic, hence just use first item in list.
if (diagnostics.length === 0 || !this.canHandle(diagnostics[0])) {
return;
}
const diagnostic = diagnostics[0];
const commandPrompts = this.getCommandPrompts(diagnostic);

await this.messageService.handle(diagnostic, { commandPrompts });
}
public async validatePythonPath(pythonPath?: string, resource?: Uri) {
pythonPath = pythonPath ? this.resolveVariables(pythonPath, resource) : undefined;
let pathInLaunchJson = true;
Expand All @@ -85,6 +100,16 @@ export class InvalidPythonPathInDebuggerService extends BaseDiagnosticsService i
}
return false;
}
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
// This class can only handle one type of diagnostic, hence just use first item in list.
if (diagnostics.length === 0 || !this.canHandle(diagnostics[0])) {
return;
}
const diagnostic = diagnostics[0];
const commandPrompts = this.getCommandPrompts(diagnostic);

await this.messageService.handle(diagnostic, { commandPrompts });
}
protected resolveVariables(pythonPath: string, resource: Uri | undefined): string {
const workspaceFolder = resource ? this.workspace.getWorkspaceFolder(resource) : undefined;
const systemVariables = new SystemVariables(workspaceFolder ? workspaceFolder.uri.fsPath : undefined);
Expand All @@ -93,22 +118,30 @@ export class InvalidPythonPathInDebuggerService extends BaseDiagnosticsService i
private getCommandPrompts(diagnostic: IDiagnostic): { prompt: string; command?: IDiagnosticCommand }[] {
switch (diagnostic.code) {
case DiagnosticCodes.InvalidPythonPathInDebuggerSettingsDiagnostic: {
return [{
prompt: 'Select Python Interpreter',
command: this.commandFactory.createCommand(diagnostic, { type: 'executeVSCCommand', options: 'python.setInterpreter' })
}];
return [
{
prompt: 'Select Python Interpreter',
command: this.commandFactory.createCommand(diagnostic, {
type: 'executeVSCCommand',
options: 'python.setInterpreter'
})
}
];
}
case DiagnosticCodes.InvalidPythonPathInDebuggerLaunchDiagnostic: {
return [{
prompt: 'Open launch.json',
// tslint:disable-next-line:no-object-literal-type-assertion
command: {
diagnostic, invoke: async (): Promise<void> => {
const launchJson = this.getLaunchJsonFile(workspc.workspaceFolders![0]);
await openFile(launchJson);
return [
{
prompt: 'Open launch.json',
// tslint:disable-next-line:no-object-literal-type-assertion
command: {
diagnostic,
invoke: async (): Promise<void> => {
const launchJson = this.getLaunchJsonFile(workspc.workspaceFolders![0]);
await openFile(launchJson);
}
}
}
}];
];
}
default: {
throw new Error('Invalid diagnostic for \'InvalidPythonPathInDebuggerService\'');
Expand Down
26 changes: 18 additions & 8 deletions src/client/application/diagnostics/checks/lsNotSupported.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,37 @@ import { DiagnosticScope, IDiagnostic, IDiagnosticHandlerService } from '../type

export class LSNotSupportedDiagnostic extends BaseDiagnostic {
constructor(message: string, resource: Resource) {
super(DiagnosticCodes.LSNotSupportedDiagnostic,
message, DiagnosticSeverity.Warning, DiagnosticScope.Global, resource);
super(
DiagnosticCodes.LSNotSupportedDiagnostic,
message,
DiagnosticSeverity.Warning,
DiagnosticScope.Global,
resource
);
}
}

export const LSNotSupportedDiagnosticServiceId = 'LSNotSupportedDiagnosticServiceId';

export class LSNotSupportedDiagnosticService extends BaseDiagnosticsService {
constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer,
@inject(ILanguageServerCompatibilityService) private readonly lsCompatibility: ILanguageServerCompatibilityService,
@inject(IDiagnosticHandlerService) @named(DiagnosticCommandPromptHandlerServiceId) protected readonly messageService: IDiagnosticHandlerService<MessageCommandPrompt>) {
constructor(
@inject(IServiceContainer) serviceContainer: IServiceContainer,
@inject(ILanguageServerCompatibilityService)
private readonly lsCompatibility: ILanguageServerCompatibilityService,
@inject(IDiagnosticHandlerService)
@named(DiagnosticCommandPromptHandlerServiceId)
protected readonly messageService: IDiagnosticHandlerService<MessageCommandPrompt>
) {
super([DiagnosticCodes.LSNotSupportedDiagnostic], serviceContainer);
}
public async diagnose(resource: Resource): Promise<IDiagnostic[]>{
public async diagnose(resource: Resource): Promise<IDiagnostic[]> {
if (await this.lsCompatibility.isSupported()) {
return [];
} else{
} else {
return [new LSNotSupportedDiagnostic(Diagnostics.lsNotSupported(), resource)];
}
}
public async onHandle(diagnostics: IDiagnostic[]): Promise<void>{
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
if (diagnostics.length === 0 || !this.canHandle(diagnostics[0])) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class InvalidMacPythonInterpreterService extends BaseDiagnosticsService {

return [new InvalidMacPythonInterpreterDiagnostic(DiagnosticCodes.MacInterpreterSelectedAndHaveOtherInterpretersDiagnostic, resource)];
}
public async handle(diagnostics: IDiagnostic[]): Promise<void> {
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
if (diagnostics.length === 0) {
return;
}
Expand Down
Loading

0 comments on commit c83a3a5

Please sign in to comment.