function to_public_ast(source, ast, modern) {
	if (modern) {
		const clean = (/** @type {any} */ node) => {
			delete node.metadata;
		};

		ast.options?.attributes.forEach((attribute) => {
			clean(attribute);
			clean(attribute.value);
			if (Array.isArray(attribute.value)) {
				attribute.value.forEach(clean);
			}
		});

		// remove things that we don't want to treat as public API
		return zimmerframe_walk(ast, null, {
			_(node, { next }) {
				clean(node);
				next();
			}
		});
	}

	return convert(source, ast);
}
@param {string} source
@param {AST.Root} ast
@param {boolean | undefined} modern