forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpydocstyle.ts
More file actions
107 lines (96 loc) · 4.98 KB
/
Copy pathpydocstyle.ts
File metadata and controls
107 lines (96 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'use strict';
import * as path from 'path';
import * as baseLinter from './baseLinter';
import {ILintMessage} from './baseLinter';
import {OutputChannel, window} from 'vscode';
import { exec } from 'child_process';
import {execPythonFile, IS_WINDOWS} from './../common/utils';
export class Linter extends baseLinter.BaseLinter {
constructor(outputChannel: OutputChannel, workspaceRootPath: string) {
super('pydocstyle', outputChannel, workspaceRootPath);
}
public isEnabled(): Boolean {
return this.pythonSettings.linting.pydocstyleEnabled;
}
public runLinter(filePath: string, txtDocumentLines: string[]): Promise<baseLinter.ILintMessage[]> {
if (!this.pythonSettings.linting.pydocstyleEnabled) {
return Promise.resolve([]);
}
let pydocStylePath = this.pythonSettings.linting.pydocStylePath;
let pydocstyleArgs = Array.isArray(this.pythonSettings.linting.pydocstleArgs) ? this.pythonSettings.linting.pydocstleArgs : [];
return new Promise<baseLinter.ILintMessage[]>(resolve => {
this.run(pydocStylePath, pydocstyleArgs.concat([filePath]), filePath, txtDocumentLines).then(messages => {
// All messages in pep8 are treated as warnings for now
messages.forEach(msg => {
msg.severity = baseLinter.LintMessageSeverity.Information;
});
resolve(messages);
});
});
}
protected run(commandLine: string, args: string[], filePath: string, txtDocumentLines: string[]): Promise<ILintMessage[]> {
let outputChannel = this.outputChannel;
let linterId = this.Id;
return new Promise<ILintMessage[]>((resolve, reject) => {
let fileDir = path.dirname(filePath);
execPythonFile(commandLine, args, this.workspaceRootPath, true).then(data => {
outputChannel.append('#'.repeat(10) + 'Linting Output - ' + this.Id + '#'.repeat(10) + '\n');
outputChannel.append(data);
let outputLines = data.split(/\r?\n/g);
let diagnostics: ILintMessage[] = [];
let baseFileName = path.basename(filePath);
// Remember, the first line of the response contains the file name and line number, the next line contains the error message
// So we have two lines per message, hence we need to take lines in pairs
let maxLines = this.pythonSettings.linting.maxNumberOfProblems * 2;
// First line is almost always empty
let oldOutputLines = outputLines.filter(line => line.length > 0);
outputLines = [];
for (let counter = 0; counter < oldOutputLines.length / 2; counter++) {
outputLines.push(oldOutputLines[2 * counter] + oldOutputLines[(2 * counter) + 1]);
}
outputLines = outputLines.filter((value, index) => {
return index < maxLines && value.indexOf(':') >= 0;
}).map(line => {
// Windows will have a : after the drive letter (e.g. c:\)
if (IS_WINDOWS) {
return line.substring(line.indexOf(baseFileName + ':') + baseFileName.length + 1).trim();
}
return line.substring(line.indexOf(':') + 1).trim();
});
// Iterate through the lines (skipping the messages)
// So, just iterate the response in pairs
outputLines.forEach(line => {
try {
if (line.trim().length === 0) {
return;
}
let lineNumber = parseInt(line.substring(0, line.indexOf(' ')));
let part = line.substring(line.indexOf(':') + 1).trim();
let code = part.substring(0, part.indexOf(':')).trim();
let message = part.substring(part.indexOf(':') + 1).trim();
let sourceLine = txtDocumentLines[lineNumber - 1];
let trmmedSourceLine = sourceLine.trim();
let sourceStart = sourceLine.indexOf(trmmedSourceLine);
let endCol = sourceStart + trmmedSourceLine.length;
diagnostics.push({
code: code,
message: message,
column: sourceStart,
line: lineNumber,
type: '',
provider: this.Id
});
}
catch (ex) {
// Hmm, need to handle this later
let y = '';
}
});
resolve(diagnostics);
}, error => {
this.handleError(this.Id, commandLine, error);
resolve([]);
});
});
}
}