parameters: (self, token_info)
docstring: Adds the given token info to the stack.
  
      Args:
        token_info: The token information to add.
docstring_summary: Adds the given token info to the stack.
docstring_tokens: Adds the given token info to the stack .
function: 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)
function_tokens: 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 )