[fix] raise compile error if variable name is same as imported variable name (#7145)

pull/7190/head
Yuichiro Yamashita 3 years ago committed by GitHub
parent 0881aa98d7
commit 5665f711fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -191,27 +191,33 @@ export default class Component {
this.stylesheet.warn_on_unused_selectors(this); this.stylesheet.warn_on_unused_selectors(this);
} }
add_var(variable: Var, add_to_lookup = true) { add_var(node: Node, variable: Var, add_to_lookup = true) {
this.vars.push(variable); this.vars.push(variable);
if (add_to_lookup) { if (add_to_lookup) {
if (this.var_lookup.has(variable.name)) {
const exists_var = this.var_lookup.get(variable.name);
if (exists_var.module && exists_var.imported) {
this.error(node as any, compiler_errors.illegal_variable_declaration);
}
}
this.var_lookup.set(variable.name, variable); this.var_lookup.set(variable.name, variable);
} }
} }
add_reference(name: string) { add_reference(node: Node, name: string) {
const variable = this.var_lookup.get(name); const variable = this.var_lookup.get(name);
if (variable) { if (variable) {
variable.referenced = true; variable.referenced = true;
} else if (is_reserved_keyword(name)) { } else if (is_reserved_keyword(name)) {
this.add_var({ this.add_var(node, {
name, name,
injected: true, injected: true,
referenced: true referenced: true
}); });
} else if (name[0] === '$') { } else if (name[0] === '$') {
this.add_var({ this.add_var(node, {
name, name,
injected: true, injected: true,
referenced: true, referenced: true,
@ -228,7 +234,7 @@ export default class Component {
} }
} else { } else {
if (this.compile_options.varsReport === 'full') { if (this.compile_options.varsReport === 'full') {
this.add_var({ name, referenced: true }, false); this.add_var(node, { name, referenced: true }, false);
} }
this.used_names.add(name); this.used_names.add(name);
@ -599,12 +605,14 @@ export default class Component {
} }
const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let'); const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let');
const imported = node.type.startsWith('Import');
this.add_var({ this.add_var(node, {
name, name,
module: true, module: true,
hoistable: true, hoistable: true,
writable writable,
imported
}); });
}); });
@ -612,7 +620,7 @@ export default class Component {
if (name[0] === '$') { if (name[0] === '$') {
return this.error(node as any, compiler_errors.illegal_subscription); return this.error(node as any, compiler_errors.illegal_subscription);
} else { } else {
this.add_var({ this.add_var(node, {
name, name,
global: true, global: true,
hoistable: true hoistable: true
@ -674,7 +682,7 @@ export default class Component {
const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let'); const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let');
const imported = node.type.startsWith('Import'); const imported = node.type.startsWith('Import');
this.add_var({ this.add_var(node, {
name, name,
initialised: instance_scope.initialised_declarations.has(name), initialised: instance_scope.initialised_declarations.has(name),
writable, writable,
@ -697,7 +705,7 @@ export default class Component {
const node = globals.get(name); const node = globals.get(name);
if (this.injected_reactive_declaration_vars.has(name)) { if (this.injected_reactive_declaration_vars.has(name)) {
this.add_var({ this.add_var(node, {
name, name,
injected: true, injected: true,
writable: true, writable: true,
@ -705,7 +713,7 @@ export default class Component {
initialised: true initialised: true
}); });
} else if (is_reserved_keyword(name)) { } else if (is_reserved_keyword(name)) {
this.add_var({ this.add_var(node, {
name, name,
injected: true injected: true
}); });
@ -714,14 +722,14 @@ export default class Component {
return this.error(node as any, compiler_errors.illegal_global(name)); return this.error(node as any, compiler_errors.illegal_global(name));
} }
this.add_var({ this.add_var(node, {
name, name,
injected: true, injected: true,
mutated: true, mutated: true,
writable: true writable: true
}); });
this.add_reference(name.slice(1)); this.add_reference(node, name.slice(1));
const variable = this.var_lookup.get(name.slice(1)); const variable = this.var_lookup.get(name.slice(1));
if (variable) { if (variable) {
@ -729,7 +737,7 @@ export default class Component {
variable.referenced_from_script = true; variable.referenced_from_script = true;
} }
} else { } else {
this.add_var({ this.add_var(node, {
name, name,
global: true, global: true,
hoistable: true hoistable: true

@ -190,6 +190,10 @@ export default {
code: 'illegal-global', code: 'illegal-global',
message: `${name} is an illegal variable name` message: `${name} is an illegal variable name`
}), }),
illegal_variable_declaration: {
code: 'illegal-variable-declaration',
message: 'Cannot declare same variable name which is imported inside <script context="module">'
},
cyclical_reactive_declaration: (cycle: string[]) => ({ cyclical_reactive_declaration: (cycle: string[]) => ({
code: 'cyclical-reactive-declaration', code: 'cyclical-reactive-declaration',
message: `Cyclical dependency detected: ${cycle.join(' → ')}` message: `Cyclical dependency detected: ${cycle.join(' → ')}`

@ -18,7 +18,7 @@ export default class Action extends Node {
component.warn_if_undefined(object, info, scope); component.warn_if_undefined(object, info, scope);
this.name = info.name; this.name = info.name;
component.add_reference(object); component.add_reference(this as any, object);
this.expression = info.expression this.expression = info.expression
? new Expression(component, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)

@ -18,7 +18,7 @@ export default class Animation extends Node {
component.warn_if_undefined(info.name, info, scope); component.warn_if_undefined(info.name, info, scope);
this.name = info.name; this.name = info.name;
component.add_reference(info.name.split('.')[0]); component.add_reference(this as any, info.name.split('.')[0]);
if (parent.animation) { if (parent.animation) {
component.error(this, compiler_errors.duplicate_animation); component.error(this, compiler_errors.duplicate_animation);

@ -29,7 +29,7 @@ export default class InlineComponent extends Node {
if (info.name !== 'svelte:component' && info.name !== 'svelte:self') { if (info.name !== 'svelte:component' && info.name !== 'svelte:self') {
const name = info.name.split('.')[0]; // accommodate namespaces const name = info.name.split('.')[0]; // accommodate namespaces
component.warn_if_undefined(name, info, scope); component.warn_if_undefined(name, info, scope);
component.add_reference(name); component.add_reference(this as any, name);
} }
this.name = info.name; this.name = info.name;
@ -141,10 +141,10 @@ export default class InlineComponent extends Node {
} }
if (info.children.some(node => not_whitespace_text(node))) { if (info.children.some(node => not_whitespace_text(node))) {
children.push({ children.push({
start: info.start, start: info.start,
end: info.end, end: info.end,
type: 'SlotTemplate', type: 'SlotTemplate',
name: 'svelte:fragment', name: 'svelte:fragment',
attributes: [], attributes: [],
children: info.children children: info.children

@ -19,7 +19,7 @@ export default class Transition extends Node {
component.warn_if_undefined(info.name, info, scope); component.warn_if_undefined(info.name, info, scope);
this.name = info.name; this.name = info.name;
component.add_reference(info.name.split('.')[0]); component.add_reference(this as any, info.name.split('.')[0]);
this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out'; this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';
this.is_local = info.modifiers.includes('local'); this.is_local = info.modifiers.includes('local');

@ -187,7 +187,7 @@ function mark_referenced(
if (is_reference(node, parent)) { if (is_reference(node, parent)) {
const { name } = flatten_reference(node); const { name } = flatten_reference(node);
if (!scope.is_let(name) && !scope.names.has(name)) { if (!scope.is_let(name) && !scope.names.has(name)) {
component.add_reference(name); component.add_reference(node, name);
} }
} }
} }

@ -110,7 +110,7 @@ export default class Expression {
dependencies.add(name); dependencies.add(name);
} }
component.add_reference(name); component.add_reference(node, name);
component.warn_if_undefined(name, nodes[0], template_scope); component.warn_if_undefined(name, nodes[0], template_scope);
} }
@ -144,7 +144,7 @@ export default class Expression {
const each_block = template_scope.get_owner(name); const each_block = template_scope.get_owner(name);
(each_block as EachBlock).has_binding = true; (each_block as EachBlock).has_binding = true;
} else { } else {
component.add_reference(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;
@ -220,7 +220,7 @@ export default class Expression {
}); });
} else { } else {
dependencies.add(name); dependencies.add(name);
component.add_reference(name); // TODO is this redundant/misplaced? component.add_reference(node, name); // TODO is this redundant/misplaced?
} }
} else if (is_contextual(component, template_scope, name)) { } else if (is_contextual(component, template_scope, name)) {
const reference = block.renderer.reference(node, ctx); const reference = block.renderer.reference(node, ctx);
@ -267,7 +267,7 @@ export default class Expression {
this.replace(id as any); this.replace(id as any);
component.add_var({ component.add_var(node, {
name: id.name, name: id.name,
internal: true, internal: true,
hoistable: true, hoistable: true,

@ -264,7 +264,7 @@ export default class Renderer {
// TODO is this correct? // TODO is this correct?
if (this.component.var_lookup.get(name)) { if (this.component.var_lookup.get(name)) {
this.component.add_reference(name); this.component.add_reference(node, name);
} }
if (member !== undefined) { if (member !== undefined) {

@ -0,0 +1,17 @@
[
{
"code": "illegal-variable-declaration",
"message": "Cannot declare same variable name which is imported inside <script context=\"module\">",
"start": {
"line": 6,
"column": 1,
"character": 86
},
"end": {
"line": 6,
"column": 9,
"character": 94
},
"pos": 86
}
]

@ -0,0 +1,9 @@
<script context="module">
import { FOO } from './dummy.svelte';
</script>
<script>
let FOO;
</script>
{FOO}
Loading…
Cancel
Save