Skip to content
Browse files

An example to detect nested ternary conditionals.

  • Loading branch information...
1 parent 2eefe2d commit b4eb1b6359a1c0725180d85b376ce01fc05208a3 @ariya committed Sep 28, 2012
Showing with 129 additions and 0 deletions.
  1. +23 −0 doc/index.html
  2. +106 −0 examples/detectnestedternary.js
View
23 doc/index.html
@@ -108,6 +108,29 @@ <h2 id="usage">Basic Usage</h2>
<h2 id="examples">Examples</h2>
+<h3 id="nestedternary">Detect Nested Ternary Conditionals</h3>
+
+<p>The script <code>detectnestedternary.js</code> in the <code>examples/</code> subdirectory is using Esprima to look for a ternary conditional, i.e. <a href="http://en.wikipedia.org/wiki/%3F:">operator ?:</a>, which is immediately followed (in one of its code paths) by another ternary conditional. The script can be invoked from the command-line with Node.js:</p>
+
+<pre class="prettyprint lang-bsh">
+node detectnestedternary.js /some/path
+</pre>
+
+<p>An example code fragment which will be flagged by this script as having a nested ternary conditional:</p>
+
+<pre class="prettyprint lang-js">
+var str = (age < 1) ? "baby" :
+ (age < 5) ? "toddler" :
+ (age < 18) ? "child": "adult";
+</pre>
+
+<p>which will yield the following report:</p>
+
+<pre>
+ Line 1 : Nested ternary for "age &lt 1"
+ Line 2 : Nested ternary for "age &lt 5"
+</pre>
+
<h3 id="booleantrap">Find Possible Boolean Traps</h3>
<p>The script <code>findbooleantrap.js</code> in the <code>examples/</code> subdirectory is using Esprima to detect some possible cases of Boolean trap, i.e. the use of Boolean literal which may lead to ambiguities and lack of readability. The script can be invoked from command-line with Node.js:</p>
View
106 examples/detectnestedternary.js
@@ -0,0 +1,106 @@
+// Usage: node detectnestedternary.js /path/to/some/directory
+// For more details, please read http://esprima.org/doc/#nestedternary
+
+/*jslint node:true sloppy:true plusplus:true */
+
+var fs = require('fs'),
+ esprima = require('../esprima'),
+ dirname = process.argv[2];
+
+
+// Executes visitor on the object and its children (recursively).
+function traverse(object, visitor) {
+ var key, child;
+
+ visitor.call(null, object);
+ for (key in object) {
+ if (object.hasOwnProperty(key)) {
+ child = object[key];
+ if (typeof child === 'object' && child !== null) {
+ traverse(child, visitor);
+ }
+ }
+ }
+}
+
+// http://stackoverflow.com/q/5827612/
+function walk(dir, done) {
+ var results = [];
+ fs.readdir(dir, function (err, list) {
+ if (err) {
+ return done(err);
+ }
+ var i = 0;
+ (function next() {
+ var file = list[i++];
+ if (!file) {
+ return done(null, results);
+ }
+ file = dir + '/' + file;
+ fs.stat(file, function (err, stat) {
+ if (stat && stat.isDirectory()) {
+ walk(file, function (err, res) {
+ results = results.concat(res);
+ next();
+ });
+ } else {
+ results.push(file);
+ next();
+ }
+ });
+ }());
+ });
+}
+
+walk(dirname, function (err, results) {
+ if (err) {
+ console.log('Error', err);
+ return;
+ }
+
+ results.forEach(function (filename) {
+ var shortname, first, content, syntax;
+
+ shortname = filename;
+ first = true;
+
+ if (shortname.substr(0, dirname.length) === dirname) {
+ shortname = shortname.substr(dirname.length + 1, shortname.length);
+ }
+
+ function report(node, problem) {
+ if (first === true) {
+ console.log(shortname + ': ');
+ first = false;
+ }
+ console.log(' Line', node.loc.start.line, ':', problem);
+ }
+
+ function checkConditional(node) {
+ var condition;
+
+ if (node.consequent.type === 'ConditionalExpression' ||
+ node.alternate.type === 'ConditionalExpression') {
+
+ condition = content.substring(node.test.range[0], node.test.range[1]);
+ if (condition.length > 20) {
+ condition = condition.substring(0, 20) + '...';
+ }
+ condition = '"' + condition + '"';
+ report(node, 'Nested ternary for ' + condition);
+ }
+ }
+
+ try {
+ content = fs.readFileSync(filename, 'utf-8');
+ syntax = esprima.parse(content, { tolerant: true, loc: true, range: true });
+ traverse(syntax, function (node) {
+ if (node.type === 'ConditionalExpression') {
+ checkConditional(node);
+ }
+ });
+ } catch (e) {
+ }
+
+ });
+});

0 comments on commit b4eb1b6

Please sign in to comment.
Something went wrong with that request. Please try again.