class_docstr: Helper that visits all nodes in the AST tree and assigns .first_token and .last_token attributes
  to each of them. This is the heart of the token-marking logic.
class_docstr_tok: ["Helper","that","visits","all","nodes","in","the","AST","tree","and","assigns",".first_token","and",".last_token","attributes","to","each","of","them",".","This","is","the","heart","of","the","token-marking","logic","."]
code: def visit_joinedstr(
      self,
      node,  # type: AstNode
      first_token,  # type: util.Token
      last_token,  # type: util.Token
  ):
      # type: (...) -> Tuple[util.Token, util.Token]
      if sys.version_info < (3, 12):
          # Older versions don't tokenize the contents of f-strings
          return self.handle_str(first_token, last_token)
  
      last = first_token
      while True:
          if util.match_token(last, getattr(token, "FSTRING_START")):
              # Python 3.12+ has tokens for the start (e.g. `f"`) and end (`"`)
              # of the f-string. We can't just look for the next FSTRING_END
              # because f-strings can be nested, e.g. f"{f'{x}'}", so we need
              # to treat this like matching balanced parentheses.
              count = 1
              while count > 0:
                  last = self._code.next_token(last)
                  # mypy complains about token.FSTRING_START and token.FSTRING_END.
                  if util.match_token(
                      last, getattr(token, "FSTRING_START")
                  ):
                      count += 1
                  elif util.match_token(
                      last, getattr(token, "FSTRING_END")
                  ):
                      count -= 1
              last_token = last
              last = self._code.next_token(last_token)
          elif util.match_token(last, token.STRING):
              # Similar to handle_str, we also need to handle adjacent strings.
              last_token = last
              last = self._code.next_token(last_token)
          else:
              break
      return (first_token, last_token)
  
imports: import ast
  import numbers
  import sys
  import token
  from ast import Module
  from typing import Callable, List, Union, cast, Optional, Tuple, TYPE_CHECKING
  import six
  from .None import util
  from .asttokens import ASTTokens
  from .util import AstConstant
  from .astroid_compat import astroid_node_classes, BaseContainer
label_desc: Use image node_id 22 for calling the MarkTokens obj's underlying member method code with example usage: obj.visit_joinedstr(node, first_token, last_token) and returns: first_token,  last_token, self