function resolvedExpressions(context, node) {
  /** @type {Map<Expression, Set<Expression>>} */
  const resolvedMap = new Map()

  return resolvedExpressionsInternal(node)

  /**
   * @param {Expression} node
   * @returns {Set<Expression>}
   */
  function resolvedExpressionsInternal(node) {
    let resolvedSet = resolvedMap.get(node)
    if (!resolvedSet) {
      resolvedSet = new Set()
      resolvedMap.set(node, resolvedSet)
      for (const e of extractResolvedExpressions(node)) {
        resolvedSet.add(e)
      }
    }

    if (resolvedSet.size === 0) {
      resolvedSet.add(node)
    }

    return resolvedSet
  }
  /**
   * @param {Expression} node
   * @returns {Iterable<Expression>}
   */
  function* extractResolvedExpressions(node) {
    switch (node.type) {
      case 'Identifier': {
        const variable = utils.findVariableByIdentifier(context, node)
        if (variable) {
          for (const ref of variable.references) {
            const id = ref.identifier
            if (id.parent.type === 'VariableDeclarator') {
              if (id.parent.id === id && id.parent.init) {
                yield* resolvedExpressionsInternal(id.parent.init)
              }
            } else if (
              id.parent.type === 'AssignmentExpression' &&
              id.parent.left === id
            ) {
              yield* resolvedExpressionsInternal(id.parent.right)
            }
          }
        }

        break
      }
      case 'ConditionalExpression': {
        yield* resolvedExpressionsInternal(node.consequent)
        yield* resolvedExpressionsInternal(node.alternate)

        break
      }
      case 'LogicalExpression': {
        yield* resolvedExpressionsInternal(node.left)
        yield* resolvedExpressionsInternal(node.right)

        break
      }
    }
  }
}
@param {RuleContext} context
@param {Expression} node
@returns {Set<Expression>}