javascriptlint-commit Mailing List for JavaScript Lint (Page 3)
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...> - 2013-10-09 20:21:35
|
Revision: 337
http://sourceforge.net/p/javascriptlint/code/337
Author: matthiasmiller
Date: 2013-10-09 20:21:32 +0000 (Wed, 09 Oct 2013)
Log Message:
-----------
Attempt to simplify token definitions.
Modified Paths:
--------------
trunk/jsengine/tokenizer/__init__.py
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-10-09 19:41:02 UTC (rev 336)
+++ trunk/jsengine/tokenizer/__init__.py 2013-10-09 20:21:32 UTC (rev 337)
@@ -10,139 +10,131 @@
u'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
u'$_'
-_PUNCTUATORS = {
- "<<<=": "ASSIGN_ULSHIFT",
- ">>>=": "ASSIGN_URSHIFT",
- "===": "EQ_STRICT",
- "!==": "NE_STRICT",
- ">>>": "URSHIFT",
- "<<=": "ASSIGN_LSHIFT",
- ">>=": "ASSIGN_RSHIFT",
- "<=": "LE",
- ">=": "GE",
- "==": "EQ",
- "!=": "NE",
- "++": "INC",
- "--": "DEC",
- "<<": "LSHIFT",
- ">>": "RSHIFT",
- "&&": "LOGICAL_AND",
- "||": "LOGICAL_OR",
- "+=": "ASSIGN_ADD",
- "-=": "ASSIGN_SUB",
- "*=": "ASSIGN_MUL",
- "%=": "ASSIGN_MOD",
- "&=": "ASSIGN_BIT_AND",
- "|=": "ASSIGN_BIT_OR",
- "^=": "ASSIGN_BIT_XOR",
- "/=": "ASSIGN_DIV",
- "{": "LBRACE",
- "}": "RBRACE",
- "(": "LPAREN",
- ")": "RPAREN",
- "[": "LBRACKET",
- "]": "RBRACKET",
- ".": "DOT",
- ";": "SEMI",
- ",": "COMMA",
- "<": "LT",
- ">": "GT",
- "+": "ADD",
- "-": "SUB",
- "*": "MUL",
- "%": "MOD",
- "|": "BIT_OR",
- "&": "BIT_AND",
- "^": "BIT_XOR",
- "!": "LOGICAL_NOT",
- "~": "BIT_NOT",
- "?": "QUESTION",
- ":": "COLON",
- "=": "ASSIGN",
- "/": "DIV",
- "!": "LOGICAL_NOT",
-}
+_ALL_TOKENS = []
-_KEYWORDS = dict((keyword, keyword.upper()) for keyword in [
- 'break',
- 'case',
- 'catch',
- 'continue',
- 'default',
- 'delete',
- 'do',
- 'else',
- 'false',
- 'finally',
- 'for',
- 'function',
- 'if',
- 'in',
- 'instanceof',
- 'new',
- 'null',
- 'return',
- 'switch',
- 'this',
- 'throw',
- 'true',
- 'typeof',
- 'try',
- 'var',
- 'void',
- 'while',
- 'with',
-])
+class _Token(object):
+ def __init__(self, category, literal):
+ self._category = category
+ self._literal = literal
+ _ALL_TOKENS.append(self)
-_TOKENS = [
- 'C_COMMENT',
- 'CPP_COMMENT',
- 'HTML_COMMENT',
- 'ERROR',
- 'EOF',
- 'EOL',
- 'NAME',
- 'NUMBER',
- 'OPERATOR',
- 'REGEXP',
- 'SPACE',
- 'STRING',
-]
+ def __repr__(self):
+ return '_Token(%r, %r)' % (self._category, self._literal)
-class _Token(object):
- def __init__(self, name):
- self._name = name
+ @property
+ def category(self):
+ return self._category
- def __eq__(self, other):
- assert isinstance(other, _Token)
- return self is other
+ @property
+ def literal(self):
+ return self._literal
- def __repr__(self):
- return 'tok.%s' % self._name
-
-class _Tokens:
+class _Tokens(object):
def __init__(self):
- for token in _TOKENS:
- setattr(self, token, _Token(token))
+ # Load symbols
+ self.ASSIGN_ULSHIFT = _Token('sym', '<<<=')
+ self.ASSIGN_URSHIFT = _Token('sym', '>>>=')
+ self.EQ_STRICT = _Token('sym', '===')
+ self.NE_STRICT = _Token('sym', '!==')
+ self.URSHIFT = _Token('sym', '>>>')
+ self.ASSIGN_LSHIFT = _Token('sym', '<<=')
+ self.ASSIGN_RSHIFT = _Token('sym', '>>=')
+ self.LE = _Token('sym', '<=')
+ self.GE = _Token('sym', '>=')
+ self.EQ = _Token('sym', '==')
+ self.NE = _Token('sym', '!=')
+ self.INC = _Token('sym', '++')
+ self.DEC = _Token('sym', '--')
+ self.LSHIFT = _Token('sym', '<<')
+ self.RSHIFT = _Token('sym', '>>')
+ self.LOGICAL_AND = _Token('sym', '&&')
+ self.LOGICAL_OR = _Token('sym', '||')
+ self.ASSIGN_ADD = _Token('sym', '+=')
+ self.ASSIGN_SUB = _Token('sym', '-=')
+ self.ASSIGN_MUL = _Token('sym', '*=')
+ self.ASSIGN_MOD = _Token('sym', '%=')
+ self.ASSIGN_BIT_AND = _Token('sym', '&=')
+ self.ASSIGN_BIT_OR = _Token('sym', '|=')
+ self.ASSIGN_BIT_XOR = _Token('sym', '^=')
+ self.ASSIGN_DIV = _Token('sym', '/=')
+ self.LBRACE = _Token('sym', '{')
+ self.RBRACE = _Token('sym', '}')
+ self.LPAREN = _Token('sym', '(')
+ self.RPAREN = _Token('sym', ')')
+ self.LBRACKET = _Token('sym', '[')
+ self.RBRACKET = _Token('sym', ']')
+ self.DOT = _Token('sym', '.')
+ self.SEMI = _Token('sym', ';')
+ self.COMMA = _Token('sym', ',')
+ self.LT = _Token('sym', '<')
+ self.GT = _Token('sym', '>')
+ self.ADD = _Token('sym', '+')
+ self.SUB = _Token('sym', '-')
+ self.MUL = _Token('sym', '*')
+ self.MOD = _Token('sym', '%')
+ self.BIT_OR = _Token('sym', '|')
+ self.BIT_AND = _Token('sym', '&')
+ self.BIT_XOR = _Token('sym', '^')
+ self.LOGICAL_NOT = _Token('sym', '!')
+ self.BIT_NOT = _Token('sym', '~')
+ self.QUESTION = _Token('sym', '?')
+ self.COLON = _Token('sym', ':')
+ self.ASSIGN = _Token('sym', '=')
+ self.DIV = _Token('sym', '/')
- for key, name in list(_KEYWORDS.items()):
- _KEYWORDS[key] = _Token(name)
- setattr(self, name, _KEYWORDS[key])
+ # Load keywords
+ self.BREAK = _Token('kw', 'break')
+ self.CASE = _Token('kw', 'case')
+ self.CATCH = _Token('kw', 'catch')
+ self.CONTINUE = _Token('kw', 'continue')
+ self.DEFAULT = _Token('kw', 'default')
+ self.DELETE = _Token('kw', 'delete')
+ self.DO = _Token('kw', 'do')
+ self.ELSE = _Token('kw', 'else')
+ self.FALSE = _Token('kw', 'false')
+ self.FINALLY = _Token('kw', 'finally')
+ self.FOR = _Token('kw', 'for')
+ self.FUNCTION = _Token('kw', 'function')
+ self.IF = _Token('kw', 'if')
+ self.IN = _Token('kw', 'in')
+ self.INSTANCEOF = _Token('kw', 'instanceof')
+ self.NEW = _Token('kw', 'new')
+ self.NULL = _Token('kw', 'null')
+ self.RETURN = _Token('kw', 'return')
+ self.SWITCH = _Token('kw', 'switch')
+ self.THIS = _Token('kw', 'this')
+ self.THROW = _Token('kw', 'throw')
+ self.TRUE = _Token('kw', 'true')
+ self.TYPEOF = _Token('kw', 'typeof')
+ self.TRY = _Token('kw', 'try')
+ self.VAR = _Token('kw', 'var')
+ self.VOID = _Token('kw', 'void')
+ self.WHILE = _Token('kw', 'while')
+ self.WITH = _Token('kw', 'with')
- for key, name in list(_PUNCTUATORS.items()):
- _PUNCTUATORS[key] = _Token(name)
- setattr(self, name, _PUNCTUATORS[key])
+ # Load other tokens
+ self.C_COMMENT = _Token('other', '/*')
+ self.CPP_COMMENT = _Token('other', '//')
+ self.HTML_COMMENT = _Token('other', '<!--')
+ self.ERROR = _Token('other', 'err')
+ self.EOF = _Token('other', 'eof')
+ self.EOL = _Token('other', 'eol')
+ self.NAME = _Token('other', '(name)')
+ self.NUMBER = _Token('other', '(num)')
+ self.OPERATOR = _Token('other', '(op)')
+ self.REGEXP = _Token('other', '(re)')
+ self.SPACE = _Token('other', '(sp)')
+ self.STRING = _Token('other', '(str)')
tok = _Tokens()
-
-
+_KEYWORDS = dict((t.literal, t) for t in _ALL_TOKENS if t.category == 'kw')
_PUNCTUATOR_TREE = {}
-for punctuator in _PUNCTUATORS:
+for punctuator in (t for t in _ALL_TOKENS if t.category == 'sym'):
d = _PUNCTUATOR_TREE
- for c in punctuator:
+ for c in punctuator.literal:
d = d.setdefault(c, {})
- assert not None in d
- d[None] = _PUNCTUATORS[punctuator]
+ assert not None in d, punctuator.literal
+ d[None] = punctuator
class Token:
def __init__(self, tok, atom=None):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-09 19:41:05
|
Revision: 336
http://sourceforge.net/p/javascriptlint/code/336
Author: matthiasmiller
Date: 2013-10-09 19:41:02 +0000 (Wed, 09 Oct 2013)
Log Message:
-----------
Change op.*, tok.*, and kind.* to not be derived from string.
Modified Paths:
--------------
trunk/jsengine/parser/__init__.py
trunk/jsengine/parser/_constants_kind.py
trunk/jsengine/parser/_constants_op.py
trunk/jsengine/tokenizer/__init__.py
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-10-09 13:52:50 UTC (rev 335)
+++ trunk/jsengine/parser/__init__.py 2013-10-09 19:41:02 UTC (rev 336)
@@ -785,7 +785,7 @@
elif x.tok not in (tok.LBRACE, tok.FUNCTION):
expr = _expression(t, True)
- if expr.kind == tok.NAME and t.peek().tok == tok.COLON:
+ if expr.kind == kind.NAME and t.peek().tok == tok.COLON:
t.expect(tok.COLON)
stmt = _statement(t)
return ParseNode(kind.COLON, op.NAME, expr.start_offset,
Modified: trunk/jsengine/parser/_constants_kind.py
===================================================================
--- trunk/jsengine/parser/_constants_kind.py 2013-10-09 13:52:50 UTC (rev 335)
+++ trunk/jsengine/parser/_constants_kind.py 2013-10-09 19:41:02 UTC (rev 336)
@@ -65,15 +65,22 @@
'STRING',
'YIELD', # TODO
]
-class _Kind(str):
+class _Kind(object):
+ def __init__(self, name):
+ self._name = name
+
+ def __eq__(self, other):
+ assert isinstance(other, _Kind), repr(other)
+ return self is other
+
def __repr__(self):
- return 'kind.%s' % self
+ return 'kind.%s' % self._name
class _Kinds:
def __init__(self):
for kind in _KINDS:
setattr(self, kind, _Kind(kind))
def contains(self, item):
- return isinstance(item, _Kind) and \
- getattr(self, item) is item
+ return isinstance(item, _Kind)
+
kind = _Kinds()
Modified: trunk/jsengine/parser/_constants_op.py
===================================================================
--- trunk/jsengine/parser/_constants_op.py 2013-10-09 13:52:50 UTC (rev 335)
+++ trunk/jsengine/parser/_constants_op.py 2013-10-09 19:41:02 UTC (rev 336)
@@ -70,9 +70,18 @@
'VOID',
'CALL',
]
-class _Op(str):
+class _Op(object):
+ def __init__(self, name):
+ self._name = name
+
+ def __eq__(self, other):
+ if other is None:
+ return False
+ assert isinstance(other, _Op), repr(other)
+ return self is other
+
def __repr__(self):
- return 'op.%s' % self
+ return 'op.%s' % self._name
class _Ops:
NOP = None # TODO!
@@ -80,6 +89,6 @@
for op in _OPS:
setattr(self, op, _Op(op))
def contains(self, item):
- return isinstance(item, _Op) and \
- getattr(self, item) is item
+ return isinstance(item, _Op)
+
op = _Ops()
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-10-09 13:52:50 UTC (rev 335)
+++ trunk/jsengine/tokenizer/__init__.py 2013-10-09 19:41:02 UTC (rev 336)
@@ -109,9 +109,17 @@
'STRING',
]
-class _Token(str):
- pass
+class _Token(object):
+ def __init__(self, name):
+ self._name = name
+ def __eq__(self, other):
+ assert isinstance(other, _Token)
+ return self is other
+
+ def __repr__(self):
+ return 'tok.%s' % self._name
+
class _Tokens:
def __init__(self):
for token in _TOKENS:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-09 13:52:55
|
Revision: 335
http://sourceforge.net/p/javascriptlint/code/335
Author: matthiasmiller
Date: 2013-10-09 13:52:50 +0000 (Wed, 09 Oct 2013)
Log Message:
-----------
Simplify TokenStream.
Modified Paths:
--------------
trunk/jsengine/tokenizer/__init__.py
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-10-08 16:36:44 UTC (rev 334)
+++ trunk/jsengine/tokenizer/__init__.py 2013-10-09 13:52:50 UTC (rev 335)
@@ -178,24 +178,27 @@
return self._content[self._offset - 1]
raise JSSyntaxError(self.get_offset(-1), 'unexpected_eof')
- def readif(self, len_, seq):
- s = self.peekif(len_, seq)
+ def readchrif(self, seq):
+ s = self.peekchrif(seq)
if s:
- assert len(s) == len_
- self._offset += len_
+ assert len(s) == 1
+ self._offset += 1
return s
- def peekchr(self, seq):
- if self._offset < len(self._content) and self._content[self._offset] in seq:
+ def peekchrif(self, seq):
+ if self._offset < len(self._content) and \
+ self._content[self._offset] in seq:
return self._content[self._offset]
- def peekif(self, len_, seq):
+ def readtextif(self, text):
""" Returns the string if found. Otherwise returns None.
"""
+ len_ = len(text)
if self._offset + len_ <= len(self._content):
peeked = self._content[self._offset:self._offset+len_]
- if peeked in seq:
- return peeked
+ if peeked == text:
+ self._offset += len_
+ return text
class Tokenizer:
def __init__(self, stream):
@@ -308,7 +311,7 @@
# TODO: Validate and save
while True:
- c = stream.readif(1, _IDENT)
+ c = stream.readchrif(_IDENT)
if not c:
break
@@ -326,9 +329,9 @@
if c in _WHITESPACE or c in _LINETERMINATOR:
linebreak = c in _LINETERMINATOR
while True:
- if stream.readif(1, _LINETERMINATOR):
+ if stream.readchrif(_LINETERMINATOR):
linebreak = True
- elif stream.readif(1, _WHITESPACE):
+ elif stream.readchrif(_WHITESPACE):
pass
else:
break
@@ -339,11 +342,11 @@
# COMMENTS
if c == '/':
- if stream.peekchr("/"):
- while not stream.eof() and not stream.peekif(1, _LINETERMINATOR):
+ if stream.peekchrif("/"):
+ while not stream.eof() and not stream.peekchrif(_LINETERMINATOR):
stream.readchr()
return Token(tok.CPP_COMMENT)
- if stream.peekchr("*"):
+ if stream.peekchrif("*"):
linebreak = False
while True:
if stream.eof():
@@ -351,12 +354,12 @@
c = stream.readchr()
if c in _LINETERMINATOR:
linebreak = True
- elif c == '*' and stream.readif(1, '/'):
+ elif c == '*' and stream.readchrif('/'):
return Token(tok.C_COMMENT)
return Token(tok.EOF)
elif c == '<':
- if stream.readif(3, ('!--',)):
- while not stream.eof() and not stream.peekif(1, _LINETERMINATOR):
+ if stream.readtextif('!--'):
+ while not stream.eof() and not stream.peekchrif(_LINETERMINATOR):
stream.readchr()
return Token(tok.HTML_COMMENT)
@@ -374,35 +377,35 @@
s += c
# NUMBERS
- if c in _DIGITS or (c == '.' and stream.peekchr(_DIGITS)):
+ if c in _DIGITS or (c == '.' and stream.peekchrif(_DIGITS)):
s = c # TODO
stream.watch_reads()
- if c == '0' and stream.readif(1, 'xX'):
+ if c == '0' and stream.readchrif('xX'):
# Hex
- while stream.readif(1, _HEX_DIGITS):
+ while stream.readchrif(_HEX_DIGITS):
pass
- elif c == '0' and stream.readif(1, _DIGITS):
+ elif c == '0' and stream.readchrif(_DIGITS):
# Octal
- while stream.readif(1, _DIGITS):
+ while stream.readchrif(_DIGITS):
pass
else:
# Decimal
if c != '.':
- while stream.readif(1, _DIGITS):
+ while stream.readchrif(_DIGITS):
pass
- stream.readif(1, '.')
+ stream.readchrif('.')
- while stream.readif(1, _DIGITS):
+ while stream.readchrif(_DIGITS):
pass
- if stream.readif(1, 'eE'):
- stream.readif(1, '+-')
- if not stream.readif(1, _DIGITS):
+ if stream.readchrif('eE'):
+ stream.readchrif('+-')
+ if not stream.readchrif(_DIGITS):
raise JSSyntaxError(stream.get_offset(), 'syntax_error')
- while stream.readif(1, _DIGITS):
+ while stream.readchrif(_DIGITS):
pass
- if stream.peekchr(_IDENT):
+ if stream.peekchrif(_IDENT):
return Token(tok.ERROR)
atom = s + stream.get_watched_reads()
@@ -411,7 +414,7 @@
if c in _PUNCTUATOR_TREE:
d = _PUNCTUATOR_TREE[c]
while True:
- c = stream.readif(1, list(d.keys()))
+ c = stream.readchrif(list(d.keys()))
if c:
d = d[c]
else:
@@ -426,7 +429,7 @@
s = ''
while c:
s += c
- c = stream.readif(1, _IDENT + _DIGITS)
+ c = stream.readchrif(_IDENT + _DIGITS)
if s in _KEYWORDS:
return Token(_KEYWORDS[s], atom=s)
elif s:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-08 16:36:50
|
Revision: 334
http://sourceforge.net/p/javascriptlint/code/334
Author: matthiasmiller
Date: 2013-10-08 16:36:44 +0000 (Tue, 08 Oct 2013)
Log Message:
-----------
Change the parser to only use offsets internally and to convert offsets to line/col only when reporting errors.
Modified Paths:
--------------
trunk/javascriptlint/htmlparse.py
trunk/javascriptlint/jsparse.py
trunk/javascriptlint/lint.py
trunk/javascriptlint/warnings.py
trunk/jsengine/__init__.py
trunk/jsengine/parser/__init__.py
trunk/jsengine/structs.py
trunk/jsengine/tokenizer/__init__.py
trunk/test.py
Modified: trunk/javascriptlint/htmlparse.py
===================================================================
--- trunk/javascriptlint/htmlparse.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/javascriptlint/htmlparse.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -2,18 +2,25 @@
import HTMLParser
import unittest
+from jsengine.structs import NodePos, NodePositions
+
class _Parser(HTMLParser.HTMLParser):
def __init__(self):
HTMLParser.HTMLParser.__init__(self)
self._tags = []
+ self._node_positions = None
+ def feed(self, data):
+ # Reset line numbers whenever we get data.
+ self._node_positions = None
+ HTMLParser.HTMLParser.feed(self, data)
+
def handle_starttag(self, tag, attributes):
if tag.lower() == 'script':
attr = dict(attributes)
self._tags.append({
'type': 'start',
- 'lineno': self.lineno,
- 'offset': self.offset,
+ 'offset': self._getoffset(),
'len': len(self.get_starttag_text()),
'attr': attr
})
@@ -22,8 +29,7 @@
if tag.lower() == 'script':
self._tags.append({
'type': 'end',
- 'lineno': self.lineno,
- 'offset': self.offset,
+ 'offset': self._getoffset(),
})
def unknown_decl(self, data):
@@ -33,9 +39,16 @@
def gettags(self):
return self._tags
+ def _getoffset(self):
+ # htmlparse returns 1-based line numbers. Calculate the offset of the
+ # script's contents.
+ if self._node_positions is None:
+ self._node_positions = NodePositions(self.rawdata)
+ pos = NodePos(self.lineno - 1, self.offset)
+ return self._node_positions.to_offset(pos)
+
+
def findscripttags(s):
- """ Note that the lineno is 1-based.
- """
parser = _Parser()
parser.feed(s)
parser.close()
Modified: trunk/javascriptlint/jsparse.py
===================================================================
--- trunk/javascriptlint/jsparse.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/javascriptlint/jsparse.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -16,7 +16,8 @@
return True
return jsengine.parser.is_valid_version(jsversion.version)
-def findpossiblecomments(script, node_positions):
+def findpossiblecomments(script, script_offset):
+ assert not script_offset is None
pos = 0
single_line_re = r"//[^\r\n]*"
multi_line_re = r"/\*(.*?)\*/"
@@ -41,38 +42,34 @@
start_offset = match.start()
end_offset = match.end()-1
- start_pos = node_positions.from_offset(start_offset)
- end_pos = node_positions.from_offset(end_offset)
- comment_node = ParseNode(kind.COMMENT, opcode, start_pos, end_pos,
- comment_text, [])
+ comment_node = ParseNode(kind.COMMENT, opcode,
+ script_offset + start_offset,
+ script_offset + end_offset, comment_text, [])
comments.append(comment_node)
# Start searching immediately after the start of the comment in case
# this one was within a string or a regexp.
pos = match.start()+1
-def parse(script, jsversion, error_callback, startpos=None):
- """ All node positions will be relative to startpos. This allows scripts
- to be embedded in a file (for example, HTML).
+def parse(script, jsversion, error_callback, start_offset=0):
+ """ All node positions will be relative to start_offset. This allows
+ scripts to be embedded in a file (for example, HTML).
"""
- startpos = startpos or NodePos(0, 0)
+ assert not start_offset is None
jsversion = jsversion or JSVersion.default()
assert isvalidversion(jsversion), jsversion
if jsversion.e4x:
- error_callback(startpos.line, startpos.col, 'e4x_deprecated', {})
+ error_callback(start_offset, 'e4x_deprecated', {})
return jsengine.parser.parse(script, jsversion.version,
- error_callback,
- startpos)
+ error_callback, start_offset)
-def filtercomments(possible_comments, node_positions, root_node):
+def filtercomments(possible_comments, root_node):
comment_ignore_ranges = NodeRanges()
def process(node):
if node.kind == tok.STRING or \
(node.kind == tok.OBJECT and node.opcode == op.REGEXP):
- start_offset = node_positions.to_offset(node.start_pos())
- end_offset = node_positions.to_offset(node.end_pos())
- comment_ignore_ranges.add(start_offset, end_offset)
+ comment_ignore_ranges.add(node.start_offset, node.end_offset)
for kid in node.kids:
if kid:
process(kid)
@@ -80,25 +77,22 @@
comments = []
for comment in possible_comments:
- start_offset = node_positions.to_offset(comment.start_pos())
- end_offset = node_positions.to_offset(comment.end_pos())
- if comment_ignore_ranges.has(start_offset):
+ if comment_ignore_ranges.has(comment.start_offset):
continue
- comment_ignore_ranges.add(start_offset, end_offset)
+ comment_ignore_ranges.add(comment.start_offset, comment.end_offset)
comments.append(comment)
return comments
-def findcomments(script, root_node, start_pos=None):
- node_positions = NodePositions(script, start_pos)
- possible_comments = findpossiblecomments(script, node_positions)
- return filtercomments(possible_comments, node_positions, root_node)
+def findcomments(script, root_node, start_offset=0):
+ possible_comments = findpossiblecomments(script, start_offset)
+ return filtercomments(possible_comments, root_node)
def is_compilable_unit(script, jsversion):
jsversion = jsversion or JSVersion.default()
assert isvalidversion(jsversion)
return jsengine.parser.is_compilable_unit(script, jsversion.version)
-def _dump_node(node, depth=0):
+def _dump_node(node, node_positions, depth=0):
if node is None:
print ' '*depth,
print '(None)'
@@ -107,7 +101,8 @@
print ' '*depth,
print '%s, %s' % (repr(node.kind), repr(node.opcode))
print ' '*depth,
- print '%s - %s' % (node.start_pos(), node.end_pos())
+ print '%s - %s' % (node_positions.from_offset(node.start_offset),
+ node_positions.from_offset(node.end_offset))
if hasattr(node, 'atom'):
print ' '*depth,
print 'atom: %s' % node.atom
@@ -116,13 +111,14 @@
print '(no semicolon)'
print
for node in node.kids:
- _dump_node(node, depth+1)
+ _dump_node(node, node_positions, depth+1)
def dump_tree(script):
def error_callback(line, col, msg, msg_args):
print '(%i, %i): %s', (line, col, msg)
node = parse(script, None, error_callback)
- _dump_node(node)
+ node_positions = NodePositions(script)
+ _dump_node(node, node_positions)
class TestComments(unittest.TestCase):
def _test(self, script, expected_comments):
@@ -230,42 +226,42 @@
class TestLineOffset(unittest.TestCase):
def testErrorPos(self):
- def geterror(script, startpos):
+ def geterror(script, start_offset):
errors = []
- def onerror(line, col, msg, msg_args):
- errors.append((line, col, msg, msg_args))
- parse(script, None, onerror, startpos)
+ def onerror(offset, msg, msg_args):
+ errors.append((offset, msg, msg_args))
+ parse(script, None, onerror, start_offset)
self.assertEquals(len(errors), 1)
return errors[0]
- self.assertEquals(geterror(' ?', None), (0, 1, 'syntax_error', {}))
- self.assertEquals(geterror('\n ?', None), (1, 1, 'syntax_error', {}))
- self.assertEquals(geterror(' ?', NodePos(1, 1)), (1, 2, 'syntax_error', {}))
- self.assertEquals(geterror('\n ?', NodePos(1, 1)), (2, 1, 'syntax_error', {}))
+ self.assertEquals(geterror(' ?', 0), (1, 'syntax_error', {}))
+ self.assertEquals(geterror('\n ?', 0), (2, 'syntax_error', {}))
+ self.assertEquals(geterror(' ?', 2), (3, 'syntax_error', {}))
+ self.assertEquals(geterror('\n ?', 2), (4, 'syntax_error', {}))
def testNodePos(self):
- def getnodepos(script, startpos):
- root = parse(script, None, None, startpos)
+ def getnodepos(script, start_offset):
+ root = parse(script, None, None, start_offset)
self.assertEquals(root.kind, tok.LC)
var, = root.kids
self.assertEquals(var.kind, tok.VAR)
- return var.start_pos()
- self.assertEquals(getnodepos('var x;', None), NodePos(0, 0))
- self.assertEquals(getnodepos(' var x;', None), NodePos(0, 1))
- self.assertEquals(getnodepos('\n\n var x;', None), NodePos(2, 1))
- self.assertEquals(getnodepos('var x;', NodePos(3, 4)), NodePos(3, 4))
- self.assertEquals(getnodepos(' var x;', NodePos(3, 4)), NodePos(3, 5))
- self.assertEquals(getnodepos('\n\n var x;', NodePos(3, 4)), NodePos(5, 1))
+ return var.start_offset
+ self.assertEquals(getnodepos('var x;', 0), 0)
+ self.assertEquals(getnodepos(' var x;', 0), 1)
+ self.assertEquals(getnodepos('\n\n var x;', 0), 3)
+ self.assertEquals(getnodepos('var x;', 7), 7)
+ self.assertEquals(getnodepos(' var x;', 7), 8)
+ self.assertEquals(getnodepos('\n\n var x;', 7), 10)
def testComments(self):
- def testcomment(comment, startpos, expectedpos):
+ def testcomment(comment, startpos, expected_offset):
root = parse(comment, None, None, startpos)
comment, = findcomments(comment, root, startpos)
- self.assertEquals(comment.start_pos(), expectedpos)
+ self.assertEquals(comment.start_offset, expected_offset)
for comment in ('/*comment*/', '//comment'):
- testcomment(comment, None, NodePos(0, 0))
- testcomment(' %s' % comment, None, NodePos(0, 1))
- testcomment('\n\n %s' % comment, None, NodePos(2, 1))
- testcomment('%s' % comment, NodePos(3, 4), NodePos(3, 4))
- testcomment(' %s' % comment, NodePos(3, 4), NodePos(3, 5))
- testcomment('\n\n %s' % comment, NodePos(3, 4), NodePos(5, 1))
+ testcomment(comment, 0, 0)
+ testcomment(' %s' % comment, 0, 1)
+ testcomment('\n\n %s' % comment, 0, 3)
+ testcomment('%s' % comment, 7, 7)
+ testcomment(' %s' % comment, 7, 8)
+ testcomment('\n\n %s' % comment, 7, 10)
if __name__ == '__main__':
unittest.main()
Modified: trunk/javascriptlint/lint.py
===================================================================
--- trunk/javascriptlint/lint.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/javascriptlint/lint.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -140,7 +140,7 @@
# sorted by node position.
unreferenced = [(key[0], key[1], node) for key, node
in unreferenced.items()]
- unreferenced.sort(key=lambda x: x[2].start_pos())
+ unreferenced.sort(key=lambda x: x[2].start_offset)
return {
'unreferenced': unreferenced,
@@ -214,8 +214,8 @@
# Conditionally add it to an inner scope.
assert self._node
- if (node.start_pos() >= self._node.start_pos() and \
- node.end_pos() <= self._node.end_pos()):
+ if (node.start_offset >= self._node.start_offset and \
+ node.end_offset <= self._node.end_offset):
return self
class _Script:
@@ -245,7 +245,6 @@
def _findhtmlscripts(contents, default_version):
starttag = None
- nodepos = jsparse.NodePositions(contents)
for tag in htmlparse.findscripttags(contents):
if tag['type'] == 'start':
# Ignore nested start tags.
@@ -265,13 +264,9 @@
# htmlparse returns 1-based line numbers. Calculate the
# position of the script's contents.
- tagpos = jsparse.NodePos(starttag['lineno']-1, starttag['offset'])
- tagoffset = nodepos.to_offset(tagpos)
- startoffset = tagoffset + starttag['len']
- startpos = nodepos.from_offset(startoffset)
- endpos = jsparse.NodePos(tag['lineno']-1, tag['offset'])
- endoffset = nodepos.to_offset(endpos)
- script = contents[startoffset:endoffset]
+ start_offset = starttag['offset'] + starttag['len']
+ end_offset = tag['offset']
+ script = contents[start_offset:end_offset]
if not jsparse.isvalidversion(starttag['jsversion']) or \
jsparse.is_compilable_unit(script, starttag['jsversion']):
@@ -279,7 +274,7 @@
yield {
'type': 'inline',
'jsversion': starttag['jsversion'],
- 'pos': startpos,
+ 'offset': start_offset,
'contents': script,
}
starttag = None
@@ -294,8 +289,9 @@
import_path = import_path.replace('\\', os.sep)
import_path = os.path.join(os.path.dirname(path), import_path)
return lint_file(import_path, 'js', jsversion, encoding)
- def _lint_error(*args):
- return lint_error(normpath, *args)
+ def _lint_error(offset, errname, errdesc):
+ pos = node_positions.from_offset(offset)
+ return lint_error(normpath, pos.line, pos.col, errname, errdesc)
normpath = fs.normpath(path)
if normpath in lint_cache:
@@ -307,12 +303,13 @@
try:
contents = fs.readfile(path, encoding)
except IOError, error:
- _lint_error(0, 0, 'io_error', unicode(error))
+ lint_error(normpath, 0, 0, 'io_error', unicode(error))
return lint_cache[normpath]
+ node_positions = jsparse.NodePositions(contents)
script_parts = []
if kind == 'js':
- script_parts.append((None, jsversion or conf['default-version'], contents))
+ script_parts.append((0, jsversion or conf['default-version'], contents))
elif kind == 'html':
assert jsversion is None
for script in _findhtmlscripts(contents, conf['default-version']):
@@ -324,7 +321,7 @@
other = import_script(script['src'], script['jsversion'])
lint_cache[normpath].importscript(other)
elif script['type'] == 'inline':
- script_parts.append((script['pos'], script['jsversion'],
+ script_parts.append((script['offset'], script['jsversion'],
script['contents']))
else:
assert False, 'Invalid internal script type %s' % \
@@ -343,18 +340,18 @@
else:
lint_file(path, 'js', None, encoding)
-def _lint_script_part(scriptpos, jsversion, script, script_cache, conf,
+def _lint_script_part(script_offset, jsversion, script, script_cache, conf,
ignores, report_native, report_lint, import_callback):
- def parse_error(row, col, msg, msg_args):
+ def parse_error(offset, msg, msg_args):
if not msg in ('anon_no_return_value', 'no_return_value',
'redeclared_var', 'var_hides_arg'):
- parse_errors.append((jsparse.NodePos(row, col), msg, msg_args))
+ parse_errors.append((offset, msg, msg_args))
- def report(node, errname, pos=None, **errargs):
+ def report(node, errname, offset=0, **errargs):
if errname == 'empty_statement' and node.kind == tok.LC:
for pass_ in passes:
- if pass_.start_pos() > node.start_pos() and \
- pass_.end_pos() < node.end_pos():
+ if pass_.start_offset > node.start_offset and \
+ pass_.end_offset < node.end_offset:
passes.remove(pass_)
return
@@ -363,12 +360,12 @@
# the next case/default.
assert node.kind in (tok.CASE, tok.DEFAULT)
prevnode = node.parent.kids[node.node_index-1]
- expectedfallthru = prevnode.end_pos(), node.start_pos()
+ expectedfallthru = prevnode.end_offset, node.start_offset
elif errname == 'missing_break_for_last_case':
# Find the end of the current case/default and the end of the
# switch.
assert node.parent.kind == tok.LC
- expectedfallthru = node.end_pos(), node.parent.end_pos()
+ expectedfallthru = node.end_offset, node.parent.end_offset
else:
expectedfallthru = None
@@ -377,11 +374,11 @@
for fallthru in fallthrus:
# Look for a fallthru between the end of the current case or
# default statement and the beginning of the next token.
- if fallthru.start_pos() > start and fallthru.end_pos() < end:
+ if fallthru.start_offset > start and fallthru.end_offset < end:
fallthrus.remove(fallthru)
return
- report_lint(node, errname, pos, **errargs)
+ report_lint(node, errname, offset, **errargs)
parse_errors = []
declares = []
@@ -390,8 +387,7 @@
fallthrus = []
passes = []
- node_positions = jsparse.NodePositions(script, scriptpos)
- possible_comments = jsparse.findpossiblecomments(script, node_positions)
+ possible_comments = jsparse.findpossiblecomments(script, script_offset)
# Check control comments for the correct version. It may be this comment
# isn't a valid comment (for example, it might be inside a string literal)
@@ -410,18 +406,18 @@
report(node, 'unsupported_version', version=parms)
if not jsparse.isvalidversion(jsversion):
- report_lint(jsversionnode, 'unsupported_version', scriptpos,
+ report_lint(jsversionnode, 'unsupported_version', script_offset,
version=jsversion.version)
return
- root = jsparse.parse(script, jsversion, parse_error, scriptpos)
+ root = jsparse.parse(script, jsversion, parse_error, script_offset)
if not root:
# Report errors and quit.
- for pos, msg, msg_args in parse_errors:
- report_native(pos, msg, msg_args)
+ for offset, msg, msg_args in parse_errors:
+ report_native(offset, msg, msg_args)
return
- comments = jsparse.filtercomments(possible_comments, node_positions, root)
+ comments = jsparse.filtercomments(possible_comments, root)
if jsversionnode is not None and jsversionnode not in comments:
# TODO
@@ -449,7 +445,7 @@
start_ignore = node
elif keyword == 'end':
if start_ignore:
- ignores.append((start_ignore.start_pos(), node.end_pos()))
+ ignores.append((start_ignore.start_offset, node.end_offset))
start_ignore = None
else:
report(node, 'mismatch_ctrl_comments')
@@ -471,8 +467,8 @@
# Report at the actual error of the location. Add two
# characters for the opening two characters.
if nested_comment >= 0:
- pos = node_positions.from_offset(node_positions.to_offset(comment.start_pos()) + 2 + nested_comment)
- report(comment, 'nested_comment', pos=pos)
+ offset = comment.start_offset + 2 + nested_comment
+ report(comment, 'nested_comment', offset=offset)
if comment.atom.lower().startswith('jsl:'):
report(comment, 'jsl_cc_not_understood')
elif comment.atom.startswith('@'):
@@ -481,8 +477,8 @@
report(start_ignore, 'mismatch_ctrl_comments')
# Wait to report parse errors until loading jsl:ignore directives.
- for pos, msg in parse_errors:
- report_native(pos, msg)
+ for offset, msg in parse_errors:
+ report_native(offset, msg)
# Find all visitors and convert them into "onpush" callbacks that call "report"
visitors = {
@@ -516,15 +512,15 @@
unused_scope.set_unused(name, node)
def _lint_script_parts(script_parts, script_cache, lint_error, conf, import_callback):
- def report_lint(node, errname, pos=None, **errargs):
+ def report_lint(node, errname, offset=0, **errargs):
errdesc = warnings.format_error(errname, **errargs)
- _report(pos or node.start_pos(), errname, errdesc, True)
+ _report(offset or node.start_offset, errname, errdesc, True)
- def report_native(pos, errname, errargs):
+ def report_native(offset, errname, errargs):
errdesc = warnings.format_error(errname, **errargs)
- _report(pos, errname, errdesc, False)
+ _report(offset, errname, errdesc, False)
- def _report(pos, errname, errdesc, require_key):
+ def _report(offset, errname, errdesc, require_key):
try:
if not conf[errname]:
return
@@ -533,14 +529,14 @@
raise
for start, end in ignores:
- if pos >= start and pos <= end:
+ if offset >= start and offset <= end:
return
- return lint_error(pos.line, pos.col, errname, errdesc)
+ return lint_error(offset, errname, errdesc)
- for scriptpos, jsversion, script in script_parts:
+ for script_offset, jsversion, script in script_parts:
ignores = []
- _lint_script_part(scriptpos, jsversion, script, script_cache, conf, ignores,
+ _lint_script_part(script_offset, jsversion, script, script_cache, conf, ignores,
report_native, report_lint, import_callback)
scope = script_cache.scope
@@ -576,10 +572,10 @@
# TODO: This is ugly hardcoding to improve the error positioning of
# "missing_semicolon" errors.
if visitor.warning in ('missing_semicolon', 'missing_semicolon_for_lambda'):
- pos = warning.node.end_pos()
+ offset = warning.node.end_offset
else:
- pos = None
- report(warning.node, visitor.warning, pos=pos, **warning.errargs)
+ offset = None
+ report(warning.node, visitor.warning, offset=offset, **warning.errargs)
return onpush
def _warn_or_declare(scope, name, type_, node, report):
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/javascriptlint/warnings.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -584,7 +584,7 @@
if filter(is_return_with_val, exit_points):
# If the function returns a value, find all returns without a value.
returns = filter(is_return_without_val, exit_points)
- returns.sort(key=lambda node: node.start_pos())
+ returns.sort(key=lambda node: node.start_offset)
if returns:
raise LintWarning(returns[0], name=name)
# Warn if the function sometimes exits naturally.
Modified: trunk/jsengine/__init__.py
===================================================================
--- trunk/jsengine/__init__.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/jsengine/__init__.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -10,12 +10,12 @@
)
class JSSyntaxError(BaseException):
- def __init__(self, pos, msg, msg_args=None):
+ def __init__(self, offset, msg, msg_args=None):
assert msg in _MESSAGES, msg
- self.pos = pos
+ self.offset = offset
self.msg = msg
self.msg_args = msg_args or {}
def __unicode__(self):
- return '%s: %s' % (self.pos, self.msg)
+ return '%s: %s' % (self.offset, self.msg)
def __repr__(self):
- return 'JSSyntaxError(%r, %r, %r)' % (self.pos, self.msg. self.msg_args)
+ return 'JSSyntaxError(%r, %r, %r)' % (self.offset, self.msg. self.msg_args)
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/jsengine/parser/__init__.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -22,16 +22,16 @@
"1.7",
]
-def _auto_semicolon(t, kind_, op_, startpos, endpos, atom, kids):
+def _auto_semicolon(t, kind_, op_, start_offset, end_offset, atom, kids):
nosemi = False
if t.peek_sameline().tok not in (tok.EOF, tok.EOL, tok.RBRACE):
x = t.advance()
if x.tok != tok.SEMI:
- raise JSSyntaxError(x.startpos, 'semi_before_stmnt')
- endpos = x.endpos
+ raise JSSyntaxError(x.start_offset, 'semi_before_stmnt')
+ end_offset = x.end_offset
else:
nosemi = True
- return ParseNode(kind_, op_, startpos, endpos, atom, kids, nosemi)
+ return ParseNode(kind_, op_, start_offset, end_offset, atom, kids, nosemi)
def _function_arglist(t):
fn_args = []
@@ -39,8 +39,8 @@
while True:
x = t.expect(tok.NAME)
fn_args.append(ParseNode(kind.NAME, op.ARGNAME,
- x.startpos,
- x.endpos, x.atom, []))
+ x.start_offset,
+ x.end_offset, x.atom, []))
if t.peek().tok == tok.COMMA:
t.advance()
else:
@@ -50,23 +50,23 @@
def _primary_expression(t):
x = t.next_withregexp()
if x.tok == tok.THIS:
- return ParseNode(kind.PRIMARY, op.THIS, x.startpos, x.endpos, None, [])
+ return ParseNode(kind.PRIMARY, op.THIS, x.start_offset, x.end_offset, None, [])
elif x.tok == tok.NAME:
- return ParseNode(kind.NAME, op.NAME, x.startpos, x.endpos, x.atom, [None])
+ return ParseNode(kind.NAME, op.NAME, x.start_offset, x.end_offset, x.atom, [None])
elif x.tok == tok.NULL:
- return ParseNode(kind.PRIMARY, op.NULL, x.startpos, x.endpos, None, [])
+ return ParseNode(kind.PRIMARY, op.NULL, x.start_offset, x.end_offset, None, [])
elif x.tok == tok.TRUE:
- return ParseNode(kind.PRIMARY, op.TRUE, x.startpos, x.endpos, None, [])
+ return ParseNode(kind.PRIMARY, op.TRUE, x.start_offset, x.end_offset, None, [])
elif x.tok == tok.FALSE:
- return ParseNode(kind.PRIMARY, op.FALSE, x.startpos, x.endpos, None, [])
+ return ParseNode(kind.PRIMARY, op.FALSE, x.start_offset, x.end_offset, None, [])
elif x.tok == tok.STRING:
- return ParseNode(kind.STRING, op.STRING, x.startpos, x.endpos, x.atom, [])
+ return ParseNode(kind.STRING, op.STRING, x.start_offset, x.end_offset, x.atom, [])
elif x.tok == tok.REGEXP:
- return ParseNode(kind.OBJECT, op.REGEXP, x.startpos, x.endpos, None, [])
+ return ParseNode(kind.OBJECT, op.REGEXP, x.start_offset, x.end_offset, None, [])
elif x.tok == tok.NUMBER:
- return ParseNode(kind.NUMBER, None, x.startpos, x.endpos, x.atom, [])
+ return ParseNode(kind.NUMBER, None, x.start_offset, x.end_offset, x.atom, [])
elif x.tok == tok.LBRACKET:
- startpos = x.startpos
+ start_offset = x.start_offset
items = []
end_comma = None
if t.peek().tok != tok.RBRACKET:
@@ -83,18 +83,18 @@
# Expect a comma and use it if the value was missing.
x = t.expect(tok.COMMA)
comma = ParseNode(kind.COMMA, None,
- x.startpos, x.endpos, None, [])
+ x.start_offset, x.end_offset, None, [])
items[-1] = items[-1] or comma
# Check for the end.
if t.peek().tok == tok.RBRACKET:
end_comma = comma
break
- endpos = t.expect(tok.RBRACKET).endpos
- return ParseNode(kind.RB, None, startpos, endpos, None, items,
+ end_offset = t.expect(tok.RBRACKET).end_offset
+ return ParseNode(kind.RB, None, start_offset, end_offset, None, items,
end_comma=end_comma)
elif x.tok == tok.LBRACE:
- startpos = x.startpos
+ start_offset = x.start_offset
kids = []
# TODO: get/set
end_comma = None
@@ -104,50 +104,50 @@
break
elif x.tok == tok.STRING:
t.expect(tok.STRING)
- key = ParseNode(kind.STRING, None, x.startpos,
- x.endpos, x.atom, [])
+ key = ParseNode(kind.STRING, None, x.start_offset,
+ x.end_offset, x.atom, [])
elif x.tok == tok.NUMBER:
t.expect(tok.NUMBER)
- key = ParseNode(kind.NUMBER, None, x.startpos,
- x.endpos, x.atom, [])
+ key = ParseNode(kind.NUMBER, None, x.start_offset,
+ x.end_offset, x.atom, [])
else:
x = t.expect_identifiername()
- key = ParseNode(kind.NAME, None, x.startpos, x.endpos,
+ key = ParseNode(kind.NAME, None, x.start_offset, x.end_offset,
x.atom, [])
t.expect(tok.COLON)
value = _assignment_expression(t, True)
- kids.append(ParseNode(kind.COLON, None, key.startpos,
- value.endpos, None, [key, value]))
+ kids.append(ParseNode(kind.COLON, None, key.start_offset,
+ value.end_offset, None, [key, value]))
if t.peek().tok == tok.COMMA:
x = t.advance()
end_comma = ParseNode(kind.COMMA, None,
- x.startpos, x.endpos, None, [])
+ x.start_offset, x.end_offset, None, [])
else:
end_comma = None
break
- endpos = t.expect(tok.RBRACE).endpos
- return ParseNode(kind.RC, None, startpos, endpos, None, kids,
+ end_offset = t.expect(tok.RBRACE).end_offset
+ return ParseNode(kind.RC, None, start_offset, end_offset, None, kids,
end_comma=end_comma)
elif x.tok == tok.LPAREN:
- startpos = x.startpos
+ start_offset = x.start_offset
kid = _expression(t, True)
- endpos = t.expect(tok.RPAREN).endpos
- return ParseNode(kind.RP, None, startpos, endpos, None, [kid])
+ end_offset = t.expect(tok.RPAREN).end_offset
+ return ParseNode(kind.RP, None, start_offset, end_offset, None, [kid])
else:
- raise JSSyntaxError(x.startpos, 'syntax_error')
+ raise JSSyntaxError(x.start_offset, 'syntax_error')
def _function_declaration(t, named_opcode):
node = _function_expression(t, named_opcode)
# Convert anonymous functions in expressions.
if node.opcode == op.ANONFUNOBJ:
- node = _auto_semicolon(t, kind.SEMI, None, node.startpos, node.endpos,
+ node = _auto_semicolon(t, kind.SEMI, None, node.start_offset, node.end_offset,
None, [node])
return node
def _function_expression(t, named_opcode):
- startpos = t.expect(tok.FUNCTION).startpos
+ start_offset = t.expect(tok.FUNCTION).start_offset
if t.peek().tok == tok.NAME:
fn_name = t.expect(tok.NAME).atom
opcode = named_opcode
@@ -157,12 +157,12 @@
t.expect(tok.LPAREN)
fn_args = _function_arglist(t)
t.expect(tok.RPAREN)
- fn_body_startpos = t.expect(tok.LBRACE).startpos
+ fn_body_start_offset = t.expect(tok.LBRACE).start_offset
kids = _sourceelements(t, tok.RBRACE)
- fn_body_endpos = t.expect(tok.RBRACE).endpos
- fn_body = ParseNode(kind.LC, None, fn_body_startpos,
- fn_body_endpos, None, kids)
- return ParseNode(kind.FUNCTION, opcode, startpos, fn_body.endpos,
+ fn_body_end_offset = t.expect(tok.RBRACE).end_offset
+ fn_body = ParseNode(kind.LC, None, fn_body_start_offset,
+ fn_body_end_offset, None, kids)
+ return ParseNode(kind.FUNCTION, opcode, start_offset, fn_body.end_offset,
fn_name, [fn_body], fn_args=fn_args)
def _argument_list(t):
@@ -177,17 +177,17 @@
return args
def _new_expression(t):
- startpos = t.expect(tok.NEW).startpos
+ start_offset = t.expect(tok.NEW).start_offset
expr = _member_expression(t)
# If no (), this is a variant of the NewExpression
if t.peek().tok == tok.LPAREN:
t.expect(tok.LPAREN)
args = _argument_list(t)
- endpos = t.expect(tok.RPAREN).endpos
+ end_offset = t.expect(tok.RPAREN).end_offset
else:
args = []
- endpos = expr.endpos
- return ParseNode(kind.NEW, op.NEW, startpos, endpos,
+ end_offset = expr.end_offset
+ return ParseNode(kind.NEW, op.NEW, start_offset, end_offset,
None, [expr] + args)
def _member_expression(t, _recurse=True):
@@ -203,13 +203,13 @@
if t.peek().tok == tok.LBRACKET:
t.advance()
expr = _expression(t, True)
- endpos = t.expect(tok.RBRACKET).endpos
- kid = ParseNode(kind.LB, op.GETELEM, kid.startpos, endpos,
+ end_offset = t.expect(tok.RBRACKET).end_offset
+ kid = ParseNode(kind.LB, op.GETELEM, kid.start_offset, end_offset,
None, [kid, expr])
elif t.peek().tok == tok.DOT:
t.advance()
expr = t.expect_identifiername()
- kid = ParseNode(kind.DOT, op.GETPROP, kid.startpos, expr.endpos,
+ kid = ParseNode(kind.DOT, op.GETPROP, kid.start_offset, expr.end_offset,
expr.atom, [kid])
else:
return kid
@@ -224,21 +224,21 @@
if x.tok == tok.LPAREN:
t.expect(tok.LPAREN)
args = _argument_list(t)
- endpos = t.expect(tok.RPAREN).endpos
- expr = ParseNode(kind.LP, op.CALL, expr.startpos,
- endpos, None, [expr] + args)
+ end_offset = t.expect(tok.RPAREN).end_offset
+ expr = ParseNode(kind.LP, op.CALL, expr.start_offset,
+ end_offset, None, [expr] + args)
elif x.tok == tok.LBRACKET:
t.expect(tok.LBRACKET)
lookup = _expression(t, True)
- endpos = t.expect(tok.RBRACKET).endpos
+ end_offset = t.expect(tok.RBRACKET).end_offset
expr = ParseNode(kind.LB, op.GETELEM,
- expr.startpos, endpos,
+ expr.start_offset, end_offset,
None, [expr, lookup])
elif x.tok == tok.DOT:
t.expect(tok.DOT)
lookup = t.expect_identifiername()
expr = ParseNode(kind.DOT, op.GETPROP,
- expr.startpos, lookup.endpos,
+ expr.start_offset, lookup.end_offset,
lookup.atom, [expr])
else:
return expr
@@ -251,17 +251,17 @@
def _postfix_expression(t):
kid = _lefthandside_expression(t)
if t.peek_sameline().tok == tok.INC:
- endpos = t.expect(tok.INC).endpos
+ end_offset = t.expect(tok.INC).end_offset
if kid.kind == kind.DOT and kid.opcode == op.GETPROP:
opcode = op.PROPINC
else:
opcode = op.NAMEINC
return ParseNode(kind.INC, opcode,
- kid.startpos, endpos, None, [kid])
+ kid.start_offset, end_offset, None, [kid])
elif t.peek_sameline().tok == tok.DEC:
- endpos = t.expect(tok.DEC).endpos
+ end_offset = t.expect(tok.DEC).end_offset
return ParseNode(kind.DEC, op.NAMEDEC,
- kid.startpos, endpos, None, [kid])
+ kid.start_offset, end_offset, None, [kid])
else:
return kid
@@ -280,9 +280,9 @@
x = t.peek()
if x.tok in _UNARY:
kind_, op_ = _UNARY[x.tok]
- startpos = t.advance().startpos
+ start_offset = t.advance().start_offset
kid = _unary_expression(t)
- return ParseNode(kind_, op_, startpos, kid.endpos, None, [kid])
+ return ParseNode(kind_, op_, start_offset, kid.end_offset, None, [kid])
else:
return _postfix_expression(t)
@@ -300,7 +300,7 @@
t.advance()
kids.append(child_expr_callback(t))
expr = ParseNode(kind_, op_,
- kids[0].startpos, kids[1].endpos,
+ kids[0].start_offset, kids[1].end_offset,
None, kids)
_MULTIPLICATIVE = {
@@ -359,7 +359,7 @@
t.advance()
right = _equality_expression(t, allowin)
left = ParseNode(kind.BITAND, op.BITAND,
- left.startpos, right.endpos,
+ left.start_offset, right.end_offset,
None, [left, right])
return left
@@ -369,7 +369,7 @@
t.advance()
right = _bitwise_and_expression(t, allowin)
left = ParseNode(kind.BITXOR, op.BITXOR,
- left.startpos, right.endpos,
+ left.start_offset, right.end_offset,
None, [left, right])
return left
@@ -379,7 +379,7 @@
t.advance()
right = _bitwise_xor_expression(t, allowin)
left = ParseNode(kind.BITOR, op.BITOR,
- left.startpos, right.endpos,
+ left.start_offset, right.end_offset,
None, [left, right])
return left
@@ -396,7 +396,7 @@
right = exprs.pop()
left = exprs[-1]
exprs[-1] = ParseNode(kind.AND, op.AND,
- left.startpos, right.endpos,
+ left.start_offset, right.end_offset,
None, [left, right])
return exprs[0]
@@ -413,7 +413,7 @@
right = exprs.pop()
left = exprs[-1]
exprs[-1] = ParseNode(kind.OR, op.OR,
- left.startpos, right.endpos,
+ left.start_offset, right.end_offset,
None, [left, right])
return exprs[0]
@@ -425,7 +425,7 @@
t.expect(tok.COLON)
else_ = _assignment_expression(t, allowin)
return ParseNode(kind.HOOK, None,
- kid.startpos, else_.endpos,
+ kid.start_offset, else_.end_offset,
None, [kid, if_, else_])
else:
return kid
@@ -463,12 +463,12 @@
assert kid.opcode == op.CALL
kid.opcode = op.SETCALL
else:
- raise JSSyntaxError(left.startpos, 'invalid_assign')
+ raise JSSyntaxError(left.start_offset, 'invalid_assign')
kind_, op_ = _ASSIGNS[t.peek().tok]
t.advance()
right = _assignment_expression(t, allowin)
return ParseNode(kind_, op_,
- left.startpos, right.endpos, None, [left, right])
+ left.start_offset, right.end_offset, None, [left, right])
else:
return left
@@ -479,8 +479,8 @@
t.advance()
items.append(_assignment_expression(t, allowin))
if len(items) > 1:
- return ParseNode(kind.COMMA, None, items[0].startpos,
- items[-1].endpos, None, items)
+ return ParseNode(kind.COMMA, None, items[0].start_offset,
+ items[-1].end_offset, None, items)
else:
return items[0]
@@ -493,8 +493,8 @@
t.advance()
value = _assignment_expression(t, allowin)
nodes.append(ParseNode(kind.NAME, op.SETNAME if value else op.NAME,
- x.startpos,
- value.endpos if value else x.endpos,
+ x.start_offset,
+ value.end_offset if value else x.end_offset,
x.atom, [value]))
if t.peek().tok == tok.COMMA:
@@ -504,27 +504,27 @@
def _block_statement(t):
kids = []
- startpos = t.expect(tok.LBRACE).startpos
+ start_offset = t.expect(tok.LBRACE).start_offset
while t.peek().tok != tok.RBRACE:
kids.append(_statement(t))
- endpos = t.expect(tok.RBRACE).endpos
- return ParseNode(kind.LC, None, startpos, endpos, None, kids)
+ end_offset = t.expect(tok.RBRACE).end_offset
+ return ParseNode(kind.LC, None, start_offset, end_offset, None, kids)
def _empty_statement(t):
# EMPTY STATEMENT
x = t.expect(tok.SEMI)
- return ParseNode(kind.SEMI, None, x.startpos, x.endpos, None, [None])
+ return ParseNode(kind.SEMI, None, x.start_offset, x.end_offset, None, [None])
def _var_statement(t):
# VARIABLE STATEMENT
- startpos = t.expect(tok.VAR).startpos
+ start_offset = t.expect(tok.VAR).start_offset
nodes = _variable_declaration(t, True)
return _auto_semicolon(t, kind.VAR, op.DEFVAR,
- startpos, nodes[-1].endpos, None, nodes)
+ start_offset, nodes[-1].end_offset, None, nodes)
def _if_statement(t):
# IF STATEMENT
- startpos = t.expect(tok.IF).startpos
+ start_offset = t.expect(tok.IF).start_offset
t.expect(tok.LPAREN)
condition = _expression(t, True)
t.expect(tok.RPAREN)
@@ -534,38 +534,38 @@
else_body = _statement(t)
else:
else_body = None
- endpos = else_body.endpos if else_body else if_body.endpos
- return ParseNode(kind.IF, None, startpos,
- endpos, None, [condition, if_body, else_body])
+ end_offset = else_body.end_offset if else_body else if_body.end_offset
+ return ParseNode(kind.IF, None, start_offset,
+ end_offset, None, [condition, if_body, else_body])
def _do_statement(t):
- startpos = t.expect(tok.DO).startpos
+ start_offset = t.expect(tok.DO).start_offset
code = _statement(t)
t.expect(tok.WHILE)
t.expect(tok.LPAREN)
expr = _expression(t, True)
endtoken = t.expect(tok.RPAREN)
return _auto_semicolon(t, kind.DO, None,
- startpos, endtoken.endpos, None, [code, expr])
+ start_offset, endtoken.end_offset, None, [code, expr])
def _while_statement(t):
- startpos = t.expect(tok.WHILE).startpos
+ start_offset = t.expect(tok.WHILE).start_offset
t.expect(tok.LPAREN)
expr = _expression(t, True)
t.expect(tok.RPAREN)
code = _statement(t)
return ParseNode(kind.WHILE, None,
- startpos, code.endpos, None, [expr, code])
+ start_offset, code.end_offset, None, [expr, code])
def _for_statement(t):
- for_startpos = t.expect(tok.FOR).startpos
+ for_start_offset = t.expect(tok.FOR).start_offset
t.expect(tok.LPAREN)
for_exprs = []
if t.peek().tok == tok.VAR:
- var_startpos = t.advance().startpos
+ var_start_offset = t.advance().start_offset
kids = _variable_declaration(t, False)
- vars = ParseNode(kind.VAR, op.DEFVAR, var_startpos, kids[-1].endpos,
+ vars = ParseNode(kind.VAR, op.DEFVAR, var_start_offset, kids[-1].end_offset,
None, kids)
if t.peek().tok == tok.IN:
@@ -589,8 +589,8 @@
for_exprs = [expr, None, None]
if len(for_exprs) == 2:
- condition = ParseNode(kind.IN, None, for_exprs[0].startpos,
- for_exprs[-1].endpos, None, for_exprs)
+ condition = ParseNode(kind.IN, None, for_exprs[0].start_offset,
+ for_exprs[-1].end_offset, None, for_exprs)
else:
x = t.expect(tok.SEMI)
if t.peek().tok != tok.SEMI:
@@ -605,12 +605,12 @@
body = _statement(t)
return ParseNode(kind.FOR,
op.FORIN if condition.kind == kind.IN else None,
- for_startpos, body.endpos,
+ for_start_offset, body.end_offset,
None, [condition, body])
def _continue_statement(t):
endtoken = t.expect(tok.CONTINUE)
- startpos = endtoken.startpos
+ start_offset = endtoken.start_offset
if t.peek_sameline().tok == tok.NAME:
endtoken = t.expect(tok.NAME)
@@ -618,11 +618,11 @@
else:
name = None
# TODO: Validate Scope Labels
- return _auto_semicolon(t, kind.CONTINUE, None, startpos, endtoken.endpos, name, [])
+ return _auto_semicolon(t, kind.CONTINUE, None, start_offset, endtoken.end_offset, name, [])
def _break_statement(t):
endtoken = t.expect(tok.BREAK)
- startpos = endtoken.startpos
+ start_offset = endtoken.start_offset
if t.peek_sameline().tok == tok.NAME:
endtoken = t.expect(tok.NAME)
@@ -630,11 +630,11 @@
else:
name = None
# TODO: Validate Scope Labels
- return _auto_semicolon(t, kind.BREAK, None, startpos, endtoken.endpos, name, [])
+ return _auto_semicolon(t, kind.BREAK, None, start_offset, endtoken.end_offset, name, [])
def _return_statement(t):
endtoken = t.expect(tok.RETURN)
- startpos = endtoken.startpos
+ start_offset = endtoken.start_offset
if t.peek_sameline().tok not in (tok.EOF, tok.EOL, tok.SEMI, tok.RBRACE):
expr = _expression(t, True)
@@ -642,108 +642,108 @@
else:
expr = None
# TODO: Validate Scope Labels
- return _auto_semicolon(t, kind.RETURN, None, startpos, endtoken.endpos,
+ return _auto_semicolon(t, kind.RETURN, None, start_offset, endtoken.end_offset,
None, [expr])
def _with_statement(t):
- startpos = t.expect(tok.WITH).startpos
+ start_offset = t.expect(tok.WITH).start_offset
t.expect(tok.LPAREN)
expr = _expression(t, True)
t.expect(tok.RPAREN)
body = _statement(t)
- return ParseNode(kind.WITH, None, startpos, body.endpos, None, [expr, body])
+ return ParseNode(kind.WITH, None, start_offset, body.end_offset, None, [expr, body])
def _switch_statement(t):
- switch_startpos = t.expect(tok.SWITCH).startpos
+ switch_start_offset = t.expect(tok.SWITCH).start_offset
t.expect(tok.LPAREN)
expr = _expression(t, True)
t.expect(tok.RPAREN)
- lc_startpos = t.expect(tok.LBRACE).startpos
+ lc_start_offset = t.expect(tok.LBRACE).start_offset
cases = []
while t.peek().tok != tok.RBRACE:
case_kind = None
case_expr = None
if t.peek().tok == tok.CASE:
- case_startpos = t.advance().startpos
+ case_start_offset = t.advance().start_offset
case_kind = kind.CASE
case_expr = _expression(t, True)
elif t.peek().tok == tok.DEFAULT:
- case_startpos = t.advance().startpos
+ case_start_offset = t.advance().start_offset
case_kind = kind.DEFAULT
else:
- raise JSSyntaxError(t.peek().startpos, 'invalid_case')
+ raise JSSyntaxError(t.peek().start_offset, 'invalid_case')
- case_endpos = t.expect(tok.COLON).endpos
+ case_end_offset = t.expect(tok.COLON).end_offset
statements = []
while t.peek().tok not in (tok.DEFAULT, tok.CASE, tok.RBRACE):
statements.append(_statement(t))
if statements:
- statements_startpos = statements[0].startpos
- statements_endpos = statements[-1].endpos
- case_endpos = statements[-1].endpos
+ statements_start_offset = statements[0].start_offset
+ statements_end_offset = statements[-1].end_offset
+ case_end_offset = statements[-1].end_offset
else:
- statements_startpos = case_endpos
- statements_endpos = case_endpos
+ statements_start_offset = case_end_offset
+ statements_end_offset = case_end_offset
- cases.append(ParseNode(case_kind, None, case_startpos, case_endpos,
+ cases.append(ParseNode(case_kind, None, case_start_offset, case_end_offset,
None, [
case_expr,
- ParseNode(kind.LC, None, statements_startpos,
- statements_endpos, None, statements)
+ ParseNode(kind.LC, None, statements_start_offset,
+ statements_end_offset, None, statements)
]))
- rc_endpos = t.expect(tok.RBRACE).endpos
- return ParseNode(kind.SWITCH, None, switch_startpos, rc_endpos,
+ rc_end_offset = t.expect(tok.RBRACE).end_offset
+ return ParseNode(kind.SWITCH, None, switch_start_offset, rc_end_offset,
None, [expr,
- ParseNode(kind.LC, None, lc_startpos, rc_endpos, None, cases)])
+ ParseNode(kind.LC, None, lc_start_offset, rc_end_offset, None, cases)])
def _throw_statement(t):
# TODO: Validate Scope
- startpos = t.expect(tok.THROW).startpos
+ start_offset = t.expect(tok.THROW).start_offset
if t.peek_sameline().tok == tok.EOL:
- raise JSSyntaxError(t.peek_sameline().startpos, 'expected_statement')
+ raise JSSyntaxError(t.peek_sameline().start_offset, 'expected_statement')
expr = _expression(t, True)
- return _auto_semicolon(t, kind.THROW, op.THROW, startpos, expr.endpos,
+ return _auto_semicolon(t, kind.THROW, op.THROW, start_offset, expr.end_offset,
None, [expr])
def _try_statement(t):
- try_startpos = t.expect(tok.TRY).startpos
+ try_start_offset = t.expect(tok.TRY).start_offset
try_node = _block_statement(t)
catch_node = None
finally_node = None
- try_endpos = None
+ try_end_offset = None
if t.peek().tok == tok.CATCH:
- catch_startpos = t.advance().startpos
+ catch_start_offset = t.advance().start_offset
t.expect(tok.LPAREN)
x = t.expect(tok.NAME)
- catch_expr = ParseNode(kind.NAME, None, x.startpos, x.endpos,
+ catch_expr = ParseNode(kind.NAME, None, x.start_offset, x.end_offset,
x.atom, [None])
t.expect(tok.RPAREN)
catch_block = _block_statement(t)
- catch_endpos = catch_block.endpos
+ catch_end_offset = catch_block.end_offset
catch_node = \
ParseNode(kind.RESERVED, None, None, None, None, [
ParseNode(kind.LEXICALSCOPE, op.LEAVEBLOCK,
- catch_startpos, catch_endpos, None, [
- ParseNode(kind.CATCH, None, catch_startpos,
- catch_endpos, None,
+ catch_start_offset, catch_end_offset, None, [
+ ParseNode(kind.CATCH, None, catch_start_offset,
+ catch_end_offset, None,
[catch_expr, None, catch_block])
])
])
- try_endpos = catch_endpos
+ try_end_offset = catch_end_offset
if t.peek().tok == tok.FINALLY:
t.advance()
finally_node = _block_statement(t)
- try_endpos = finally_node.endpos
+ try_end_offset = finally_node.end_offset
if not catch_node and not finally_node:
- raise JSSyntaxError(try_endpos, 'invalid_catch')
+ raise JSSyntaxError(try_end_offset, 'invalid_catch')
- return ParseNode(kind.TRY, None, try_startpos, try_endpos,
+ return ParseNode(kind.TRY, None, try_start_offset, try_end_offset,
None,
[try_node, catch_node, finally_node])
@@ -779,7 +779,7 @@
elif x.tok == tok.TRY:
return _try_statement(t)
elif x.tok == tok.EOF:
- raise JSSyntaxError(x.startpos, 'unexpected_eof')
+ raise JSSyntaxError(x.start_offset, 'unexpected_eof')
elif x.tok == tok.FUNCTION:
return _function_declaration(t, op.CLOSURE) #TODO: warn, since this is not reliable
@@ -788,13 +788,13 @@
if expr.kind == tok.NAME and t.peek().tok == tok.COLON:
t.expect(tok.COLON)
stmt = _statement(t)
- return ParseNode(kind.COLON, op.NAME, expr.startpos,
- stmt.endpos, expr.atom, [stmt])
+ return ParseNode(kind.COLON, op.NAME, expr.start_offset,
+ stmt.end_offset, expr.atom, [stmt])
- return _auto_semicolon(t, kind.SEMI, None, expr.startpos, expr.endpos,
+ return _auto_semicolon(t, kind.SEMI, None, expr.start_offset, expr.end_offset,
None, [expr])
else:
- raise JSSyntaxError(x.startpos, 'syntax_error')
+ raise JSSyntaxError(x.start_offset, 'syntax_error')
def _sourceelements(t, end_tok):
nodes = []
@@ -807,13 +807,14 @@
else:
nodes.append(_statement(t))
-def parsestring(s, startpos=None):
- stream = tokenizer.TokenStream(s, startpos)
+def parsestring(s, start_offset=0):
+ assert not start_offset is None
+ stream = tokenizer.TokenStream(s, start_offset)
t = tokenizer.Tokenizer(stream)
nodes = _sourceelements(t, tok.EOF)
- lc_endpos = t.expect(tok.EOF).endpos
- lc_startpos = nodes[-1].startpos if nodes else lc_endpos
- return ParseNode(kind.LC, None, lc_startpos, lc_endpos, None, nodes)
+ lc_end_offset = t.expect(tok.EOF).end_offset
+ lc_start_offset = nodes[-1].start_offset if nodes else lc_end_offset
+ return ParseNode(kind.LC, None, lc_start_offset, lc_end_offset, None, nodes)
def is_valid_version(version):
return version in _VERSIONS
@@ -824,14 +825,13 @@
assert kid.parent is node
_validate(kid, depth+1)
-def parse(script, jsversion,
- error_callback, startpos):
+def parse(script, jsversion, error_callback, start_offset):
# TODO: respect version
assert is_valid_version(jsversion)
try:
- root = parsestring(script, startpos)
+ root = parsestring(script, start_offset)
except JSSyntaxError as error:
- error_callback(error.pos.line, error.pos.col, error.msg, error.msg_args)
+ error_callback(error.offset, error.msg, error.msg_args)
return None
_validate(root)
return root
@@ -868,8 +868,8 @@
self.assertEquals(right.kind, kind.RC)
node = right.end_comma
self.assertEquals(node.kind, tok.COMMA)
- self.assertEquals(node.startpos, NodePos(0, 6))
- self.assertEquals(node.endpos, NodePos(0, 6))
+ self.assertEquals(node.start_offset, NodePos(0, 6))
+ self.assertEquals(node.end_offset, NodePos(0, 6))
def _testArrayEndComma(self, script, col):
root = parsestring(script)
node, = root.kids
@@ -885,8 +885,8 @@
self.assert_(node is None)
else:
self.assertEquals(node.kind, tok.COMMA)
- self.assertEquals(node.startpos, NodePos(0, col))
- self.assertEquals(node.endpos, NodePos(0, col))
+ self.assertEquals(node.start_offset, NodePos(0, col))
+ self.assertEquals(node.end_offset, NodePos(0, col))
def testArrayEndComma(self):
self._testArrayEndComma('a=[,]', 3)
self._testArrayEndComma('a=[a,]', 4)
Modified: trunk/jsengine/structs.py
===================================================================
--- trunk/jsengine/structs.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/jsengine/structs.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -90,26 +90,27 @@
class ParseNode:
node_index = None
parent = None
- def __init__(self, kind_, op_, start_pos, end_pos, atom, kids,
+ def __init__(self, kind_, op_, start_offset, end_offset, atom, kids,
no_semi=False, end_comma=None, fn_args=None):
assert not kids is None
assert kind.contains(kind_)
assert op_ is None or op.contains(op_)
if kind_ == kind.RESERVED:
- assert start_pos is None
- assert end_pos is None
+ assert start_offset is None
+ assert end_offset is None
else:
- assert isinstance(start_pos, NodePos), repr(start_pos)
- assert isinstance(end_pos, NodePos), repr(end_pos)
+ assert isinstance(start_offset, int), repr(start_offset)
+ assert isinstance(end_offset, int), repr(end_offset)
assert end_comma is None or isinstance(end_comma, ParseNode)
- assert (start_pos is None and end_pos is None) or start_pos <= end_pos
+ assert (start_offset is None and end_offset is None) or start_offset <= end_offset, \
+ (start_offset, end_offset)
self.kind = kind_
self.opcode = op_
self.atom = atom
self.kids = kids
self._lefthandside = False
- self.startpos = start_pos
- self.endpos = end_pos
+ self.start_offset = start_offset
+ self.end_offset = end_offset
self.no_semi = no_semi
self.end_comma = end_comma
@@ -132,11 +133,6 @@
else:
self.dval = float(self.atom)
- def start_pos(self):
- return self.startpos
- def end_pos(self):
- return self.endpos
-
def is_equivalent(self, other, are_functions_equiv=False):
if not other:
return False
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-10-03 20:13:37 UTC (rev 333)
+++ trunk/jsengine/tokenizer/__init__.py 2013-10-08 16:36:44 UTC (rev 334)
@@ -1,6 +1,5 @@
# vim: sw=4 ts=4 et
from jsengine import JSSyntaxError
-from jsengine.structs import NodePositions
_WHITESPACE = u'\u0020\t\u000B\u000C\u00A0\uFFFF'
_LINETERMINATOR = u'\u000A\u000D\u2028\u2029'
@@ -141,59 +140,60 @@
def __init__(self, tok, atom=None):
self.tok = tok
self.atom = atom
- self.startpos = None
- self.endpos = None
- def setpos(self, startpos, endpos):
- self.startpos = startpos
- self.endpos = endpos
+ self.start_offset = None
+ self.end_offset = None
+ def set_offset(self, start_offset, end_offset):
+ self.start_offset = start_offset
+ self.end_offset = end_offset
def __repr__(self):
return 'Token(%r, %r)' % \
(self.tok, self.atom)
class TokenStream:
- def __init__(self, content, startpos=None):
+ def __init__(self, content, start_offset=0):
+ assert isinstance(start_offset, int)
self._content = content
- self._pos = 0
- self._watched_pos = None
- self._nodepositions = NodePositions(content, startpos)
+ self._start_offset = start_offset
+ self._offset = 0
+ self._watched_offset = None
- def getpos(self, offset=0):
- return self._nodepositions.from_offset(self._pos+offset)
+ def get_offset(self, offset=0):
+ return self._start_offset + self._offset + offset
def watch_reads(self):
- self._watched_pos = self._pos
+ self._watched_offset = self._offset
def get_watched_reads(self):
- assert not self._watched_pos == None
- s = self._content[self._watched_pos:self._pos]...
[truncated message content] |
|
From: <mat...@us...> - 2013-10-03 20:13:40
|
Revision: 333
http://sourceforge.net/p/javascriptlint/code/333
Author: matthiasmiller
Date: 2013-10-03 20:13:37 +0000 (Thu, 03 Oct 2013)
Log Message:
-----------
Fix parsing numbers with exponents.
Modified Paths:
--------------
trunk/jsengine/tokenizer/__init__.py
trunk/test.py
Added Paths:
-----------
trunk/tests/bugs/numbers.js
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-10-03 19:48:25 UTC (rev 332)
+++ trunk/jsengine/tokenizer/__init__.py 2013-10-03 20:13:37 UTC (rev 333)
@@ -397,7 +397,8 @@
if stream.readif(1, 'eE'):
stream.readif(1, '+-')
- stream.require(_DIGITS)
+ if not stream.readif(1, _DIGITS):
+ raise JSSyntaxError(stream.getpos(), 'syntax_error')
while stream.readif(1, _DIGITS):
pass
Modified: trunk/test.py
===================================================================
--- trunk/test.py 2013-10-03 19:48:25 UTC (rev 332)
+++ trunk/test.py 2013-10-03 20:13:37 UTC (rev 333)
@@ -105,6 +105,10 @@
def _get_python_modules(dir_):
for root, dirs, files in os.walk(dir_):
+ for exclude in ('build', 'dist'):
+ if exclude in dirs:
+ build.remove(exclude)
+
if '.svn' in dirs:
dirs.remove('.svn')
for name in files:
Added: trunk/tests/bugs/numbers.js
===================================================================
--- trunk/tests/bugs/numbers.js (rev 0)
+++ trunk/tests/bugs/numbers.js 2013-10-03 20:13:37 UTC (rev 333)
@@ -0,0 +1,5 @@
+function number() {
+ var i = 1.1e10;
+ i = 1.1e+10;
+ i = 1.1e-10;
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-03 19:48:28
|
Revision: 332
http://sourceforge.net/p/javascriptlint/code/332
Author: matthiasmiller
Date: 2013-10-03 19:48:25 +0000 (Thu, 03 Oct 2013)
Log Message:
-----------
Gracefully handle IO errors.
Modified Paths:
--------------
trunk/javascriptlint/lint.py
trunk/javascriptlint/warnings.py
Modified: trunk/javascriptlint/lint.py
===================================================================
--- trunk/javascriptlint/lint.py 2013-10-03 19:39:07 UTC (rev 331)
+++ trunk/javascriptlint/lint.py 2013-10-03 19:48:25 UTC (rev 332)
@@ -302,8 +302,13 @@
return lint_cache[normpath]
if printpaths:
print normpath
- contents = fs.readfile(path, encoding)
+
lint_cache[normpath] = _Script()
+ try:
+ contents = fs.readfile(path, encoding)
+ except IOError, error:
+ _lint_error(0, 0, 'io_error', unicode(error))
+ return lint_cache[normpath]
script_parts = []
if kind == 'js':
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-10-03 19:39:07 UTC (rev 331)
+++ trunk/javascriptlint/warnings.py 2013-10-03 19:48:25 UTC (rev 332)
@@ -114,6 +114,7 @@
'expected_tok': 'expected token: {token}',
'unexpected_char': 'unexpected character: {char}',
'unexpected_eof': 'unexpected end of file',
+ 'io_error': '{error}',
}
def format_error(errname, **errargs):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-03 19:39:11
|
Revision: 331
http://sourceforge.net/p/javascriptlint/code/331
Author: matthiasmiller
Date: 2013-10-03 19:39:07 +0000 (Thu, 03 Oct 2013)
Log Message:
-----------
Handle Ctrl+C.
Modified Paths:
--------------
trunk/javascriptlint/jsl.py
Modified: trunk/javascriptlint/jsl.py
===================================================================
--- trunk/javascriptlint/jsl.py 2013-10-03 19:16:44 UTC (rev 330)
+++ trunk/javascriptlint/jsl.py 2013-10-03 19:39:07 UTC (rev 331)
@@ -66,7 +66,7 @@
def _profile_disabled(func, *args, **kwargs):
func(*args, **kwargs)
-def main():
+def _main():
parser = OptionParser(usage="%prog [options] [files]")
add = parser.add_option
add("--conf", dest="conf", metavar="CONF",
@@ -154,6 +154,12 @@
sys.exit(1)
sys.exit(0)
+def main():
+ try:
+ _main()
+ except KeyboardInterrupt:
+ raise SystemExit(130)
+
if __name__ == '__main__':
main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-03 19:16:49
|
Revision: 330
http://sourceforge.net/p/javascriptlint/code/330
Author: matthiasmiller
Date: 2013-10-03 19:16:44 +0000 (Thu, 03 Oct 2013)
Log Message:
-----------
Embed version number and revision.
Modified Paths:
--------------
trunk/javascriptlint/conf.py
trunk/javascriptlint/jsl.py
trunk/setup.py
Added Paths:
-----------
trunk/javascriptlint/version.py
Modified: trunk/javascriptlint/conf.py
===================================================================
--- trunk/javascriptlint/conf.py 2013-10-02 23:27:18 UTC (rev 329)
+++ trunk/javascriptlint/conf.py 2013-10-03 19:16:44 UTC (rev 330)
@@ -4,6 +4,7 @@
import fs
import util
+import version
import warnings
_DISABLED_WARNINGS = (
@@ -100,7 +101,7 @@
# or "+process Folder\Path\*.htm".
#
""" % {
- 'version': '', # TODO
+ 'version': version.version,
'warnings': _getwarningsconf(),
}
Modified: trunk/javascriptlint/jsl.py
===================================================================
--- trunk/javascriptlint/jsl.py 2013-10-02 23:27:18 UTC (rev 329)
+++ trunk/javascriptlint/jsl.py 2013-10-03 19:16:44 UTC (rev 330)
@@ -14,6 +14,7 @@
import jsparse
import lint
import util
+import version
_lint_results = {
'warnings': 0,
@@ -48,8 +49,7 @@
return paths or [path]
def printlogo():
- # TODO: Print version number.
- print "JavaScript Lint"
+ print "JavaScript Lint %s" % version.version
print "Developed by Matthias Miller (http://www.JavaScriptLint.com)"
def _profile_enabled(func, *args, **kwargs):
Added: trunk/javascriptlint/version.py
===================================================================
--- trunk/javascriptlint/version.py (rev 0)
+++ trunk/javascriptlint/version.py 2013-10-03 19:16:44 UTC (rev 330)
@@ -0,0 +1,19 @@
+import os.path
+import subprocess
+
+try:
+ from __svnversion__ import version
+except ImportError:
+ def _getrevnum():
+ path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ p = subprocess.Popen(['svnversion', path], stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ raise _BuildError('Error running svnversion: %s' % stderr)
+ version = stdout.strip().rstrip('M')
+ version = version.rpartition(':')[-1]
+ return int(version)
+
+ version = '0.5.0/r%i' % _getrevnum()
+
Modified: trunk/setup.py
===================================================================
--- trunk/setup.py 2013-10-02 23:27:18 UTC (rev 329)
+++ trunk/setup.py 2013-10-03 19:16:44 UTC (rev 330)
@@ -7,20 +7,12 @@
import subprocess
import sys
+from javascriptlint import version
+
class _BuildError(Exception):
pass
-def _getrevnum():
- path = os.path.dirname(os.path.abspath(__file__))
- p = subprocess.Popen(['svnversion', path], stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- raise _BuildError('Error running svnversion: %s' % stderr)
- version = stdout.strip().rstrip('M')
- return int(version)
-
-if __name__ == '__main__':
+def _setup():
cmdclass = {
'build': distutils.command.build.build,
'clean': distutils.command.clean.clean,
@@ -28,12 +20,12 @@
args = {}
args.update(
name = 'javascriptlint',
- version = '0.0.0.%i' % _getrevnum(),
+ version = version.version,
author = 'Matthias Miller',
author_email = 'in...@ja...',
url = 'http://www.javascriptlint.com/',
cmdclass = cmdclass,
- description = 'JavaScript Lint (pyjsl beta r%i)' % _getrevnum(),
+ description = 'JavaScript Lint %s' % version.version,
packages = ['javascriptlint'],
scripts = ['jsl']
)
@@ -64,3 +56,18 @@
)
setup(**args)
+def _main():
+ # Create a temporary __svnversion__.py to bundle the version
+ path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ 'javascriptlint', '__svnversion__.py')
+ with open(path, 'w') as f:
+ f.write('version = %r' % version.version)
+ try:
+ _setup()
+ finally:
+ os.unlink(path)
+ if os.path.exists(path + 'c'):
+ os.unlink(path + 'c')
+
+if __name__ == '__main__':
+ _main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-02 23:27:22
|
Revision: 329
http://sourceforge.net/p/javascriptlint/code/329
Author: matthiasmiller
Date: 2013-10-02 23:27:18 +0000 (Wed, 02 Oct 2013)
Log Message:
-----------
pylint: fix more whitespace issues
Modified Paths:
--------------
trunk/javascriptlint/jsparse.py
trunk/javascriptlint/warnings.py
trunk/jsengine/parser/__init__.py
trunk/jsengine/structs.py
trunk/test.py
trunk/www.py
Modified: trunk/javascriptlint/jsparse.py
===================================================================
--- trunk/javascriptlint/jsparse.py 2013-10-02 23:23:24 UTC (rev 328)
+++ trunk/javascriptlint/jsparse.py 2013-10-02 23:27:18 UTC (rev 329)
@@ -55,7 +55,7 @@
""" All node positions will be relative to startpos. This allows scripts
to be embedded in a file (for example, HTML).
"""
- startpos = startpos or NodePos(0,0)
+ startpos = startpos or NodePos(0, 0)
jsversion = jsversion or JSVersion.default()
assert isvalidversion(jsversion), jsversion
if jsversion.e4x:
@@ -173,7 +173,7 @@
self.assertEquals(pos.to_offset(NodePos(1, 0)), 5)
self.assertEquals(pos.to_offset(NodePos(3, 1)), 11)
def testStartPos(self):
- pos = NodePositions('abc\r\ndef\n\nghi', NodePos(3,4))
+ pos = NodePositions('abc\r\ndef\n\nghi', NodePos(3, 4))
self.assertEquals(pos.to_offset(NodePos(3, 4)), 0)
self.assertEquals(pos.to_offset(NodePos(3, 5)), 1)
self.assertEquals(pos.from_offset(0), NodePos(3, 4))
@@ -185,21 +185,21 @@
def testAdd(self):
r = NodeRanges()
r.add(5, 10)
- self.assertEquals(r._offsets, [5,11])
+ 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])
+ 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)
@@ -239,8 +239,8 @@
return errors[0]
self.assertEquals(geterror(' ?', None), (0, 1, 'syntax_error', {}))
self.assertEquals(geterror('\n ?', None), (1, 1, 'syntax_error', {}))
- self.assertEquals(geterror(' ?', NodePos(1,1)), (1, 2, 'syntax_error', {}))
- self.assertEquals(geterror('\n ?', NodePos(1,1)), (2, 1, 'syntax_error', {}))
+ self.assertEquals(geterror(' ?', NodePos(1, 1)), (1, 2, 'syntax_error', {}))
+ self.assertEquals(geterror('\n ?', NodePos(1, 1)), (2, 1, 'syntax_error', {}))
def testNodePos(self):
def getnodepos(script, startpos):
root = parse(script, None, None, startpos)
@@ -248,24 +248,24 @@
var, = root.kids
self.assertEquals(var.kind, tok.VAR)
return var.start_pos()
- self.assertEquals(getnodepos('var x;', None), NodePos(0,0))
- self.assertEquals(getnodepos(' var x;', None), NodePos(0,1))
- self.assertEquals(getnodepos('\n\n var x;', None), NodePos(2,1))
- self.assertEquals(getnodepos('var x;', NodePos(3,4)), NodePos(3,4))
- self.assertEquals(getnodepos(' var x;', NodePos(3,4)), NodePos(3,5))
- self.assertEquals(getnodepos('\n\n var x;', NodePos(3,4)), NodePos(5,1))
+ self.assertEquals(getnodepos('var x;', None), NodePos(0, 0))
+ self.assertEquals(getnodepos(' var x;', None), NodePos(0, 1))
+ self.assertEquals(getnodepos('\n\n var x;', None), NodePos(2, 1))
+ self.assertEquals(getnodepos('var x;', NodePos(3, 4)), NodePos(3, 4))
+ self.assertEquals(getnodepos(' var x;', NodePos(3, 4)), NodePos(3, 5))
+ self.assertEquals(getnodepos('\n\n var x;', NodePos(3, 4)), NodePos(5, 1))
def testComments(self):
def testcomment(comment, startpos, expectedpos):
root = parse(comment, None, None, startpos)
comment, = findcomments(comment, root, startpos)
self.assertEquals(comment.start_pos(), expectedpos)
for comment in ('/*comment*/', '//comment'):
- testcomment(comment, None, NodePos(0,0))
- testcomment(' %s' % comment, None, NodePos(0,1))
- testcomment('\n\n %s' % comment, None, NodePos(2,1))
- testcomment('%s' % comment, NodePos(3,4), NodePos(3,4))
- testcomment(' %s' % comment, NodePos(3,4), NodePos(3,5))
- testcomment('\n\n %s' % comment, NodePos(3,4), NodePos(5,1))
+ testcomment(comment, None, NodePos(0, 0))
+ testcomment(' %s' % comment, None, NodePos(0, 1))
+ testcomment('\n\n %s' % comment, None, NodePos(2, 1))
+ testcomment('%s' % comment, NodePos(3, 4), NodePos(3, 4))
+ testcomment(' %s' % comment, NodePos(3, 4), NodePos(3, 5))
+ testcomment('\n\n %s' % comment, NodePos(3, 4), NodePos(5, 1))
if __name__ == '__main__':
unittest.main()
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-10-02 23:23:24 UTC (rev 328)
+++ trunk/javascriptlint/warnings.py 2013-10-02 23:27:18 UTC (rev 329)
@@ -290,7 +290,7 @@
def with_statement(node):
raise LintWarning(node)
-@lookfor(tok.EQOP,tok.RELOP)
+@lookfor(tok.EQOP, tok.RELOP)
def useless_comparison(node):
for lvalue, rvalue in itertools.combinations(node.kids, 2):
if lvalue.is_equivalent(rvalue):
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-10-02 23:23:24 UTC (rev 328)
+++ trunk/jsengine/parser/__init__.py 2013-10-02 23:27:18 UTC (rev 329)
@@ -854,7 +854,7 @@
try:
parsestring('/*')
except JSSyntaxError as error:
- self.assertEqual(error.pos, NodePos(0,1))
+ self.assertEqual(error.pos, NodePos(0, 1))
else:
self.assert_(False)
def testObjectEndComma(self):
Modified: trunk/jsengine/structs.py
===================================================================
--- trunk/jsengine/structs.py 2013-10-02 23:23:24 UTC (rev 328)
+++ trunk/jsengine/structs.py 2013-10-02 23:27:18 UTC (rev 329)
@@ -63,7 +63,7 @@
end = self._offsets[j]
j += 1
- self._offsets[i:j] = [start,end]
+ self._offsets[i:j] = [start, end]
def has(self, pos):
return bisect.bisect_right(self._offsets, pos) % 2 == 1
Modified: trunk/test.py
===================================================================
--- trunk/test.py 2013-10-02 23:23:24 UTC (rev 328)
+++ trunk/test.py 2013-10-02 23:27:18 UTC (rev 329)
@@ -130,8 +130,6 @@
'C0202', # Class method should have "cls" as first argument
'C0301', # Line too long (%s/%s)
'C0321', # More than one statement on a single line
- 'C0323', # Operator not followed by a space
- 'C0324', # Comma not followed by a space
'C1001', # Old style class
'E0602', # Undefined variable %r
'E1101', # %s %r has no %r member
Modified: trunk/www.py
===================================================================
--- trunk/www.py 2013-10-02 23:23:24 UTC (rev 328)
+++ trunk/www.py 2013-10-02 23:27:18 UTC (rev 329)
@@ -361,12 +361,12 @@
if action == 'build':
build(host)
return
- print >>sys.stderr, """\
+ sys.stderr.write("""\
Usage: www.py [server|build] <host>
server runs a test server on localhost
build generates static HTML files from the markup
-"""
+""")
sys.exit(1)
if __name__ == '__main__':
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-02 23:23:27
|
Revision: 328
http://sourceforge.net/p/javascriptlint/code/328
Author: matthiasmiller
Date: 2013-10-02 23:23:24 +0000 (Wed, 02 Oct 2013)
Log Message:
-----------
pylint: clean up trailing whitespace
Modified Paths:
--------------
trunk/javascriptlint/conf.py
trunk/javascriptlint/lint.py
trunk/jsengine/parser/__init__.py
trunk/jsengine/structs.py
trunk/jsengine/tokenizer/__init__.py
trunk/test.py
Modified: trunk/javascriptlint/conf.py
===================================================================
--- trunk/javascriptlint/conf.py 2013-10-02 23:18:30 UTC (rev 327)
+++ trunk/javascriptlint/conf.py 2013-10-02 23:23:24 UTC (rev 328)
@@ -163,14 +163,14 @@
def load(self, enabled, parm):
if not enabled:
raise ConfError('Expected +.')
-
+
self.value = util.JSVersion.fromtype(parm)
if not self.value:
raise ConfError('Invalid JavaScript version: %s' % parm)
class Conf:
def __init__(self):
- recurse = BooleanSetting(False)
+ recurse = BooleanSetting(False)
self._settings = {
'recurse': recurse,
'output-format': StringSetting('__FILE__(__LINE__): __ERROR__'),
Modified: trunk/javascriptlint/lint.py
===================================================================
--- trunk/javascriptlint/lint.py 2013-10-02 23:18:30 UTC (rev 327)
+++ trunk/javascriptlint/lint.py 2013-10-02 23:23:24 UTC (rev 328)
@@ -19,7 +19,7 @@
'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',
@@ -27,7 +27,7 @@
'eval', 'NaN', 'Infinity',
'escape', 'unescape', 'uneval',
'decodeURI', 'encodeURI', 'decodeURIComponent', 'encodeURIComponent',
- 'Function', 'Object',
+ 'Function', 'Object',
'Error', 'InternalError', 'EvalError', 'RangeError', 'ReferenceError',
'SyntaxError', 'TypeError', 'URIError',
'arguments', 'undefined'
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-10-02 23:18:30 UTC (rev 327)
+++ trunk/jsengine/parser/__init__.py 2013-10-02 23:23:24 UTC (rev 328)
@@ -86,7 +86,7 @@
x.startpos, x.endpos, None, [])
items[-1] = items[-1] or comma
- # Check for the end.
+ # Check for the end.
if t.peek().tok == tok.RBRACKET:
end_comma = comma
break
@@ -306,7 +306,7 @@
_MULTIPLICATIVE = {
tok.MUL: (kind.STAR, op.MUL),
tok.DIV: (kind.DIVOP, op.DIV),
- tok.MOD: (kind.DIVOP, op.MOD),
+ tok.MOD: (kind.DIVOP, op.MOD),
}
def _multiplicative_expression(t):
return _binary_expression(t, _MULTIPLICATIVE, _unary_expression)
@@ -391,7 +391,7 @@
t.expect(tok.LOGICAL_AND)
else:
break
-
+
while len(exprs) > 1:
right = exprs.pop()
left = exprs[-1]
@@ -408,7 +408,7 @@
t.expect(tok.LOGICAL_OR)
else:
break
-
+
while len(exprs) > 1:
right = exprs.pop()
left = exprs[-1]
@@ -467,7 +467,7 @@
kind_, op_ = _ASSIGNS[t.peek().tok]
t.advance()
right = _assignment_expression(t, allowin)
- return ParseNode(kind_, op_,
+ return ParseNode(kind_, op_,
left.startpos, right.endpos, None, [left, right])
else:
return left
@@ -607,7 +607,7 @@
op.FORIN if condition.kind == kind.IN else None,
for_startpos, body.endpos,
None, [condition, body])
-
+
def _continue_statement(t):
endtoken = t.expect(tok.CONTINUE)
startpos = endtoken.startpos
@@ -617,7 +617,7 @@
name = endtoken.atom
else:
name = None
- # TODO: Validate Scope Labels
+ # TODO: Validate Scope Labels
return _auto_semicolon(t, kind.CONTINUE, None, startpos, endtoken.endpos, name, [])
def _break_statement(t):
@@ -629,19 +629,19 @@
name = endtoken.atom
else:
name = None
- # TODO: Validate Scope Labels
+ # TODO: Validate Scope Labels
return _auto_semicolon(t, kind.BREAK, None, startpos, endtoken.endpos, name, [])
def _return_statement(t):
endtoken = t.expect(tok.RETURN)
startpos = endtoken.startpos
-
+
if t.peek_sameline().tok not in (tok.EOF, tok.EOL, tok.SEMI, tok.RBRACE):
expr = _expression(t, True)
endtoken = expr
else:
expr = None
- # TODO: Validate Scope Labels
+ # TODO: Validate Scope Labels
return _auto_semicolon(t, kind.RETURN, None, startpos, endtoken.endpos,
None, [expr])
@@ -672,7 +672,7 @@
case_kind = kind.DEFAULT
else:
raise JSSyntaxError(t.peek().startpos, 'invalid_case')
-
+
case_endpos = t.expect(tok.COLON).endpos
statements = []
@@ -692,7 +692,7 @@
ParseNode(kind.LC, None, statements_startpos,
statements_endpos, None, statements)
]))
-
+
rc_endpos = t.expect(tok.RBRACE).endpos
return ParseNode(kind.SWITCH, None, switch_startpos, rc_endpos,
None, [expr,
@@ -734,7 +734,7 @@
])
])
try_endpos = catch_endpos
-
+
if t.peek().tok == tok.FINALLY:
t.advance()
finally_node = _block_statement(t)
@@ -782,7 +782,7 @@
raise JSSyntaxError(x.startpos, 'unexpected_eof')
elif x.tok == tok.FUNCTION:
return _function_declaration(t, op.CLOSURE) #TODO: warn, since this is not reliable
-
+
elif x.tok not in (tok.LBRACE, tok.FUNCTION):
expr = _expression(t, True)
if expr.kind == tok.NAME and t.peek().tok == tok.COLON:
Modified: trunk/jsengine/structs.py
===================================================================
--- trunk/jsengine/structs.py 2013-10-02 23:18:30 UTC (rev 327)
+++ trunk/jsengine/structs.py 2013-10-02 23:23:24 UTC (rev 328)
@@ -112,7 +112,7 @@
self.endpos = end_pos
self.no_semi = no_semi
self.end_comma = end_comma
-
+
for i, kid in enumerate(self.kids):
if kid:
assert isinstance(kid, ParseNode)
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-10-02 23:18:30 UTC (rev 327)
+++ trunk/jsengine/tokenizer/__init__.py 2013-10-02 23:23:24 UTC (rev 328)
@@ -41,7 +41,7 @@
"}": "RBRACE",
"(": "LPAREN",
")": "RPAREN",
- "[": "LBRACKET",
+ "[": "LBRACKET",
"]": "RBRACKET",
".": "DOT",
";": "SEMI",
@@ -58,7 +58,7 @@
"!": "LOGICAL_NOT",
"~": "BIT_NOT",
"?": "QUESTION",
- ":": "COLON",
+ ":": "COLON",
"=": "ASSIGN",
"/": "DIV",
"!": "LOGICAL_NOT",
@@ -159,7 +159,7 @@
def getpos(self, offset=0):
return self._nodepositions.from_offset(self._pos+offset)
-
+
def watch_reads(self):
self._watched_pos = self._pos
@@ -316,7 +316,7 @@
def _next(self, parse_regexp=False):
stream = self._stream
-
+
if stream.eof():
return Token(tok.EOF)
@@ -331,10 +331,10 @@
elif stream.readif(1, _WHITESPACE):
pass
else:
- break
+ break
if linebreak:
return Token(tok.EOL)
- else:
+ else:
return Token(tok.SPACE)
# COMMENTS
Modified: trunk/test.py
===================================================================
--- trunk/test.py 2013-10-02 23:18:30 UTC (rev 327)
+++ trunk/test.py 2013-10-02 23:23:24 UTC (rev 328)
@@ -96,7 +96,7 @@
class _CustomLintReporter(TextReporter):
line_format = '{path}({line}): [{msg_id}({symbol}){obj}] {msg}'
def __init__(self):
- TextReporter.__init__(self)
+ TextReporter.__init__(self)
self.msg_count = 0
def write_message(self, msg):
@@ -129,7 +129,6 @@
'C0103', # Invalid name "%s" (should match %s)
'C0202', # Class method should have "cls" as first argument
'C0301', # Line too long (%s/%s)
- 'C0303', # Trailing whitespace
'C0321', # More than one statement on a single line
'C0323', # Operator not followed by a space
'C0324', # Comma not followed by a space
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-02 23:18:33
|
Revision: 327
http://sourceforge.net/p/javascriptlint/code/327
Author: matthiasmiller
Date: 2013-10-02 23:18:30 +0000 (Wed, 02 Oct 2013)
Log Message:
-----------
pylint: fix raise syntax
Modified Paths:
--------------
trunk/javascriptlint/conf.py
trunk/javascriptlint/visitation.py
trunk/javascriptlint/warnings.py
trunk/setup.py
trunk/test.py
trunk/www.py
Modified: trunk/javascriptlint/conf.py
===================================================================
--- trunk/javascriptlint/conf.py 2013-10-02 23:16:54 UTC (rev 326)
+++ trunk/javascriptlint/conf.py 2013-10-02 23:18:30 UTC (rev 327)
@@ -119,7 +119,7 @@
wants_parm = False
value = None
def load(self, enabled):
- raise ConfError, 'This setting is deprecated.'
+ raise ConfError('This setting is deprecated.')
class BooleanSetting(Setting):
wants_parm = False
@@ -134,7 +134,7 @@
self.value = default
def load(self, enabled, parm):
if not enabled:
- raise ConfError, 'Expected +.'
+ raise ConfError('Expected +.')
self.value = parm
class DeclareSetting(Setting):
@@ -143,7 +143,7 @@
self.value = []
def load(self, enabled, parm):
if not enabled:
- raise ConfError, 'Expected +.'
+ raise ConfError('Expected +.')
self.value.append(parm)
class ProcessSetting(Setting):
@@ -162,11 +162,11 @@
value = util.JSVersion.default()
def load(self, enabled, parm):
if not enabled:
- raise ConfError, 'Expected +.'
+ raise ConfError('Expected +.')
self.value = util.JSVersion.fromtype(parm)
if not self.value:
- raise ConfError, 'Invalid JavaScript version: %s' % parm
+ raise ConfError('Invalid JavaScript version: %s' % parm)
class Conf:
def __init__(self):
@@ -227,7 +227,7 @@
elif line.startswith('-'):
enabled = False
else:
- raise ConfError, 'Expected + or -.'
+ raise ConfError('Expected + or -.')
line = line[1:]
# Parse the key/parms
@@ -242,7 +242,7 @@
if setting.wants_parm:
args['parm'] = parm
elif parm:
- raise ConfError, 'The %s setting does not expect a parameter.' % name
+ raise ConfError('The %s setting does not expect a parameter.' % name)
if setting.wants_dir:
args['dir'] = dir
setting.load(**args)
Modified: trunk/javascriptlint/visitation.py
===================================================================
--- trunk/javascriptlint/visitation.py 2013-10-02 23:16:54 UTC (rev 326)
+++ trunk/javascriptlint/visitation.py 2013-10-02 23:18:30 UTC (rev 327)
@@ -27,9 +27,9 @@
# Intantiate an instance of each class
for klass in klasses:
if klass.__name__.lower() != klass.__name__:
- raise ValueError, 'class names must be lowercase'
+ raise ValueError('class names must be lowercase')
if not klass.__doc__:
- raise ValueError, 'missing docstring on class %s' % klass.__name__
+ raise ValueError('missing docstring on class %s' % klass.__name__)
# Look for functions with the "_visit_nodes" property.
visitor = klass()
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-10-02 23:16:54 UTC (rev 326)
+++ trunk/javascriptlint/warnings.py 2013-10-02 23:18:30 UTC (rev 327)
@@ -12,7 +12,7 @@
@lookfor(tok.NODEKIND, (tok.NODEKIND, op.OPCODE))
def warning_name(node):
if questionable:
- raise LintWarning, node
+ raise LintWarning(node)
"""
import itertools
import re
@@ -125,7 +125,7 @@
try:
errdesc = re.sub(r"{(\w+)}", lambda match: errargs[match.group(1)], errdesc)
except (TypeError, KeyError):
- raise KeyError, 'Invalid keyword in error: ' + errdesc
+ raise KeyError('Invalid keyword in error: ' + errdesc)
return errdesc
_visitors = []
@@ -253,17 +253,17 @@
def comparison_type_conv(node):
for kid in node.kids:
if kid.kind == tok.PRIMARY and kid.opcode in (op.NULL, op.TRUE, op.FALSE):
- raise LintWarning, kid
+ raise LintWarning(kid)
if kid.kind == tok.NUMBER and not kid.dval:
- raise LintWarning, kid
+ raise LintWarning(kid)
if kid.kind == tok.STRING and not kid.atom:
- raise LintWarning, kid
+ raise LintWarning(kid)
@lookfor(tok.DEFAULT)
def default_not_at_end(node):
siblings = node.parent.kids
if node.node_index != len(siblings)-1:
- raise LintWarning, siblings[node.node_index+1]
+ raise LintWarning(siblings[node.node_index+1])
@lookfor(tok.CASE)
def duplicate_case_in_switch(node):
@@ -276,7 +276,7 @@
if sibling.kind == tok.CASE:
sibling_value = sibling.kids[0]
if node_value.is_equivalent(sibling_value, True):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.SWITCH)
def missing_default_case(node):
@@ -284,21 +284,21 @@
for case in cases.kids:
if case.kind == tok.DEFAULT:
return
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.WITH)
def with_statement(node):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.EQOP,tok.RELOP)
def useless_comparison(node):
for lvalue, rvalue in itertools.combinations(node.kids, 2):
if lvalue.is_equivalent(rvalue):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor((tok.COLON, op.NAME))
def use_of_label(node):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor((tok.OBJECT, op.REGEXP))
def misplaced_regex(node):
@@ -314,7 +314,7 @@
return # Allow in /re/.property
if node.parent.kind == tok.RETURN:
return # Allow for return values
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.ASSIGN)
def assign_to_function_call(node):
@@ -323,7 +323,7 @@
while kid.kind == tok.RP:
kid, = kid.kids
if kid.kind == tok.LP:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor((tok.ASSIGN, None))
def equal_as_assign(node):
@@ -333,7 +333,7 @@
if not node.parent.kind in (tok.SEMI, tok.RESERVED, tok.RP, tok.COMMA,
tok.ASSIGN):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.IF)
def ambiguous_else_stmt(node):
@@ -349,13 +349,13 @@
return
# Else is only ambiguous in the first branch of an if statement.
if tmp.parent.kind == tok.IF and tmp.node_index == 1:
- raise LintWarning, else_
+ raise LintWarning(else_)
tmp = tmp.parent
@lookfor(tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH)
def block_without_braces(node):
if node.kids[1].kind != tok.LC:
- raise LintWarning, node.kids[1]
+ raise LintWarning(node.kids[1])
_block_nodes = (tok.IF, tok.WHILE, tok.DO, tok.FOR, tok.WITH)
@lookfor(*_block_nodes)
@@ -368,7 +368,7 @@
# was inside a block statement without clarifying curlies.
# (Otherwise, the node type would be tok.LC.)
if node.parent.kind in _block_nodes:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.INC, tok.DEC)
def inc_dec_within_stmt(node):
@@ -384,7 +384,7 @@
tmp.parent.parent.kind == tok.FOR:
return
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.COMMA)
def comma_separated_stmts(node):
@@ -394,12 +394,12 @@
# This is an array
if node.parent.kind == tok.RB:
return
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.SEMI)
def empty_statement(node):
if not node.kids[0]:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.LC)
def empty_statement_(node):
if node.kids:
@@ -410,7 +410,7 @@
# Some empty blocks are meaningful.
if node.parent.kind in (tok.CATCH, tok.CASE, tok.DEFAULT, tok.SWITCH, tok.FUNCTION):
return
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.CASE, tok.DEFAULT)
def missing_break(node):
@@ -424,7 +424,7 @@
return
if None in _get_exit_points(case_contents):
# Show the warning on the *next* node.
- raise LintWarning, node.parent.kids[node.node_index+1]
+ raise LintWarning(node.parent.kids[node.node_index+1])
@lookfor(tok.CASE, tok.DEFAULT)
def missing_break_for_last_case(node):
@@ -433,16 +433,16 @@
case_contents = node.kids[1]
assert case_contents.kind == tok.LC
if None in _get_exit_points(case_contents):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.INC)
def multiple_plus_minus(node):
if node.node_index == 0 and node.parent.kind == tok.PLUS:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.DEC)
def multiple_plus_minus_(node):
if node.node_index == 0 and node.parent.kind == tok.MINUS:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor((tok.NAME, op.SETNAME))
def useless_assign(node):
@@ -452,7 +452,7 @@
elif node.parent.kind == tok.VAR:
value = node.kids[0]
if value and value.kind == tok.NAME and node.atom == value.atom:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.BREAK, tok.CONTINUE, tok.RETURN, tok.THROW)
def unreachable_code(node):
@@ -463,12 +463,12 @@
for variable in sibling.kids:
value, = variable.kids
if value:
- raise LintWarning, value
+ raise LintWarning(value)
elif sibling.kind == tok.FUNCTION:
# Functions are always declared.
pass
else:
- raise LintWarning, sibling
+ raise LintWarning(sibling)
@lookfor(tok.FOR)
def unreachable_code_(node):
@@ -478,73 +478,73 @@
pre, condition, post = preamble.kids
if post:
if not None in _get_exit_points(code):
- raise LintWarning, post
+ raise LintWarning(post)
@lookfor(tok.DO)
def unreachable_code__(node):
# Warn if the do..while loop always exits.
code, condition = node.kids
if not None in _get_exit_points(code):
- raise LintWarning, condition
+ raise LintWarning(condition)
#TODO: @lookfor(tok.IF)
def meaningless_block(node):
condition, if_, else_ = node.kids
if condition.kind == tok.PRIMARY and condition.opcode in (op.TRUE, op.FALSE, op.NULL):
- raise LintWarning, condition
+ raise LintWarning(condition)
#TODO: @lookfor(tok.WHILE)
def meaningless_blocK_(node):
condition = node.kids[0]
if condition.kind == tok.PRIMARY and condition.opcode in (op.FALSE, op.NULL):
- raise LintWarning, condition
+ raise LintWarning(condition)
@lookfor(tok.LC)
def meaningless_block__(node):
if node.parent and node.parent.kind == tok.LC:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor((tok.UNARYOP, op.VOID))
def useless_void(node):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor((tok.LP, op.CALL))
def parseint_missing_radix(node):
if node.kids[0].kind == tok.NAME and node.kids[0].atom == 'parseInt' and len(node.kids) <= 2:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.NUMBER)
def leading_decimal_point(node):
if node.atom.startswith('.'):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.NUMBER)
def trailing_decimal_point(node):
if node.parent.kind == tok.DOT:
- raise LintWarning, node
+ raise LintWarning(node)
if node.atom.endswith('.'):
- raise LintWarning, node
+ raise LintWarning(node)
_octal_regexp = re.compile('^0[0-9]')
@lookfor(tok.NUMBER)
def octal_number(node):
if _octal_regexp.match(node.atom):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.RC)
def trailing_comma(node):
if node.end_comma:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.RB)
def trailing_comma_in_array(node):
if node.end_comma:
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.STRING)
def useless_quotes(node):
if node.node_index == 0 and node.parent.kind == tok.COLON:
# Only warn if the quotes could safely be removed.
if util.isidentifier(node.atom):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(tok.SEMI)
def want_assign_or_call(node):
@@ -566,7 +566,7 @@
grandchild = child.kids[0]
if grandchild.kind == tok.FUNCTION:
return
- raise LintWarning, child
+ raise LintWarning(child)
def _check_return_value(node):
name = node.fn_name or '(anonymous function)'
@@ -605,7 +605,7 @@
assert node.kids[0].kind == tok.IN
left, right = node.kids[0].kids
if not left.kind in (tok.VAR, tok.NAME):
- raise LintWarning, left
+ raise LintWarning(left)
@lookfor(tok.FUNCTION)
def misplaced_function(node):
@@ -635,7 +635,7 @@
return # Allow for return values
if parent.kind == tok.NEW:
return # Allow as constructors
- raise LintWarning, node
+ raise LintWarning(node)
def _get_expected_function_name(node):
# Ignore function statements.
@@ -724,7 +724,7 @@
def missing_semicolon(node):
if node.no_semi:
if not _get_assigned_lambda(node):
- raise LintWarning, node
+ raise LintWarning(node)
@lookfor(*_ALL_TOKENS)
def missing_semicolon_for_lambda(node):
@@ -733,7 +733,7 @@
# statements, so use the position of the lambda instead.
lambda_ = _get_assigned_lambda(node)
if lambda_:
- raise LintWarning, lambda_
+ raise LintWarning(lambda_)
@lookfor()
def ambiguous_newline(node):
Modified: trunk/setup.py
===================================================================
--- trunk/setup.py 2013-10-02 23:16:54 UTC (rev 326)
+++ trunk/setup.py 2013-10-02 23:18:30 UTC (rev 327)
@@ -16,7 +16,7 @@
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
- raise _BuildError, 'Error running svnversion: %s' % stderr
+ raise _BuildError('Error running svnversion: %s' % stderr)
version = stdout.strip().rstrip('M')
return int(version)
@@ -48,7 +48,7 @@
for exe in self.console_exe_files:
ret = subprocess.call(['upx', '-9', exe])
if ret != 0:
- raise _BuildError, 'Error running upx on %s' % exe
+ raise _BuildError('Error running upx on %s' % exe)
args['cmdclass']['py2exe'] = _MyPy2Exe
args.update(
Modified: trunk/test.py
===================================================================
--- trunk/test.py 2013-10-02 23:16:54 UTC (rev 326)
+++ trunk/test.py 2013-10-02 23:18:30 UTC (rev 327)
@@ -76,7 +76,7 @@
for line, warning, errdesc in unexpected_warnings:
errors.append('\tline %i: %s/%s' % (line+1, warning, errdesc))
if errors:
- raise TestError, '\n'.join(errors)
+ raise TestError('\n'.join(errors))
def _get_test_files():
# Get a list of test files.
@@ -143,7 +143,6 @@
'R0924', # Badly implemented
'W0109', # Duplicate key %r in dictionary
'W0120', # Else clause on loop without a break statement
- 'W0121', # old-raise-syntax
'W0141', # Used builtin function %r
'W0201', # Attribute %r defined outside __init__
'W0212', # Access to a protected member %s of a client class
Modified: trunk/www.py
===================================================================
--- trunk/www.py 2013-10-02 23:16:54 UTC (rev 326)
+++ trunk/www.py 2013-10-02 23:18:30 UTC (rev 327)
@@ -53,7 +53,7 @@
if not attrvalue.startswith('/'):
targetpath = _get_path_for_url(attrvalue, self._filepath)
if not targetpath:
- raise ValueError, 'Could not resolve URL %s' % attrvalue
+ raise ValueError('Could not resolve URL %s' % attrvalue)
# Get the folder of the parent path.
parenturl = _get_relurl_for_filepath(self._filepath)
@@ -89,7 +89,7 @@
root = os.path.dirname(parentpath)
assert (root + os.sep).startswith(DOC_ROOT + os.sep)
else:
- raise ValueError, 'Tried resolving relative URL: %s' % url
+ raise ValueError('Tried resolving relative URL: %s' % url)
urls = [
url.rstrip('/') + '/index.htm',
@@ -136,11 +136,11 @@
channel = doc.createElement("channel")
rss.appendChild(channel)
if not title:
- raise ValueError, 'Missing @title= setting.'
+ raise ValueError('Missing @title= setting.')
if not link:
- raise ValueError, 'Missing @link= setting.'
+ raise ValueError('Missing @link= setting.')
if not desc:
- raise ValueError, 'Missing @desc= setting.'
+ raise ValueError('Missing @desc= setting.')
channel.appendChild(doc.createElement('title', textNode=title))
channel.appendChild(doc.createElement('link', textNode=link))
channel.appendChild(doc.createElement('description', textNode=desc))
@@ -153,7 +153,7 @@
for child in oldDocElement.childNodes:
if child.type != "element":
if child.value.strip():
- raise ValueError, 'Expected outer-level element, not text.'
+ raise ValueError('Expected outer-level element, not text.')
continue
if child.nodeName == 'h1':
@@ -161,24 +161,24 @@
elif child.nodeName == "h2":
link = len(child.childNodes) == 1 and child.childNodes[0]
if not link or link.type != 'element' or link.nodeName != 'a':
- raise ValueError, 'Each heading must be a link.'
+ raise ValueError('Each heading must be a link.')
titlenode = len(link.childNodes) == 1 and link.childNodes[0]
if not titlenode or titlenode.type != 'text':
- raise ValueError, 'Each heading link must contain a ' + \
- 'single text node.'
+ raise ValueError('Each heading link must contain a ' + \
+ 'single text node.')
heading = titlenode.value.strip()
# Combine the href with the linkbase.
assert 'href' in link.attributes
href = link.attribute_values['href']
if not linkbase.endswith('/'):
- raise ValueError, 'The @linkbase must be a directory: %s' % \
- linkbase
+ raise ValueError('The @linkbase must be a directory: %s' % \
+ linkbase)
href = linkbase + href
if href in guids:
- raise ValueError, "Duplicate link: %s" % href
+ raise ValueError("Duplicate link: %s" % href)
guids.append(href)
item = doc.createElement("item")
@@ -193,21 +193,21 @@
# The first paragraph is <p><em>pubDate</em></p>
em = len(child.childNodes) == 1 and child.childNodes[0]
if not em or em.type != 'element' or em.nodeName != 'em':
- raise ValueError, 'The first paragraph must contain ' + \
- 'only an <em>.'
+ raise ValueError('The first paragraph must contain ' + \
+ 'only an <em>.')
emchild = len(em.childNodes) == 1 and em.childNodes[0]
if not emchild or emchild.type != 'text':
- raise ValueError, "The first paragraph's em must " + \
- "contain only text."
+ raise ValueError("The first paragraph's em must " + \
+ "contain only text.")
pubdate = emchild.value
format = "%a, %d %b %Y %H:%M:%S +0000"
dateobj = datetime.datetime.strptime(pubdate, format)
normalized = dateobj.strftime(format)
if normalized != pubdate:
- raise ValueError, 'Encountered date %s but expected %s' % \
- (pubdate, normalized)
+ raise ValueError('Encountered date %s but expected %s' % \
+ (pubdate, normalized))
item.appendChild(doc.createElement('pubDate', emchild.value))
@@ -218,7 +218,7 @@
item_desc.appendChild(cdata)
else:
- raise ValueError, 'Unsupported node type: %s' % child.nodeName
+ raise ValueError('Unsupported node type: %s' % child.nodeName)
return doc.toxml()
def _preprocess(path):
@@ -227,13 +227,13 @@
# will resolve.
url = match.group(1).strip()
if '/' in url:
- raise ValueError, 'Inclusions cannot cross directories'
+ raise ValueError('Inclusions cannot cross directories')
# When including a file, update global settings and replace
# with contents.
includepath = _get_path_for_url(url, path)
if not includepath:
- raise ValueError, 'Unmatched URL: %s' % match.group(1)
+ raise ValueError('Unmatched URL: %s' % match.group(1))
settings, contents = _preprocess(includepath)
childsettings.update(settings)
return contents
@@ -291,7 +291,7 @@
page = open(template_path).read() % keywords
return 'text/html', page
else:
- raise ValueError, 'Invalid file type: %s' % path
+ raise ValueError('Invalid file type: %s' % path)
class _Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
@@ -339,7 +339,7 @@
yield relpath
if not host or '/' in host:
- raise ValueError, 'Host must be sub.domain.com'
+ raise ValueError('Host must be sub.domain.com')
for relpath in findfiles(DOC_ROOT):
sourcepath = os.path.join(DOC_ROOT, relpath)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-02 23:16:59
|
Revision: 326
http://sourceforge.net/p/javascriptlint/code/326
Author: matthiasmiller
Date: 2013-10-02 23:16:54 +0000 (Wed, 02 Oct 2013)
Log Message:
-----------
pylint: start work to run pylint on jsl
Modified Paths:
--------------
trunk/test.py
Modified: trunk/test.py
===================================================================
--- trunk/test.py 2013-10-01 17:12:20 UTC (rev 325)
+++ trunk/test.py 2013-10-02 23:16:54 UTC (rev 326)
@@ -4,6 +4,9 @@
import re
import sys
+import pylint.lint
+from pylint.reporters.text import TextReporter
+
import javascriptlint.conf
import javascriptlint.lint
@@ -90,7 +93,93 @@
all_files.sort()
return all_files
+class _CustomLintReporter(TextReporter):
+ line_format = '{path}({line}): [{msg_id}({symbol}){obj}] {msg}'
+ def __init__(self):
+ TextReporter.__init__(self)
+ self.msg_count = 0
+
+ def write_message(self, msg):
+ TextReporter.write_message(self, msg)
+ self.msg_count += 1
+
+def _get_python_modules(dir_):
+ for root, dirs, files in os.walk(dir_):
+ if '.svn' in dirs:
+ dirs.remove('.svn')
+ for name in files:
+ if name.endswith('.py'):
+ yield os.path.join(root, name)
+
+def _run_pylint():
+ IGNORE = [
+ 'C0111', # Missing docstring
+ 'I0011', # Locally disabling warning
+ 'R0902', # Too many instance attributes (%s/%s)
+ 'R0903', # Too few public methods (%s/%s)
+ 'R0904', # Too many public methods (%s/%s)
+ 'R0911', # Too many return statements (%s/%s)
+ 'R0912', # Too many branches (%s/%s)
+ 'R0913', # Too many arguments (%s/%s)
+ 'R0914', # Too many local variables (%s/%s)
+ 'R0915', # Too many statements (%s/%s)
+ 'W0142', # Used * or ** magic
+ ]
+ REVIEW = [
+ 'C0103', # Invalid name "%s" (should match %s)
+ 'C0202', # Class method should have "cls" as first argument
+ 'C0301', # Line too long (%s/%s)
+ 'C0303', # Trailing whitespace
+ 'C0321', # More than one statement on a single line
+ 'C0323', # Operator not followed by a space
+ 'C0324', # Comma not followed by a space
+ 'C1001', # Old style class
+ 'E0602', # Undefined variable %r
+ 'E1101', # %s %r has no %r member
+ 'E1103', # %s %r has no %r member (but some types could not be inferred)
+ 'E1306', # Not enough arguments for format string
+ 'F0401', # Cyclic import (%s)
+ 'R0201', # Attribute %r defined outside __init__
+ 'R0924', # Badly implemented
+ 'W0109', # Duplicate key %r in dictionary
+ 'W0120', # Else clause on loop without a break statement
+ 'W0121', # old-raise-syntax
+ 'W0141', # Used builtin function %r
+ 'W0201', # Attribute %r defined outside __init__
+ 'W0212', # Access to a protected member %s of a client class
+ 'W0231', # __init__ method from base class %r is not called
+ 'W0232', # Class has no __init__ method
+ 'W0301', # Unnecessary semicolon
+ 'W0311', # Bad indentation
+ 'W0401', # Wildcard import %s
+ 'W0403', # Relative import %r
+ 'W0511', # TODO
+ 'W0611', # Unused import %s
+ 'W0612', # unused variable
+ 'W0613', # Unused argument %r
+ 'W0614', # Unused import %s from wildcard import
+ 'W0621', # Redefining name %r from outer scope (line %s)
+ 'W0622', # Redefining built-in %r
+ 'W0631', # Using possibly undefined loop variable %r
+ 'W0632', # unbalanced-tuple-unpacking
+ 'W1401', # Anomalous backslash in string
+ ]
+
+ dir_ = os.path.dirname(os.path.abspath(__file__))
+ modules = list(_get_python_modules(dir_))
+ reporter = _CustomLintReporter()
+ pylint.lint.Run([
+ '--reports=n',
+ ] + [
+ '--disable=%s' % code for code in (IGNORE + REVIEW)
+ ] + modules, reporter=reporter, exit=False)
+ if reporter.msg_count:
+ print '\nLint failed!\n'
+ sys.exit(1)
+
def main():
+ _run_pylint()
+
haderrors = False
for file in _get_test_files():
ext = os.path.splitext(file)[1]
@@ -108,5 +197,9 @@
sys.exit(haderrors)
if __name__ == '__main__':
- main()
+ try:
+ main()
+ except KeyboardInterrupt:
+ sys.stderr.write('\n\nCanceled.\n')
+ sys.exit(1)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-01 17:12:24
|
Revision: 325
http://sourceforge.net/p/javascriptlint/code/325
Author: matthiasmiller
Date: 2013-10-01 17:12:20 +0000 (Tue, 01 Oct 2013)
Log Message:
-----------
First cut at warnings to validate function expression names (disabled by default)
Modified Paths:
--------------
trunk/javascriptlint/conf.py
trunk/javascriptlint/warnings.py
trunk/tests/control_comments/option_explicit.js
trunk/tests/warnings/want_assign_or_call.js
Added Paths:
-----------
trunk/tests/warnings/function_name_mismatch.js
trunk/tests/warnings/function_name_missing.js
trunk/tests/warnings/misplaced_function.js
Modified: trunk/javascriptlint/conf.py
===================================================================
--- trunk/javascriptlint/conf.py 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/javascriptlint/conf.py 2013-10-01 17:12:20 UTC (rev 325)
@@ -6,12 +6,18 @@
import util
import warnings
+_DISABLED_WARNINGS = (
+ 'block_without_braces',
+ 'function_name_missing',
+ 'function_name_mismatch',
+)
+
def _getwarningsconf():
lines = []
for name in sorted(warnings.warnings.keys()):
message = warnings.warnings[name]
sign = '+'
- if name == 'block_without_braces':
+ if name in _DISABLED_WARNINGS:
sign = '-'
assert len(name) < 29
lines.append(sign + name.ljust(29) + '# ' + message)
@@ -183,7 +189,8 @@
}
for name in warnings.warnings:
self._settings[name] = BooleanSetting(True)
- self.loadline('-block_without_braces')
+ for warning in _DISABLED_WARNINGS:
+ self.loadline('-%s' % warning)
def loadfile(self, path):
path = os.path.abspath(path)
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/javascriptlint/warnings.py 2013-10-01 17:12:20 UTC (rev 325)
@@ -102,6 +102,9 @@
'unsupported_version': 'JavaScript {version} is not supported',
'incorrect_version': 'Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version.',
'for_in_missing_identifier': 'for..in should have identifier on left side',
+ 'misplaced_function': 'unconventional use of function expression',
+ 'function_name_missing': 'anonymous function should be named to match property name {name}',
+ 'function_name_mismatch': 'function name {fn_name} does not match property name {prop_name}',
}
errors = {
@@ -604,6 +607,87 @@
if not left.kind in (tok.VAR, tok.NAME):
raise LintWarning, left
+@lookfor(tok.FUNCTION)
+def misplaced_function(node):
+ # Ignore function statements.
+ if node.opcode in (None, op.CLOSURE):
+ return
+
+ # Ignore parens.
+ parent = node.parent
+ while parent.kind == tok.RP:
+ parent = parent.parent
+
+ # Allow x = x || ...
+ if parent.kind == tok.OR and len(parent.kids) == 2 and \
+ node is parent.kids[-1]:
+ parent = parent.parent
+
+ if parent.kind == tok.NAME and parent.opcode == op.SETNAME:
+ return # Allow in var statements
+ if parent.kind == tok.ASSIGN and parent.opcode == op.NOP:
+ return # Allow in assigns
+ if parent.kind == tok.COLON and parent.parent.kind == tok.RC:
+ return # Allow in object literals
+ if parent.kind == tok.LP and parent.opcode in (op.CALL, op.SETCALL):
+ return # Allow in parameters
+ if parent.kind == tok.RETURN:
+ return # Allow for return values
+ if parent.kind == tok.NEW:
+ return # Allow as constructors
+ raise LintWarning, node
+
+def _get_expected_function_name(node):
+ # Ignore function statements.
+ if node.opcode in (None, op.CLOSURE):
+ return
+
+ # Ignore parens.
+ parent = node.parent
+ while parent.kind == tok.RP:
+ parent = parent.parent
+
+ # Allow x = x || ...
+ if parent.kind == tok.OR and len(parent.kids) == 2 and \
+ node is parent.kids[-1]:
+ parent = parent.parent
+
+ # Var assignment.
+ if parent.kind == tok.NAME and parent.opcode == op.SETNAME:
+ return parent.atom
+
+ # Assignment.
+ if parent.kind == tok.ASSIGN and parent.opcode == op.NOP:
+ if parent.kids[0].kind == tok.NAME and \
+ parent.kids[0].opcode == op.SETNAME:
+ return parent.kids[0].atom
+ return '<error>'
+
+ # Object literal.
+ if parent.kind == tok.COLON and parent.parent.kind == tok.RC:
+ return parent.kids[0].atom
+
+@lookfor(tok.FUNCTION)
+def function_name_missing(node):
+ if node.fn_name:
+ return
+
+ expected_name = _get_expected_function_name(node)
+ if not expected_name is None:
+ raise LintWarning(node, name=expected_name)
+
+@lookfor(tok.FUNCTION)
+def function_name_mismatch(node):
+ if not node.fn_name:
+ return
+
+ expected_name = _get_expected_function_name(node)
+ if expected_name is None:
+ return
+
+ if expected_name != node.fn_name:
+ raise LintWarning(node, fn_name=node.fn_name, prop_name=expected_name)
+
@lookfor()
def mismatch_ctrl_comments(node):
pass
Modified: trunk/tests/control_comments/option_explicit.js
===================================================================
--- trunk/tests/control_comments/option_explicit.js 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/tests/control_comments/option_explicit.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -62,7 +62,7 @@
// This should be undeclared because this is an expression,
// not a declaration.
- (function func_expr() { /*warning:want_assign_or_call*/
+ (function func_expr() { /*warning:misplaced_function*/ /*warning:want_assign_or_call*/
return 10;
});
j = func_expr(); /*warning:undeclared_identifier*/
Added: trunk/tests/warnings/function_name_mismatch.js
===================================================================
--- trunk/tests/warnings/function_name_mismatch.js (rev 0)
+++ trunk/tests/warnings/function_name_mismatch.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -0,0 +1,36 @@
+/*conf:+function_name_mismatch*/
+function function_name_mismatch() {
+ var f = function bogus() { /*warning:function_name_mismatch*/
+ };
+ var g = function g() {
+ };
+
+ f = new function bogus() {
+ };
+ f = new function() {
+ };
+
+ f = (function() {
+ return 10;
+ })();
+
+ var o = {
+ f: function bogus() { /*warning:function_name_mismatch*/
+ return null;
+ }
+ };
+ o.a.b = {
+ f: function bogus() { /*warning:function_name_mismatch*/
+ return null;
+ }
+ };
+ o.a.b = o.a.b || function bogus() { return 10; }; /*warning:function_name_mismatch*/
+
+ function closure(a) {
+ return function() { return a; };
+ }
+
+ function x() {
+ }
+}
+
Added: trunk/tests/warnings/function_name_missing.js
===================================================================
--- trunk/tests/warnings/function_name_missing.js (rev 0)
+++ trunk/tests/warnings/function_name_missing.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -0,0 +1,30 @@
+/*conf:+function_name_missing*/
+function function_name_missing() {
+ var f = function() { /*warning:function_name_missing*/
+ };
+ f = new function() {
+ };
+ f = (function() {
+ return 10;
+ })();
+
+ var o = {
+ f: function() { /*warning:function_name_missing*/
+ return null;
+ }
+ };
+ o.a.b = {
+ f: function() { /*warning:function_name_missing*/
+ return null;
+ }
+ };
+ o.a.b = o.a.b || function() { return 10; }; /*warning:function_name_missing*/
+
+ function closure(a) {
+ return function() { return a; };
+ }
+
+ function x() {
+ }
+}
+
Added: trunk/tests/warnings/misplaced_function.js
===================================================================
--- trunk/tests/warnings/misplaced_function.js (rev 0)
+++ trunk/tests/warnings/misplaced_function.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -0,0 +1,33 @@
+/*conf:-want_assign_or_call*/
+function misplaced_functions() {
+ var f = function() {
+ };
+ f = new function() {
+ };
+ f = (function() {
+ return 10;
+ })();
+
+ var o = {
+ f: function() {
+ return null;
+ }
+ };
+ o.a.b = {
+ f: function() {
+ return null;
+ }
+ };
+ o.a.b = o.a.b || function() { return 10; };
+ o.a.b = o.a.c || function() { return 10; }; /*TODO*/
+
+ function closure(a) {
+ return function() { return a; };
+ }
+
+ function x() {
+ }
+
+ function() {}; /*warning:misplaced_function*/
+}
+
Modified: trunk/tests/warnings/want_assign_or_call.js
===================================================================
--- trunk/tests/warnings/want_assign_or_call.js 2013-10-01 17:07:11 UTC (rev 324)
+++ trunk/tests/warnings/want_assign_or_call.js 2013-10-01 17:12:20 UTC (rev 325)
@@ -14,7 +14,7 @@
function test() {
}
- function() { /*warning:want_assign_or_call*/
+ function() { /*warning:want_assign_or_call*/ /*warning:misplaced_function*/
return 42;
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-10-01 17:07:15
|
Revision: 324
http://sourceforge.net/p/javascriptlint/code/324
Author: matthiasmiller
Date: 2013-10-01 17:07:11 +0000 (Tue, 01 Oct 2013)
Log Message:
-----------
Correctly handle top-level function declarations.
Modified Paths:
--------------
trunk/javascriptlint/lint.py
trunk/tests/control_comments/option_explicit.js
trunk/tests/warnings/redeclared_var.js
trunk/tests/warnings/unreferenced_identifier.js
Modified: trunk/javascriptlint/lint.py
===================================================================
--- trunk/javascriptlint/lint.py 2013-09-30 23:16:37 UTC (rev 323)
+++ trunk/javascriptlint/lint.py 2013-10-01 17:07:11 UTC (rev 324)
@@ -609,7 +609,7 @@
@visitation.visit('push', tok.FUNCTION)
def _push_func(self, node):
- if node.opcode != op.CLOSURE and node.fn_name:
+ if node.opcode in (None, op.CLOSURE) and node.fn_name:
_warn_or_declare(scopes[-1], node.fn_name, 'function', node, report)
self._push_scope(node)
for var_name in node.fn_args:
Modified: trunk/tests/control_comments/option_explicit.js
===================================================================
--- trunk/tests/control_comments/option_explicit.js 2013-09-30 23:16:37 UTC (rev 323)
+++ trunk/tests/control_comments/option_explicit.js 2013-10-01 17:07:11 UTC (rev 324)
@@ -65,7 +65,10 @@
(function func_expr() { /*warning:want_assign_or_call*/
return 10;
});
- j = func_expr();
+ j = func_expr(); /*warning:undeclared_identifier*/
return "";
}
+
+// Ensure that we can reference top-level functions.
+option_explicit(null);
Modified: trunk/tests/warnings/redeclared_var.js
===================================================================
--- trunk/tests/warnings/redeclared_var.js 2013-09-30 23:16:37 UTC (rev 323)
+++ trunk/tests/warnings/redeclared_var.js 2013-10-01 17:07:11 UTC (rev 324)
@@ -7,4 +7,9 @@
return;
}
var myFunction; /*warning:redeclared_var*/
+
+ // myFunction isn't a redeclaration, since function names in function
+ // expressions don't matter.
+ var tmp = function myFunction(){};
+ /*jsl:unused tmp*/
}
Modified: trunk/tests/warnings/unreferenced_identifier.js
===================================================================
--- trunk/tests/warnings/unreferenced_identifier.js 2013-09-30 23:16:37 UTC (rev 323)
+++ trunk/tests/warnings/unreferenced_identifier.js 2013-10-01 17:07:11 UTC (rev 324)
@@ -74,8 +74,10 @@
tmp = ref_dec--; /*warning:inc_dec_within_stmt*/
tmp = -tmp;
- /* Test named functions as references. */
- var fn = function ref_func() { return 42; }; /*warning:unreferenced_function*/
+ /* Test named functions as references.
+ * (The name is ignored since it's a function expression.)
+ */
+ var fn = function ref_func() { return 42; };
fn();
/* Test nested scopes. */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 23:16:40
|
Revision: 323
http://sourceforge.net/p/javascriptlint/code/323
Author: matthiasmiller
Date: 2013-09-30 23:16:37 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Function expressions should not declare a variable.
Modified Paths:
--------------
trunk/javascriptlint/lint.py
trunk/jsengine/parser/__init__.py
trunk/tests/control_comments/option_explicit.js
Modified: trunk/javascriptlint/lint.py
===================================================================
--- trunk/javascriptlint/lint.py 2013-09-30 21:54:32 UTC (rev 322)
+++ trunk/javascriptlint/lint.py 2013-09-30 23:16:37 UTC (rev 323)
@@ -609,7 +609,7 @@
@visitation.visit('push', tok.FUNCTION)
def _push_func(self, node):
- if node.fn_name:
+ if node.opcode != op.CLOSURE and node.fn_name:
_warn_or_declare(scopes[-1], node.fn_name, 'function', node, report)
self._push_scope(node)
for var_name in node.fn_args:
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-09-30 21:54:32 UTC (rev 322)
+++ trunk/jsengine/parser/__init__.py 2013-09-30 23:16:37 UTC (rev 323)
@@ -162,10 +162,8 @@
fn_body_endpos = t.expect(tok.RBRACE).endpos
fn_body = ParseNode(kind.LC, None, fn_body_startpos,
fn_body_endpos, None, kids)
- return ParseNode(kind.FUNCTION,
- op.ANONFUNOBJ if fn_name is None else op.NAMEDFUNOBJ,
- startpos, fn_body.endpos,
- fn_name, [fn_body], fn_args=fn_args)
+ return ParseNode(kind.FUNCTION, opcode, startpos, fn_body.endpos,
+ fn_name, [fn_body], fn_args=fn_args)
def _argument_list(t):
args = []
Modified: trunk/tests/control_comments/option_explicit.js
===================================================================
--- trunk/tests/control_comments/option_explicit.js 2013-09-30 21:54:32 UTC (rev 322)
+++ trunk/tests/control_comments/option_explicit.js 2013-09-30 23:16:37 UTC (rev 323)
@@ -60,5 +60,12 @@
/* illegal */
y(); /*warning:undeclared_identifier*/
+ // This should be undeclared because this is an expression,
+ // not a declaration.
+ (function func_expr() { /*warning:want_assign_or_call*/
+ return 10;
+ });
+ j = func_expr();
+
return "";
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 21:54:35
|
Revision: 322
http://sourceforge.net/p/javascriptlint/code/322
Author: matthiasmiller
Date: 2013-09-30 21:54:32 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Fix single-line returns without semicolons.
Modified Paths:
--------------
trunk/jsengine/parser/__init__.py
Added Paths:
-----------
trunk/tests/bugs/one_line_return.js
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-09-30 21:19:27 UTC (rev 321)
+++ trunk/jsengine/parser/__init__.py 2013-09-30 21:54:32 UTC (rev 322)
@@ -638,7 +638,7 @@
endtoken = t.expect(tok.RETURN)
startpos = endtoken.startpos
- if t.peek_sameline().tok not in (tok.EOF, tok.EOL, tok.SEMI):
+ if t.peek_sameline().tok not in (tok.EOF, tok.EOL, tok.SEMI, tok.RBRACE):
expr = _expression(t, True)
endtoken = expr
else:
Added: trunk/tests/bugs/one_line_return.js
===================================================================
--- trunk/tests/bugs/one_line_return.js (rev 0)
+++ trunk/tests/bugs/one_line_return.js 2013-09-30 21:54:32 UTC (rev 322)
@@ -0,0 +1,2 @@
+function one_line_return() { return } /*warning:missing_semicolon*/
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 21:19:29
|
Revision: 321
http://sourceforge.net/p/javascriptlint/code/321
Author: matthiasmiller
Date: 2013-09-30 21:19:27 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Don't warning against increment/decrement assignments in expressions.
Modified Paths:
--------------
trunk/javascriptlint/warnings.py
trunk/tests/warnings/equal_as_assign.js
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-09-30 21:11:45 UTC (rev 320)
+++ trunk/javascriptlint/warnings.py 2013-09-30 21:19:27 UTC (rev 321)
@@ -322,7 +322,7 @@
if kid.kind == tok.LP:
raise LintWarning, node
-@lookfor(tok.ASSIGN)
+@lookfor((tok.ASSIGN, None))
def equal_as_assign(node):
# Allow in VAR statements.
if node.parent.parent and node.parent.parent.kind == tok.VAR:
Modified: trunk/tests/warnings/equal_as_assign.js
===================================================================
--- trunk/tests/warnings/equal_as_assign.js 2013-09-30 21:11:45 UTC (rev 320)
+++ trunk/tests/warnings/equal_as_assign.js 2013-09-30 21:19:27 UTC (rev 321)
@@ -4,6 +4,9 @@
while (a = b) { /*warning:equal_as_assign*/
a++;
}
+ while (a -= b) {
+ a--;
+ }
var c;
a = b = c;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 21:11:48
|
Revision: 320
http://sourceforge.net/p/javascriptlint/code/320
Author: matthiasmiller
Date: 2013-09-30 21:11:45 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Allow chained assignments in VAR statements.
Modified Paths:
--------------
trunk/javascriptlint/warnings.py
trunk/tests/warnings/equal_as_assign.js
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-09-30 21:03:23 UTC (rev 319)
+++ trunk/javascriptlint/warnings.py 2013-09-30 21:11:45 UTC (rev 320)
@@ -324,6 +324,10 @@
@lookfor(tok.ASSIGN)
def equal_as_assign(node):
+ # Allow in VAR statements.
+ if node.parent.parent and node.parent.parent.kind == tok.VAR:
+ return
+
if not node.parent.kind in (tok.SEMI, tok.RESERVED, tok.RP, tok.COMMA,
tok.ASSIGN):
raise LintWarning, node
Modified: trunk/tests/warnings/equal_as_assign.js
===================================================================
--- trunk/tests/warnings/equal_as_assign.js 2013-09-30 21:03:23 UTC (rev 319)
+++ trunk/tests/warnings/equal_as_assign.js 2013-09-30 21:11:45 UTC (rev 320)
@@ -7,4 +7,7 @@
var c;
a = b = c;
+
+ var x, y, z;
+ var w = x = y = z;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 21:03:26
|
Revision: 319
http://sourceforge.net/p/javascriptlint/code/319
Author: matthiasmiller
Date: 2013-09-30 21:03:23 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Allow chained assigns.
Modified Paths:
--------------
trunk/javascriptlint/warnings.py
trunk/tests/warnings/equal_as_assign.js
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-09-30 20:59:56 UTC (rev 318)
+++ trunk/javascriptlint/warnings.py 2013-09-30 21:03:23 UTC (rev 319)
@@ -324,7 +324,8 @@
@lookfor(tok.ASSIGN)
def equal_as_assign(node):
- if not node.parent.kind in (tok.SEMI, tok.RESERVED, tok.RP, tok.COMMA):
+ if not node.parent.kind in (tok.SEMI, tok.RESERVED, tok.RP, tok.COMMA,
+ tok.ASSIGN):
raise LintWarning, node
@lookfor(tok.IF)
Modified: trunk/tests/warnings/equal_as_assign.js
===================================================================
--- trunk/tests/warnings/equal_as_assign.js 2013-09-30 20:59:56 UTC (rev 318)
+++ trunk/tests/warnings/equal_as_assign.js 2013-09-30 21:03:23 UTC (rev 319)
@@ -4,4 +4,7 @@
while (a = b) { /*warning:equal_as_assign*/
a++;
}
+
+ var c;
+ a = b = c;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 20:59:58
|
Revision: 318
http://sourceforge.net/p/javascriptlint/code/318
Author: matthiasmiller
Date: 2013-09-30 20:59:56 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Fix case preservation in control comments.
Modified Paths:
--------------
trunk/javascriptlint/lint.py
trunk/tests/warnings/unreferenced_identifier.js
Modified: trunk/javascriptlint/lint.py
===================================================================
--- trunk/javascriptlint/lint.py 2013-09-30 20:53:58 UTC (rev 317)
+++ trunk/javascriptlint/lint.py 2013-09-30 20:59:56 UTC (rev 318)
@@ -48,8 +48,8 @@
def _parse_control_comment(comment):
""" Returns None or (keyword, parms) """
- comment_atom = comment.atom.lower().strip()
- if comment_atom.startswith('jsl:'):
+ comment_atom = comment.atom.strip()
+ 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]
@@ -70,8 +70,8 @@
)
for keyword in keywords:
# The keyword must either match or be separated by a space.
- if control_comment == keyword or \
- (control_comment.startswith(keyword) and \
+ if control_comment.lower() == keyword or \
+ (control_comment.lower().startswith(keyword) and \
control_comment[len(keyword)].isspace()):
parms = control_comment[len(keyword):].strip()
return (comment, keyword, parms.strip())
Modified: trunk/tests/warnings/unreferenced_identifier.js
===================================================================
--- trunk/tests/warnings/unreferenced_identifier.js 2013-09-30 20:53:58 UTC (rev 317)
+++ trunk/tests/warnings/unreferenced_identifier.js 2013-09-30 20:59:56 UTC (rev 318)
@@ -98,5 +98,9 @@
}
}
+ function test_unused_camel_case(CamelCaseParm) { /*warning:unreferenced_function*/
+ /*jsl:unused CamelCaseParm*/
+ }
+
return get_callback(42);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-30 20:54:01
|
Revision: 317
http://sourceforge.net/p/javascriptlint/code/317
Author: matthiasmiller
Date: 2013-09-30 20:53:58 +0000 (Mon, 30 Sep 2013)
Log Message:
-----------
Fix number parsing.
Modified Paths:
--------------
trunk/jsengine/structs.py
trunk/jsengine/tokenizer/__init__.py
trunk/tests/warnings/useless_comparison.js
Modified: trunk/jsengine/structs.py
===================================================================
--- trunk/jsengine/structs.py 2013-09-28 19:39:16 UTC (rev 316)
+++ trunk/jsengine/structs.py 2013-09-30 20:53:58 UTC (rev 317)
@@ -125,7 +125,12 @@
else:
assert fn_args is None
if self.kind == kind.NUMBER:
- self.dval = float(self.atom)
+ if self.atom.lower().startswith('0x'):
+ self.dval = int(self.atom, 16)
+ elif self.atom.startswith('0') and self.atom.isdigit():
+ self.dval = int(self.atom, 8)
+ else:
+ self.dval = float(self.atom)
def start_pos(self):
return self.startpos
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-09-28 19:39:16 UTC (rev 316)
+++ trunk/jsengine/tokenizer/__init__.py 2013-09-30 20:53:58 UTC (rev 317)
@@ -378,27 +378,32 @@
s = c # TODO
stream.watch_reads()
if c == '0' and stream.readif(1, 'xX'):
+ # Hex
while stream.readif(1, _HEX_DIGITS):
pass
- return Token(tok.NUMBER, atom=stream.get_watched_reads())
-
- if c != '.':
+ elif c == '0' and stream.readif(1, _DIGITS):
+ # Octal
while stream.readif(1, _DIGITS):
pass
- stream.readif(1, '.')
+ else:
+ # Decimal
+ if c != '.':
+ while stream.readif(1, _DIGITS):
+ pass
+ stream.readif(1, '.')
- while stream.readif(1, _DIGITS):
- pass
-
- if stream.readif(1, 'eE'):
- stream.readif(1, '+-')
- stream.require(_DIGITS)
while stream.readif(1, _DIGITS):
pass
- if stream.peekchr(_IDENT):
- return Token(tok.ERROR)
+ if stream.readif(1, 'eE'):
+ stream.readif(1, '+-')
+ stream.require(_DIGITS)
+ while stream.readif(1, _DIGITS):
+ pass
+ if stream.peekchr(_IDENT):
+ return Token(tok.ERROR)
+
atom = s + stream.get_watched_reads()
return Token(tok.NUMBER, atom=atom)
Modified: trunk/tests/warnings/useless_comparison.js
===================================================================
--- trunk/tests/warnings/useless_comparison.js 2013-09-28 19:39:16 UTC (rev 316)
+++ trunk/tests/warnings/useless_comparison.js 2013-09-30 20:53:58 UTC (rev 317)
@@ -60,4 +60,10 @@
return;
if (i == 3 == j == 3) /*warning:useless_comparison*/
return;
+
+ // Test bases
+ if (010 == 8) /*warning:useless_comparison*/ /*warning:octal_number*/
+ return;
+ if (0xA == 10) /*warning:useless_comparison*/
+ return;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-28 19:39:24
|
Revision: 316
http://sourceforge.net/p/javascriptlint/code/316
Author: matthiasmiller
Date: 2013-09-28 19:39:16 +0000 (Sat, 28 Sep 2013)
Log Message:
-----------
Fix unexpected-eof warning.
Modified Paths:
--------------
trunk/javascriptlint/warnings.py
trunk/jsengine/__init__.py
trunk/jsengine/parser/__init__.py
trunk/jsengine/tokenizer/__init__.py
trunk/tests/warnings/useless_comparison.js
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-09-28 05:00:30 UTC (rev 315)
+++ trunk/javascriptlint/warnings.py 2013-09-28 19:39:16 UTC (rev 316)
@@ -110,6 +110,7 @@
'syntax_error': 'syntax error',
'expected_tok': 'expected token: {token}',
'unexpected_char': 'unexpected character: {char}',
+ 'unexpected_eof': 'unexpected end of file',
}
def format_error(errname, **errargs):
Modified: trunk/jsengine/__init__.py
===================================================================
--- trunk/jsengine/__init__.py 2013-09-28 05:00:30 UTC (rev 315)
+++ trunk/jsengine/__init__.py 2013-09-28 19:39:16 UTC (rev 316)
@@ -1,7 +1,7 @@
# vim: sw=4 ts=4 et
_MESSAGES = (
- 'eof',
+ 'unexpected_eof',
'semi_before_stmnt',
'syntax_error',
'unterminated_comment',
Modified: trunk/jsengine/parser/__init__.py
===================================================================
--- trunk/jsengine/parser/__init__.py 2013-09-28 05:00:30 UTC (rev 315)
+++ trunk/jsengine/parser/__init__.py 2013-09-28 19:39:16 UTC (rev 316)
@@ -781,7 +781,7 @@
elif x.tok == tok.TRY:
return _try_statement(t)
elif x.tok == tok.EOF:
- raise JSSyntaxError(x.startpos, 'eof')
+ raise JSSyntaxError(x.startpos, 'unexpected_eof')
elif x.tok == tok.FUNCTION:
return _function_declaration(t, op.CLOSURE) #TODO: warn, since this is not reliable
@@ -844,7 +844,7 @@
try:
parsestring(script)
except JSSyntaxError as error:
- return error.msg not in ('eof', 'unterminated_comment')
+ return error.msg not in ('unexpected_eof', 'unterminated_comment')
return True
class TestParser(unittest.TestCase):
Modified: trunk/jsengine/tokenizer/__init__.py
===================================================================
--- trunk/jsengine/tokenizer/__init__.py 2013-09-28 05:00:30 UTC (rev 315)
+++ trunk/jsengine/tokenizer/__init__.py 2013-09-28 19:39:16 UTC (rev 316)
@@ -176,7 +176,7 @@
if self._pos < len(self._content):
self._pos += 1
return self._content[self._pos - 1]
- raise JSSyntaxError(self.getpos(-1), 'eof')
+ raise JSSyntaxError(self.getpos(-1), 'unexpected_eof')
def readif(self, len_, seq):
s = self.peekif(len_, seq)
Modified: trunk/tests/warnings/useless_comparison.js
===================================================================
--- trunk/tests/warnings/useless_comparison.js 2013-09-28 05:00:30 UTC (rev 315)
+++ trunk/tests/warnings/useless_comparison.js 2013-09-28 19:39:16 UTC (rev 316)
@@ -59,5 +59,5 @@
if (i == 3 == i) /*warning:useless_comparison*/
return;
if (i == 3 == j == 3) /*warning:useless_comparison*/
- return;}
+ return;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-28 05:00:33
|
Revision: 315
http://sourceforge.net/p/javascriptlint/code/315
Author: matthiasmiller
Date: 2013-09-28 05:00:30 +0000 (Sat, 28 Sep 2013)
Log Message:
-----------
Warn against multiple useless comparison (e.g. a == a == b)
Modified Paths:
--------------
trunk/javascriptlint/warnings.py
trunk/tests/warnings/useless_comparison.js
Modified: trunk/javascriptlint/warnings.py
===================================================================
--- trunk/javascriptlint/warnings.py 2013-09-28 04:50:25 UTC (rev 314)
+++ trunk/javascriptlint/warnings.py 2013-09-28 05:00:30 UTC (rev 315)
@@ -14,6 +14,7 @@
if questionable:
raise LintWarning, node
"""
+import itertools
import re
import sys
import types
@@ -287,9 +288,9 @@
@lookfor(tok.EQOP,tok.RELOP)
def useless_comparison(node):
- lvalue, rvalue = node.kids
- if lvalue.is_equivalent(rvalue):
- raise LintWarning, node
+ for lvalue, rvalue in itertools.combinations(node.kids, 2):
+ if lvalue.is_equivalent(rvalue):
+ raise LintWarning, node
@lookfor((tok.COLON, op.NAME))
def use_of_label(node):
Modified: trunk/tests/warnings/useless_comparison.js
===================================================================
--- trunk/tests/warnings/useless_comparison.js 2013-09-28 04:50:25 UTC (rev 314)
+++ trunk/tests/warnings/useless_comparison.js 2013-09-28 05:00:30 UTC (rev 315)
@@ -52,4 +52,12 @@
if (useless_comparison() == useless_comparison()) {
return;
}
+
+ // Test multiple comparisons.
+ if (i == i == 3) /*warning:useless_comparison*/
+ return;
+ if (i == 3 == i) /*warning:useless_comparison*/
+ return;
+ if (i == 3 == j == 3) /*warning:useless_comparison*/
+ return;}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-28 04:50:28
|
Revision: 314
http://sourceforge.net/p/javascriptlint/code/314
Author: matthiasmiller
Date: 2013-09-28 04:50:25 +0000 (Sat, 28 Sep 2013)
Log Message:
-----------
#32 Crashing on valid regex string
Additional test case
Added Paths:
-----------
trunk/tests/html/script_tag_in_regexp.js
Added: trunk/tests/html/script_tag_in_regexp.js
===================================================================
--- trunk/tests/html/script_tag_in_regexp.js (rev 0)
+++ trunk/tests/html/script_tag_in_regexp.js 2013-09-28 04:50:25 UTC (rev 314)
@@ -0,0 +1 @@
+var re = /<script(.|\s)*?\/script>/g;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mat...@us...> - 2013-09-28 04:48:21
|
Revision: 313
http://sourceforge.net/p/javascriptlint/code/313
Author: matthiasmiller
Date: 2013-09-28 04:48:18 +0000 (Sat, 28 Sep 2013)
Log Message:
-----------
#32 Crashing on valid regex string
Add a test case to confirm this works.
Added Paths:
-----------
trunk/tests/html/script_tag_in_regexp.html
Added: trunk/tests/html/script_tag_in_regexp.html
===================================================================
--- trunk/tests/html/script_tag_in_regexp.html (rev 0)
+++ trunk/tests/html/script_tag_in_regexp.html 2013-09-28 04:48:18 UTC (rev 313)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+ <title>JavaScript Lint Test Page</title>
+ <script type="text/javascript"><!--
+ var re = /<script(.|\s)*?\/script>/g;
+ /*jsl:unused re*/
+ //-->
+ </script>
+</head>
+<body>
+</body>
+</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|