make label optional

pull/14290/head
Rich Harris 2 years ago
parent 457619f276
commit 7778e99510

@ -1,11 +1,11 @@
/** @import { CallExpression, VariableDeclarator } from 'estree' */
/** @import { ArrowFunctionExpression, CallExpression, FunctionDeclaration, FunctionExpression, Identifier, VariableDeclarator } from 'estree' */
/** @import { AST } from '#compiler' */
/** @import { Context } from '../types' */
import { get_rune } from '../../scope.js';
import * as e from '../../../errors.js';
import { get_parent, unwrap_optional } from '../../../utils/ast.js';
import { is_pure, is_safe_identifier } from './shared/utils.js';
import { dev } from '../../../state.js';
import { dev, locate_node, source } from '../../../state.js';
/**
* @param {CallExpression} node
@ -137,21 +137,27 @@ export function CallExpression(node, context) {
break;
case '$inspect.trace': {
if (node.arguments.length !== 1) {
e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
if (node.arguments.length > 1) {
e.rune_invalid_arguments_length(node, rune, 'zero or one arguments');
}
if (node.arguments[0].type !== 'Literal' || typeof node.arguments[0].value !== 'string') {
if (
node.arguments[0] &&
(node.arguments[0].type !== 'Literal' || typeof node.arguments[0].value !== 'string')
) {
e.trace_rune_invalid_argument(node);
}
const grand_parent = context.path.at(-2);
const fn = context.path.at(-3);
if (
parent.type !== 'ExpressionStatement' ||
grand_parent?.type !== 'BlockStatement' ||
!(
context.path.at(-3)?.type === 'FunctionDeclaration' ||
context.path.at(-3)?.type === 'FunctionExpression' ||
context.path.at(-3)?.type === 'ArrowFunctionExpression'
fn?.type === 'FunctionDeclaration' ||
fn?.type === 'FunctionExpression' ||
fn?.type === 'ArrowFunctionExpression'
) ||
grand_parent.body[0] !== parent
) {
@ -159,7 +165,14 @@ export function CallExpression(node, context) {
}
if (dev) {
context.state.scope.tracing = node.arguments[0].value;
if (node.arguments[0]) {
context.state.scope.tracing = /** @type {string} */ (node.arguments[0].value);
} else {
const label = get_function_label(context.path.slice(0, -2));
const loc = `(${locate_node(fn)})`;
context.state.scope.tracing = label ? label + ' ' + loc : loc;
}
}
break;
@ -210,3 +223,27 @@ export function CallExpression(node, context) {
}
}
}
/**
* @param {AST.SvelteNode[]} nodes
*/
function get_function_label(nodes) {
const fn = /** @type {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} */ (
nodes.at(-1)
);
if ((fn.type === 'FunctionDeclaration' || fn.type === 'FunctionExpression') && fn.id != null) {
return fn.id.name;
}
const parent = nodes.at(-2);
if (!parent) return;
if (parent.type === 'CallExpression') {
return source.slice(parent.callee.start, parent.callee.end) + '(...)';
}
if (parent.type === 'Property' && !parent.computed) {
return /** @type {Identifier} */ (parent.key).name;
}
}

