UNPKG

3.43 kBJavaScriptView Raw
1/**
2 * Requires proper alignment in object literals.
3 *
4 * Type: `String`
5 *
6 * Values:
7 * - `"all"` for strict mode,
8 * - `"ignoreFunction"` ignores objects if one of the property values is a function expression,
9 * - `"ignoreLineBreak"` ignores objects if there are line breaks between properties
10 *
11 * #### Example
12 *
13 * ```js
14 * "requireAlignedObjectValues": "all"
15 * ```
16 *
17 * ##### Valid
18 * ```js
19 * var x = {
20 * a : 1,
21 * bcd : 2,
22 * ef : 'str'
23 * };
24 * ```
25 * ##### Invalid
26 * ```js
27 * var x = {
28 * a : 1,
29 * bcd : 2,
30 * ef : 'str'
31 * };
32 * ```
33 */
34
35var assert = require('assert');
36
37module.exports = function() {};
38
39module.exports.prototype = {
40
41 configure: function(mode) {
42 var modes = {
43 'all': 'all',
44 'ignoreFunction': 'ignoreFunction',
45 'ignoreLineBreak': 'ignoreLineBreak',
46 'skipWithFunction': 'ignoreFunction',
47 'skipWithLineBreak': 'ignoreLineBreak'
48 };
49 assert(
50 typeof mode === 'string' && modes[mode],
51 this.getOptionName() + ' requires one of the following values: ' + Object.keys(modes).join(', ')
52 );
53 this._mode = modes[mode];
54 },
55
56 getOptionName: function() {
57 return 'requireAlignedObjectValues';
58 },
59
60 check: function(file, errors) {
61 var mode = this._mode;
62
63 file.iterateNodesByType('ObjectExpression', function(node) {
64 if (node.getNewlineCount() === 0 || node.properties < 2) {
65 return;
66 }
67
68 var maxKeyEndPos = 0;
69 var prevKeyEndPos = 0;
70 var minColonPos = 0;
71 var tokens = [];
72 var skip = node.properties.some(function(property, index) {
73 if (property.shorthand || property.method ||
74 property.type === 'SpreadProperty') {
75 return true;
76 }
77
78 if (mode === 'ignoreFunction' && property.value.type === 'FunctionExpression') {
79 return true;
80 }
81
82 if (mode === 'ignoreLineBreak' && index > 0 &&
83 node.properties[index - 1].getLoc().end.line !== property.getLoc().start.line - 1) {
84 return true;
85 }
86
87 prevKeyEndPos = maxKeyEndPos;
88 maxKeyEndPos = Math.max(maxKeyEndPos, property.key.getLoc().end.column);
89 var keyToken = file.getFirstNodeToken(property.key);
90 if (property.computed === true) {
91 while (keyToken.value !== ']') {
92 keyToken = file.getNextToken(keyToken);
93 }
94 }
95 var colon = file.getNextToken(keyToken);
96 if (prevKeyEndPos < maxKeyEndPos) {
97 minColonPos = colon.getLoc().start.column;
98 }
99 tokens.push({key: keyToken, colon: colon});
100 });
101
102 if (skip) {
103 return;
104 }
105
106 var space = minColonPos - maxKeyEndPos;
107 tokens.forEach(function(pair) {
108 errors.assert.spacesBetween({
109 token: pair.key,
110 nextToken: pair.colon,
111 exactly: maxKeyEndPos - pair.key.getLoc().end.column + space,
112 message: 'Alignment required'
113 });
114 });
115 });
116 }
117
118};