mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
* feat: add helpers to create PHP extensions (#1644) * feat: add helpers to create PHP extensions * cs * feat: GoString * test * add test for RegisterExtension * cs * optimize includes * fix * feat(extensions): add the PHP extension generator (#1649) * feat(extensions): add the PHP extension generator * unexport many types * unexport more symbols * cleanup some tests * unexport more symbols * fix * revert types files * revert * add better validation and fix templates * remove GoStringCopy * small fixes --------- Co-authored-by: Kévin Dunglas <kevin@dunglas.fr> * try to fix tests * fix CS * try some workarounds * try some workarounds * ingore TestRegisterExtension * exclude cgo tests in Docker images * fix * workaround... * race detector * simplify tests and code * make linter happy * feat(gofile): use templates to generate the Go file (#1666) --------- Co-authored-by: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com>
138 lines
3.1 KiB
Go
138 lines
3.1 KiB
Go
package extgen
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
const BuildDir = "build"
|
|
|
|
type Generator struct {
|
|
BaseName string
|
|
SourceFile string
|
|
BuildDir string
|
|
Functions []phpFunction
|
|
Classes []phpClass
|
|
Constants []phpConstant
|
|
}
|
|
|
|
// EXPERIMENTAL
|
|
func (g *Generator) Generate() error {
|
|
if err := g.setupBuildDirectory(); err != nil {
|
|
return fmt.Errorf("setup build directory: %w", err)
|
|
}
|
|
if err := g.parseSource(); err != nil {
|
|
return fmt.Errorf("parse source: %w", err)
|
|
}
|
|
|
|
if len(g.Functions) == 0 && len(g.Classes) == 0 && len(g.Constants) == 0 {
|
|
return fmt.Errorf("no PHP functions, classes, or constants found in source file")
|
|
}
|
|
|
|
generators := []struct {
|
|
name string
|
|
fn func() error
|
|
}{
|
|
{"stub file", g.generateStubFile},
|
|
{"arginfo", g.generateArginfo},
|
|
{"header file", g.generateHeaderFile},
|
|
{"C file", g.generateCFile},
|
|
{"Go file", g.generateGoFile},
|
|
{"documentation", g.generateDocumentation},
|
|
}
|
|
|
|
for _, gen := range generators {
|
|
if err := gen.fn(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) setupBuildDirectory() error {
|
|
if err := os.RemoveAll(g.BuildDir); err != nil {
|
|
return fmt.Errorf("removing build directory: %w", err)
|
|
}
|
|
|
|
return os.MkdirAll(g.BuildDir, 0755)
|
|
}
|
|
|
|
func (g *Generator) parseSource() error {
|
|
parser := SourceParser{}
|
|
|
|
functions, err := parser.ParseFunctions(g.SourceFile)
|
|
if err != nil {
|
|
return fmt.Errorf("parsing functions: %w", err)
|
|
}
|
|
g.Functions = functions
|
|
|
|
classes, err := parser.ParseClasses(g.SourceFile)
|
|
if err != nil {
|
|
return fmt.Errorf("parsing classes: %w", err)
|
|
}
|
|
g.Classes = classes
|
|
|
|
constants, err := parser.ParseConstants(g.SourceFile)
|
|
if err != nil {
|
|
return fmt.Errorf("parsing constants: %w", err)
|
|
}
|
|
g.Constants = constants
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) generateStubFile() error {
|
|
generator := StubGenerator{g}
|
|
if err := generator.generate(); err != nil {
|
|
return &GeneratorError{"stub generation", "failed to generate stub file", err}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) generateArginfo() error {
|
|
generator := arginfoGenerator{generator: g}
|
|
if err := generator.generate(); err != nil {
|
|
return &GeneratorError{"arginfo generation", "failed to generate arginfo", err}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) generateHeaderFile() error {
|
|
generator := HeaderGenerator{g}
|
|
if err := generator.generate(); err != nil {
|
|
return &GeneratorError{"header generation", "failed to generate header file", err}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) generateCFile() error {
|
|
generator := cFileGenerator{g}
|
|
if err := generator.generate(); err != nil {
|
|
return &GeneratorError{"C file generation", "failed to generate C file", err}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) generateGoFile() error {
|
|
generator := GoFileGenerator{g}
|
|
if err := generator.generate(); err != nil {
|
|
return &GeneratorError{"Go file generation", "failed to generate Go file", err}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (g *Generator) generateDocumentation() error {
|
|
docGen := DocumentationGenerator{g}
|
|
if err := docGen.generate(); err != nil {
|
|
return &GeneratorError{"documentation generation", "failed to generate documentation", err}
|
|
}
|
|
|
|
return nil
|
|
}
|