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_after_children(self, node, parent_token, token):
      # type: (AstNode, Optional[util.Token], Optional[util.Token]) -> None
      # This processes the node generically first, after all children have been processed.
  
      # Get the first and last tokens that belong to children. Note how this doesn't assume that we
      # iterate through children in order that corresponds to occurrence in source code. This
      # assumption can fail (e.g. with return annotations).
      first = token
      last = None
      for child in cast(Callable, self._iter_children)(node):
          # astroid slices have especially wrong positions, we don't want them to corrupt their parents.
          if util.is_empty_astroid_slice(child):
              continue
          if not first or child.first_token.index < first.index:
              first = child.first_token
          if not last or child.last_token.index > last.index:
              last = child.last_token
  
      # If we don't have a first token from _visit_before_children, and there were no children, then
      # use the parent's token as the first token.
      first = first or parent_token
  
      # If no children, set last token to the first one.
      last = last or first
  
      # Statements continue to before NEWLINE. This helps cover a few different cases at once.
      if util.is_stmt(node):
          last = self._find_last_in_stmt(cast(util.Token, last))
  
      # Capture any unmatched brackets.
      first, last = self._expand_to_matching_pairs(
          cast(util.Token, first), cast(util.Token, last), node
      )
  
      # Give a chance to node-specific methods to adjust.
      nfirst, nlast = self._methods.get(self, node.__class__)(
          node, first, last
      )
  
      if (nfirst, nlast) != (first, last):
          # If anything changed, expand again to capture any unmatched brackets.
          nfirst, nlast = self._expand_to_matching_pairs(
              nfirst, nlast, node
          )
  
      node.first_token = nfirst
      node.last_token = nlast
  
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 4 for calling the MarkTokens obj's underlying member method code with example usage: obj._visit_after_children(node, parent_token, token) without return types