Skip to content

Commit b57cd06

Browse files
committed
✨ add more parsing errors about directive keys
1 parent bc89f92 commit b57cd06

File tree

17 files changed

+1971
-236
lines changed

17 files changed

+1971
-236
lines changed

src/template/index.ts

+49-7
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,13 @@ function createSimpleToken(
7979
/**
8080
* Parse the given attribute name as a directive key.
8181
* @param node The identifier node to parse.
82+
* @param document The document to add parsing errors.
8283
* @returns The directive key node.
8384
*/
84-
function parseDirectiveKeyStatically(node: VIdentifier): VDirectiveKey {
85+
function parseDirectiveKeyStatically(
86+
node: VIdentifier,
87+
document: VDocumentFragment | null,
88+
): VDirectiveKey {
8589
const {
8690
name: text,
8791
rawName: rawText,
@@ -136,23 +140,53 @@ function parseDirectiveKeyStatically(node: VIdentifier): VDirectiveKey {
136140
.slice(i)
137141
.split(".")
138142
.map(modifierName => {
139-
//TODO: generate syntax error if modifierName.length === 0.
140143
const modifier = createIdentifier(i, i + modifierName.length)
144+
if (modifierName === "") {
145+
insertError(
146+
document,
147+
new ParseError(
148+
`Unexpected token '${text[i]}'`,
149+
undefined,
150+
offset + i,
151+
line,
152+
column + i,
153+
),
154+
)
155+
}
141156
i += modifierName.length + 1
142157
return modifier
143158
})
144159

145160
if (directiveKey.name == null) {
146161
directiveKey.name = nameOrArgument
147-
} else {
162+
} else if (nameOrArgument.name !== "") {
148163
directiveKey.argument = nameOrArgument
149164
}
150-
directiveKey.modifiers = modifiers
165+
directiveKey.modifiers = modifiers.filter(isNotEmptyModifier)
166+
167+
if (directiveKey.name.name === "v-") {
168+
insertError(
169+
document,
170+
new ParseError(
171+
`Unexpected token '${
172+
text[directiveKey.name.range[1] - offset]
173+
}'`,
174+
undefined,
175+
directiveKey.name.range[1],
176+
directiveKey.name.loc.end.line,
177+
directiveKey.name.loc.end.column,
178+
),
179+
)
180+
}
151181

152-
if (directiveKey.name.rawName === "." && !modifiers.some(isPropModifier)) {
182+
// v-bind.prop shorthand
183+
if (
184+
directiveKey.name.rawName === "." &&
185+
!directiveKey.modifiers.some(isPropModifier)
186+
) {
153187
const pos = (directiveKey.argument || directiveKey.name).range[1]
154188
const propModifier = createIdentifier(pos, pos, "prop")
155-
modifiers.unshift(propModifier)
189+
directiveKey.modifiers.unshift(propModifier)
156190
}
157191

158192
return directiveKey
@@ -166,6 +200,14 @@ function isPropModifier(node: VIdentifier): boolean {
166200
return node.name === "prop"
167201
}
168202

203+
/**
204+
* Check whether a given identifier node is empty or not.
205+
* @param node The identifier node to check.
206+
*/
207+
function isNotEmptyModifier(node: VIdentifier): boolean {
208+
return node.name !== ""
209+
}
210+
169211
/**
170212
* Parse the tokens of a given key node.
171213
* @param node The key node to parse.
@@ -335,7 +377,7 @@ function createDirectiveKey(
335377
locationCalculator: LocationCalculator,
336378
): VDirectiveKey {
337379
// Parse node and tokens.
338-
const directiveKey = parseDirectiveKeyStatically(node)
380+
const directiveKey = parseDirectiveKeyStatically(node, document)
339381
const tokens = parseDirectiveKeyTokens(directiveKey)
340382
replaceTokens(document, directiveKey, tokens)
341383

0 commit comments

Comments
 (0)