import { Import } from "../Languages/Imports/Import" ; import { LineResults } from "../LineResults" ; import { CommandNames } from "../Names/CommandNames" ; import { Command } from "./Command" ; import { CommandResult } from "./CommandResult" ; import { CommandMetadata } from "./Metadata/CommandMetadata" ; import { SingleParameter } from "./Metadata/Parameters/SingleParameter" ; import { addLineEnder } from "./Utilities" ; /**
 * Starts a foreach loop over a container's pairs.
 */ export class ForEachPairStartCommand extends Command { /**
     * Metadata on the command.
     */ private static metadata : CommandMetadata = new CommandMetadata ( CommandNames . ForEachPairStart ) . withDescription ( "Starts a foreach loop over a container's pairs" ) . withIndentation ( [ 1 ] ) . withParameters ( [ new SingleParameter ( "container" , "A container to iterate over." , true ) , new SingleParameter ( "pairName" , "The name of the pair variable" , true ) , new SingleParameter ( "keyName" , "The name of the key variable." , true ) , new SingleParameter ( "keyType" , "The type of the key variable." , true ) , new SingleParameter ( "valueName" , "The name of the value variable." , true ) , new SingleParameter ( "valueType" , "The type of the value variable." , true ) , ] ) ; returns public getMetadata ( ) { return ForEachPairStartCommand . metadata ; } param parameters returns public render ( parameters ) { if ( this . language . syntax . loops . forEachAsMethod ) { return this . renderForEachAsMethod ( parameters ) ; } return this . renderForEachAsLoop ( parameters ) ; } param parameters returns remarks public renderForEachAsLoop ( parameters ) { const imports = [ ] ; let line = this . language . syntax . loops . foreach ; let output ; line += this . language . syntax . conditionals . startLeft ; if ( this . language . syntax . variables . declarationRequired ) { let typeName ; let iteratorName ; if ( this . language . syntax . loops . forEachPairsAsKeys ) { iteratorName = parameters [ 3 ] ; } else { iteratorName = parameters [ 2 ] ; } if ( this . language . syntax . loops . forEachPairsAsPair ) { typeName = this . language . syntax . loops . forEachPairsPairClass ; typeName += "<" + this . addTypeNameType ( parameters [ 4 ] , imports ) ; typeName += ", " + this . addTypeNameType ( parameters [ 6 ] , imports ) + ">" ; } else { typeName = parameters [ 4 ] ; } line += this . language . syntax . variables . declaration ; if ( this . language . syntax . loops . forEachPairsTypedPair ) { const typedLine = this . context . convertParsed ( [ CommandNames . VariableInline , iteratorName , typeName ] ) ; line += typedLine . commandResults [ 0 ] . text ; imports . push ( ... typedLine . addedImports ) ; } else { line += iteratorName ; } } else { line += parameters [ 3 ] ; if ( this . language . syntax . loops . forEachPairsAsPair ) { line += ", " + parameters [ 5 ] ; } } line += this . language . syntax . loops . forEachMiddle ; line += parameters [ 1 ] ; line += this . language . syntax . loops . forEachGetPairs ; line += this . language . syntax . loops . forEachRight ; output = [ new CommandResult ( line , 0 ) ] ; addLineEnder ( output , this . language . syntax . conditionals . startRight , 1 ) ; if ( this . language . syntax . loops . forEachPairsAsPair && this . language . syntax . variables . declarationRequired ) { this . addPairKeyLookup ( parameters , imports , output ) ; this . addPairValueLookup ( parameters , imports , output ) ; } else if ( this . language . syntax . loops . forEachPairsAsKeys ) { this . addKeyedValueLookup ( parameters , imports , output ) ; } return new LineResults ( output ) . withImports ( imports ) ; } private addTypeNameType ( rawType , imports ) { const typeNameLine = this . context . convertParsed ( [ CommandNames . Type , rawType ] ) ; imports . push ( ... typeNameLine . addedImports ) ; return typeNameLine . commandResults [ 0 ] . text ; } param parameters returns remarks public renderForEachAsMethod ( parameters ) { let output = parameters [ 1 ] ; output += this . language . syntax . loops . forEachGetPairs ; output += parameters [ 3 ] ; output += ", " ; output += parameters [ 5 ] ; output += this . language . syntax . loops . forEachRight ; return new LineResults ( [ new CommandResult ( output , 1 ) ] ) ; } param parameters param imports param output remarks private addKeyedValueLookup ( parameters , imports , output ) { const valueNameLine = this . context . convertParsed ( [ CommandNames . Type , parameters [ 5 ] ] ) ; const valueName = valueNameLine . commandResults [ 0 ] . text ; const valueType = parameters [ 6 ] ; const valueLookup = this . context . convertParsed ( [ CommandNames . DictionaryGet , parameters [ 1 ] , parameters [ 3 ] ] ) . commandResults [ 0 ] . text ; let valueVariable = this . context . convertParsed ( [ CommandNames . Variable , valueName , valueType , valueLookup ] ) . commandResults [ 0 ] . text ; valueVariable += this . language . syntax . style . semicolon ; imports . push ( ... valueNameLine . addedImports ) ; output . push ( new CommandResult ( valueVariable , 0 ) ) ; } param parameters param imports param output remarks private addPairKeyLookup ( parameters , imports , output ) { const keyNameLine = this . context . convertParsed ( [ CommandNames . Type , parameters [ 3 ] ] ) ; const keyName = keyNameLine . commandResults [ 0 ] . text ; const keyType = parameters [ 4 ] ; const keyLookup = parameters [ 2 ] + this . language . syntax . loops . forEachPairsRetrieveKey ; let keyVariable = this . context . convertParsed ( [ CommandNames . Variable , keyName , keyType , keyLookup ] ) . commandResults [ 0 ] . text ; keyVariable += this . language . syntax . style . semicolon ; imports . push ( ... keyNameLine . addedImports ) ; output . push ( new CommandResult ( keyVariable , 0 ) ) ; } param parameters param imports param output remarks private addPairValueLookup ( parameters , imports , output ) { const valueNameLine = this . context . convertParsed ( [ CommandNames . Type , parameters [ 5 ] ] ) ; const valueName = valueNameLine . commandResults [ 0 ] . text ; const valueType = parameters [ 6 ] ; const valueLookup = parameters [ 2 ] + this . language . syntax . loops . forEachPairsRetrieveValue ; let valueVariable = this . context . convertParsed ( [ CommandNames . Variable , valueName , valueType , valueLookup ] ) . commandResults [ 0 ] . text ; valueVariable += this . language . syntax . style . semicolon ; imports . push ( ... valueNameLine . addedImports ) ; output . push ( new CommandResult ( valueVariable , 0 ) ) ; } }