@ -8,7 +8,7 @@ import {
get_attribute_expression,
is_event_attribute
} from '../../../../utils/ast.js';
import { dev, filename, is_ignored, locator } from '../../../../state.js';
import { dev, filename, is_ignored, locate_node, locator } from '../../../../state.js';
import { build_proxy_reassignment, should_proxy } from '../utils.js';
import { visit_assignment_expression } from '../../shared/assignments.js';
@ -183,9 +183,6 @@ function build_assignment(operator, left, right, context) {
if (left.type === 'MemberExpression' && should_transform) {
const callee = callees[operator];
const loc = /** @type {Location} */ (locator(/** @type {number} */ (left.start)));
const location = `${filename}:${loc.line}:${loc.column}`;
return /** @type {Expression} */ (
context.visit(
b.call(
@ -197,7 +194,7 @@ function build_assignment(operator, left, right, context) {
: b.literal(/** @type {Identifier} */ (left.property).name)
),
right,
b.literal(location)
b.literal(locate_node(left))
)
)
);

@ -1,6 +1,8 @@
/** @import { Location } from 'locate-character' */
/** @import { CompileOptions } from './types' */
/** @import { AST, Warning } from '#compiler' */
import { getLocator } from 'locate-character';
import { sanitize_location } from '../utils.js';
/** @typedef {{ start?: number, end?: number }} NodeLike */
@ -28,6 +30,14 @@ export let dev;
export let locator = getLocator('', { offsetLine: 1 });
/**
* @param {AST.SvelteNode & { start?: number | undefined }} node
*/
export function locate_node(node) {
const loc = /** @type {Location} */ (locator(/** @type {number} */ (node.start)));
return `${sanitize_location(filename)}:${loc?.line}:${loc.column}`;
}
/** @type {NonNullable<CompileOptions['warningFilter']>} */
export let warning_filter;

@ -1,6 +1,6 @@
import { sanitize_location } from '../../../utils.js';
import { untrack } from '../runtime.js';
import * as w from '../warnings.js';
import { sanitize_location } from './location.js';
/**
*

@ -1,25 +0,0 @@
import { DEV } from 'esm-env';
import { FILENAME } from '../../../constants.js';
import { dev_current_component_function } from '../runtime.js';
/**
*
* @param {number} [line]
* @param {number} [column]
*/
export function get_location(line, column) {
if (!DEV || line === undefined) return undefined;
var filename = dev_current_component_function?.[FILENAME];
var location = filename && `${filename}:${line}:${column}`;
return sanitize_location(location);
}
/**
* Prevent devtools trying to make `location` a clickable link by inserting a zero-width space
* @param {string | undefined} location
*/
export function sanitize_location(location) {
return location?.replace(/\//g, '/\u200b');
}

@ -5,11 +5,10 @@ import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from '../hydr
import { create_fragment_from_html } from '../reconciler.js';
import { assign_nodes } from '../template.js';
import * as w from '../../warnings.js';
import { hash } from '../../../../utils.js';
import { hash, sanitize_location } from '../../../../utils.js';
import { DEV } from 'esm-env';
import { dev_current_component_function } from '../../runtime.js';
import { get_first_child, get_next_sibling } from '../operations.js';
import { sanitize_location } from '../../dev/location.js';
/**
* @param {Element} element

@ -1,4 +1,4 @@
/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, Reaction, TemplateNode, TransitionManager } from '#client' */
/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */
import {
check_dirtiness,
component_context,
@ -16,8 +16,7 @@ import {
set_is_flushing_effect,
set_signal_status,
untrack,
skip_reaction,
capture_signals
skip_reaction
} from '../runtime.js';
import {
DIRTY,
@ -40,13 +39,10 @@ import {
} from '../constants.js';
import { set } from './sources.js';
import * as e from '../errors.js';
import * as w from '../warnings.js';
import { DEV } from 'esm-env';
import { define_property } from '../../shared/utils.js';
import { get_next_sibling } from '../dom/operations.js';
import { destroy_derived } from './deriveds.js';
import { FILENAME } from '../../../constants.js';
import { get_location } from '../dev/location.js';
/**
* @param {'$effect' | '$effect.pre' | '$inspect'} rune

@ -450,3 +450,11 @@ const RAW_TEXT_ELEMENTS = /** @type {const} */ (['textarea', 'script', 'style',
export function is_raw_text_element(name) {
return RAW_TEXT_ELEMENTS.includes(/** @type {RAW_TEXT_ELEMENTS[number]} */ (name));
}
/**
* Prevent devtools trying to make `location` a clickable link by inserting a zero-width space
* @param {string | undefined} location
*/
export function sanitize_location(location) {
return location?.replace(/\//g, '/\u200b');
}

Loading…
Cancel
Save