1 | /**
|
2 | * @fileoverview RuleContext utility for rules
|
3 | * @author Nicholas C. Zakas
|
4 | */
|
5 | ;
|
6 |
|
7 | //------------------------------------------------------------------------------
|
8 | // Requirements
|
9 | //------------------------------------------------------------------------------
|
10 |
|
11 | const RuleFixer = require("./util/rule-fixer");
|
12 |
|
13 | //------------------------------------------------------------------------------
|
14 | // Constants
|
15 | //------------------------------------------------------------------------------
|
16 |
|
17 | const PASSTHROUGHS = [
|
18 | "getAncestors",
|
19 | "getDeclaredVariables",
|
20 | "getFilename",
|
21 | "getScope",
|
22 | "markVariableAsUsed",
|
23 |
|
24 | // DEPRECATED
|
25 | "getAllComments",
|
26 | "getComments",
|
27 | "getFirstToken",
|
28 | "getFirstTokens",
|
29 | "getJSDocComment",
|
30 | "getLastToken",
|
31 | "getLastTokens",
|
32 | "getNodeByRangeIndex",
|
33 | "getSource",
|
34 | "getSourceLines",
|
35 | "getTokenAfter",
|
36 | "getTokenBefore",
|
37 | "getTokenByRangeStart",
|
38 | "getTokens",
|
39 | "getTokensAfter",
|
40 | "getTokensBefore",
|
41 | "getTokensBetween"
|
42 | ];
|
43 |
|
44 | //------------------------------------------------------------------------------
|
45 | // Typedefs
|
46 | //------------------------------------------------------------------------------
|
47 |
|
48 | /**
|
49 | * An error message description
|
50 | * @typedef {Object} MessageDescriptor
|
51 | * @property {string} nodeType The type of node.
|
52 | * @property {Location} loc The location of the problem.
|
53 | * @property {string} message The problem message.
|
54 | * @property {Object} [data] Optional data to use to fill in placeholders in the
|
55 | * message.
|
56 | * @property {Function} fix The function to call that creates a fix command.
|
57 | */
|
58 |
|
59 | //------------------------------------------------------------------------------
|
60 | // Rule Definition
|
61 | //------------------------------------------------------------------------------
|
62 |
|
63 | /**
|
64 | * Acts as an abstraction layer between rules and the main eslint object.
|
65 | * @constructor
|
66 | * @param {string} ruleId The ID of the rule using this object.
|
67 | * @param {eslint} eslint The eslint object.
|
68 | * @param {number} severity The configured severity level of the rule.
|
69 | * @param {Array} options The configuration information to be added to the rule.
|
70 | * @param {Object} settings The configuration settings passed from the config file.
|
71 | * @param {Object} parserOptions The parserOptions settings passed from the config file.
|
72 | * @param {Object} parserPath The parser setting passed from the config file.
|
73 | * @param {Object} meta The metadata of the rule
|
74 | */
|
75 | function RuleContext(ruleId, eslint, severity, options, settings, parserOptions, parserPath, meta) {
|
76 |
|
77 | // public.
|
78 | this.id = ruleId;
|
79 | this.options = options;
|
80 | this.settings = settings;
|
81 | this.parserOptions = parserOptions;
|
82 | this.parserPath = parserPath;
|
83 | this.meta = meta;
|
84 |
|
85 | // private.
|
86 | this.eslint = eslint;
|
87 | this.severity = severity;
|
88 |
|
89 | Object.freeze(this);
|
90 | }
|
91 |
|
92 | RuleContext.prototype = {
|
93 | constructor: RuleContext,
|
94 |
|
95 | /**
|
96 | * Passthrough to eslint.getSourceCode().
|
97 | * @returns {SourceCode} The SourceCode object for the code.
|
98 | */
|
99 | getSourceCode() {
|
100 | return this.eslint.getSourceCode();
|
101 | },
|
102 |
|
103 | /**
|
104 | * Passthrough to eslint.report() that automatically assigns the rule ID and severity.
|
105 | * @param {ASTNode|MessageDescriptor} nodeOrDescriptor The AST node related to the message or a message
|
106 | * descriptor.
|
107 | * @param {Object=} location The location of the error.
|
108 | * @param {string} message The message to display to the user.
|
109 | * @param {Object} opts Optional template data which produces a formatted message
|
110 | * with symbols being replaced by this object's values.
|
111 | * @returns {void}
|
112 | */
|
113 | report(nodeOrDescriptor, location, message, opts) {
|
114 |
|
115 | // check to see if it's a new style call
|
116 | if (arguments.length === 1) {
|
117 | const descriptor = nodeOrDescriptor;
|
118 | let fix = null;
|
119 |
|
120 | // if there's a fix specified, get it
|
121 | if (typeof descriptor.fix === "function") {
|
122 | fix = descriptor.fix(new RuleFixer());
|
123 | }
|
124 |
|
125 | this.eslint.report(
|
126 | this.id,
|
127 | this.severity,
|
128 | descriptor.node,
|
129 | descriptor.loc || descriptor.node.loc.start,
|
130 | descriptor.message,
|
131 | descriptor.data,
|
132 | fix,
|
133 | this.meta
|
134 | );
|
135 |
|
136 | return;
|
137 | }
|
138 |
|
139 | // old style call
|
140 | this.eslint.report(
|
141 | this.id,
|
142 | this.severity,
|
143 | nodeOrDescriptor,
|
144 | location,
|
145 | message,
|
146 | opts,
|
147 | this.meta
|
148 | );
|
149 | }
|
150 | };
|
151 |
|
152 | // Copy over passthrough methods. All functions will have 5 or fewer parameters.
|
153 | PASSTHROUGHS.forEach(function(name) {
|
154 | this[name] = function(a, b, c, d, e) {
|
155 | return this.eslint[name](a, b, c, d, e);
|
156 | };
|
157 | }, RuleContext.prototype);
|
158 |
|
159 | module.exports = RuleContext;
|