Skip to content

Commit 7778e99

Browse files
committed
make label optional
1 parent 457619f commit 7778e99

File tree

8 files changed

+70
-48
lines changed

8 files changed

+70
-48
lines changed

packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
/** @import { CallExpression, VariableDeclarator } from 'estree' */
1+
/** @import { ArrowFunctionExpression, CallExpression, FunctionDeclaration, FunctionExpression, Identifier, VariableDeclarator } from 'estree' */
22
/** @import { AST } from '#compiler' */
33
/** @import { Context } from '../types' */
44
import { get_rune } from '../../scope.js';
55
import * as e from '../../../errors.js';
66
import { get_parent, unwrap_optional } from '../../../utils/ast.js';
77
import { is_pure, is_safe_identifier } from './shared/utils.js';
8-
import { dev } from '../../../state.js';
8+
import { dev, locate_node, source } from '../../../state.js';
99

1010
/**
1111
* @param {CallExpression} node
@@ -137,29 +137,42 @@ export function CallExpression(node, context) {
137137
break;
138138

139139
case '$inspect.trace': {
140-
if (node.arguments.length !== 1) {
141-
e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
140+
if (node.arguments.length > 1) {
141+
e.rune_invalid_arguments_length(node, rune, 'zero or one arguments');
142142
}
143-
if (node.arguments[0].type !== 'Literal' || typeof node.arguments[0].value !== 'string') {
143+
144+
if (
145+
node.arguments[0] &&
146+
(node.arguments[0].type !== 'Literal' || typeof node.arguments[0].value !== 'string')
147+
) {
144148
e.trace_rune_invalid_argument(node);
145149
}
150+
146151
const grand_parent = context.path.at(-2);
152+
const fn = context.path.at(-3);
147153

148154
if (
149155
parent.type !== 'ExpressionStatement' ||
150156
grand_parent?.type !== 'BlockStatement' ||
151157
!(
152-
context.path.at(-3)?.type === 'FunctionDeclaration' ||
153-
context.path.at(-3)?.type === 'FunctionExpression' ||
154-
context.path.at(-3)?.type === 'ArrowFunctionExpression'
158+
fn?.type === 'FunctionDeclaration' ||
159+
fn?.type === 'FunctionExpression' ||
160+
fn?.type === 'ArrowFunctionExpression'
155161
) ||
156162
grand_parent.body[0] !== parent
157163
) {
158164
e.trace_rune_invalid_location(node);
159165
}
160166

161167
if (dev) {
162-
context.state.scope.tracing = node.arguments[0].value;
168+
if (node.arguments[0]) {
169+
context.state.scope.tracing = /** @type {string} */ (node.arguments[0].value);
170+
} else {
171+
const label = get_function_label(context.path.slice(0, -2));
172+
const loc = `(${locate_node(fn)})`;
173+
174+
context.state.scope.tracing = label ? label + ' ' + loc : loc;
175+
}
163176
}
164177

165178
break;
@@ -210,3 +223,27 @@ export function CallExpression(node, context) {
210223
}
211224
}
212225
}
226+
227+
/**
228+
* @param {AST.SvelteNode[]} nodes
229+
*/
230+
function get_function_label(nodes) {
231+
const fn = /** @type {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} */ (
232+
nodes.at(-1)
233+
);
234+
235+
if ((fn.type === 'FunctionDeclaration' || fn.type === 'FunctionExpression') && fn.id != null) {
236+
return fn.id.name;
237+
}
238+
239+
const parent = nodes.at(-2);
240+
if (!parent) return;
241+
242+
if (parent.type === 'CallExpression') {
243+
return source.slice(parent.callee.start, parent.callee.end) + '(...)';
244+
}
245+
246+
if (parent.type === 'Property' && !parent.computed) {
247+
return /** @type {Identifier} */ (parent.key).name;
248+
}
249+
}

packages/svelte/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
get_attribute_expression,
99
is_event_attribute
1010
} from '../../../../utils/ast.js';
11-
import { dev, filename, is_ignored, locator } from '../../../../state.js';
11+
import { dev, filename, is_ignored, locate_node, locator } from '../../../../state.js';
1212
import { build_proxy_reassignment, should_proxy } from '../utils.js';
1313
import { visit_assignment_expression } from '../../shared/assignments.js';
1414

