92 lines
3.4 KiB
Markdown
92 lines
3.4 KiB
Markdown
# php2go
|
|
|
|
Convert PHP source code to Go by AST walking.
|
|
|
|
The goal is to produce idiomatic, maintainable Go code as part of a one-off conversion. This is not generally possible for highly dynamic PHP code, that may require manual fixups.
|
|
|
|
## Progress
|
|
|
|
[X] Convert some small programs
|
|
[X] Error handling
|
|
- [X] All functions return `(type, error)`
|
|
- [X] Convert `throw` to err return
|
|
- [ ] Elide error return for functions that cannot throw
|
|
- ?? Could be a standalone Go refactoring tool
|
|
- [ ] Non-leaf function calls need to check + bubble errors
|
|
- [ ] Behaviour of function calls in rvalue cases where err cannot be checked
|
|
[ ] Comprehensive coverage of all AST node types
|
|
- [ ] Node
|
|
- [ ] Stmt
|
|
- [ ] Expr
|
|
- [X] Binary
|
|
- [ ] Scalar
|
|
[X] Array handling
|
|
- [X] Infer whether to use slice/map for PHP array
|
|
- [ ] Infer whether map use should be order-preserving
|
|
[ ] Multi-file programs
|
|
- [ ] Include/Require
|
|
[ ] Namespaces
|
|
[ ] Generators
|
|
[ ] Numbered break/continue
|
|
[ ] Goto
|
|
[ ] Comma operator
|
|
[ ] `null` -> `nil`
|
|
[ ] Consts and `define()`
|
|
[ ] `isset`/`unset`
|
|
[ ] `instanceof`
|
|
[ ] `try`/`catch`/`finally`
|
|
- Intend to implement using err checks, not panic/recover
|
|
- Any statements within the try block should capture the finally/catch to run within any interior err-check blocks
|
|
[ ] Abandon upon sight of `eval` / `extract` / ...
|
|
[ ] Assignment expressions
|
|
- Go doesn't support assignment in rvalues, only as a statement
|
|
- When walking below stmt level, need to first fully walk and check for any function calls + assignments that may need hoisting (and we can probably only do that correctly if there is no short-circuiting)
|
|
- [X] Add subtree walk + catch error for this case
|
|
- [ ] Add hoisting pass
|
|
[ ] Closures
|
|
- [ ] Handle value/reference captures
|
|
[X] Convert top-level calls to `init()`/`main()`
|
|
- *Currently always `init`*
|
|
[ ] Class/object transformations
|
|
- [X] Convert `new X` constructor calls to `NewX`
|
|
- [X] Visibility
|
|
- [X] Apply PHP visibility modifiers as Go case change
|
|
- [ ] Call mangled function name at call sites
|
|
- *PHP variable names are case-sensitive, function names are case-insensitive*
|
|
- [X] Static methods
|
|
- [X] Inheritance *partial*
|
|
- [X] Interfaces
|
|
- [X] super
|
|
- [X] Need to track current conversion state through into function generator, to select the concrete parent
|
|
- [X] parent::
|
|
- [X] self::
|
|
- [ ] static::
|
|
- [ ] Traits / `use`
|
|
- [ ] Abstract methods
|
|
[ ] Type inference
|
|
- [ ] Convert known PHP typenames to Go equivalents
|
|
- [ ] Parse extra types from phpdoc blocks
|
|
[ ] Infer whether to declare variable (`var` / `:=`) or reuse (`=`)
|
|
- [ ] Track current visibility scope
|
|
[ ] Library/environment transformations
|
|
- [ ] Standard library transformations
|
|
- [ ] Track golang package imports
|
|
- [ ] Handle conflicts between golang stdlib packages / local variable names
|
|
- [ ] uasort -> sort.Slice
|
|
- [ ] PHP Superglobal transformations
|
|
- [ ] `$_SERVER['argv']` to os.Args
|
|
- [ ] `$_GET['name']` to r.FormValue('name')
|
|
- [ ] Common 3rd party package transformations to popular equivalents (optional)
|
|
- [ ] Guzzle
|
|
- [ ] AWS SDK
|
|
- [ ] PHPUnit -> Go Test
|
|
- [ ] Replace Composer/PSR-4 autoloading with Go imports
|
|
[X] Variadic function parameters
|
|
[X] Preserve comments
|
|
[ ] Preserve rough line spacing
|
|
[ ] Convert wordpress / mediawiki / symfony
|
|
- [ ] Option to convert with preset=cli, preset=web, webroot path
|
|
- [ ] Option to generate built-in web server
|
|
[ ] Generate source maps
|
|
[ ] Command-line tool option to `go run`
|