@@ -82,14 +82,15 @@ type Diagnostic struct {
82
82
}
83
83
84
84
type CheckResult struct {
85
- emptiedAccount map [string ]struct {}
86
- unboundedSend bool
87
- declaredVars map [string ]parser.VarDeclaration
88
- unusedVars map [string ]parser.Range
89
- varResolution map [* parser.VariableLiteral ]parser.VarDeclaration
90
- fnCallResolution map [* parser.FnCallIdentifier ]FnCallResolution
91
- Diagnostics []Diagnostic
92
- Program parser.Program
85
+ unboundedAccountInSend parser.Literal
86
+ emptiedAccount map [string ]struct {}
87
+ unboundedSend bool
88
+ declaredVars map [string ]parser.VarDeclaration
89
+ unusedVars map [string ]parser.Range
90
+ varResolution map [* parser.VariableLiteral ]parser.VarDeclaration
91
+ fnCallResolution map [* parser.FnCallIdentifier ]FnCallResolution
92
+ Diagnostics []Diagnostic
93
+ Program parser.Program
93
94
}
94
95
95
96
func (r CheckResult ) GetErrorsCount () int {
@@ -154,6 +155,7 @@ func (res *CheckResult) check() {
154
155
}
155
156
}
156
157
for _ , statement := range res .Program .Statements {
158
+ res .unboundedAccountInSend = nil
157
159
res .checkStatement (statement )
158
160
}
159
161
@@ -382,32 +384,30 @@ func (res *CheckResult) checkSentValue(sentValue parser.SentValue) {
382
384
}
383
385
}
384
386
385
- func (res * CheckResult ) withCloneEmptyAccount () func () {
386
- bkEmptiedAccount := res .emptiedAccount
387
- res .emptiedAccount = make (map [string ]struct {})
388
- for k , v := range bkEmptiedAccount {
389
- res .emptiedAccount [k ] = v
390
- }
391
- return func () {
392
- res .emptiedAccount = bkEmptiedAccount
393
- }
394
- }
395
-
396
387
func (res * CheckResult ) checkSource (source parser.Source ) {
397
388
if source == nil {
398
389
return
399
390
}
400
391
392
+ if res .unboundedAccountInSend != nil {
393
+ res .Diagnostics = append (res .Diagnostics , Diagnostic {
394
+ Range : source .GetRange (),
395
+ Kind : & UnboundedAccountIsNotLast {},
396
+ })
397
+ }
398
+
401
399
switch source := source .(type ) {
402
400
case * parser.AccountLiteral :
403
- if source .Name == "world" && res .unboundedSend {
401
+ if source .IsWorld () && res .unboundedSend {
404
402
res .Diagnostics = append (res .Diagnostics , Diagnostic {
405
403
Range : source .GetRange (),
406
404
Kind : & InvalidUnboundedAccount {},
407
405
})
406
+ } else if source .IsWorld () {
407
+ res .unboundedAccountInSend = source
408
408
}
409
409
410
- if _ , emptied := res .emptiedAccount [source .Name ]; emptied && source .Name != "world" {
410
+ if _ , emptied := res .emptiedAccount [source .Name ]; emptied && ! source .IsWorld () {
411
411
res .Diagnostics = append (res .Diagnostics , Diagnostic {
412
412
Kind : & EmptiedAccount {Name : source .Name },
413
413
Range : source .Range ,
@@ -420,13 +420,17 @@ func (res *CheckResult) checkSource(source parser.Source) {
420
420
res .checkLiteral (source , TypeAccount )
421
421
422
422
case * parser.SourceOverdraft :
423
- if accountLiteral , ok := source .Address .(* parser.AccountLiteral ); ok && accountLiteral .Name == "world" {
423
+ if accountLiteral , ok := source .Address .(* parser.AccountLiteral ); ok && accountLiteral .IsWorld () {
424
424
res .Diagnostics = append (res .Diagnostics , Diagnostic {
425
425
Range : accountLiteral .Range ,
426
426
Kind : & InvalidWorldOverdraft {},
427
427
})
428
428
}
429
429
430
+ if source .Bounded == nil {
431
+ res .unboundedAccountInSend = source .Address
432
+ }
433
+
430
434
if res .unboundedSend {
431
435
res .Diagnostics = append (res .Diagnostics , Diagnostic {
432
436
Range : source .Address .GetRange (),
@@ -445,18 +449,13 @@ func (res *CheckResult) checkSource(source parser.Source) {
445
449
}
446
450
447
451
case * parser.SourceCapped :
448
- bkSendAll := res .unboundedSend
449
- res .unboundedSend = false
450
- defer func () {
451
- res .unboundedSend = bkSendAll
452
- }()
453
-
454
- handler := res .withCloneEmptyAccount ()
455
- defer handler ()
452
+ onExit := res .enterCappedSource ()
456
453
457
454
res .checkLiteral (source .Cap , TypeMonetary )
458
455
res .checkSource (source .From )
459
456
457
+ onExit ()
458
+
460
459
case * parser.SourceAllotment :
461
460
if res .unboundedSend {
462
461
res .Diagnostics = append (res .Diagnostics , Diagnostic {
@@ -489,9 +488,9 @@ func (res *CheckResult) checkSource(source parser.Source) {
489
488
}
490
489
}
491
490
492
- handler := res .withCloneEmptyAccount ()
491
+ onExit := res .enterCappedSource ()
493
492
res .checkSource (allottedItem .From )
494
- handler ()
493
+ onExit ()
495
494
}
496
495
497
496
res .checkHasBadAllotmentSum (* sum , source .Range , remainingAllotment , variableLiterals )
@@ -606,3 +605,44 @@ func (res *CheckResult) checkHasBadAllotmentSum(
606
605
}
607
606
}
608
607
}
608
+
609
+ func (res * CheckResult ) withCloneEmptyAccount () func () {
610
+ initial := res .emptiedAccount
611
+ res .emptiedAccount = make (map [string ]struct {})
612
+ for k , v := range initial {
613
+ res .emptiedAccount [k ] = v
614
+ }
615
+ return func () {
616
+ res .emptiedAccount = initial
617
+ }
618
+ }
619
+
620
+ func (res * CheckResult ) withCloneUnboundedAccountInSend () func () {
621
+ initial := res .unboundedAccountInSend
622
+ res .unboundedAccountInSend = nil
623
+
624
+ return func () {
625
+ res .unboundedAccountInSend = initial
626
+ }
627
+ }
628
+
629
+ func (res * CheckResult ) withCloneUnboundedSend () func () {
630
+ initial := res .unboundedSend
631
+ res .unboundedSend = false
632
+
633
+ return func () {
634
+ res .unboundedSend = initial
635
+ }
636
+ }
637
+
638
+ func (res * CheckResult ) enterCappedSource () func () {
639
+ exitCloneEmptyAccount := res .withCloneEmptyAccount ()
640
+ exitCloneUnboundeAccountInSend := res .withCloneUnboundedAccountInSend ()
641
+ exitCloneUnboundedSend := res .withCloneUnboundedSend ()
642
+
643
+ return func () {
644
+ exitCloneEmptyAccount ()
645
+ exitCloneUnboundeAccountInSend ()
646
+ exitCloneUnboundedSend ()
647
+ }
648
+ }
0 commit comments