javascriptlint-commit Mailing List for JavaScript Lint (Page 9)
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-04-02 15:14:34
|
Revision: 187 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=187&view=rev Author: matthiasmiller Date: 2008-04-02 08:14:31 -0700 (Wed, 02 Apr 2008) Log Message: ----------- Fix vim modelines. Modified Paths: -------------- trunk/pyspidermonkey/pyspidermonkey.c Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-04-02 14:25:55 UTC (rev 186) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-04-02 15:14:31 UTC (rev 187) @@ -1,4 +1,5 @@ -/* vim: ts=4 sw=4 expandtab */ +/* vim: ts=4 sw=4 expandtab + */ #include <Python.h> #include <js_operating_system.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-02 14:26:01
|
Revision: 186 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=186&view=rev Author: matthiasmiller Date: 2008-04-02 07:25:55 -0700 (Wed, 02 Apr 2008) Log Message: ----------- Add comments for vim modelines. Modified Paths: -------------- trunk/jsl.py trunk/pyjsl/__init__.py trunk/pyjsl/conf.py trunk/pyjsl/jsparse.py trunk/pyjsl/lint.py trunk/pyjsl/util.py trunk/pyjsl/visitation.py trunk/pyjsl/warnings.py trunk/pyspidermonkey/pyspidermonkey.c trunk/setup.py trunk/test.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/jsl.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,4 +1,5 @@ #!/usr/bin/python +# vim: ts=4 sw=4 expandtab import codecs import glob import os Modified: trunk/pyjsl/__init__.py =================================================================== --- trunk/pyjsl/__init__.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/__init__.py 2008-04-02 14:25:55 UTC (rev 186) @@ -0,0 +1,2 @@ +# vim: ts=4 sw=4 expandtab + Modified: trunk/pyjsl/conf.py =================================================================== --- trunk/pyjsl/conf.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/conf.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,3 +1,4 @@ +# vim: ts=4 sw=4 expandtab import os import warnings Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/jsparse.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,4 +1,5 @@ #!/usr/bin/python +# vim: ts=4 sw=4 expandtab """ Parses a script into nodes. """ import bisect import re Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/lint.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,4 +1,5 @@ #!/usr/bin/python +# vim: ts=4 sw=4 expandtab import os.path import re Modified: trunk/pyjsl/util.py =================================================================== --- trunk/pyjsl/util.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/util.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,3 +1,4 @@ +# vim: ts=4 sw=4 expandtab import codecs import os.path Modified: trunk/pyjsl/visitation.py =================================================================== --- trunk/pyjsl/visitation.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/visitation.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,3 +1,4 @@ +# vim: ts=4 sw=4 expandtab """ This is an abstract module for visiting specific nodes. This is useed to traverse the tree to generate warnings. """ Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyjsl/warnings.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,3 +1,4 @@ +# 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. Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-04-02 14:25:55 UTC (rev 186) @@ -1,4 +1,4 @@ - +/* vim: ts=4 sw=4 expandtab */ #include <Python.h> #include <js_operating_system.h> Modified: trunk/setup.py =================================================================== --- trunk/setup.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/setup.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,4 +1,5 @@ #!/usr/bin/python +# vim: ts=4 sw=4 expandtab from distutils.core import setup, Extension import os Modified: trunk/test.py =================================================================== --- trunk/test.py 2008-04-01 01:54:10 UTC (rev 185) +++ trunk/test.py 2008-04-02 14:25:55 UTC (rev 186) @@ -1,3 +1,4 @@ +# vim: ts=4 sw=4 expandtab import re import pyjsl.conf This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-04-01 01:54:12
|
Revision: 185 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=185&view=rev Author: matthiasmiller Date: 2008-03-31 18:54:10 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Stop using unittest.main to run unit tests and respect --quiet and --verbose. Modified Paths: -------------- trunk/jsl.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-31 23:47:13 UTC (rev 184) +++ trunk/jsl.py 2008-04-01 01:54:10 UTC (rev 185) @@ -108,6 +108,11 @@ help="dump this script") add("--unittest", dest="unittest", action="store_true", default=False, help="run the python unittests") + add("--quiet", dest="verbosity", action="store_const", const=0, + help="minimal output") + add("--verbose", dest="verbosity", action="store_const", const=2, + help="verbose output") + parser.set_defaults(verbosity=1) options, args = parser.parse_args() if len(sys.argv) == 1: @@ -123,7 +128,8 @@ profile_func = profile_enabled if options.unittest: - unittest.main(pyjsl.jsparse, argv=[sys.argv[0]]) + runner = unittest.TextTestRunner(verbosity=options.verbosity) + runner.run(unittest.findTestCases(pyjsl.jsparse)) if options.test: profile_func(run_tests) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 23:47:16
|
Revision: 184 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=184&view=rev Author: matthiasmiller Date: 2008-03-31 16:47:13 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Clarify call to unittest.main. Suggested by: Jeff Balogh <its.jeff.balogh at gmail.com> Modified Paths: -------------- trunk/jsl.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-31 21:56:57 UTC (rev 183) +++ trunk/jsl.py 2008-03-31 23:47:13 UTC (rev 184) @@ -123,7 +123,7 @@ profile_func = profile_enabled if options.unittest: - unittest.main(pyjsl.jsparse, argv=sys.argv[:1]) + unittest.main(pyjsl.jsparse, argv=[sys.argv[0]]) if options.test: profile_func(run_tests) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 21:56:59
|
Revision: 183 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=183&view=rev Author: matthiasmiller Date: 2008-03-31 14:56:57 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Fix incorrect line number in error messages. Modified Paths: -------------- trunk/jsl.py trunk/pyjsl/jsparse.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-31 21:50:09 UTC (rev 182) +++ trunk/jsl.py 2008-03-31 21:56:57 UTC (rev 183) @@ -56,7 +56,7 @@ def _lint(paths, conf): def lint_error(path, line, col, errname): _lint_results['warnings'] = _lint_results['warnings'] + 1 - print '%s(%i): %s' % (path, line, errname) + print '%s(%i): %s' % (path, line+1, errname) pyjsl.lint.lint_files(paths, lint_error, conf=conf) def _resolve_paths(path, recurse): Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-03-31 21:50:09 UTC (rev 182) +++ trunk/pyjsl/jsparse.py 2008-03-31 21:56:57 UTC (rev 183) @@ -13,6 +13,7 @@ )) class NodePos: + " Represents zero-based line and column number. " def __init__(self, line, col): self.line = line self.col = col This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 21:50:11
|
Revision: 182 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=182&view=rev Author: matthiasmiller Date: 2008-03-31 14:50:09 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Target Python 2.4. Modified Paths: -------------- trunk/DEVELOPMENT Modified: trunk/DEVELOPMENT =================================================================== --- trunk/DEVELOPMENT 2008-03-31 21:46:09 UTC (rev 181) +++ trunk/DEVELOPMENT 2008-03-31 21:50:09 UTC (rev 182) @@ -2,6 +2,7 @@ > All lines should be 79 characters or less > Follow http://www.python.org/dev/peps/pep-0008/ as much as possible. +> Target Python 2.4. ** TODO This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 21:46:14
|
Revision: 181 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=181&view=rev Author: matthiasmiller Date: 2008-03-31 14:46:09 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Fix ConfError's call to Exception.__init__. Patch by: Jeff Balogh <its.jeff.balogh at gmail.com> Modified Paths: -------------- trunk/pyjsl/conf.py Modified: trunk/pyjsl/conf.py =================================================================== --- trunk/pyjsl/conf.py 2008-03-31 21:39:34 UTC (rev 180) +++ trunk/pyjsl/conf.py 2008-03-31 21:46:09 UTC (rev 181) @@ -4,7 +4,7 @@ class ConfError(Exception): def __init__(self, error): - Exception.__init__(error) + Exception.__init__(self, error) self.lineno = None self.path = None This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 21:39:39
|
Revision: 180 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=180&view=rev Author: matthiasmiller Date: 2008-03-31 14:39:34 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Replace getopt with optparse. Patch by: Jeff Balogh <its.jeff.balogh at gmail.com> Modified Paths: -------------- trunk/jsl.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-31 14:01:17 UTC (rev 179) +++ trunk/jsl.py 2008-03-31 21:39:34 UTC (rev 180) @@ -1,10 +1,10 @@ #!/usr/bin/python import codecs -import getopt import glob import os import sys import unittest +from optparse import OptionParser try: import setup @@ -95,46 +95,45 @@ def profile_disabled(func, *args, **kwargs): func(*args, **kwargs) -def usage(): - print """ -Usage: - jsl [files] - --help (-h) print this help - --test (-t) run tests - --dump= dump this script -""" - if __name__ == '__main__': - try: - opts, args = getopt.getopt(sys.argv[1:], 'ht:v', ['conf=', 'help', 'test', 'dump', 'unittest', 'profile']) - except getopt.GetoptError: - usage() - sys.exit(2) + parser = OptionParser(usage="%prog [options] [files]") + add = parser.add_option + add("--conf", dest="conf", metavar="CONF", + help="set the conf file") + add("-t", "--test", dest="test", action="store_true", default=False, + help="run the javascript tests") + add("--profile", dest="profile", action="store_true", default=False, + help="turn on hotshot profiling") + add("--dump", dest="dump", action="store_true", default=False, + help="dump this script") + add("--unittest", dest="unittest", action="store_true", default=False, + help="run the python unittests") + options, args = parser.parse_args() - dump = False + if len(sys.argv) == 1: + parser.print_help() + sys.exit() + conf = pyjsl.conf.Conf() + if options.conf: + conf.loadfile(options.conf) + profile_func = profile_disabled - for opt, val in opts: - if opt in ('-h', '--help'): - usage() - sys.exit() - if opt in ('--dump',): - dump = True - if opt in ('-t', '--test'): - profile_func(run_tests) - if opt in ('--unittest',): - unittest.main(pyjsl.jsparse, argv=sys.argv[:1]) - if opt in ('--profile',): - profile_func = profile_enabled - if opt in ('--conf',): - conf.loadfile(val) + if options.profile: + profile_func = profile_enabled + if options.unittest: + unittest.main(pyjsl.jsparse, argv=sys.argv[:1]) + + if options.test: + profile_func(run_tests) + paths = [] for recurse, path in conf['paths']: paths.extend(_resolve_paths(path, recurse)) for arg in args: paths.extend(_resolve_paths(arg, False)) - if dump: + if options.dump: profile_func(_dump, paths) else: profile_func(_lint, paths, conf) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 14:01:25
|
Revision: 179 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=179&view=rev Author: matthiasmiller Date: 2008-03-31 07:01:17 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Use consistent indentation in tests. Modified Paths: -------------- trunk/tests/conf/define.js trunk/tests/conf/legacy_control_comments.js trunk/tests/control_comments/invalid_fallthru.js trunk/tests/html/script_tag_in_js_literal.html trunk/tests/path_resolution/is_a_dir.js trunk/tests/path_resolution/is_a_dir_not_file.js trunk/tests/path_resolution/is_a_file.js trunk/tests/path_resolution/process/error-2.ecmascript trunk/tests/path_resolution/process/error.ecmascript trunk/tests/path_resolution/process/included.ecmascript trunk/tests/run_tests.pl trunk/tests/warnings/default_not_at_end.js trunk/tests/warnings/legacy_cc_not_understood.js trunk/tests/warnings/missing_semicolon.js Modified: trunk/tests/conf/define.js =================================================================== --- trunk/tests/conf/define.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/conf/define.js 2008-03-31 14:01:17 UTC (rev 179) @@ -1,8 +1,8 @@ /*conf:+define window*/ /*jsl:option explicit*/ function define() { - window.alert('http://www.javascriptlint.com/'); + window.alert('http://www.javascriptlint.com/'); - /* cannot use document, however */ - document.write('<a href="http://www.javascriptlint.com/">JavaScript Lint</a>'); /*warning:undeclared_identifier*/ + /* cannot use document, however */ + document.write('<a href="http://www.javascriptlint.com/">JavaScript Lint</a>'); /*warning:undeclared_identifier*/ } Modified: trunk/tests/conf/legacy_control_comments.js =================================================================== --- trunk/tests/conf/legacy_control_comments.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/conf/legacy_control_comments.js 2008-03-31 14:01:17 UTC (rev 179) @@ -2,7 +2,7 @@ /* Make sure that legacy control comments aren't respected */ function legacy_control_comments() { - /*@ignore@*/ - ; /*warning:empty_statement*/ - /*@end@*/ + /*@ignore@*/ + ; /*warning:empty_statement*/ + /*@end@*/ } Modified: trunk/tests/control_comments/invalid_fallthru.js =================================================================== --- trunk/tests/control_comments/invalid_fallthru.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/control_comments/invalid_fallthru.js 2008-03-31 14:01:17 UTC (rev 179) @@ -2,12 +2,12 @@ function invalid_fallthru() { /* mistake - invalid use of fallthru */ /*jsl:fallthru*/ /*warning:invalid_fallthru*/ - var i; + var i; switch (i) { /*jsl:fallthru*/ /*warning:invalid_fallthru*/ case /*jsl:fallthru*/1: /*warning:invalid_fallthru*/ break; default /*jsl:fallthru*/: /*warning:invalid_fallthru*/ - break; + break; } } Modified: trunk/tests/html/script_tag_in_js_literal.html =================================================================== --- trunk/tests/html/script_tag_in_js_literal.html 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/html/script_tag_in_js_literal.html 2008-03-31 14:01:17 UTC (rev 179) @@ -1,13 +1,13 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <html> <head> - <title>JavaScript Lint Test Page</title> - <script type="text/javascript"><!-- - /* alert the </script> end tag */ - var x = "</script>"; - window.alert(x); - //--> - </script> + <title>JavaScript Lint Test Page</title> + <script type="text/javascript"><!-- + /* alert the </script> end tag */ + var x = "</script>"; + window.alert(x); + //--> + </script> </head> <body> </body> Modified: trunk/tests/path_resolution/is_a_dir.js =================================================================== --- trunk/tests/path_resolution/is_a_dir.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/path_resolution/is_a_dir.js 2008-03-31 14:01:17 UTC (rev 179) @@ -1,4 +1,4 @@ /*conf:+process dir/ */ function zero() { - return 0; + return 0; } Modified: trunk/tests/path_resolution/is_a_dir_not_file.js =================================================================== --- trunk/tests/path_resolution/is_a_dir_not_file.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/path_resolution/is_a_dir_not_file.js 2008-03-31 14:01:17 UTC (rev 179) @@ -1,4 +1,4 @@ /*conf:+process dir*/ function zero() { - return 0; + return 0; } Modified: trunk/tests/path_resolution/is_a_file.js =================================================================== --- trunk/tests/path_resolution/is_a_file.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/path_resolution/is_a_file.js 2008-03-31 14:01:17 UTC (rev 179) @@ -1,4 +1,4 @@ /*conf:+process file*/ function zero() { - return 0; + return 0; } Modified: trunk/tests/path_resolution/process/error-2.ecmascript =================================================================== --- trunk/tests/path_resolution/process/error-2.ecmascript 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/path_resolution/process/error-2.ecmascript 2008-03-31 14:01:17 UTC (rev 179) @@ -1,3 +1,3 @@ function process() { - error! + error! } Modified: trunk/tests/path_resolution/process/error.ecmascript =================================================================== --- trunk/tests/path_resolution/process/error.ecmascript 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/path_resolution/process/error.ecmascript 2008-03-31 14:01:17 UTC (rev 179) @@ -1,3 +1,3 @@ function process() { - error! + error! } Modified: trunk/tests/path_resolution/process/included.ecmascript =================================================================== --- trunk/tests/path_resolution/process/included.ecmascript 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/path_resolution/process/included.ecmascript 2008-03-31 14:01:17 UTC (rev 179) @@ -1,3 +1,3 @@ function zero() { - return 0; + return 0; } Modified: trunk/tests/run_tests.pl =================================================================== --- trunk/tests/run_tests.pl 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/run_tests.pl 2008-03-31 14:01:17 UTC (rev 179) @@ -8,7 +8,7 @@ # require a path to jsl # if (scalar(@ARGV) != 1) { - die("Usage: run_tests.pl <path to jsl>\n"); + die("Usage: run_tests.pl <path to jsl>\n"); } my $jsl_path = File::Spec->rel2abs($ARGV[0]); my $tests_path = $FindBin::Bin; @@ -16,84 +16,84 @@ my $num_tests = 0; my $num_passed = 0; sub TestFile { - /\.(js|htm|html)$/ or return; - my $filename = $_; - my $pretty_name = $File::Find::name; + /\.(js|htm|html)$/ or return; + my $filename = $_; + my $pretty_name = $File::Find::name; - my $conf_file = ".jsl.conf"; + my $conf_file = ".jsl.conf"; - # open the path being validated - open(FILE, $filename) or die("Could not open $filename: $!"); - my @contents = <FILE>; + # open the path being validated + open(FILE, $filename) or die("Could not open $filename: $!"); + my @contents = <FILE>; - # look for special configuration directives - my @conf = grep(s/\/\*conf:(([^*]|(\*[^\/]))*)\*\//\1\n/g, @contents); - open(FILE, ">$conf_file") or die("Could not open configuration file $conf_file: $!"); - print FILE join("",@conf); - close FILE; + # look for special configuration directives + my @conf = grep(s/\/\*conf:(([^*]|(\*[^\/]))*)\*\//\1\n/g, @contents); + open(FILE, ">$conf_file") or die("Could not open configuration file $conf_file: $!"); + print FILE join("",@conf); + close FILE; - my $this_passed = 1; + my $this_passed = 1; - # look for expected configuration error - my @all_conf_errors = grep(s/\/\*conf_error:(([^*]|(\*[^\/]))*)\*\//\1/g, @contents); - my $conf_error; - if (scalar(@all_conf_errors) > 1) { - print "Only one conf_error allowed per script."; - $this_passed = 0; - } - elsif (scalar(@all_conf_errors) == 1) { - $conf_error = $all_conf_errors[0]; - unless ($conf_error) { - print "Missing conf_error text."; - $this_passed = 0; - } - } + # look for expected configuration error + my @all_conf_errors = grep(s/\/\*conf_error:(([^*]|(\*[^\/]))*)\*\//\1/g, @contents); + my $conf_error; + if (scalar(@all_conf_errors) > 1) { + print "Only one conf_error allowed per script."; + $this_passed = 0; + } + elsif (scalar(@all_conf_errors) == 1) { + $conf_error = $all_conf_errors[0]; + unless ($conf_error) { + print "Missing conf_error text."; + $this_passed = 0; + } + } - # run the lint - print "Testing $pretty_name...\n"; - my $results = `$jsl_path --conf $conf_file --process $filename --nologo --nofilelisting --nocontext --nosummary -output-format __LINE__,__ERROR_NAME__`; - my $exit_code = $? >> 8; - unlink $conf_file; - die "Error executing $jsl_path" unless defined $results; + # run the lint + print "Testing $pretty_name...\n"; + my $results = `$jsl_path --conf $conf_file --process $filename --nologo --nofilelisting --nocontext --nosummary -output-format __LINE__,__ERROR_NAME__`; + my $exit_code = $? >> 8; + unlink $conf_file; + die "Error executing $jsl_path" unless defined $results; - if ($conf_error) { - unless ($exit_code == 2) { - print "Expected exit code: $exit_code\n"; - $this_passed = 0; - } - unless (index($results, "configuration error: $conf_error") > 0) { - print "Expected configuration error: $conf_error"; - print "Got configuration error: $results"; - $this_passed = 0; - } - } - elsif ($exit_code == 2) { - print "Usage or configuration error:\n$results"; - $this_passed = 0; - } + if ($conf_error) { + unless ($exit_code == 2) { + print "Expected exit code: $exit_code\n"; + $this_passed = 0; + } + unless (index($results, "configuration error: $conf_error") > 0) { + print "Expected configuration error: $conf_error"; + print "Got configuration error: $results"; + $this_passed = 0; + } + } + elsif ($exit_code == 2) { + print "Usage or configuration error:\n$results"; + $this_passed = 0; + } - foreach my $result (split("\n", $results)) { - my ($line, $error) = split(",", $result); - next unless $error; # for now, skip blank errors (such as inability to open file) + foreach my $result (split("\n", $results)) { + my ($line, $error) = split(",", $result); + next unless $error; # for now, skip blank errors (such as inability to open file) - # some warnings point beyond the end of the file - $line = scalar(@contents) if $line > scalar(@contents); + # some warnings point beyond the end of the file + $line = scalar(@contents) if $line > scalar(@contents); - unless ($contents[$line-1] =~ s/\/\*warning:$error\*\///) { - print "Error in $filename, line $line: $error\n"; - $this_passed = 0; - } - } - for (my $i = 1; $i <= scalar(@contents); $i++) { - if ($contents[$i-1] =~ /\/\*warning:([^*]*)\*\//) { - print "Error in $filename, line $i: no $1 warning\n"; - $this_passed = 0; - } - } - close(FILE); + unless ($contents[$line-1] =~ s/\/\*warning:$error\*\///) { + print "Error in $filename, line $line: $error\n"; + $this_passed = 0; + } + } + for (my $i = 1; $i <= scalar(@contents); $i++) { + if ($contents[$i-1] =~ /\/\*warning:([^*]*)\*\//) { + print "Error in $filename, line $i: no $1 warning\n"; + $this_passed = 0; + } + } + close(FILE); - $num_tests++; - $num_passed++ if $this_passed; + $num_tests++; + $num_passed++ if $this_passed; } # locate all files in the test folder Modified: trunk/tests/warnings/default_not_at_end.js =================================================================== --- trunk/tests/warnings/default_not_at_end.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/warnings/default_not_at_end.js 2008-03-31 14:01:17 UTC (rev 179) @@ -4,9 +4,9 @@ /*default case at top*/ switch (i) { - default: - i++; - break; + default: + i++; + break; case 1: /*warning:default_not_at_end*/ return 1; } Modified: trunk/tests/warnings/legacy_cc_not_understood.js =================================================================== --- trunk/tests/warnings/legacy_cc_not_understood.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/warnings/legacy_cc_not_understood.js 2008-03-31 14:01:17 UTC (rev 179) @@ -5,5 +5,5 @@ /* illegal - unrecognized */ /*@bogon@*/ /*warning:legacy_cc_not_understood*/ - return; + return; } Modified: trunk/tests/warnings/missing_semicolon.js =================================================================== --- trunk/tests/warnings/missing_semicolon.js 2008-03-31 13:45:14 UTC (rev 178) +++ trunk/tests/warnings/missing_semicolon.js 2008-03-31 14:01:17 UTC (rev 179) @@ -8,12 +8,12 @@ /* missing semicolon after return */ /* missing semicolon after lambda */ function x() { - this.y = function() { return 0 } /*warning:missing_semicolon*/ + this.y = function() { return 0 } /*warning:missing_semicolon*/ } /*warning:missing_semicolon*/ /* missing semicolon after return */ /* missing semicolon after lambda */ x.prototype.z = function() { - return 1 + return 1 } /*warning:missing_semicolon*/ } /*warning:missing_semicolon*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-31 13:45:22
|
Revision: 178 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=178&view=rev Author: matthiasmiller Date: 2008-03-31 06:45:14 -0700 (Mon, 31 Mar 2008) Log Message: ----------- Use spaces instead of tabs. Modified Paths: -------------- trunk/DEVELOPMENT trunk/jsl.py trunk/pyjsl/conf.py trunk/pyjsl/jsparse.py trunk/pyjsl/lint.py trunk/pyjsl/util.py trunk/pyjsl/visitation.py trunk/pyjsl/warnings.py trunk/pyspidermonkey/pyspidermonkey.c trunk/setup.py trunk/test.py Modified: trunk/DEVELOPMENT =================================================================== --- trunk/DEVELOPMENT 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/DEVELOPMENT 2008-03-31 13:45:14 UTC (rev 178) @@ -1,9 +1,7 @@ ** STYLE GUIDELINES -> Use tabs instead of spaces (for now) > All lines should be 79 characters or less -> For everything else, follow http://www.python.org/dev/peps/pep-0008/ as much - as possible. +> Follow http://www.python.org/dev/peps/pep-0008/ as much as possible. ** TODO @@ -23,9 +21,9 @@ SpiderMonkey. Use a relative path for pretty commit messages. svn_load_dirs.pl \ - -t X.X.X \ - -p svn_load_dirs.conf \ - https://javascriptlint.svn.sourceforge.net/svnroot/javascriptlint/vendorsrc/Mozilla.org/js \ - current \ - js-X.X.X + -t X.X.X \ + -p svn_load_dirs.conf \ + https://javascriptlint.svn.sourceforge.net/svnroot/javascriptlint/vendorsrc/Mozilla.org/js \ + current \ + js-X.X.X Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/jsl.py 2008-03-31 13:45:14 UTC (rev 178) @@ -7,11 +7,11 @@ import unittest try: - import setup + import setup except ImportError: - pass + pass else: - sys.path.append(setup.get_lib_path()) + sys.path.append(setup.get_lib_path()) import pyjsl.conf import pyjsl.jsparse @@ -19,84 +19,84 @@ import test _lint_results = { - 'warnings': 0, - 'errors': 0 + 'warnings': 0, + 'errors': 0 } def get_test_files(): - # Get a list of test files. - dir_ = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tests') + # Get a list of test files. + dir_ = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tests') - all_files = [] - for root, dirs, files in os.walk(dir_): - all_files += [os.path.join(dir_, root, file) for file in files] - if '.svn' in dirs: - dirs.remove('.svn') - # TODO - if 'conf' in dirs: - dirs.remove('conf') - all_files.sort() - return all_files + all_files = [] + for root, dirs, files in os.walk(dir_): + all_files += [os.path.join(dir_, root, file) for file in files] + if '.svn' in dirs: + dirs.remove('.svn') + # TODO + if 'conf' in dirs: + dirs.remove('conf') + all_files.sort() + return all_files def run_tests(): - for file in get_test_files(): - if file.endswith('.htm') or file.endswith('.html'): - continue #TODO - elif file.endswith('.js'): - try: - test.run(file) - except test.TestError, error: - print error + for file in get_test_files(): + if file.endswith('.htm') or file.endswith('.html'): + continue #TODO + elif file.endswith('.js'): + try: + test.run(file) + except test.TestError, error: + print error def _dump(paths): - for path in paths: - script = pyjsl.util.readfile(path) - pyjsl.jsparse.dump_tree(script) + for path in paths: + script = pyjsl.util.readfile(path) + pyjsl.jsparse.dump_tree(script) def _lint(paths, conf): - def lint_error(path, line, col, errname): - _lint_results['warnings'] = _lint_results['warnings'] + 1 - print '%s(%i): %s' % (path, line, errname) - pyjsl.lint.lint_files(paths, lint_error, conf=conf) + def lint_error(path, line, col, errname): + _lint_results['warnings'] = _lint_results['warnings'] + 1 + print '%s(%i): %s' % (path, line, errname) + pyjsl.lint.lint_files(paths, lint_error, conf=conf) def _resolve_paths(path, recurse): - if os.path.isfile(path): - return [path] - elif os.path.isdir(path): - dir = path - pattern = '*' - else: - dir, pattern = os.path.split(path) + if os.path.isfile(path): + return [path] + elif os.path.isdir(path): + dir = path + pattern = '*' + else: + dir, pattern = os.path.split(path) - # Build a list of directories - dirs = [dir] - if recurse: - for cur_root, cur_dirs, cur_files in os.walk(dir): - for name in cur_dirs: - dirs.append(os.path.join(cur_root, name)) + # Build a list of directories + dirs = [dir] + if recurse: + for cur_root, cur_dirs, cur_files in os.walk(dir): + for name in cur_dirs: + dirs.append(os.path.join(cur_root, name)) - # Glob all files. - paths = [] - for dir in dirs: - paths.extend(glob.glob(os.path.join(dir, pattern))) - return paths + # Glob all files. + paths = [] + for dir in dirs: + paths.extend(glob.glob(os.path.join(dir, pattern))) + return paths def profile_enabled(func, *args, **kwargs): - import tempfile - import hotshot - import hotshot.stats - handle, filename = tempfile.mkstemp() - profile = hotshot.Profile(filename) - profile.runcall(func, *args, **kwargs) - profile.close() - stats = hotshot.stats.load(filename) - stats = stats.sort_stats("time") - stats.print_stats() + import tempfile + import hotshot + import hotshot.stats + handle, filename = tempfile.mkstemp() + profile = hotshot.Profile(filename) + profile.runcall(func, *args, **kwargs) + profile.close() + stats = hotshot.stats.load(filename) + stats = stats.sort_stats("time") + stats.print_stats() def profile_disabled(func, *args, **kwargs): - func(*args, **kwargs) + func(*args, **kwargs) def usage(): - print """ + print """ Usage: jsl [files] --help (-h) print this help @@ -105,42 +105,42 @@ """ if __name__ == '__main__': - try: - opts, args = getopt.getopt(sys.argv[1:], 'ht:v', ['conf=', 'help', 'test', 'dump', 'unittest', 'profile']) - except getopt.GetoptError: - usage() - sys.exit(2) + try: + opts, args = getopt.getopt(sys.argv[1:], 'ht:v', ['conf=', 'help', 'test', 'dump', 'unittest', 'profile']) + except getopt.GetoptError: + usage() + sys.exit(2) - dump = False - conf = pyjsl.conf.Conf() - profile_func = profile_disabled - for opt, val in opts: - if opt in ('-h', '--help'): - usage() - sys.exit() - if opt in ('--dump',): - dump = True - if opt in ('-t', '--test'): - profile_func(run_tests) - if opt in ('--unittest',): - unittest.main(pyjsl.jsparse, argv=sys.argv[:1]) - if opt in ('--profile',): - profile_func = profile_enabled - if opt in ('--conf',): - conf.loadfile(val) + dump = False + conf = pyjsl.conf.Conf() + profile_func = profile_disabled + for opt, val in opts: + if opt in ('-h', '--help'): + usage() + sys.exit() + if opt in ('--dump',): + dump = True + if opt in ('-t', '--test'): + profile_func(run_tests) + if opt in ('--unittest',): + unittest.main(pyjsl.jsparse, argv=sys.argv[:1]) + if opt in ('--profile',): + profile_func = profile_enabled + if opt in ('--conf',): + conf.loadfile(val) - paths = [] - for recurse, path in conf['paths']: - paths.extend(_resolve_paths(path, recurse)) - for arg in args: - paths.extend(_resolve_paths(arg, False)) - if dump: - profile_func(_dump, paths) - else: - profile_func(_lint, paths, conf) + paths = [] + for recurse, path in conf['paths']: + paths.extend(_resolve_paths(path, recurse)) + for arg in args: + paths.extend(_resolve_paths(arg, False)) + if dump: + profile_func(_dump, paths) + else: + profile_func(_lint, paths, conf) - if _lint_results['errors']: - sys.exit(3) - if _lint_results['warnings']: - sys.exit(1) + if _lint_results['errors']: + sys.exit(3) + if _lint_results['warnings']: + sys.exit(1) Modified: trunk/pyjsl/conf.py =================================================================== --- trunk/pyjsl/conf.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/pyjsl/conf.py 2008-03-31 13:45:14 UTC (rev 178) @@ -3,133 +3,133 @@ import warnings class ConfError(Exception): - def __init__(self, error): - Exception.__init__(error) - self.lineno = None - self.path = None + def __init__(self, error): + Exception.__init__(error) + self.lineno = None + self.path = None class Setting: - wants_parm = False - wants_dir = False + wants_parm = False + wants_dir = False class BooleanSetting(Setting): - wants_parm = False - def __init__(self, default): - self.value = default - def load(self, enabled): - self.value = enabled + wants_parm = False + def __init__(self, default): + self.value = default + def load(self, enabled): + self.value = enabled class StringSetting(Setting): - wants_parm = True - def __init__(self, default): - self.value = default - def load(self, enabled, parm): - if not enabled: - raise ConfError, 'Expected +.' - self.value = parm + wants_parm = True + def __init__(self, default): + self.value = default + def load(self, enabled, parm): + if not enabled: + raise ConfError, 'Expected +.' + self.value = parm class DeclareSetting(Setting): - wants_parm = True - def __init__(self): - self.value = [] - def load(self, enabled, parm): - if not enabled: - raise ConfError, 'Expected +.' - self.value.append(parm) + wants_parm = True + def __init__(self): + self.value = [] + def load(self, enabled, parm): + if not enabled: + raise ConfError, 'Expected +.' + self.value.append(parm) class ProcessSetting(Setting): - wants_parm = True - wants_dir = True - def __init__(self, recurse_setting): - self.value = [] - self._recurse = recurse_setting - def load(self, enabled, parm, dir): - if dir: - parm = os.path.join(dir, parm) - self.value.append((self._recurse.value, parm)) + wants_parm = True + wants_dir = True + def __init__(self, recurse_setting): + self.value = [] + self._recurse = recurse_setting + def load(self, enabled, parm, dir): + if dir: + parm = os.path.join(dir, parm) + self.value.append((self._recurse.value, parm)) class Conf: - def __init__(self): - recurse = BooleanSetting(False) - self._settings = { - 'recurse': recurse, - 'show_context': BooleanSetting(False), - 'output-format': StringSetting('TODO'), - 'lambda_assign_requires_semicolon': BooleanSetting(False), - 'legacy_control_comments': BooleanSetting(True), - 'jscript_function_extensions': BooleanSetting(False), - 'always_use_option_explicit': BooleanSetting(False), - 'define': DeclareSetting(), - 'context': BooleanSetting(False), - 'process': ProcessSetting(recurse), - # SpiderMonkey warnings - 'no_return_value': BooleanSetting(True), - 'equal_as_assign': BooleanSetting(True), - 'anon_no_return_value': BooleanSetting(True) - } - for klass in warnings.klasses: - self._settings[klass.__name__] = BooleanSetting(True) - self.loadline('-block_without_braces') + def __init__(self): + recurse = BooleanSetting(False) + self._settings = { + 'recurse': recurse, + 'show_context': BooleanSetting(False), + 'output-format': StringSetting('TODO'), + 'lambda_assign_requires_semicolon': BooleanSetting(False), + 'legacy_control_comments': BooleanSetting(True), + 'jscript_function_extensions': BooleanSetting(False), + 'always_use_option_explicit': BooleanSetting(False), + 'define': DeclareSetting(), + 'context': BooleanSetting(False), + 'process': ProcessSetting(recurse), + # SpiderMonkey warnings + 'no_return_value': BooleanSetting(True), + 'equal_as_assign': BooleanSetting(True), + 'anon_no_return_value': BooleanSetting(True) + } + for klass in warnings.klasses: + self._settings[klass.__name__] = BooleanSetting(True) + self.loadline('-block_without_braces') - def loadfile(self, path): - path = os.path.abspath(path) - conf = open(path, 'r').read() - try: - self.loadtext(conf, dir=os.path.dirname(path)) - except ConfError, error: - error.path = path - raise + def loadfile(self, path): + path = os.path.abspath(path) + conf = open(path, 'r').read() + try: + self.loadtext(conf, dir=os.path.dirname(path)) + except ConfError, error: + error.path = path + raise - def loadtext(self, conf, dir=None): - lines = conf.splitlines() - for lineno in range(0, len(lines)): - try: - self.loadline(lines[lineno], dir) - except ConfError, error: - error.lineno = lineno - raise + def loadtext(self, conf, dir=None): + lines = conf.splitlines() + for lineno in range(0, len(lines)): + try: + self.loadline(lines[lineno], dir) + except ConfError, error: + error.lineno = lineno + raise - def loadline(self, line, dir=None): - assert not '\r' in line - assert not '\n' in line + def loadline(self, line, dir=None): + assert not '\r' in line + assert not '\n' in line - # Allow comments - if '#' in line: - line = line[:line.find('#')] - line = line.rstrip() - if not line: - return + # Allow comments + if '#' in line: + line = line[:line.find('#')] + line = line.rstrip() + if not line: + return - # Parse the +/- - if line.startswith('+'): - enabled = True - elif line.startswith('-'): - enabled = False - else: - raise ConfError, 'Expected + or -.' - line = line[1:] + # Parse the +/- + if line.startswith('+'): + enabled = True + elif line.startswith('-'): + enabled = False + else: + raise ConfError, 'Expected + or -.' + line = line[1:] - # Parse the key/parms - name = line.split()[0].lower() - parm = line[len(name):].lstrip() + # Parse the key/parms + name = line.split()[0].lower() + parm = line[len(name):].lstrip() - # Load the setting - setting = self._settings[name] - args = { - 'enabled': enabled - } - if setting.wants_parm: - args['parm'] = parm - elif parm: - raise ConfError, 'The %s setting does not expect a parameter.' % name - if setting.wants_dir: - args['dir'] = dir - setting.load(**args) + # Load the setting + setting = self._settings[name] + args = { + 'enabled': enabled + } + if setting.wants_parm: + args['parm'] = parm + elif parm: + raise ConfError, 'The %s setting does not expect a parameter.' % name + if setting.wants_dir: + args['dir'] = dir + setting.load(**args) - def __getitem__(self, name): - if name == 'paths': - name = 'process' - elif name == 'declarations': - name = 'define' - return self._settings[name].value + def __getitem__(self, name): + if name == 'paths': + name = 'process' + elif name == 'declarations': + name = 'define' + return self._settings[name].value Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/pyjsl/jsparse.py 2008-03-31 13:45:14 UTC (rev 178) @@ -8,325 +8,325 @@ from pyspidermonkey import tok, op _tok_names = dict(zip( - [getattr(tok, prop) for prop in dir(tok)], - ['tok.%s' % prop for prop in dir(tok)] + [getattr(tok, prop) for prop in dir(tok)], + ['tok.%s' % prop for prop in dir(tok)] )) class NodePos: - 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) + 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) class NodePositions: - " Given a string, allows [x] lookups for NodePos line and column numbers." - def __init__(self, text): - # Find the length of each line and incrementally sum all of the lengths - # to determine the ending position of each line. - self._lines = text.splitlines(True) - lines = [0] + [len(x) for x in self._lines] - for x in range(1, len(lines)): - lines[x] += lines[x-1] - self._line_offsets = lines - def from_offset(self, offset): - line = bisect.bisect(self._line_offsets, offset)-1 - col = offset - self._line_offsets[line] - return NodePos(line, col) - def to_offset(self, pos): - offset = self._line_offsets[pos.line] + pos.col - assert offset <= self._line_offsets[pos.line+1] # out-of-bounds col num - return offset - def text(self, start, end): - assert start <= end - # Trim the ending first in case it's a single line. - lines = self._lines[start.line:end.line+1] - lines[-1] = lines[-1][:end.col+1] - lines[0] = lines[0][start.col:] - return ''.join(lines) + " Given a string, allows [x] lookups for NodePos line and column numbers." + def __init__(self, text): + # Find the length of each line and incrementally sum all of the lengths + # to determine the ending position of each line. + self._lines = text.splitlines(True) + lines = [0] + [len(x) for x in self._lines] + for x in range(1, len(lines)): + lines[x] += lines[x-1] + self._line_offsets = lines + def from_offset(self, offset): + line = bisect.bisect(self._line_offsets, offset)-1 + col = offset - self._line_offsets[line] + return NodePos(line, col) + def to_offset(self, pos): + offset = self._line_offsets[pos.line] + pos.col + assert offset <= self._line_offsets[pos.line+1] # out-of-bounds col num + return offset + def text(self, start, end): + assert start <= end + # Trim the ending first in case it's a single line. + lines = self._lines[start.line:end.line+1] + lines[-1] = lines[-1][:end.col+1] + lines[0] = lines[0][start.col:] + return ''.join(lines) class NodeRanges: - def __init__(self): - self._offsets = [] - def add(self, start, end): - i = bisect.bisect_left(self._offsets, start) - if i % 2 == 1: - i -= 1 - start = self._offsets[i] + def __init__(self): + self._offsets = [] + def add(self, start, end): + i = bisect.bisect_left(self._offsets, start) + if i % 2 == 1: + i -= 1 + start = self._offsets[i] - end = end + 1 - j = bisect.bisect_left(self._offsets, end) - if j % 2 == 1: - end = self._offsets[j] - j += 1 + end = end + 1 + j = bisect.bisect_left(self._offsets, end) + if j % 2 == 1: + end = self._offsets[j] + j += 1 - self._offsets[i:j] = [start,end] - def has(self, pos): - return bisect.bisect_right(self._offsets, pos) % 2 == 1 + self._offsets[i:j] = [start,end] + def has(self, pos): + return bisect.bisect_right(self._offsets, pos) % 2 == 1 class _Node: - def add_child(self, node): - if node: - node.node_index = len(self.kids) - node.parent = self - self.kids.append(node) - - def start_pos(self): - try: - return self._start_pos - except AttributeError: - self._start_pos = NodePos(self._start_line, self._start_col) - return self._start_pos + def add_child(self, node): + if node: + node.node_index = len(self.kids) + node.parent = self + self.kids.append(node) + + def start_pos(self): + try: + return self._start_pos + except AttributeError: + self._start_pos = NodePos(self._start_line, self._start_col) + return self._start_pos - def end_pos(self): - try: - return self._end_pos - except AttributeError: - self._end_pos = NodePos(self._end_line, self._end_col) - return self._end_pos + def end_pos(self): + try: + return self._end_pos + except AttributeError: + self._end_pos = NodePos(self._end_line, self._end_col) + return self._end_pos - def __str__(self): - kind = self.kind - if not kind: - kind = '(none)' - return '%s>%s' % (_tok_names[kind], str(self.kids)) + def __str__(self): + kind = self.kind + if not kind: + kind = '(none)' + return '%s>%s' % (_tok_names[kind], str(self.kids)) - def is_equivalent(self, other, are_functions_equiv=False): - if not other: - return False + def is_equivalent(self, other, are_functions_equiv=False): + if not other: + return False - # Bail out for functions - if not are_functions_equiv: - if self.kind == tok.FUNCTION: - return False - if self.kind == tok.LP and self.opcode == op.CALL: - return False + # Bail out for functions + if not are_functions_equiv: + if self.kind == tok.FUNCTION: + return False + if self.kind == tok.LP and self.opcode == op.CALL: + return False - if self.kind != other.kind: - return False - if self.opcode != other.opcode: - return False + if self.kind != other.kind: + return False + if self.opcode != other.opcode: + return False - # Check atoms on names, properties, and string constants - if self.kind in (tok.NAME, tok.DOT, tok.STRING) and self.atom != other.atom: - return False + # Check atoms on names, properties, and string constants + if self.kind in (tok.NAME, tok.DOT, tok.STRING) and self.atom != other.atom: + return False - # Check values on numbers - if self.kind == tok.NUMBER and self.dval != other.dval: - return False + # Check values on numbers + if self.kind == tok.NUMBER and self.dval != other.dval: + return False - # Compare child nodes - if len(self.kids) != len(other.kids): - return False - for i in range(0, len(self.kids)): - # Watch for dead nodes - if not self.kids[i]: - if not other.kids[i]: return True - else: return False - if not self.kids[i].is_equivalent(other.kids[i]): - return False + # Compare child nodes + if len(self.kids) != len(other.kids): + return False + for i in range(0, len(self.kids)): + # Watch for dead nodes + if not self.kids[i]: + if not other.kids[i]: return True + else: return False + if not self.kids[i].is_equivalent(other.kids[i]): + return False - return True + return True def _parse_comments(script, root, node_positions, ignore_ranges): - pos = 0 - single_line_re = r"//[^\r\n]*" - multi_line_re = r"/\*(.*?)\*/" - full_re = "(%s)|(%s)" % (single_line_re, multi_line_re) - comment_re = re.compile(full_re, re.DOTALL) + pos = 0 + single_line_re = r"//[^\r\n]*" + multi_line_re = r"/\*(.*?)\*/" + full_re = "(%s)|(%s)" % (single_line_re, multi_line_re) + comment_re = re.compile(full_re, re.DOTALL) - comments = [] - while True: - match = comment_re.search(script, pos) - if not match: - return comments + comments = [] + while True: + match = comment_re.search(script, pos) + if not match: + return comments - # Get the comment text - comment_text = script[match.start():match.end()] - if comment_text.startswith('/*'): - comment_text = comment_text[2:-2] - opcode = 'JSOP_C_COMMENT' - else: - comment_text = comment_text[2:] - opcode = 'JSOP_CPP_COMMENT' - opcode = opcode[5:].lower() + # Get the comment text + comment_text = script[match.start():match.end()] + if comment_text.startswith('/*'): + comment_text = comment_text[2:-2] + opcode = 'JSOP_C_COMMENT' + else: + comment_text = comment_text[2:] + opcode = 'JSOP_CPP_COMMENT' + opcode = opcode[5:].lower() - start_offset = match.start()+1 - end_offset = match.end() + start_offset = match.start()+1 + end_offset = match.end() - # 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 + # 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 def parse(script, error_callback): - def _wrapped_callback(line, col, msg): - assert msg.startswith('JSMSG_') - msg = msg[6:].lower() - error_callback(line, col, msg) + def _wrapped_callback(line, col, msg): + assert msg.startswith('JSMSG_') + msg = msg[6:].lower() + error_callback(line, col, msg) - positions = NodePositions(script) + positions = NodePositions(script) - roots = [] - nodes = [] - comment_ignore_ranges = NodeRanges() - def process(node): - if node.kind == tok.NUMBER: - node.atom = 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()) - comment_ignore_ranges.add(start_offset, end_offset) - for kid in node.kids: - if kid: - process(kid) - def pop(): - nodes.pop() + roots = [] + nodes = [] + comment_ignore_ranges = NodeRanges() + def process(node): + if node.kind == tok.NUMBER: + node.atom = 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()) + comment_ignore_ranges.add(start_offset, end_offset) + for kid in node.kids: + if kid: + process(kid) + def pop(): + nodes.pop() - root_node = pyspidermonkey.parse(script, _Node, _wrapped_callback) - process(root_node) + root_node = pyspidermonkey.parse(script, _Node, _wrapped_callback) + process(root_node) - comments = _parse_comments(script, root_node, positions, comment_ignore_ranges) - return root_node, comments + comments = _parse_comments(script, root_node, positions, comment_ignore_ranges) + return root_node, comments def _dump_node(node, depth=0): - print '. '*depth, - if node is None: - print '(none)' - else: - print '%s\t%s, %s' % (_tok_names[node.kind], node.start_pos(), node.end_pos()) - for node in node.kids: - _dump_node(node, depth+1) + print '. '*depth, + if node is None: + print '(none)' + else: + print '%s\t%s, %s' % (_tok_names[node.kind], node.start_pos(), node.end_pos()) + for node in node.kids: + _dump_node(node, depth+1) def dump_tree(script): - def error_callback(line, col, msg): - print '(%i, %i): %s', (line, col, msg) - node, comments = parse(script, error_callback) - _dump_node(node) + def error_callback(line, col, msg): + print '(%i, %i): %s', (line, col, msg) + node, comments = 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) - encountered_comments = [node.atom for node in comments] - self.assertEquals(encountered_comments, list(expected_comments)) - def testSimpleComments(self): - self._test('re = /\//g', ()) - self._test('re = /\///g', ()) - self._test('re = /\////g', ('g',)) - def testCComments(self): - self._test('/*a*//*b*/', ('a', 'b')) - self._test('/*a\r\na*//*b\r\nb*/', ('a\r\na', 'b\r\nb')) - self._test('a//*b*/c', ('*b*/c',)) - self._test('a///*b*/c', ('/*b*/c',)) - self._test('a/*//*/;', ('//',)) - self._test('a/*b*/+/*c*/d', ('b', 'c')) + def _test(self, script, expected_comments): + root, comments = parse(script, lambda line, col, msg: None) + encountered_comments = [node.atom for node in comments] + self.assertEquals(encountered_comments, list(expected_comments)) + def testSimpleComments(self): + self._test('re = /\//g', ()) + self._test('re = /\///g', ()) + self._test('re = /\////g', ('g',)) + def testCComments(self): + self._test('/*a*//*b*/', ('a', 'b')) + self._test('/*a\r\na*//*b\r\nb*/', ('a\r\na', 'b\r\nb')) + self._test('a//*b*/c', ('*b*/c',)) + self._test('a///*b*/c', ('/*b*/c',)) + self._test('a/*//*/;', ('//',)) + self._test('a/*b*/+/*c*/d', ('b', 'c')) class TestNodePositions(unittest.TestCase): - def _test(self, text, expected_lines, expected_cols): - # Get a NodePos list - positions = NodePositions(text) - positions = [positions.from_offset(i) for i in range(0, len(text))] - encountered_lines = ''.join([str(x.line) for x in positions]) - encountered_cols = ''.join([str(x.col) for x in positions]) - self.assertEquals(encountered_lines, expected_lines.replace(' ', '')) - self.assertEquals(encountered_cols, expected_cols.replace(' ', '')) - def testSimple(self): - self._test( - 'abc\r\ndef\nghi\n\nj', - '0000 0 1111 2222 3 4', - '0123 4 0123 0123 0 0' - ) - self._test( - '\rabc', - '0 111', - '0 012' - ) - def testText(self): - pos = NodePositions('abc\r\ndef\n\nghi') - self.assertEquals(pos.text(NodePos(0, 0), NodePos(0, 0)), 'a') - self.assertEquals(pos.text(NodePos(0, 0), NodePos(0, 2)), 'abc') - self.assertEquals(pos.text(NodePos(0, 2), NodePos(1, 2)), 'c\r\ndef') - def testOffset(self): - pos = NodePositions('abc\r\ndef\n\nghi') - self.assertEquals(pos.to_offset(NodePos(0, 2)), 2) - self.assertEquals(pos.to_offset(NodePos(1, 0)), 5) - self.assertEquals(pos.to_offset(NodePos(3, 1)), 11) + def _test(self, text, expected_lines, expected_cols): + # Get a NodePos list + positions = NodePositions(text) + positions = [positions.from_offset(i) for i in range(0, len(text))] + encountered_lines = ''.join([str(x.line) for x in positions]) + encountered_cols = ''.join([str(x.col) for x in positions]) + self.assertEquals(encountered_lines, expected_lines.replace(' ', '')) + self.assertEquals(encountered_cols, expected_cols.replace(' ', '')) + def testSimple(self): + self._test( + 'abc\r\ndef\nghi\n\nj', + '0000 0 1111 2222 3 4', + '0123 4 0123 0123 0 0' + ) + self._test( + '\rabc', + '0 111', + '0 012' + ) + def testText(self): + pos = NodePositions('abc\r\ndef\n\nghi') + self.assertEquals(pos.text(NodePos(0, 0), NodePos(0, 0)), 'a') + self.assertEquals(pos.text(NodePos(0, 0), NodePos(0, 2)), 'abc') + self.assertEquals(pos.text(NodePos(0, 2), NodePos(1, 2)), 'c\r\ndef') + def testOffset(self): + pos = NodePositions('abc\r\ndef\n\nghi') + self.assertEquals(pos.to_offset(NodePos(0, 2)), 2) + self.assertEquals(pos.to_offset(NodePos(1, 0)), 5) + self.assertEquals(pos.to_offset(NodePos(3, 1)), 11) class TestNodeRanges(unittest.TestCase): - def testAdd(self): - r = NodeRanges() - r.add(5, 10) - self.assertEquals(r._offsets, [5,11]) - r.add(15, 20) - self.assertEquals(r._offsets, [5,11,15,21]) - r.add(21,22) - self.assertEquals(r._offsets, [5,11,15,23]) - r.add(4,5) - self.assertEquals(r._offsets, [4,11,15,23]) - r.add(9,11) - self.assertEquals(r._offsets, [4,12,15,23]) - r.add(10,20) - self.assertEquals(r._offsets, [4,23]) - r.add(4,22) - self.assertEquals(r._offsets, [4,23]) - r.add(30,30) - self.assertEquals(r._offsets, [4,23,30,31]) - def testHas(self): - r = NodeRanges() - r.add(5, 10) - r.add(15, 15) - assert not r.has(4) - assert r.has(5) - assert r.has(6) - assert r.has(9) - assert r.has(10) - assert not r.has(14) - assert r.has(15) - assert not r.has(16) + def testAdd(self): + r = NodeRanges() + r.add(5, 10) + self.assertEquals(r._offsets, [5,11]) + r.add(15, 20) + self.assertEquals(r._offsets, [5,11,15,21]) + r.add(21,22) + self.assertEquals(r._offsets, [5,11,15,23]) + r.add(4,5) + self.assertEquals(r._offsets, [4,11,15,23]) + r.add(9,11) + self.assertEquals(r._offsets, [4,12,15,23]) + r.add(10,20) + self.assertEquals(r._offsets, [4,23]) + r.add(4,22) + self.assertEquals(r._offsets, [4,23]) + r.add(30,30) + self.assertEquals(r._offsets, [4,23,30,31]) + def testHas(self): + r = NodeRanges() + r.add(5, 10) + r.add(15, 15) + assert not r.has(4) + assert r.has(5) + assert r.has(6) + assert r.has(9) + assert r.has(10) + assert not r.has(14) + assert r.has(15) + assert not r.has(16) class TestCompilableUnit(unittest.TestCase): - def test(self): - tests = ( - ('var s = "', False), - ('bogon()', True), - ('int syntax_error;', True), - ('a /* b', False), - ('re = /.*', False), - ('{ // missing curly', False) - ) - for text, is_compilable_unit in tests: - self.assertEquals(pyspidermonkey.is_compilable_unit(text), - is_compilable_unit) + def test(self): + tests = ( + ('var s = "', False), + ('bogon()', True), + ('int syntax_error;', True), + ('a /* b', False), + ('re = /.*', False), + ('{ // missing curly', False) + ) + for text, is_compilable_unit in tests: + self.assertEquals(pyspidermonkey.is_compilable_unit(text), + is_compilable_unit) if __name__ == '__main__': - unittest.main() + unittest.main() Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/pyjsl/lint.py 2008-03-31 13:45:14 UTC (rev 178) @@ -11,282 +11,282 @@ from pyspidermonkey import tok, op _newline_kinds = ( - 'eof', 'comma', 'dot', 'semi', 'colon', 'lc', 'rc', 'lp', 'rb', 'assign', - 'relop', 'hook', 'plus', 'minus', 'star', 'divop', 'eqop', 'shop', 'or', - 'and', 'bitor', 'bitxor', 'bitand', 'else', 'try' + 'eof', 'comma', 'dot', 'semi', 'colon', 'lc', 'rc', 'lp', 'rb', 'assign', + 'relop', 'hook', 'plus', 'minus', 'star', 'divop', 'eqop', 'shop', 'or', + 'and', 'bitor', 'bitxor', 'bitand', 'else', 'try' ) _globals = frozenset([ - 'Array', 'Boolean', 'Math', 'Number', 'String', 'RegExp', 'Script', 'Date', - 'isNaN', 'isFinite', 'parseFloat', 'parseInt', - 'eval', 'NaN', 'Infinity', - 'escape', 'unescape', 'uneval', - 'decodeURI', 'encodeURI', 'decodeURIComponent', 'encodeURIComponent', - 'Function', 'Object', - 'Error', 'InternalError', 'EvalError', 'RangeError', 'ReferenceError', - 'SyntaxError', 'TypeError', 'URIError', - 'arguments', 'undefined' + 'Array', 'Boolean', 'Math', 'Number', 'String', 'RegExp', 'Script', 'Date', + 'isNaN', 'isFinite', 'parseFloat', 'parseInt', + 'eval', 'NaN', 'Infinity', + 'escape', 'unescape', 'uneval', + 'decodeURI', 'encodeURI', 'decodeURIComponent', 'encodeURIComponent', + 'Function', 'Object', + 'Error', 'InternalError', 'EvalError', 'RangeError', 'ReferenceError', + 'SyntaxError', 'TypeError', 'URIError', + 'arguments', 'undefined' ]) _identifier = re.compile('^[A-Za-z_$][A-Za-z0-9_$]*$') def _find_function(node): - while node and node.kind != tok.FUNCTION: - node = node.parent - return node + while node and node.kind != tok.FUNCTION: + node = node.parent + return node def _find_functions(node): - functions = [] - while node: - if node.kind == tok.FUNCTION: - functions.append(node) - node = node.parent - return functions + functions = [] + while node: + if node.kind == tok.FUNCTION: + functions.append(node) + node = node.parent + return functions def _parse_control_comment(comment): - """ Returns None or (keyword, parms) """ - if comment.atom.lower().startswith('jsl:'): - control_comment = comment.atom[4:] - elif comment.atom.startswith('@') and comment.atom.endswith('@'): - control_comment = comment.atom[1:-1] - else: - return None + """ Returns None or (keyword, parms) """ + if comment.atom.lower().startswith('jsl:'): + control_comment = comment.atom[4:] + elif comment.atom.startswith('@') and comment.atom.endswith('@'): + control_comment = comment.atom[1:-1] + else: + return None - control_comments = { - 'ignoreall': (False), - 'ignore': (False), - 'end': (False), - 'option explicit': (False), - 'import': (True), - 'fallthru': (False), - 'pass': (False), - 'declare': (True) - } - if control_comment.lower() in control_comments: - keyword = control_comment.lower() - else: - keyword = control_comment.lower().split()[0] - if not keyword in control_comments: - return None + control_comments = { + 'ignoreall': (False), + 'ignore': (False), + 'end': (False), + 'option explicit': (False), + 'import': (True), + 'fallthru': (False), + 'pass': (False), + 'declare': (True) + } + if control_comment.lower() in control_comments: + keyword = control_comment.lower() + else: + keyword = control_comment.lower().split()[0] + if not keyword in control_comments: + return None - parms = control_comment[len(keyword):].strip() - return (comment, keyword, parms) + parms = control_comment[len(keyword):].strip() + return (comment, keyword, parms) class Scope: - def __init__(self, node): - self._is_with_scope = node.kind == tok.WITH - self._parent = None - self._kids = [] - self._identifiers = {} - self._references = [] - self._node = node - def add_scope(self, node): - self._kids.append(Scope(node)) - self._kids[-1]._parent = self - if self._is_with_scope: - self._kids[-1]._is_with_scope = True - return self._kids[-1] - def add_declaration(self, name, node): - if not self._is_with_scope: - self._identifiers[name] = node - def add_reference(self, name, node): - if not self._is_with_scope: - self._references.append((name, node)) - def get_identifier(self, name): - if name in self._identifiers: - return self._identifiers[name] - else: - return None - def get_identifiers(self): - "returns a list of names" - return self._identifiers.keys() - def resolve_identifier(self, name): - if name in self._identifiers: - return self, self._identifiers[name] - if self._parent: - return self._parent.resolve_identifier(name) - return None - def get_undeclared_identifiers(self): - identifiers = [] - for child in self._kids: - identifiers += child.get_undeclared_identifiers() - for name, node in self._references: - if not self.resolve_identifier(name): - identifiers.append(node) - return identifiers - def find_scope(self, node): - for kid in self._kids: - scope = kid.find_scope(node) - if scope: - return scope + def __init__(self, node): + self._is_with_scope = node.kind == tok.WITH + self._parent = None + self._kids = [] + self._identifiers = {} + self._references = [] + self._node = node + def add_scope(self, node): + self._kids.append(Scope(node)) + self._kids[-1]._parent = self + if self._is_with_scope: + self._kids[-1]._is_with_scope = True + return self._kids[-1] + def add_declaration(self, name, node): + if not self._is_with_scope: + self._identifiers[name] = node + def add_reference(self, name, node): + if not self._is_with_scope: + self._references.append((name, node)) + def get_identifier(self, name): + if name in self._identifiers: + return self._identifiers[name] + else: + return None + def get_identifiers(self): + "returns a list of names" + return self._identifiers.keys() + def resolve_identifier(self, name): + if name in self._identifiers: + return self, self._identifiers[name] + if self._parent: + return self._parent.resolve_identifier(name) + return None + def get_undeclared_identifiers(self): + identifiers = [] + for child in self._kids: + identifiers += child.get_undeclared_identifiers() + for name, node in self._references: + if not self.resolve_identifier(name): + identifiers.append(node) + return identifiers + def find_scope(self, node): + for kid in self._kids: + scope = kid.find_scope(node) + if scope: + return scope - # Always add it to the outer scope. - if not self._parent or \ - (node.start_pos() >= self._node.start_pos() and \ - node.end_pos() <= self._node.end_pos()): - return self + # Always add it to the outer scope. + if not self._parent or \ + (node.start_pos() >= self._node.start_pos() and \ + node.end_pos() <= self._node.end_pos()): + return self - return None + return None def lint_files(paths, lint_error, conf=conf.Conf()): - def lint_file(path): - def import_script(import_path): - import_path = os.path.join(os.path.dirname(path), import_path) - return lint_file(import_path) - def _lint_error(*args): - return lint_error(normpath, *args) + def lint_file(path): + def import_script(import_path): + import_path = os.path.join(os.path.dirname(path), import_path) + return lint_file(import_path) + def _lint_error(*args): + return lint_error(normpath, *args) - normpath = util.normpath(path) - if not normpath in lint_cache: - lint_cache[normpath] = {} - script = util.readfile(path) - print normpath - _lint_script(script, lint_cache[normpath], _lint_error, conf, import_script) - return lint_cache[normpath] + normpath = util.normpath(path) + if not normpath in lint_cache: + lint_cache[normpath] = {} + script = util.readfile(path) + print normpath + _lint_script(script, lint_cache[normpath], _lint_error, conf, import_script) + return lint_cache[normpath] - lint_cache = {} - for path in paths: - lint_file(path) + lint_cache = {} + for path in paths: + lint_file(path) def _lint_script(script, script_cache, lint_error, conf, import_callback): - def parse_error(row, col, msg): - if not msg in ('redeclared_var', 'var_hides_arg'): - parse_errors.append((jsparse.NodePos(row, col), msg)) + def parse_error(row, col, msg): + if not msg in ('redeclared_var', 'var_hides_arg'): + parse_errors.append((jsparse.NodePos(row, col), msg)) - def report(node, errname): - _report(node.start_pos(), errname, True) + def report(node, errname): + _report(node.start_pos(), errname, True) - def _report(pos, errname, require_key): - try: - if not conf[errname]: - return - except KeyError, err: - if require_key: - raise + def _report(pos, errname, require_key): + try: + if not conf[errname]: + return + except KeyError, err: + if require_key: + raise - for start, end in ignores: - if pos >= start and pos <= end: - return + for start, end in ignores: + if pos >= start and pos <= end: + return - return lint_error(pos.line, pos.col, errname) + return lint_error(pos.line, pos.col, errname) - parse_errors = [] - root, comments = jsparse.parse(script, parse_error) - ignores = [] - start_ignore = None - declares = [] - import_paths = [] - for comment in comments: - cc = _parse_control_comment(comment) - if cc: - node, keyword, parms = cc - if keyword == 'declare': - if not _identifier.match(parms): - report(node, 'jsl_cc_not_understood') - else: - declares.append((parms, node)) - elif keyword == 'ignore': - if start_ignore: - report(node, 'mismatch_ctrl_comments') - else: - start_ignore = node - elif keyword == 'end': - if start_ignore: - ignores.append((start_ignore.start_pos(), node.end_pos())) - start_ignore = None - else: - report(node, 'mismatch_ctrl_comments') - elif keyword == 'import': - if not parms: - report(node, 'jsl_cc_not_understood') - else: - import_paths.append(parms) - else: - if comment.opcode == 'c_comment': - if '/*' in comment.atom or comment.atom.endswith('/'): - report(comment, 'nested_comment') - if comment.atom.lower().startswith('jsl:'): - report(comment, 'jsl_cc_not_understood') - elif comment.atom.startswith('@'): - report(comment, 'legacy_cc_not_understood') - if start_ignore: - report(start_ignore, 'mismatch_ctrl_comments') + parse_errors = [] + root, comments = jsparse.parse(script, parse_error) + ignores = [] + start_ignore = None + declares = [] + import_paths = [] + for comment in comments: + cc = _parse_control_comment(comment) + if cc: + node, keyword, parms = cc + if keyword == 'declare': + if not _identifier.match(parms): + report(node, 'jsl_cc_not_understood') + else: + declares.append((parms, node)) + elif keyword == 'ignore': + if start_ignore: + report(node, 'mismatch_ctrl_comments') + else: + start_ignore = node + elif keyword == 'end': + if start_ignore: + ignores.append((start_ignore.start_pos(), node.end_pos())) + start_ignore = None + else: + report(node, 'mismatch_ctrl_comments') + elif keyword == 'import': + if not parms: + report(node, 'jsl_cc_not_understood') + else: + import_paths.append(parms) + else: + if comment.opcode == 'c_comment': + if '/*' in comment.atom or comment.atom.endswith('/'): + report(comment, 'nested_comment') + if comment.atom.lower().startswith('jsl:'): + report(comment, 'jsl_cc_not_understood') + elif comment.atom.startswith('@'): + report(comment, 'legacy_cc_not_understood') + if start_ignore: + report(start_ignore, 'mismatch_ctrl_comments') - # Wait to report parse errors until loading jsl:ignore directives. - for pos, msg in parse_errors: - _report(pos, msg, False) + # Wait to report parse errors until loading jsl:ignore directives. + for pos, msg in parse_errors: + _report(pos, msg, False) - visitors = visitation.make_visitors(warnings.klasses) + visitors = visitation.make_visitors(warnings.klasses) - assert not script_cache - imports = script_cache['imports'] = set() - scope = script_cache['scope'] = Scope(root) + assert not script_cache + imports = script_cache['imports'] = set() + scope = script_cache['scope'] = Scope(root) - # kickoff! - _lint_node(root, visitors, report, scope) + # kickoff! + _lint_node(root, visitors, report, scope) - # Process imports by copying global declarations into the universal scope. - imports |= set(conf['declarations']) - imports |= _globals - for path in import_paths: - cache = import_callback(path) - imports |= cache['imports'] - imports |= set(cache['scope'].get_identifiers()) + # Process imports by copying global declarations into the universal scope. + imports |= set(conf['declarations']) + imports |= _globals + for path in import_paths: + cache = import_callback(path) + imports |= cache['imports'] + imports |= set(cache['scope'].get_identifiers()) - for name, node in declares: - declare_scope = scope.find_scope(node) - if declare_scope.get_identifier(name): - report(node, 'redeclared_var') - else: - declare_scope.add_declaration(name, node) + for name, node in declares: + declare_scope = scope.find_scope(node) + if declare_scope.get_identifier(name): + report(node, 'redeclared_var') + else: + declare_scope.add_declaration(name, node) - for node in scope.get_undeclared_identifiers(): - if not node.atom in imports: - report(node, 'undeclared_identifier') + for node in scope.get_undeclared_identifiers(): + if not node.atom in imports: + report(node, 'undeclared_identifier') 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) + 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: - for visitor in visitors[kind]: - warning_node = visitor(node) - if warning_node: - report(warning_node, visitor.im_class.__name__) + # Let the visitors warn. + 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__) - 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) + 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) - # Push function identifiers - if node.kind == tok.FUNCTION: - if node.fn_name: - warn_or_declare(node.fn_name, node) - 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) + # Push function identifiers + if node.kind == tok.FUNCTION: + if node.fn_name: + warn_or_declare(node.fn_name, node) + 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) - if node.parent and node.parent.kind == tok.VAR: - warn_or_declare(node.atom, node) + if node.parent and node.parent.kind == tok.VAR: + warn_or_declare(node.atom, node) - for child in node.kids: - if child: - _lint_node(child, visitors, report, scope) + for child in node.kids: + if child: + _lint_node(child, visitors, report, scope) Modified: trunk/pyjsl/util.py =================================================================== --- trunk/pyjsl/util.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/pyjsl/util.py 2008-03-31 13:45:14 UTC (rev 178) @@ -2,15 +2,15 @@ import os.path def readfile(path): - file = codecs.open(path, 'r', 'utf-8') - contents = file.read() - if contents[0] == unicode(codecs.BOM_UTF8, 'utf8'): - contents = contents[1:] - return contents + file = codecs.open(path, 'r', 'utf-8') + contents = file.read() + if contents[0] == unicode(codecs.BOM_UTF8, 'utf8'): + contents = contents[1:] + return contents def normpath(path): - path = os.path.abspath(path) - path = os.path.normcase(path) - path = os.path.normpath(path) - return path + path = os.path.abspath(path) + path = os.path.normcase(path) + path = os.path.normpath(path) + return path Modified: trunk/pyjsl/visitation.py =================================================================== --- trunk/pyjsl/visitation.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/pyjsl/visitation.py 2008-03-31 13:45:14 UTC (rev 178) @@ -3,33 +3,33 @@ """ def visit(*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_nodes = args - return fn - return _decorate + """ 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_nodes = args + return fn + return _decorate def make_visitors(klasses): - """ Searches klasses for all member functions decorated with @visit and - returns a dictionary that maps from node type to visitor function. """ - visitors = {} + """ Searches klasses for all member functions decorated with @visit and + returns a dictionary that maps from node type to visitor function. """ + visitors = {} - # Intantiate an instance of each class - for klass in klasses: - if klass.__name__.lower() != klass.__name__: - raise ValueError, 'class names must be lowercase' - if not klass.__doc__: - raise ValueError, 'missing docstring on class' + # Intantiate an instance of each class + for klass in klasses: + if klass.__name__.lower() != klass.__name__: + raise ValueError, 'class names must be lowercase' + if not klass.__doc__: + raise ValueError, 'missing docstring on class' - # Look for functions with the "_visit_nodes" property. - visitor = klass() - for func in [getattr(visitor, name) for name in dir(visitor)]: - for node_kind in getattr(func, '_visit_nodes', ()): - # Map from node_kind to the function - if not node_kind in visitors: - visitors[node_kind] = [] - visitors[node_kind].append(func) - return visitors + # Look for functions with the "_visit_nodes" property. + visitor = klass() + for func in [getattr(visitor, name) for name in dir(visitor)]: + for node_kind in getattr(func, '_visit_nodes', ()): + # Map from node_kind to the function + if not node_kind in visitors: + visitors[node_kind] = [] + visitors[node_kind].append(func) + return visitors Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-03-20 21:38:49 UTC (rev 177) +++ trunk/pyjsl/warnings.py 2008-03-31 13:45:14 UTC (rev 178) @@ -10,12 +10,12 @@ For example: - class warning_name: - 'questionable JavaScript coding style' - @lookat(tok.NODEKIND, (tok.NODEKIND, op.OPCODE)) - def _lint(self, node): - if questionable: - return node + class warning_name: + 'questionable JavaScript coding style' + @lookat(tok.NODEKIND, (tok.NODEKIND, op.OPCODE)) + def _lint(self, node): + if questionable: + return node """ import re import sys @@ -27,468 +27,468 @@ # TODO: document inspect, node:opcode, etc 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 \ - node.parent.parent.kind == tok.FOR: - return node.node_index - return None + " Returns None if this is not one of the branches in a 'for' " + if node.parent and node.parent.kind == tok.RESERVED and \ + node.parent.parent.kind == tok.FOR: + return node.node_index + return None def _get_exit_points(node): - if node.kind == tok.LC: - # Only if the last child contains it - exit_points = set([None]) - for kid in node.kids: - # "None" is only a valid exit point for the last statement. - if None in exit_points: - exit_points.remove(None) - if kid: - exit_points |= _get_exit_points(kid) - elif node.kind == tok.IF: - # Only if both branches have an exit point - cond_, if_, else_ = node.kids - exit_points = _get_exit_points(if_) - if else_: - exit_points |= _get_exit_points(else_) - elif node.kind == tok.SWITCH: - exit_points = set([None]) + if node.kind == tok.LC: + # Only if the last child contains it + exit_points = set([None]) + for kid in node.kids: + # "None" is only a valid exit point for the last statement. + if None in exit_points: + exit_points.remove(None) + if kid: + exit_points |= _get_exit_points(kid) + elif node.kind == tok.IF: + # Only if both branches have an exit point + cond_, if_, else_ = node.kids + exit_points = _get_exit_points(if_) + if else_: + exit_points |= _get_exit_points(else_) + elif node.kind == tok.SWITCH: + exit_points = set([None]) - switch_has_default = False - switch_has_final_fallthru = True + switch_has_default = False + switch_has_final_fallthru = True - switch_var, switch_stmts = node.kids - for node in switch_stmts.kids: - case_val, case_stmt = node.kids - case_exit_points = _get_exit_points(case_stmt) - switch_has_default = switch_has_default or node.kind == tok.DEFAULT - switch_has_final_fallthru = None in case_exit_points - exit_points |= case_exit_points + switch_var, switch_stmts = node.kids + for node in switch_stmts.kids: + case_val, case_stmt = node.kids + case_exit_points = _get_exit_points(case_stmt) + switch_has_default = switch_has_default or node.kind == tok.DEFAULT + switch_has_final_fallthru = None in case_exit_points + exit_points |= case_exit_points - # Correct the "None" exit point. - exi... [truncated message content] |
From: <mat...@us...> - 2008-03-20 21:38:52
|
Revision: 177 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=177&view=rev Author: matthiasmiller Date: 2008-03-20 14:38:49 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: print the file name only once Modified Paths: -------------- trunk/jsl.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-20 21:38:16 UTC (rev 176) +++ trunk/jsl.py 2008-03-20 21:38:49 UTC (rev 177) @@ -43,7 +43,6 @@ if file.endswith('.htm') or file.endswith('.html'): continue #TODO elif file.endswith('.js'): - print file try: test.run(file) except test.TestError, error: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 21:38:21
|
Revision: 176 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=176&view=rev Author: matthiasmiller Date: 2008-03-20 14:38:16 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: fix some more incorrect line positions Modified Paths: -------------- trunk/tests/control_comments/declare.js trunk/tests/errors/unterminated_comment.js trunk/tests/warnings/ambiguous_newline.js trunk/tests/warnings/block_without_braces.js trunk/tests/warnings/empty_statement.js Modified: trunk/tests/control_comments/declare.js =================================================================== --- trunk/tests/control_comments/declare.js 2008-03-20 21:31:06 UTC (rev 175) +++ trunk/tests/control_comments/declare.js 2008-03-20 21:38:16 UTC (rev 176) @@ -1,10 +1,10 @@ /*jsl:option explicit*/ function declare() { window.alert('http://www.javascriptlint.com/'); - /*jsl:declare window*/ + /*jsl:declare window*/ /*warning:redeclared_var*/ /* redeclaration only at local scope */ - var window;/*warning:redeclared_var*/ + var window; var document; /*jsl:declare document*//*warning:redeclared_var*/ } @@ -17,8 +17,8 @@ document.write('<a href="http://www.javascriptlint.com/">JavaScript Lint</a>'); -/*jsl:declare document*/ -function document()/*warning:redeclared_var*/ +/*jsl:declare document*/ /*warning:redeclared_var*/ +function document() { } Modified: trunk/tests/errors/unterminated_comment.js =================================================================== --- trunk/tests/errors/unterminated_comment.js 2008-03-20 21:31:06 UTC (rev 175) +++ trunk/tests/errors/unterminated_comment.js 2008-03-20 21:38:16 UTC (rev 176) @@ -1,8 +1,8 @@ function unterminated_comment() { - /* - This should not produce a syntax error - when ending a multiline-comment like this: - ////////////////////////////////////////////////////////*/ /*warning:nested_comment*/ - - return true; + /* + This should not produce a syntax error + when ending a multiline-comment like this: + ////////////////////////////////////////////////////////*/ /*warning:nested_comment*/ + + return true; } Modified: trunk/tests/warnings/ambiguous_newline.js =================================================================== --- trunk/tests/warnings/ambiguous_newline.js 2008-03-20 21:31:06 UTC (rev 175) +++ trunk/tests/warnings/ambiguous_newline.js 2008-03-20 21:38:16 UTC (rev 176) @@ -218,15 +218,15 @@ + "!"; /*warning:ambiguous_newline*/ /* illegal: ++ */ - b = i++ - || true; /*warning:ambiguous_newline*//*warning:inc_dec_within_stmt*/ + b = i++ /*warning:inc_dec_within_stmt*/ + || true; /*warning:ambiguous_newline*/ /* illegal: -- */ - s = i-- - + " = i"; /*warning:ambiguous_newline*//*warning:inc_dec_within_stmt*/ + s = i-- /*warning:inc_dec_within_stmt*/ + + " = i"; /*warning:ambiguous_newline*/ /* legal */ - if (true) + if (true) /*warning:meaningless_block*/ { i++; } Modified: trunk/tests/warnings/block_without_braces.js =================================================================== --- trunk/tests/warnings/block_without_braces.js 2008-03-20 21:31:06 UTC (rev 175) +++ trunk/tests/warnings/block_without_braces.js 2008-03-20 21:38:16 UTC (rev 176) @@ -5,8 +5,8 @@ if (i) i++; /*warning:block_without_braces*/ - do i--; /*warning:block_without_braces*/ - while (i); + do i--; + while (i); /*warning:block_without_braces*/ for (i = 0; i < 10; i++) i *= 2; /*warning:block_without_braces*/ Modified: trunk/tests/warnings/empty_statement.js =================================================================== --- trunk/tests/warnings/empty_statement.js 2008-03-20 21:31:06 UTC (rev 175) +++ trunk/tests/warnings/empty_statement.js 2008-03-20 21:38:16 UTC (rev 176) @@ -7,16 +7,16 @@ while (false); /*warning:empty_statement*/ while (false) /*jsl:pass*/; /*warning:invalid_pass*//*warning:empty_statement*/ + while (false) { /*warning:empty_statement*/ + } while (false) { - } /*warning:empty_statement*/ - while (false) { /*jsl:pass*/ } /* empty block within for; useless expression */ + for (i = 0; i < 2; i += 1) { /*warning:empty_statement*/ + } for (i = 0; i < 2; i += 1) { - } /*warning:empty_statement*/ - for (i = 0; i < 2; i += 1) { /*jsl:pass*/ } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 21:31:09
|
Revision: 175 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=175&view=rev Author: matthiasmiller Date: 2008-03-20 14:31:06 -0700 (Thu, 20 Mar 2008) Log Message: ----------- missing_break warning: fix try/catch/finally statements Modified Paths: -------------- trunk/pyjsl/warnings.py trunk/tests/warnings/missing_break.js Modified: trunk/pyjsl/warnings.py =================================================================== --- trunk/pyjsl/warnings.py 2008-03-20 21:30:17 UTC (rev 174) +++ trunk/pyjsl/warnings.py 2008-03-20 21:31:06 UTC (rev 175) @@ -89,12 +89,28 @@ elif node.kind == tok.TRY: try_, catch_, finally_ = node.kids + assert catch_.kind == tok.RESERVED + catch_, = catch_.kids + assert catch_.kind == tok.LEXICALSCOPE + catch_, = catch_.kids + assert catch_.kind == tok.CATCH + ignored, ignored, catch_ = catch_.kids + assert catch_.kind == tok.LC + exit_points = _get_exit_points(try_) | _get_exit_points(catch_) if finally_: - # Always if the finally has an exit point - if None in exit_points: - exit_points.remove(None) - exit_points |= _get_exit_points(finally_) + finally_exit_points = _get_exit_points(finally_) + if None in finally_exit_points: + # The finally statement does not add a missing exit point. + finally_exit_points.remove(None) + else: + # If the finally statement always returns, the other + # exit points are irrelevant. + if None in exit_points: + exit_points.remove(None) + + exit_points |= finally_exit_points + else: exit_points = set([None]) @@ -311,7 +327,8 @@ if not case_contents.kids: return if None in _get_exit_points(case_contents): - return node + # Show the warning on the *next* node. + return node.parent.kids[node.node_index+1] class missing_break_for_last_case: 'missing break statement for last case in switch' Modified: trunk/tests/warnings/missing_break.js =================================================================== --- trunk/tests/warnings/missing_break.js 2008-03-20 21:30:17 UTC (rev 174) +++ trunk/tests/warnings/missing_break.js 2008-03-20 21:31:06 UTC (rev 175) @@ -52,7 +52,7 @@ } case 6: /*warning:missing_break*/ - /*ok; finally statement never called*/ + /*ok; finally statement does not affect it */ try { i--; break; @@ -79,6 +79,19 @@ break; } + case 8: + /*ok; return statement in finally*/ + try { + i--; + } + catch (err) { + s = null; + } + finally { + i++; + return i; + } + default: break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 21:30:19
|
Revision: 174 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=174&view=rev Author: matthiasmiller Date: 2008-03-20 14:30:17 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: missing_default_case is now reported at the top of the switch, and missing_break_for_last_case is now reported at the top of the case statement Modified Paths: -------------- trunk/tests/warnings/missing_break_for_last_case.js trunk/tests/warnings/missing_default_case.js Modified: trunk/tests/warnings/missing_break_for_last_case.js =================================================================== --- trunk/tests/warnings/missing_break_for_last_case.js 2008-03-20 21:28:43 UTC (rev 173) +++ trunk/tests/warnings/missing_break_for_last_case.js 2008-03-20 21:30:17 UTC (rev 174) @@ -1,15 +1,15 @@ /*jsl:option explicit*/ function missing_break_for_last_case(i) { switch (i) { - default: + default: /*warning:missing_break_for_last_case*/ /*missing break at end of switch (without code)*/ - } /*warning:missing_break_for_last_case*/ + } /*missing break at end of switch (with code)*/ switch (i) { - default: + default: /*warning:missing_break_for_last_case*/ i++; - } /*warning:missing_break_for_last_case*/ + } /*ok because of fallthru*/ switch (i) { Modified: trunk/tests/warnings/missing_default_case.js =================================================================== --- trunk/tests/warnings/missing_default_case.js 2008-03-20 21:28:43 UTC (rev 173) +++ trunk/tests/warnings/missing_default_case.js 2008-03-20 21:30:17 UTC (rev 174) @@ -3,10 +3,10 @@ var i, s; /*missing default case*/ - switch (i) { + switch (i) { /*warning:missing_default_case*/ case 1: return 1; - } /*warning:missing_default_case*/ + } /* ambivalence - allow fallthru but don't enforce it */ switch (i) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 21:28:44
|
Revision: 173 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=173&view=rev Author: matthiasmiller Date: 2008-03-20 14:28:43 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: warnings for control comments are now reported on the same line as the control comment Modified Paths: -------------- trunk/tests/control_comments/control_comments.js Modified: trunk/tests/control_comments/control_comments.js =================================================================== --- trunk/tests/control_comments/control_comments.js 2008-03-20 21:28:00 UTC (rev 172) +++ trunk/tests/control_comments/control_comments.js 2008-03-20 21:28:43 UTC (rev 173) @@ -28,6 +28,6 @@ /*jsl:end*/ /* illegal - don't forget to end */ - /*jsl:ignore*/ + /*jsl:ignore*/ /*warning:mismatch_ctrl_comments*/ } -/*warning:mismatch_ctrl_comments*/ + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 21:28:03
|
Revision: 172 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=172&view=rev Author: matthiasmiller Date: 2008-03-20 14:28:00 -0700 (Thu, 20 Mar 2008) Log Message: ----------- warn against unrecognized control comments Modified Paths: -------------- trunk/pyjsl/lint.py Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-03-20 20:57:33 UTC (rev 171) +++ trunk/pyjsl/lint.py 2008-03-20 21:28:00 UTC (rev 172) @@ -66,6 +66,8 @@ keyword = control_comment.lower() else: keyword = control_comment.lower().split()[0] + if not keyword in control_comments: + return None parms = control_comment[len(keyword):].strip() return (comment, keyword, parms) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 20:57:35
|
Revision: 171 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=171&view=rev Author: matthiasmiller Date: 2008-03-20 13:57:33 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: improve test result output Modified Paths: -------------- trunk/test.py Modified: trunk/test.py =================================================================== --- trunk/test.py 2008-03-20 20:53:24 UTC (rev 170) +++ trunk/test.py 2008-03-20 20:57:33 UTC (rev 171) @@ -54,9 +54,13 @@ errors = [] if expected_warnings: - errors.append('Expected warnings: ' + str(expected_warnings)) + errors.append('Expected warnings:') + for line, warning in expected_warnings: + errors.append('\tline %i: %s' % (line+1, warning)) if unexpected_warnings: - errors.append('Unexpected warnings: ' + str(unexpected_warnings)) + errors.append('Unexpected warnings:') + for line, warning in unexpected_warnings: + errors.append('\tline %i: %s' % (line+1, warning)) if errors: raise TestError, '\n'.join(errors) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 20:53:25
|
Revision: 170 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=170&view=rev Author: matthiasmiller Date: 2008-03-20 13:53:24 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: remove syntactically invalid labels Modified Paths: -------------- trunk/tests/warnings/inc_dec_within_stmt-ignore.js trunk/tests/warnings/inc_dec_within_stmt.js Modified: trunk/tests/warnings/inc_dec_within_stmt-ignore.js =================================================================== --- trunk/tests/warnings/inc_dec_within_stmt-ignore.js 2008-03-20 20:52:15 UTC (rev 169) +++ trunk/tests/warnings/inc_dec_within_stmt-ignore.js 2008-03-20 20:53:24 UTC (rev 170) @@ -14,7 +14,6 @@ /*jsl:end*/ } while (x > 0); - Label--: /*warning:bad_label*/ do { x++; } while (x < 0); Modified: trunk/tests/warnings/inc_dec_within_stmt.js =================================================================== --- trunk/tests/warnings/inc_dec_within_stmt.js 2008-03-20 20:52:15 UTC (rev 169) +++ trunk/tests/warnings/inc_dec_within_stmt.js 2008-03-20 20:53:24 UTC (rev 170) @@ -55,7 +55,6 @@ /*jsl:end*/ } while (x > 0); - Label--: /*warning:bad_label*/ do { x++; } while (x < 0); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 20:52:22
|
Revision: 169 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=169&view=rev Author: matthiasmiller Date: 2008-03-20 13:52:15 -0700 (Thu, 20 Mar 2008) Log Message: ----------- tests: remove import-overflow.js since buffer overflows are no longer an issue Removed Paths: ------------- trunk/tests/control_comments/import-overflow.js Deleted: trunk/tests/control_comments/import-overflow.js =================================================================== --- trunk/tests/control_comments/import-overflow.js 2008-03-20 20:48:39 UTC (rev 168) +++ trunk/tests/control_comments/import-overflow.js 2008-03-20 20:52:15 UTC (rev 169) @@ -1,9 +0,0 @@ -/*jsl:option explicit*/ -function cc_import() { - -/* Test 511 bytes (arbitrary cutoff point) */ -/*jsl:import 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901*/ - -/* Test 512 bytes */ -/*jsl:import 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012*//*warning:jsl_cc_not_understood*/ -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-20 20:48:41
|
Revision: 168 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=168&view=rev Author: matthiasmiller Date: 2008-03-20 13:48:39 -0700 (Thu, 20 Mar 2008) Log Message: ----------- various fixes for Python 2.4 Modified Paths: -------------- trunk/pyjsl/conf.py trunk/pyjsl/jsparse.py trunk/pyjsl/lint.py Modified: trunk/pyjsl/conf.py =================================================================== --- trunk/pyjsl/conf.py 2008-03-04 15:15:14 UTC (rev 167) +++ trunk/pyjsl/conf.py 2008-03-20 20:48:39 UTC (rev 168) @@ -8,7 +8,7 @@ self.lineno = None self.path = None -class Setting(): +class Setting: wants_parm = False wants_dir = False @@ -48,7 +48,7 @@ parm = os.path.join(dir, parm) self.value.append((self._recurse.value, parm)) -class Conf(): +class Conf: def __init__(self): recurse = BooleanSetting(False) self._settings = { @@ -94,7 +94,8 @@ assert not '\n' in line # Allow comments - line = line.partition('#')[0] + if '#' in line: + line = line[:line.find('#')] line = line.rstrip() if not line: return Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-03-04 15:15:14 UTC (rev 167) +++ trunk/pyjsl/jsparse.py 2008-03-20 20:48:39 UTC (rev 168) @@ -12,7 +12,7 @@ ['tok.%s' % prop for prop in dir(tok)] )) -class NodePos(): +class NodePos: def __init__(self, line, col): self.line = line self.col = col @@ -29,7 +29,7 @@ def __str__(self): return '(line %i, col %i)' % (self.line+1, self.col+1) -class NodePositions(): +class NodePositions: " Given a string, allows [x] lookups for NodePos line and column numbers." def __init__(self, text): # Find the length of each line and incrementally sum all of the lengths @@ -55,7 +55,7 @@ lines[0] = lines[0][start.col:] return ''.join(lines) -class NodeRanges(): +class NodeRanges: def __init__(self): self._offsets = [] def add(self, start, end): @@ -74,7 +74,7 @@ def has(self, pos): return bisect.bisect_right(self._offsets, pos) % 2 == 1 -class _Node(): +class _Node: def add_child(self, node): if node: node.node_index = len(self.kids) Modified: trunk/pyjsl/lint.py =================================================================== --- trunk/pyjsl/lint.py 2008-03-04 15:15:14 UTC (rev 167) +++ trunk/pyjsl/lint.py 2008-03-20 20:48:39 UTC (rev 168) @@ -70,7 +70,7 @@ parms = control_comment[len(keyword):].strip() return (comment, keyword, parms) -class Scope(): +class Scope: def __init__(self, node): self._is_with_scope = node.kind == tok.WITH self._parent = None This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-04 15:15:19
|
Revision: 167 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=167&view=rev Author: matthiasmiller Date: 2008-03-04 07:15:14 -0800 (Tue, 04 Mar 2008) Log Message: ----------- pyspidermonkey: change traverse_node to jsnode_to_pynode to clarify reference counting responsibilities Modified Paths: -------------- trunk/pyjsl/jsparse.py trunk/pyspidermonkey/pyspidermonkey.c Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-03-04 03:56:49 UTC (rev 166) +++ trunk/pyjsl/jsparse.py 2008-03-04 15:15:14 UTC (rev 167) @@ -212,9 +212,7 @@ def pop(): nodes.pop() - roots = pyspidermonkey.traverse(script, _Node, _wrapped_callback) - assert len(roots) == 1 - root_node = roots[0] + root_node = pyspidermonkey.parse(script, _Node, _wrapped_callback) process(root_node) comments = _parse_comments(script, root_node, positions, comment_ignore_ranges) Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-03-04 03:56:49 UTC (rev 166) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-03-04 15:15:14 UTC (rev 167) @@ -50,14 +50,14 @@ */ static PyObject* -module_traverse(PyObject *self, PyObject *args); +module_parse(PyObject *self, PyObject *args); static PyObject* is_compilable_unit(PyObject *self, PyObject *args); static PyMethodDef module_methods[] = { - {"traverse", module_traverse, METH_VARARGS, - "Parses \"script\" and calls \"push\" and \"pop\" for each node."}, + {"parse", module_parse, METH_VARARGS, + "Parses \"script\" and returns a tree of \"node_class\"."}, {"is_compilable_unit", is_compilable_unit, METH_VARARGS, "Returns True if \"script\" is a compilable unit."}, @@ -160,8 +160,8 @@ } /* returns 0 on success and -1 on failure */ -static int -traverse_node(JSContext* context, JSParseNode* jsnode, PyObject* parent, PyObject* tuple, int node_offset) { +static PyObject* +jsnode_to_pynode(JSContext* context, JSParseNode* jsnode) { JSContextData* data = JS_GetContextPrivate(context); PyObject* pynode = NULL; PyObject* kids = NULL; @@ -170,8 +170,7 @@ if (!jsnode) { Py_INCREF(Py_None); - PyTuple_SET_ITEM(tuple, node_offset, Py_None); - return 0; + return Py_None; } /* pass in a dictionary of options */ @@ -179,15 +178,14 @@ if (!pynode) goto fail; - PyTuple_SET_ITEM(tuple, node_offset, pynode); - - Py_INCREF(parent); - if (PyObject_SetAttrString(pynode, "parent", parent) == -1) + Py_INCREF(Py_None); + if (PyObject_SetAttrString(pynode, "parent", Py_None) == -1) goto fail; + Py_INCREF(Py_None); + if (PyObject_SetAttrString(pynode, "node_index", Py_None) == -1) + goto fail; if (PyObject_SetAttrString(pynode, "kind", Py_BuildValue("i", TOK_TO_NUM(jsnode->pn_type))) == -1) goto fail; - if (PyObject_SetAttrString(pynode, "node_index", Py_BuildValue("i", node_offset)) == -1) - goto fail; /* pass the position */ if (PyObject_SetAttrString(pynode, "_start_line", Py_BuildValue("i", jsnode->pn_pos.begin.lineno-1)) == -1) @@ -274,8 +272,7 @@ switch (jsnode->pn_arity) { case PN_FUNC: kids = PyTuple_New(1); - if (traverse_node(context, jsnode->pn_body, pynode, kids, 0) == -1) - return -1; + PyTuple_SET_ITEM(kids, 0, jsnode_to_pynode(context, jsnode->pn_body)); break; case PN_LIST: { @@ -283,40 +280,32 @@ int i; kids = PyTuple_New(jsnode->pn_count); for (i = 0, p = jsnode->pn_head; p; p = p->pn_next, i++) { - if (traverse_node(context, p, pynode, kids, i) == -1) - return -1; + PyTuple_SET_ITEM(kids, i, jsnode_to_pynode(context, p)); } } break; case PN_TERNARY: kids = PyTuple_New(3); - if (traverse_node(context, jsnode->pn_kid1, pynode, kids, 0) == -1) - return -1; - if (traverse_node(context, jsnode->pn_kid2, pynode, kids, 1) == -1) - return -1; - if (traverse_node(context, jsnode->pn_kid3, pynode, kids, 2) == -1) - return -1; + PyTuple_SET_ITEM(kids, 0, jsnode_to_pynode(context, jsnode->pn_kid1)); + PyTuple_SET_ITEM(kids, 1, jsnode_to_pynode(context, jsnode->pn_kid2)); + PyTuple_SET_ITEM(kids, 2, jsnode_to_pynode(context, jsnode->pn_kid3)); break; case PN_BINARY: kids = PyTuple_New(2); - if (traverse_node(context, jsnode->pn_left, pynode, kids, 0) == -1) - return -1; - if (traverse_node(context, jsnode->pn_right, pynode, kids, 1) == -1) - return -1; + PyTuple_SET_ITEM(kids, 0, jsnode_to_pynode(context, jsnode->pn_left)); + PyTuple_SET_ITEM(kids, 1, jsnode_to_pynode(context, jsnode->pn_right)); break; case PN_UNARY: kids = PyTuple_New(1); - if (traverse_node(context, jsnode->pn_kid, pynode, kids, 0) == -1) - return -1; + PyTuple_SET_ITEM(kids, 0, jsnode_to_pynode(context, jsnode->pn_kid)); break; case PN_NAME: kids = PyTuple_New(1); - if (traverse_node(context, jsnode->pn_expr, pynode, kids, 0) == -1) - return -1; + PyTuple_SET_ITEM(kids, 0, jsnode_to_pynode(context, jsnode->pn_expr)); break; case PN_NULLARY: @@ -324,23 +313,43 @@ break; } + if (!kids) + goto fail; + if (PyObject_SetAttrString(pynode, "kids", kids) == -1) goto fail; - return 0; + { + int i; + for (i = 0; i < PyTuple_GET_SIZE(kids); i++) { + PyObject* kid = PyTuple_GET_ITEM(kids, i); + if (!kid) + goto fail; + if (kid == Py_None) + continue; + Py_INCREF(pynode); + if (PyObject_SetAttrString(kid, "parent", pynode) == -1) + goto fail; + if (PyObject_SetAttrString(kid, "node_index", Py_BuildValue("i", i)) == -1) + goto fail; + } + } + + return pynode; + fail: if (pynode) { Py_XDECREF(pynode); } - return -1; + return NULL; } static PyObject* -module_traverse(PyObject *self, PyObject *args) { +module_parse(PyObject *self, PyObject *args) { struct { const char* script; - PyObject* kids; + PyObject* pynode; JSRuntime* runtime; JSContext* context; @@ -414,8 +423,8 @@ goto cleanup; } - m.kids = PyTuple_New(1); - if (traverse_node(m.context, m.jsnode, Py_None, m.kids, 0) == -1) { + m.pynode = jsnode_to_pynode(m.context, m.jsnode); + if (!m.pynode) { error = ""; goto cleanup; } @@ -434,8 +443,7 @@ } return NULL; } - Py_INCREF(m.kids); - return m.kids; + return m.pynode; } static PyObject* This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-04 03:56:51
|
Revision: 166 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=166&view=rev Author: matthiasmiller Date: 2008-03-03 19:56:49 -0800 (Mon, 03 Mar 2008) Log Message: ----------- fix several gcc warnings Modified Paths: -------------- trunk/pyspidermonkey/pyspidermonkey.c Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-03-04 03:53:55 UTC (rev 165) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-03-04 03:56:49 UTC (rev 166) @@ -66,7 +66,7 @@ }; PyMODINIT_FUNC -initpyspidermonkey() { +initpyspidermonkey(void) { PyObject* module; PyObject* class; PyObject* tok; @@ -109,7 +109,7 @@ } PyMODINIT_FUNC -initpyspidermonkey_d() { +initpyspidermonkey_d(void) { initpyspidermonkey(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-04 03:53:57
|
Revision: 165 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=165&view=rev Author: matthiasmiller Date: 2008-03-03 19:53:55 -0800 (Mon, 03 Mar 2008) Log Message: ----------- fix warnings in setup.py when py2exe isn't installed Modified Paths: -------------- trunk/setup.py Modified: trunk/setup.py =================================================================== --- trunk/setup.py 2008-03-04 03:42:17 UTC (rev 164) +++ trunk/setup.py 2008-03-04 03:53:55 UTC (rev 165) @@ -2,11 +2,6 @@ from distutils.core import setup, Extension import os -try: - import py2exe -except ImportError: - pass - # Add the bin directory to the module search path def get_lib_path(): import distutils.dist @@ -28,21 +23,30 @@ libraries = [library], sources = ['pyspidermonkey/pyspidermonkey.c'] ) - setup( + args = {} + args.update( name = 'pyjsl', version = '1.0', author = 'Matthias Miller', author_email = 'in...@ja...', url = 'http://www.javascriptlint.com/', - console = ['jsl.py'], description = 'JavaScript Lint', - ext_modules = [pyspidermonkey], - options = { - 'py2exe': { - 'excludes': 'setup', - 'bundle_files': 1 - } - }, - zipfile = None + ext_modules = [pyspidermonkey] ) + try: + import py2exe + except ImportError: + pass + else: + args.update( + console = ['jsl.py'], + options = { + 'py2exe': { + 'excludes': 'setup', + 'bundle_files': 1 + } + }, + zipfile = None + ) + setup(**args) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-04 03:44:14
|
Revision: 164 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=164&view=rev Author: matthiasmiller Date: 2008-03-03 19:42:17 -0800 (Mon, 03 Mar 2008) Log Message: ----------- provide an interface to SpiderMonkey to determine if a script is a compilable unit Modified Paths: -------------- trunk/pyjsl/jsparse.py trunk/pyspidermonkey/pyspidermonkey.c Modified: trunk/pyjsl/jsparse.py =================================================================== --- trunk/pyjsl/jsparse.py 2008-03-04 03:37:22 UTC (rev 163) +++ trunk/pyjsl/jsparse.py 2008-03-04 03:42:17 UTC (rev 164) @@ -306,14 +306,29 @@ r = NodeRanges() r.add(5, 10) r.add(15, 15) - assert not r.has(4) - assert r.has(5) - assert r.has(6) - assert r.has(9) - assert r.has(10) - assert not r.has(14) - assert r.has(15) - assert not r.has(16) + assert not r.has(4) + assert r.has(5) + assert r.has(6) + assert r.has(9) + assert r.has(10) + assert not r.has(14) + assert r.has(15) + assert not r.has(16) + +class TestCompilableUnit(unittest.TestCase): + def test(self): + tests = ( + ('var s = "', False), + ('bogon()', True), + ('int syntax_error;', True), + ('a /* b', False), + ('re = /.*', False), + ('{ // missing curly', False) + ) + for text, is_compilable_unit in tests: + self.assertEquals(pyspidermonkey.is_compilable_unit(text), + is_compilable_unit) + if __name__ == '__main__': unittest.main() Modified: trunk/pyspidermonkey/pyspidermonkey.c =================================================================== --- trunk/pyspidermonkey/pyspidermonkey.c 2008-03-04 03:37:22 UTC (rev 163) +++ trunk/pyspidermonkey/pyspidermonkey.c 2008-03-04 03:42:17 UTC (rev 164) @@ -52,10 +52,16 @@ static PyObject* module_traverse(PyObject *self, PyObject *args); +static PyObject* +is_compilable_unit(PyObject *self, PyObject *args); + static PyMethodDef module_methods[] = { {"traverse", module_traverse, METH_VARARGS, "Parses \"script\" and calls \"push\" and \"pop\" for each node."}, + {"is_compilable_unit", is_compilable_unit, METH_VARARGS, + "Returns True if \"script\" is a compilable unit."}, + {NULL, NULL, 0, NULL} /* Sentinel */ }; @@ -432,3 +438,67 @@ return m.kids; } +static PyObject* +is_compilable_unit(PyObject *self, PyObject *args) { + struct { + const char* script; + JSRuntime* runtime; + JSContext* context; + JSObject* global; + JSBool is_compilable; + } m; + const char* error; + + memset(&m, 0, sizeof(m)); + error = "encountered an unknown error"; + + if (!PyArg_ParseTuple(args, "s", &m.script)) + return NULL; + + m.runtime = JS_NewRuntime(8L * 1024L * 1024L); + if (m.runtime == NULL) { + error = "cannot create runtime"; + goto cleanup; + } + + m.context = JS_NewContext(m.runtime, 8192); + if (m.context == NULL) { + error = "cannot create context"; + goto cleanup; + } + + m.global = JS_NewObject(m.context, NULL, NULL, NULL); + if (m.global == NULL) { + error = "cannot create global object"; + goto cleanup; + } + + if (!JS_InitStandardClasses(m.context, m.global)) { + error = "cannot initialize standard classes"; + goto cleanup; + } + + m.is_compilable = JS_BufferIsCompilableUnit(m.context, m.global, + m.script, strlen(m.script)); + error = NULL; + +cleanup: + if (m.context) + JS_DestroyContext(m.context); + if (m.runtime) + JS_DestroyRuntime(m.runtime); + + if (error) { + PyErr_SetString(PyExc_StandardError, error); + return NULL; + } + if (m.is_compilable) { + Py_INCREF(Py_True); + return Py_True; + } + else { + Py_INCREF(Py_False); + return Py_False; + } +} + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mat...@us...> - 2008-03-04 03:40:13
|
Revision: 163 http://javascriptlint.svn.sourceforge.net/javascriptlint/?rev=163&view=rev Author: matthiasmiller Date: 2008-03-03 19:37:22 -0800 (Mon, 03 Mar 2008) Log Message: ----------- fix pyjsl.jsparse imports Modified Paths: -------------- trunk/jsl.py Modified: trunk/jsl.py =================================================================== --- trunk/jsl.py 2008-03-04 03:10:46 UTC (rev 162) +++ trunk/jsl.py 2008-03-04 03:37:22 UTC (rev 163) @@ -14,7 +14,7 @@ sys.path.append(setup.get_lib_path()) import pyjsl.conf -import pyjsl.parse +import pyjsl.jsparse import pyjsl.util import test @@ -52,7 +52,7 @@ def _dump(paths): for path in paths: script = pyjsl.util.readfile(path) - pyjsl.parse.dump_tree(script) + pyjsl.jsparse.dump_tree(script) def _lint(paths, conf): def lint_error(path, line, col, errname): @@ -124,7 +124,7 @@ if opt in ('-t', '--test'): profile_func(run_tests) if opt in ('--unittest',): - unittest.main(pyjsl.parse, argv=sys.argv[:1]) + unittest.main(pyjsl.jsparse, argv=sys.argv[:1]) if opt in ('--profile',): profile_func = profile_enabled if opt in ('--conf',): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |