Repository: sveltejs/svelte
File: packages/svelte/src/compiler/phases/3-transform/client/visitors/global.js (JavaScript)

Code before:
export const global_visitors = {
	Identifier(node, { path, state }) {
		if (is_reference(node, /** @type {import('estree').Node} */ (path.at(-1)))) {
			if (node.name === '$$props') {
				return b.id('$$sanitized_props');
			}
			return serialize_get_binding(node, state);
		}
	},
	MemberExpression(node, { state, next }) {
		// rewrite `this.#foo` as `this.#foo.v` inside a constructor
		if (node.property.type === 'PrivateIdentifier') {
			const field = state.private_state.get(node.property.name);
			if (field) {
				return state.in_constructor ? b.member(node, b.id('v')) : b.call('$.get', node);
			}
		} else if (node.object.type === 'ThisExpression') {
			// rewrite `this.foo` as `this.#foo.v` inside a constructor
			if (node.property.type === 'Identifier' && !node.computed) {
				const field = state.public_state.get(node.property.name);

				if (field && state.in_constructor) {
					return b.member(b.member(b.this, field.id), b.id('v'));
				}
			}
		}
		next();
	},
	AssignmentExpression(node, context) {
		return serialize_set_binding(node, context, context.next);
	},
	UpdateExpression(node, context) {
		const { state, next, visit } = context;
		const argument = node.argument;

		if (argument.type === 'Identifier') {
			const binding = state.scope.get(argument.name);
			const is_store = binding?.kind === 'store_sub';
			const name = is_store ? argument.name.slice(1) : argument.name;

			// use runtime functions for smaller output
			if (
				binding?.kind === 'state' ||
				binding?.kind === 'frozen_state' ||
				binding?.kind === 'each' ||
				binding?.kind === 'legacy_reactive' ||
				binding?.kind === 'prop' ||
				binding?.kind === 'bindable_prop' ||
				is_store
			) {
				/** @type {import('estree').Expression[]} */

Review comment (suggestion):
I added this code here instead of inside `serialize_get_binding` to not bloat that function even further and to not having to adjust the other callsites (AFAIK we only need that logic here)

Code after:
export const global_visitors = {
	Identifier(node, { path, state }) {
		if (is_reference(node, /** @type {import('estree').Node} */ (path.at(-1)))) {
			if (node.name === '$$props') {
				return b.id('$$sanitized_props');
			}

			// Optimize prop access: If it's a member read access, we can use the $$props object directly
			const binding = state.scope.get(node.name);
			if (
				state.analysis.runes && // can't do this in legacy mode because the proxy does more than just read/write
				binding !== null &&
				node !== binding.node &&
				binding.kind === 'rest_prop'
			) {
				const parent = path.at(-1);
				const grand_parent = path.at(-2);
				if (
					parent?.type === 'MemberExpression' &&
					!parent.computed &&
					grand_parent?.type !== 'AssignmentExpression' &&
					grand_parent?.type !== 'UpdateExpression'
				) {
					return b.id('$$props');
				}
			}

			return serialize_get_binding(node, state);
		}
	},
	MemberExpression(node, { state, next }) {
		// rewrite `this.#foo` as `this.#foo.v` inside a constructor
		if (node.property.type === 'PrivateIdentifier') {
			const field = state.private_state.get(node.property.name);
			if (field) {
				return state.in_constructor ? b.member(node, b.id('v')) : b.call('$.get', node);
			}
		} else if (node.object.type === 'ThisExpression') {
			// rewrite `this.foo` as `this.#foo.v` inside a constructor
			if (node.property.type === 'Identifier' && !node.computed) {
				const field = state.public_state.get(node.property.name);

				if (field && state.in_constructor) {
					return b.member(b.member(b.this, field.id), b.id('v'));
				}
			}
		}
		next();
	},
	AssignmentExpression(node, context) {
		return serialize_set_binding(node, context, context.next);