import { DEFAULT_EXPORT } from "../../BlockSyntax" ; import { BlockReference } from "../ast" ; /**
 * Map of `aliasName` to `blockName`. Used to store data from `@block`
 * import / export statements.
 */ export interface BlockNames { [ aliasName ] : string ; } /**
 * Defines parser state for a single run of the parser function.
 * TODO: Illustrate FSM.
 */ interface ParserState { useDefault : boolean ; buildingAlias : boolean ; inParens : boolean ; block : string ; token : string ; alias : string ; } param state return function commit ( state ) { if ( ! state . token ) { return state . token ; } if ( state . buildingAlias ) { return state . alias = state . token ; } return state . alias = state . block = state . token ; } param state function reset ( state ) { if ( ! state . useDefault || state . inParens ) { state . buildingAlias = false ; state . token = state . alias = state . block = "" ; } else { state . buildingAlias = true ; state . token = state . alias = "" ; state . block = DEFAULT_EXPORT ; } } param str param useDefault return export function parseBlockNames ( str , useDefault ) { const mapping = { } ; const state = { useDefault , buildingAlias : useDefault , inParens : ! useDefault , block : useDefault ? DEFAULT_EXPORT : "" , token : "" , alias : "" , } ; for ( let next of str ) { switch ( state . token ) { case "as" : state . buildingAlias = true ; state . token = "" ; break ; default : break ; } switch ( next ) { case "," : commit ( state ) ; mapping [ state . alias ] = state . block ; reset ( state ) ; break ; case "(" : state . buildingAlias = false ; state . inParens = true ; break ; case ")" : state . inParens = false ; break ; case " " : commit ( state ) ; state . token = "" ; break ; default : state . token = `${ state . token }${ next }` ; break ; } } commit ( state ) ; mapping [ state . alias ] = state . block ; return mapping ; } export function parseBlockNamesAST ( blockList , useDefault ) { let defaultName ; let blockNames = parseBlockNames ( blockList , useDefault ) ; let names ; for ( let asName of Object . keys ( blockNames ) ) { let name = blockNames [ asName ] ; if ( name === DEFAULT_EXPORT ) { defaultName = asName ; } else { names = names || [ ] ; if ( name === asName ) { names . push ( { name } ) ; } else { names . push ( { name , asName } ) ; } } } return { defaultName , names , } ; }