@@ -18,6 +18,7 @@ import {
18
18
isSdsEnumVariant ,
19
19
isSdsExpressionLambda ,
20
20
isSdsExpressionStatement ,
21
+ isSdsFunction ,
21
22
isSdsIndexedAccess ,
22
23
isSdsInfixOperation ,
23
24
isSdsList ,
@@ -59,12 +60,12 @@ import { NodeFileSystem } from 'langium/node';
59
60
import {
60
61
getAbstractResults ,
61
62
getAssignees ,
62
- streamBlockLambdaResults ,
63
63
getImportedDeclarations ,
64
64
getImports ,
65
- isRequiredParameter ,
66
65
getModuleMembers ,
67
66
getStatements ,
67
+ isRequiredParameter ,
68
+ streamBlockLambdaResults ,
68
69
} from '../language/helpers/nodeProperties.js' ;
69
70
import { IdManager } from '../language/helpers/idManager.js' ;
70
71
import { isInStubFile } from '../language/helpers/fileExtensions.js' ;
@@ -209,7 +210,7 @@ const generateParameter = function (
209
210
frame : GenerationInfoFrame ,
210
211
defaultValue : boolean = true ,
211
212
) : string {
212
- return expandToString `${ getPythonNameOrDefault ( frame . getServices ( ) , parameter ) } ${
213
+ return expandToString `${ getPythonNameOrDefault ( frame . services , parameter ) } ${
213
214
defaultValue && parameter . defaultValue !== undefined
214
215
? '=' + generateExpression ( parameter . defaultValue , frame )
215
216
: ''
@@ -291,7 +292,7 @@ const generateStatement = function (statement: SdsStatement, frame: GenerationIn
291
292
292
293
const generateAssignment = function ( assignment : SdsAssignment , frame : GenerationInfoFrame ) : string {
293
294
const requiredAssignees = isSdsCall ( assignment . expression )
294
- ? getAbstractResults ( frame . getServices ( ) . helpers . NodeMapper . callToCallable ( assignment . expression ) ) . length
295
+ ? getAbstractResults ( frame . services . helpers . NodeMapper . callToCallable ( assignment . expression ) ) . length
295
296
: /* c8 ignore next */
296
297
1 ;
297
298
const assignees = getAssignees ( assignment ) ;
@@ -347,7 +348,7 @@ const generateExpression = function (expression: SdsExpression, frame: Generatio
347
348
}
348
349
}
349
350
350
- const partiallyEvaluatedNode = frame . getServices ( ) . evaluation . PartialEvaluator . evaluate ( expression ) ;
351
+ const partiallyEvaluatedNode = frame . services . evaluation . PartialEvaluator . evaluate ( expression ) ;
351
352
if ( partiallyEvaluatedNode instanceof BooleanConstant ) {
352
353
return partiallyEvaluatedNode . value ? 'True' : 'False' ;
353
354
} else if ( partiallyEvaluatedNode instanceof IntConstant ) {
@@ -360,39 +361,44 @@ const generateExpression = function (expression: SdsExpression, frame: Generatio
360
361
} else if ( partiallyEvaluatedNode instanceof StringConstant ) {
361
362
return `'${ formatStringSingleLine ( partiallyEvaluatedNode . value ) } '` ;
362
363
}
363
- // Handled after constant expressions: EnumVariant, List, Map
364
364
365
- if ( isSdsTemplateString ( expression ) ) {
365
+ // Handled after constant expressions: EnumVariant, List, Map
366
+ else if ( isSdsTemplateString ( expression ) ) {
366
367
return `f'${ expression . expressions . map ( ( expr ) => generateExpression ( expr , frame ) ) . join ( '' ) } '` ;
367
- }
368
-
369
- if ( isSdsMap ( expression ) ) {
368
+ } else if ( isSdsMap ( expression ) ) {
370
369
const mapContent = expression . entries . map (
371
370
( entry ) => `${ generateExpression ( entry . key , frame ) } : ${ generateExpression ( entry . value , frame ) } ` ,
372
371
) ;
373
372
return `{${ mapContent . join ( ', ' ) } }` ;
374
- }
375
- if ( isSdsList ( expression ) ) {
373
+ } else if ( isSdsList ( expression ) ) {
376
374
const listContent = expression . elements . map ( ( value ) => generateExpression ( value , frame ) ) ;
377
375
return `[${ listContent . join ( ', ' ) } ]` ;
378
- }
379
-
380
- if ( isSdsBlockLambda ( expression ) ) {
376
+ } else if ( isSdsBlockLambda ( expression ) ) {
381
377
return frame . getUniqueLambdaBlockName ( expression ) ;
382
- }
383
- if ( isSdsCall ( expression ) ) {
384
- const sortedArgs = sortArguments ( frame . getServices ( ) , expression . argumentList . arguments ) ;
378
+ } else if ( isSdsCall ( expression ) ) {
379
+ const callable = frame . services . helpers . NodeMapper . callToCallable ( expression ) ;
380
+ if ( isSdsFunction ( callable ) ) {
381
+ const pythonCall = frame . services . builtins . Annotations . getPythonCall ( callable ) ;
382
+ if ( pythonCall ) {
383
+ let thisParam : string | undefined = undefined ;
384
+ if ( isSdsMemberAccess ( expression . receiver ) ) {
385
+ thisParam = generateExpression ( expression . receiver . receiver , frame ) ;
386
+ }
387
+ const argumentsMap = getArgumentsMap ( expression . argumentList . arguments , frame ) ;
388
+ return generatePythonCall ( pythonCall , argumentsMap , thisParam ) ;
389
+ }
390
+ }
391
+
392
+ const sortedArgs = sortArguments ( frame . services , expression . argumentList . arguments ) ;
385
393
return expandToString `${ generateExpression ( expression . receiver , frame ) } (${ sortedArgs
386
394
. map ( ( arg ) => generateArgument ( arg , frame ) )
387
395
. join ( ', ' ) } )`;
388
- }
389
- if ( isSdsExpressionLambda ( expression ) ) {
396
+ } else if ( isSdsExpressionLambda ( expression ) ) {
390
397
return `lambda ${ generateParameters ( expression . parameterList , frame ) } : ${ generateExpression (
391
398
expression . result ,
392
399
frame ,
393
400
) } `;
394
- }
395
- if ( isSdsInfixOperation ( expression ) ) {
401
+ } else if ( isSdsInfixOperation ( expression ) ) {
396
402
const leftOperand = generateExpression ( expression . leftOperand , frame ) ;
397
403
const rightOperand = generateExpression ( expression . rightOperand , frame ) ;
398
404
switch ( expression . operator ) {
@@ -412,14 +418,12 @@ const generateExpression = function (expression: SdsExpression, frame: Generatio
412
418
default :
413
419
return `(${ leftOperand } ) ${ expression . operator } (${ rightOperand } )` ;
414
420
}
415
- }
416
- if ( isSdsIndexedAccess ( expression ) ) {
421
+ } else if ( isSdsIndexedAccess ( expression ) ) {
417
422
return expandToString `${ generateExpression ( expression . receiver , frame ) } [${ generateExpression (
418
423
expression . index ,
419
424
frame ,
420
425
) } ]`;
421
- }
422
- if ( isSdsMemberAccess ( expression ) ) {
426
+ } else if ( isSdsMemberAccess ( expression ) ) {
423
427
const member = expression . member ?. target . ref ! ;
424
428
const receiver = generateExpression ( expression . receiver , frame ) ;
425
429
if ( isSdsEnumVariant ( member ) ) {
@@ -442,31 +446,49 @@ const generateExpression = function (expression: SdsExpression, frame: Generatio
442
446
return `${ receiver } .${ memberExpression } ` ;
443
447
}
444
448
}
445
- }
446
- if ( isSdsParenthesizedExpression ( expression ) ) {
449
+ } else if ( isSdsParenthesizedExpression ( expression ) ) {
447
450
return expandToString `${ generateExpression ( expression . expression , frame ) } ` ;
448
- }
449
- if ( isSdsPrefixOperation ( expression ) ) {
451
+ } else if ( isSdsPrefixOperation ( expression ) ) {
450
452
const operand = generateExpression ( expression . operand , frame ) ;
451
453
switch ( expression . operator ) {
452
454
case 'not' :
453
455
return expandToString `not (${ operand } )` ;
454
456
case '-' :
455
457
return expandToString `-(${ operand } )` ;
456
458
}
457
- }
458
- if ( isSdsReference ( expression ) ) {
459
+ } else if ( isSdsReference ( expression ) ) {
459
460
const declaration = expression . target . ref ! ;
460
461
const referenceImport =
461
- getExternalReferenceNeededImport ( frame . getServices ( ) , expression , declaration ) ||
462
- getInternalReferenceNeededImport ( frame . getServices ( ) , expression , declaration ) ;
462
+ getExternalReferenceNeededImport ( frame . services , expression , declaration ) ||
463
+ getInternalReferenceNeededImport ( frame . services , expression , declaration ) ;
463
464
frame . addImport ( referenceImport ) ;
464
- return referenceImport ?. alias || getPythonNameOrDefault ( frame . getServices ( ) , declaration ) ;
465
+ return referenceImport ?. alias || getPythonNameOrDefault ( frame . services , declaration ) ;
465
466
}
466
467
/* c8 ignore next 2 */
467
468
throw new Error ( `Unknown expression type: ${ expression . $type } ` ) ;
468
469
} ;
469
470
471
+ const generatePythonCall = function (
472
+ pythonCall : string ,
473
+ argumentsMap : Map < string , string > ,
474
+ thisParam : string | undefined = undefined ,
475
+ ) : string {
476
+ if ( thisParam ) {
477
+ argumentsMap . set ( 'this' , thisParam ) ;
478
+ }
479
+
480
+ return pythonCall . replace ( / \$ [ _ a - z A - Z ] [ _ a - z A - Z 0 - 9 ] * / gu, ( value ) => argumentsMap . get ( value . substring ( 1 ) ) ! ) ;
481
+ } ;
482
+
483
+ const getArgumentsMap = function ( argumentList : SdsArgument [ ] , frame : GenerationInfoFrame ) : Map < string , string > {
484
+ const argumentsMap = new Map < string , string > ( ) ;
485
+ argumentList . reduce ( ( map , value ) => {
486
+ map . set ( frame . services . helpers . NodeMapper . argumentToParameter ( value ) ?. name ! , generateArgument ( value , frame ) ) ;
487
+ return map ;
488
+ } , argumentsMap ) ;
489
+ return argumentsMap ;
490
+ } ;
491
+
470
492
const sortArguments = function ( services : SafeDsServices , argumentList : SdsArgument [ ] ) : SdsArgument [ ] {
471
493
// $containerIndex contains the index of the parameter in the receivers parameter list
472
494
const parameters = argumentList . map ( ( argument ) => {
@@ -482,7 +504,7 @@ const sortArguments = function (services: SafeDsServices, argumentList: SdsArgum
482
504
} ;
483
505
484
506
const generateArgument = function ( argument : SdsArgument , frame : GenerationInfoFrame ) {
485
- const parameter = frame . getServices ( ) . helpers . NodeMapper . argumentToParameter ( argument ) ;
507
+ const parameter = frame . services . helpers . NodeMapper . argumentToParameter ( argument ) ;
486
508
return expandToString `${
487
509
parameter !== undefined && ! isRequiredParameter ( parameter )
488
510
? generateParameter ( parameter , frame , false ) + '='
@@ -567,9 +589,9 @@ interface ImportData {
567
589
}
568
590
569
591
class GenerationInfoFrame {
570
- services : SafeDsServices ;
571
- blockLambdaManager : IdManager < SdsBlockLambda > ;
572
- importSet : Map < String , ImportData > ;
592
+ readonly services : SafeDsServices ;
593
+ private readonly blockLambdaManager : IdManager < SdsBlockLambda > ;
594
+ private readonly importSet : Map < String , ImportData > ;
573
595
574
596
constructor ( services : SafeDsServices , importSet : Map < String , ImportData > = new Map < String , ImportData > ( ) ) {
575
597
this . services = services ;
@@ -589,10 +611,6 @@ class GenerationInfoFrame {
589
611
getUniqueLambdaBlockName ( lambda : SdsBlockLambda ) : string {
590
612
return `${ BLOCK_LAMBDA_PREFIX } ${ this . blockLambdaManager . assignId ( lambda ) } ` ;
591
613
}
592
-
593
- getServices ( ) : SafeDsServices {
594
- return this . services ;
595
- }
596
614
}
597
615
598
616
export interface GenerateOptions {
0 commit comments