Skip to content

Commit 31dfadd

Browse files
committed
first commit
0 parents  commit 31dfadd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+10113
-0
lines changed

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
13+
14+
[*.yml]
15+
indent_size = 2

.gitattributes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
* text=auto eol=lf
2+
/.github export-ignore
3+
.scrutinizer.yml export-ignore
4+
BACKERS.md export-ignore
5+
CONTRIBUTING.md export-ignore
6+
CHANGELOG.md export-ignore

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/vendor
2+
/.idea
3+
/.vscode
4+
/.vagrant
5+
.phpunit.result.cache
6+
/buildroot
7+
/downloads
8+
/source
9+
.DS_Store

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# PHP Parser CLI

app/Commands/CompileBinaryCommand.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace App\Commands;
4+
5+
use App\Parser\Walker;
6+
use Illuminate\Support\Facades\File;
7+
use Illuminate\Support\Facades\Process;
8+
use LaravelZero\Framework\Commands\Command;
9+
10+
use function Laravel\Prompts\confirm;
11+
use function Laravel\Prompts\info;
12+
13+
class CompileBinaryCommand extends Command
14+
{
15+
protected $signature = 'compile-binary';
16+
17+
protected $description = 'Parse the given PHP code';
18+
19+
public function handle(): void
20+
{
21+
$version = File::json(base_path('composer.json'))['version'];
22+
23+
info("Compiling binary for version {$version}");
24+
25+
$destination = base_path('bin/php-parser-' . $version);
26+
27+
if (File::exists($destination)) {
28+
if (!confirm('The binary already exists. Do you want to overwrite it?', false)) {
29+
return;
30+
}
31+
} else {
32+
confirm('Continue?', true);
33+
}
34+
35+
36+
$extensions = collect([
37+
'bcmath',
38+
'calendar',
39+
'ctype',
40+
'curl',
41+
'dba',
42+
'dom',
43+
'exif',
44+
'filter',
45+
'fileinfo',
46+
'iconv',
47+
'mbstring',
48+
'mbregex',
49+
'openssl',
50+
'pcntl',
51+
'pdo',
52+
'pdo_mysql',
53+
'pdo_sqlite',
54+
'phar',
55+
'posix',
56+
'readline',
57+
'simplexml',
58+
'sockets',
59+
'sqlite3',
60+
'tokenizer',
61+
'xml',
62+
'xmlreader',
63+
'xmlwriter',
64+
'zip',
65+
'zlib',
66+
'sodium',
67+
])->implode(',');
68+
69+
$spc = base_path('spc');
70+
71+
collect([
72+
sprintf('%s download --with-php=8.2 --for-extensions="%s"', $spc, $extensions),
73+
sprintf('%s build --build-micro --build-cli "%s"', $spc, $extensions),
74+
sprintf('%s micro:combine %s -O %s', $spc, base_path('builds/php-parser'), $destination),
75+
])->each(function (string $command) {
76+
Process::run($command, function (string $type, string $output) {
77+
echo $output;
78+
});
79+
});
80+
}
81+
}

app/Commands/ParseCommand.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Commands;
4+
5+
use App\Parser\Walker;
6+
use LaravelZero\Framework\Commands\Command;
7+
8+
class ParseCommand extends Command
9+
{
10+
protected $signature = 'parse {code}';
11+
12+
protected $description = 'Parse the given PHP code';
13+
14+
public function handle(): void
15+
{
16+
$walker = new Walker($this->argument('code'));
17+
18+
echo $walker->walk()->toJson();
19+
}
20+
}

app/Parser/Context.php

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
namespace App\Parser;
4+
5+
class Context
6+
{
7+
public $classDefinition = null;
8+
9+
public $implements = [];
10+
11+
public $extends = null;
12+
13+
public $methodDefinition = null;
14+
15+
public $methodDefinitionParams = [];
16+
17+
public $methodExistingArgs = [];
18+
19+
public $classUsed = null;
20+
21+
public $methodUsed = null;
22+
23+
public $child = null;
24+
25+
public $variables = [];
26+
27+
public $definedProperties = [];
28+
29+
protected $freshObject = [];
30+
31+
public $fillingInArrayKey = false;
32+
33+
public $fillingInArrayValue = false;
34+
35+
public $paramIndex = 0;
36+
37+
public function __construct(public ?Context $parent = null)
38+
{
39+
$this->freshObject = $this->toArray();
40+
}
41+
42+
public function pristine(): bool
43+
{
44+
return $this->toArray() === $this->freshObject;
45+
}
46+
47+
public function touched(): bool
48+
{
49+
return !$this->pristine();
50+
}
51+
52+
public function addVariable(string $name, array $attributes)
53+
{
54+
if (isset($attributes['name'])) {
55+
unset($attributes['name']);
56+
}
57+
58+
$this->variables[ltrim($name, '$')] = $attributes;
59+
}
60+
61+
public function searchForProperty(string $name)
62+
{
63+
$prop = $this->definedProperties[$name];
64+
65+
if ($prop) {
66+
return $prop;
67+
}
68+
69+
if ($this->parent) {
70+
return $this->parent->searchForProperty($name);
71+
}
72+
73+
return null;
74+
}
75+
76+
public function searchForVar(string $name)
77+
{
78+
$param = array_filter(
79+
$this->methodDefinitionParams,
80+
fn($param) => $param['name'] === $name,
81+
);
82+
83+
if (count($param)) {
84+
return array_values($param)[0];
85+
}
86+
87+
if (array_key_exists($name, $this->variables)) {
88+
return $this->variables[$name];
89+
}
90+
91+
if ($this->parent) {
92+
return $this->parent->searchForVar($name);
93+
}
94+
95+
return null;
96+
}
97+
98+
public function toArray()
99+
{
100+
return [
101+
'classDefinition' => $this->classDefinition,
102+
'implements' => $this->implements,
103+
'extends' => $this->extends,
104+
'methodDefinition' => $this->methodDefinition,
105+
'methodDefinitionParams' => $this->methodDefinitionParams,
106+
'methodExistingArgs' => $this->methodExistingArgs,
107+
'classUsed' => $this->classUsed,
108+
'methodUsed' => $this->methodUsed,
109+
'parent' => $this->parent?->toArray(),
110+
'variables' => $this->variables,
111+
'definedProperties' => $this->definedProperties,
112+
'fillingInArrayKey' => $this->fillingInArrayKey,
113+
'fillingInArrayValue' => $this->fillingInArrayValue,
114+
'paramIndex' => $this->paramIndex,
115+
];
116+
}
117+
118+
public function toJson($flags = 0)
119+
{
120+
return json_encode($this->toArray(), $flags);
121+
}
122+
}

0 commit comments

Comments
 (0)