Thread: [javascriptlint-commit] SF.net SVN: javascriptlint:[211] trunk/pyjsl
Status: Beta
Brought to you by:
matthiasmiller
|
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 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-09-01 14:04:12
|
Revision: 236
http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=236&view=rev
Author: matthiasmiller
Date: 2008-09-01 14:04:10 +0000 (Mon, 01 Sep 2008)
Log Message:
-----------
allow jsparse to locate possible comments before the script is parsed
Modified Paths:
--------------
trunk/pyjsl/jsparse.py
trunk/pyjsl/lint.py
Modified: trunk/pyjsl/jsparse.py
===================================================================
--- trunk/pyjsl/jsparse.py 2008-09-01 13:56:13 UTC (rev 235)
+++ trunk/pyjsl/jsparse.py 2008-09-01 14:04:10 UTC (rev 236)
@@ -145,7 +145,7 @@
return True
-def _parse_comments(script, node_positions, ignore_ranges):
+def findpossiblecomments(script, node_positions):
pos = 0
single_line_re = r"//[^\r\n]*"
multi_line_re = r"/\*(.*?)\*/"
@@ -169,31 +169,30 @@
opcode = opcode[5:].lower()
start_offset = match.start()
- end_offset = match.end()
+ end_offset = match.end()-1
- # Make sure it doesn't start in a string or regexp
- if not ignore_ranges.has(start_offset):
- start_pos = node_positions.from_offset(start_offset)
- end_pos = node_positions.from_offset(end_offset)
- kwargs = {
- 'type': 'COMMENT',
- 'atom': comment_text,
- 'opcode': opcode,
- '_start_line': start_pos.line,
- '_start_col': start_pos.col,
- '_end_line': end_pos.line,
- '_end_col': end_pos.col,
- 'parent': None,
- 'kids': [],
- 'node_index': None
- }
- comment_node = _Node()
- comment_node.__dict__.update(kwargs)
- comments.append(comment_node)
- pos = match.end()
- else:
- pos = match.start()+1
+ start_pos = node_positions.from_offset(start_offset)
+ end_pos = node_positions.from_offset(end_offset)
+ kwargs = {
+ 'type': 'COMMENT',
+ 'atom': comment_text,
+ 'opcode': opcode,
+ '_start_line': start_pos.line,
+ '_start_col': start_pos.col,
+ '_end_line': end_pos.line,
+ '_end_col': end_pos.col,
+ 'parent': None,
+ 'kids': [],
+ 'node_index': None
+ }
+ comment_node = _Node()
+ comment_node.__dict__.update(kwargs)
+ comments.append(comment_node)
+ # Start searching immediately after the start of the comment in case
+ # this one was within a string or a regexp.
+ pos = match.start()+1
+
def parse(script, error_callback, startpos=None):
""" All node positions will be relative to startpos. This allows scripts
to be embedded in a file (for example, HTML).
@@ -207,28 +206,37 @@
return pyspidermonkey.parse(script, _Node, _wrapped_callback,
startpos.line, startpos.col)
-def parsecomments(script, root_node, startpos=None):
- """ All node positions will be relative to startpos. This allows scripts
- to be embedded in a file (for example, HTML).
- """
- positions = NodePositions(script, startpos)
+def filtercomments(possible_comments, node_positions, root_node):
comment_ignore_ranges = NodeRanges()
def process(node):
if node.kind == tok.NUMBER:
- node.atom = positions.text(node.start_pos(), node.end_pos())
+ node.atom = node_positions.text(node.start_pos(), node.end_pos())
elif node.kind == tok.STRING or \
(node.kind == tok.OBJECT and node.opcode == op.REGEXP):
- start_offset = positions.to_offset(node.start_pos())
- end_offset = positions.to_offset(node.end_pos()) - 1
+ start_offset = node_positions.to_offset(node.start_pos())
+ end_offset = node_positions.to_offset(node.end_pos()) - 1
comment_ignore_ranges.add(start_offset, end_offset)
for kid in node.kids:
if kid:
process(kid)
process(root_node)
- return _parse_comments(script, positions, comment_ignore_ranges)
+ comments = []
+ for comment in possible_comments:
+ start_offset = node_positions.to_offset(comment.start_pos())
+ end_offset = node_positions.to_offset(comment.end_pos())
+ if comment_ignore_ranges.has(start_offset):
+ continue
+ comment_ignore_ranges.add(start_offset, end_offset)
+ comments.append(comment)
+ return comments
+def findcomments(script, root_node, start_pos=None):
+ node_positions = NodePositions(script, start_pos)
+ possible_comments = findpossiblecomments(script, node_positions)
+ return filtercomments(possible_comments, node_positions, root_node)
+
def is_compilable_unit(script):
return pyspidermonkey.is_compilable_unit(script)
@@ -258,7 +266,7 @@
class TestComments(unittest.TestCase):
def _test(self, script, expected_comments):
root = parse(script, lambda line, col, msg: None)
- comments = parsecomments(script, root)
+ comments = findcomments(script, root)
encountered_comments = [node.atom for node in comments]
self.assertEquals(encountered_comments, list(expected_comments))
def testSimpleComments(self):
@@ -386,7 +394,7 @@
def testComments(self):
def testcomment(comment, startpos, expectedpos):
root = parse(comment, None, startpos)
- comment, = parsecomments(comment, root, startpos)
+ comment, = findcomments(comment, root, startpos)
self.assertEquals(comment.start_pos(), expectedpos)
for comment in ('/*comment*/', '//comment'):
testcomment(comment, None, NodePos(0,0))
Modified: trunk/pyjsl/lint.py
===================================================================
--- trunk/pyjsl/lint.py 2008-09-01 13:56:13 UTC (rev 235)
+++ trunk/pyjsl/lint.py 2008-09-01 14:04:10 UTC (rev 236)
@@ -288,6 +288,9 @@
fallthrus = []
passes = []
+ node_positions = jsparse.NodePositions(script, scriptpos)
+ possible_comments = jsparse.findpossiblecomments(script, node_positions)
+
root = jsparse.parse(script, parse_error, scriptpos)
if not root:
# Report errors and quit.
@@ -295,7 +298,7 @@
report_native(pos, msg)
return
- comments = jsparse.parsecomments(script, root, scriptpos)
+ comments = jsparse.filtercomments(possible_comments, node_positions, root)
start_ignore = None
for comment in comments:
cc = _parse_control_comment(comment)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2009-03-04 07:19:21
|
Revision: 242
http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=242&view=rev
Author: matthiasmiller
Date: 2009-03-04 07:19:18 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
expand the named parameters
Modified Paths:
--------------
trunk/pyjsl/lint.py
trunk/pyjsl/warnings.py
Modified: trunk/pyjsl/lint.py
===================================================================
--- trunk/pyjsl/lint.py 2009-03-04 06:52:38 UTC (rev 241)
+++ trunk/pyjsl/lint.py 2009-03-04 07:19:18 UTC (rev 242)
@@ -252,7 +252,7 @@
'redeclared_var', 'var_hides_arg'):
parse_errors.append((jsparse.NodePos(row, col), msg))
- def report(node, errname):
+ def report(node, errname, **errargs):
if errname == 'empty_statement' and node.kind == tok.LC:
for pass_ in passes:
if pass_.start_pos() > node.start_pos() and \
@@ -283,7 +283,7 @@
fallthrus.remove(fallthru)
return
- report_lint(node, errname)
+ report_lint(node, errname, **errargs)
parse_errors = []
declares = []
@@ -373,19 +373,19 @@
for name, node in declares:
declare_scope = script_cache.scope.find_scope(node)
if declare_scope.get_identifier(name):
- report(node, 'redeclared_var')
+ report(node, 'redeclared_var', name=name)
else:
declare_scope.add_declaration(name, node)
def _lint_script_parts(script_parts, script_cache, lint_error, conf, import_callback):
- def report_lint(node, errname):
+ def report_lint(node, errname, **errargs):
# TODO: This is ugly hardcoding to improve the error positioning of
# "missing_semicolon" errors.
if errname == 'missing_semicolon' or errname == 'missing_semicolon_for_lambda':
pos = node.end_pos()
else:
pos = node.start_pos()
- errdesc = warnings.warnings[errname]
+ errdesc = warnings.format_error(errname, **errargs)
_report(pos, errname, errdesc, True)
def report_native(pos, errname):
@@ -419,11 +419,11 @@
if name in _globals:
continue
if not script_cache.hasglobal(name):
- report_lint(node, 'undeclared_identifier')
+ report_lint(node, 'undeclared_identifier', name=name)
for ref_scope, name, node in unreferenced:
# Ignore the outer scope.
if ref_scope != scope:
- report_lint(node, 'unreferenced_identifier')
+ report_lint(node, 'unreferenced_identifier', name=name)
def _getreporter(visitor, report):
def onpush(node):
@@ -431,15 +431,15 @@
ret = visitor(node)
assert ret is None, 'visitor should raise an exception, not return a value'
except warnings.LintWarning, warning:
- report(warning.node, visitor.warning)
+ report(warning.node, visitor.warning, **warning.errargs)
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:
- report(node, 'var_hides_arg')
+ report(node, 'var_hides_arg', name=name)
elif other:
- report(node, 'redeclared_var')
+ report(node, 'redeclared_var', name=name)
else:
scope.add_declaration(name, node)
Modified: trunk/pyjsl/warnings.py
===================================================================
--- trunk/pyjsl/warnings.py 2009-03-04 06:52:38 UTC (rev 241)
+++ trunk/pyjsl/warnings.py 2009-03-04 07:19:18 UTC (rev 242)
@@ -72,13 +72,13 @@
'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}',
- 'unreferenced_identifier': 'identifier is declared but never referenced: {0}',
+ 'redeclared_var': 'redeclaration of {name}',
+ 'undeclared_identifier': 'undeclared identifier: {name}',
+ 'unreferenced_identifier': 'identifier is declared but never referenced: {name}',
'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',
+ 'var_hides_arg': 'variable {name} hides argument',
'duplicate_formal': 'TODO',
'missing_semicolon': 'missing semicolon',
'missing_semicolon_for_lambda': 'missing semicolon for lambda assignment',
@@ -89,10 +89,18 @@
'invalid_fallthru': 'unexpected "fallthru" control comment',
'invalid_pass': 'unexpected "pass" control comment',
'want_assign_or_call': 'expected an assignment or function call',
- 'no_return_value': 'function {0} does not always return a value',
+ 'no_return_value': 'function {name} does not always return a value',
'anon_no_return_value': 'anonymous function does not always return value'
}
+def format_error(errname, **errargs):
+ errdesc = warnings[errname]
+ try:
+ errdesc = re.sub(r"{(\w+)}", lambda match: errargs[match.group(1)], errdesc)
+ except (TypeError, KeyError):
+ raise KeyError, 'Invalid keyword in error: ' + errdesc
+ return errdesc
+
_visitors = []
def lookfor(*args):
def decorate(fn):
@@ -104,8 +112,9 @@
return decorate
class LintWarning(Exception):
- def __init__(self, node):
+ def __init__(self, node, **errargs):
self.node = node
+ self.errargs = errargs
def _get_branch_in_for(node):
" Returns None if this is not one of the branches in a 'for' "
@@ -496,6 +505,8 @@
raise LintWarning, child
def _check_return_value(node):
+ name = node.fn_name or '(anonymous function)'
+
def is_return_with_val(node):
return node and node.kind == tok.RETURN and node.kids[0]
def is_return_without_val(node):
@@ -510,10 +521,10 @@
returns = filter(is_return_without_val, exit_points)
returns.sort(key=lambda node: node.start_pos())
if returns:
- raise LintWarning, returns[0]
+ raise LintWarning(returns[0], name=name)
# Warn if the function sometimes exits naturally.
if None in exit_points:
- raise LintWarning, node
+ raise LintWarning(node, name=name)
@lookfor(tok.FUNCTION)
def no_return_value(node):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|