[javascriptlint-commit] SF.net SVN: javascriptlint:[325] trunk
Status: Beta
Brought to you by:
matthiasmiller
|
From: <mat...@us...> - 2013-10-01 17:12:24
|
Revision: 325
http://sourceforge.net/p/javascriptlint/code/325
Author: matthiasmiller
Date: 2013-10-01 17:12:20 +0000 (Tue, 01 Oct 2013)
Log Message:
-----------
First cut at warnings to validate function expression names (disabled by default)
Modified Paths:
--------------
trunk/javascriptlint/conf.py
trunk/javascriptlint/warnings.py
trunk/tests/control_comments/option_explicit.js
trunk/tests/warnings/want_assign_or_call.js
Added Paths:
-----------
trunk/tests/warnings/function_name_mismatch.js
trunk/tests/warnings/function_name_missing.js
trunk/tests/warnings/misplaced_function.js
Modified: trunk/javascriptlint/conf.py
===================================================================
--- trunk/javascriptlint/conf.py 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/javascriptlint/conf.py 2013-10-01 17:12:20 UTC (rev 325)
@@ -6,12 +6,18 @@
import util
import warnings
+_DISABLED_WARNINGS = (
+ 'block_without_braces',
+ 'function_name_missing',
+ 'function_name_mismatch',
+)
+
def _getwarningsconf():
lines = []
for name in sorted(warnings.warnings.keys()):
message = warnings.warnings[name]
sign = '+'
- if name == 'block_without_braces':
+ if name in _DISABLED_WARNINGS:
sign = '-'
assert len(name) < 29
lines.append(sign + name.ljust(29) + '# ' + message)
@@ -183,7 +189,8 @@
}
for name in warnings.warnings:
self._settings[name] = BooleanSetting(True)
- self.loadline('-block_without_braces')
+ for warning in _DISABLED_WARNINGS:
+ self.loadline('-%s' % warning)
def loadfile(self, path):
path = os.path.abspath(path)
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/javascriptlint/warnings.py 2013-10-01 17:12:20 UTC (rev 325)
@@ -102,6 +102,9 @@
'unsupported_version': 'JavaScript {version} is not supported',
'incorrect_version': 'Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version.',
'for_in_missing_identifier': 'for..in should have identifier on left side',
+ 'misplaced_function': 'unconventional use of function expression',
+ 'function_name_missing': 'anonymous function should be named to match property name {name}',
+ 'function_name_mismatch': 'function name {fn_name} does not match property name {prop_name}',
}
errors = {
@@ -604,6 +607,87 @@
if not left.kind in (tok.VAR, tok.NAME):
raise LintWarning, left
+@lookfor(tok.FUNCTION)
+def misplaced_function(node):
+ # Ignore function statements.
+ if node.opcode in (None, op.CLOSURE):
+ return
+
+ # Ignore parens.
+ parent = node.parent
+ while parent.kind == tok.RP:
+ parent = parent.parent
+
+ # Allow x = x || ...
+ if parent.kind == tok.OR and len(parent.kids) == 2 and \
+ node is parent.kids[-1]:
+ parent = parent.parent
+
+ if parent.kind == tok.NAME and parent.opcode == op.SETNAME:
+ return # Allow in var statements
+ if parent.kind == tok.ASSIGN and parent.opcode == op.NOP:
+ return # Allow in assigns
+ if parent.kind == tok.COLON and parent.parent.kind == tok.RC:
+ return # Allow in object literals
+ if parent.kind == tok.LP and parent.opcode in (op.CALL, op.SETCALL):
+ return # Allow in parameters
+ if parent.kind == tok.RETURN:
+ return # Allow for return values
+ if parent.kind == tok.NEW:
+ return # Allow as constructors
+ raise LintWarning, node
+
+def _get_expected_function_name(node):
+ # Ignore function statements.
+ if node.opcode in (None, op.CLOSURE):
+ return
+
+ # Ignore parens.
+ parent = node.parent
+ while parent.kind == tok.RP:
+ parent = parent.parent
+
+ # Allow x = x || ...
+ if parent.kind == tok.OR and len(parent.kids) == 2 and \
+ node is parent.kids[-1]:
+ parent = parent.parent
+
+ # Var assignment.
+ if parent.kind == tok.NAME and parent.opcode == op.SETNAME:
+ return parent.atom
+
+ # Assignment.
+ if parent.kind == tok.ASSIGN and parent.opcode == op.NOP:
+ if parent.kids[0].kind == tok.NAME and \
+ parent.kids[0].opcode == op.SETNAME:
+ return parent.kids[0].atom
+ return '<error>'
+
+ # Object literal.
+ if parent.kind == tok.COLON and parent.parent.kind == tok.RC:
+ return parent.kids[0].atom
+
+@lookfor(tok.FUNCTION)
+def function_name_missing(node):
+ if node.fn_name:
+ return
+
+ expected_name = _get_expected_function_name(node)
+ if not expected_name is None:
+ raise LintWarning(node, name=expected_name)
+
+@lookfor(tok.FUNCTION)
+def function_name_mismatch(node):
+ if not node.fn_name:
+ return
+
+ expected_name = _get_expected_function_name(node)
+ if expected_name is None:
+ return
+
+ if expected_name != node.fn_name:
+ raise LintWarning(node, fn_name=node.fn_name, prop_name=expected_name)
+
@lookfor()
def mismatch_ctrl_comments(node):
pass
Modified: trunk/tests/control_comments/option_explicit.js
===================================================================
--- trunk/tests/control_comments/option_explicit.js 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/tests/control_comments/option_explicit.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -62,7 +62,7 @@
// This should be undeclared because this is an expression,
// not a declaration.
- (function func_expr() { /*warning:want_assign_or_call*/
+ (function func_expr() { /*warning:misplaced_function*/ /*warning:want_assign_or_call*/
return 10;
});
j = func_expr(); /*warning:undeclared_identifier*/
Added: trunk/tests/warnings/function_name_mismatch.js
===================================================================
--- trunk/tests/warnings/function_name_mismatch.js (rev 0)
+++ trunk/tests/warnings/function_name_mismatch.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -0,0 +1,36 @@
+/*conf:+function_name_mismatch*/
+function function_name_mismatch() {
+ var f = function bogus() { /*warning:function_name_mismatch*/
+ };
+ var g = function g() {
+ };
+
+ f = new function bogus() {
+ };
+ f = new function() {
+ };
+
+ f = (function() {
+ return 10;
+ })();
+
+ var o = {
+ f: function bogus() { /*warning:function_name_mismatch*/
+ return null;
+ }
+ };
+ o.a.b = {
+ f: function bogus() { /*warning:function_name_mismatch*/
+ return null;
+ }
+ };
+ o.a.b = o.a.b || function bogus() { return 10; }; /*warning:function_name_mismatch*/
+
+ function closure(a) {
+ return function() { return a; };
+ }
+
+ function x() {
+ }
+}
+
Added: trunk/tests/warnings/function_name_missing.js
===================================================================
--- trunk/tests/warnings/function_name_missing.js (rev 0)
+++ trunk/tests/warnings/function_name_missing.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -0,0 +1,30 @@
+/*conf:+function_name_missing*/
+function function_name_missing() {
+ var f = function() { /*warning:function_name_missing*/
+ };
+ f = new function() {
+ };
+ f = (function() {
+ return 10;
+ })();
+
+ var o = {
+ f: function() { /*warning:function_name_missing*/
+ return null;
+ }
+ };
+ o.a.b = {
+ f: function() { /*warning:function_name_missing*/
+ return null;
+ }
+ };
+ o.a.b = o.a.b || function() { return 10; }; /*warning:function_name_missing*/
+
+ function closure(a) {
+ return function() { return a; };
+ }
+
+ function x() {
+ }
+}
+
Added: trunk/tests/warnings/misplaced_function.js
===================================================================
--- trunk/tests/warnings/misplaced_function.js (rev 0)
+++ trunk/tests/warnings/misplaced_function.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -0,0 +1,33 @@
+/*conf:-want_assign_or_call*/
+function misplaced_functions() {
+ var f = function() {
+ };
+ f = new function() {
+ };
+ f = (function() {
+ return 10;
+ })();
+
+ var o = {
+ f: function() {
+ return null;
+ }
+ };
+ o.a.b = {
+ f: function() {
+ return null;
+ }
+ };
+ o.a.b = o.a.b || function() { return 10; };
+ o.a.b = o.a.c || function() { return 10; }; /*TODO*/
+
+ function closure(a) {
+ return function() { return a; };
+ }
+
+ function x() {
+ }
+
+ function() {}; /*warning:misplaced_function*/
+}
+
Modified: trunk/tests/warnings/want_assign_or_call.js
===================================================================
--- trunk/tests/warnings/want_assign_or_call.js 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/tests/warnings/want_assign_or_call.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -14,7 +14,7 @@
function test() {
}
- function() { /*warning:want_assign_or_call*/
+ function() { /*warning:want_assign_or_call*/ /*warning:misplaced_function*/
return 42;
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|