source-code-fixer.js
3.42 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* @fileoverview An object that caches and applies source code fixes.
* @author Nicholas C. Zakas
* @copyright 2015 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var debug = require("debug")("eslint:text-fixer");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Compares items in a messages array by line and column.
* @param {Message} a The first message.
* @param {Message} b The second message.
* @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
* @private
*/
function compareMessagesByLocation(a, b) {
var lineDiff = a.line - b.line;
if (lineDiff === 0) {
return a.column - b.column;
} else {
return lineDiff;
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* Utility for apply fixes to source code.
* @constructor
*/
function SourceCodeFixer() {
Object.freeze(this);
}
/**
* Applies the fixes specified by the messages to the given text. Tries to be
* smart about the fixes and won't apply fixes over the same area in the text.
* @param {SourceCode} sourceCode The source code to apply the changes to.
* @param {Message[]} messages The array of messages reported by ESLint.
* @returns {Object} An object containing the fixed text and any unfixed messages.
*/
SourceCodeFixer.applyFixes = function(sourceCode, messages) {
debug("Applying fixes");
if (!sourceCode) {
debug("No source code to fix");
return {
fixed: false,
messages: messages,
output: ""
};
}
// clone the array
var remainingMessages = [],
fixes = [],
text = sourceCode.text,
lastFixPos = text.length + 1;
messages.forEach(function(problem) {
if (problem.hasOwnProperty("fix")) {
fixes.push(problem);
} else {
remainingMessages.push(problem);
}
});
if (fixes.length) {
debug("Found fixes to apply");
// sort in reverse order of occurrence
fixes.sort(function(a, b) {
if (a.fix.range[1] <= b.fix.range[0]) {
return 1;
} else {
return -1;
}
});
// split into array of characters for easier manipulation
var chars = text.split("");
fixes.forEach(function(problem) {
var fix = problem.fix;
if (fix.range[1] < lastFixPos) {
chars.splice(fix.range[0], fix.range[1] - fix.range[0], fix.text);
lastFixPos = fix.range[0];
} else {
remainingMessages.push(problem);
}
});
return {
fixed: true,
messages: remainingMessages.sort(compareMessagesByLocation),
output: chars.join("")
};
} else {
debug("No fixes to apply");
return {
fixed: false,
messages: messages,
output: text
};
}
};
module.exports = SourceCodeFixer;