Index: third_party/closure_linter/closure_linter/indentation.py |
diff --git a/third_party/closure_linter/closure_linter/indentation.py b/third_party/closure_linter/closure_linter/indentation.py |
index cb97853a91c42f0f4f8c08b3c081797372883c36..0abb25b149a0111aa8be38ff1eee7534a708bf43 100755 |
--- a/third_party/closure_linter/closure_linter/indentation.py |
+++ b/third_party/closure_linter/closure_linter/indentation.py |
@@ -1,5 +1,4 @@ |
#!/usr/bin/env python |
-# |
# Copyright 2010 The Closure Linter Authors. All Rights Reserved. |
# |
# Licensed under the Apache License, Version 2.0 (the "License"); |
@@ -18,6 +17,8 @@ |
__author__ = ('robbyw@google.com (Robert Walker)') |
+import gflags as flags |
+ |
from closure_linter import ecmametadatapass |
from closure_linter import errors |
from closure_linter import javascripttokens |
@@ -25,7 +26,6 @@ from closure_linter import tokenutil |
from closure_linter.common import error |
from closure_linter.common import position |
-import gflags as flags |
flags.DEFINE_boolean('debug_indentation', False, |
'Whether to print debugging information for indentation.') |
@@ -89,7 +89,7 @@ class TokenInfo(object): |
self.overridden_by = None |
self.is_permanent_override = False |
self.is_block = is_block |
- self.is_transient = not is_block and not token.type in ( |
+ self.is_transient = not is_block and token.type not in ( |
Type.START_PAREN, Type.START_PARAMETERS) |
self.line_number = token.line_number |
@@ -121,7 +121,7 @@ class IndentationRules(object): |
if self._stack: |
old_stack = self._stack |
self._stack = [] |
- raise Exception("INTERNAL ERROR: indentation stack is not empty: %r" % |
+ raise Exception('INTERNAL ERROR: indentation stack is not empty: %r' % |
old_stack) |
def CheckToken(self, token, state): |
@@ -155,7 +155,7 @@ class IndentationRules(object): |
start_token = self._PopTo(Type.START_BLOCK) |
# Check for required goog.scope comment. |
if start_token: |
- goog_scope = self._GoogScopeOrNone(start_token.token) |
+ goog_scope = tokenutil.GoogScopeOrNoneFromStartBlock(start_token.token) |
if goog_scope is not None: |
if not token.line.endswith('; // goog.scope\n'): |
if (token.line.find('//') > -1 and |
@@ -230,7 +230,8 @@ class IndentationRules(object): |
# Add tokens that could increase indentation. |
if token_type == Type.START_BRACKET: |
- self._Add(TokenInfo(token=token, |
+ self._Add(TokenInfo( |
+ token=token, |
is_block=token.metadata.context.type == Context.ARRAY_LITERAL)) |
elif token_type == Type.START_BLOCK or token.metadata.is_implied_block: |
@@ -255,10 +256,10 @@ class IndentationRules(object): |
if is_last: |
if token_type == Type.OPERATOR: |
if token.string == ':': |
- if (stack and stack[-1].token.string == '?'): |
+ if stack and stack[-1].token.string == '?': |
# When a ternary : is on a different line than its '?', it doesn't |
# add indentation. |
- if (token.line_number == stack[-1].token.line_number): |
+ if token.line_number == stack[-1].token.line_number: |
self._Add(TokenInfo(token)) |
elif token.metadata.context.type == Context.CASE_BLOCK: |
# Pop transient tokens from say, line continuations, e.g., |
@@ -294,6 +295,8 @@ class IndentationRules(object): |
elif token_type == Type.PARAMETERS and token.string.endswith(','): |
# Parameter lists. |
self._Add(TokenInfo(token)) |
+ elif token.IsKeyword('var'): |
+ self._Add(TokenInfo(token)) |
elif token.metadata.is_implied_semicolon: |
self._PopTransient() |
elif token.IsAssignment(): |
@@ -321,6 +324,12 @@ class IndentationRules(object): |
def _IsHardStop(self, token): |
"""Determines if the given token can have a hard stop after it. |
+ Args: |
+ token: token to examine |
+ |
+ Returns: |
+ Whether the token can have a hard stop after it. |
+ |
Hard stops are indentations defined by the position of another token as in |
indentation lined up with return, (, [, and ?. |
""" |
@@ -365,7 +374,8 @@ class IndentationRules(object): |
# Handle hard stops after (, [, return, =, and ? |
if self._IsHardStop(token): |
override_is_hard_stop = (token_info.overridden_by and |
- self._IsHardStop(token_info.overridden_by.token)) |
+ self._IsHardStop( |
+ token_info.overridden_by.token)) |
if not override_is_hard_stop: |
start_index = token.start_index |
if token.line_number in self._start_index_offset: |
@@ -377,7 +387,7 @@ class IndentationRules(object): |
elif token.string == 'return' and not token_info.overridden_by: |
hard_stops.add(start_index + 7) |
- elif (token.type == Type.START_BRACKET): |
+ elif token.type == Type.START_BRACKET: |
hard_stops.add(start_index + 1) |
elif token.IsAssignment(): |
@@ -447,27 +457,6 @@ class IndentationRules(object): |
if token.type not in Type.NON_CODE_TYPES: |
return False |
- def _GoogScopeOrNone(self, token): |
- """Determines if the given START_BLOCK is part of a goog.scope statement. |
- |
- Args: |
- token: A token of type START_BLOCK. |
- |
- Returns: |
- The goog.scope function call token, or None if such call doesn't exist. |
- """ |
- # Search for a goog.scope statement, which will be 5 tokens before the |
- # block. Illustration of the tokens found prior to the start block: |
- # goog.scope(function() { |
- # 5 4 3 21 ^ |
- |
- maybe_goog_scope = token |
- for unused_i in xrange(5): |
- maybe_goog_scope = (maybe_goog_scope.previous if maybe_goog_scope and |
- maybe_goog_scope.previous else None) |
- if maybe_goog_scope and maybe_goog_scope.string == 'goog.scope': |
- return maybe_goog_scope |
- |
def _Add(self, token_info): |
"""Adds the given token info to the stack. |
@@ -479,7 +468,8 @@ class IndentationRules(object): |
return |
if token_info.is_block or token_info.token.type == Type.START_PAREN: |
- token_info.overridden_by = self._GoogScopeOrNone(token_info.token) |
+ token_info.overridden_by = ( |
+ tokenutil.GoogScopeOrNoneFromStartBlock(token_info.token)) |
index = 1 |
while index <= len(self._stack): |
stack_info = self._stack[-index] |
@@ -497,9 +487,11 @@ class IndentationRules(object): |
# a: 10 |
# }, |
# 30); |
+ # b/11450054. If a string is not closed properly then close_block |
+ # could be null. |
close_block = token_info.token.metadata.context.end_token |
- stack_info.is_permanent_override = \ |
- close_block.line_number != token_info.token.line_number |
+ stack_info.is_permanent_override = close_block and ( |
+ close_block.line_number != token_info.token.line_number) |
elif (token_info.token.type == Type.START_BLOCK and |
token_info.token.metadata.context.type == Context.BLOCK and |
(stack_token.IsAssignment() or |