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.
|