Skip to content

Commit b9410ba

Browse files
feature: add inlay hints and upgrade to 5.0
1 parent 6c29008 commit b9410ba

File tree

3 files changed

+70
-5
lines changed

3 files changed

+70
-5
lines changed

app/Http/Controllers/Api/GenerateController.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,36 @@
22

33
namespace App\Http\Controllers\Api;
44

5+
use App\Traverser\CollectSignificantNodeLocations;
56
use Illuminate\Http\Request;
67
use PhpParser\Error;
7-
use PhpParser\ParserFactory;
8+
use PhpParser\Lexer\Emulative;
9+
use PhpParser\NodeTraverser;
10+
use PhpParser\Parser\Php8;
11+
use PhpParser\PhpVersion;
812

913
class GenerateController
1014
{
1115
public function __invoke(Request $request)
1216
{
1317
$code = $request->input('code');
14-
$parser = (new ParserFactory)->create(ParserFactory::ONLY_PHP7);
18+
$lexer = new Emulative(PhpVersion::getNewestSupported());
19+
$parser = new Php8($lexer, PhpVersion::getNewestSupported());
20+
21+
$ast = $parser->parse($code);
22+
23+
$traverser = new NodeTraverser($collector = new CollectSignificantNodeLocations());
24+
$traverser->traverse($ast);
1525

1626
try {
1727
return response()->json([
18-
'ast' => $parser->parse($code),
28+
'ast' => $ast,
29+
'significantNodeLocations' => $collector->getSignificantNodeLocations(),
1930
]);
2031
} catch (Error $e) {
2132
return response()->json([
2233
'ast' => [],
34+
'significantNodeLocations' => [],
2335
'error' => $e->getMessage(),
2436
]);
2537
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace App\Traverser;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
8+
use PhpParser\NodeVisitorAbstract;
9+
10+
final class CollectSignificantNodeLocations extends NodeVisitorAbstract
11+
{
12+
private array $significantNodeLocations = [];
13+
14+
public function enterNode(Node $node)
15+
{
16+
if ($node instanceof Identifier | $node instanceof Name) {
17+
return;
18+
}
19+
20+
$this->significantNodeLocations[] = [
21+
'type' => $node::class,
22+
'startPosition' => $node->getStartFilePos(),
23+
'endPosition' => $node->getEndFilePos(),
24+
];
25+
}
26+
27+
public function getSignificantNodeLocations(): array
28+
{
29+
return $this->significantNodeLocations;
30+
}
31+
}

resources/js/app.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import axios from 'axios';
22
import JSONFormatter from 'json-formatter-js';
33
import * as monaco from 'monaco-editor'
44

5+
let inlayHintLocations = [];
6+
let editor
7+
58
document.addEventListener('DOMContentLoaded', () => {
69
const element = document.getElementById('editor');
7-
const editor = monaco.editor.create(element, {
10+
editor = monaco.editor.create(element, {
811
value: "<?php\n\n",
912
language: 'php',
1013
theme: 'vs-dark',
@@ -27,6 +30,21 @@ document.addEventListener('DOMContentLoaded', () => {
2730

2831
generate(code);
2932
})
33+
34+
monaco.languages.registerInlayHintsProvider('php', {
35+
provideInlayHints(model, range, token) {
36+
return {
37+
hints: inlayHintLocations.map(({ type, startPosition, endPosition }) => {
38+
return {
39+
kind: monaco.languages.InlayHintKind.Type,
40+
position: model.getPositionAt(endPosition + 1),
41+
label: `: ${type}`,
42+
}
43+
}),
44+
dispose: () => {},
45+
}
46+
}
47+
})
3048
})
3149

3250
async function generate(code) {
@@ -40,7 +58,7 @@ async function generate(code) {
4058

4159
axios.post('/api/generate', { code })
4260
.then(response => response.data)
43-
.then(({ ast, error = undefined }) => {
61+
.then(({ ast, significantNodeLocations, error = undefined }) => {
4462
output.innerHTML = "";
4563

4664
if (error !== undefined) {
@@ -58,5 +76,9 @@ async function generate(code) {
5876
output.appendChild(formatter.render());
5977

6078
loader.style.display = "none";
79+
80+
inlayHintLocations = significantNodeLocations;
81+
82+
editor.setValue(code);
6183
});
6284
}

0 commit comments

Comments
 (0)