| Index: third_party/closure_linter/closure_linter/javascriptstatetracker.py
|
| diff --git a/third_party/closure_linter/closure_linter/javascriptstatetracker.py b/third_party/closure_linter/closure_linter/javascriptstatetracker.py
|
| index 2ce5c02c6c4af432b049adf0faaf46893c33e80e..1b051d3bf6bd2de91ee6fd318a14e16ea2469819 100755
|
| --- a/third_party/closure_linter/closure_linter/javascriptstatetracker.py
|
| +++ b/third_party/closure_linter/closure_linter/javascriptstatetracker.py
|
| @@ -1,5 +1,4 @@
|
| #!/usr/bin/env python
|
| -#
|
| # Copyright 2008 The Closure Linter Authors. All Rights Reserved.
|
| #
|
| # Licensed under the Apache License, Version 2.0 (the "License");
|
| @@ -50,7 +49,7 @@ class JsDocFlag(statetracker.DocFlag):
|
| # TODO(robbyw): determine which of these, if any, should be illegal.
|
| EXTENDED_DOC = frozenset([
|
| 'class', 'code', 'desc', 'final', 'hidden', 'inheritDoc', 'link',
|
| - 'meaning', 'protected', 'notypecheck', 'throws'])
|
| + 'meaning', 'provideGoog', 'throws'])
|
|
|
| LEGAL_DOC = EXTENDED_DOC | statetracker.DocFlag.LEGAL_DOC
|
|
|
| @@ -74,6 +73,11 @@ class JavaScriptStateTracker(statetracker.StateTracker):
|
| """Initializes a JavaScript token stream state tracker."""
|
| statetracker.StateTracker.__init__(self, JsDocFlag)
|
|
|
| + def Reset(self):
|
| + self._scope_depth = 0
|
| + self._block_stack = []
|
| + super(JavaScriptStateTracker, self).Reset()
|
| +
|
| def InTopLevel(self):
|
| """Compute whether we are at the top level in the class.
|
|
|
| @@ -85,7 +89,26 @@ class JavaScriptStateTracker(statetracker.StateTracker):
|
| Returns:
|
| Whether we are at the top level in the class.
|
| """
|
| - return not self.InParentheses()
|
| + return self._scope_depth == self.ParenthesesDepth()
|
| +
|
| + def InFunction(self):
|
| + """Returns true if the current token is within a function.
|
| +
|
| + This js-specific override ignores goog.scope functions.
|
| +
|
| + Returns:
|
| + True if the current token is within a function.
|
| + """
|
| + return self._scope_depth != self.FunctionDepth()
|
| +
|
| + def InNonScopeBlock(self):
|
| + """Compute whether we are nested within a non-goog.scope block.
|
| +
|
| + Returns:
|
| + True if the token is not enclosed in a block that does not originate from
|
| + a goog.scope statement. False otherwise.
|
| + """
|
| + return self._scope_depth != self.BlockDepth()
|
|
|
| def GetBlockType(self, token):
|
| """Determine the block type given a START_BLOCK token.
|
| @@ -97,20 +120,38 @@ class JavaScriptStateTracker(statetracker.StateTracker):
|
| Returns:
|
| Code block type for current token.
|
| """
|
| - last_code = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES, None,
|
| - True)
|
| + last_code = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES, reverse=True)
|
| if last_code.type in (Type.END_PARAMETERS, Type.END_PAREN,
|
| Type.KEYWORD) and not last_code.IsKeyword('return'):
|
| return self.CODE
|
| else:
|
| return self.OBJECT_LITERAL
|
|
|
| + def GetCurrentBlockStart(self):
|
| + """Gets the start token of current block.
|
| +
|
| + Returns:
|
| + Starting token of current block. None if not in block.
|
| + """
|
| + if self._block_stack:
|
| + return self._block_stack[-1]
|
| + else:
|
| + return None
|
| +
|
| def HandleToken(self, token, last_non_space_token):
|
| """Handles the given token and updates state.
|
|
|
| Args:
|
| token: The token to handle.
|
| - last_non_space_token:
|
| + last_non_space_token: The last non space token encountered
|
| """
|
| + if token.type == Type.START_BLOCK:
|
| + self._block_stack.append(token)
|
| + if token.type == Type.IDENTIFIER and token.string == 'goog.scope':
|
| + self._scope_depth += 1
|
| + if token.type == Type.END_BLOCK:
|
| + start_token = self._block_stack.pop()
|
| + if tokenutil.GoogScopeOrNoneFromStartBlock(start_token):
|
| + self._scope_depth -= 1
|
| super(JavaScriptStateTracker, self).HandleToken(token,
|
| last_non_space_token)
|
|
|