declare(node, kind, declaration_kind, initial = null) {
		if (this.parent) {
			if (declaration_kind === 'var' && this.#porous) {
				return this.parent.declare(node, kind, declaration_kind);
			}

			if (declaration_kind === 'import') {
				return this.parent.declare(node, kind, declaration_kind, initial);
			}
		}

		if (this.declarations.has(node.name)) {
			const binding = this.declarations.get(node.name);
			if (binding && binding.declaration_kind !== 'var' && declaration_kind !== 'var') {
				// This also errors on function types, but that's arguably a good thing
				// declaring function twice is also caught by acorn in the parse phase
				e.declaration_duplicate(node, node.name);
			}
		}

		const binding = new Binding(this, node, kind, declaration_kind, initial);

		validate_identifier_name(binding, this.function_depth);

		this.declarations.set(node.name, binding);
		this.root.conflicts.add(node.name);
		return binding;
	}
@param {Identifier} node
@param {Binding['kind']} kind
@param {DeclarationKind} declaration_kind
@param {null | Expression | FunctionDeclaration | ClassDeclaration | ImportDeclaration | AST.EachBlock | AST.SnippetBlock} initial
@returns {Binding}