8a43f8388e76e30500c6ce67b6aeb5c13dbd48ad
[platform/framework/web/crosswalk-tizen.git] /
1 /**
2  * @fileoverview Disallow undeclared variables in JSX
3  * @author Yannick Croissant
4  */
5
6 'use strict';
7
8 /**
9  * Checks if a node name match the JSX tag convention.
10  * @param {String} name - Name of the node to check.
11  * @returns {boolean} Whether or not the node name match the JSX tag convention.
12  */
13 var tagConvention = /^[a-z]|\-/;
14 function isTagName(name) {
15   return tagConvention.test(name);
16 }
17
18 // ------------------------------------------------------------------------------
19 // Rule Definition
20 // ------------------------------------------------------------------------------
21
22 module.exports = function(context) {
23
24   /**
25    * Compare an identifier with the variables declared in the scope
26    * @param {ASTNode} node - Identifier or JSXIdentifier node
27    * @returns {void}
28    */
29   function checkIdentifierInJSX(node) {
30     var scope = context.getScope();
31     var variables = scope.variables;
32     var i;
33     var len;
34
35     while (scope.type !== 'global') {
36       scope = scope.upper;
37       variables = scope.variables.concat(variables);
38     }
39     if (scope.childScopes.length) {
40       variables = scope.childScopes[0].variables.concat(variables);
41       // Temporary fix for babel-eslint
42       if (scope.childScopes[0].childScopes.length) {
43         variables = scope.childScopes[0].childScopes[0].variables.concat(variables);
44       }
45     }
46
47     for (i = 0, len = variables.length; i < len; i++) {
48       if (variables[i].name === node.name) {
49         return;
50       }
51     }
52
53     context.report(node, '\'' + node.name + '\' is not defined.');
54   }
55
56   return {
57         JSXOpeningElement: function(node) {
58           if (isTagName(node.name.name)) {
59             return;
60           }
61           checkIdentifierInJSX(node.name);
62         }
63   };
64
65 };