isDefaultThisBinding(node, sourceCode, { capIsConstructor = true } = {}) {
		/*
		 * Class field initializers are implicit functions, but ESTree doesn't have the AST node of field initializers.
		 * Therefore, A expression node at `PropertyDefinition#value` is a function.
		 * In this case, `this` is always not default binding.
		 */
		if (
			node.parent.type === "PropertyDefinition" &&
			node.parent.value === node
		) {
			return false;
		}

		// Class static blocks are implicit functions. In this case, `this` is always not default binding.
		if (node.type === "StaticBlock") {
			return false;
		}

		// Check if the function has a parameter named `this`.
		if (
			(node.type === "FunctionDeclaration" ||
				node.type === "FunctionExpression") &&
			node.params.some(
				param => param.type === "Identifier" && param.name === "this",
			)
		) {
			return false;
		}

		if (
			(capIsConstructor && isES5Constructor(node)) ||
			hasJSDocThisTag(node, sourceCode)
		) {
			return false;
		}
		const isAnonymous = node.id === null;
		let currentNode = node;

		while (currentNode) {
			const parent = currentNode.parent;

			switch (parent.type) {
				/*
				 * Looks up the destination.
				 * e.g., obj.foo = nativeFoo || function foo() { ... };
				 */
				case "LogicalExpression":
				case "ConditionalExpression":
				case "ChainExpression":
					currentNode = parent;
					break;

				/*
				 * If the upper function is IIFE, checks the destination of the return value.
				 * e.g.
				 *   obj.foo = (function() {
				 *     // setup...
				 *     return function foo() { ... };
				 *   })();
				 *   obj.foo = (() =>
				 *     function foo() { ... }
				 *   )();
				 */
				case "ReturnStatement": {
					const func = getUpperFunction(parent);

					if (func === null || !isCallee(func)) {
						return true;
					}
					currentNode = func.parent;
					break;
				}
				case "ArrowFunctionExpression":
					if (currentNode !== parent.body || !isCallee(parent)) {
						return true;
					}
					currentNode = parent.parent;
					break;

				/*
				 * e.g.
				 *   var obj = { foo() { ... } };
				 *   var obj = { foo: function() { ... } };
				 *   class A { constructor() { ... } }
				 *   class A { foo() { ... } }
				 *   class A { get foo() { ... } }
				 *   class A { set foo() { ... } }
				 *   class A { static foo() { ... } }
				 *   class A { foo = function() { ... } }
				 */
				case "Property":
				case "PropertyDefinition":
				case "MethodDefinition":
					return parent.value !== currentNode;

				/*
				 * e.g.
				 *   obj.foo = function foo() { ... };
				 *   Foo = function() { ... };
				 *   [obj.foo = function foo() { ... }] = a;
				 *   [Foo = function() { ... }] = a;
				 */
				case "AssignmentExpression":
				case "AssignmentPattern":
					if (parent.left.type === "MemberExpression") {
						return false;
					}
					if (
						capIsConstructor &&
						isAnonymous &&
						parent.left.type === "Identifier" &&
						startsWithUpperCase(parent.left.name)
					) {
						return false;
					}
					return true;

				/*
				 * e.g.
				 *   var Foo = function() { ... };
				 */
				case "VariableDeclarator":
					return !(
						capIsConstructor &&
						isAnonymous &&
						parent.init === currentNode &&
						parent.id.type === "Identifier" &&
						startsWithUpperCase(parent.id.name)
					);

				/*
				 * e.g.
				 *   var foo = function foo() { ... }.bind(obj);
				 *   (function foo() { ... }).call(obj);
				 *   (function foo() { ... }).apply(obj, []);
				 */
				case "MemberExpression":
					if (
						parent.object === currentNode &&
						isSpecificMemberAccess(
							parent,
							null,
							bindOrCallOrApplyPattern,
						)
					) {
						const maybeCalleeNode =
							parent.parent.type === "ChainExpression"
								? parent.parent
								: parent;

						return !(
							isCallee(maybeCalleeNode) &&
							maybeCalleeNode.parent.arguments.length >= 1 &&
							!isNullOrUndefined(
								maybeCalleeNode.parent.arguments[0],
							)
						);
					}
					return true;

				/*
				 * e.g.
				 *   Reflect.apply(function() {}, obj, []);
				 *   Array.from([], function() {}, obj);
				 *   list.forEach(function() {}, obj);
				 */
				case "CallExpression":
					if (isReflectApply(parent.callee)) {
						return (
							parent.arguments.length !== 3 ||
							parent.arguments[0] !== currentNode ||
							isNullOrUndefined(parent.arguments[1])
						);
					}
					if (isArrayFromMethod(parent.callee)) {
						return (
							parent.arguments.length !== 3 ||
							parent.arguments[1] !== currentNode ||
							isNullOrUndefined(parent.arguments[2])
						);
					}
					if (isMethodWhichHasThisArg(parent.callee)) {
						return (
							parent.arguments.length !== 2 ||
							parent.arguments[0] !== currentNode ||
							isNullOrUndefined(parent.arguments[1])
						);
					}
					return true;

				// Otherwise `this` is default.
				default:
					return true;
			}
		}

		/* c8 ignore next */
		return true;
	}
Checks whether or not a given function node is the default `this` binding.

First, this checks the node:

- The given node is not in `PropertyDefinition#value` position.
- The given node is not `StaticBlock`.
- The function name does not start with uppercase. It's a convention to capitalize the names
  of constructor functions. This check is not performed if `capIsConstructor` is set to `false`.
- The function does not have a JSDoc comment that has a @this tag.

Next, this checks the location of the node.
If the location is below, this judges `this` is valid.

- The location is not on an object literal.
- The location is not assigned to a variable which starts with an uppercase letter. Applies to anonymous
  functions only, as the name of the variable is considered to be the name of the function in this case.
  This check is not performed if `capIsConstructor` is set to `false`.
- The location is not on an ES2015 class.
- Its `bind`/`call`/`apply` method is not called directly.
- The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
@param {ASTNode} node A function node to check. It also can be an implicit function, like `StaticBlock`
or any expression that is `PropertyDefinition#value` node.
@param {SourceCode} sourceCode A SourceCode instance to get comments.
@param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts
with an uppercase or are assigned to a variable which name starts with an uppercase are constructors.
@returns {boolean} The function node is the default `this` binding.