mirror of
https://github.com/sveltejs/svelte.git
synced 2024-12-01 01:11:24 +01:00
better error message for mismatched tags due to autoclosing (#5060)
This commit is contained in:
parent
40987b7780
commit
3dad14f0e1
@ -5,6 +5,7 @@
|
||||
* Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144))
|
||||
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
|
||||
* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118))
|
||||
* Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049))
|
||||
|
||||
## 3.24.0
|
||||
|
||||
|
@ -8,6 +8,12 @@ import error from '../utils/error';
|
||||
|
||||
type ParserState = (parser: Parser) => (ParserState | void);
|
||||
|
||||
interface LastAutoClosedTag {
|
||||
tag: string;
|
||||
reason: string;
|
||||
depth: number;
|
||||
}
|
||||
|
||||
export class Parser {
|
||||
readonly template: string;
|
||||
readonly filename?: string;
|
||||
@ -20,6 +26,7 @@ export class Parser {
|
||||
css: Style[] = [];
|
||||
js: Script[] = [];
|
||||
meta_tags = {};
|
||||
last_auto_closed_tag?: LastAutoClosedTag;
|
||||
|
||||
constructor(template: string, options: ParserOptions) {
|
||||
if (typeof template !== 'string') {
|
||||
|
@ -133,11 +133,15 @@ export default function tag(parser: Parser) {
|
||||
|
||||
// close any elements that don't have their own closing tags, e.g. <div><p></div>
|
||||
while (parent.name !== name) {
|
||||
if (parent.type !== 'Element')
|
||||
if (parent.type !== 'Element') {
|
||||
const message = parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name
|
||||
? `</${name}> attempted to close <${name}> that was already automatically closed by <${parser.last_auto_closed_tag.reason}>`
|
||||
: `</${name}> attempted to close an element that was not open`;
|
||||
parser.error({
|
||||
code: `invalid-closing-tag`,
|
||||
message: `</${name}> attempted to close an element that was not open`
|
||||
message
|
||||
}, start);
|
||||
}
|
||||
|
||||
parent.end = start;
|
||||
parser.stack.pop();
|
||||
@ -148,10 +152,19 @@ export default function tag(parser: Parser) {
|
||||
parent.end = parser.index;
|
||||
parser.stack.pop();
|
||||
|
||||
if (parser.last_auto_closed_tag && parser.stack.length < parser.last_auto_closed_tag.depth) {
|
||||
parser.last_auto_closed_tag = null;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (closing_tag_omitted(parent.name, name)) {
|
||||
parent.end = start;
|
||||
parser.stack.pop();
|
||||
parser.last_auto_closed_tag = {
|
||||
tag: parent.name,
|
||||
reason: name,
|
||||
depth: parser.stack.length,
|
||||
};
|
||||
}
|
||||
|
||||
const unique_names: Set<string> = new Set();
|
||||
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"code": "invalid-closing-tag",
|
||||
"message": "</p> attempted to close an element that was not open",
|
||||
"pos": 38,
|
||||
"start": {
|
||||
"character": 38,
|
||||
"column": 0,
|
||||
"line": 5
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<div>
|
||||
<p>
|
||||
<pre>pre tag</pre>
|
||||
</div>
|
||||
</p>
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"code": "invalid-closing-tag",
|
||||
"message": "</p> attempted to close <p> that was already automatically closed by <pre>",
|
||||
"pos": 24,
|
||||
"start": {
|
||||
"character": 24,
|
||||
"column": 0,
|
||||
"line": 3
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>
|
||||
<pre>pre tag</pre>
|
||||
</p>
|
Loading…
Reference in New Issue
Block a user