| 21 | type FuncParser struct{} |
| 22 | |
| 23 | func (fp *FuncParser) parse(filename string) ([]phpFunction, error) { |
| 24 | src, err := os.ReadFile(filename) |
| 25 | if err != nil { |
| 26 | return nil, err |
| 27 | } |
| 28 | |
| 29 | fset := token.NewFileSet() |
| 30 | file, err := parser.ParseFile(fset, filename, src, parser.ParseComments) |
| 31 | if err != nil { |
| 32 | return nil, fmt.Errorf("parsing file: %w", err) |
| 33 | } |
| 34 | |
| 35 | validator := Validator{} |
| 36 | var functions []phpFunction |
| 37 | consumed := make(map[int]bool) |
| 38 | |
| 39 | for _, decl := range file.Decls { |
| 40 | funcDecl, ok := decl.(*ast.FuncDecl) |
| 41 | if !ok || funcDecl.Recv != nil { |
| 42 | continue |
| 43 | } |
| 44 | |
| 45 | directive, directiveLine := findDirective(funcDecl.Doc, fset, phpFuncRegex) |
| 46 | if directive == "" { |
| 47 | continue |
| 48 | } |
| 49 | consumed[directiveLine] = true |
| 50 | |
| 51 | phpFunc, err := fp.parseSignature(directive) |
| 52 | if err != nil { |
| 53 | warnf("Warning: Error parsing signature '%s': %v\n", directive, err) |
| 54 | continue |
| 55 | } |
| 56 | |
| 57 | if err := validator.validateFunction(*phpFunc); err != nil { |
| 58 | warnf("Warning: Invalid function '%s': %v\n", phpFunc.Name, err) |
| 59 | continue |
| 60 | } |
| 61 | |
| 62 | if err := validator.validateTypes(*phpFunc); err != nil { |
| 63 | warnf("Warning: Function '%s' uses unsupported types: %v\n", phpFunc.Name, err) |
| 64 | continue |
| 65 | } |
| 66 | |
| 67 | phpFunc.lineNumber = directiveLine |
| 68 | phpFunc.GoFunction = extractNodeSource(src, fset, funcDecl) |
| 69 | |
| 70 | if err := validator.validateGoFunctionSignatureWithOptions(*phpFunc, false); err != nil { |
| 71 | warnf("Warning: Go function signature mismatch for %q: %v\n", phpFunc.Name, err) |
| 72 | continue |
| 73 | } |
| 74 | |
| 75 | functions = append(functions, *phpFunc) |
| 76 | } |
| 77 | |
| 78 | if err := checkOrphanDirectives(file, fset, phpFuncRegex, consumed, "//export_php:function"); err != nil { |
| 79 | return nil, err |
| 80 | } |