import { eat , finishToken , lookaheadTypeAndKeyword , match } from "../tokenizer" ; import { ContextualKeyword } from "../tokenizer/keywords" ; import { ErrorWithPos } from "../tokenizer/state" ; import { formatTokenType , TokenType , TokenType as tt } from "../tokenizer/types" ; import { charCodes } from "../util/charcodes" ; import { input , state } from "./base" ; export function isContextual ( contextualKeyword ) { return state . contextualKeyword === contextualKeyword ; } export function isLookaheadContextual ( contextualKeyword ) { const l = lookaheadTypeAndKeyword ( ) ; return l . type === tt . name && l . contextualKeyword === contextualKeyword ; } export function eatContextual ( contextualKeyword ) { return state . contextualKeyword === contextualKeyword && eat ( tt . name ) ; } export function expectContextual ( contextualKeyword ) { if ( ! eatContextual ( contextualKeyword ) ) { unexpected ( ) ; } } export function canInsertSemicolon ( ) { return match ( tt . eof ) || match ( tt . braceR ) || hasPrecedingLineBreak ( ) ; } export function hasPrecedingLineBreak ( ) { const prevToken = state . tokens [ state . tokens . length - 1 ] ; const lastTokEnd = prevToken ? prevToken . end : 0 ; for ( let i = lastTokEnd ; i < state . start ; i ++ ) { const code = input . charCodeAt ( i ) ; if ( code === charCodes . lineFeed || code === charCodes . carriageReturn || code === 0x2028 || code === 0x2029 ) { return true ; } } return false ; } export function isLineTerminator ( ) { return eat ( tt . semi ) || canInsertSemicolon ( ) ; } export function semicolon ( ) { if ( ! isLineTerminator ( ) ) { unexpected ( 'Unexpected token, expected ";"' ) ; } } export function expect ( type ) { const matched = eat ( type ) ; if ( ! matched ) { unexpected ( `Unexpected token, expected "${ formatTokenType ( type ) }"` ) ; } } /**
 * Transition the parser to an error state. All code needs to be written to naturally unwind in this
 * state, which allows us to backtrack without exceptions and without error plumbing everywhere.
 */ export function unexpected ( message = "Unexpected token" , pos = state . start ) { if ( state . error ) { return ; } const err = new ErrorWithPos ( message ) ; err . pos = pos ; state . error = err ; state . pos = input . length ; finishToken ( tt . eof ) ; }