1- ' use strict' ;
1+ " use strict" ;
22
3- import * as path from 'path' ;
4- import * as baseLinter from './baseLinter' ;
5- import { OutputChannel , workspace } from 'vscode' ;
3+ import * as path from "path" ;
4+ import * as baseLinter from "./baseLinter" ;
5+ import { OutputChannel , workspace , window } from "vscode" ;
6+ import { sendCommand } from "./../common/childProc" ;
67
7- const PROSPECTOR_COMMANDLINE = " --output-format=vscode" ;
8-
9- const REGEX = '(?<line>\\d+),(?<column>\\d+),(?<type>[\\w-]+),(?<code>[\\w-]+):(?<message>.*)\\r?(\\n|$)' ;
8+ const PROSPECTOR_COMMANDLINE = " --absolute-paths --output-format=json" ;
109
10+ interface IProspectorResponse {
11+ messages : IProspectorMessage [ ] ;
12+ }
13+ interface IProspectorMessage {
14+ source : "string" ;
15+ message : "string" ;
16+ code : "string" ;
17+ location : IProspectorLocation ;
18+ }
19+ interface IProspectorLocation {
20+ function : string ;
21+ path : string ;
22+ line : number ;
23+ character : number ;
24+ module : "beforeFormat" ;
25+ }
1126
1227export class Linter extends baseLinter . BaseLinter {
1328 constructor ( outputChannel : OutputChannel ) {
@@ -22,21 +37,53 @@ export class Linter extends baseLinter.BaseLinter {
2237 return Promise . resolve ( [ ] ) ;
2338 }
2439
25- var prospectorPath = this . pythonSettings . linting . prospectorPath ;
26- var prospectorSourcePath = this . pythonSettings . linting . prospectorSourcePath ;
27- var prospectorExtraCommands = this . pythonSettings . linting . prospectorExtraCommands ;
28- // prospector works best with relative path
29- var fileName = filePath . replace ( path . join ( workspace . rootPath , prospectorSourcePath , '/' ) , '' ) ;
30- var cmdLine = ` ${ prospectorPath } ${ PROSPECTOR_COMMANDLINE } ${ prospectorExtraCommands } " ${ fileName } "` ;
40+ let prospectorPath = this . pythonSettings . linting . prospectorPath ;
41+ let prospectorExtraCommands = this . pythonSettings . linting . prospectorExtraCommands ;
42+ let cmdLine = ` ${ prospectorPath } ${ PROSPECTOR_COMMANDLINE } ${ prospectorExtraCommands } " ${ filePath } "` ;
43+ let outputChannel = this . outputChannel ;
44+ let linterId = this . Id ;
45+
3146 return new Promise < baseLinter . ILintMessage [ ] > ( ( resolve , reject ) => {
32- this . run ( cmdLine , filePath , txtDocumentLines , path . join ( workspace . rootPath , prospectorSourcePath ) , REGEX ) . then ( messages => {
33- //All messages in prospector are treated as warn, ings for now
34- messages . forEach ( msg => {
35- msg . severity = baseLinter . LintMessageSeverity . Information ;
47+ sendCommand ( cmdLine , workspace . rootPath , false ) . then ( data => {
48+ outputChannel . clear ( ) ;
49+ let parsedData : IProspectorResponse ;
50+ try {
51+ parsedData = JSON . parse ( data ) ;
52+ }
53+ catch ( ex ) {
54+ outputChannel . append ( data ) ;
55+ return resolve ( [ ] ) ;
56+ }
57+ let diagnostics : baseLinter . ILintMessage [ ] = [ ] ;
58+ parsedData . messages . filter ( ( value , index ) => index <= this . pythonSettings . linting . maxNumberOfProblems ) . forEach ( msg => {
59+
60+ let sourceLine = txtDocumentLines [ msg . location . line - 1 ] ;
61+ let sourceStart = sourceLine . substring ( msg . location . character ) ;
62+ let endCol = txtDocumentLines [ msg . location . line - 1 ] . length ;
63+
64+ // try to get the first word from the starting position
65+ let possibleProblemWords = sourceStart . match ( / \w + / g) ;
66+ let possibleWord : string ;
67+ if ( possibleProblemWords != null && possibleProblemWords . length > 0 && sourceStart . startsWith ( possibleProblemWords [ 0 ] ) ) {
68+ possibleWord = possibleProblemWords [ 0 ] ;
69+ }
70+
71+ diagnostics . push ( {
72+ code : msg . code ,
73+ message : msg . message ,
74+ column : msg . location . character ,
75+ line : msg . location . line ,
76+ possibleWord : possibleWord ,
77+ type : msg . code ,
78+ provider : `${ this . Id } -${ msg . source } `
79+ } ) ;
3680 } ) ;
3781
38- resolve ( messages ) ;
39- } , reject ) ;
82+ resolve ( diagnostics ) ;
83+ } ) . catch ( error => {
84+ outputChannel . appendLine ( `Linting with ${ linterId } failed. If not installed please turn if off in settings.\n ${ error } ` ) ;
85+ window . showInformationMessage ( `Linting with ${ linterId } failed. If not installed please turn if off in settings. View Python output for details.` ) ;
86+ } ) ;
4087 } ) ;
4188 }
4289}
0 commit comments