Skip to content

Commit 5665f71

Browse files
authored
[fix] raise compile error if variable name is same as imported variable name (#7145)
1 parent 0881aa9 commit 5665f71

File tree

11 files changed

+64
-26
lines changed

11 files changed

+64
-26
lines changed

src/compiler/compile/Component.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -191,27 +191,33 @@ export default class Component {
191191
this.stylesheet.warn_on_unused_selectors(this);
192192
}
193193

194-
add_var(variable: Var, add_to_lookup = true) {
194+
add_var(node: Node, variable: Var, add_to_lookup = true) {
195195
this.vars.push(variable);
196196

197197
if (add_to_lookup) {
198+
if (this.var_lookup.has(variable.name)) {
199+
const exists_var = this.var_lookup.get(variable.name);
200+
if (exists_var.module && exists_var.imported) {
201+
this.error(node as any, compiler_errors.illegal_variable_declaration);
202+
}
203+
}
198204
this.var_lookup.set(variable.name, variable);
199205
}
200206
}
201207

202-
add_reference(name: string) {
208+
add_reference(node: Node, name: string) {
203209
const variable = this.var_lookup.get(name);
204210

205211
if (variable) {
206212
variable.referenced = true;
207213
} else if (is_reserved_keyword(name)) {
208-
this.add_var({
214+
this.add_var(node, {
209215
name,
210216
injected: true,
211217
referenced: true
212218
});
213219
} else if (name[0] === '$') {
214-
this.add_var({
220+
this.add_var(node, {
215221
name,
216222
injected: true,
217223
referenced: true,
@@ -228,7 +234,7 @@ export default class Component {
228234
}
229235
} else {
230236
if (this.compile_options.varsReport === 'full') {
231-
this.add_var({ name, referenced: true }, false);
237+
this.add_var(node, { name, referenced: true }, false);
232238
}
233239

234240
this.used_names.add(name);
@@ -599,20 +605,22 @@ export default class Component {
599605
}
600606

601607
const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let');
608+
const imported = node.type.startsWith('Import');
602609

603-
this.add_var({
610+
this.add_var(node, {
604611
name,
605612
module: true,
606613
hoistable: true,
607-
writable
614+
writable,
615+
imported
608616
});
609617
});
610618

611619
globals.forEach((node, name) => {
612620
if (name[0] === '$') {
613621
return this.error(node as any, compiler_errors.illegal_subscription);
614622
} else {
615-
this.add_var({
623+
this.add_var(node, {
616624
name,
617625
global: true,
618626
hoistable: true
@@ -674,7 +682,7 @@ export default class Component {
674682
const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let');
675683
const imported = node.type.startsWith('Import');
676684

677-
this.add_var({
685+
this.add_var(node, {
678686
name,
679687
initialised: instance_scope.initialised_declarations.has(name),
680688
writable,
@@ -697,15 +705,15 @@ export default class Component {
697705
const node = globals.get(name);
698706

699707
if (this.injected_reactive_declaration_vars.has(name)) {
700-
this.add_var({
708+
this.add_var(node, {
701709
name,
702710
injected: true,
703711
writable: true,
704712
reassigned: true,
705713
initialised: true
706714
});
707715
} else if (is_reserved_keyword(name)) {
708-
this.add_var({
716+
this.add_var(node, {
709717
name,
710718
injected: true
711719
});
@@ -714,22 +722,22 @@ export default class Component {
714722
return this.error(node as any, compiler_errors.illegal_global(name));
715723
}
716724

717-
this.add_var({
725+
this.add_var(node, {
718726
name,
719727
injected: true,
720728
mutated: true,
721729
writable: true
722730
});
723731

724-
this.add_reference(name.slice(1));
732+
this.add_reference(node, name.slice(1));
725733

726734
const variable = this.var_lookup.get(name.slice(1));
727735
if (variable) {
728736
variable.subscribable = true;
729737
variable.referenced_from_script = true;
730738
}
731739
} else {
732-
this.add_var({
740+
this.add_var(node, {
733741
name,
734742
global: true,
735743
hoistable: true

src/compiler/compile/compiler_errors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ export default {
190190
code: 'illegal-global',
191191
message: `${name} is an illegal variable name`
192192
}),
193+
illegal_variable_declaration: {
194+
code: 'illegal-variable-declaration',
195+
message: 'Cannot declare same variable name which is imported inside <script context="module">'
196+
},
193197
cyclical_reactive_declaration: (cycle: string[]) => ({
194198
code: 'cyclical-reactive-declaration',
195199
message: `Cyclical dependency detected: ${cycle.join(' → ')}`

src/compiler/compile/nodes/Action.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class Action extends Node {
1818
component.warn_if_undefined(object, info, scope);
1919

2020
this.name = info.name;
21-
component.add_reference(object);
21+
component.add_reference(this as any, object);
2222

2323
this.expression = info.expression
2424
? new Expression(component, this, scope, info.expression)

src/compiler/compile/nodes/Animation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class Animation extends Node {
1818
component.warn_if_undefined(info.name, info, scope);
1919

2020
this.name = info.name;
21-
component.add_reference(info.name.split('.')[0]);
21+
component.add_reference(this as any, info.name.split('.')[0]);
2222

2323
if (parent.animation) {
2424
component.error(this, compiler_errors.duplicate_animation);

src/compiler/compile/nodes/InlineComponent.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default class InlineComponent extends Node {
2929
if (info.name !== 'svelte:component' && info.name !== 'svelte:self') {
3030
const name = info.name.split('.')[0]; // accommodate namespaces
3131
component.warn_if_undefined(name, info, scope);
32-
component.add_reference(name);
32+
component.add_reference(this as any, name);
3333
}
3434

3535
this.name = info.name;
@@ -141,10 +141,10 @@ export default class InlineComponent extends Node {
141141
}
142142

143143
if (info.children.some(node => not_whitespace_text(node))) {
144-
children.push({
144+
children.push({
145145
start: info.start,
146146
end: info.end,
147-
type: 'SlotTemplate',
147+
type: 'SlotTemplate',
148148
name: 'svelte:fragment',
149149
attributes: [],
150150
children: info.children

src/compiler/compile/nodes/Transition.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default class Transition extends Node {
1919
component.warn_if_undefined(info.name, info, scope);
2020

2121
this.name = info.name;
22-
component.add_reference(info.name.split('.')[0]);
22+
component.add_reference(this as any, info.name.split('.')[0]);
2323

2424
this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';
2525
this.is_local = info.modifiers.includes('local');

src/compiler/compile/nodes/shared/Context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ function mark_referenced(
187187
if (is_reference(node, parent)) {
188188
const { name } = flatten_reference(node);
189189
if (!scope.is_let(name) && !scope.names.has(name)) {
190-
component.add_reference(name);
190+
component.add_reference(node, name);
191191
}
192192
}
193193
}

src/compiler/compile/nodes/shared/Expression.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export default class Expression {
110110
dependencies.add(name);
111111
}
112112

113-
component.add_reference(name);
113+
component.add_reference(node, name);
114114
component.warn_if_undefined(name, nodes[0], template_scope);
115115
}
116116

@@ -144,7 +144,7 @@ export default class Expression {
144144
const each_block = template_scope.get_owner(name);
145145
(each_block as EachBlock).has_binding = true;
146146
} else {
147-
component.add_reference(name);
147+
component.add_reference(node, name);
148148

149149
const variable = component.var_lookup.get(name);
150150
if (variable) variable[deep ? 'mutated' : 'reassigned'] = true;
@@ -220,7 +220,7 @@ export default class Expression {
220220
});
221221
} else {
222222
dependencies.add(name);
223-
component.add_reference(name); // TODO is this redundant/misplaced?
223+
component.add_reference(node, name); // TODO is this redundant/misplaced?
224224
}
225225
} else if (is_contextual(component, template_scope, name)) {
226226
const reference = block.renderer.reference(node, ctx);
@@ -267,7 +267,7 @@ export default class Expression {
267267

268268
this.replace(id as any);
269269

270-
component.add_var({
270+
component.add_var(node, {
271271
name: id.name,
272272
internal: true,
273273
hoistable: true,

src/compiler/compile/render_dom/Renderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ export default class Renderer {
264264

265265
// TODO is this correct?
266266
if (this.component.var_lookup.get(name)) {
267-
this.component.add_reference(name);
267+
this.component.add_reference(node, name);
268268
}
269269

270270
if (member !== undefined) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"code": "illegal-variable-declaration",
4+
"message": "Cannot declare same variable name which is imported inside <script context=\"module\">",
5+
"start": {
6+
"line": 6,
7+
"column": 1,
8+
"character": 86
9+
},
10+
"end": {
11+
"line": 6,
12+
"column": 9,
13+
"character": 94
14+
},
15+
"pos": 86
16+
}
17+
]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<script context="module">
2+
import { FOO } from './dummy.svelte';
3+
</script>
4+
5+
<script>
6+
let FOO;
7+
</script>
8+
9+
{FOO}

0 commit comments

Comments
 (0)