warn on assignment to const

pull/4960/head
Billy Levin 6 years ago committed by tanhauhau
parent 6ac7038e47
commit d6a9182d21

@ -788,6 +788,33 @@ export default class Component {
scope = map.get(node); scope = map.get(node);
} }
let deep = false;
let names: string[] | null;
if (node.type === 'AssignmentExpression') {
deep = node.left.type === 'MemberExpression';
names = deep
? [get_object(node.left).name]
: extract_names(node.left);
} else if (node.type === 'UpdateExpression') {
deep = node.argument.type === 'MemberExpression';
const { name } = get_object(node.argument);
names = [name];
}
if (names) {
names.forEach(name => {
const variable = component.var_lookup.get(name);
if (variable && variable.writable === false && !deep) {
component.warn(node as any, {
code: 'assignment-to-const',
message: 'You are assigning to a const'
});
}
});
}
if (node.type === 'ImportDeclaration') { if (node.type === 'ImportDeclaration') {
component.extract_imports(node); component.extract_imports(node);
// TODO: to use actual remove // TODO: to use actual remove

@ -62,7 +62,7 @@ export default class Expression {
// discover dependencies, but don't change the code yet // discover dependencies, but don't change the code yet
walk(info, { walk(info, {
enter(node: any, parent: any, key: string) { enter(node: Node, parent: any, key: string) {
// don't manipulate shorthand props twice // don't manipulate shorthand props twice
if (key === 'key' && parent.shorthand) return; if (key === 'key' && parent.shorthand) return;
// don't manipulate `import.meta`, `new.target` // don't manipulate `import.meta`, `new.target`
@ -126,6 +126,7 @@ export default class Expression {
deep = node.left.type === 'MemberExpression'; deep = node.left.type === 'MemberExpression';
names = extract_names(deep ? get_object(node.left) : node.left); names = extract_names(deep ? get_object(node.left) : node.left);
} else if (node.type === 'UpdateExpression') { } else if (node.type === 'UpdateExpression') {
deep = node.argument.type === 'MemberExpression';
names = extract_names(get_object(node.argument)); names = extract_names(get_object(node.argument));
} }
} }
@ -146,8 +147,18 @@ export default class Expression {
} else { } else {
component.add_reference(node, name); component.add_reference(node, name);
const variable = component.var_lookup.get(name); const variable = component.var_lookup.get(name);
if (variable) variable[deep ? 'mutated' : 'reassigned'] = true;
if (variable) {
variable[deep ? 'mutated' : 'reassigned'] = true;
if (!deep && variable.writable === false) {
component.warn(node as any, {
code: 'assignment-to-const',
message: 'You are assigning to a const'
});
}
}
} }
}); });
} }

@ -0,0 +1,34 @@
<script>
const immutable1 = false;
const immutable2 = 0;
// these ones should not warn
const obj1 = { prop: true };
const obj2 = { prop: 0 };
function func1() {
immutable1 = true
}
function func2() {
immutable2++;
}
function func3() {
obj1.prop = false;
}
function func4() {
obj2.prop++;
}
</script>
<button on:click={func1}>click</button>
<button on:click={func2}>click</button>
<button on:click={func3}>click</button>
<button on:click={func4}>click</button>
<button on:click={() => immutable2 = true}>click</button>
<button on:click={() => immutable2++}>click</button>
<button on:click={() => obj1.prop = false}>click</button>
<button on:click={() => obj2.prop++}>click</button>

@ -0,0 +1,62 @@
[
{
"code": "assignment-to-const",
"message": "You are assigning to a const",
"start": {
"line": 31,
"column": 24,
"character": 512
},
"end": {
"line": 31,
"column": 41,
"character": 529
},
"pos": 512
},
{
"code": "assignment-to-const",
"message": "You are assigning to a const",
"start": {
"line": 32,
"column": 24,
"character": 570
},
"end": {
"line": 32,
"column": 36,
"character": 582
},
"pos": 570
},
{
"code": "assignment-to-const",
"message": "You are assigning to a const",
"start": {
"line": 10,
"column": 2,
"character": 171
},
"end": {
"line": 10,
"column": 19,
"character": 188
},
"pos": 171
},
{
"code": "assignment-to-const",
"message": "You are assigning to a const",
"start": {
"line": 14,
"column": 2,
"character": 215
},
"end": {
"line": 14,
"column": 14,
"character": 227
},
"pos": 215
}
]
Loading…
Cancel
Save