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