@@ -352,8 +352,28 @@ private String objectArray(List<String> names) {
352
352
}
353
353
354
354
static TypeName externalAnnName = TypeName .get (TExternal .class );
355
+ static TypeName optionalAnnName = TypeName .get (TOptional .class );
355
356
static TypeName eventAnnName = TypeName .get (EventLog .class );
356
357
358
+ private static boolean hasOptional (ParameterSpec p ) {
359
+ return p .annotations .stream ().anyMatch (
360
+ a -> a .type .equals (optionalAnnName )
361
+ );
362
+ }
363
+
364
+ private List <List <ParameterSpec >> explodeOptionalParameters (List <ParameterSpec > params ) {
365
+ List <List <ParameterSpec >> specs = new ArrayList <>();
366
+ List <ParameterSpec > spec = new ArrayList <>();
367
+ for (var p : params ) {
368
+ if (hasOptional (p )) {
369
+ specs .add (List .copyOf (spec ));
370
+ }
371
+ spec .add (ParameterSpec .builder (p .type , p .name , p .modifiers .toArray (Modifier []::new )).build ());
372
+ }
373
+ specs .add (List .copyOf (spec ));
374
+ return specs ;
375
+ }
376
+
357
377
private TypeSpec clientTypeSpec (ClassName tScoreClassName , List <MethodSpec > methods ) {
358
378
ClassName className = tScoreClassName .nestedClass ("Client" );
359
379
String FILED_SCORE = "score" ;
@@ -382,7 +402,7 @@ private TypeSpec clientTypeSpec(ClassName tScoreClassName, List<MethodSpec> meth
382
402
.map (m -> m .parameters )
383
403
.orElse (new ArrayList <>());
384
404
MethodSpec .Builder deployMethodBuilder = MethodSpec .methodBuilder ("deploy" )
385
- .addModifiers (Modifier .STATIC )
405
+ .addModifiers (Modifier .STATIC , Modifier . PUBLIC )
386
406
.addException (Exception .class )
387
407
.addParameter (ServiceManager .class , "sm" )
388
408
.addParameter (Account .class , "caller" )
@@ -410,33 +430,37 @@ private TypeSpec clientTypeSpec(ClassName tScoreClassName, List<MethodSpec> meth
410
430
for (MethodSpec method : methods ) {
411
431
AnnotationSpec ann = method .annotations .stream ().filter (a -> a .type .equals (externalAnnName )).findAny ().orElse (null );
412
432
if (ann != null ) {
413
- MethodSpec .Builder externalMethodBuilder = MethodSpec .methodBuilder (method .name )
414
- .addModifiers (method .modifiers )
415
- .returns (method .returnType );
416
433
boolean readonly = ann .members .get ("readonly" ).get (0 ).toString ().equals ("true" );
417
434
boolean payable = ann .members .get ("payable" ).get (0 ).toString ().equals ("true" );
418
- List < String > paramNames = method . parameters . stream (). map ( p -> p . name ). collect ( Collectors . toList ());
419
- String params = paramJoin ( paramNames );
420
- if ( paramNames . size () > 0 ) {
421
- params = ", " + params ;
422
- }
423
- if ( readonly ) {
424
- externalMethodBuilder . addStatement ( "return this.$L.call($T.class, \" $L \" $L)" ,
425
- FILED_SCORE , method . returnType , method . name , params );
426
- } else {
427
- if ( payable ) {
428
- String PARAM_VALUE = resolveName ( paramNames , "valueForPayable" );
429
- externalMethodBuilder . addParameter ( ParameterSpec . builder ( BigInteger . class , PARAM_VALUE ). build ());
430
- externalMethodBuilder .addStatement ("this.$L.invoke(this.$L, $L , \" $L\" $L)" ,
431
- FILED_SCORE , FILED_FROM , PARAM_VALUE , method .name , params );
435
+
436
+ List < List < ParameterSpec >> parameterSets =
437
+ explodeOptionalParameters ( method . parameters );
438
+ for ( var parameters : parameterSets ) {
439
+ MethodSpec . Builder externalMethodBuilder = MethodSpec . methodBuilder ( method . name )
440
+ . addModifiers ( method . modifiers );
441
+ List < String > paramNames = parameters . stream (). map ( p -> p . name ). collect ( Collectors . toList ());
442
+ String params = paramJoin ( paramNames );
443
+ if ( paramNames . size () > 0 ) {
444
+ params = ", " + params ;
445
+ }
446
+ if ( readonly ) {
447
+ externalMethodBuilder .addStatement ("return this.$L.call($T.class , \" $L\" $L)" ,
448
+ FILED_SCORE , method . returnType , method .name , params ). returns ( method . returnType );
432
449
} else {
433
- externalMethodBuilder .addStatement ("this.$L.invoke(this.$L, \" $L\" $L)" ,
434
- FILED_SCORE , FILED_FROM , method .name , params );
450
+ if (payable ) {
451
+ String PARAM_VALUE = resolveName (paramNames , "valueForPayable" );
452
+ externalMethodBuilder .addParameter (ParameterSpec .builder (BigInteger .class , PARAM_VALUE ).build ());
453
+ externalMethodBuilder .addStatement ("this.$L.invoke(this.$L, $L, \" $L\" $L)" ,
454
+ FILED_SCORE , FILED_FROM , PARAM_VALUE , method .name , params );
455
+ } else {
456
+ externalMethodBuilder .addStatement ("this.$L.invoke(this.$L, \" $L\" $L)" ,
457
+ FILED_SCORE , FILED_FROM , method .name , params );
458
+ }
435
459
}
460
+ builder .addMethod (externalMethodBuilder
461
+ .addParameters (parameters )
462
+ .build ());
436
463
}
437
- builder .addMethod (externalMethodBuilder
438
- .addParameters (method .parameters )
439
- .build ());
440
464
} else {
441
465
boolean isEvent = method .annotations .stream ().anyMatch (a -> a .type .equals (eventAnnName ));
442
466
if (isEvent ) {
0 commit comments