Merge pull request #1345 from sveltejs/gh-1069

use destructuring syntax for computed props in v2 mode - fixes #1069
pull/1346/head
Rich Harris 7 years ago committed by GitHub
commit 6249fa6bc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -84,6 +84,7 @@ export default class Generator {
source: string;
name: string;
options: CompileOptions;
v2: boolean;
customElement: CustomElementOptions;
tag: string;
@ -132,6 +133,8 @@ export default class Generator {
stats.start('compile');
this.stats = stats;
this.v2 = options.parser === 'v2';
this.ast = clone(parsed);
this.parsed = parsed;
@ -575,10 +578,10 @@ export default class Generator {
const key = getName(prop.key);
const value = prop.value;
const deps = value.params.map(
(param: Node) =>
param.type === 'AssignmentPattern' ? param.left.name : param.name
);
const deps = this.v2
? value.params[0].properties.map(prop => prop.key.name)
: value.params.map(param => param.type === 'AssignmentPattern' ? param.left.name : param.name);
deps.forEach(dep => {
this.expectedProperties.add(dep);
});

@ -99,9 +99,11 @@ export default function dom(
const condition = `${deps.map(dep => `changed.${dep}`).join(' || ')}`;
const statement = `if (this._differs(state.${key}, (state.${key} = %computed-${key}(${deps
.map(dep => `state.${dep}`)
.join(', ')})))) changed.${key} = true;`;
const call = generator.v2
? `%computed-${key}(state)`
: `%computed-${key}(${deps.map(dep => `state.${dep}`).join(', ')})`;
const statement = `if (this._differs(state.${key}, (state.${key} = ${call}))) changed.${key} = true;`;
computationBuilder.addConditional(condition, statement);
});

@ -10,6 +10,7 @@ import { Node, Parsed, CompileOptions, Warning } from '../interfaces';
export class Validator {
readonly source: string;
readonly filename: string;
readonly v2: boolean;
options: CompileOptions;
onwarn: ({}) => void;
@ -38,6 +39,7 @@ export class Validator {
this.filename = options.filename;
this.onwarn = options.onwarn;
this.options = options;
this.v2 = options.parser === 'v2';
this.namespace = null;
this.defaultExport = null;
@ -96,7 +98,7 @@ export default function validate(
stylesheet: Stylesheet,
options: CompileOptions
) {
const { onwarn, onerror, name, filename, store, dev } = options;
const { onwarn, onerror, name, filename, store, dev, parser } = options;
try {
if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) {
@ -119,7 +121,8 @@ export default function validate(
name,
filename,
store,
dev
dev,
parser
});
if (parsed.js) {

@ -7,6 +7,7 @@ import { Validator } from '../../index';
import { Node } from '../../../interfaces';
import walkThroughTopFunctionScope from '../../../utils/walkThroughTopFunctionScope';
import isThisGetCallExpression from '../../../utils/isThisGetCallExpression';
import validCalleeObjects from '../../../utils/validCalleeObjects';
const isFunctionExpression = new Set([
'FunctionExpression',
@ -74,19 +75,37 @@ export default function computed(validator: Validator, prop: Node) {
});
}
params.forEach((param: Node) => {
const valid =
param.type === 'Identifier' ||
(param.type === 'AssignmentPattern' &&
param.left.type === 'Identifier');
if (!valid) {
// TODO change this for v2
validator.error(param, {
if (validator.v2) {
if (params.length > 1) {
validator.error(computation.value, {
code: `invalid-computed-arguments`,
message: `Computed properties cannot use destructuring in function parameters`
message: `Computed properties must take a single argument`
});
}
});
const param = params[0];
if (param.type !== 'ObjectPattern') {
// TODO in v2, allow the entire object to be passed in
validator.error(computation.value, {
code: `invalid-computed-argument`,
message: `Computed property argument must be a destructured object pattern`
});
}
} else {
params.forEach((param: Node) => {
const valid =
param.type === 'Identifier' ||
(param.type === 'AssignmentPattern' &&
param.left.type === 'Identifier');
if (!valid) {
// TODO change this for v2
validator.error(param, {
code: `invalid-computed-arguments`,
message: `Computed properties cannot use destructuring in function parameters`
});
}
});
}
});
}

@ -203,7 +203,7 @@ var protoDev = {
/* generated by Svelte vX.Y.Z */
function bar(foo) {
function bar({ foo }) {
return foo * 2;
}
@ -268,7 +268,7 @@ SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) {
SvelteComponent.prototype._recompute = function _recompute(changed, state) {
if (changed.foo) {
if (this._differs(state.bar, (state.bar = bar(state.foo)))) changed.bar = true;
if (this._differs(state.bar, (state.bar = bar(state)))) changed.bar = true;
}
};

@ -203,7 +203,7 @@ var protoDev = {
/* generated by Svelte vX.Y.Z */
function bar(foo) {
function bar({ foo }) {
return foo * 2;
}
@ -268,7 +268,7 @@ SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) {
SvelteComponent.prototype._recompute = function _recompute(changed, state) {
if (changed.foo) {
if (this._differs(state.bar, (state.bar = bar(state.foo)))) changed.bar = true;
if (this._differs(state.bar, (state.bar = bar(state)))) changed.bar = true;
}
};

@ -1,7 +1,7 @@
/* generated by Svelte vX.Y.Z */
import { appendNode, assign, createElement, createText, detachNode, init, insertNode, noop, protoDev } from "svelte/shared.js";
function bar(foo) {
function bar({ foo }) {
return foo * 2;
}
@ -66,7 +66,7 @@ SvelteComponent.prototype._checkReadOnly = function _checkReadOnly(newState) {
SvelteComponent.prototype._recompute = function _recompute(changed, state) {
if (changed.foo) {
if (this._differs(state.bar, (state.bar = bar(state.foo)))) changed.bar = true;
if (this._differs(state.bar, (state.bar = bar(state)))) changed.bar = true;
}
}
export default SvelteComponent;

@ -6,7 +6,7 @@
<script>
export default {
computed: {
bar: foo => foo * 2
bar: ({ foo }) => foo * 2
}
};
</script>

@ -0,0 +1,20 @@
<p>{scale(x)}</p>
<script>
export default {
data: () => ({
x: 5,
domain: [ 0, 10 ],
range: [ 0, 100 ]
}),
computed: {
scale: ({ domain, range }) => {
return num => {
const t = domain[0] + ( num - domain[0] ) / ( domain[1] - domain[0] );
return range[0] + t * ( range[1] - range[0] );
}
}
}
};
</script>

@ -0,0 +1,14 @@
<span>{state}</span>
<script>
export default {
data() {
return {
x: 'waiting'
};
},
computed: {
state: ({ x }) => x
}
};
</script>

@ -0,0 +1,9 @@
<p>{foo}</p>
<script>
export default {
computed: {
foo: ({ a = 1 }) => a * 2
}
};
</script>

@ -0,0 +1,28 @@
<p>{x}</p>
<script>
let _x;
function getX () {
return _x;
}
export default {
data () {
return {
y: 1
};
},
computed: {
xGetter ({ y }) {
_x = y * 2;
return getX;
},
x ({ xGetter }) {
return xGetter();
}
}
};
</script>

@ -0,0 +1,16 @@
<p>{a} + {b} = {c}</p>
<p>{c} * {c} = {cSquared}</p>
<script>
export default {
data: () => ({
a: 1,
b: 2
}),
computed: {
c: ({ a, b }) => a + b,
cSquared: ({ c }) => c * c
}
};
</script>
Loading…
Cancel
Save