Blame view

node_modules/eslint/lib/util/source-code-fixer.js 3.42 KB
c39994410   Ryan Glover   wip converting to...
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;