github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/abi/bad_parser.go (about)

     1  package abi
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types"
     7  )
     8  
     9  // This code sucks
    10  
    11  func ExtractSigs(code string) []types.Function {
    12  	code = prepareCode(code)
    13  
    14  	ret := []types.Function{}
    15  	for _, line := range strings.Split(code, "\n") {
    16  		if !strings.Contains(line, "function") && !strings.Contains(line, "event") {
    17  			continue
    18  		}
    19  
    20  		funcType := "function"
    21  		if strings.Contains(line, "event") {
    22  			funcType = "event"
    23  		}
    24  		line = strings.ReplaceAll(strings.ReplaceAll(line, "event", ""), "function", "")
    25  
    26  		if p1, p2, ok := splitLine(line); ok {
    27  			parts := strings.Split(p2, ",")
    28  			x := []string{}
    29  			for _, p := range parts {
    30  				pp := strings.Split(p, " ")
    31  				x = append(x, pp[0])
    32  			}
    33  			ps := []string{p1}
    34  			f := types.Function{
    35  				FunctionType: funcType,
    36  				Name:         ps[0],
    37  				Signature:    ps[0] + "(" + strings.Join(x, ",") + ")",
    38  			}
    39  			ret = append(ret, f)
    40  		}
    41  	}
    42  	return ret
    43  }
    44  
    45  var keywords = []string{
    46  	"indexed",
    47  	"memory",
    48  }
    49  
    50  func splitLine(line string) (string, string, bool) {
    51  	openIndex := strings.Index(line, "(")
    52  	if openIndex == -1 {
    53  		return "", "", false
    54  	}
    55  
    56  	nestingLevel := 1
    57  	start := openIndex + 1
    58  	for i := openIndex + 1; i < len(line); i++ {
    59  		switch line[i] {
    60  		case '(':
    61  			nestingLevel++
    62  		case ')':
    63  			nestingLevel--
    64  			if nestingLevel == 0 {
    65  				p1 := line[:openIndex]
    66  				p1 = strings.ReplaceAll(p1, "function ", "")
    67  				p1 = strings.ReplaceAll(p1, "event ", "")
    68  				p1 = strings.TrimSpace(p1)
    69  
    70  				p2 := strings.TrimSpace(line[start : i+1])
    71  				p2 = strings.ReplaceAll(p2, "\t", " ")
    72  				for _, k := range keywords {
    73  					p2 = strings.ReplaceAll(p2, k, " ")
    74  				}
    75  				for {
    76  					if !strings.Contains(p2, "  ") {
    77  						break
    78  					}
    79  					p2 = strings.ReplaceAll(p2, "  ", " ")
    80  				}
    81  				p2 = strings.ReplaceAll(p2, ", ", ",")
    82  				p2 = strings.TrimSuffix(p2, ")")
    83  
    84  				return p1, p2, true
    85  			}
    86  		}
    87  	}
    88  
    89  	return "", "", false
    90  }
    91  
    92  func prepareCode(code string) string {
    93  	if !strings.Contains(code, "function") && !strings.Contains(code, "event") {
    94  		if code[0:1] == strings.ToUpper(code[0:1]) {
    95  			code = "event " + code
    96  		} else {
    97  			code = "function " + code
    98  		}
    99  	}
   100  	code = strings.ReplaceAll(code, "|", "")
   101  	code = strings.ReplaceAll(code, "\n", "")
   102  	code = strings.ReplaceAll(code, "event", "}event")
   103  	code = strings.ReplaceAll(code, "function", "}function")
   104  	code = strings.ReplaceAll(code, "}", "\n")
   105  	return code
   106  }