import { SelectedScript } from '@/application/Context/State/Selection/SelectedScript' ; import { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition' ; import { IScriptingDefinition } from '@/domain/IScriptingDefinition' ; import { CodePosition } from '../Position/CodePosition' ; import { IUserScriptGenerator } from './IUserScriptGenerator' ; import { IUserScript } from './IUserScript' ; import { ICodeBuilder } from './ICodeBuilder' ; import { ICodeBuilderFactory } from './ICodeBuilderFactory' ; import { CodeBuilderFactory } from './CodeBuilderFactory' ; export class UserScriptGenerator implements IUserScriptGenerator { constructor ( private readonly codeBuilderFactory = new CodeBuilderFactory ( ) ) { } public buildCode ( selectedScripts , scriptingDefinition ) { if ( ! selectedScripts ) { throw new Error ( 'undefined scripts' ) ; } if ( ! scriptingDefinition ) { throw new Error ( 'undefined definition' ) ; } if ( ! selectedScripts . length ) { return { code : '' , scriptPositions : new Map < SelectedScript , ICodePosition > ( ) } ; } let builder = this . codeBuilderFactory . create ( scriptingDefinition . language ) ; builder = initializeCode ( scriptingDefinition . startCode , builder ) ; const scriptPositions = selectedScripts . reduce ( ( result , selection ) => { return appendSelection ( selection , result , builder ) ; } , new Map < SelectedScript , ICodePosition > ( ) ) ; const code = finalizeCode ( builder , scriptingDefinition . endCode ) ; return { code , scriptPositions } ; } } function initializeCode ( startCode , builder ) { if ( ! startCode ) { return builder ; } return builder . appendLine ( startCode ) . appendLine ( ) ; } function finalizeCode ( builder , endCode ) { if ( ! endCode ) { return builder . toString ( ) ; } return builder . appendLine ( ) . appendLine ( endCode ) . toString ( ) ; } function appendSelection ( selection , scriptPositions , builder ) { const startPosition = builder . currentLine + 1 ; appendCode ( selection , builder ) ; const endPosition = builder . currentLine - 1 ; builder . appendLine ( ) ; const position = new CodePosition ( startPosition , endPosition ) ; scriptPositions . set ( selection , position ) ; return scriptPositions ; } function appendCode ( selection , builder ) { const { script } = selection ; const name = selection . revert ? `${ script . name } (revert)` : script . name ; const scriptCode = selection . revert ? script . code . revert : script . code . execute ; return builder . appendLine ( ) . appendFunction ( name , scriptCode ) ; }