Skip to content

Commit 2a80537

Browse files
committed
basic folio support
1 parent c3f054c commit 2a80537

File tree

3 files changed

+152
-50
lines changed

3 files changed

+152
-50
lines changed

php-templates/routes.php

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,97 @@
11
<?php
22

3-
function vsCodeGetRouterReflection(\Illuminate\Routing\Route $route)
4-
{
5-
if ($route->getActionName() === 'Closure') {
6-
return new \ReflectionFunction($route->getAction()['uses']);
3+
$routes = new class {
4+
public function all()
5+
{
6+
return collect(app('router')->getRoutes()->getRoutes())
7+
->map(fn(\Illuminate\Routing\Route $route) => $this->getRoute($route))
8+
->merge($this->getFolioRoutes());
79
}
810

9-
if (!str_contains($route->getActionName(), '@')) {
10-
return new \ReflectionClass($route->getActionName());
11+
protected function getFolioRoutes()
12+
{
13+
try {
14+
$output = new \Symfony\Component\Console\Output\BufferedOutput();
15+
16+
\Illuminate\Support\Facades\Artisan::call("folio:list", ["--json" => true], $output);
17+
18+
$mountPaths = collect(app(\Laravel\Folio\FolioManager::class)->mountPaths());
19+
20+
return collect(json_decode($output->fetch(), true))->map(fn($route) => $this->getFolioRoute($route, $mountPaths));
21+
} catch (\Exception | \Throwable $e) {
22+
return [];
23+
}
1124
}
1225

13-
try {
14-
return new \ReflectionMethod($route->getControllerClass(), $route->getActionMethod());
15-
} catch (\Throwable $e) {
16-
$namespace = app(\Illuminate\Routing\UrlGenerator::class)->getRootControllerNamespace()
17-
?? (app()->getNamespace() . 'Http\Controllers');
26+
protected function getFolioRoute($route, $mountPaths)
27+
{
28+
if ($mountPaths->count() === 1) {
29+
$mountPath = $mountPaths[0];
30+
} else {
31+
$mountPath = $mountPaths->first(fn($mp) => file_exists($mp->path . DIRECTORY_SEPARATOR . $route['view']));
32+
}
33+
34+
$path = $route['view'];
35+
36+
if ($mountPath) {
37+
$path = $mountPath->path . DIRECTORY_SEPARATOR . $path;
38+
}
1839

19-
return new \ReflectionMethod(
20-
$namespace . '\\' . ltrim($route->getControllerClass(), '\\'),
21-
$route->getActionMethod(),
22-
);
40+
return [
41+
'method' => $route['method'],
42+
'uri' => $route['uri'],
43+
'name' => $route['name'],
44+
'action' => null,
45+
'parameters' => [],
46+
'filename' => $path,
47+
'line' => 0,
48+
];
2349
}
24-
}
2550

26-
echo collect(app('router')->getRoutes()->getRoutes())
27-
->map(function (\Illuminate\Routing\Route $route) {
51+
protected function getRoute(\Illuminate\Routing\Route $route)
52+
{
2853
try {
29-
$reflection = vsCodeGetRouterReflection($route);
54+
$reflection = $this->getRouteReflection($route);
3055
} catch (\Throwable $e) {
3156
$reflection = null;
3257
}
3358

3459
return [
35-
'method' => collect($route->methods())->filter(function ($method) {
36-
return $method !== 'HEAD';
37-
})->implode('|'),
60+
'method' => collect($route->methods())
61+
->filter(fn($method) => $method !== 'HEAD')
62+
->implode('|'),
3863
'uri' => $route->uri(),
3964
'name' => $route->getName(),
4065
'action' => $route->getActionName(),
4166
'parameters' => $route->parameterNames(),
4267
'filename' => $reflection ? $reflection->getFileName() : null,
4368
'line' => $reflection ? $reflection->getStartLine() : null,
4469
];
45-
})
46-
->toJson();
70+
}
71+
72+
protected function getRouteReflection(\Illuminate\Routing\Route $route)
73+
{
74+
if ($route->getActionName() === 'Closure') {
75+
return new \ReflectionFunction($route->getAction()['uses']);
76+
}
77+
78+
if (!str_contains($route->getActionName(), '@')) {
79+
return new \ReflectionClass($route->getActionName());
80+
}
81+
82+
try {
83+
return new \ReflectionMethod($route->getControllerClass(), $route->getActionMethod());
84+
} catch (\Throwable $e) {
85+
$namespace = app(\Illuminate\Routing\UrlGenerator::class)->getRootControllerNamespace()
86+
?? (app()->getNamespace() . 'Http\Controllers');
87+
88+
return new \ReflectionMethod(
89+
$namespace . '\\' . ltrim($route->getControllerClass(), '\\'),
90+
$route->getActionMethod(),
91+
);
92+
}
93+
}
94+
};
95+
96+
97+
echo $routes->all()->toJson();

src/features/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ export const linkProvider: LinkProvider = (doc: vscode.TextDocument) => {
7272
(route) => route.name === param.value,
7373
);
7474

75-
if (!route || !route.filename || !route.line) {
75+
if (!route || !route.filename) {
7676
return null;
7777
}
7878

7979
return new vscode.DocumentLink(
8080
detectedRange(param),
8181
vscode.Uri.file(route.filename).with({
82-
fragment: `L${route.line}`,
82+
fragment: `L${route.line ?? 0}`,
8383
}),
8484
);
8585
},

src/templates/routes.ts

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,98 @@
11
// This file was generated from php-templates/routes.php, do not edit directly
22
export default `
3-
function vsCodeGetRouterReflection(\\Illuminate\\Routing\\Route $route)
4-
{
5-
if ($route->getActionName() === 'Closure') {
6-
return new \\ReflectionFunction($route->getAction()['uses']);
3+
$routes = new class {
4+
public function all()
5+
{
6+
return collect(app('router')->getRoutes()->getRoutes())
7+
->map(fn(\\Illuminate\\Routing\\Route $route) => $this->getRoute($route))
8+
->merge($this->getFolioRoutes());
79
}
810
9-
if (!str_contains($route->getActionName(), '@')) {
10-
return new \\ReflectionClass($route->getActionName());
11+
protected function getFolioRoutes()
12+
{
13+
try {
14+
$output = new \\Symfony\\Component\\Console\\Output\\BufferedOutput();
15+
16+
\\Illuminate\\Support\\Facades\\Artisan::call("folio:list", ["--json" => true], $output);
17+
18+
$mountPaths = collect(app(\\Laravel\\Folio\\FolioManager::class)->mountPaths());
19+
20+
return collect(json_decode($output->fetch(), true))->map(fn($route) => $this->getFolioRoute($route, $mountPaths));
21+
} catch (\\Exception | \\Throwable $e) {
22+
return [];
23+
}
1124
}
1225
13-
try {
14-
return new \\ReflectionMethod($route->getControllerClass(), $route->getActionMethod());
15-
} catch (\\Throwable $e) {
16-
$namespace = app(\\Illuminate\\Routing\\UrlGenerator::class)->getRootControllerNamespace()
17-
?? (app()->getNamespace() . 'Http\\Controllers');
26+
protected function getFolioRoute($route, $mountPaths)
27+
{
28+
if ($mountPaths->count() === 1) {
29+
$mountPath = $mountPaths[0];
30+
} else {
31+
$mountPath = $mountPaths->first(fn($mp) => file_exists($mp->path . DIRECTORY_SEPARATOR . $route['view']));
32+
}
33+
34+
$path = $route['view'];
35+
36+
if ($mountPath) {
37+
$path = $mountPath->path . DIRECTORY_SEPARATOR . $path;
38+
}
1839
19-
return new \\ReflectionMethod(
20-
$namespace . '\\\\' . ltrim($route->getControllerClass(), '\\\\'),
21-
$route->getActionMethod(),
22-
);
40+
return [
41+
'method' => $route['method'],
42+
'uri' => $route['uri'],
43+
'name' => $route['name'],
44+
'action' => null,
45+
'parameters' => [],
46+
'filename' => $path,
47+
'line' => 0,
48+
];
2349
}
24-
}
2550
26-
echo collect(app('router')->getRoutes()->getRoutes())
27-
->map(function (\\Illuminate\\Routing\\Route $route) {
51+
protected function getRoute(\\Illuminate\\Routing\\Route $route)
52+
{
2853
try {
29-
$reflection = vsCodeGetRouterReflection($route);
54+
$reflection = $this->getRouteReflection($route);
3055
} catch (\\Throwable $e) {
3156
$reflection = null;
3257
}
3358
3459
return [
35-
'method' => collect($route->methods())->filter(function ($method) {
36-
return $method !== 'HEAD';
37-
})->implode('|'),
60+
'method' => collect($route->methods())
61+
->filter(fn($method) => $method !== 'HEAD')
62+
->implode('|'),
3863
'uri' => $route->uri(),
3964
'name' => $route->getName(),
4065
'action' => $route->getActionName(),
4166
'parameters' => $route->parameterNames(),
4267
'filename' => $reflection ? $reflection->getFileName() : null,
4368
'line' => $reflection ? $reflection->getStartLine() : null,
4469
];
45-
})
46-
->toJson();
70+
}
71+
72+
protected function getRouteReflection(\\Illuminate\\Routing\\Route $route)
73+
{
74+
if ($route->getActionName() === 'Closure') {
75+
return new \\ReflectionFunction($route->getAction()['uses']);
76+
}
77+
78+
if (!str_contains($route->getActionName(), '@')) {
79+
return new \\ReflectionClass($route->getActionName());
80+
}
81+
82+
try {
83+
return new \\ReflectionMethod($route->getControllerClass(), $route->getActionMethod());
84+
} catch (\\Throwable $e) {
85+
$namespace = app(\\Illuminate\\Routing\\UrlGenerator::class)->getRootControllerNamespace()
86+
?? (app()->getNamespace() . 'Http\\Controllers');
87+
88+
return new \\ReflectionMethod(
89+
$namespace . '\\\\' . ltrim($route->getControllerClass(), '\\\\'),
90+
$route->getActionMethod(),
91+
);
92+
}
93+
}
94+
};
95+
96+
97+
echo $routes->all()->toJson();
4798
`;

0 commit comments

Comments
 (0)