(self, token_info)
Adds the given token info to the stack.

    Args:
      token_info: The token information to add.
Adds the given token info to the stack.
Adds the given token info to the stack .
def _Add(self, token_info):
    """Adds the given token info to the stack.

    Args:
      token_info: The token information to add.
    """
    if self._stack and self._stack[-1].token == token_info.token:
      # Don't add the same token twice.
      return

    if token_info.is_block or token_info.token.type == Type.START_PAREN:
      index = 1
      while index <= len(self._stack):
        stack_info = self._stack[-index]
        stack_token = stack_info.token

        if stack_info.line_number == token_info.line_number:
          # In general, tokens only override each other when they are on
          # the same line.
          stack_info.overridden_by = token_info
          if (token_info.token.type == Type.START_BLOCK and
              (stack_token.IsAssignment() or
               stack_token.type in (Type.IDENTIFIER, Type.START_PAREN))):
            # Multi-line blocks have lasting overrides, as in:
            # callFn({
            #   a: 10
            # },
            # 30);
            close_block = token_info.token.metadata.context.end_token
            stack_info.is_permanent_override = \
                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
               stack_token.type == Type.IDENTIFIER)):
          # When starting a function block, the override can transcend lines.
          # For example
          # long.long.name = function(
          #     a) {
          # In this case the { and the = are on different lines.  But the
          # override should still apply.
          stack_info.overridden_by = token_info
          stack_info.is_permanent_override = True
        else:
          break
        index += 1

    self._stack.append(token_info)
def _Add ( self , token_info ) : if self . _stack and self . _stack [ - 1 ] . token == token_info . token : # Don't add the same token twice. return if token_info . is_block or token_info . token . type == Type . START_PAREN : index = 1 while index <= len ( self . _stack ) : stack_info = self . _stack [ - index ] stack_token = stack_info . token if stack_info . line_number == token_info . line_number : # In general, tokens only override each other when they are on # the same line. stack_info . overridden_by = token_info if ( token_info . token . type == Type . START_BLOCK and ( stack_token . IsAssignment ( ) or stack_token . type in ( Type . IDENTIFIER , Type . START_PAREN ) ) ) : # Multi-line blocks have lasting overrides, as in: # callFn({ #   a: 10 # }, # 30); close_block = token_info . token . metadata . context . end_token stack_info . is_permanent_override = 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 stack_token . type == Type . IDENTIFIER ) ) : # When starting a function block, the override can transcend lines. # For example # long.long.name = function( #     a) { # In this case the { and the = are on different lines.  But the # override should still apply. stack_info . overridden_by = token_info stack_info . is_permanent_override = True else : break index += 1 self . _stack . append ( token_info )