UNPKG

3.33 kBJavaScriptView Raw
1/**
2 * @fileoverview An object that caches and applies source code fixes.
3 * @author Nicholas C. Zakas
4 * @copyright 2015 Nicholas C. Zakas. All rights reserved.
5 * See LICENSE file in root directory for full license.
6 */
7"use strict";
8
9//------------------------------------------------------------------------------
10// Requirements
11//------------------------------------------------------------------------------
12
13var debug = require("debug")("eslint:text-fixer");
14
15//------------------------------------------------------------------------------
16// Helpers
17//------------------------------------------------------------------------------
18
19/**
20 * Compares items in a messages array by line and column.
21 * @param {Message} a The first message.
22 * @param {Message} b The second message.
23 * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
24 * @private
25 */
26function compareMessagesByLocation(a, b) {
27 var lineDiff = a.line - b.line;
28
29 if (lineDiff === 0) {
30 return a.column - b.column;
31 } else {
32 return lineDiff;
33 }
34}
35
36//------------------------------------------------------------------------------
37// Public Interface
38//------------------------------------------------------------------------------
39
40/**
41 * Utility for apply fixes to source code.
42 * @constructor
43 */
44function SourceCodeFixer() {
45 Object.freeze(this);
46}
47
48/**
49 * Applies the fixes specified by the messages to the given text. Tries to be
50 * smart about the fixes and won't apply fixes over the same area in the text.
51 * @param {SourceCode} sourceCode The source code to apply the changes to.
52 * @param {Message[]} messages The array of messages reported by ESLint.
53 * @returns {Object} An object containing the fixed text and any unfixed messages.
54 */
55SourceCodeFixer.applyFixes = function(sourceCode, messages) {
56
57 debug("Applying fixes");
58
59 // clone the array
60 var remainingMessages = [],
61 fixes = [],
62 text = sourceCode.text,
63 lastFixPos = text.length + 1;
64
65 messages.forEach(function(problem) {
66 if (problem.hasOwnProperty("fix")) {
67 fixes.push(problem);
68 } else {
69 remainingMessages.push(problem);
70 }
71 });
72
73 if (fixes.length) {
74 debug("Found fixes to apply");
75
76 // sort in reverse order of occurrence
77 fixes.sort(function(a, b) {
78 if (a.fix.range[1] <= b.fix.range[0]) {
79 return 1;
80 } else {
81 return -1;
82 }
83 });
84
85 // split into array of characters for easier manipulation
86 var chars = text.split("");
87
88 fixes.forEach(function(problem) {
89 var fix = problem.fix;
90
91 if (fix.range[1] <= lastFixPos) {
92 chars.splice(fix.range[0], fix.range[1] - fix.range[0], fix.text);
93 lastFixPos = fix.range[0];
94 } else {
95 remainingMessages.push(problem);
96 }
97 });
98
99 return {
100 fixed: true,
101 messages: remainingMessages.sort(compareMessagesByLocation),
102 output: chars.join("")
103 };
104 } else {
105 debug("No fixes to apply");
106 return {
107 fixed: false,
108 messages: messages,
109 output: text
110 };
111 }
112};
113
114module.exports = SourceCodeFixer;