chore: make `dev` state globally available (#12669)

* make `dev` state globally available

* tidy up
pull/12671/head
Rich Harris 1 year ago committed by GitHub
parent 2d9bc2565f
commit 4b1b886855
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -12,7 +12,7 @@ import { javascript_visitors_runes } from './visitors/javascript-runes.js';
import { javascript_visitors_legacy } from './visitors/javascript-legacy.js';
import { serialize_get_binding } from './utils.js';
import { render_stylesheet } from '../css/index.js';
import { filename } from '../../../state.js';
import { dev, filename } from '../../../state.js';
/**
* This function ensures visitor sets don't accidentally clobber each other
@ -164,7 +164,7 @@ export function client_component(source, analysis, options) {
store_setup.push(
b.const(
binding.node,
options.dev
dev
? b.thunk(
b.sequence([
b.call('$.validate_store', store_reference, b.literal(name.slice(1))),
@ -210,7 +210,7 @@ export function client_component(source, analysis, options) {
getter,
b.set(alias ?? name, [b.stmt(b.assignment('=', expression, b.id('$$value')))])
];
} else if (!options.dev) {
} else if (!dev) {
return b.init(alias ?? name, expression);
}
}
@ -238,7 +238,7 @@ export function client_component(source, analysis, options) {
(binding.kind === 'prop' || binding.kind === 'bindable_prop') && !name.startsWith('$$')
);
if (analysis.runes && options.dev) {
if (dev && analysis.runes) {
const exports = analysis.exports.map(({ name, alias }) => b.literal(alias ?? name));
/** @type {ESTree.Literal[]} */
const bindable = [];
@ -300,12 +300,12 @@ export function client_component(source, analysis, options) {
)
)
);
} else if (options.dev) {
} else if (dev) {
component_returned_object.push(b.spread(b.call(b.id('$.legacy_api'))));
}
const push_args = [b.id('$$props'), b.literal(analysis.runes)];
if (options.dev) push_args.push(b.id(analysis.name));
if (dev) push_args.push(b.id(analysis.name));
const component_block = b.block([
...store_setup,
@ -345,10 +345,10 @@ export function client_component(source, analysis, options) {
}
const should_inject_context =
dev ||
analysis.needs_context ||
analysis.reactive_statements.size > 0 ||
component_returned_object.length > 0 ||
options.dev;
component_returned_object.length > 0;
if (should_inject_context) {
component_block.body.unshift(b.stmt(b.call('$.push', ...push_args)));
@ -462,7 +462,7 @@ export function client_component(source, analysis, options) {
body.push(b.export_default(component));
}
if (options.dev) {
if (dev) {
if (filename) {
// add `App[$.FILENAME] = 'App.svelte'` so that we can print useful messages later
body.unshift(
@ -498,7 +498,7 @@ export function client_component(source, analysis, options) {
)
)
);
} else if (options.dev) {
} else if (dev) {
component_block.body.unshift(b.stmt(b.call('$.check_target', b.id('new.target'))));
}

@ -16,6 +16,7 @@ import {
PROPS_IS_RUNES,
PROPS_IS_UPDATED
} from '../../../../constants.js';
import { dev } from '../../../state.js';
/**
* @template {ClientTransformState} State
@ -212,7 +213,7 @@ export function serialize_set_binding(node, context, fallback, prefix, options)
assignment.right =
private_state.kind === 'frozen_state'
? b.call('$.freeze', value)
: serialize_proxy_reassignment(value, private_state.id, state);
: serialize_proxy_reassignment(value, private_state.id);
return assignment;
}
}
@ -225,7 +226,7 @@ export function serialize_set_binding(node, context, fallback, prefix, options)
should_proxy_or_freeze(value, context.state.scope)
? private_state.kind === 'frozen_state'
? b.call('$.freeze', value)
: serialize_proxy_reassignment(value, private_state.id, state)
: serialize_proxy_reassignment(value, private_state.id)
: value
);
}
@ -249,7 +250,7 @@ export function serialize_set_binding(node, context, fallback, prefix, options)
assignment.right =
public_state.kind === 'frozen_state'
? b.call('$.freeze', value)
: serialize_proxy_reassignment(value, public_state.id, state);
: serialize_proxy_reassignment(value, public_state.id);
return assignment;
}
}
@ -317,7 +318,7 @@ export function serialize_set_binding(node, context, fallback, prefix, options)
context.state.analysis.runes &&
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value, context.state.scope)
? serialize_proxy_reassignment(value, left_name, state)
? serialize_proxy_reassignment(value, left_name)
: value
);
} else if (binding.kind === 'frozen_state') {
@ -340,7 +341,7 @@ export function serialize_set_binding(node, context, fallback, prefix, options)
!options?.skip_proxy_and_freeze &&
should_proxy_or_freeze(value, context.state.scope) &&
binding.kind === 'bindable_prop'
? serialize_proxy_reassignment(value, left_name, state)
? serialize_proxy_reassignment(value, left_name)
: value
);
} else {
@ -435,10 +436,9 @@ export function serialize_set_binding(node, context, fallback, prefix, options)
/**
* @param {Expression} value
* @param {PrivateIdentifier | string} proxy_reference
* @param {ClientTransformState} state
*/
export function serialize_proxy_reassignment(value, proxy_reference, state) {
return state.options.dev
export function serialize_proxy_reassignment(value, proxy_reference) {
return dev
? b.call(
'$.proxy',
value,

@ -14,6 +14,7 @@ import {
} from '../utils.js';
import { extract_paths } from '../../../../utils/ast.js';
import { regex_invalid_identifier_chars } from '../../../patterns.js';
import { dev } from '../../../../state.js';
/** @type {ComponentVisitors} */
export const javascript_visitors_runes = {
@ -148,11 +149,7 @@ export const javascript_visitors_runes = {
'set',
definition.key,
[value],
[
b.stmt(
b.call('$.set', member, serialize_proxy_reassignment(value, field.id, state))
)
]
[b.stmt(b.call('$.set', member, serialize_proxy_reassignment(value, field.id)))]
)
);
}
@ -170,7 +167,7 @@ export const javascript_visitors_runes = {
);
}
if ((field.kind === 'derived' || field.kind === 'derived_call') && state.options.dev) {
if (dev && (field.kind === 'derived' || field.kind === 'derived_call')) {
body.push(
b.method(
'set',
@ -188,7 +185,7 @@ export const javascript_visitors_runes = {
body.push(/** @type {MethodDefinition} **/ (visit(definition, child_state)));
}
if (state.options.dev && public_state.size > 0) {
if (dev && public_state.size > 0) {
// add an `[$.ADD_OWNER]` method so that a class with state fields can widen ownership
body.push(
b.method(
@ -248,7 +245,7 @@ export const javascript_visitors_runes = {
/** @type {Expression[]} */
const args = [b.id('$$props'), b.array(seen.map((name) => b.literal(name)))];
if (state.options.dev) {
if (dev) {
// include rest name, so we can provide informative error messages
args.push(b.literal(declarator.id.name));
}
@ -287,7 +284,7 @@ export const javascript_visitors_runes = {
/** @type {Expression[]} */
const args = [b.id('$$props'), b.array(seen.map((name) => b.literal(name)))];
if (state.options.dev) {
if (dev) {
// include rest name, so we can provide informative error messages
args.push(b.literal(/** @type {Identifier} */ (property.argument).name));
}
@ -474,7 +471,7 @@ export const javascript_visitors_runes = {
BinaryExpression(node, { state, visit, next }) {
const operator = node.operator;
if (state.options.dev) {
if (dev) {
if (operator === '===' || operator === '!==') {
return b.call(
'$.strict_equals',

@ -53,7 +53,7 @@ import { regex_is_valid_identifier } from '../../../patterns.js';
import { javascript_visitors_runes } from './javascript-runes.js';
import { sanitize_template_string } from '../../../../utils/sanitize_template_string.js';
import { walk } from 'zimmerframe';
import { locator } from '../../../../state.js';
import { dev, locator } from '../../../../state.js';
import is_reference from 'is-reference';
/**
@ -780,18 +780,14 @@ function serialize_inline_component(node, component_name, context, anchor = cont
} else if (attribute.type === 'BindDirective') {
const expression = /** @type {Expression} */ (context.visit(attribute.expression));
if (
expression.type === 'MemberExpression' &&
context.state.options.dev &&
context.state.analysis.runes
) {
if (dev && expression.type === 'MemberExpression' && context.state.analysis.runes) {
context.state.init.push(serialize_validate_binding(context.state, attribute, expression));
}
if (attribute.name === 'this') {
bind_this = attribute.expression;
} else {
if (context.state.options.dev) {
if (dev) {
binding_initializers.push(
b.stmt(b.call(b.id('$.add_owner_effect'), b.thunk(expression), b.id(component_name)))
);
@ -894,9 +890,7 @@ function serialize_inline_component(node, component_name, context, anchor = cont
push_prop(
b.init(
'children',
context.state.options.dev
? b.call('$.wrap_snippet', b.id(context.state.analysis.name), slot_fn)
: slot_fn
dev ? b.call('$.wrap_snippet', b.id(context.state.analysis.name), slot_fn) : slot_fn
)
);
@ -968,7 +962,7 @@ function serialize_inline_component(node, component_name, context, anchor = cont
b.block([
...binding_initializers,
b.stmt(
context.state.options.dev
dev
? b.call('$.validate_dynamic_component', b.thunk(prev(b.id('$$anchor'))))
: prev(b.id('$$anchor'))
)
@ -1696,7 +1690,7 @@ export const template_visitors = {
*/
const add_template = (template_name, args) => {
let call = b.call(get_template_function(namespace, state), ...args);
if (context.state.options.dev) {
if (dev) {
call = b.call(
'$.add_locations',
call,
@ -1837,7 +1831,7 @@ export const template_visitors = {
// we need to eagerly evaluate the expression in order to hit any
// 'Cannot access x before initialization' errors
if (state.options.dev) {
if (dev) {
state.init.push(b.stmt(b.call('$.get', declaration.id)));
}
} else {
@ -1871,7 +1865,7 @@ export const template_visitors = {
// we need to eagerly evaluate the expression in order to hit any
// 'Cannot access x before initialization' errors
if (state.options.dev) {
if (dev) {
state.init.push(b.stmt(b.call('$.get', tmp)));
}
@ -1987,7 +1981,7 @@ export const template_visitors = {
/** @type {SourceLocation} */
let location = [-1, -1];
if (context.state.options.dev) {
if (dev) {
const loc = locator(node.start);
if (loc) {
location[0] = loc.line;
@ -2370,7 +2364,7 @@ export const template_visitors = {
const get_tag = b.thunk(/** @type {Expression} */ (context.visit(node.tag)));
if (context.state.options.dev && context.state.metadata.namespace !== 'foreign') {
if (dev && context.state.metadata.namespace !== 'foreign') {
if (node.fragment.nodes.length > 0) {
context.state.init.push(b.stmt(b.call('$.validate_void_dynamic_element', get_tag)));
}
@ -2395,7 +2389,7 @@ export const template_visitors = {
).body
);
const location = context.state.options.dev && locator(node.start);
const location = dev && locator(node.start);
context.state.init.push(
b.stmt(
@ -2614,7 +2608,7 @@ export const template_visitors = {
// we need to eagerly evaluate the expression in order to hit any
// 'Cannot access x before initialization' errors
if (context.state.options.dev) {
if (dev) {
declarations.push(b.stmt(getter));
}
@ -2641,7 +2635,7 @@ export const template_visitors = {
declarations.push(b.let(node.index, index));
}
if (context.state.options.dev && (flags & EACH_KEYED) !== 0) {
if (dev && (flags & EACH_KEYED) !== 0) {
context.state.init.push(
b.stmt(b.call('$.validate_each_keys', b.thunk(collection), key_function))
);
@ -2834,7 +2828,7 @@ export const template_visitors = {
// we need to eagerly evaluate the expression in order to hit any
// 'Cannot access x before initialization' errors
if (context.state.options.dev) {
if (dev) {
declarations.push(b.stmt(getters[name]));
}
}
@ -2848,7 +2842,7 @@ export const template_visitors = {
/** @type {Expression} */
let snippet = b.arrow(args, body);
if (context.state.options.dev) {
if (dev) {
snippet = b.call('$.wrap_snippet', b.id(context.state.analysis.name), snippet);
}
@ -2908,7 +2902,7 @@ export const template_visitors = {
type === 'AwaitBlock' ||
type === 'KeyBlock'
)) &&
context.state.options.dev &&
dev &&
context.state.analysis.runes
) {
context.state.init.push(

@ -5,11 +5,11 @@ import MagicString from 'magic-string';
import { walk } from 'zimmerframe';
import { is_keyframes_node, regex_css_name_boundary, remove_css_prefix } from '../../css.js';
import { merge_with_preprocessor_map } from '../../../utils/mapped_code.js';
import { dev } from '../../../state.js';
/**
* @typedef {{
* code: MagicString;
* dev: boolean;
* hash: string;
* selector: string;
* keyframes: string[];
@ -31,7 +31,6 @@ export function render_stylesheet(source, analysis, options) {
/** @type {State} */
const state = {
code,
dev: options.dev,
hash: analysis.css.hash,
selector: `.${analysis.css.hash}`,
keyframes: analysis.css.keyframes,
@ -60,7 +59,7 @@ export function render_stylesheet(source, analysis, options) {
merge_with_preprocessor_map(css, options, css.map.sources[0]);
if (options.dev && options.css === 'injected' && css.code) {
if (dev && options.css === 'injected' && css.code) {
css.code += `\n/*# sourceMappingURL=${css.map.toUrl()} */`;
}
@ -122,7 +121,7 @@ const visitors = {
Rule(node, { state, next, visit }) {
// keep empty rules in dev, because it's convenient to
// see them in devtools
if (!state.dev && is_empty(node)) {
if (!dev && is_empty(node)) {
state.code.prependRight(node.start, '/* (empty) ');
state.code.appendLeft(node.end, '*/');
escape_comment_close(node, state.code);

@ -6,7 +6,7 @@ import { walk } from 'zimmerframe';
import { set_scope } from '../../scope.js';
import { extract_identifiers } from '../../../utils/ast.js';
import * as b from '../../../utils/builders.js';
import { filename } from '../../../state.js';
import { dev, filename } from '../../../state.js';
import { render_stylesheet } from '../css/index.js';
import { AssignmentExpression } from './visitors/AssignmentExpression.js';
import { AwaitBlock } from './visitors/AwaitBlock.js';
@ -269,10 +269,10 @@ export function server_component(analysis, options) {
.../** @type {Statement[]} */ (template.body)
]);
let should_inject_context = analysis.needs_context || options.dev;
let should_inject_context = dev || analysis.needs_context;
if (should_inject_context) {
component_block.body.unshift(b.stmt(b.call('$.push', options.dev && b.id(analysis.name))));
component_block.body.unshift(b.stmt(b.call('$.push', dev && b.id(analysis.name))));
component_block.body.push(b.stmt(b.call('$.pop')));
}
@ -358,7 +358,7 @@ export function server_component(analysis, options) {
),
b.export_default(b.id(analysis.name))
);
} else if (options.dev) {
} else if (dev) {
body.push(
component_function,
b.stmt(
@ -383,7 +383,7 @@ export function server_component(analysis, options) {
body.push(b.export_default(component_function));
}
if (options.dev && filename) {
if (dev && filename) {
// add `App[$.FILENAME] = 'App.svelte'` so that we can print useful messages later
body.unshift(
b.stmt(

@ -1,6 +1,7 @@
/** @import { ClassBody, Expression, MethodDefinition, PropertyDefinition } from 'estree' */
/** @import { Context } from '../types.js' */
/** @import { StateField } from '../../client/types.js' */
import { dev } from '../../../../state.js';
import * as b from '../../../../utils/builders.js';
import { get_rune } from '../../../scope.js';
@ -92,10 +93,7 @@ export function ClassBodyRunes(node, context) {
// get foo() { return this.#foo; }
body.push(b.method('get', definition.key, [], [b.return(b.call(member))]));
if (
(field.kind === 'derived' || field.kind === 'derived_call') &&
context.state.options.dev
) {
if (dev && (field.kind === 'derived' || field.kind === 'derived_call')) {
body.push(
b.method(
'set',

@ -2,7 +2,7 @@
/** @import { RegularElement, Text } from '#compiler' */
/** @import { ComponentContext, ComponentServerTransformState } from '../types.js' */
/** @import { Scope } from '../../../scope.js' */
import { locator } from '../../../../state.js';
import { dev, locator } from '../../../../state.js';
import * as b from '../../../../utils/builders.js';
import { VoidElements } from '../../../constants.js';
import { clean_nodes, determine_namespace_for_children } from '../../utils.js';
@ -55,7 +55,7 @@ export function RegularElement(node, context) {
context.visit(node, state);
}
if (state.options.dev) {
if (dev) {
const location = /** @type {Location} */ (locator(node.start));
state.template.push(
b.stmt(
@ -99,7 +99,7 @@ export function RegularElement(node, context) {
state.template.push(b.literal(`</${node.name}>`));
}
if (state.options.dev) {
if (dev) {
state.template.push(b.stmt(b.call('$.pop_element')));
}
}

@ -1,6 +1,7 @@
/** @import { BlockStatement, Expression } from 'estree' */
/** @import { SvelteElement } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import { dev } from '../../../../state.js';
import * as b from '../../../../utils/builders.js';
import { determine_namespace_for_children } from '../../utils.js';
import { serialize_element_attributes } from './shared/element.js';
@ -18,7 +19,7 @@ export function SvelteElement(node, context) {
tag = b.id(tag_id);
}
if (context.state.options.dev) {
if (dev) {
if (node.fragment.nodes.length > 0) {
context.state.init.push(b.stmt(b.call('$.validate_void_dynamic_element', b.thunk(tag))));
}
@ -34,7 +35,7 @@ export function SvelteElement(node, context) {
serialize_element_attributes(node, { ...context, state });
if (context.state.options.dev) {
if (dev) {
context.state.template.push(b.stmt(b.call('$.push_element', tag, b.id('$$payload'))));
}
@ -53,7 +54,7 @@ export function SvelteElement(node, context) {
)
);
if (context.state.options.dev) {
if (dev) {
context.state.template.push(b.stmt(b.call('$.pop_element')));
}
}

@ -14,6 +14,7 @@ import { extract_identifiers } from '../../utils/ast.js';
import check_graph_for_cycles from '../2-analyze/utils/check_graph_for_cycles.js';
import is_reference from 'is-reference';
import { set_scope } from '../scope.js';
import { dev } from '../../state.js';
/**
* @param {Node} node
@ -424,7 +425,7 @@ export function transform_inspect_rune(node, context) {
const { state, visit } = context;
const as_fn = state.options.generate === 'client';
if (!state.options.dev) return b.unary('void', b.literal(0));
if (!dev) return b.unary('void', b.literal(0));
if (node.callee.type === 'MemberExpression') {
const raw_inspect_args = /** @type {CallExpression} */ (node.callee.object).arguments;

@ -20,6 +20,12 @@ export let filename;
*/
export let source;
/**
* True if compiling with `dev: true`
* @type {boolean}
*/
export let dev;
export let locator = getLocator('', { offsetLine: 1 });
/** @type {NonNullable<CompileOptions['warningFilter']>} */
@ -61,13 +67,15 @@ export function reset_warning_filter(fn = () => true) {
/**
* @param {string} _source
* @param {{ filename?: string, rootDir?: string }} options
* @param {{ dev?: boolean; filename?: string; rootDir?: string }} options
*/
export function reset(_source, options) {
source = _source;
const root_dir = options.rootDir?.replace(/\\/g, '/');
filename = options.filename?.replace(/\\/g, '/');
dev = !!options.dev;
if (
typeof filename === 'string' &&
typeof root_dir === 'string' &&

Loading…
Cancel
Save