@@ -22,6 +22,7 @@ package bind
22
22
23
23
import (
24
24
"bytes"
25
+ "errors"
25
26
"fmt"
26
27
"go/format"
27
28
"regexp"
@@ -38,6 +39,10 @@ type Lang int
38
39
39
40
const (
40
41
LangGo Lang = iota
42
+ // ADDED by Jakub Pajek BEG (revert mobile nuke)
43
+ LangJava
44
+ LangObjC
45
+ // ADDED by Jakub Pajek END (revert mobile nuke)
41
46
)
42
47
43
48
func isKeyWord (arg string ) bool {
@@ -218,6 +223,13 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
218
223
if evmABI .HasReceive () {
219
224
receive = & tmplMethod {Original : evmABI .Receive }
220
225
}
226
+ // ADDED by Jakub Pajek BEG (revert mobile nuke)
227
+ // There is no easy way to pass arbitrary java objects to the Go side.
228
+ if len (structs ) > 0 && lang == LangJava {
229
+ return "" , errors .New ("java binding for tuple arguments is not supported yet" )
230
+ }
231
+ // ADDED by Jakub Pajek END (revert mobile nuke)
232
+
221
233
contracts [types [i ]] = & tmplContract {
222
234
Type : capitalise (types [i ]),
223
235
InputABI : strings .ReplaceAll (strippedABI , "\" " , "\\ \" " ),
@@ -291,6 +303,8 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
291
303
// programming language types.
292
304
var bindType = map [Lang ]func (kind abi.Type , structs map [string ]* tmplStruct ) string {
293
305
LangGo : bindTypeGo ,
306
+ // ADDED by Jakub Pajek (revert mobile nuke)
307
+ LangJava : bindTypeJava ,
294
308
}
295
309
296
310
// bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go ones.
@@ -333,10 +347,90 @@ func bindTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
333
347
}
334
348
}
335
349
350
+ // ADDED by Jakub Pajek (revert mobile nuke)
351
+ // bindBasicTypeJava converts basic solidity types(except array, slice and tuple) to Java ones.
352
+ func bindBasicTypeJava (kind abi.Type ) string {
353
+ switch kind .T {
354
+ case abi .AddressTy :
355
+ return "Address"
356
+ case abi .IntTy , abi .UintTy :
357
+ // Note that uint and int (without digits) are also matched,
358
+ // these are size 256, and will translate to BigInt (the default).
359
+ parts := regexp .MustCompile (`(u)?int([0-9]*)` ).FindStringSubmatch (kind .String ())
360
+ if len (parts ) != 3 {
361
+ return kind .String ()
362
+ }
363
+ // All unsigned integers should be translated to BigInt since gomobile doesn't
364
+ // support them.
365
+ if parts [1 ] == "u" {
366
+ return "BigInt"
367
+ }
368
+
369
+ namedSize := map [string ]string {
370
+ "8" : "byte" ,
371
+ "16" : "short" ,
372
+ "32" : "int" ,
373
+ "64" : "long" ,
374
+ }[parts [2 ]]
375
+
376
+ // default to BigInt
377
+ if namedSize == "" {
378
+ namedSize = "BigInt"
379
+ }
380
+ return namedSize
381
+ case abi .FixedBytesTy , abi .BytesTy :
382
+ return "byte[]"
383
+ case abi .BoolTy :
384
+ return "boolean"
385
+ case abi .StringTy :
386
+ return "String"
387
+ case abi .FunctionTy :
388
+ return "byte[24]"
389
+ default :
390
+ return kind .String ()
391
+ }
392
+ }
393
+
394
+ // ADDED by Jakub Pajek (revert mobile nuke)
395
+ // pluralizeJavaType explicitly converts multidimensional types to predefined
396
+ // types in go side.
397
+ func pluralizeJavaType (typ string ) string {
398
+ switch typ {
399
+ case "boolean" :
400
+ return "Bools"
401
+ case "String" :
402
+ return "Strings"
403
+ case "Address" :
404
+ return "Addresses"
405
+ case "byte[]" :
406
+ return "Binaries"
407
+ case "BigInt" :
408
+ return "BigInts"
409
+ }
410
+ return typ + "[]"
411
+ }
412
+
413
+ // ADDED by Jakub Pajek (revert mobile nuke)
414
+ // bindTypeJava converts a Solidity type to a Java one. Since there is no clear mapping
415
+ // from all Solidity types to Java ones (e.g. uint17), those that cannot be exactly
416
+ // mapped will use an upscaled type (e.g. BigDecimal).
417
+ func bindTypeJava (kind abi.Type , structs map [string ]* tmplStruct ) string {
418
+ switch kind .T {
419
+ case abi .TupleTy :
420
+ return structs [kind .TupleRawName + kind .String ()].Name
421
+ case abi .ArrayTy , abi .SliceTy :
422
+ return pluralizeJavaType (bindTypeJava (* kind .Elem , structs ))
423
+ default :
424
+ return bindBasicTypeJava (kind )
425
+ }
426
+ }
427
+
336
428
// bindTopicType is a set of type binders that convert Solidity types to some
337
429
// supported programming language topic types.
338
430
var bindTopicType = map [Lang ]func (kind abi.Type , structs map [string ]* tmplStruct ) string {
339
431
LangGo : bindTopicTypeGo ,
432
+ // ADDED by Jakub Pajek (revert mobile nuke)
433
+ LangJava : bindTopicTypeJava ,
340
434
}
341
435
342
436
// bindTopicTypeGo converts a Solidity topic type to a Go one. It is almost the same
@@ -356,10 +450,30 @@ func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
356
450
return bound
357
451
}
358
452
453
+ // ADDED by Jakub Pajek (revert mobile nuke)
454
+ // bindTopicTypeJava converts a Solidity topic type to a Java one. It is almost the same
455
+ // functionality as for simple types, but dynamic types get converted to hashes.
456
+ func bindTopicTypeJava (kind abi.Type , structs map [string ]* tmplStruct ) string {
457
+ bound := bindTypeJava (kind , structs )
458
+
459
+ // todo(rjl493456442) according solidity documentation, indexed event
460
+ // parameters that are not value types i.e. arrays and structs are not
461
+ // stored directly but instead a keccak256-hash of an encoding is stored.
462
+ //
463
+ // We only convert strings and bytes to hash, still need to deal with
464
+ // array(both fixed-size and dynamic-size) and struct.
465
+ if bound == "String" || bound == "byte[]" {
466
+ bound = "Hash"
467
+ }
468
+ return bound
469
+ }
470
+
359
471
// bindStructType is a set of type binders that convert Solidity tuple types to some supported
360
472
// programming language struct definition.
361
473
var bindStructType = map [Lang ]func (kind abi.Type , structs map [string ]* tmplStruct ) string {
362
474
LangGo : bindStructTypeGo ,
475
+ // ADDED by Jakub Pajek (revert mobile nuke)
476
+ LangJava : bindStructTypeJava ,
363
477
}
364
478
365
479
// bindStructTypeGo converts a Solidity tuple type to a Go one and records the mapping
@@ -408,10 +522,77 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
408
522
}
409
523
}
410
524
525
+ // ADDED by Jakub Pajek (revert mobile nuke)
526
+ // bindStructTypeJava converts a Solidity tuple type to a Java one and records the mapping
527
+ // in the given map.
528
+ // Notably, this function will resolve and record nested struct recursively.
529
+ func bindStructTypeJava (kind abi.Type , structs map [string ]* tmplStruct ) string {
530
+ switch kind .T {
531
+ case abi .TupleTy :
532
+ // We compose a raw struct name and a canonical parameter expression
533
+ // together here. The reason is before solidity v0.5.11, kind.TupleRawName
534
+ // is empty, so we use canonical parameter expression to distinguish
535
+ // different struct definition. From the consideration of backward
536
+ // compatibility, we concat these two together so that if kind.TupleRawName
537
+ // is not empty, it can have unique id.
538
+ id := kind .TupleRawName + kind .String ()
539
+ if s , exist := structs [id ]; exist {
540
+ return s .Name
541
+ }
542
+ var fields []* tmplField
543
+ for i , elem := range kind .TupleElems {
544
+ field := bindStructTypeJava (* elem , structs )
545
+ fields = append (fields , & tmplField {Type : field , Name : decapitalise (kind .TupleRawNames [i ]), SolKind : * elem })
546
+ }
547
+ name := kind .TupleRawName
548
+ if name == "" {
549
+ name = fmt .Sprintf ("Class%d" , len (structs ))
550
+ }
551
+ structs [id ] = & tmplStruct {
552
+ Name : name ,
553
+ Fields : fields ,
554
+ }
555
+ return name
556
+ case abi .ArrayTy , abi .SliceTy :
557
+ return pluralizeJavaType (bindStructTypeJava (* kind .Elem , structs ))
558
+ default :
559
+ return bindBasicTypeJava (kind )
560
+ }
561
+ }
562
+
411
563
// namedType is a set of functions that transform language specific types to
412
564
// named versions that may be used inside method names.
413
565
var namedType = map [Lang ]func (string , abi.Type ) string {
414
566
LangGo : func (string , abi.Type ) string { panic ("this shouldn't be needed" ) },
567
+ // ADDED by Jakub Pajek (revert mobile nuke)
568
+ LangJava : namedTypeJava ,
569
+ }
570
+
571
+ // ADDED by Jakub Pajek (revert mobile nuke)
572
+ // namedTypeJava converts some primitive data types to named variants that can
573
+ // be used as parts of method names.
574
+ func namedTypeJava (javaKind string , solKind abi.Type ) string {
575
+ switch javaKind {
576
+ case "byte[]" :
577
+ return "Binary"
578
+ case "boolean" :
579
+ return "Bool"
580
+ default :
581
+ parts := regexp .MustCompile (`(u)?int([0-9]*)(\[[0-9]*\])?` ).FindStringSubmatch (solKind .String ())
582
+ if len (parts ) != 4 {
583
+ return javaKind
584
+ }
585
+ switch parts [2 ] {
586
+ case "8" , "16" , "32" , "64" :
587
+ if parts [3 ] == "" {
588
+ return capitalise (fmt .Sprintf ("%sint%s" , parts [1 ], parts [2 ]))
589
+ }
590
+ return capitalise (fmt .Sprintf ("%sint%ss" , parts [1 ], parts [2 ]))
591
+
592
+ default :
593
+ return javaKind
594
+ }
595
+ }
415
596
}
416
597
417
598
// alias returns an alias of the given string based on the aliasing rules
@@ -427,6 +608,8 @@ func alias(aliases map[string]string, n string) string {
427
608
// conform to target language naming conventions.
428
609
var methodNormalizer = map [Lang ]func (string ) string {
429
610
LangGo : abi .ToCamelCase ,
611
+ // ADDED by Jakub Pajek (revert mobile nuke)
612
+ LangJava : decapitalise ,
430
613
}
431
614
432
615
// capitalise makes a camel-case string which starts with an upper case character.
0 commit comments