/**
 *  Copyright (c) 2020 DeltaXML Ltd. and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the MIT license
 *  which accompanies this distribution.
 *
 *  Contributors:
 *  DeltaXML Ltd. - XPath/XSLT Lexer/Syntax Highlighter
 */ import { CharLevelState , TokenLevelState , Token , XPathLexer } from "./xpLexer" ; export class Debug { public static printResultTokens ( tokens ) { tokens . forEach ( Debug . showTokens ) ; } public static printSerializedTokens ( testTitle , testXpath , tokens ) { let preamble = `
        
        test('${ testTitle }', () => {
        let l: XPathLexer = new XPathLexer();
        let r: Token[] = l.analyse('${ testXpath }');
        let ts: Token[] = ` ; let postamble = `
        expect (r).toEqual(ts);
    });` ; let r = tokens . reduce ( this . serializeTokens , '' ) ; let result = '[' + r + ']' ; console . log ( preamble + result + postamble ) ; } public static printTokenValues ( xpathExpr , resultTokens ) { let lines = xpathExpr . split ( /\r\n|\r|\n/ ) ; console . log ( '-----------------' ) ; console . log ( 'line count: ' + lines . length ) ; console . log ( 'token count: ' + resultTokens . length ) ; for ( let i = 0 ; i < resultTokens . length ; i ++ ) { let t = resultTokens [ i ] ; if ( t . tokenType . valueOf ( ) !== TokenLevelState . Whitespace . valueOf ( ) ) { let line = lines [ t . line ] ; let sc = t . startCharacter ? t . startCharacter : 0 ; console . log ( i + '. ' + line . substr ( sc , t . length ) + '_' ) ; } } } private static serializeTokens = function ( accumulator , token ) : any { if ( ! token ) { return accumulator ; } let err = ( token . error ) ? ', error' : '\"\"' ; let value = token . value ; let tokenType = 'TokenLevelState.' + Debug . tokenStateToString ( token . tokenType ) ; let charType = 'CharLevelState.' + Debug . charStateToString ( token . charType ) ; let childrenString = '' ; if ( token . children ) { childrenString = ',\nchildren:' ; childrenString += '[' + token . children . reduce ( Debug . serializeTokens , '' ) + ']' ; } let objectString = `
{value: "${ value }",
charType: ${ charType },
tokenType: ${ tokenType + childrenString }
},` ; return accumulator + objectString ; } ; public static printMinSerializedTokens ( testTitle , testXpath , tokens ) { let preamble = `
        
        test(\`${ testTitle }\`, () => {
        let l: XPathLexer = new XPathLexer();
        let rx: Token[] = l.analyse(\`${ testXpath }\`, ExitCondition.None, pos);
        let r: Token[] = Utilities.minimiseTokens2(rx);
        let ts: Token[] = ` ; let postamble = `
        expect (r).toEqual(ts);
    });` ; let r = tokens . reduce ( this . minSerializeTokens , '' ) ; let result = '[' + r + ']' ; console . log ( preamble + result + postamble ) ; } private static minSerializeTokens = function ( accumulator , token ) : any { if ( ! token || XPathLexer . isCharTypeEqual ( token , CharLevelState . lWs ) ) { return accumulator ; } else { let err = ( token . hasOwnProperty ( 'error' ) ) ? "\nerror: true," : '' ; let value = token . value ; let tokenType = 'TokenLevelState.' + Debug . tokenStateToString ( token . tokenType ) ; let childrenString = '' ; if ( token . children ) { childrenString = ',\nchildren:' ; childrenString += '[' + token . children . reduce ( Debug . minSerializeTokens , '' ) + ']' ; } let objectString = `
    {value: \`${ value }\`,${ err }
    tokenType: ${ tokenType + childrenString },
    line: ${ token . line },
    length: ${ token . length },
    startCharacter: ${ token . startCharacter }
    },` ; return accumulator + objectString ; } } ; private static showTokens = function ( token ) { let err = ( token . error ) ? ' error' : '' ; let tokenValue = token . value + '' ; let charState = Debug . charStateToString ( token . charType ) ; console . log ( Debug . padString ( tokenValue ) + Debug . padString ( charState ) + Debug . tokenStateToString ( token . tokenType ) + err ) ; if ( token . children ) { console . log ( '--- children-start---' ) ; token . children . forEach ( Debug . showTokens ) ; console . log ( '--- children-end ----' ) ; } } ; public static printDebugOutput ( cachedRealToken , newValue , lineNumber , startCharacter ) { if ( newValue . value !== '' ) { let showWhitespace = true ; let cachedRealTokenString = cachedRealToken ? this . getTokenDebugString ( cachedRealToken ) : '' ; let newT = this . getTokenDebugString ( newValue ) ; let posString = lineNumber + ':' + startCharacter ; let posPadding = this . padColumns ( newT . length ) ; let cachedTpadding = this . padColumns ( cachedRealTokenString . length ) ; if ( newValue . charType === CharLevelState . lWs && ! ( showWhitespace ) ) { } else { console . log ( cachedRealTokenString + cachedTpadding + newT + posPadding + posString ) ; } } } public static printStateOuput ( prevRealToken , currentLabelState , nextLabelState , token ) { console . log ( '============STATE CHANGE ===========================' ) ; let prevType ; let prevToken = '' ; if ( prevRealToken === null ) { prevType = 'NULL' ; } else { prevType = Debug . charStateToString ( prevRealToken . charType ) ; prevToken = prevRealToken . value ; } console . log ( 'prevReal: ' + prevType + '[' + prevToken + ']' ) ; console . log ( "from: " + Debug . charStateToString ( currentLabelState ) ) ; console . log ( "to:   " + Debug . charStateToString ( nextLabelState ) ) + "[" + token + "]" ; } public static getTokenDebugString ( lrt ) { let prevType ; let prevToken = '' ; if ( lrt === null ) { prevType = 'NULL' ; } else { prevType = this . charStateToString ( lrt . charType ) ; prevToken = lrt . value ; } let prevTypeLength = ( prevType ) ? prevType . length : 0 ; let oldT = prevType + this . padParts ( prevTypeLength ) + prevToken + '_' ; return oldT ; } private static padString ( text ) { return text + this . padParts ( text . length ) ; } private static padStringDots ( padLength ) { let padding = '' ; for ( let i = 0 ; i < 16 - padLength ; i ++ ) { padding += '.' ; } return padding ; } private static padColumns ( padLength ) { let padding = '' ; for ( let i = 0 ; i < 50 - padLength ; i ++ ) { padding += ' ' ; } return padding ; } private static padParts ( padLength ) { let padding = '' ; for ( let i = 0 ; i < 16 - padLength ; i ++ ) { padding += ' ' ; } return padding ; } public static debugHeading ( ) { let cachedT = 'Cached Real Token' ; let newT = 'New Token' ; let oldT = 'New Real Token' ; let paddingCached = this . padColumns ( cachedT . length ) ; let padding = this . padColumns ( newT . length ) ; console . log ( '===============================================================================================================' ) ; console . log ( cachedT + paddingCached + newT ) ; console . log ( '===============================================================================================================' ) ; } public static tokenStateToString ( resolvedState ) { return TokenLevelState [ resolvedState ] ; } public static charStateToString ( stringCommentState ) { return stringCommentState ? CharLevelState [ stringCommentState ] : '' ; } }