isml-linter 5.38.2 → 5.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -33
- package/README.md +2 -1
- package/package.json +2 -2
- package/src/Constants.js +2 -2
- package/src/IsmlLinter.js +14 -0
- package/src/enums/{SfccTags.js → SfccTagContainer.js} +0 -0
- package/src/isml_tree/ContainerNode.js +1 -1
- package/src/isml_tree/IsmlNode.js +88 -83
- package/src/isml_tree/MaskUtils.js +2 -2
- package/src/isml_tree/ParseUtils.js +15 -13
- package/src/isml_tree/TreeBuilder.js +47 -18
- package/src/rules/prototypes/TreeRulePrototype.js +4 -8
- package/src/rules/tree/align-isset.js +2 -2
- package/src/rules/tree/contextual-attrs.js +4 -4
- package/src/rules/tree/custom-tags.js +6 -6
- package/src/rules/tree/disallow-tags.js +2 -2
- package/src/rules/tree/empty-eof.js +11 -11
- package/src/rules/tree/enforce-security.js +2 -2
- package/src/rules/tree/eslint-to-isscript.js +13 -12
- package/src/rules/tree/indent.js +73 -73
- package/src/rules/tree/leading-iscache.js +1 -1
- package/src/rules/tree/leading-iscontent.js +1 -1
- package/src/rules/tree/no-deprecated-attrs.js +4 -4
- package/src/rules/tree/no-embedded-isml.js +2 -2
- package/src/rules/tree/no-hardcode.js +6 -6
- package/src/rules/tree/no-iselse-slash.js +3 -3
- package/src/rules/tree/no-redundant-context.js +8 -8
- package/src/rules/tree/no-require-in-loop.js +8 -8
- package/src/rules/tree/one-element-per-line.js +3 -3
- package/src/util/ConsoleUtils.js +44 -2
- package/src/util/{CustomTagUtils.js → CustomTagContainer.js} +0 -0
- package/src/util/ExceptionUtils.js +27 -0
- package/src/util/RuleUtils.js +16 -6
- package/src/util/TempRuleUtils.js +4 -4
|
@@ -10,14 +10,14 @@ TreeRulePrototype.check = function(node, data) {
|
|
|
10
10
|
const occurrenceList = this.checkChildren(node, data);
|
|
11
11
|
|
|
12
12
|
if (this.isBroken(node)) {
|
|
13
|
-
let length = node.
|
|
13
|
+
let length = node.head.trim().length;
|
|
14
14
|
|
|
15
15
|
if (data.isCrlfLineBreak) {
|
|
16
|
-
length += ParseUtils.getLineBreakQty(node.
|
|
16
|
+
length += ParseUtils.getLineBreakQty(node.head.trim());
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const error = this.getError(
|
|
20
|
-
node.
|
|
20
|
+
node.head.trim(),
|
|
21
21
|
node.lineNumber,
|
|
22
22
|
node.columnNumber,
|
|
23
23
|
node.globalPos,
|
|
@@ -68,7 +68,7 @@ TreeRulePrototype.return = function(node, occurrenceList, config) {
|
|
|
68
68
|
TreeRulePrototype.fix = function(stream = '') {
|
|
69
69
|
|
|
70
70
|
if (!this.isRoot() && !this.isContainer()) {
|
|
71
|
-
stream += this.
|
|
71
|
+
stream += this.head;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
for (let i = 0; i < this.children.length; i++) {
|
|
@@ -78,10 +78,6 @@ TreeRulePrototype.fix = function(stream = '') {
|
|
|
78
78
|
this.getFixedContent(node, stream);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
if (!this.isRoot() && !this.isContainer()) {
|
|
82
|
-
stream += this.suffix;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
81
|
return stream;
|
|
86
82
|
};
|
|
87
83
|
|
|
@@ -67,11 +67,11 @@ Rule.checkAttributesAlignments = function(issetChildren, attrPosContainer) {
|
|
|
67
67
|
const attr = attrArray[i];
|
|
68
68
|
if (attr.localPos !== attrPosContainer[attr.name]) {
|
|
69
69
|
const error = this.getError(
|
|
70
|
-
issetNode.
|
|
70
|
+
issetNode.head.trim(),
|
|
71
71
|
issetNode.lineNumber,
|
|
72
72
|
issetNode.columnNumber,
|
|
73
73
|
issetNode.globalPos,
|
|
74
|
-
issetNode.
|
|
74
|
+
issetNode.head.trim().length,
|
|
75
75
|
description
|
|
76
76
|
);
|
|
77
77
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
-
const
|
|
2
|
+
const SfccTagContainer = require('../../enums/SfccTagContainer');
|
|
3
3
|
|
|
4
4
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
5
5
|
const description = 'Embedded ISML is not allowed';
|
|
@@ -15,7 +15,7 @@ Rule.isBroken = function(node) {
|
|
|
15
15
|
|
|
16
16
|
const attrList = node.getAttributeList();
|
|
17
17
|
const nodeType = node.getType();
|
|
18
|
-
const sfccTagObj =
|
|
18
|
+
const sfccTagObj = SfccTagContainer[nodeType];
|
|
19
19
|
let result = null;
|
|
20
20
|
|
|
21
21
|
attrList.some( nodeAttribute => {
|
|
@@ -86,11 +86,11 @@ Rule.check = function(node, data) {
|
|
|
86
86
|
const occurrence = this.isBroken(node);
|
|
87
87
|
if (occurrence) {
|
|
88
88
|
const error = this.getError(
|
|
89
|
-
node.
|
|
89
|
+
node.head.trim(),
|
|
90
90
|
node.lineNumber,
|
|
91
91
|
node.columnNumber,
|
|
92
92
|
node.globalPos,
|
|
93
|
-
node.
|
|
93
|
+
node.head.trim().length,
|
|
94
94
|
occurrence.message
|
|
95
95
|
);
|
|
96
96
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const TreeRulePrototype
|
|
2
|
-
const
|
|
1
|
+
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
+
const CustomTagContainer = require('../../util/CustomTagContainer');
|
|
3
3
|
|
|
4
4
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
5
5
|
const description = 'Invalid custom tag';
|
|
@@ -10,11 +10,11 @@ Rule.init(ruleId, description);
|
|
|
10
10
|
|
|
11
11
|
Rule.addError = function(node, message) {
|
|
12
12
|
return this.getError(
|
|
13
|
-
node.
|
|
13
|
+
node.head.trim(),
|
|
14
14
|
node.lineNumber,
|
|
15
15
|
node.columnNumber,
|
|
16
16
|
node.globalPos,
|
|
17
|
-
node.
|
|
17
|
+
node.head.trim().length,
|
|
18
18
|
message
|
|
19
19
|
);
|
|
20
20
|
};
|
|
@@ -26,7 +26,7 @@ Rule.check = function(node, data) {
|
|
|
26
26
|
if (data) {
|
|
27
27
|
const isUsedButNotDeclared = !data.moduleDefinition && data.customModuleArray && data.customModuleArray.length > 0;
|
|
28
28
|
|
|
29
|
-
if (node.
|
|
29
|
+
if (node.head.indexOf('template="util/modules"') >= 0) {
|
|
30
30
|
const isUnnecessaryDefinition = data.moduleDefinition && !data.customModuleArray;
|
|
31
31
|
|
|
32
32
|
if (isUnnecessaryDefinition) {
|
|
@@ -37,7 +37,7 @@ Rule.check = function(node, data) {
|
|
|
37
37
|
|
|
38
38
|
if (isUsedButNotDeclared && node.isCustomIsmlTag()) {
|
|
39
39
|
const error = this.addError(node,
|
|
40
|
-
|
|
40
|
+
CustomTagContainer[node.getType()] ?
|
|
41
41
|
`Custom tag "${node.getType()}" could not be identified. Maybe you forgot to include the modules template?` :
|
|
42
42
|
`Unknown tag "${node.getType()}". Maybe you forgot to add it to util/modules template?`
|
|
43
43
|
);
|
|
@@ -22,11 +22,11 @@ Rule.check = function(node, data) {
|
|
|
22
22
|
|
|
23
23
|
if (this.isBroken(node)) {
|
|
24
24
|
const error = this.getError(
|
|
25
|
-
node.
|
|
25
|
+
node.head.trim(),
|
|
26
26
|
node.lineNumber,
|
|
27
27
|
node.columnNumber,
|
|
28
28
|
node.globalPos,
|
|
29
|
-
node.
|
|
29
|
+
node.head.trim().length,
|
|
30
30
|
`Tag "${node.getType()}" is not allowed.`
|
|
31
31
|
);
|
|
32
32
|
|
|
@@ -12,9 +12,9 @@ Rule.init(ruleId, description);
|
|
|
12
12
|
Rule.isBroken = function(node) {
|
|
13
13
|
const tempNode = node.isContainer() ? node.getLastChild() : node;
|
|
14
14
|
|
|
15
|
-
return !(tempNode.
|
|
16
|
-
tempNode.
|
|
17
|
-
tempNode.
|
|
15
|
+
return !(tempNode.tail ?
|
|
16
|
+
tempNode.tail.endsWith(Constants.EOL) :
|
|
17
|
+
tempNode.head.endsWith(Constants.EOL));
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
Rule.check = function(rootNode, data) {
|
|
@@ -28,22 +28,22 @@ Rule.check = function(rootNode, data) {
|
|
|
28
28
|
const lineBreakQty = ParseUtils.getLineBreakQty(node.toString());
|
|
29
29
|
const lineNumber = node.lineNumber + lineBreakQty - 1;
|
|
30
30
|
let globalPos = node.globalPos;
|
|
31
|
-
let length = node.
|
|
31
|
+
let length = node.head.trim().length;
|
|
32
32
|
|
|
33
|
-
if (node.
|
|
34
|
-
const lastLineBreakPos = node.
|
|
35
|
-
const trailingSpaces = node.
|
|
33
|
+
if (node.tail) {
|
|
34
|
+
const lastLineBreakPos = node.tail.lastIndexOf(Constants.EOL);
|
|
35
|
+
const trailingSpaces = node.tail.substring(lastLineBreakPos + 1);
|
|
36
36
|
|
|
37
37
|
if (trailingSpaces.length > 0) {
|
|
38
|
-
globalPos = node.
|
|
38
|
+
globalPos = node.tailGlobalPos + node.tail.trim().length + 1;
|
|
39
39
|
length = trailingSpaces.length;
|
|
40
40
|
|
|
41
41
|
if (data.isCrlfLineBreak) {
|
|
42
|
-
globalPos += ParseUtils.getLineBreakQty(node.
|
|
42
|
+
globalPos += ParseUtils.getLineBreakQty(node.tail.trimStart());
|
|
43
43
|
}
|
|
44
44
|
} else {
|
|
45
|
-
globalPos = node.
|
|
46
|
-
length = node.
|
|
45
|
+
globalPos = node.tailGlobalPos + 1;
|
|
46
|
+
length = node.tail.trim().length;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -42,11 +42,11 @@ Rule.check = function(node, data) {
|
|
|
42
42
|
|
|
43
43
|
for (let i = 0; i < errorMessageList.length; i++) {
|
|
44
44
|
const error = this.getError(
|
|
45
|
-
node.
|
|
45
|
+
node.head.trim(),
|
|
46
46
|
node.lineNumber,
|
|
47
47
|
node.columnNumber,
|
|
48
48
|
node.globalPos,
|
|
49
|
-
node.
|
|
49
|
+
node.head.trim().length,
|
|
50
50
|
errorMessageList[i]
|
|
51
51
|
);
|
|
52
52
|
|
|
@@ -17,10 +17,10 @@ Rule.init(ruleId, description);
|
|
|
17
17
|
Rule.addError = function(node, eslintError, ismlOffset, linter, data) {
|
|
18
18
|
const errorLine = linter.getSourceCode() ?
|
|
19
19
|
linter.getSourceCode().lines[eslintError.line - 1] :
|
|
20
|
-
node.
|
|
20
|
+
node.head.split('\n')[eslintError.line - 1];
|
|
21
21
|
|
|
22
|
-
const duplicatedOffset = ParseUtils.getNextNonEmptyCharPos(node.
|
|
23
|
-
const errorLocalPos = node.
|
|
22
|
+
const duplicatedOffset = ParseUtils.getNextNonEmptyCharPos(node.head);
|
|
23
|
+
const errorLocalPos = node.head.indexOf(errorLine.trimStart()) - duplicatedOffset;
|
|
24
24
|
let errorGlobalPos = node.globalPos;
|
|
25
25
|
let columnNumber = node.columnNumber;
|
|
26
26
|
let length = errorLine.trimStart().length;
|
|
@@ -28,7 +28,7 @@ Rule.addError = function(node, eslintError, ismlOffset, linter, data) {
|
|
|
28
28
|
|
|
29
29
|
errorGlobalPos += data.isCrlfLineBreak ?
|
|
30
30
|
errorLocalPos + eslintError.line - 2 :
|
|
31
|
-
node.
|
|
31
|
+
node.head.trimStart().indexOf(errorLine.trimStart());
|
|
32
32
|
|
|
33
33
|
if (eslintError.ruleId === 'indent') {
|
|
34
34
|
length = getIndentErrorLength(eslintError, ismlOffset);
|
|
@@ -69,29 +69,30 @@ Rule.check = function(node, data) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
if (node.isRoot()) {
|
|
72
|
-
const
|
|
73
|
-
const
|
|
72
|
+
const ESLinter = require('eslint').Linter;
|
|
73
|
+
const ruleConfig = this.getConfigs();
|
|
74
|
+
const eslinter = new ESLinter();
|
|
74
75
|
const occurrenceList = [];
|
|
75
76
|
|
|
76
77
|
for (let index = 0; index < isscriptContentArray.length; index++) {
|
|
77
78
|
const jsContentNode = isscriptContentArray[index];
|
|
78
|
-
let content = jsContentNode.
|
|
79
|
+
let content = jsContentNode.head;
|
|
79
80
|
|
|
80
81
|
const ismlOffset = getIsmlOffset(jsContentNode);
|
|
81
82
|
|
|
82
83
|
content = unindent(content, ismlOffset.length);
|
|
83
84
|
|
|
84
|
-
const errorArray =
|
|
85
|
+
const errorArray = eslinter.verify(content, eslintConfig);
|
|
85
86
|
|
|
86
87
|
for (let i = 0; i < errorArray.length; i++) {
|
|
87
|
-
const error = this.addError(jsContentNode, errorArray[i], ismlOffset,
|
|
88
|
+
const error = this.addError(jsContentNode, errorArray[i], ismlOffset, eslinter, data);
|
|
88
89
|
occurrenceList.push(error);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
isscriptContentArray = [];
|
|
93
94
|
|
|
94
|
-
return
|
|
95
|
+
return this.return(node, occurrenceList, ruleConfig);
|
|
95
96
|
}
|
|
96
97
|
};
|
|
97
98
|
|
|
@@ -112,12 +113,12 @@ Rule.getFixedContent = function(node) {
|
|
|
112
113
|
if (node.isIsscriptContent()) {
|
|
113
114
|
const Linter = require('eslint').Linter;
|
|
114
115
|
const linter = new Linter();
|
|
115
|
-
let content = node.
|
|
116
|
+
let content = node.head;
|
|
116
117
|
const ismlOffset = getIsmlOffset(node);
|
|
117
118
|
|
|
118
119
|
this.result.fixedContent = content = linter.verifyAndFix(content, eslintConfig).output;
|
|
119
120
|
|
|
120
|
-
node.
|
|
121
|
+
node.head = reIndent(content, ismlOffset);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
return GeneralUtils.applyActiveLineBreaks(node.toString());
|
package/src/rules/tree/indent.js
CHANGED
|
@@ -58,13 +58,13 @@ Rule.isBroken = function(node) {
|
|
|
58
58
|
!node.isInSameLineAsPreviousSibling();
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
Rule.
|
|
61
|
+
Rule.isTailBroken = function(node) {
|
|
62
62
|
|
|
63
63
|
const configIndentSize = this.getConfigs().indent;
|
|
64
64
|
const expectedIndentation = getExpectedIndentation(node, configIndentSize);
|
|
65
|
-
const actualIndentation =
|
|
66
|
-
const isInSameLineAsOpeningTag = node.lineNumber === node.
|
|
67
|
-
const isInSameLineAsLastChild = node.hasChildren() && node.getLastChild().getLastLineNumber() === node.
|
|
65
|
+
const actualIndentation = getActualTailIndentation(node);
|
|
66
|
+
const isInSameLineAsOpeningTag = node.lineNumber === node.tailLineNumber;
|
|
67
|
+
const isInSameLineAsLastChild = node.hasChildren() && node.getLastChild().getLastLineNumber() === node.tailLineNumber;
|
|
68
68
|
|
|
69
69
|
return !node.isRoot() &&
|
|
70
70
|
!node.isContainer() &&
|
|
@@ -94,8 +94,8 @@ Rule.isClosingCharBroken = function(node) {
|
|
|
94
94
|
|
|
95
95
|
if (node.isSelfClosing()) {
|
|
96
96
|
if (closingCharsConfigs.selfClosingTag === 'always') {
|
|
97
|
-
const
|
|
98
|
-
const isClosingCharStandingAlone =
|
|
97
|
+
const nodeHeadLineList = node.head.trim().split(Constants.EOL);
|
|
98
|
+
const isClosingCharStandingAlone = nodeHeadLineList[nodeHeadLineList.length - 1].trim() === '/>';
|
|
99
99
|
|
|
100
100
|
return {
|
|
101
101
|
isBroken : !isClosingCharStandingAlone,
|
|
@@ -103,8 +103,8 @@ Rule.isClosingCharBroken = function(node) {
|
|
|
103
103
|
};
|
|
104
104
|
|
|
105
105
|
} else if (closingCharsConfigs.selfClosingTag === 'never') {
|
|
106
|
-
const
|
|
107
|
-
const isClosingCharStandingAlone =
|
|
106
|
+
const nodeHeadLineList = node.head.trim().split(Constants.EOL);
|
|
107
|
+
const isClosingCharStandingAlone = nodeHeadLineList[nodeHeadLineList.length - 1].trim() === '/>';
|
|
108
108
|
|
|
109
109
|
return {
|
|
110
110
|
isBroken : isClosingCharStandingAlone,
|
|
@@ -113,8 +113,8 @@ Rule.isClosingCharBroken = function(node) {
|
|
|
113
113
|
}
|
|
114
114
|
} else {
|
|
115
115
|
if (closingCharsConfigs.nonSelfClosingTag === 'always') {
|
|
116
|
-
const
|
|
117
|
-
const isClosingCharStandingAlone =
|
|
116
|
+
const nodeHeadLineList = node.head.trim().split(Constants.EOL);
|
|
117
|
+
const isClosingCharStandingAlone = nodeHeadLineList[nodeHeadLineList.length - 1].trim() === '>';
|
|
118
118
|
|
|
119
119
|
return {
|
|
120
120
|
isBroken : !isClosingCharStandingAlone,
|
|
@@ -122,8 +122,8 @@ Rule.isClosingCharBroken = function(node) {
|
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
} else if (closingCharsConfigs.nonSelfClosingTag === 'never') {
|
|
125
|
-
const
|
|
126
|
-
const isClosingCharStandingAlone =
|
|
125
|
+
const nodeHeadLineList = node.head.trim().split(Constants.EOL);
|
|
126
|
+
const isClosingCharStandingAlone = nodeHeadLineList[nodeHeadLineList.length - 1].trim() === '>';
|
|
127
127
|
|
|
128
128
|
return {
|
|
129
129
|
isBroken : isClosingCharStandingAlone,
|
|
@@ -193,13 +193,13 @@ Rule.check = function(node, data) {
|
|
|
193
193
|
const configIndentSize = ruleConfig.indent;
|
|
194
194
|
const expectedIndentation = getExpectedIndentation(node, configIndentSize);
|
|
195
195
|
const actualIndentation = getActualIndentation(node);
|
|
196
|
-
const
|
|
196
|
+
const nodeHead = node.head.trim();
|
|
197
197
|
const occurrenceLength = actualIndentation === 0 ?
|
|
198
|
-
|
|
198
|
+
nodeHead.length + ParseUtils.getLineBreakQty(nodeHead) :
|
|
199
199
|
getActualIndentation(node);
|
|
200
200
|
|
|
201
201
|
const error = this.getError(
|
|
202
|
-
node.
|
|
202
|
+
node.head.trim(),
|
|
203
203
|
node.lineNumber,
|
|
204
204
|
node.columnNumber,
|
|
205
205
|
errorGlobalPos,
|
|
@@ -217,22 +217,22 @@ Rule.check = function(node, data) {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
// Checks node
|
|
221
|
-
if (node.
|
|
220
|
+
// Checks node tail value;
|
|
221
|
+
if (node.tail && this.isTailBroken(node)) {
|
|
222
222
|
const configIndentSize = ruleConfig.indent;
|
|
223
223
|
const expectedIndentation = getExpectedIndentation(node, configIndentSize);
|
|
224
|
-
const actualIndentation =
|
|
225
|
-
const
|
|
224
|
+
const actualIndentation = getActualTailIndentation(node);
|
|
225
|
+
const nodeTail = node.tail.trim();
|
|
226
226
|
const occurrenceLength = actualIndentation === 0 ?
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const
|
|
227
|
+
nodeTail.length + ParseUtils.getLineBreakQty(nodeTail) :
|
|
228
|
+
getActualTailIndentation(node);
|
|
229
|
+
const tailGlobalPos = node.tailGlobalPos - getActualTailIndentation(node);
|
|
230
230
|
|
|
231
231
|
const error = this.getError(
|
|
232
|
-
node.
|
|
233
|
-
node.
|
|
234
|
-
node.
|
|
235
|
-
|
|
232
|
+
node.tail.trim(),
|
|
233
|
+
node.tailLineNumber,
|
|
234
|
+
node.tailColumnNumber,
|
|
235
|
+
tailGlobalPos,
|
|
236
236
|
occurrenceLength,
|
|
237
237
|
getOccurrenceDescription(expectedIndentation, actualIndentation)
|
|
238
238
|
);
|
|
@@ -248,15 +248,15 @@ Rule.check = function(node, data) {
|
|
|
248
248
|
if (node.isSelfClosing()) {
|
|
249
249
|
const closingChar = '/>';
|
|
250
250
|
const globalPos = node.globalPos
|
|
251
|
-
+ node.
|
|
252
|
-
const lineList = node.
|
|
251
|
+
+ node.head.trim().lastIndexOf(closingChar);
|
|
252
|
+
const lineList = node.head.split(Constants.EOL);
|
|
253
253
|
const columnNumber = lineList[lineList.length - 1].lastIndexOf(closingChar) + 1;
|
|
254
254
|
const message = checkResult.config === 'always' ?
|
|
255
255
|
getStandAloneCharDescription(node.getType(), closingChar) :
|
|
256
256
|
getNonStandAloneCharDescription(node.getType(), closingChar);
|
|
257
257
|
|
|
258
258
|
const error = this.getError(
|
|
259
|
-
node.
|
|
259
|
+
node.head.trim(),
|
|
260
260
|
node.endLineNumber,
|
|
261
261
|
columnNumber,
|
|
262
262
|
globalPos,
|
|
@@ -269,15 +269,15 @@ Rule.check = function(node, data) {
|
|
|
269
269
|
} else {
|
|
270
270
|
const closingChar = '>';
|
|
271
271
|
const globalPos = node.globalPos
|
|
272
|
-
+ node.
|
|
273
|
-
const lineList = node.
|
|
272
|
+
+ node.head.trim().length - closingChar.length;
|
|
273
|
+
const lineList = node.head.trim().split(Constants.EOL);
|
|
274
274
|
const columnNumber = lineList[lineList.length - 1].lastIndexOf(closingChar) + 1;
|
|
275
275
|
const message = checkResult.config === 'always' ?
|
|
276
276
|
getStandAloneCharDescription(node.getType(), closingChar) :
|
|
277
277
|
getNonStandAloneCharDescription(node.getType(), closingChar);
|
|
278
278
|
|
|
279
279
|
const error = this.getError(
|
|
280
|
-
node.
|
|
280
|
+
node.head.trim(),
|
|
281
281
|
node.endLineNumber,
|
|
282
282
|
columnNumber,
|
|
283
283
|
globalPos,
|
|
@@ -406,7 +406,7 @@ const removeIndentation = content => {
|
|
|
406
406
|
};
|
|
407
407
|
|
|
408
408
|
const addIndentationToText = node => {
|
|
409
|
-
const content = node.
|
|
409
|
+
const content = node.head;
|
|
410
410
|
const lineArray = content
|
|
411
411
|
.split(Constants.EOL)
|
|
412
412
|
.filter( (line, i) => !(i === 0 && line === ''))
|
|
@@ -584,15 +584,15 @@ const getExpressionAttributeIndentation = (attributeValue, nodeIndentation, attr
|
|
|
584
584
|
};
|
|
585
585
|
|
|
586
586
|
const getClosingChars = node => {
|
|
587
|
-
const
|
|
587
|
+
const nodeHead = node.head.trim();
|
|
588
588
|
|
|
589
|
-
if (
|
|
589
|
+
if (nodeHead.endsWith(' />')) {
|
|
590
590
|
return ' />';
|
|
591
|
-
} else if (
|
|
591
|
+
} else if (nodeHead.endsWith('/>')) {
|
|
592
592
|
return ' />';
|
|
593
|
-
} else if (
|
|
593
|
+
} else if (nodeHead.endsWith(' >')) {
|
|
594
594
|
return ' >';
|
|
595
|
-
} else if (
|
|
595
|
+
} else if (nodeHead.endsWith('>')) {
|
|
596
596
|
return '>';
|
|
597
597
|
}
|
|
598
598
|
|
|
@@ -600,7 +600,7 @@ const getClosingChars = node => {
|
|
|
600
600
|
};
|
|
601
601
|
|
|
602
602
|
const addIndentation = (node, isOpeningTag) => {
|
|
603
|
-
const content = isOpeningTag ? node.
|
|
603
|
+
const content = isOpeningTag ? node.head : node.tail;
|
|
604
604
|
const startingPos = ParseUtils.getNextNonEmptyCharPos(content);
|
|
605
605
|
const endingPos = content.length - ParseUtils.getNextNonEmptyCharPos(content.split('').reverse().join(''));
|
|
606
606
|
const fullLeadingContent = content.substring(0, startingPos);
|
|
@@ -614,13 +614,13 @@ const addIndentation = (node, isOpeningTag) => {
|
|
|
614
614
|
if (isOpeningTag) {
|
|
615
615
|
const shouldAddIndentationToClosingChar = shouldAddIndentationToClosingChars(node);
|
|
616
616
|
const closingChars = getClosingChars(node);
|
|
617
|
-
const tagNameEndPos = ParseUtils.getLeadingLineBreakQty(node.
|
|
618
|
-
+ ParseUtils.getFirstEmptyCharPos(node.
|
|
617
|
+
const tagNameEndPos = ParseUtils.getLeadingLineBreakQty(node.head)
|
|
618
|
+
+ ParseUtils.getFirstEmptyCharPos(node.head.trim()) + 1;
|
|
619
619
|
|
|
620
|
-
if (ParseUtils.getLineBreakQty(node.
|
|
620
|
+
if (ParseUtils.getLineBreakQty(node.head.trim()) > 0 || shouldAddIndentationToClosingChar && node.isSelfClosing()) {
|
|
621
621
|
contentResult = attributeList.length > 0 ?
|
|
622
|
-
node.
|
|
623
|
-
node.
|
|
622
|
+
node.head.substring(0, tagNameEndPos).trimStart() :
|
|
623
|
+
node.head.trimStart();
|
|
624
624
|
|
|
625
625
|
for (let i = 0; i < attributeList.length; i++) {
|
|
626
626
|
contentResult += indentAttribute(attributeList, i, nodeIndentation, attributeOffset);
|
|
@@ -632,10 +632,10 @@ const addIndentation = (node, isOpeningTag) => {
|
|
|
632
632
|
closingChars;
|
|
633
633
|
}
|
|
634
634
|
} else {
|
|
635
|
-
contentResult = node.
|
|
635
|
+
contentResult = node.head.trim();
|
|
636
636
|
}
|
|
637
637
|
} else {
|
|
638
|
-
contentResult = node.
|
|
638
|
+
contentResult = node.tail.trim();
|
|
639
639
|
}
|
|
640
640
|
|
|
641
641
|
return preLineBreakContent + nodeIndentation + contentResult + fullTrailingContent;
|
|
@@ -644,15 +644,15 @@ const addIndentation = (node, isOpeningTag) => {
|
|
|
644
644
|
const removeAllIndentation = node => {
|
|
645
645
|
if (!node.isRoot() && !node.isContainer() && !node.parent.isOneOfTypes(['isscript', 'script'])) {
|
|
646
646
|
|
|
647
|
-
const
|
|
648
|
-
const
|
|
647
|
+
const shouldRemoveHeadIndentation = node.head && !node.isInSameLineAsPreviousSibling() && !node.isInSameLineAsParent() && !(node.lineNumber === node.parent.endLineNumber);
|
|
648
|
+
const shouldRemoveTailIndentation = node.tail && !(node.hasChildren() && node.getLastChild().lineNumber === node.tailLineNumber);
|
|
649
649
|
|
|
650
|
-
if (
|
|
651
|
-
node.
|
|
650
|
+
if (shouldRemoveHeadIndentation) {
|
|
651
|
+
node.head = removeIndentation(node.head);
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
-
if (
|
|
655
|
-
node.
|
|
654
|
+
if (shouldRemoveTailIndentation) {
|
|
655
|
+
node.tail = removeIndentation(node.tail);
|
|
656
656
|
}
|
|
657
657
|
}
|
|
658
658
|
|
|
@@ -665,21 +665,21 @@ const addCorrectIndentation = node => {
|
|
|
665
665
|
|
|
666
666
|
if (!node.isRoot() && !node.isContainer() && !node.parent.isOneOfTypes(['isscript', 'script'])) {
|
|
667
667
|
if (node.parent.isOfType('iscomment')) {
|
|
668
|
-
const shouldAddIndentationToText =
|
|
668
|
+
const shouldAddIndentationToText = checkIfShouldAddIndentationToHead(node);
|
|
669
669
|
|
|
670
670
|
if (shouldAddIndentationToText) {
|
|
671
|
-
node.
|
|
671
|
+
node.head = addIndentationToText(node);
|
|
672
672
|
}
|
|
673
673
|
} else {
|
|
674
|
-
const
|
|
675
|
-
const
|
|
674
|
+
const shouldAddIndentationToHead = checkIfShouldAddIndentationToHead(node);
|
|
675
|
+
const shouldAddIndentationToTail = checkIfShouldAddIndentationToTail(node);
|
|
676
676
|
|
|
677
|
-
if (
|
|
678
|
-
node.
|
|
677
|
+
if (shouldAddIndentationToHead) {
|
|
678
|
+
node.head = addIndentation(node, true);
|
|
679
679
|
}
|
|
680
680
|
|
|
681
|
-
if (
|
|
682
|
-
node.
|
|
681
|
+
if (shouldAddIndentationToTail) {
|
|
682
|
+
node.tail = addIndentation(node, false);
|
|
683
683
|
}
|
|
684
684
|
}
|
|
685
685
|
}
|
|
@@ -706,7 +706,7 @@ const shouldAddIndentationToClosingChars = node => {
|
|
|
706
706
|
}
|
|
707
707
|
}
|
|
708
708
|
|
|
709
|
-
const lineList = node.
|
|
709
|
+
const lineList = node.head.split(Constants.EOL);
|
|
710
710
|
const lastLine = lineList[lineList.length - 1];
|
|
711
711
|
|
|
712
712
|
return ['/>', '>'].indexOf(lastLine) >= 0;
|
|
@@ -727,31 +727,31 @@ const shouldAddIndentationToClosingQuote = attribute => {
|
|
|
727
727
|
return lastLine.trim().length === 0;
|
|
728
728
|
};
|
|
729
729
|
|
|
730
|
-
const
|
|
730
|
+
const checkIfShouldAddIndentationToHead = node => {
|
|
731
731
|
const previousSibling = node.getPreviousSibling();
|
|
732
732
|
const isInSameLineAsPrevSiblingLastLine = !node.isRoot() &&
|
|
733
733
|
previousSibling &&
|
|
734
734
|
node.lineNumber === previousSibling.getLastLineNumber();
|
|
735
|
-
const
|
|
735
|
+
const isInSameLineAsParentHeadEnd = node.parent.endLineNumber === node.lineNumber && !node.parent.isContainer();
|
|
736
736
|
|
|
737
737
|
const shouldAdd = !node.isRoot() &&
|
|
738
738
|
!isInSameLineAsPrevSiblingLastLine &&
|
|
739
|
-
!
|
|
739
|
+
!isInSameLineAsParentHeadEnd &&
|
|
740
740
|
(node.isFirstChild() || previousSibling && node.lineNumber !== previousSibling.lineNumber) &&
|
|
741
|
-
node.
|
|
741
|
+
node.head && node.lineNumber !== node.parent.endLineNumber;
|
|
742
742
|
|
|
743
743
|
return shouldAdd;
|
|
744
744
|
};
|
|
745
745
|
|
|
746
|
-
const
|
|
747
|
-
const
|
|
746
|
+
const checkIfShouldAddIndentationToTail = node => {
|
|
747
|
+
const hasTail = !!node.tail;
|
|
748
748
|
const isLastClause = !!node.parent && node.parent.isContainer() && !node.isLastChild();
|
|
749
749
|
const isInSameLineAsChild = !node.hasChildren() || node.getLastChild().isInSameLineAsParent();
|
|
750
|
-
const
|
|
751
|
-
const isBrokenIntoMultipleLines = !node.hasChildren() && node.
|
|
750
|
+
const isTailInSameLineAsChild = !node.hasChildren() || node.tailLineNumber === node.getLastChild().getLastLineNumber();
|
|
751
|
+
const isBrokenIntoMultipleLines = !node.hasChildren() && node.tailLineNumber && node.lineNumber !== node.tailLineNumber;
|
|
752
752
|
|
|
753
|
-
const shouldAdd =
|
|
754
|
-
!
|
|
753
|
+
const shouldAdd = hasTail &&
|
|
754
|
+
!isTailInSameLineAsChild &&
|
|
755
755
|
!isInSameLineAsChild &&
|
|
756
756
|
!isLastClause
|
|
757
757
|
||
|
|
@@ -765,7 +765,7 @@ const getEslintChildTrailingSpaces = node => {
|
|
|
765
765
|
if (node.isOfType('isscript')) {
|
|
766
766
|
const child = node.getLastChild();
|
|
767
767
|
|
|
768
|
-
const trailingSpacesQty = child.
|
|
768
|
+
const trailingSpacesQty = child.head
|
|
769
769
|
.replace(/\r\n/g, '_')
|
|
770
770
|
.split('')
|
|
771
771
|
.reverse()
|
|
@@ -848,6 +848,6 @@ const getNonStandAloneCharDescription = (tagName, closingChars) => `"${closingC
|
|
|
848
848
|
const getOccurrenceDescription = (expected, actual) => `Expected indentation of ${expected} spaces but found ${actual}`;
|
|
849
849
|
const getExpectedIndentation = (node, configIndentSize) => (node.depth - 1) * configIndentSize;
|
|
850
850
|
const getActualIndentation = node => node.getIndentationSize();
|
|
851
|
-
const
|
|
851
|
+
const getActualTailIndentation = node => node.getTailIndentationSize() + getEslintChildTrailingSpaces(node);
|
|
852
852
|
|
|
853
853
|
module.exports = Rule;
|
|
@@ -32,7 +32,7 @@ Rule.getFixedContent = function(rootNode) {
|
|
|
32
32
|
|
|
33
33
|
if (isContentNode) {
|
|
34
34
|
isContentNode.parent.removeChild(isContentNode);
|
|
35
|
-
isContentNode.
|
|
35
|
+
isContentNode.head = isContentNode.head.trim() + Constants.EOL;
|
|
36
36
|
rootNode.addChildNodeToPos(isContentNode, 0);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -28,7 +28,7 @@ Rule.getFixedContent = function(rootNode) {
|
|
|
28
28
|
|
|
29
29
|
if (isContentNode) {
|
|
30
30
|
isContentNode.parent.removeChild(isContentNode);
|
|
31
|
-
isContentNode.
|
|
31
|
+
isContentNode.head = isContentNode.head.trim() + Constants.EOL;
|
|
32
32
|
rootNode.addChildNodeToPos(isContentNode, 0);
|
|
33
33
|
}
|
|
34
34
|
}
|