| 25 | } |
| 26 | |
| 27 | func (cp *classParser) parse(filename string) (classes []phpClass, err error) { |
| 28 | fset := token.NewFileSet() |
| 29 | node, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) |
| 30 | if err != nil { |
| 31 | return nil, fmt.Errorf("parsing file: %w", err) |
| 32 | } |
| 33 | |
| 34 | validator := Validator{} |
| 35 | |
| 36 | exportDirectives := cp.collectExportDirectives(node, fset) |
| 37 | methods, err := cp.parseMethods(filename) |
| 38 | if err != nil { |
| 39 | return nil, fmt.Errorf("parsing methods: %w", err) |
| 40 | } |
| 41 | |
| 42 | // match structs to directives |
| 43 | matchedDirectives := make(map[int]bool) |
| 44 | |
| 45 | var genDecl *ast.GenDecl |
| 46 | var ok bool |
| 47 | for _, decl := range node.Decls { |
| 48 | if genDecl, ok = decl.(*ast.GenDecl); !ok || genDecl.Tok != token.TYPE { |
| 49 | continue |
| 50 | } |
| 51 | |
| 52 | for _, spec := range genDecl.Specs { |
| 53 | var typeSpec *ast.TypeSpec |
| 54 | if typeSpec, ok = spec.(*ast.TypeSpec); !ok { |
| 55 | continue |
| 56 | } |
| 57 | |
| 58 | var structType *ast.StructType |
| 59 | if structType, ok = typeSpec.Type.(*ast.StructType); !ok { |
| 60 | continue |
| 61 | } |
| 62 | |
| 63 | var phpCl string |
| 64 | var directiveLine int |
| 65 | if phpCl, directiveLine = cp.extractPHPClassCommentWithLine(genDecl.Doc, fset); phpCl == "" { |
| 66 | continue |
| 67 | } |
| 68 | |
| 69 | matchedDirectives[directiveLine] = true |
| 70 | |
| 71 | class := phpClass{ |
| 72 | Name: phpCl, |
| 73 | GoStruct: typeSpec.Name.Name, |
| 74 | } |
| 75 | |
| 76 | class.Properties = cp.parseStructFields(structType.Fields.List) |
| 77 | |
| 78 | // associate methods with this class |
| 79 | for _, method := range methods { |
| 80 | if method.ClassName == phpCl { |
| 81 | class.Methods = append(class.Methods, method) |
| 82 | } |
| 83 | } |
| 84 | |