Skip to content

feat: move dev-time component properties to private symbols #12461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fluffy-colts-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

feat: move dev-time component properties to private symbols'
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ export function client_component(source, analysis, options) {

if (options.hmr) {
const accept_fn_body = [
b.stmt(b.call('$.set', b.id('s'), b.member(b.id('module.default'), b.id('original'))))
b.stmt(b.call('$.set', b.id('s'), b.member(b.id('module.default'), b.id('$.ORIGINAL'), true)))
];

if (analysis.css.hash) {
Expand Down Expand Up @@ -446,7 +446,11 @@ export function client_component(source, analysis, options) {
// Assign the original component to the wrapper so we can use it on hot reload patching,
// else we would call the HMR function two times
b.stmt(
b.assignment('=', b.member(b.id(analysis.name), b.id('original')), b.id('$$original'))
b.assignment(
'=',
b.member(b.id(analysis.name), b.id('$.ORIGINAL'), true),
b.id('$$original')
)
),
b.stmt(b.call('import.meta.hot.accept', b.arrow([b.id('module')], b.block(accept_fn_body))))
]);
Expand All @@ -458,10 +462,14 @@ export function client_component(source, analysis, options) {

if (options.dev) {
if (filename) {
// add `App.filename = 'App.svelte'` so that we can print useful messages later
// add `App[$.FILENAME] = 'App.svelte'` so that we can print useful messages later
body.unshift(
b.stmt(
b.assignment('=', b.member(b.id(analysis.name), b.id('filename')), b.literal(filename))
b.assignment(
'=',
b.member(b.id(analysis.name), b.id('$.FILENAME'), true),
b.literal(filename)
)
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ export const template_visitors = {
call = b.call(
'$.add_locations',
call,
b.member(b.id(context.state.analysis.name), b.id('filename')),
b.member(b.id(context.state.analysis.name), b.id('$.FILENAME'), true),
serialize_locations(state.locations)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2249,10 +2249,14 @@ export function server_component(analysis, options) {
}

if (options.dev && filename) {
// add `App.filename = 'App.svelte'` so that we can print useful messages later
// add `App[$.FILENAME] = 'App.svelte'` so that we can print useful messages later
body.unshift(
b.stmt(
b.assignment('=', b.member(b.id(analysis.name), b.id('filename')), b.literal(filename))
b.assignment(
'=',
b.member(b.id(analysis.name), b.id('$.FILENAME'), true),
b.literal(filename)
)
)
);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/svelte/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export const ELEMENT_PRESERVE_ATTRIBUTE_CASE = 1 << 1;

export const UNINITIALIZED = Symbol();

// Dev-time component properties
export const FILENAME = Symbol('filename');
export const ORIGINAL = Symbol('original');

/** List of elements that require raw contents and should not have SSR comments put in them */
export const RawTextElements = ['textarea', 'script', 'style', 'title'];

Expand Down
9 changes: 5 additions & 4 deletions packages/svelte/src/internal/client/dev/legacy.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as e from '../errors.js';
import { current_component_context } from '../runtime.js';
import { FILENAME } from '../../../constants.js';
import { get_component } from './ownership.js';

/** @param {Function & { filename: string }} target */
/** @param {Function & { [FILENAME]: string }} target */
export function check_target(target) {
if (target) {
e.component_api_invalid_new(target.filename ?? 'a component', target.name);
e.component_api_invalid_new(target[FILENAME] ?? 'a component', target.name);
}
}

Expand All @@ -15,8 +16,8 @@ export function legacy_api() {
/** @param {string} method */
function error(method) {
// @ts-expect-error
const parent = get_component()?.filename ?? 'Something';
e.component_api_changed(parent, method, component.filename);
const parent = get_component()?.[FILENAME] ?? 'Something';
e.component_api_changed(parent, method, component[FILENAME]);
}

return {
Expand Down
9 changes: 5 additions & 4 deletions packages/svelte/src/internal/client/dev/ownership.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { render_effect, user_pre_effect } from '../reactivity/effects.js';
import { dev_current_component_function } from '../runtime.js';
import { get_prototype_of } from '../../shared/utils.js';
import * as w from '../warnings.js';
import { FILENAME } from '../../../constants.js';

/** @type {Record<string, Array<{ start: Location, end: Location, component: Function }>>} */
const boundaries = {};
Expand Down Expand Up @@ -115,8 +116,8 @@ export function add_owner(object, owner, global = false) {
if (metadata && !has_owner(metadata, component)) {
let original = get_owner(metadata);

if (owner.filename !== component.filename) {
w.ownership_invalid_binding(component.filename, owner.filename, original.filename);
if (owner[FILENAME] !== component[FILENAME]) {
w.ownership_invalid_binding(component[FILENAME], owner[FILENAME], original[FILENAME]);
}
}
}
Expand Down Expand Up @@ -236,9 +237,9 @@ export function check_ownership(metadata) {
let original = get_owner(metadata);

// @ts-expect-error
if (original.filename !== component.filename) {
if (original[FILENAME] !== component[FILENAME]) {
// @ts-expect-error
w.ownership_invalid_mutation(component.filename, original.filename);
w.ownership_invalid_mutation(component[FILENAME], original[FILENAME]);
} else {
w.ownership_invalid_mutation();
}
Expand Down
6 changes: 3 additions & 3 deletions packages/svelte/src/internal/client/dom/blocks/html.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @import { Effect, TemplateNode } from '#client' */
import { HYDRATION_ERROR } from '../../../../constants.js';
import { FILENAME, HYDRATION_ERROR } from '../../../../constants.js';
import { block, branch, destroy_effect } from '../../reactivity/effects.js';
import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from '../hydration.js';
import { create_fragment_from_html } from '../reconciler.js';
Expand All @@ -23,8 +23,8 @@ function check_hash(element, server_hash, value) {
const loc = element.__svelte_meta?.loc;
if (loc) {
location = `near ${loc.file}:${loc.line}:${loc.column}`;
} else if (dev_current_component_function?.filename) {
location = `in ${dev_current_component_function.filename}`;
} else if (dev_current_component_function?.[FILENAME]) {
location = `in ${dev_current_component_function[FILENAME]}`;
}

w.hydration_html_changed(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @import { Effect, EffectNodes, TemplateNode } from '#client' */
import { namespace_svg } from '../../../../constants.js';
import { FILENAME, namespace_svg } from '../../../../constants.js';
import {
hydrate_next,
hydrate_node,
Expand Down Expand Up @@ -38,7 +38,7 @@ export function element(node, get_tag, is_svg, render_fn, get_namespace, locatio
hydrate_next();
}

var filename = DEV && location && current_component_context?.function.filename;
var filename = DEV && location && current_component_context?.function[FILENAME];

/** @type {string | null} */
var tag;
Expand Down
1 change: 1 addition & 0 deletions packages/svelte/src/internal/client/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { FILENAME, ORIGINAL } from '../../constants.js';
export { add_locations } from './dev/elements.js';
export { hmr } from './dev/hmr.js';
export {
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { mutate, set, source } from './reactivity/sources.js';
import { update_derived } from './reactivity/deriveds.js';
import * as e from './errors.js';
import { lifecycle_outside_component } from '../shared/errors.js';
import { FILENAME } from '../../constants.js';

const FLUSH_MICROTASK = 0;
const FLUSH_SYNC = 1;
Expand Down Expand Up @@ -226,7 +227,7 @@ function handle_error(error, effect, component_context) {

while (current_context !== null) {
/** @type {string} */
var filename = current_context.function?.filename;
var filename = current_context.function?.[FILENAME];

if (filename) {
const file = filename.split('/').pop();
Expand Down
7 changes: 4 additions & 3 deletions packages/svelte/src/internal/client/validate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { untrack } from './runtime.js';
import { get_descriptor, is_array } from '../shared/utils.js';
import * as e from './errors.js';
import { FILENAME } from '../../constants.js';

/** regex of all html void element names */
const void_element_names =
Expand Down Expand Up @@ -70,7 +71,7 @@ export function validate_each_keys(collection, key_fn) {
* @param {Record<string, any>} $$props
* @param {string[]} bindable
* @param {string[]} exports
* @param {Function & { filename: string }} component
* @param {Function & { [FILENAME]: string }} component
*/
export function validate_prop_bindings($$props, bindable, exports, component) {
for (const key in $$props) {
Expand All @@ -79,11 +80,11 @@ export function validate_prop_bindings($$props, bindable, exports, component) {

if (setter) {
if (exports.includes(key)) {
e.bind_invalid_export(component.filename, key, name);
e.bind_invalid_export(component[FILENAME], key, name);
}

if (!bindable.includes(key)) {
e.bind_not_bindable(key, component.filename, name);
e.bind_not_bindable(key, component[FILENAME], name);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/svelte/src/internal/server/dev.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
FILENAME,
disallowed_paragraph_contents,
interactive_elements,
is_tag_valid_with_parent
Expand Down Expand Up @@ -56,7 +57,7 @@ function print_error(payload, parent, child) {
* @param {number} column
*/
export function push_element(payload, tag, line, column) {
var filename = /** @type {import('#server').Component} */ (current_component).function.filename;
var filename = /** @type {import('#server').Component} */ (current_component).function[FILENAME];
var child = { tag, parent, filename, line, column };

if (parent !== null && !is_tag_valid_with_parent(tag, parent.tag)) {
Expand Down
1 change: 1 addition & 0 deletions packages/svelte/src/internal/server/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/** @import { Component, Payload, RenderOutput } from '#server' */
/** @import { Store } from '#shared' */
export { FILENAME, ORIGINAL } from '../../constants.js';
import { is_promise, noop } from '../shared/utils.js';
import { subscribe_to_store } from '../../store/utils.js';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ if (import.meta.hot) {

Hmr = $.hmr(s);
Hmr.filename = filename;
Hmr.original = $$original;
Hmr[$.ORIGINAL] = $$original;

import.meta.hot.accept((module) => {
$.set(s, module.default.original);
$.set(s, module.default[$.ORIGINAL]);
});
}

Expand Down
Loading