docs: def extractArgumentsFromCallStr(callStr):
      """
      Parse the argument string via an AST instead of the overly simple
      callStr.split(','). The latter incorrectly splits any string parameters
      that contain commas therein, like ic(1, 'a,b', 2).
      """
      def isTuple(ele):
          return classname(ele) == 'Tuple'
  
      paramsStr = callStr.split('(', 1)[-1].rsplit(')', 1)[0].strip()
  
      root = ast.parse(paramsStr).body[0].value
      eles = root.elts if isTuple(root) else [root]
  
      # The ast module parses 'a, b' and '(a, b)' identically. Thus, ast.parse()
      # alone can't tell the difference between
      #
      #   ic(a, b)
      #
      # and
      #
      #   ic((a, b))
      #
      # Detect this situation and preserve whole tuples, e.g. '(a, b)', passed to
      # ic() by creating a new, temporary tuple around the original tuple and
      # parsing that.
      if paramsStr[0] == '(' and paramsStr[-1] == ')' and len(eles) > 1:
          newTupleStr = '(' + paramsStr + ", 'ignored')"
          argStrs = extractArgumentsFromCallStr(newTupleStr)[:-1]
          return argStrs
  
      indices = [
          max(0, e.col_offset - 1) if isTuple(e) else e.col_offset for e in eles]
      argStrs = [s.strip(' ,') for s in splitStringAtIndices(paramsStr, indices)]
  
      return argStrs