javascriptlint-commit Mailing List for JavaScript Lint (Page 8)
Status: Beta
Brought to you by:
matthiasmiller
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
(42) |
Apr
(15) |
May
(2) |
Jun
|
Jul
|
Aug
(33) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
|
Feb
|
Mar
(5) |
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
(43) |
Nov
(4) |
Dec
(1) |
2010 |
Jan
|
Feb
|
Mar
|
Apr
(6) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(20) |
Oct
(23) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(4) |
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(18) |
2018 |
Jan
(7) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(8) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <mat...@us...> - 2008-08-23 22:32:51
|
Revision: 212 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=212&view=rev Author: matthiasmiller Date: 2008-08-23 22:32:48 +0000 (Sat, 23 Aug 2008) Log Message: ----------- slight fix to r210 Modified Paths: -------------- trunk/pyjsl/jsparse.py trunk/pyjsl/lint.py Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-08-23 22:24:59 UTC (rev 211) +++ trunk/pyjsl/jsparse.py 2008-08-23 22:32:48 UTC (rev 212) @@ -124,7 +124,7 @@ return True -def _parse_comments(script, root, node_positions, ignore_ranges): +def _parse_comments(script, node_positions, ignore_ranges): pos = 0 single_line_re = r"//[^\r\n]*" multi_line_re = r"/\*(.*?)\*/" @@ -198,7 +198,7 @@ process(kid) process(root_node) - return _parse_comments(script, root_node, positions, comment_ignore_ranges) + return _parse_comments(script, positions, comment_ignore_ranges) def is_compilable_unit(script): return pyspidermonkey.is_compilable_unit(script) Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-08-23 22:24:59 UTC (rev 211) +++ trunk/pyjsl/lint.py 2008-08-23 22:32:48 UTC (rev 212) @@ -177,7 +177,10 @@ parse_errors = [] root = jsparse.parse(script, parse_error) - comments = jsparse.parsecomments(script, root) + if root: + comments = jsparse.parsecomments(script, root) + else: + comments = [] ignores = [] start_ignore = None declares = [] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-23 22:25:00
|
Revision: 211 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=211&view=rev Author: matthiasmiller Date: 2008-08-23 22:24:59 +0000 (Sat, 23 Aug 2008) Log Message: ----------- Break part of jsparse.parse into jsparse.parsecomments. Modified Paths: -------------- trunk/pyjsl/jsparse.py trunk/pyjsl/lint.py Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-08-23 21:58:12 UTC (rev 210) +++ trunk/pyjsl/jsparse.py 2008-08-23 22:24:59 UTC (rev 211) @@ -179,11 +179,12 @@ msg = msg[6:].lower() error_callback(line, col, msg) - positions = NodePositions(script) + return pyspidermonkey.parse(script, _Node, _wrapped_callback) - roots = [] - nodes = [] +def parsecomments(script, root_node): + positions = NodePositions(script) comment_ignore_ranges = NodeRanges() + def process(node): if node.kind == tok.NUMBER: node.atom = positions.text(node.start_pos(), node.end_pos()) @@ -195,16 +196,10 @@ for kid in node.kids: if kid: process(kid) - def pop(): - nodes.pop() + process(root_node) - root_node = pyspidermonkey.parse(script, _Node, _wrapped_callback) - if root_node: - process(root_node) + return _parse_comments(script, root_node, positions, comment_ignore_ranges) - comments = _parse_comments(script, root_node, positions, comment_ignore_ranges) - return root_node, comments - def is_compilable_unit(script): return pyspidermonkey.is_compilable_unit(script) @@ -220,12 +215,13 @@ def dump_tree(script): def error_callback(line, col, msg): print '(%i, %i): %s', (line, col, msg) - node, comments = parse(script, error_callback) + node = parse(script, error_callback) _dump_node(node) class TestComments(unittest.TestCase): def _test(self, script, expected_comments): - root, comments = parse(script, lambda line, col, msg: None) + root = parse(script, lambda line, col, msg: None) + comments = parsecomments(script, root) encountered_comments = [node.atom for node in comments] self.assertEquals(encountered_comments, list(expected_comments)) def testSimpleComments(self): Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-08-23 21:58:12 UTC (rev 210) +++ trunk/pyjsl/lint.py 2008-08-23 22:24:59 UTC (rev 211) @@ -176,7 +176,8 @@ return lint_error(pos.line, pos.col, errname) parse_errors = [] - root, comments = jsparse.parse(script, parse_error) + root = jsparse.parse(script, parse_error) + comments = jsparse.parsecomments(script, root) ignores = [] start_ignore = None declares = [] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-23 21:58:16
|
Revision: 210 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=210&view=rev Author: matthiasmiller Date: 2008-08-23 21:58:12 +0000 (Sat, 23 Aug 2008) Log Message: ----------- var_hides_arg: add test for possible enhancement Modified Paths: -------------- trunk/tests/warnings/var_hides_arg.js Modified: trunk/tests/warnings/var_hides_arg.js =================================================================== --- trunk/tests/warnings/var_hides_arg.js 2008-08-23 19:14:03 UTC (rev 209) +++ trunk/tests/warnings/var_hides_arg.js 2008-08-23 21:58:12 UTC (rev 210) @@ -1,4 +1,7 @@ /*jsl:option explicit*/ -function var_hides_arg(duplicate) { - var duplicate; /*warning:var_hides_arg*/ +function var_hides_arg(duplicate1, duplicate2) { + var duplicate1; /*warning:var_hides_arg*/ + function inner() { + var duplicate2; /*warning:var_hides_arg*/ + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-23 19:14:06
|
Revision: 209 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=209&view=rev Author: matthiasmiller Date: 2008-08-23 19:14:03 +0000 (Sat, 23 Aug 2008) Log Message: ----------- Bump version to 0.3.1. Modified Paths: -------------- branches/cjsl/src/jsl.c Modified: branches/cjsl/src/jsl.c =================================================================== --- branches/cjsl/src/jsl.c 2008-08-23 19:01:54 UTC (rev 208) +++ branches/cjsl/src/jsl.c 2008-08-23 19:14:03 UTC (rev 209) @@ -81,7 +81,7 @@ #include <conio.h> #endif -#define JSL_VERSION "0.3.0" +#define JSL_VERSION "0.3.1" #define JSL_DEVELOPED_BY "Developed by Matthias Miller (http://www.JavaScriptLint.com)" /* exit code values */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-23 19:01:59
|
Revision: 208 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=208&view=rev Author: matthiasmiller Date: 2008-08-23 19:01:54 +0000 (Sat, 23 Aug 2008) Log Message: ----------- Fix column indices for very long lines. Modified Paths: -------------- branches/cjsl/src/jsapi.h branches/cjsl/src/jsl.c branches/cjsl/src/jsscan.c Modified: branches/cjsl/src/jsapi.h =================================================================== --- branches/cjsl/src/jsapi.h 2008-08-22 13:24:53 UTC (rev 207) +++ branches/cjsl/src/jsapi.h 2008-08-23 19:01:54 UTC (rev 208) @@ -1722,6 +1722,7 @@ struct JSErrorReport { const char *filename; /* source file name, URL, etc., or null */ uintN lineno; /* source line number */ + uintN linepos; const char *linebuf; /* offending source line without final \n */ const char *tokenptr; /* pointer to error token in linebuf */ const jschar *uclinebuf; /* unicode (original) line buffer */ Modified: branches/cjsl/src/jsl.c =================================================================== --- branches/cjsl/src/jsl.c 2008-08-22 13:24:53 UTC (rev 207) +++ branches/cjsl/src/jsl.c 2008-08-23 19:01:54 UTC (rev 208) @@ -2171,7 +2171,7 @@ /* colno is 1-based */ colno = 0; if (report->linebuf) - colno = PTRDIFF(report->tokenptr, report->linebuf, char)+1; + colno = report->linepos + PTRDIFF(report->tokenptr, report->linebuf, char)+1; OutputErrorMessage(report->filename, report->lineno, colno, errorNames[report->errorNumber], prefix, message); Modified: branches/cjsl/src/jsscan.c =================================================================== --- branches/cjsl/src/jsscan.c 2008-08-22 13:24:53 UTC (rev 207) +++ branches/cjsl/src/jsscan.c 2008-08-23 19:01:54 UTC (rev 208) @@ -560,6 +560,7 @@ linestr = js_NewStringCopyN(cx, ts->linebuf.base, ts->linebuf.limit - ts->linebuf.base, 0); + report.linepos = ts->linepos; report.linebuf = linestr ? JS_GetStringBytes(linestr) : NULL; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-22 13:24:56
|
Revision: 207 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=207&view=rev Author: matthiasmiller Date: 2008-08-22 13:24:53 +0000 (Fri, 22 Aug 2008) Log Message: ----------- #1625651: warn against -process and support --no-process Modified Paths: -------------- branches/cjsl/src/jsl.c Modified: branches/cjsl/src/jsl.c =================================================================== --- branches/cjsl/src/jsl.c 2008-08-15 19:53:49 UTC (rev 206) +++ branches/cjsl/src/jsl.c 2008-08-22 13:24:53 UTC (rev 207) @@ -1603,7 +1603,7 @@ fputc('\n', stdout); PrintHeader(); fputs("Usage: jsl [-help:conf]\n" - "\t[-conf filename] [-process filename] [+recurse|-recurse] [-stdin]\n" + "\t[-conf filename] [--process filename] [--no-process filename] [+recurse|-recurse] [-stdin]\n" "\t[-nologo] [-nofilelisting] [-nocontext] [-nosummary] [-output-format ______]\n", stdout); #ifdef WIN32 @@ -2009,11 +2009,17 @@ configPath = argv[i]; } - else if (strcasecmp(parm, "process") == 0) { - /* TODO: -process is handled as +process" */ + else if (strcasecmp(parm, "process") == 0 || + (strcasecmp(parm, "no-process") == 0 && dashes == 2)) { + JSLPathAction action = tolower(*parm) == 'p' ? JSL_PATH_ACTION_ADD : JSL_PATH_ACTION_REMOVE; + if (dashes != 2) { + fprintf(stdout, "Error: -process is now ambiguous. Use --process or --no-process."); + result = usage(); + goto cleanup; + } if (++i < argc) { char *err = NULL; - if (!AddRelativePathToList(&scriptPaths, argv[i], JSL_PATH_ACTION_ADD, &err)) { + if (!AddRelativePathToList(&scriptPaths, argv[i], action, &err)) { fprintf(stdout, "Error: %s\n", err); JS_smprintf_free(err); result = usage(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-15 19:53:51
|
Revision: 206 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=206&view=rev Author: matthiasmiller Date: 2008-08-15 19:53:49 +0000 (Fri, 15 Aug 2008) Log Message: ----------- fix duplicate meaningless_block warning Modified Paths: -------------- trunk/pyjsl/warnings.py Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-08-15 15:14:03 UTC (rev 205) +++ trunk/pyjsl/warnings.py 2008-08-15 19:53:49 UTC (rev 206) @@ -31,7 +31,6 @@ 'with_statement': 'with statement hides undeclared variables; use temporary variable instead', 'useless_comparison': 'useless comparison; comparing identical expressions', 'use_of_label': 'use of label', - 'meaningless_block': 'meaningless block; curly braces have no impact', 'misplaced_regex': 'regular expressions should be preceded by a left parenthesis, assignment, colon, or comma', 'assign_to_function_call': 'assignment to a function call', 'ambiguous_else_stmt': 'the else statement could be matched with one of multiple if statements (use curly braces to indicate intent', @@ -223,11 +222,6 @@ def use_of_label(node): raise LintWarning, node -@lookfor(tok.LC) -def meaningless_block(node): - if node.parent and node.parent.kind == tok.LC: - raise LintWarning, node - @lookfor((tok.OBJECT, op.REGEXP)) def misplaced_regex(node): if node.parent.kind == tok.NAME and node.parent.opcode == op.SETNAME: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-15 15:14:08
|
Revision: 205 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=205&view=rev Author: matthiasmiller Date: 2008-08-15 15:14:03 +0000 (Fri, 15 Aug 2008) Log Message: ----------- revert r203; var_hides_arg is handled elsewhere Modified Paths: -------------- trunk/pyjsl/warnings.py Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-08-15 15:11:11 UTC (rev 204) +++ trunk/pyjsl/warnings.py 2008-08-15 15:14:03 UTC (rev 205) @@ -450,17 +450,10 @@ def legacy_cc_not_understood(node): pass -@lookfor(tok.NAME) +@lookfor() def var_hides_arg(node): - if node.parent.kind != tok.VAR: - return + pass - parent = node.parent - while parent: - if parent.kind == tok.FUNCTION and node.atom in parent.fn_args: - raise LintWarning, node - parent = parent.parent - @lookfor() def duplicate_formal(node): pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-15 15:11:13
|
Revision: 204 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=204&view=rev Author: matthiasmiller Date: 2008-08-15 15:11:11 +0000 (Fri, 15 Aug 2008) Log Message: ----------- fix bug in variable declarations getting added to the wrong scope Modified Paths: -------------- trunk/pyjsl/lint.py Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-08-15 14:55:20 UTC (rev 203) +++ trunk/pyjsl/lint.py 2008-08-15 15:11:11 UTC (rev 204) @@ -310,7 +310,7 @@ @visitation.visit('push', tok.VAR) def _push_var(self, node): for kid in node.kids: - _warn_or_declare(scope, kid.atom, node, report) + _warn_or_declare(scopes[-1], kid.atom, node, report) return scope_checks This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-15 14:55:24
|
Revision: 203 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=203&view=rev Author: matthiasmiller Date: 2008-08-15 14:55:20 +0000 (Fri, 15 Aug 2008) Log Message: ----------- var_hides_arg: implement warning Modified Paths: -------------- trunk/pyjsl/warnings.py Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-08-15 14:47:29 UTC (rev 202) +++ trunk/pyjsl/warnings.py 2008-08-15 14:55:20 UTC (rev 203) @@ -450,10 +450,17 @@ def legacy_cc_not_understood(node): pass -@lookfor() +@lookfor(tok.NAME) def var_hides_arg(node): - pass + if node.parent.kind != tok.VAR: + return + parent = node.parent + while parent: + if parent.kind == tok.FUNCTION and node.atom in parent.fn_args: + raise LintWarning, node + parent = parent.parent + @lookfor() def duplicate_formal(node): pass This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-08-15 14:47:31
|
Revision: 202 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=202&view=rev Author: matthiasmiller Date: 2008-08-15 14:47:29 +0000 (Fri, 15 Aug 2008) Log Message: ----------- comparison_type_conv: fix warning Modified Paths: -------------- trunk/pyjsl/warnings.py Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-05-14 16:04:10 UTC (rev 201) +++ trunk/pyjsl/warnings.py 2008-08-15 14:47:29 UTC (rev 202) @@ -176,12 +176,11 @@ def comparison_type_conv(node): for kid in node.kids: if kid.kind == tok.PRIMARY and kid.opcode in (op.NULL, op.TRUE, op.FALSE): - continue + raise LintWarning, kid if kid.kind == tok.NUMBER and not kid.dval: - continue + raise LintWarning, kid if kid.kind == tok.STRING and not kid.atom: - continue - raise LintWarning, kid + raise LintWarning, kid @lookfor(tok.DEFAULT) def default_not_at_end(node): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-05-14 16:04:17
|
Revision: 201 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=201&view=rev Author: matthiasmiller Date: 2008-05-14 09:04:10 -0700 (Wed, 14 May 2008) Log Message: ----------- fix reporting of syntax errors Modified Paths: -------------- trunk/pyjsl/jsparse.py trunk/pyjsl/lint.py trunk/pyspidermonkey/pyspidermonkey.c Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-05-06 15:59:24 UTC (rev 200) +++ trunk/pyjsl/jsparse.py 2008-05-14 16:04:10 UTC (rev 201) @@ -199,7 +199,8 @@ nodes.pop() root_node = pyspidermonkey.parse(script, _Node, _wrapped_callback) - process(root_node) + if root_node: + process(root_node) comments = _parse_comments(script, root_node, positions, comment_ignore_ranges) return root_node, comments Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-05-06 15:59:24 UTC (rev 200) +++ trunk/pyjsl/lint.py 2008-05-14 16:04:10 UTC (rev 201) @@ -75,7 +75,8 @@ class Scope: def __init__(self, node): - self._is_with_scope = node.kind == tok.WITH + """ node may be None """ + self._is_with_scope = node and node.kind == tok.WITH self._parent = None self._kids = [] self._identifiers = {} @@ -116,6 +117,9 @@ identifiers.append(node) return identifiers def find_scope(self, node): + if not self._node: + return None + for kid in self._kids: scope = kid.find_scope(node) if scope: @@ -233,7 +237,8 @@ visitation.make_visitors(visitors, [_get_scope_checks(scope, report)]) # kickoff! - _lint_node(root, visitors) + if root: + _lint_node(root, visitors) # Process imports by copying global declarations into the universal scope. imports |= set(conf['declarations']) Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-05-06 15:59:24 UTC (rev 200) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-05-14 16:04:10 UTC (rev 201) @@ -423,8 +423,10 @@ m.jsnode = js_ParseTokenStream(m.context, m.global, m.token_stream); if (!m.jsnode) { - error = "parse error in file"; - goto cleanup; + if (!JS_ReportPendingException(m.context)) { + error = "parse error in file"; + goto cleanup; + } } m.pynode = jsnode_to_pynode(m.context, m.jsnode); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-05-06 15:59:49
|
Revision: 200 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=200&view=rev Author: matthiasmiller Date: 2008-05-06 08:59:24 -0700 (Tue, 06 May 2008) Log Message: ----------- Move NodePos into the C module. Modified Paths: -------------- trunk/pyjsl/jsparse.py trunk/pyspidermonkey/pyspidermonkey.c trunk/setup.py Added Paths: ----------- trunk/pyspidermonkey/nodepos.c trunk/pyspidermonkey/nodepos.h Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-04-26 05:14:50 UTC (rev 199) +++ trunk/pyjsl/jsparse.py 2008-05-06 15:59:24 UTC (rev 200) @@ -13,23 +13,7 @@ ['tok.%s' % prop for prop in dir(tok)] )) -class NodePos: - " Represents zero-based line and column number. " - def __init__(self, line, col): - self.line = line - self.col = col - def __cmp__(self, other): - if self.line < other.line: - return -1 - if self.line > other.line: - return 1 - if self.col < other.col: - return -1 - if self.col > other.col: - return 1 - return 0 - def __str__(self): - return '(line %i, col %i)' % (self.line+1, self.col+1) +NodePos = pyspidermonkey.NodePos class NodePositions: " Given a string, allows [x] lookups for NodePos line and column numbers." Added: trunk/pyspidermonkey/nodepos.c =================================================================== --- trunk/pyspidermonkey/nodepos.c (rev 0) +++ trunk/pyspidermonkey/nodepos.c 2008-05-06 15:59:24 UTC (rev 200) @@ -0,0 +1,117 @@ +/* vim: ts=4 sw=4 expandtab + */ +#include <Python.h> +#include "structmember.h" + +#include "nodepos.h" + +typedef struct { + PyObject_HEAD + int line; + int col; +} NodePosObject; + +static PyObject* +NodePos_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + NodePosObject* self; + + self = (NodePosObject*)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + + self->line = -1; + self->col = -1; + + return (PyObject*)self; +} + +static int +NodePos_init(NodePosObject* self, PyObject* args, PyObject* kwds) +{ + static char* kwlist[] = {"line", "col", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwlist, &self->line, &self->col)) + return -1; + + return 0; +} + +static PyObject* +NodePos_str(NodePosObject* self) +{ + return PyString_FromFormat("(line %i, col %i)", self->line+1, self->col+1); +} + +static int +NodePos_compare(NodePosObject* left, NodePosObject* right) +{ + if (left->line < right->line) + return -1; + if (left->line > right->line) + return 1; + if (left->col < right->col) + return -1; + if (left->col > right->col) + return 1; + return 0; +} + +static PyMemberDef +NodePos_members[] = { + {"line", T_INT, offsetof(NodePosObject, line), 0, "zero-based line number"}, + {"col", T_INT, offsetof(NodePosObject, col), 0, "zero-based column number"}, + {NULL} /* Sentinel */ +}; + +PyTypeObject NodePosType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pyspidermonkey.NodePos", /*tp_name*/ + sizeof(NodePosObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + (cmpfunc)NodePos_compare, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + (reprfunc)NodePos_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "Represents zero-based line and column number.", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + NodePos_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)NodePos_init, /* tp_init */ + 0, /* tp_alloc */ + NodePos_new, /* tp_new */ +}; + +void +RegisterNodePosType(PyObject* module) +{ + if (PyType_Ready(&NodePosType) < 0) + return; + + Py_INCREF(&NodePosType); + PyModule_AddObject(module, "NodePos", (PyObject*)&NodePosType); +} + Property changes on: trunk/pyspidermonkey/nodepos.c ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/pyspidermonkey/nodepos.h =================================================================== --- trunk/pyspidermonkey/nodepos.h (rev 0) +++ trunk/pyspidermonkey/nodepos.h 2008-05-06 15:59:24 UTC (rev 200) @@ -0,0 +1,10 @@ +/* vim: ts=4 sw=4 expandtab + */ +#ifndef NODEPOS_H +#define NODEPOS_H + +void +RegisterNodePosType(PyObject* module); + +#endif + Property changes on: trunk/pyspidermonkey/nodepos.h ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-04-26 05:14:50 UTC (rev 199) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-05-06 15:59:24 UTC (rev 200) @@ -15,6 +15,7 @@ #include <jsscope.h> #include <jsstr.h> +#include "nodepos.h" #define ARRAY_COUNT(a) (sizeof(a) / sizeof(a[0])) @@ -107,6 +108,8 @@ if (PyObject_SetAttrString(op, opcode, PyLong_FromLong(OPCODE_TO_NUM(i))) == -1) return; } + + RegisterNodePosType(module); } PyMODINIT_FUNC Modified: trunk/setup.py =================================================================== --- trunk/setup.py 2008-04-26 05:14:50 UTC (rev 199) +++ trunk/setup.py 2008-05-06 15:59:24 UTC (rev 200) @@ -22,7 +22,10 @@ include_dirs = ['spidermonkey/src', 'build/spidermonkey'], library_dirs = ['build/spidermonkey'], libraries = [library], - sources = ['pyspidermonkey/pyspidermonkey.c'] + sources = [ + 'pyspidermonkey/pyspidermonkey.c', + 'pyspidermonkey/nodepos.c' + ] ) args = {} args.update( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-26 05:14:52
|
Revision: 199 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=199&view=rev Author: matthiasmiller Date: 2008-04-25 22:14:50 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Slight tweak to the way visitors are collected. Modified Paths: -------------- trunk/pyjsl/warnings.py Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-26 05:09:30 UTC (rev 198) +++ trunk/pyjsl/warnings.py 2008-04-26 05:14:50 UTC (rev 199) @@ -68,12 +68,14 @@ 'dup_option_explicit': 'duplicate "option explicit" control comment', } +_visitors = [] def lookfor(*args): def decorate(fn): - fn._lint_nodes = args fn.warning = fn.func_name.rstrip('_') assert fn.warning in warnings, 'Missing warning description: %s' % fn.warning - return fn + + for arg in args: + _visitors.append((arg, fn)) return decorate class LintWarning(Exception): @@ -478,17 +480,11 @@ pass def make_visitors(): - functions = [ - obj for obj in sys.modules[__name__].__dict__.values() - if type(obj) == types.FunctionType and hasattr(obj, '_lint_nodes') - ] - visitors = {} - for func in functions: - for node_kind in func._lint_nodes: - try: - visitors[node_kind].append(func) - except KeyError: - visitors[node_kind] = [func] + for kind, func in _visitors: + try: + visitors[kind].append(func) + except KeyError: + visitors[kind] = [func] return visitors This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-26 05:09:32
|
Revision: 198 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=198&view=rev Author: matthiasmiller Date: 2008-04-25 22:09:30 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Change the visitors to be functions instead of classes. Modified Paths: -------------- trunk/pyjsl/conf.py trunk/pyjsl/lint.py trunk/pyjsl/warnings.py Modified: trunk/pyjsl/conf.py =================================================================== --- trunk/pyjsl/conf.py 2008-04-26 04:40:07 UTC (rev 197) +++ trunk/pyjsl/conf.py 2008-04-26 05:09:30 UTC (rev 198) @@ -68,8 +68,8 @@ 'equal_as_assign': BooleanSetting(True), 'anon_no_return_value': BooleanSetting(True) } - for klass in warnings.klasses: - self._settings[klass.__name__] = BooleanSetting(True) + for name in warnings.warnings: + self._settings[name] = BooleanSetting(True) self.loadline('-block_without_braces') def loadfile(self, path): Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-04-26 04:40:07 UTC (rev 197) +++ trunk/pyjsl/lint.py 2008-04-26 05:09:30 UTC (rev 198) @@ -218,8 +218,9 @@ _report(pos, msg, False) # Find all visitors and convert them into "onpush" callbacks that call "report" - visitors = {} - visitation.make_visitors(visitors, warnings.klasses) + visitors = { + 'push': warnings.make_visitors() + } for event in visitors: for kind, callbacks in visitors[event].items(): visitors[event][kind] = [_getreporter(callback, report) for callback in callbacks] @@ -259,7 +260,7 @@ ret = visitor(node) assert ret is None, 'visitor should raise an exception, not return a value' except warnings.LintWarning, warning: - report(warning.node, visitor.im_class.__name__) + report(warning.node, visitor.warning) return onpush def _warn_or_declare(scope, name, node, report): Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-26 04:40:07 UTC (rev 197) +++ trunk/pyjsl/warnings.py 2008-04-26 05:09:30 UTC (rev 198) @@ -1,22 +1,18 @@ # vim: ts=4 sw=4 expandtab """ This module contains all the warnings. To add a new warning, define a -class. Its name should be in lowercase and words should be separated by -underscores. Its docstring should be the warning message. +function. Its name should be in lowercase and words should be separated by +underscores. -The class can have one more more member functions to inspect nodes. The -function should be decorated with a @onpush call specifying the nodes it +The function should be decorated with a @lookfor call specifying the nodes it wants to examine. The node names may be in the tok.KIND or (tok.KIND, op.OPCODE) -format. To report a warning, the function should return the node causing -the warning. +format. To report a warning, the function should raise a LintWarning exception. For example: - class warning_name: - 'questionable JavaScript coding style' - @onpush(tok.NODEKIND, (tok.NODEKIND, op.OPCODE)) - def _lint(self, node): - if questionable: - return node + @lookfor(tok.NODEKIND, (tok.NODEKIND, op.OPCODE)) + def warning_name(node): + if questionable: + raise LintWarning, node """ import re import sys @@ -27,9 +23,59 @@ # TODO: document inspect, node:opcode, etc -def onpush(*args): - return visitation.visit('push', *args) +warnings = { + 'comparison_type_conv': 'comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)', + 'default_not_at_end': 'the default case is not at the end of the switch statement', + 'duplicate_case_in_switch': 'duplicate case in switch statement', + 'missing_default_case': 'missing default case in switch statement', + 'with_statement': 'with statement hides undeclared variables; use temporary variable instead', + 'useless_comparison': 'useless comparison; comparing identical expressions', + 'use_of_label': 'use of label', + 'meaningless_block': 'meaningless block; curly braces have no impact', + 'misplaced_regex': 'regular expressions should be preceded by a left parenthesis, assignment, colon, or comma', + 'assign_to_function_call': 'assignment to a function call', + 'ambiguous_else_stmt': 'the else statement could be matched with one of multiple if statements (use curly braces to indicate intent', + 'block_without_braces': 'block statement without curly braces', + 'ambiguous_nested_stmt': 'block statements containing block statements should use curly braces to resolve ambiguity', + 'inc_dec_within_stmt': 'increment (++) and decrement (--) operators used as part of greater statement', + 'comma_separated_stmts': 'multiple statements separated by commas (use semicolons?)', + 'empty_statement': 'empty statement or extra semicolon', + 'missing_break': 'missing break statement', + 'missing_break_for_last_case': 'missing break statement for last case in switch', + 'multiple_plus_minus': 'unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs', + 'useless_assign': 'useless assignment', + 'unreachable_code': 'unreachable code', + 'meaningless_block': 'meaningless block; curly braces have no impact', + 'useless_void': 'use of the void type may be unnecessary (void is always undefined)', + 'parseint_missing_radix': 'parseInt missing radix parameter', + 'leading_decimal_point': 'leading decimal point may indicate a number or an object member', + 'trailing_decimal_point': 'trailing decimal point may indicate a number or an object member', + 'octal_number': 'leading zeros make an octal number', + 'trailing_comma_in_array': 'extra comma is not recommended in array initializers', + 'useless_quotes': 'the quotation marks are unnecessary', + 'mismatch_ctrl_comments': 'mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence', + 'redeclared_var': 'redeclaration of {0} {1}', + 'undeclared_identifier': 'undeclared identifier: {0}', + 'jsl_cc_not_understood': 'couldn\'t understand control comment using /*jsl:keyword*/ syntax', + 'nested_comment': 'nested comment', + 'legacy_cc_not_understood': 'couldn\'t understand control comment using /*@keyword@*/ syntax', + 'var_hides_arg': 'variable {0} hides argument', + 'duplicate_formal': 'TODO', + 'missing_semicolon': 'missing semicolon', + 'ambiguous_newline': 'unexpected end of line; it is ambiguous whether these lines are part of the same statement', + 'missing_option_explicit': 'the "option explicit" control comment is missing', + 'partial_option_explicit': 'the "option explicit" control comment, if used, must be in the first script tag', + 'dup_option_explicit': 'duplicate "option explicit" control comment', +} +def lookfor(*args): + def decorate(fn): + fn._lint_nodes = args + fn.warning = fn.func_name.rstrip('_') + assert fn.warning in warnings, 'Missing warning description: %s' % fn.warning + return fn + return decorate + class LintWarning(Exception): def __init__(self, node): self.node = node @@ -124,382 +170,325 @@ return exit_points -class comparison_type_conv: - 'comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)' - @onpush((tok.EQOP, op.EQ)) - def comparison_type_conv(self, node): - for kid in node.kids: - if kid.kind == tok.PRIMARY and kid.opcode in (op.NULL, op.TRUE, op.FALSE): - continue - if kid.kind == tok.NUMBER and not kid.dval: - continue - if kid.kind == tok.STRING and not kid.atom: - continue - raise LintWarning, kid +@lookfor((tok.EQOP, op.EQ)) +def comparison_type_conv(node): + for kid in node.kids: + if kid.kind == tok.PRIMARY and kid.opcode in (op.NULL, op.TRUE, op.FALSE): + continue + if kid.kind == tok.NUMBER and not kid.dval: + continue + if kid.kind == tok.STRING and not kid.atom: + continue + raise LintWarning, kid -class default_not_at_end: - 'the default case is not at the end of the switch statement' - @onpush(tok.DEFAULT) - def default_not_at_end(self, node): - siblings = node.parent.kids - if node.node_index != len(siblings)-1: - raise LintWarning, siblings[node.node_index+1] +@lookfor(tok.DEFAULT) +def default_not_at_end(node): + siblings = node.parent.kids + if node.node_index != len(siblings)-1: + raise LintWarning, siblings[node.node_index+1] -class duplicate_case_in_switch: - 'duplicate case in switch statement' - @onpush(tok.CASE) - def duplicate_case_in_switch(self, node): - # Only look at previous siblings - siblings = node.parent.kids - siblings = siblings[:node.node_index] - # Compare values (first kid) - node_value = node.kids[0] - for sibling in siblings: - if sibling.kind == tok.CASE: - sibling_value = sibling.kids[0] - if node_value.is_equivalent(sibling_value, True): - raise LintWarning, node +@lookfor(tok.CASE) +def duplicate_case_in_switch(node): + # Only look at previous siblings + siblings = node.parent.kids + siblings = siblings[:node.node_index] + # Compare values (first kid) + node_value = node.kids[0] + for sibling in siblings: + if sibling.kind == tok.CASE: + sibling_value = sibling.kids[0] + if node_value.is_equivalent(sibling_value, True): + raise LintWarning, node -class missing_default_case: - 'missing default case in switch statement' - @onpush(tok.SWITCH) - def missing_default_case(self, node): - value, cases = node.kids - for case in cases.kids: - if case.kind == tok.DEFAULT: - return - raise LintWarning, node +@lookfor(tok.SWITCH) +def missing_default_case(node): + value, cases = node.kids + for case in cases.kids: + if case.kind == tok.DEFAULT: + return + raise LintWarning, node -class with_statement: - 'with statement hides undeclared variables; use temporary variable instead' - @onpush(tok.WITH) - def with_statement(self, node): +@lookfor(tok.WITH) +def with_statement(node): + raise LintWarning, node + +@lookfor(tok.EQOP,tok.RELOP) +def useless_comparison(node): + lvalue, rvalue = node.kids + if lvalue.is_equivalent(rvalue): raise LintWarning, node -class useless_comparison: - 'useless comparison; comparing identical expressions' - @onpush(tok.EQOP,tok.RELOP) - def useless_comparison(self, node): - lvalue, rvalue = node.kids - if lvalue.is_equivalent(rvalue): - raise LintWarning, node +@lookfor((tok.COLON, op.NAME)) +def use_of_label(node): + raise LintWarning, node -class use_of_label: - 'use of label' - @onpush((tok.COLON, op.NAME)) - def use_of_label(self, node): +@lookfor(tok.LC) +def meaningless_block(node): + if node.parent and node.parent.kind == tok.LC: raise LintWarning, node -class meaningless_block: - 'meaningless block; curly braces have no impact' - @onpush(tok.LC) - def meaningless_block(self, node): - if node.parent and node.parent.kind == tok.LC: - raise LintWarning, node +@lookfor((tok.OBJECT, op.REGEXP)) +def misplaced_regex(node): + if node.parent.kind == tok.NAME and node.parent.opcode == op.SETNAME: + return # Allow in var statements + if node.parent.kind == tok.ASSIGN and node.parent.opcode == op.NOP: + return # Allow in assigns + if node.parent.kind == tok.COLON and node.parent.parent.kind == tok.RC: + return # Allow in object literals + if node.parent.kind == tok.LP and node.parent.opcode == op.CALL: + return # Allow in parameters + if node.parent.kind == tok.DOT and node.parent.opcode == op.GETPROP: + return # Allow in /re/.property + if node.parent.kind == tok.RETURN: + return # Allow for return values + raise LintWarning, node -class misplaced_regex: - 'regular expressions should be preceded by a left parenthesis, assignment, colon, or comma' - @onpush((tok.OBJECT, op.REGEXP)) - def misplaced_regex(self, node): - if node.parent.kind == tok.NAME and node.parent.opcode == op.SETNAME: - return # Allow in var statements - if node.parent.kind == tok.ASSIGN and node.parent.opcode == op.NOP: - return # Allow in assigns - if node.parent.kind == tok.COLON and node.parent.parent.kind == tok.RC: - return # Allow in object literals - if node.parent.kind == tok.LP and node.parent.opcode == op.CALL: - return # Allow in parameters - if node.parent.kind == tok.DOT and node.parent.opcode == op.GETPROP: - return # Allow in /re/.property - if node.parent.kind == tok.RETURN: - return # Allow for return values +@lookfor(tok.ASSIGN) +def assign_to_function_call(node): + if node.kids[0].kind == tok.LP: raise LintWarning, node -class assign_to_function_call: - 'assignment to a function call' - @onpush(tok.ASSIGN) - def assign_to_function_call(self, node): - if node.kids[0].kind == tok.LP: - raise LintWarning, node +@lookfor(tok.IF) +def ambiguous_else_stmt(node): + # Only examine this node if it has an else statement. + condition, if_, else_ = node.kids + if not else_: + return -class ambiguous_else_stmt: - 'the else statement could be matched with one of multiple if statements (use curly braces to indicate intent' - @onpush(tok.IF) - def ambiguous_else_stmt(self, node): - # Only examine this node if it has an else statement. - condition, if_, else_ = node.kids - if not else_: + tmp = node + while tmp: + # Curly braces always clarify if statements. + if tmp.kind == tok.LC: return + # Else is only ambiguous in the first branch of an if statement. + if tmp.parent.kind == tok.IF and tmp.node_index == 1: + raise LintWarning, else_ + tmp = tmp.parent - tmp = node - while tmp: - # Curly braces always clarify if statements. - if tmp.kind == tok.LC: - return - # Else is only ambiguous in the first branch of an if statement. - if tmp.parent.kind == tok.IF and tmp.node_index == 1: - raise LintWarning, else_ - tmp = tmp.parent +@lookfor(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) +def block_without_braces(node): + if node.kids[1].kind != tok.LC: + raise LintWarning, node.kids[1] -class block_without_braces: - 'block statement without curly braces' - @onpush(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) - def block_without_braces(self, node): - if node.kids[1].kind != tok.LC: - raise LintWarning, node.kids[1] +_block_nodes = (tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) +@lookfor(*_block_nodes) +def ambiguous_nested_stmt(node): + # Ignore "else if" + if node.kind == tok.IF and node.node_index == 2 and node.parent.kind == tok.IF: + return -class ambiguous_nested_stmt: - 'block statements containing block statements should use curly braces to resolve ambiguity' - _block_nodes = (tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) - @onpush(*_block_nodes) - def ambiguous_nested_stmt(self, node): - # Ignore "else if" - if node.kind == tok.IF and node.node_index == 2 and node.parent.kind == tok.IF: - return + # If the parent is a block, it means a block statement + # was inside a block statement without clarifying curlies. + # (Otherwise, the node type would be tok.LC.) + if node.parent.kind in _block_nodes: + raise LintWarning, node - # If the parent is a block, it means a block statement - # was inside a block statement without clarifying curlies. - # (Otherwise, the node type would be tok.LC.) - if node.parent.kind in self._block_nodes: - raise LintWarning, node +@lookfor(tok.INC, tok.DEC) +def inc_dec_within_stmt(node): + if node.parent.kind == tok.SEMI: + return -class inc_dec_within_stmt: - 'increment (++) and decrement (--) operators used as part of greater statement' - @onpush(tok.INC, tok.DEC) - def inc_dec_within_stmt(self, node): - if node.parent.kind == tok.SEMI: - return + # Allow within the third part of the "for" + tmp = node + while tmp and tmp.parent and tmp.parent.kind == tok.COMMA: + tmp = tmp.parent + if tmp and tmp.node_index == 2 and \ + tmp.parent.kind == tok.RESERVED and \ + tmp.parent.parent.kind == tok.FOR: + return - # Allow within the third part of the "for" - tmp = node - while tmp and tmp.parent and tmp.parent.kind == tok.COMMA: - tmp = tmp.parent - if tmp and tmp.node_index == 2 and \ - tmp.parent.kind == tok.RESERVED and \ - tmp.parent.parent.kind == tok.FOR: - return + raise LintWarning, node +@lookfor(tok.COMMA) +def comma_separated_stmts(node): + # Allow within the first and third part of "for(;;)" + if _get_branch_in_for(node) in (0, 2): + return + # This is an array + if node.parent.kind == tok.RB: + return + raise LintWarning, node + +@lookfor(tok.SEMI) +def empty_statement(node): + if not node.kids[0]: raise LintWarning, node - def _is_for_ternary_stmt(self, node, branch=None): - if node.parent and node.parent.kind == tok.COMMA: - return _is_for_ternary_stmt(node.parent, branch) - return node.node_index == branch and \ - node.parent and \ - node.parent.kind == tok.RESERVED and \ - node.parent.parent.kind == tok.FOR +@lookfor(tok.LC) +def empty_statement_(node): + if node.kids: + return + # Ignore the outermost block. + if not node.parent: + return + # Some empty blocks are meaningful. + if node.parent.kind in (tok.CATCH, tok.CASE, tok.DEFAULT, tok.SWITCH, tok.FUNCTION): + return + raise LintWarning, node -class comma_separated_stmts: - 'multiple statements separated by commas (use semicolons?)' - @onpush(tok.COMMA) - def comma_separated_stmts(self, node): - # Allow within the first and third part of "for(;;)" - if _get_branch_in_for(node) in (0, 2): - return - # This is an array - if node.parent.kind == tok.RB: - return +@lookfor(tok.CASE, tok.DEFAULT) +def missing_break(node): + # The last item is handled separately + if node.node_index == len(node.parent.kids)-1: + return + case_contents = node.kids[1] + assert case_contents.kind == tok.LC + # Ignore empty case statements + if not case_contents.kids: + return + if None in _get_exit_points(case_contents): + # Show the warning on the *next* node. + raise LintWarning, node.parent.kids[node.node_index+1] + +@lookfor(tok.CASE, tok.DEFAULT) +def missing_break_for_last_case(node): + if node.node_index < len(node.parent.kids)-1: + return + case_contents = node.kids[1] + assert case_contents.kind == tok.LC + if None in _get_exit_points(case_contents): raise LintWarning, node -class empty_statement: - 'empty statement or extra semicolon' - @onpush(tok.SEMI) - def empty_statement(self, node): - if not node.kids[0]: - raise LintWarning, node - @onpush(tok.LC) - def empty_statement_(self, node): - if node.kids: - return - # Ignore the outermost block. - if not node.parent: - return - # Some empty blocks are meaningful. - if node.parent.kind in (tok.CATCH, tok.CASE, tok.DEFAULT, tok.SWITCH, tok.FUNCTION): - return +@lookfor(tok.INC) +def multiple_plus_minus(node): + if node.node_index == 0 and node.parent.kind == tok.PLUS: raise LintWarning, node +@lookfor(tok.DEC) +def multiple_plus_minus_(node): + if node.node_index == 0 and node.parent.kind == tok.MINUS: + raise LintWarning, node -class missing_break: - 'missing break statement' - @onpush(tok.CASE, tok.DEFAULT) - def missing_break(self, node): - # The last item is handled separately - if node.node_index == len(node.parent.kids)-1: - return - case_contents = node.kids[1] - assert case_contents.kind == tok.LC - # Ignore empty case statements - if not case_contents.kids: - return - if None in _get_exit_points(case_contents): - # Show the warning on the *next* node. - raise LintWarning, node.parent.kids[node.node_index+1] +@lookfor((tok.NAME, op.SETNAME)) +def useless_assign(node): + if node.parent.kind == tok.ASSIGN: + assert node.node_index == 0 + value = node.parent.kids[1] + elif node.parent.kind == tok.VAR: + value = node.kids[0] + if value and value.kind == tok.NAME and node.atom == value.atom: + raise LintWarning, node -class missing_break_for_last_case: - 'missing break statement for last case in switch' - @onpush(tok.CASE, tok.DEFAULT) - def missing_break_for_last_case(self, node): - if node.node_index < len(node.parent.kids)-1: - return - case_contents = node.kids[1] - assert case_contents.kind == tok.LC - if None in _get_exit_points(case_contents): - raise LintWarning, node +@lookfor(tok.BREAK, tok.CONTINUE, tok.RETURN, tok.THROW) +def unreachable_code(node): + if node.parent.kind == tok.LC and \ + node.node_index != len(node.parent.kids)-1: + raise LintWarning, node.parent.kids[node.node_index+1] -class multiple_plus_minus: - 'unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs' - @onpush(tok.INC) - def multiple_plus_minus(self, node): - if node.node_index == 0 and node.parent.kind == tok.PLUS: - raise LintWarning, node - @onpush(tok.DEC) - def multiple_plus_minus_(self, node): - if node.node_index == 0 and node.parent.kind == tok.MINUS: - raise LintWarning, node +#TODO: @lookfor(tok.IF) +def meaningless_block(node): + condition, if_, else_ = node.kids + if condition.kind == tok.PRIMARY and condition.opcode in (op.TRUE, op.FALSE, op.NULL): + raise LintWarning, condition +#TODO: @lookfor(tok.WHILE) +def meaningless_blocK_(node): + condition = node.kids[0] + if condition.kind == tok.PRIMARY and condition.opcode in (op.FALSE, op.NULL): + raise LintWarning, condition +@lookfor(tok.LC) +def meaningless_block__(node): + if node.parent and node.parent.kind == tok.LC: + raise LintWarning, node -class useless_assign: - 'useless assignment' - @onpush((tok.NAME, op.SETNAME)) - def useless_assign(self, node): - if node.parent.kind == tok.ASSIGN: - assert node.node_index == 0 - value = node.parent.kids[1] - elif node.parent.kind == tok.VAR: - value = node.kids[0] - if value and value.kind == tok.NAME and node.atom == value.atom: - raise LintWarning, node +@lookfor((tok.UNARYOP, op.VOID)) +def useless_void(node): + raise LintWarning, node -class unreachable_code: - 'unreachable code' - @onpush(tok.BREAK, tok.CONTINUE, tok.RETURN, tok.THROW) - def unreachable_code(self, node): - if node.parent.kind == tok.LC and \ - node.node_index != len(node.parent.kids)-1: - raise LintWarning, node.parent.kids[node.node_index+1] +@lookfor((tok.LP, op.CALL)) +def parseint_missing_radix(node): + if node.kids[0].kind == tok.NAME and node.kids[0].atom == 'parseInt' and len(node.kids) <= 2: + raise LintWarning, node -class meaningless_block: - 'meaningless block; curly braces have no impact' - #TODO: @onpush(tok.IF) - def meaningless_block(self, node): - condition, if_, else_ = node.kids - if condition.kind == tok.PRIMARY and condition.opcode in (op.TRUE, op.FALSE, op.NULL): - raise LintWarning, condition - #TODO: @onpush(tok.WHILE) - def meaningless_blocK_(self, node): - condition = node.kids[0] - if condition.kind == tok.PRIMARY and condition.opcode in (op.FALSE, op.NULL): - raise LintWarning, condition - @onpush(tok.LC) - def meaningless_block__(self, node): - if node.parent and node.parent.kind == tok.LC: - raise LintWarning, node +@lookfor(tok.NUMBER) +def leading_decimal_point(node): + if node.atom.startswith('.'): + raise LintWarning, node -class useless_void: - 'use of the void type may be unnecessary (void is always undefined)' - @onpush((tok.UNARYOP, op.VOID)) - def useless_void(self, node): +@lookfor(tok.NUMBER) +def trailing_decimal_point(node): + if node.parent.kind == tok.DOT: raise LintWarning, node + if node.atom.endswith('.'): + raise LintWarning, node -class parseint_missing_radix: - 'parseInt missing radix parameter' - @onpush((tok.LP, op.CALL)) - def parseint_missing_radix(self, node): - if node.kids[0].kind == tok.NAME and node.kids[0].atom == 'parseInt' and len(node.kids) <= 2: - raise LintWarning, node +_octal_regexp = re.compile('^0[0-9]') +@lookfor(tok.NUMBER) +def octal_number(node): + if _octal_regexp.match(node.atom): + raise LintWarning, node -class leading_decimal_point: - 'leading decimal point may indicate a number or an object member' - @onpush(tok.NUMBER) - def leading_decimal_point(self, node): - if node.atom.startswith('.'): - raise LintWarning, node +@lookfor(tok.RB) +def trailing_comma_in_array(node): + if node.end_comma: + raise LintWarning, node -class trailing_decimal_point: - 'trailing decimal point may indicate a number or an object member' - @onpush(tok.NUMBER) - def trailing_decimal_point(self, node): - if node.parent.kind == tok.DOT: - raise LintWarning, node - if node.atom.endswith('.'): - raise LintWarning, node +@lookfor(tok.STRING) +def useless_quotes(node): + if node.node_index == 0 and node.parent.kind == tok.COLON: + raise LintWarning, node -class octal_number: - 'leading zeros make an octal number' - _regexp = re.compile('^0[0-9]') - @onpush(tok.NUMBER) - def octal_number(self, node): - if self._regexp.match(node.atom): - raise LintWarning, node - -class trailing_comma_in_array: - 'extra comma is not recommended in array initializers' - @onpush(tok.RB) - def trailing_comma_in_array(self, node): - if node.end_comma: - raise LintWarning, node - -class useless_quotes: - 'the quotation marks are unnecessary' - @onpush(tok.STRING) - def useless_quotes(self, node): - if node.node_index == 0 and node.parent.kind == tok.COLON: - raise LintWarning, node - -class mismatch_ctrl_comments: - 'mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence' +@lookfor() +def mismatch_ctrl_comments(node): pass -class redeclared_var: - 'redeclaration of {0} {1}' +@lookfor() +def redeclared_var(node): pass -class undeclared_identifier: - 'undeclared identifier: {0}' +@lookfor() +def undeclared_identifier(node): pass -class jsl_cc_not_understood: - 'couldn\'t understand control comment using /*jsl:keyword*/ syntax' +@lookfor() +def jsl_cc_not_understood(node): pass -class nested_comment: - 'nested comment' +@lookfor() +def nested_comment(node): pass -class legacy_cc_not_understood: - 'couldn\'t understand control comment using /*@keyword@*/ syntax' +@lookfor() +def legacy_cc_not_understood(node): pass -class var_hides_arg: - 'variable {0} hides argument' +@lookfor() +def var_hides_arg(node): pass -class duplicate_formal: - 'TODO' +@lookfor() +def duplicate_formal(node): pass -class missing_semicolon: - 'missing semicolon' +@lookfor() +def missing_semicolon(node): pass -class ambiguous_newline: - 'unexpected end of line; it is ambiguous whether these lines are part of the same statement' +@lookfor() +def ambiguous_newline(node): pass -class missing_option_explicit: - 'the "option explicit" control comment is missing' +@lookfor() +def missing_option_explicit(node): pass -class partial_option_explicit: - 'the "option explicit" control comment, if used, must be in the first script tag' +@lookfor() +def partial_option_explicit(node): pass -class dup_option_explicit: - 'duplicate "option explicit" control comment' +@lookfor() +def dup_option_explicit(node): pass -klasses = tuple([ - obj for - obj in - sys.modules[__name__].__dict__.values() if - type(obj) == types.ClassType -]) +def make_visitors(): + functions = [ + obj for obj in sys.modules[__name__].__dict__.values() + if type(obj) == types.FunctionType and hasattr(obj, '_lint_nodes') + ] + visitors = {} + for func in functions: + for node_kind in func._lint_nodes: + try: + visitors[node_kind].append(func) + except KeyError: + visitors[node_kind] = [func] + return visitors + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-26 04:40:13
|
Revision: 197 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=197&view=rev Author: matthiasmiller Date: 2008-04-25 21:40:07 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Change member function names to match class names. Modified Paths: -------------- trunk/pyjsl/warnings.py Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-25 22:27:58 UTC (rev 196) +++ trunk/pyjsl/warnings.py 2008-04-26 04:40:07 UTC (rev 197) @@ -127,7 +127,7 @@ class comparison_type_conv: 'comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)' @onpush((tok.EQOP, op.EQ)) - def _lint(self, node): + def comparison_type_conv(self, node): for kid in node.kids: if kid.kind == tok.PRIMARY and kid.opcode in (op.NULL, op.TRUE, op.FALSE): continue @@ -140,7 +140,7 @@ class default_not_at_end: 'the default case is not at the end of the switch statement' @onpush(tok.DEFAULT) - def _lint(self, node): + def default_not_at_end(self, node): siblings = node.parent.kids if node.node_index != len(siblings)-1: raise LintWarning, siblings[node.node_index+1] @@ -148,7 +148,7 @@ class duplicate_case_in_switch: 'duplicate case in switch statement' @onpush(tok.CASE) - def _lint(self, node): + def duplicate_case_in_switch(self, node): # Only look at previous siblings siblings = node.parent.kids siblings = siblings[:node.node_index] @@ -163,7 +163,7 @@ class missing_default_case: 'missing default case in switch statement' @onpush(tok.SWITCH) - def _lint(self, node): + def missing_default_case(self, node): value, cases = node.kids for case in cases.kids: if case.kind == tok.DEFAULT: @@ -173,13 +173,13 @@ class with_statement: 'with statement hides undeclared variables; use temporary variable instead' @onpush(tok.WITH) - def _lint(self, node): + def with_statement(self, node): raise LintWarning, node class useless_comparison: 'useless comparison; comparing identical expressions' @onpush(tok.EQOP,tok.RELOP) - def _lint(self, node): + def useless_comparison(self, node): lvalue, rvalue = node.kids if lvalue.is_equivalent(rvalue): raise LintWarning, node @@ -187,20 +187,20 @@ class use_of_label: 'use of label' @onpush((tok.COLON, op.NAME)) - def _lint(self, node): + def use_of_label(self, node): raise LintWarning, node class meaningless_block: 'meaningless block; curly braces have no impact' @onpush(tok.LC) - def _lint(self, node): + def meaningless_block(self, node): if node.parent and node.parent.kind == tok.LC: raise LintWarning, node class misplaced_regex: 'regular expressions should be preceded by a left parenthesis, assignment, colon, or comma' @onpush((tok.OBJECT, op.REGEXP)) - def _lint(self, node): + def misplaced_regex(self, node): if node.parent.kind == tok.NAME and node.parent.opcode == op.SETNAME: return # Allow in var statements if node.parent.kind == tok.ASSIGN and node.parent.opcode == op.NOP: @@ -218,14 +218,14 @@ class assign_to_function_call: 'assignment to a function call' @onpush(tok.ASSIGN) - def _lint(self, node): + def assign_to_function_call(self, node): if node.kids[0].kind == tok.LP: raise LintWarning, node class ambiguous_else_stmt: 'the else statement could be matched with one of multiple if statements (use curly braces to indicate intent' @onpush(tok.IF) - def _lint(self, node): + def ambiguous_else_stmt(self, node): # Only examine this node if it has an else statement. condition, if_, else_ = node.kids if not else_: @@ -244,7 +244,7 @@ class block_without_braces: 'block statement without curly braces' @onpush(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) - def _lint(self, node): + def block_without_braces(self, node): if node.kids[1].kind != tok.LC: raise LintWarning, node.kids[1] @@ -252,7 +252,7 @@ 'block statements containing block statements should use curly braces to resolve ambiguity' _block_nodes = (tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) @onpush(*_block_nodes) - def _lint(self, node): + def ambiguous_nested_stmt(self, node): # Ignore "else if" if node.kind == tok.IF and node.node_index == 2 and node.parent.kind == tok.IF: return @@ -266,7 +266,7 @@ class inc_dec_within_stmt: 'increment (++) and decrement (--) operators used as part of greater statement' @onpush(tok.INC, tok.DEC) - def _lint(self, node): + def inc_dec_within_stmt(self, node): if node.parent.kind == tok.SEMI: return @@ -291,7 +291,7 @@ class comma_separated_stmts: 'multiple statements separated by commas (use semicolons?)' @onpush(tok.COMMA) - def _lint(self, node): + def comma_separated_stmts(self, node): # Allow within the first and third part of "for(;;)" if _get_branch_in_for(node) in (0, 2): return @@ -303,11 +303,11 @@ class empty_statement: 'empty statement or extra semicolon' @onpush(tok.SEMI) - def _semi(self, node): + def empty_statement(self, node): if not node.kids[0]: raise LintWarning, node @onpush(tok.LC) - def _lc(self, node): + def empty_statement_(self, node): if node.kids: return # Ignore the outermost block. @@ -321,7 +321,7 @@ class missing_break: 'missing break statement' @onpush(tok.CASE, tok.DEFAULT) - def _lint(self, node): + def missing_break(self, node): # The last item is handled separately if node.node_index == len(node.parent.kids)-1: return @@ -337,7 +337,7 @@ class missing_break_for_last_case: 'missing break statement for last case in switch' @onpush(tok.CASE, tok.DEFAULT) - def _lint(self, node): + def missing_break_for_last_case(self, node): if node.node_index < len(node.parent.kids)-1: return case_contents = node.kids[1] @@ -348,18 +348,18 @@ class multiple_plus_minus: 'unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs' @onpush(tok.INC) - def _inc(self, node): + def multiple_plus_minus(self, node): if node.node_index == 0 and node.parent.kind == tok.PLUS: raise LintWarning, node @onpush(tok.DEC) - def _dec(self, node): + def multiple_plus_minus_(self, node): if node.node_index == 0 and node.parent.kind == tok.MINUS: raise LintWarning, node class useless_assign: 'useless assignment' @onpush((tok.NAME, op.SETNAME)) - def _lint(self, node): + def useless_assign(self, node): if node.parent.kind == tok.ASSIGN: assert node.node_index == 0 value = node.parent.kids[1] @@ -371,7 +371,7 @@ class unreachable_code: 'unreachable code' @onpush(tok.BREAK, tok.CONTINUE, tok.RETURN, tok.THROW) - def _lint(self, node): + def unreachable_code(self, node): if node.parent.kind == tok.LC and \ node.node_index != len(node.parent.kids)-1: raise LintWarning, node.parent.kids[node.node_index+1] @@ -379,44 +379,44 @@ class meaningless_block: 'meaningless block; curly braces have no impact' #TODO: @onpush(tok.IF) - def _lint(self, node): + def meaningless_block(self, node): condition, if_, else_ = node.kids if condition.kind == tok.PRIMARY and condition.opcode in (op.TRUE, op.FALSE, op.NULL): raise LintWarning, condition #TODO: @onpush(tok.WHILE) - def _lint(self, node): + def meaningless_blocK_(self, node): condition = node.kids[0] if condition.kind == tok.PRIMARY and condition.opcode in (op.FALSE, op.NULL): raise LintWarning, condition @onpush(tok.LC) - def _lint(self, node): + def meaningless_block__(self, node): if node.parent and node.parent.kind == tok.LC: raise LintWarning, node class useless_void: 'use of the void type may be unnecessary (void is always undefined)' @onpush((tok.UNARYOP, op.VOID)) - def _lint(self, node): + def useless_void(self, node): raise LintWarning, node class parseint_missing_radix: 'parseInt missing radix parameter' @onpush((tok.LP, op.CALL)) - def _lint(self, node): + def parseint_missing_radix(self, node): if node.kids[0].kind == tok.NAME and node.kids[0].atom == 'parseInt' and len(node.kids) <= 2: raise LintWarning, node class leading_decimal_point: 'leading decimal point may indicate a number or an object member' @onpush(tok.NUMBER) - def _lint(self, node): + def leading_decimal_point(self, node): if node.atom.startswith('.'): raise LintWarning, node class trailing_decimal_point: 'trailing decimal point may indicate a number or an object member' @onpush(tok.NUMBER) - def _lint(self, node): + def trailing_decimal_point(self, node): if node.parent.kind == tok.DOT: raise LintWarning, node if node.atom.endswith('.'): @@ -426,21 +426,21 @@ 'leading zeros make an octal number' _regexp = re.compile('^0[0-9]') @onpush(tok.NUMBER) - def _line(self, node): + def octal_number(self, node): if self._regexp.match(node.atom): raise LintWarning, node class trailing_comma_in_array: 'extra comma is not recommended in array initializers' @onpush(tok.RB) - def _line(self, node): + def trailing_comma_in_array(self, node): if node.end_comma: raise LintWarning, node class useless_quotes: 'the quotation marks are unnecessary' @onpush(tok.STRING) - def _lint(self, node): + def useless_quotes(self, node): if node.node_index == 0 and node.parent.kind == tok.COLON: raise LintWarning, node This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-25 22:28:04
|
Revision: 196 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=196&view=rev Author: matthiasmiller Date: 2008-04-25 15:27:58 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Remove bogus exception. Modified Paths: -------------- trunk/pyjsl/visitation.py Modified: trunk/pyjsl/visitation.py =================================================================== --- trunk/pyjsl/visitation.py 2008-04-25 22:24:51 UTC (rev 195) +++ trunk/pyjsl/visitation.py 2008-04-25 22:27:58 UTC (rev 196) @@ -10,8 +10,6 @@ def _decorate(fn): fn._visit_event = event fn._visit_nodes = args - print dir(fn), fn.func_name - raise ValueError return fn return _decorate This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-25 22:24:52
|
Revision: 195 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=195&view=rev Author: matthiasmiller Date: 2008-04-25 15:24:51 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Change scope checks to use visitors. Modified Paths: -------------- trunk/pyjsl/lint.py trunk/pyjsl/visitation.py Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-04-25 21:52:35 UTC (rev 194) +++ trunk/pyjsl/lint.py 2008-04-25 22:24:51 UTC (rev 195) @@ -217,14 +217,22 @@ for pos, msg in parse_errors: _report(pos, msg, False) - visitors = visitation.make_visitors(warnings.klasses)['push'] + # Find all visitors and convert them into "onpush" callbacks that call "report" + visitors = {} + visitation.make_visitors(visitors, warnings.klasses) + for event in visitors: + for kind, callbacks in visitors[event].items(): + visitors[event][kind] = [_getreporter(callback, report) for callback in callbacks] assert not script_cache imports = script_cache['imports'] = set() scope = script_cache['scope'] = Scope(root) + # Push the scope/variable checks. + visitation.make_visitors(visitors, [_get_scope_checks(scope, report)]) + # kickoff! - _lint_node(root, visitors, report, scope) + _lint_node(root, visitors) # Process imports by copying global declarations into the universal scope. imports |= set(conf['declarations']) @@ -245,6 +253,15 @@ if not node.atom in imports: report(node, 'undeclared_identifier') +def _getreporter(visitor, report): + def onpush(node): + try: + ret = visitor(node) + assert ret is None, 'visitor should raise an exception, not return a value' + except warnings.LintWarning, warning: + report(warning.node, visitor.im_class.__name__) + return onpush + def _warn_or_declare(scope, name, node, report): other = scope.get_identifier(name) if other and other.kind == tok.FUNCTION and name in other.fn_args: @@ -254,42 +271,58 @@ else: scope.add_declaration(name, node) -def _lint_node(node, visitors, report, scope): +def _get_scope_checks(scope, report): + scopes = [scope] - # Let the visitors warn. - for kind in (node.kind, (node.kind, node.opcode)): - if kind in visitors: - for visitor in visitors[kind]: - try: - ret = visitor(node) - assert ret is None, 'visitor should raise an exception, not return a value' - except warnings.LintWarning, warning: - report(warning.node, visitor.im_class.__name__) + class scope_checks: + ' ' + @visitation.visit('push', tok.NAME) + def _name(self, node): + if node.node_index == 0 and node.parent.kind == tok.COLON and node.parent.parent.kind == tok.RC: + pass # left side of object literal + elif node.parent.kind == tok.CATCH: + scopes[-1].add_declaration(node.atom, node) + else: + scopes[-1].add_reference(node.atom, node) - if node.kind == tok.NAME: - if node.node_index == 0 and node.parent.kind == tok.COLON and node.parent.parent.kind == tok.RC: - pass # left side of object literal - elif node.parent.kind == tok.CATCH: - scope.add_declaration(node.atom, node) - else: - scope.add_reference(node.atom, node) + @visitation.visit('push', tok.FUNCTION) + def _push_func(self, node): + if node.fn_name: + _warn_or_declare(scopes[-1], node.fn_name, node, report) + self._push_scope(node) + for var_name in node.fn_args: + scopes[-1].add_declaration(var_name, node) - # Push function identifiers - if node.kind == tok.FUNCTION: - if node.fn_name: - _warn_or_declare(scope, node.fn_name, node, report) - scope = scope.add_scope(node) - for var_name in node.fn_args: - scope.add_declaration(var_name, node) - elif node.kind == tok.LEXICALSCOPE: - scope = scope.add_scope(node) - elif node.kind == tok.WITH: - scope = scope.add_scope(node) + @visitation.visit('push', tok.LEXICALSCOPE, tok.WITH) + def _push_scope(self, node): + scopes.append(scopes[-1].add_scope(node)) - if node.parent and node.parent.kind == tok.VAR: - _warn_or_declare(scope, node.atom, node, report) + @visitation.visit('pop', tok.FUNCTION, tok.LEXICALSCOPE, tok.WITH) + def _pop_scope(self, node): + scopes.pop() + @visitation.visit('push', tok.VAR) + def _push_var(self, node): + for kid in node.kids: + _warn_or_declare(scope, kid.atom, node, report) + + return scope_checks + + +def _lint_node(node, visitors): + + for kind in (node.kind, (node.kind, node.opcode)): + if kind in visitors['push']: + for visitor in visitors['push'][kind]: + visitor(node) + for child in node.kids: if child: - _lint_node(child, visitors, report, scope) + _lint_node(child, visitors) + for kind in (node.kind, (node.kind, node.opcode)): + if kind in visitors['pop']: + for visitor in visitors['pop'][kind]: + visitor(node) + + Modified: trunk/pyjsl/visitation.py =================================================================== --- trunk/pyjsl/visitation.py 2008-04-25 21:52:35 UTC (rev 194) +++ trunk/pyjsl/visitation.py 2008-04-25 22:24:51 UTC (rev 195) @@ -10,13 +10,21 @@ def _decorate(fn): fn._visit_event = event fn._visit_nodes = args + print dir(fn), fn.func_name + raise ValueError return fn return _decorate -def make_visitors(klasses): +def make_visitors(visitors, klasses): """ Searches klasses for all member functions decorated with @visit and - returns a dictionary that maps from node type to visitor function. """ - visitors = {} + fills a dictionary that looks like: + visitors = { + 'event_name': { + 'node_type' : [func1, func2] + } + } + """ + assert isinstance(visitors, dict) # Intantiate an instance of each class for klass in klasses: @@ -32,13 +40,15 @@ for node_kind in getattr(func, '_visit_nodes', ()): # Group visitors by event (e.g. push vs pop) if not event_visitors: - if not func._visit_event in visitors: - visitors[func._visit_event] = {} - event_visitors = visitors[func._visit_event] + try: + event_visitors = visitors[func._visit_event] + except KeyError: + event_visitors = visitors[func._visit_event] = {} # Map from node_kind to the function - if not node_kind in visitors: - event_visitors[node_kind] = [] - event_visitors[node_kind].append(func) + try: + event_visitors[node_kind].append(func) + except KeyError: + event_visitors[node_kind] = [func] return visitors This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-25 21:52:36
|
Revision: 194 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=194&view=rev Author: matthiasmiller Date: 2008-04-25 14:52:35 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Change visitors to raise an exception instead of return the invalid node. Modified Paths: -------------- trunk/pyjsl/lint.py trunk/pyjsl/warnings.py Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-04-25 21:39:29 UTC (rev 193) +++ trunk/pyjsl/lint.py 2008-04-25 21:52:35 UTC (rev 194) @@ -260,9 +260,11 @@ for kind in (node.kind, (node.kind, node.opcode)): if kind in visitors: for visitor in visitors[kind]: - warning_node = visitor(node) - if warning_node: - report(warning_node, visitor.im_class.__name__) + try: + ret = visitor(node) + assert ret is None, 'visitor should raise an exception, not return a value' + except warnings.LintWarning, warning: + report(warning.node, visitor.im_class.__name__) if node.kind == tok.NAME: if node.node_index == 0 and node.parent.kind == tok.COLON and node.parent.parent.kind == tok.RC: Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-25 21:39:29 UTC (rev 193) +++ trunk/pyjsl/warnings.py 2008-04-25 21:52:35 UTC (rev 194) @@ -30,6 +30,10 @@ def onpush(*args): return visitation.visit('push', *args) +class LintWarning(Exception): + def __init__(self, node): + self.node = node + def _get_branch_in_for(node): " Returns None if this is not one of the branches in a 'for' " if node.parent and node.parent.kind == tok.RESERVED and \ @@ -124,18 +128,14 @@ 'comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)' @onpush((tok.EQOP, op.EQ)) def _lint(self, node): - lvalue, rvalue = node.kids - if not self._allow_coercive_compare(lvalue) or \ - not self._allow_coercive_compare(rvalue): - return node - def _allow_coercive_compare(self, node): - if node.kind == tok.PRIMARY and node.opcode in (op.NULL, op.TRUE, op.FALSE): - return False - if node.kind == tok.NUMBER and not node.dval: - return False - if node.kind == tok.STRING and not node.atom: - return False - return True + for kid in node.kids: + if kid.kind == tok.PRIMARY and kid.opcode in (op.NULL, op.TRUE, op.FALSE): + continue + if kid.kind == tok.NUMBER and not kid.dval: + continue + if kid.kind == tok.STRING and not kid.atom: + continue + raise LintWarning, kid class default_not_at_end: 'the default case is not at the end of the switch statement' @@ -143,7 +143,7 @@ def _lint(self, node): siblings = node.parent.kids if node.node_index != len(siblings)-1: - return siblings[node.node_index+1] + raise LintWarning, siblings[node.node_index+1] class duplicate_case_in_switch: 'duplicate case in switch statement' @@ -158,7 +158,7 @@ if sibling.kind == tok.CASE: sibling_value = sibling.kids[0] if node_value.is_equivalent(sibling_value, True): - return node + raise LintWarning, node class missing_default_case: 'missing default case in switch statement' @@ -168,13 +168,13 @@ for case in cases.kids: if case.kind == tok.DEFAULT: return - return node + raise LintWarning, node class with_statement: 'with statement hides undeclared variables; use temporary variable instead' @onpush(tok.WITH) def _lint(self, node): - return node + raise LintWarning, node class useless_comparison: 'useless comparison; comparing identical expressions' @@ -182,20 +182,20 @@ def _lint(self, node): lvalue, rvalue = node.kids if lvalue.is_equivalent(rvalue): - return node + raise LintWarning, node class use_of_label: 'use of label' @onpush((tok.COLON, op.NAME)) def _lint(self, node): - return node + raise LintWarning, node class meaningless_block: 'meaningless block; curly braces have no impact' @onpush(tok.LC) def _lint(self, node): if node.parent and node.parent.kind == tok.LC: - return node + raise LintWarning, node class misplaced_regex: 'regular expressions should be preceded by a left parenthesis, assignment, colon, or comma' @@ -213,14 +213,14 @@ return # Allow in /re/.property if node.parent.kind == tok.RETURN: return # Allow for return values - return node + raise LintWarning, node class assign_to_function_call: 'assignment to a function call' @onpush(tok.ASSIGN) def _lint(self, node): if node.kids[0].kind == tok.LP: - return node + raise LintWarning, node class ambiguous_else_stmt: 'the else statement could be matched with one of multiple if statements (use curly braces to indicate intent' @@ -238,7 +238,7 @@ return # Else is only ambiguous in the first branch of an if statement. if tmp.parent.kind == tok.IF and tmp.node_index == 1: - return else_ + raise LintWarning, else_ tmp = tmp.parent class block_without_braces: @@ -246,7 +246,7 @@ @onpush(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) def _lint(self, node): if node.kids[1].kind != tok.LC: - return node.kids[1] + raise LintWarning, node.kids[1] class ambiguous_nested_stmt: 'block statements containing block statements should use curly braces to resolve ambiguity' @@ -261,14 +261,14 @@ # was inside a block statement without clarifying curlies. # (Otherwise, the node type would be tok.LC.) if node.parent.kind in self._block_nodes: - return node + raise LintWarning, node class inc_dec_within_stmt: 'increment (++) and decrement (--) operators used as part of greater statement' @onpush(tok.INC, tok.DEC) def _lint(self, node): if node.parent.kind == tok.SEMI: - return None + return # Allow within the third part of the "for" tmp = node @@ -277,9 +277,9 @@ if tmp and tmp.node_index == 2 and \ tmp.parent.kind == tok.RESERVED and \ tmp.parent.parent.kind == tok.FOR: - return None + return - return node + raise LintWarning, node def _is_for_ternary_stmt(self, node, branch=None): if node.parent and node.parent.kind == tok.COMMA: return _is_for_ternary_stmt(node.parent, branch) @@ -298,14 +298,14 @@ # This is an array if node.parent.kind == tok.RB: return - return node + raise LintWarning, node class empty_statement: 'empty statement or extra semicolon' @onpush(tok.SEMI) def _semi(self, node): if not node.kids[0]: - return node + raise LintWarning, node @onpush(tok.LC) def _lc(self, node): if node.kids: @@ -316,7 +316,7 @@ # Some empty blocks are meaningful. if node.parent.kind in (tok.CATCH, tok.CASE, tok.DEFAULT, tok.SWITCH, tok.FUNCTION): return - return node + raise LintWarning, node class missing_break: 'missing break statement' @@ -332,7 +332,7 @@ return if None in _get_exit_points(case_contents): # Show the warning on the *next* node. - return node.parent.kids[node.node_index+1] + raise LintWarning, node.parent.kids[node.node_index+1] class missing_break_for_last_case: 'missing break statement for last case in switch' @@ -343,18 +343,18 @@ case_contents = node.kids[1] assert case_contents.kind == tok.LC if None in _get_exit_points(case_contents): - return node + raise LintWarning, node class multiple_plus_minus: 'unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs' @onpush(tok.INC) def _inc(self, node): if node.node_index == 0 and node.parent.kind == tok.PLUS: - return node + raise LintWarning, node @onpush(tok.DEC) def _dec(self, node): if node.node_index == 0 and node.parent.kind == tok.MINUS: - return node + raise LintWarning, node class useless_assign: 'useless assignment' @@ -366,7 +366,7 @@ elif node.parent.kind == tok.VAR: value = node.kids[0] if value and value.kind == tok.NAME and node.atom == value.atom: - return node + raise LintWarning, node class unreachable_code: 'unreachable code' @@ -374,7 +374,7 @@ def _lint(self, node): if node.parent.kind == tok.LC and \ node.node_index != len(node.parent.kids)-1: - return node.parent.kids[node.node_index+1] + raise LintWarning, node.parent.kids[node.node_index+1] class meaningless_block: 'meaningless block; curly braces have no impact' @@ -382,45 +382,45 @@ def _lint(self, node): condition, if_, else_ = node.kids if condition.kind == tok.PRIMARY and condition.opcode in (op.TRUE, op.FALSE, op.NULL): - return condition + raise LintWarning, condition #TODO: @onpush(tok.WHILE) def _lint(self, node): condition = node.kids[0] if condition.kind == tok.PRIMARY and condition.opcode in (op.FALSE, op.NULL): - return condition + raise LintWarning, condition @onpush(tok.LC) def _lint(self, node): if node.parent and node.parent.kind == tok.LC: - return node + raise LintWarning, node class useless_void: 'use of the void type may be unnecessary (void is always undefined)' @onpush((tok.UNARYOP, op.VOID)) def _lint(self, node): - return node + raise LintWarning, node class parseint_missing_radix: 'parseInt missing radix parameter' @onpush((tok.LP, op.CALL)) def _lint(self, node): if node.kids[0].kind == tok.NAME and node.kids[0].atom == 'parseInt' and len(node.kids) <= 2: - return node + raise LintWarning, node class leading_decimal_point: 'leading decimal point may indicate a number or an object member' @onpush(tok.NUMBER) def _lint(self, node): if node.atom.startswith('.'): - return node + raise LintWarning, node class trailing_decimal_point: 'trailing decimal point may indicate a number or an object member' @onpush(tok.NUMBER) def _lint(self, node): if node.parent.kind == tok.DOT: - return node + raise LintWarning, node if node.atom.endswith('.'): - return node + raise LintWarning, node class octal_number: 'leading zeros make an octal number' @@ -428,21 +428,21 @@ @onpush(tok.NUMBER) def _line(self, node): if self._regexp.match(node.atom): - return node + raise LintWarning, node class trailing_comma_in_array: 'extra comma is not recommended in array initializers' @onpush(tok.RB) def _line(self, node): if node.end_comma: - return node + raise LintWarning, node class useless_quotes: 'the quotation marks are unnecessary' @onpush(tok.STRING) def _lint(self, node): if node.node_index == 0 and node.parent.kind == tok.COLON: - return node + raise LintWarning, node class mismatch_ctrl_comments: 'mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-25 21:39:53
|
Revision: 193 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=193&view=rev Author: matthiasmiller Date: 2008-04-25 14:39:29 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Allow node visitors to specify an event (e.g. "push" vs. "pop"). Modified Paths: -------------- trunk/pyjsl/lint.py trunk/pyjsl/visitation.py trunk/pyjsl/warnings.py Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-04-25 21:16:20 UTC (rev 192) +++ trunk/pyjsl/lint.py 2008-04-25 21:39:29 UTC (rev 193) @@ -217,7 +217,7 @@ for pos, msg in parse_errors: _report(pos, msg, False) - visitors = visitation.make_visitors(warnings.klasses) + visitors = visitation.make_visitors(warnings.klasses)['push'] assert not script_cache imports = script_cache['imports'] = set() Modified: trunk/pyjsl/visitation.py =================================================================== --- trunk/pyjsl/visitation.py 2008-04-25 21:16:20 UTC (rev 192) +++ trunk/pyjsl/visitation.py 2008-04-25 21:39:29 UTC (rev 193) @@ -3,11 +3,12 @@ traverse the tree to generate warnings. """ -def visit(*args): +def visit(event, *args): """ This decorator is used to indicate which nodes the function should examine. The function should accept (self, node) and return the relevant node or None. """ def _decorate(fn): + fn._visit_event = event fn._visit_nodes = args return fn return _decorate @@ -27,10 +28,17 @@ # Look for functions with the "_visit_nodes" property. visitor = klass() for func in [getattr(visitor, name) for name in dir(visitor)]: + event_visitors = None for node_kind in getattr(func, '_visit_nodes', ()): + # Group visitors by event (e.g. push vs pop) + if not event_visitors: + if not func._visit_event in visitors: + visitors[func._visit_event] = {} + event_visitors = visitors[func._visit_event] + # Map from node_kind to the function if not node_kind in visitors: - visitors[node_kind] = [] - visitors[node_kind].append(func) + event_visitors[node_kind] = [] + event_visitors[node_kind].append(func) return visitors Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-25 21:16:20 UTC (rev 192) +++ trunk/pyjsl/warnings.py 2008-04-25 21:39:29 UTC (rev 193) @@ -4,7 +4,7 @@ underscores. Its docstring should be the warning message. The class can have one more more member functions to inspect nodes. The -function should be decorated with a @lookat call specifying the nodes it +function should be decorated with a @onpush call specifying the nodes it wants to examine. The node names may be in the tok.KIND or (tok.KIND, op.OPCODE) format. To report a warning, the function should return the node causing the warning. @@ -13,7 +13,7 @@ class warning_name: 'questionable JavaScript coding style' - @lookat(tok.NODEKIND, (tok.NODEKIND, op.OPCODE)) + @onpush(tok.NODEKIND, (tok.NODEKIND, op.OPCODE)) def _lint(self, node): if questionable: return node @@ -22,11 +22,14 @@ import sys import types -from visitation import visit as lookat +import visitation from pyspidermonkey import tok, op # TODO: document inspect, node:opcode, etc +def onpush(*args): + return visitation.visit('push', *args) + def _get_branch_in_for(node): " Returns None if this is not one of the branches in a 'for' " if node.parent and node.parent.kind == tok.RESERVED and \ @@ -119,7 +122,7 @@ class comparison_type_conv: 'comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)' - @lookat((tok.EQOP, op.EQ)) + @onpush((tok.EQOP, op.EQ)) def _lint(self, node): lvalue, rvalue = node.kids if not self._allow_coercive_compare(lvalue) or \ @@ -136,7 +139,7 @@ class default_not_at_end: 'the default case is not at the end of the switch statement' - @lookat(tok.DEFAULT) + @onpush(tok.DEFAULT) def _lint(self, node): siblings = node.parent.kids if node.node_index != len(siblings)-1: @@ -144,7 +147,7 @@ class duplicate_case_in_switch: 'duplicate case in switch statement' - @lookat(tok.CASE) + @onpush(tok.CASE) def _lint(self, node): # Only look at previous siblings siblings = node.parent.kids @@ -159,7 +162,7 @@ class missing_default_case: 'missing default case in switch statement' - @lookat(tok.SWITCH) + @onpush(tok.SWITCH) def _lint(self, node): value, cases = node.kids for case in cases.kids: @@ -169,13 +172,13 @@ class with_statement: 'with statement hides undeclared variables; use temporary variable instead' - @lookat(tok.WITH) + @onpush(tok.WITH) def _lint(self, node): return node class useless_comparison: 'useless comparison; comparing identical expressions' - @lookat(tok.EQOP,tok.RELOP) + @onpush(tok.EQOP,tok.RELOP) def _lint(self, node): lvalue, rvalue = node.kids if lvalue.is_equivalent(rvalue): @@ -183,20 +186,20 @@ class use_of_label: 'use of label' - @lookat((tok.COLON, op.NAME)) + @onpush((tok.COLON, op.NAME)) def _lint(self, node): return node class meaningless_block: 'meaningless block; curly braces have no impact' - @lookat(tok.LC) + @onpush(tok.LC) def _lint(self, node): if node.parent and node.parent.kind == tok.LC: return node class misplaced_regex: 'regular expressions should be preceded by a left parenthesis, assignment, colon, or comma' - @lookat((tok.OBJECT, op.REGEXP)) + @onpush((tok.OBJECT, op.REGEXP)) def _lint(self, node): if node.parent.kind == tok.NAME and node.parent.opcode == op.SETNAME: return # Allow in var statements @@ -214,14 +217,14 @@ class assign_to_function_call: 'assignment to a function call' - @lookat(tok.ASSIGN) + @onpush(tok.ASSIGN) def _lint(self, node): if node.kids[0].kind == tok.LP: return node class ambiguous_else_stmt: 'the else statement could be matched with one of multiple if statements (use curly braces to indicate intent' - @lookat(tok.IF) + @onpush(tok.IF) def _lint(self, node): # Only examine this node if it has an else statement. condition, if_, else_ = node.kids @@ -240,7 +243,7 @@ class block_without_braces: 'block statement without curly braces' - @lookat(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) + @onpush(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) def _lint(self, node): if node.kids[1].kind != tok.LC: return node.kids[1] @@ -248,7 +251,7 @@ class ambiguous_nested_stmt: 'block statements containing block statements should use curly braces to resolve ambiguity' _block_nodes = (tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH) - @lookat(*_block_nodes) + @onpush(*_block_nodes) def _lint(self, node): # Ignore "else if" if node.kind == tok.IF and node.node_index == 2 and node.parent.kind == tok.IF: @@ -262,7 +265,7 @@ class inc_dec_within_stmt: 'increment (++) and decrement (--) operators used as part of greater statement' - @lookat(tok.INC, tok.DEC) + @onpush(tok.INC, tok.DEC) def _lint(self, node): if node.parent.kind == tok.SEMI: return None @@ -287,7 +290,7 @@ class comma_separated_stmts: 'multiple statements separated by commas (use semicolons?)' - @lookat(tok.COMMA) + @onpush(tok.COMMA) def _lint(self, node): # Allow within the first and third part of "for(;;)" if _get_branch_in_for(node) in (0, 2): @@ -299,11 +302,11 @@ class empty_statement: 'empty statement or extra semicolon' - @lookat(tok.SEMI) + @onpush(tok.SEMI) def _semi(self, node): if not node.kids[0]: return node - @lookat(tok.LC) + @onpush(tok.LC) def _lc(self, node): if node.kids: return @@ -317,7 +320,7 @@ class missing_break: 'missing break statement' - @lookat(tok.CASE, tok.DEFAULT) + @onpush(tok.CASE, tok.DEFAULT) def _lint(self, node): # The last item is handled separately if node.node_index == len(node.parent.kids)-1: @@ -333,7 +336,7 @@ class missing_break_for_last_case: 'missing break statement for last case in switch' - @lookat(tok.CASE, tok.DEFAULT) + @onpush(tok.CASE, tok.DEFAULT) def _lint(self, node): if node.node_index < len(node.parent.kids)-1: return @@ -344,18 +347,18 @@ class multiple_plus_minus: 'unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs' - @lookat(tok.INC) + @onpush(tok.INC) def _inc(self, node): if node.node_index == 0 and node.parent.kind == tok.PLUS: return node - @lookat(tok.DEC) + @onpush(tok.DEC) def _dec(self, node): if node.node_index == 0 and node.parent.kind == tok.MINUS: return node class useless_assign: 'useless assignment' - @lookat((tok.NAME, op.SETNAME)) + @onpush((tok.NAME, op.SETNAME)) def _lint(self, node): if node.parent.kind == tok.ASSIGN: assert node.node_index == 0 @@ -367,7 +370,7 @@ class unreachable_code: 'unreachable code' - @lookat(tok.BREAK, tok.CONTINUE, tok.RETURN, tok.THROW) + @onpush(tok.BREAK, tok.CONTINUE, tok.RETURN, tok.THROW) def _lint(self, node): if node.parent.kind == tok.LC and \ node.node_index != len(node.parent.kids)-1: @@ -375,44 +378,44 @@ class meaningless_block: 'meaningless block; curly braces have no impact' - #TODO: @lookat(tok.IF) + #TODO: @onpush(tok.IF) def _lint(self, node): condition, if_, else_ = node.kids if condition.kind == tok.PRIMARY and condition.opcode in (op.TRUE, op.FALSE, op.NULL): return condition - #TODO: @lookat(tok.WHILE) + #TODO: @onpush(tok.WHILE) def _lint(self, node): condition = node.kids[0] if condition.kind == tok.PRIMARY and condition.opcode in (op.FALSE, op.NULL): return condition - @lookat(tok.LC) + @onpush(tok.LC) def _lint(self, node): if node.parent and node.parent.kind == tok.LC: return node class useless_void: 'use of the void type may be unnecessary (void is always undefined)' - @lookat((tok.UNARYOP, op.VOID)) + @onpush((tok.UNARYOP, op.VOID)) def _lint(self, node): return node class parseint_missing_radix: 'parseInt missing radix parameter' - @lookat((tok.LP, op.CALL)) + @onpush((tok.LP, op.CALL)) def _lint(self, node): if node.kids[0].kind == tok.NAME and node.kids[0].atom == 'parseInt' and len(node.kids) <= 2: return node class leading_decimal_point: 'leading decimal point may indicate a number or an object member' - @lookat(tok.NUMBER) + @onpush(tok.NUMBER) def _lint(self, node): if node.atom.startswith('.'): return node class trailing_decimal_point: 'trailing decimal point may indicate a number or an object member' - @lookat(tok.NUMBER) + @onpush(tok.NUMBER) def _lint(self, node): if node.parent.kind == tok.DOT: return node @@ -422,21 +425,21 @@ class octal_number: 'leading zeros make an octal number' _regexp = re.compile('^0[0-9]') - @lookat(tok.NUMBER) + @onpush(tok.NUMBER) def _line(self, node): if self._regexp.match(node.atom): return node class trailing_comma_in_array: 'extra comma is not recommended in array initializers' - @lookat(tok.RB) + @onpush(tok.RB) def _line(self, node): if node.end_comma: return node class useless_quotes: 'the quotation marks are unnecessary' - @lookat(tok.STRING) + @onpush(tok.STRING) def _lint(self, node): if node.node_index == 0 and node.parent.kind == tok.COLON: return node This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-25 21:16:22
|
Revision: 192 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=192&view=rev Author: matthiasmiller Date: 2008-04-25 14:16:20 -0700 (Fri, 25 Apr 2008) Log Message: ----------- Slight speedup for linting. Modified Paths: -------------- trunk/pyjsl/lint.py Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-04-23 19:07:41 UTC (rev 191) +++ trunk/pyjsl/lint.py 2008-04-25 21:16:20 UTC (rev 192) @@ -245,17 +245,17 @@ if not node.atom in imports: report(node, 'undeclared_identifier') +def _warn_or_declare(scope, name, node, report): + other = scope.get_identifier(name) + if other and other.kind == tok.FUNCTION and name in other.fn_args: + report(node, 'var_hides_arg') + elif other: + report(node, 'redeclared_var') + else: + scope.add_declaration(name, node) + def _lint_node(node, visitors, report, scope): - def warn_or_declare(name, node): - other = scope.get_identifier(name) - if other and other.kind == tok.FUNCTION and name in other.fn_args: - report(node, 'var_hides_arg') - elif other: - report(node, 'redeclared_var') - else: - scope.add_declaration(name, node) - # Let the visitors warn. for kind in (node.kind, (node.kind, node.opcode)): if kind in visitors: @@ -275,7 +275,7 @@ # Push function identifiers if node.kind == tok.FUNCTION: if node.fn_name: - warn_or_declare(node.fn_name, node) + _warn_or_declare(scope, node.fn_name, node, report) scope = scope.add_scope(node) for var_name in node.fn_args: scope.add_declaration(var_name, node) @@ -285,7 +285,7 @@ scope = scope.add_scope(node) if node.parent and node.parent.kind == tok.VAR: - warn_or_declare(node.atom, node) + _warn_or_declare(scope, node.atom, node, report) for child in node.kids: if child: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-23 19:07:51
|
Revision: 191 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=191&view=rev Author: matthiasmiller Date: 2008-04-23 12:07:41 -0700 (Wed, 23 Apr 2008) Log Message: ----------- useless_quotes: add test for invalid identifiers Modified Paths: -------------- trunk/tests/warnings/useless_quotes.js Modified: trunk/tests/warnings/useless_quotes.js =================================================================== --- trunk/tests/warnings/useless_quotes.js 2008-04-15 14:14:52 UTC (rev 190) +++ trunk/tests/warnings/useless_quotes.js 2008-04-23 19:07:41 UTC (rev 191) @@ -3,6 +3,9 @@ 'key': 1 /*warning:useless_quotes*/ }; o = { + 'key with space': false + }; + o = { key: '1' }; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-15 14:15:08
|
Revision: 190 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=190&view=rev Author: matthiasmiller Date: 2008-04-15 07:14:52 -0700 (Tue, 15 Apr 2008) Log Message: ----------- interface jsparse.is_compilable_unit Modified Paths: -------------- trunk/pyjsl/jsparse.py Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-04-03 20:39:28 UTC (rev 189) +++ trunk/pyjsl/jsparse.py 2008-04-15 14:14:52 UTC (rev 190) @@ -220,6 +220,9 @@ comments = _parse_comments(script, root_node, positions, comment_ignore_ranges) return root_node, comments +def is_compilable_unit(script): + return pyspidermonkey.is_compilable_unit(script) + def _dump_node(node, depth=0): print '. '*depth, if node is None: @@ -325,9 +328,8 @@ ('re = /.*', False), ('{ // missing curly', False) ) - for text, is_compilable_unit in tests: - self.assertEquals(pyspidermonkey.is_compilable_unit(text), - is_compilable_unit) + for text, result in tests: + self.assertEquals(is_compilable_unit(text), result) if __name__ == '__main__': unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-03 20:39:36
|
Revision: 189 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=189&view=rev Author: matthiasmiller Date: 2008-04-03 13:39:28 -0700 (Thu, 03 Apr 2008) Log Message: ----------- Add warning against useless quotes. Modified Paths: -------------- trunk/pyjsl/warnings.py Added Paths: ----------- trunk/tests/warnings/useless_quotes.js Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-02 19:11:36 UTC (rev 188) +++ trunk/pyjsl/warnings.py 2008-04-03 20:39:28 UTC (rev 189) @@ -434,6 +434,13 @@ if node.end_comma: return node +class useless_quotes: + 'the quotation marks are unnecessary' + @lookat(tok.STRING) + def _lint(self, node): + if node.node_index == 0 and node.parent.kind == tok.COLON: + return node + class mismatch_ctrl_comments: 'mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence' pass Added: trunk/tests/warnings/useless_quotes.js =================================================================== --- trunk/tests/warnings/useless_quotes.js (rev 0) +++ trunk/tests/warnings/useless_quotes.js 2008-04-03 20:39:28 UTC (rev 189) @@ -0,0 +1,8 @@ +function useless_quotes() { + var o = { + 'key': 1 /*warning:useless_quotes*/ + }; + o = { + key: '1' + }; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-02 19:11:41
|
Revision: 188 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=188&view=rev Author: matthiasmiller Date: 2008-04-02 12:11:36 -0700 (Wed, 02 Apr 2008) Log Message: ----------- Add more tests for misplaced_regex. Modified Paths: -------------- trunk/tests/warnings/misplaced_regex.js Modified: trunk/tests/warnings/misplaced_regex.js =================================================================== --- trunk/tests/warnings/misplaced_regex.js 2008-04-02 15:14:31 UTC (rev 187) +++ trunk/tests/warnings/misplaced_regex.js 2008-04-02 19:11:36 UTC (rev 188) @@ -14,7 +14,13 @@ /* legal usage: regex as parameter (besides first) */ misplaced_regex(re, /\/\./); + /* legal usage: regex in property */ + var b = /\/\./.test(new String()); + /* illegal usage: anything else */ i += /\/\./; /*warning:misplaced_regex*/ i = -/.*/; /*warning:misplaced_regex*/ + + /* legal usage: return */ + return /\/\./; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |