lint, tidy up

pull/15820/head
Rich Harris 4 months ago
parent 255603111b
commit c7e8422ceb

@ -15,9 +15,6 @@ import type { ComponentAnalysis } from '../../types.js';
import type { SourceLocation } from '#shared'; import type { SourceLocation } from '#shared';
export interface ClientTransformState extends TransformState { export interface ClientTransformState extends TransformState {
readonly state_fields: Record<string, StateField>;
readonly backing_fields: Record<string, PrivateIdentifier>;
/** /**
* `true` if the current lexical scope belongs to a class constructor. this allows * `true` if the current lexical scope belongs to a class constructor. this allows
* us to rewrite `this.foo` as `this.#foo.value` * us to rewrite `this.foo` as `this.#foo.value`

@ -55,46 +55,48 @@ function build_assignment(operator, left, right, context) {
if (context.state.analysis.runes && left.type === 'MemberExpression') { if (context.state.analysis.runes && left.type === 'MemberExpression') {
const name = get_name(left.property); const name = get_name(left.property);
// special case — state declaration in class constructor if (name !== null) {
const ancestor = context.path.at(-4); // special case — state declaration in class constructor
const ancestor = context.path.at(-4);
if (ancestor?.type === 'MethodDefinition' && ancestor.kind === 'constructor') {
const rune = get_rune(right, context.state.scope); if (ancestor?.type === 'MethodDefinition' && ancestor.kind === 'constructor') {
const rune = get_rune(right, context.state.scope);
if (rune) {
const child_state = { if (rune) {
...context.state, const child_state = {
in_constructor: rune !== '$derived' && rune !== '$derived.by' ...context.state,
}; in_constructor: rune !== '$derived' && rune !== '$derived.by'
};
const l = b.member(
b.this, const l = b.member(
left.property.type === 'PrivateIdentifier' b.this,
? left.property left.property.type === 'PrivateIdentifier'
: context.state.backing_fields[name] ? left.property
); : context.state.backing_fields[name]
);
const r = /** @type {Expression} */ (context.visit(right, child_state)); const r = /** @type {Expression} */ (context.visit(right, child_state));
return b.assignment(operator, l, r); return b.assignment(operator, l, r);
}
} }
}
// special case — assignment to private state field // special case — assignment to private state field
if (left.property.type === 'PrivateIdentifier') { if (left.property.type === 'PrivateIdentifier') {
const field = context.state.state_fields[name]; const field = context.state.state_fields[name];
if (field) { if (field) {
let value = /** @type {Expression} */ ( let value = /** @type {Expression} */ (
context.visit(build_assignment_value(operator, left, right)) context.visit(build_assignment_value(operator, left, right))
); );
const needs_proxy = const needs_proxy =
field.type === '$state' && field.type === '$state' &&
is_non_coercive_operator(operator) && is_non_coercive_operator(operator) &&
should_proxy(value, context.state.scope); should_proxy(value, context.state.scope);
return b.call('$.set', left, value, needs_proxy && b.true); return b.call('$.set', left, value, needs_proxy && b.true);
}
} }
} }
} }

@ -23,7 +23,6 @@ import { Identifier } from './visitors/Identifier.js';
import { IfBlock } from './visitors/IfBlock.js'; import { IfBlock } from './visitors/IfBlock.js';
import { KeyBlock } from './visitors/KeyBlock.js'; import { KeyBlock } from './visitors/KeyBlock.js';
import { LabeledStatement } from './visitors/LabeledStatement.js'; import { LabeledStatement } from './visitors/LabeledStatement.js';
import { MemberExpression } from './visitors/MemberExpression.js';
import { PropertyDefinition } from './visitors/PropertyDefinition.js'; import { PropertyDefinition } from './visitors/PropertyDefinition.js';
import { RegularElement } from './visitors/RegularElement.js'; import { RegularElement } from './visitors/RegularElement.js';
import { RenderTag } from './visitors/RenderTag.js'; import { RenderTag } from './visitors/RenderTag.js';
@ -49,7 +48,6 @@ const global_visitors = {
ExpressionStatement, ExpressionStatement,
Identifier, Identifier,
LabeledStatement, LabeledStatement,
MemberExpression,
PropertyDefinition, PropertyDefinition,
UpdateExpression, UpdateExpression,
VariableDeclaration VariableDeclaration
@ -99,7 +97,8 @@ export function server_component(analysis, options) {
template: /** @type {any} */ (null), template: /** @type {any} */ (null),
namespace: options.namespace, namespace: options.namespace,
preserve_whitespace: options.preserveWhitespace, preserve_whitespace: options.preserveWhitespace,
private_derived: new Map(), state_fields: {},
backing_fields: {},
skip_hydration_boundaries: false skip_hydration_boundaries: false
}; };
@ -395,7 +394,8 @@ export function server_module(analysis, options) {
// to be present for `javascript_visitors_legacy` and so is included in module // to be present for `javascript_visitors_legacy` and so is included in module
// transform state as well as component transform state // transform state as well as component transform state
legacy_reactive_statements: new Map(), legacy_reactive_statements: new Map(),
private_derived: new Map() state_fields: {},
backing_fields: {}
}; };
const module = /** @type {Program} */ ( const module = /** @type {Program} */ (

@ -2,12 +2,10 @@ import type { Expression, Statement, ModuleDeclaration, LabeledStatement } from
import type { AST, Namespace, ValidatedCompileOptions } from '#compiler'; import type { AST, Namespace, ValidatedCompileOptions } from '#compiler';
import type { TransformState } from '../types.js'; import type { TransformState } from '../types.js';
import type { ComponentAnalysis } from '../../types.js'; import type { ComponentAnalysis } from '../../types.js';
import type { StateField } from '../client/types.js';
export interface ServerTransformState extends TransformState { export interface ServerTransformState extends TransformState {
/** The $: calls, which will be ordered in the end */ /** The $: calls, which will be ordered in the end */
readonly legacy_reactive_statements: Map<LabeledStatement, Statement>; readonly legacy_reactive_statements: Map<LabeledStatement, Statement>;
readonly private_derived: Map<string, StateField>;
} }
export interface ComponentServerTransformState extends ServerTransformState { export interface ComponentServerTransformState extends ServerTransformState {

@ -25,24 +25,27 @@ export function AssignmentExpression(node, context) {
*/ */
function build_assignment(operator, left, right, context) { function build_assignment(operator, left, right, context) {
if (context.state.analysis.runes && left.type === 'MemberExpression') { if (context.state.analysis.runes && left.type === 'MemberExpression') {
// special case — state declaration in class constructor const name = get_name(left.property);
const ancestor = context.path.at(-4);
if (ancestor?.type === 'MethodDefinition' && ancestor.kind === 'constructor') { if (name !== null) {
const rune = get_rune(right, context.state.scope); // special case — state declaration in class constructor
const ancestor = context.path.at(-4);
if (rune) { if (ancestor?.type === 'MethodDefinition' && ancestor.kind === 'constructor') {
const name = get_name(left.property); const rune = get_rune(right, context.state.scope);
const key =
left.property.type === 'PrivateIdentifier' || rune === '$state' || rune === '$state.raw'
? left.property
: context.state.backing_fields[name];
const l = b.member(b.this, key, key.type === 'Literal'); if (rune) {
const key =
left.property.type === 'PrivateIdentifier' || rune === '$state' || rune === '$state.raw'
? left.property
: context.state.backing_fields[name];
const r = /** @type {Expression} */ (context.visit(right)); const l = b.member(b.this, key, key.type === 'Literal');
return b.assignment(operator, l, r); const r = /** @type {Expression} */ (context.visit(right));
return b.assignment(operator, l, r);
}
} }
} }
} }

@ -69,14 +69,9 @@ export function ClassBody(node, context) {
const backing = backing_fields[name]; const backing = backing_fields[name];
const member = b.member(b.this, backing); const member = b.member(b.this, backing);
const should_proxy = field.type === '$state' && true; // TODO
const key = b.key(name);
body.push( body.push(
b.prop_def(backing, null), b.prop_def(backing, null),
b.method('get', b.key(name), [], [b.return(b.call(member))])
b.method('get', key, [], [b.return(b.call(member))])
); );
} }
} }
@ -108,8 +103,6 @@ export function ClassBody(node, context) {
const backing = backing_fields[name]; const backing = backing_fields[name];
const member = b.member(b.this, backing); const member = b.member(b.this, backing);
const should_proxy = field.type === '$state' && true; // TODO
body.push( body.push(
b.prop_def( b.prop_def(
backing, backing,

@ -1,23 +0,0 @@
/** @import { MemberExpression } from 'estree' */
/** @import { Context } from '../types.js' */
import * as b from '#compiler/builders';
/**
* @param {MemberExpression} node
* @param {Context} context
*/
export function MemberExpression(node, context) {
if (
context.state.analysis.runes &&
node.object.type === 'ThisExpression' &&
node.property.type === 'PrivateIdentifier'
) {
const field = context.state.private_derived.get(node.property.name);
if (field) {
return b.call(node);
}
}
context.next();
}

@ -1,10 +1,14 @@
import type { Scope } from '../scope.js'; import type { Scope } from '../scope.js';
import type { AST, ValidatedModuleCompileOptions } from '#compiler'; import type { AST, StateField, ValidatedModuleCompileOptions } from '#compiler';
import type { Analysis } from '../types.js'; import type { Analysis } from '../types.js';
import type { PrivateIdentifier } from 'estree';
export interface TransformState { export interface TransformState {
readonly analysis: Analysis; readonly analysis: Analysis;
readonly options: ValidatedModuleCompileOptions; readonly options: ValidatedModuleCompileOptions;
readonly scope: Scope; readonly scope: Scope;
readonly scopes: Map<AST.SvelteNode, Scope>; readonly scopes: Map<AST.SvelteNode, Scope>;
readonly state_fields: Record<string, StateField>;
readonly backing_fields: Record<string, PrivateIdentifier>;
} }

Loading…
Cancel
Save