7 files changed,
88 insertions(+),
1 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-06-27 17:53:43 +0300
Authored at:
2026-06-27 17:09:21 +0300
Change ID:
yqkzquysxlutzszooxzwprkmxrtsqqsz
Parent:
5491069
M
journal/semantic/build.go
··· 12 12 Files: files, 13 13 Accounts: make(map[string]*AccountInfo), 14 14 Commodities: make(map[string]*CommodityInfo), 15 + Payees: make(map[string]*PayeeInfo), 15 16 } 16 17 for i, pf := range files { 17 18 for _, entry := range pf.Ast.Entries { ··· 20 21 c.addAccountDirective(e) 21 22 case *ast.CommodityDirective: 22 23 c.addCommodityDirective(e) 24 + case *ast.PayeeDirective: 25 + c.addPayeeDirective(e) 23 26 case *ast.Transaction: 24 27 c.addPostings(i, e.Postings) 28 + c.addPayee(i, e.Payee) 25 29 case *ast.PeriodicTransaction: 26 30 c.addPostings(i, e.Postings) 27 31 case *ast.AutomatedTransaction: ··· 40 44 c.Accounts[aname] = info 41 45 } 42 46 info.Directives = append(info.Directives, ad) 47 +} 48 + 49 +func (c *Context) addPayeeDirective(pd *ast.PayeeDirective) { 50 + info, ok := c.Payees[pd.Name] 51 + if !ok { 52 + info = &PayeeInfo{} 53 + c.Payees[pd.Name] = info 54 + } 55 + info.Directives = append(info.Directives, &ast.Payee{ 56 + Name: pd.Name, 57 + Span: pd.Span, 58 + }) 43 59 } 44 60 45 61 func (c *Context) addCommodityDirective(cd *ast.CommodityDirective) { ··· 49 65 c.Commodities[cd.Commodity] = info 50 66 } 51 67 info.Directives = append(info.Directives, cd) 68 +} 69 + 70 +func (c *Context) addPayee(fileIndex int, payee *ast.Payee) { 71 + if payee == nil { 72 + return 73 + } 74 + info, ok := c.Payees[payee.Name] 75 + if !ok { 76 + info = &PayeeInfo{} 77 + c.Payees[payee.Name] = info 78 + } 79 + info.Usage = append(info.Usage, PayeeUsage{ 80 + FileIndex: fileIndex, 81 + Payee: payee, 82 + }) 52 83 } 53 84 54 85 func (c *Context) addPostings(fileIndex int, postings []*ast.Posting) {
M
journal/semantic/context.go
··· 12 12 13 13 Accounts map[string]*AccountInfo 14 14 Commodities map[string]*CommodityInfo 15 + Payees map[string]*PayeeInfo 15 16 } 16 17 17 18 type AccountInfo struct { ··· 39 40 FileIndex int 40 41 Amount *ast.Amount 41 42 } 43 + 44 +type PayeeInfo struct { 45 + Directives []*ast.Payee 46 + Usage []PayeeUsage 47 +} 48 + 49 +type PayeeUsage struct { 50 + FileIndex int 51 + Payee *ast.Payee 52 +}
M
journal/semantic/dump.go
··· 55 55 fmt.Fprintf(w, " file %d: %s\n", u.FileIndex, u.Posting.Account.String()) 56 56 } 57 57 } 58 + 59 + // Payees 60 + pnames := make([]string, 0, len(ctx.Payees)) 61 + for name := range ctx.Payees { 62 + pnames = append(pnames, name) 63 + } 64 + sort.Strings(pnames) 65 + 66 + fmt.Fprintf(w, "\npayees (%d):\n", len(ctx.Payees)) 67 + for _, name := range pnames { 68 + info := ctx.Payees[name] 69 + fmt.Fprintf(w, " %s\n", name) 70 + fmt.Fprintf(w, " directives: %d\n", len(info.Directives)) 71 + for _, d := range info.Directives { 72 + fmt.Fprintf(w, " payee %s\n", d.Name) 73 + } 74 + fmt.Fprintf(w, " usages: %d\n", len(info.Usage)) 75 + for _, u := range info.Usage { 76 + fmt.Fprintf(w, " file %d: %s\n", u.FileIndex, u.Payee.Name) 77 + } 78 + } 58 79 }
M
journal/semantic/testdata/journal.golden
··· 49 49 account expenses:transport 50 50 usages: 1 51 51 file 0: expenses:transport 52 + 53 +payees (3): 54 + aws 55 + directives: 0 56 + usages: 1 57 + file 0: aws 58 + groceries 59 + directives: 0 60 + usages: 1 61 + file 0: groceries 62 + lunch 63 + directives: 0 64 + usages: 1 65 + file 0: lunch