/**
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import diff from '../diff-sequences' ; import { DIFF_DELETE , DIFF_EQUAL , DIFF_INSERT , Diff } from './cleanupSemantic' ; import { joinAlignedDiffsExpand , joinAlignedDiffsNoExpand , } from './joinAlignedDiffs' ; import { normalizeDiffOptions } from './normalizeDiffOptions' ; import type { DiffOptions , DiffOptionsNormalized } from './types' ; const isEmptyString = ( lines ) => lines . length === 1 && lines [ 0 ] . length === 0 ; type ChangeCounts = { a : number ; b : number ; } ; const countChanges = ( diffs ) : ChangeCounts => { let a = 0 ; let b = 0 ; diffs . forEach ( ( diff ) => { switch ( diff [ 0 ] ) { case DIFF_DELETE : a += 1 ; break ; case DIFF_INSERT : b += 1 ; break ; } } ) ; return { a , b } ; } ; const printAnnotation = ( { aAnnotation , aColor , aIndicator , bAnnotation , bColor , bIndicator , includeChangeCounts , omitAnnotationLines , } , changeCounts ) : string => { if ( omitAnnotationLines ) { return '' ; } let aRest = '' ; let bRest = '' ; if ( includeChangeCounts ) { const aCount = String ( changeCounts . a ) ; const bCount = String ( changeCounts . b ) ; const baAnnotationLengthDiff = bAnnotation . length - aAnnotation . length ; const aAnnotationPadding = ' ' . repeat ( Math . max ( 0 , baAnnotationLengthDiff ) ) ; const bAnnotationPadding = ' ' . repeat ( Math . max ( 0 , - baAnnotationLengthDiff ) ) ; const baCountLengthDiff = bCount . length - aCount . length ; const aCountPadding = ' ' . repeat ( Math . max ( 0 , baCountLengthDiff ) ) ; const bCountPadding = ' ' . repeat ( Math . max ( 0 , - baCountLengthDiff ) ) ; aRest = aAnnotationPadding + '  ' + aIndicator + ' ' + aCountPadding + aCount ; bRest = bAnnotationPadding + '  ' + bIndicator + ' ' + bCountPadding + bCount ; } return ( aColor ( aIndicator + ' ' + aAnnotation + aRest ) + '\n' + bColor ( bIndicator + ' ' + bAnnotation + bRest ) + '\n\n' ) ; } ; export const printDiffLines = ( diffs , options ) : string => printAnnotation ( options , countChanges ( diffs ) ) + ( options . expand ? joinAlignedDiffsExpand ( diffs , options ) : joinAlignedDiffsNoExpand ( diffs , options ) ) ; export const diffLinesUnified = ( aLines , bLines , options ? ) : string => printDiffLines ( diffLinesRaw ( isEmptyString ( aLines ) ? [ ] : aLines , isEmptyString ( bLines ) ? [ ] : bLines ) , normalizeDiffOptions ( options ) ) ; export const diffLinesUnified2 = ( aLinesDisplay , bLinesDisplay , aLinesCompare , bLinesCompare , options ? ) : string => { if ( isEmptyString ( aLinesDisplay ) && isEmptyString ( aLinesCompare ) ) { aLinesDisplay = [ ] ; aLinesCompare = [ ] ; } if ( isEmptyString ( bLinesDisplay ) && isEmptyString ( bLinesCompare ) ) { bLinesDisplay = [ ] ; bLinesCompare = [ ] ; } if ( aLinesDisplay . length !== aLinesCompare . length || bLinesDisplay . length !== bLinesCompare . length ) { return diffLinesUnified ( aLinesDisplay , bLinesDisplay , options ) ; } const diffs = diffLinesRaw ( aLinesCompare , bLinesCompare ) ; let aIndex = 0 ; let bIndex = 0 ; diffs . forEach ( ( diff ) => { switch ( diff [ 0 ] ) { case DIFF_DELETE : diff [ 1 ] = aLinesDisplay [ aIndex ] ; aIndex += 1 ; break ; case DIFF_INSERT : diff [ 1 ] = bLinesDisplay [ bIndex ] ; bIndex += 1 ; break ; default : diff [ 1 ] = bLinesDisplay [ bIndex ] ; aIndex += 1 ; bIndex += 1 ; } } ) ; return printDiffLines ( diffs , normalizeDiffOptions ( options ) ) ; } ; export const diffLinesRaw = ( aLines , bLines ) : Array < Diff > => { const aLength = aLines . length ; const bLength = bLines . length ; const isCommon = ( aIndex , bIndex ) => aLines [ aIndex ] === bLines [ bIndex ] ; const diffs = [ ] ; let aIndex = 0 ; let bIndex = 0 ; const foundSubsequence = ( nCommon , aCommon , bCommon ) => { for ( ; aIndex !== aCommon ; aIndex += 1 ) { diffs . push ( new Diff ( DIFF_DELETE , aLines [ aIndex ] ) ) ; } for ( ; bIndex !== bCommon ; bIndex += 1 ) { diffs . push ( new Diff ( DIFF_INSERT , bLines [ bIndex ] ) ) ; } for ( ; nCommon !== 0 ; nCommon -= 1 , aIndex += 1 , bIndex += 1 ) { diffs . push ( new Diff ( DIFF_EQUAL , bLines [ bIndex ] ) ) ; } } ; diff ( aLength , bLength , isCommon , foundSubsequence ) ; for ( ; aIndex !== aLength ; aIndex += 1 ) { diffs . push ( new Diff ( DIFF_DELETE , aLines [ aIndex ] ) ) ; } for ( ; bIndex !== bLength ; bIndex += 1 ) { diffs . push ( new Diff ( DIFF_INSERT , bLines [ bIndex ] ) ) ; } return diffs ; } ;