Skip to content

Commit b136e01

Browse files
committed
wip
1 parent 31dfadd commit b136e01

13 files changed

+3540
-1677
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77
/downloads
88
/source
99
.DS_Store
10+
todo.md
11+
.env
12+
/storage/local-results

Diff for: app/Commands/DetectCommand.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace App\Commands;
4+
5+
use App\Parser\DetectWalker;
6+
use App\Parser\Walker;
7+
use Illuminate\Support\Facades\File;
8+
use LaravelZero\Framework\Commands\Command;
9+
10+
class DetectCommand extends Command
11+
{
12+
protected $signature = 'detect {code} {--debug} {--from-file=}';
13+
14+
protected $description = 'Detect things we care about in the current code';
15+
16+
public function handle(): void
17+
{
18+
$code = $this->argument('code');
19+
20+
if ($this->option('from-file')) {
21+
$code = file_get_contents(__DIR__ . '/../../tests/snippets/detect/' . $this->option('from-file') . '.php');
22+
}
23+
24+
// file_put_contents(__DIR__ . '/code.txt', $this->argument('code'));
25+
26+
$walker = new DetectWalker($code, !!$this->option('debug'));
27+
$result = $walker->walk();
28+
29+
if (app()->isLocal()) {
30+
$dir = 'local-results/detect';
31+
File::ensureDirectoryExists(storage_path($dir));
32+
$now = now()->format('Y-m-d-H-i-s');
33+
34+
File::put(storage_path("{$dir}/result-{$now}.json"), $result->toJson(JSON_PRETTY_PRINT));
35+
36+
if (!$this->option('from-file')) {
37+
File::put(storage_path("{$dir}/result-{$now}.php"), $code);
38+
}
39+
}
40+
41+
echo $result->toJson();
42+
}
43+
}

Diff for: app/Commands/ParseCommand.php

+23-3
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,38 @@
33
namespace App\Commands;
44

55
use App\Parser\Walker;
6+
use Illuminate\Support\Facades\File;
67
use LaravelZero\Framework\Commands\Command;
78

89
class ParseCommand extends Command
910
{
10-
protected $signature = 'parse {code}';
11+
protected $signature = 'parse {code} {--debug} {--from-file=}';
1112

1213
protected $description = 'Parse the given PHP code';
1314

1415
public function handle(): void
1516
{
16-
$walker = new Walker($this->argument('code'));
17+
$code = $this->argument('code');
1718

18-
echo $walker->walk()->toJson();
19+
if ($this->option('from-file')) {
20+
$code = file_get_contents(__DIR__ . '/../../tests/snippets/parse/' . $this->option('from-file') . '.php');
21+
}
22+
23+
$walker = new Walker($code, !!$this->option('debug'));
24+
$result = $walker->walk();
25+
26+
if (app()->isLocal()) {
27+
$dir = 'local-results/parse';
28+
File::ensureDirectoryExists(storage_path($dir));
29+
$now = now()->format('Y-m-d-H-i-s');
30+
31+
File::put(storage_path("{$dir}/result-{$now}.json"), $result->toJson(JSON_PRETTY_PRINT));
32+
33+
if (!$this->option('from-file')) {
34+
File::put(storage_path("{$dir}/result-{$now}.php"), $code);
35+
}
36+
}
37+
38+
echo $result->toJson();
1939
}
2040
}

Diff for: app/Parser/DetectContext.php

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
namespace App\Parser;
4+
5+
class DetectContext
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 ?DetectContext $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)