summaryrefslogtreecommitdiff
path: root/tools/eslint/lib/rules/curly.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/eslint/lib/rules/curly.js')
-rw-r--r--tools/eslint/lib/rules/curly.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/curly.js b/tools/eslint/lib/rules/curly.js
new file mode 100644
index 0000000000..2bfcfb2798
--- /dev/null
+++ b/tools/eslint/lib/rules/curly.js
@@ -0,0 +1,103 @@
+/**
+ * @fileoverview Rule to flag statements without curly braces
+ * @author Nicholas C. Zakas
+ */
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+ var multiOnly = (context.options[0] === "multi");
+ var multiLine = (context.options[0] === "multi-line");
+
+ //--------------------------------------------------------------------------
+ // Helpers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Determines if a given node is a one-liner that's on the same line as it's preceding code.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code.
+ * @private
+ */
+ function isCollapsedOneLiner(node) {
+ var before = context.getTokenBefore(node),
+ last = context.getLastToken(node);
+ return before.loc.start.line === last.loc.end.line;
+ }
+
+ /**
+ * Checks the body of a node to see if it's a block statement. Depending on
+ * the rule options, reports the appropriate problems.
+ * @param {ASTNode} node The node to report if there's a problem.
+ * @param {ASTNode} body The body node to check for blocks.
+ * @param {string} name The name to report if there's a problem.
+ * @param {string} suffix Additional string to add to the end of a report.
+ * @returns {void}
+ */
+ function checkBody(node, body, name, suffix) {
+ var hasBlock = (body.type === "BlockStatement");
+
+ if (multiOnly) {
+ if (hasBlock && body.body.length === 1) {
+ context.report(node, "Unnecessary { after '{{name}}'{{suffix}}.",
+ {
+ name: name,
+ suffix: (suffix ? " " + suffix : "")
+ }
+ );
+ }
+ } else if (multiLine) {
+ if (!hasBlock && !isCollapsedOneLiner(body)) {
+ context.report(node, "Expected { after '{{name}}'{{suffix}}.",
+ {
+ name: name,
+ suffix: (suffix ? " " + suffix : "")
+ }
+ );
+ }
+ } else {
+ if (!hasBlock) {
+ context.report(node, "Expected { after '{{name}}'{{suffix}}.",
+ {
+ name: name,
+ suffix: (suffix ? " " + suffix : "")
+ }
+ );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ return {
+
+ "IfStatement": function(node) {
+
+ checkBody(node, node.consequent, "if", "condition");
+
+ if (node.alternate && node.alternate.type !== "IfStatement") {
+ checkBody(node, node.alternate, "else");
+ }
+
+ },
+
+ "WhileStatement": function(node) {
+ checkBody(node, node.body, "while", "condition");
+ },
+
+ "DoWhileStatement": function (node) {
+ checkBody(node, node.body, "do");
+ },
+
+ "ForStatement": function(node) {
+ checkBody(node, node.body, "for", "condition");
+ }
+ };
+
+};