@@ -183,9 +183,6 @@ function build_assignment(operator, left, right, context) {
183183
if (left.type === 'MemberExpression' && should_transform) {
184184
const callee = callees[operator];
185185

186-
const loc = /** @type {Location} */ (locator(/** @type {number} */ (left.start)));
187-
const location = `${filename}:${loc.line}:${loc.column}`;
188-
189186
return /** @type {Expression} */ (
190187
context.visit(
191188
b.call(
@@ -197,7 +194,7 @@ function build_assignment(operator, left, right, context) {
197194
: b.literal(/** @type {Identifier} */ (left.property).name)
198195
),
199196
right,
200-
b.literal(location)
197+
b.literal(locate_node(left))
201198
)
202199
)
203200
);

packages/svelte/src/compiler/state.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
/** @import { Location } from 'locate-character' */
12
/** @import { CompileOptions } from './types' */
23
/** @import { AST, Warning } from '#compiler' */
34
import { getLocator } from 'locate-character';
5+
import { sanitize_location } from '../utils.js';
46

57
/** @typedef {{ start?: number, end?: number }} NodeLike */
68

@@ -28,6 +30,14 @@ export let dev;
2830

2931
export let locator = getLocator('', { offsetLine: 1 });
3032

33+
/**
34+
* @param {AST.SvelteNode & { start?: number | undefined }} node
35+
*/
36+
export function locate_node(node) {
37+
const loc = /** @type {Location} */ (locator(/** @type {number} */ (node.start)));
38+
return `${sanitize_location(filename)}:${loc?.line}:${loc.column}`;
39+
}
40+
3141
/** @type {NonNullable<CompileOptions['warningFilter']>} */
3242
export let warning_filter;
3343

packages/svelte/src/internal/client/dev/assign.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { sanitize_location } from '../../../utils.js';
12
import { untrack } from '../runtime.js';
23
import * as w from '../warnings.js';
3-
import { sanitize_location } from './location.js';
44

55
/**
66
*

packages/svelte/src/internal/client/dev/location.js

Lines changed: 0 additions & 25 deletions
This file was deleted.

packages/svelte/src/internal/client/dom/blocks/html.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from '../hydr
55
import { create_fragment_from_html } from '../reconciler.js';
66
import { assign_nodes } from '../template.js';
77
import * as w from '../../warnings.js';
8-
import { hash } from '../../../../utils.js';
8+
import { hash, sanitize_location } from '../../../../utils.js';
99
import { DEV } from 'esm-env';
1010
import { dev_current_component_function } from '../../runtime.js';
1111
import { get_first_child, get_next_sibling } from '../operations.js';
12-
import { sanitize_location } from '../../dev/location.js';
1312

1413
/**
1514
* @param {Element} element

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, Reaction, TemplateNode, TransitionManager } from '#client' */
1+
/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */
22
import {
33
check_dirtiness,
44
component_context,
@@ -16,8 +16,7 @@ import {
1616
set_is_flushing_effect,
1717
set_signal_status,
1818
untrack,
19-
skip_reaction,
20-
capture_signals
19+
skip_reaction
2120
} from '../runtime.js';
2221
import {
2322
DIRTY,
@@ -40,13 +39,10 @@ import {
4039
} from '../constants.js';
4140
import { set } from './sources.js';
4241
import * as e from '../errors.js';
43-
import * as w from '../warnings.js';
4442
import { DEV } from 'esm-env';
4543
import { define_property } from '../../shared/utils.js';
4644
import { get_next_sibling } from '../dom/operations.js';
4745
import { destroy_derived } from './deriveds.js';
48-
import { FILENAME } from '../../../constants.js';
49-
import { get_location } from '../dev/location.js';
5046

5147
/**
5248
* @param {'$effect' | '$effect.pre' | '$inspect'} rune

packages/svelte/src/utils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,11 @@ const RAW_TEXT_ELEMENTS = /** @type {const} */ (['textarea', 'script', 'style',
450450
export function is_raw_text_element(name) {
451451
return RAW_TEXT_ELEMENTS.includes(/** @type {RAW_TEXT_ELEMENTS[number]} */ (name));
452452
}
453+
454+
/**
455+
* Prevent devtools trying to make `location` a clickable link by inserting a zero-width space
456+
* @param {string | undefined} location
457+
*/
458+
export function sanitize_location(location) {
459+
return location?.replace(/\//g, '/\u200b');
460+
}

0 commit comments

Comments
 (0)