@@ -79,9 +79,13 @@ function createSimpleToken(
79
79
/**
80
80
* Parse the given attribute name as a directive key.
81
81
* @param node The identifier node to parse.
82
+ * @param document The document to add parsing errors.
82
83
* @returns The directive key node.
83
84
*/
84
- function parseDirectiveKeyStatically ( node : VIdentifier ) : VDirectiveKey {
85
+ function parseDirectiveKeyStatically (
86
+ node : VIdentifier ,
87
+ document : VDocumentFragment | null ,
88
+ ) : VDirectiveKey {
85
89
const {
86
90
name : text ,
87
91
rawName : rawText ,
@@ -136,23 +140,53 @@ function parseDirectiveKeyStatically(node: VIdentifier): VDirectiveKey {
136
140
. slice ( i )
137
141
. split ( "." )
138
142
. map ( modifierName => {
139
- //TODO: generate syntax error if modifierName.length === 0.
140
143
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
+ }
141
156
i += modifierName . length + 1
142
157
return modifier
143
158
} )
144
159
145
160
if ( directiveKey . name == null ) {
146
161
directiveKey . name = nameOrArgument
147
- } else {
162
+ } else if ( nameOrArgument . name !== "" ) {
148
163
directiveKey . argument = nameOrArgument
149
164
}
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
+ }
151
181
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
+ ) {
153
187
const pos = ( directiveKey . argument || directiveKey . name ) . range [ 1 ]
154
188
const propModifier = createIdentifier ( pos , pos , "prop" )
155
- modifiers . unshift ( propModifier )
189
+ directiveKey . modifiers . unshift ( propModifier )
156
190
}
157
191
158
192
return directiveKey
@@ -166,6 +200,14 @@ function isPropModifier(node: VIdentifier): boolean {
166
200
return node . name === "prop"
167
201
}
168
202
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
+
169
211
/**
170
212
* Parse the tokens of a given key node.
171
213
* @param node The key node to parse.
@@ -335,7 +377,7 @@ function createDirectiveKey(
335
377
locationCalculator : LocationCalculator ,
336
378
) : VDirectiveKey {
337
379
// Parse node and tokens.
338
- const directiveKey = parseDirectiveKeyStatically ( node )
380
+ const directiveKey = parseDirectiveKeyStatically ( node , document )
339
381
const tokens = parseDirectiveKeyTokens ( directiveKey )
340
382
replaceTokens ( document , directiveKey , tokens )
341
383
0 commit comments