1+ // @flow
2+
13import XHTMLEntities from "./xhtml" ;
4+ import type Parser from "../../parser" ;
25import { TokenType , types as tt } from "../../tokenizer/types" ;
36import { TokContext , types as tc } from "../../tokenizer/context" ;
7+ import * as N from "../../types" ;
48import { isIdentifierChar , isIdentifierStart } from "../../util/identifier" ;
9+ import type { Pos , Position } from "../../util/location" ;
510import { isNewLine } from "../../util/whitespace" ;
611
712const HEX_NUMBER = / ^ [ \d a - f A - F ] + $ / ;
@@ -34,7 +39,7 @@ tt.jsxTagEnd.updateContext = function(prevType) {
3439
3540// Transforms JSX element name to string.
3641
37- function getQualifiedJSXName ( object ) {
42+ function getQualifiedJSXName ( object : N . JSXIdentifier | N . JSXNamespacedName | N . JSXMemberExpression ) : string {
3843 if ( object . type === "JSXIdentifier" ) {
3944 return object . name ;
4045 }
@@ -46,12 +51,15 @@ function getQualifiedJSXName(object) {
4651 if ( object . type === "JSXMemberExpression" ) {
4752 return getQualifiedJSXName ( object . object ) + "." + getQualifiedJSXName ( object . property ) ;
4853 }
54+
55+ // istanbul ignore next
56+ throw new Error ( "Node had unexpected type: " + object . type ) ;
4957}
5058
51- export default ( superClass ) => class extends superClass {
59+ export default ( superClass : Class < Parser > ) : Class < Parser > => class extends superClass {
5260 // Reads inline JSX contents token.
5361
54- jsxReadToken ( ) {
62+ jsxReadToken ( ) : void {
5563 let out = "" ;
5664 let chunkStart = this . state . pos ;
5765 for ( ; ; ) {
@@ -92,7 +100,7 @@ export default (superClass) => class extends superClass {
92100 }
93101 }
94102
95- jsxReadNewLine ( normalizeCRLF ) {
103+ jsxReadNewLine ( normalizeCRLF : boolean ) : string {
96104 const ch = this . input . charCodeAt ( this . state . pos ) ;
97105 let out ;
98106 ++ this . state . pos ;
@@ -108,7 +116,7 @@ export default (superClass) => class extends superClass {
108116 return out ;
109117 }
110118
111- jsxReadString ( quote ) {
119+ jsxReadString ( quote : number ) : void {
112120 let out = "" ;
113121 let chunkStart = ++ this . state . pos ;
114122 for ( ; ; ) {
@@ -134,7 +142,7 @@ export default (superClass) => class extends superClass {
134142 return this . finishToken ( tt . string , out ) ;
135143 }
136144
137- jsxReadEntity ( ) {
145+ jsxReadEntity ( ) : string {
138146 let str = "" ;
139147 let count = 0 ;
140148 let entity ;
@@ -176,7 +184,7 @@ export default (superClass) => class extends superClass {
176184 // Also assumes that first character was already checked
177185 // by isIdentifierStart in readToken.
178186
179- jsxReadWord ( ) {
187+ jsxReadWord ( ) : void {
180188 let ch ;
181189 const start = this . state . pos ;
182190 do {
@@ -187,7 +195,7 @@ export default (superClass) => class extends superClass {
187195
188196 // Parse next token as JSX identifier
189197
190- jsxParseIdentifier ( ) {
198+ jsxParseIdentifier ( ) : N . JSXIdentifier {
191199 const node = this . startNode ( ) ;
192200 if ( this . match ( tt . jsxName ) ) {
193201 node . name = this . state . value ;
@@ -202,7 +210,7 @@ export default (superClass) => class extends superClass {
202210
203211 // Parse namespaced identifier.
204212
205- jsxParseNamespacedName ( ) {
213+ jsxParseNamespacedName ( ) : N . JSXNamespacedName {
206214 const startPos = this . state . start ;
207215 const startLoc = this . state . startLoc ;
208216 const name = this . jsxParseIdentifier ( ) ;
@@ -217,7 +225,7 @@ export default (superClass) => class extends superClass {
217225 // Parses element name in any form - namespaced, member
218226 // or single identifier.
219227
220- jsxParseElementName ( ) {
228+ jsxParseElementName ( ) : N . JSXNamespacedName | N . JSXMemberExpression {
221229 const startPos = this . state . start ;
222230 const startLoc = this . state . startLoc ;
223231 let node = this . jsxParseNamespacedName ( ) ;
@@ -232,13 +240,13 @@ export default (superClass) => class extends superClass {
232240
233241 // Parses any type of JSX attribute value.
234242
235- jsxParseAttributeValue ( ) {
243+ jsxParseAttributeValue ( ) : N . Expression {
236244 let node ;
237245 switch ( this . state . type ) {
238246 case tt . braceL :
239247 node = this . jsxParseExpressionContainer ( ) ;
240248 if ( node . expression . type === "JSXEmptyExpression" ) {
241- this . raise ( node . start , "JSX attributes must only be assigned a non-empty expression" ) ;
249+ throw this . raise ( node . start , "JSX attributes must only be assigned a non-empty expression" ) ;
242250 } else {
243251 return node ;
244252 }
@@ -248,22 +256,22 @@ export default (superClass) => class extends superClass {
248256 return this . parseExprAtom ( ) ;
249257
250258 default :
251- this . raise ( this . state . start , "JSX value should be either an expression or a quoted JSX text" ) ;
259+ throw this . raise ( this . state . start , "JSX value should be either an expression or a quoted JSX text" ) ;
252260 }
253261 }
254262
255263 // JSXEmptyExpression is unique type since it doesn't actually parse anything,
256264 // and so it should start at the end of last read token (left brace) and finish
257265 // at the beginning of the next one (right brace).
258266
259- jsxParseEmptyExpression ( ) {
267+ jsxParseEmptyExpression ( ) : N . JSXEmptyExpression {
260268 const node = this . startNodeAt ( this . state . lastTokEnd , this . state . lastTokEndLoc ) ;
261269 return this . finishNodeAt ( node , "JSXEmptyExpression" , this . state . start , this . state . startLoc ) ;
262270 }
263271
264272 // Parse JSX spread child
265273
266- jsxParseSpreadChild ( ) {
274+ jsxParseSpreadChild ( ) : N . JSXSpreadChild {
267275 const node = this . startNode ( ) ;
268276 this . expect ( tt . braceL ) ;
269277 this . expect ( tt . ellipsis ) ;
@@ -276,7 +284,7 @@ export default (superClass) => class extends superClass {
276284 // Parses JSX expression enclosed into curly brackets.
277285
278286
279- jsxParseExpressionContainer ( ) {
287+ jsxParseExpressionContainer ( ) : N . JSXExpressionContainer {
280288 const node = this . startNode ( ) ;
281289 this . next ( ) ;
282290 if ( this . match ( tt . braceR ) ) {
@@ -290,7 +298,7 @@ export default (superClass) => class extends superClass {
290298
291299 // Parses following JSX attribute name-value pair.
292300
293- jsxParseAttribute ( ) {
301+ jsxParseAttribute ( ) : N . JSXAttribute {
294302 const node = this . startNode ( ) ;
295303 if ( this . eat ( tt . braceL ) ) {
296304 this . expect ( tt . ellipsis ) ;
@@ -305,7 +313,7 @@ export default (superClass) => class extends superClass {
305313
306314 // Parses JSX opening tag starting after "<".
307315
308- jsxParseOpeningElementAt ( startPos , startLoc ) {
316+ jsxParseOpeningElementAt ( startPos : number , startLoc : Position ) : N . JSXOpeningElement {
309317 const node = this . startNodeAt ( startPos , startLoc ) ;
310318 node . attributes = [ ] ;
311319 node . name = this . jsxParseElementName ( ) ;
@@ -319,7 +327,7 @@ export default (superClass) => class extends superClass {
319327
320328 // Parses JSX closing tag starting after "</".
321329
322- jsxParseClosingElementAt ( startPos , startLoc ) {
330+ jsxParseClosingElementAt ( startPos : number , startLoc : Position ) : N . JSXClosingElement {
323331 const node = this . startNodeAt ( startPos , startLoc ) ;
324332 node . name = this . jsxParseElementName ( ) ;
325333 this . expect ( tt . jsxTagEnd ) ;
@@ -329,7 +337,7 @@ export default (superClass) => class extends superClass {
329337 // Parses entire JSX element, including it"s opening tag
330338 // (starting after "<"), attributes, contents and closing tag.
331339
332- jsxParseElementAt ( startPos , startLoc ) {
340+ jsxParseElementAt ( startPos : number , startLoc : Position ) : N . JSXElement {
333341 const node = this . startNodeAt ( startPos , startLoc ) ;
334342 const children = [ ] ;
335343 const openingElement = this . jsxParseOpeningElementAt ( startPos , startLoc ) ;
@@ -363,12 +371,14 @@ export default (superClass) => class extends superClass {
363371
364372 // istanbul ignore next - should never happen
365373 default :
366- this . unexpected ( ) ;
374+ throw this . unexpected ( ) ;
367375 }
368376 }
369377
378+ // $FlowIgnore
370379 if ( getQualifiedJSXName ( closingElement . name ) !== getQualifiedJSXName ( openingElement . name ) ) {
371380 this . raise (
381+ // $FlowIgnore
372382 closingElement . start ,
373383 "Expected corresponding JSX closing tag for <" + getQualifiedJSXName ( openingElement . name ) + ">"
374384 ) ;
@@ -386,7 +396,7 @@ export default (superClass) => class extends superClass {
386396
387397 // Parses entire JSX element from current position.
388398
389- jsxParseElement ( ) {
399+ jsxParseElement ( ) : N . JSXElement {
390400 const startPos = this . state . start ;
391401 const startLoc = this . state . startLoc ;
392402 this . next ( ) ;
@@ -397,7 +407,7 @@ export default (superClass) => class extends superClass {
397407 // Overrides
398408 // ==================================
399409
400- parseExprAtom ( refShortHandDefaultPos ) {
410+ parseExprAtom ( refShortHandDefaultPos : ? Pos ) : N . Expression {
401411 if ( this . match ( tt . jsxText ) ) {
402412 return this . parseLiteral ( this . state . value , "JSXText" ) ;
403413 } else if ( this . match ( tt . jsxTagStart ) ) {
@@ -407,7 +417,7 @@ export default (superClass) => class extends superClass {
407417 }
408418 }
409419
410- readToken ( code ) {
420+ readToken ( code : number ) : void {
411421 if ( this . state . inPropertyName ) return super . readToken ( code ) ;
412422
413423 const context = this . curContext ( ) ;
@@ -439,7 +449,7 @@ export default (superClass) => class extends superClass {
439449 return super . readToken ( code ) ;
440450 }
441451
442- updateContext ( prevType ) {
452+ updateContext ( prevType : TokenType ) : void {
443453 if ( this . match ( tt . braceL ) ) {
444454 const curContext = this . curContext ( ) ;
445455 if ( curContext === tc . j_oTag ) {
0 commit comments