Skip to content

Commit 02c86b1

Browse files
paoloricciutiConduitryRich-Harris
authored
feat: error on invalid component name (#12821)
* feat: treat tag with `[` as a component, even if lowercase * chore: simpler regex Co-authored-by: Conduitry <[email protected]> * feat: error on invalid component name * fix: fully revert dot notation test * tweak error message --------- Co-authored-by: Conduitry <[email protected]> Co-authored-by: Rich Harris <[email protected]>
1 parent 9d9ed33 commit 02c86b1

File tree

6 files changed

+34
-0
lines changed

6 files changed

+34
-0
lines changed

.changeset/tender-bats-switch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: error on invalid component name

packages/svelte/messages/compile-errors/template.md

+4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100

101101
> This type of directive is not valid on components
102102
103+
## component_invalid_name
104+
105+
> Component name must be a valid variable name or dot notation expression
106+
103107
## const_tag_cycle
104108

105109
> Cyclical dependency detected: %cycle%

packages/svelte/src/compiler/errors.js

+9
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,15 @@ export function component_invalid_directive(node) {
786786
e(node, "component_invalid_directive", "This type of directive is not valid on components");
787787
}
788788

789+
/**
790+
* Component name must be a valid variable name or dot notation expression
791+
* @param {null | number | NodeLike} node
792+
* @returns {never}
793+
*/
794+
export function component_invalid_name(node) {
795+
e(node, "component_invalid_name", "Component name must be a valid variable name or dot notation expression");
796+
}
797+
789798
/**
790799
* Cyclical dependency detected: %cycle%
791800
* @param {null | number | NodeLike} node

packages/svelte/src/compiler/phases/1-parse/state/element.js

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ function parent_is_shadowroot_template(stack) {
7575
const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i;
7676
const regex_closing_comment = /-->/;
7777
const regex_component_name = /^(?:[A-Z]|[A-Za-z][A-Za-z0-9_$]*\.)/;
78+
const regex_valid_component_name =
79+
/^(?:[A-Z][A-Za-z0-9_$.]*|[a-z][A-Za-z0-9_$]*\.[A-Za-z0-9_$])[A-Za-z0-9_$.]*$/;
7880

7981
/** @param {Parser} parser */
8082
export default function element(parser) {
@@ -136,6 +138,10 @@ export default function element(parser) {
136138
? 'SlotElement'
137139
: 'RegularElement';
138140

141+
if (type === 'Component' && !regex_valid_component_name.test(name)) {
142+
e.component_invalid_name({ start: start + 1, end: start + name.length + 1 });
143+
}
144+
139145
/** @type {Compiler.ElementLike} */
140146
const element =
141147
type === 'RegularElement'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
error: {
5+
code: 'component_invalid_name',
6+
message: 'Component name must be a valid variable name or dot notation expression',
7+
position: [1, 14]
8+
}
9+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Components[1] />

0 commit comments

Comments
 (0)