Skip to content

Commit 80066a2

Browse files
authored
Merge pull request #73 from adelf/patch-1 (resolves #71)
IDE Builder and Blueprint completions with ide.json
2 parents 1576a07 + f7cfcb0 commit 80066a2

File tree

5 files changed

+152
-116
lines changed

5 files changed

+152
-116
lines changed

ide.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"$schema": "https://laravel-ide.com/schema/laravel-ide-v2.json",
3+
"helperCode": {
4+
"classMixins": [
5+
{
6+
"classFqn": "Illuminate\\Contracts\\Database\\Query\\Builder",
7+
"mixinFqn": "Tpetry\\PostgresqlEnhanced\\Query\\Builder"
8+
},
9+
{
10+
"classFqn": "Illuminate\\Database\\Query\\Builder",
11+
"mixinFqn": "Tpetry\\PostgresqlEnhanced\\Query\\Builder"
12+
},
13+
{
14+
"classFqn": "Illuminate\\Database\\Schema\\Blueprint",
15+
"mixinFqn": "Tpetry\\PostgresqlEnhanced\\Schema\\Blueprint"
16+
},
17+
{
18+
"classFqn": "Illuminate\\Database\\Schema\\ColumnDefinition",
19+
"mixinFqn": "Tpetry\\PostgresqlEnhanced\\Schema\\ColumnDefinition"
20+
},
21+
{
22+
"classFqn": "Illuminate\\Database\\Schema\\IndexDefinition",
23+
"mixinFqn": "Tpetry\\PostgresqlEnhanced\\Schema\\IndexDefinition"
24+
},
25+
{
26+
"classFqn": "Illuminate\\Support\\Facades\\Schema",
27+
"mixinFqn": "Tpetry\\PostgresqlEnhanced\\Support\\Facades\\Schema"
28+
}
29+
]
30+
}
31+
}

src/Schema/ColumnDefinition.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tpetry\PostgresqlEnhanced\Schema;
6+
7+
use Illuminate\Contracts\Database\Query\Expression;
8+
use Illuminate\Database\Schema\ColumnDefinition as BaseColumnDefinition;
9+
10+
/**
11+
* @internal This class is not used. It only exists to teach Laravel projects using PHPStan or IDEs supporting auto-suggest about added functionality.
12+
*/
13+
class ColumnDefinition extends BaseColumnDefinition
14+
{
15+
/**
16+
* Specify the compression method for TOASTed values (PostgreSQL).
17+
*/
18+
public function compression(string $algorithm): self
19+
{
20+
return $this;
21+
}
22+
23+
/**
24+
* Sets an initial value to the column (PostgreSQL).
25+
*/
26+
public function initial(mixed $value): self
27+
{
28+
return $this;
29+
}
30+
31+
/**
32+
* Specify casting expression when changing the column type (PostgreSQL).
33+
*/
34+
public function using(string|Expression $expression): self
35+
{
36+
return $this;
37+
}
38+
}

src/Schema/IndexDefinition.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tpetry\PostgresqlEnhanced\Schema;
6+
7+
use Illuminate\Database\Schema\IndexDefinition as BaseIndexDefinition;
8+
9+
/**
10+
* @internal This class is not used. It only exists to teach Laravel projects using PHPStan or IDEs supporting auto-suggest about added functionality.
11+
*/
12+
class IndexDefinition extends BaseIndexDefinition
13+
{
14+
/**
15+
* Include non-key columns in the index (PostgreSQL).
16+
*
17+
* @param string|array<int, string> $columns
18+
*/
19+
public function include(string|array $columns): self
20+
{
21+
return $this;
22+
}
23+
24+
/**
25+
* Mark NULLs as not distinct values (PostgreSQL).
26+
*/
27+
public function nullsNotDistinct(): self
28+
{
29+
return $this;
30+
}
31+
32+
/**
33+
* Specify fulltext index weight for columns (PostgreSQL).
34+
*
35+
* @param array<int, string> $labels
36+
*/
37+
public function weight(array $labels): self
38+
{
39+
return $this;
40+
}
41+
42+
/**
43+
* Build a partial index by specifying the rows that should be included (PostgreSQL).
44+
*
45+
* @param string|(callable(\Illuminate\Database\Query\Builder):mixed)|(callable(\Illuminate\Contracts\Database\Query\Builder):mixed) $columns
46+
*/
47+
public function where(string|callable $columns): self
48+
{
49+
return $this;
50+
}
51+
52+
/**
53+
* Specify index parameters to fine-tune its configuration (PostgreSQL).
54+
*
55+
* @param array<string, bool|float|int|string> $options
56+
*/
57+
public function with(array $options): self
58+
{
59+
return $this;
60+
}
61+
}

src/Support/Phpstan/SchemaColumnDefinitionExtension.php

Lines changed: 11 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,83 +4,31 @@
44

55
namespace Tpetry\PostgresqlEnhanced\Support\Phpstan;
66

7-
use Illuminate\Contracts\Database\Query\Expression as ExpressionContract;
8-
use Illuminate\Database\Schema\ColumnDefinition;
7+
use Illuminate\Database\Schema\ColumnDefinition as BaseColumnDefinition;
98
use PHPStan\Reflection\ClassReflection;
10-
use PHPStan\Reflection\FunctionVariant;
119
use PHPStan\Reflection\MethodReflection;
1210
use PHPStan\Reflection\MethodsClassReflectionExtension;
13-
use PHPStan\Type\Generic\TemplateTypeMap;
14-
use PHPStan\Type\MixedType;
15-
use PHPStan\Type\ObjectType;
16-
use PHPStan\Type\StringType;
17-
use Tpetry\PostgresqlEnhanced\Support\Phpstan\Values\ReflectedMethod;
18-
use Tpetry\PostgresqlEnhanced\Support\Phpstan\Values\ReflectedParameter;
11+
use PHPStan\Reflection\ReflectionProvider;
12+
use Tpetry\PostgresqlEnhanced\Schema\ColumnDefinition;
1913

2014
class SchemaColumnDefinitionExtension implements MethodsClassReflectionExtension
2115
{
22-
/**
23-
* @param 'compression'|'initial'|'using' $methodName
24-
*/
16+
public function __construct(
17+
private ReflectionProvider $reflectionProvider,
18+
) {
19+
}
20+
2521
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
2622
{
27-
return match ($methodName) {
28-
'initial' => $this->getInitialMethod($classReflection),
29-
'compression' => $this->getCompressionMethod($classReflection),
30-
'using' => $this->getUsingMethod($classReflection),
31-
};
23+
return $this->reflectionProvider->getClass(ColumnDefinition::class)->getNativeMethod($methodName);
3224
}
3325

3426
public function hasMethod(ClassReflection $classReflection, string $methodName): bool
3527
{
36-
if (ColumnDefinition::class !== $classReflection->getName()) {
28+
if (BaseColumnDefinition::class !== $classReflection->getName()) {
3729
return false;
3830
}
3931

40-
return \in_array($methodName, ['compression', 'initial', 'using']);
41-
}
42-
43-
private function getCompressionMethod(ClassReflection $classReflection): MethodReflection
44-
{
45-
$parameters = [new ReflectedParameter('algorithm', new StringType())];
46-
$returnType = new ObjectType(ColumnDefinition::class);
47-
48-
return new ReflectedMethod(
49-
classReflection: $classReflection,
50-
name: 'compression',
51-
variants: [
52-
new FunctionVariant(TemplateTypeMap::createEmpty(), null, $parameters, false, $returnType),
53-
],
54-
);
55-
}
56-
57-
private function getInitialMethod(ClassReflection $classReflection): MethodReflection
58-
{
59-
$parameters = [new ReflectedParameter('value', new MixedType())];
60-
$returnType = new ObjectType(ColumnDefinition::class);
61-
62-
return new ReflectedMethod(
63-
classReflection: $classReflection,
64-
name: 'initial',
65-
variants: [
66-
new FunctionVariant(TemplateTypeMap::createEmpty(), null, $parameters, false, $returnType),
67-
],
68-
);
69-
}
70-
71-
private function getUsingMethod(ClassReflection $classReflection): MethodReflection
72-
{
73-
$parametersExpression = [new ReflectedParameter('expression', new ObjectType(ExpressionContract::class))];
74-
$parametersString = [new ReflectedParameter('expression', new StringType())];
75-
$returnType = new ObjectType(ColumnDefinition::class);
76-
77-
return new ReflectedMethod(
78-
classReflection: $classReflection,
79-
name: 'using',
80-
variants: [
81-
new FunctionVariant(TemplateTypeMap::createEmpty(), null, $parametersExpression, false, $returnType),
82-
new FunctionVariant(TemplateTypeMap::createEmpty(), null, $parametersString, false, $returnType),
83-
],
84-
);
32+
return $this->reflectionProvider->getClass(ColumnDefinition::class)->hasNativeMethod($methodName);
8533
}
8634
}

src/Support/Phpstan/SchemaIndexDefinitionExtension.php

Lines changed: 11 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,73 +4,31 @@
44

55
namespace Tpetry\PostgresqlEnhanced\Support\Phpstan;
66

7-
use Illuminate\Contracts\Database\Query\Builder as BuilderContract;
8-
use Illuminate\Database\Query\Builder as BuilderQuery;
9-
use Illuminate\Database\Schema\IndexDefinition;
7+
use Illuminate\Database\Schema\IndexDefinition as BaseIndexDefinition;
108
use PHPStan\Reflection\ClassReflection;
11-
use PHPStan\Reflection\FunctionVariant;
129
use PHPStan\Reflection\MethodReflection;
1310
use PHPStan\Reflection\MethodsClassReflectionExtension;
14-
use PHPStan\Type\ArrayType;
15-
use PHPStan\Type\BooleanType;
16-
use PHPStan\Type\CallableType;
17-
use PHPStan\Type\FloatType;
18-
use PHPStan\Type\Generic\TemplateTypeMap;
19-
use PHPStan\Type\IntegerType;
20-
use PHPStan\Type\ObjectType;
21-
use PHPStan\Type\StringType;
22-
use PHPStan\Type\TypeCombinator;
23-
use Tpetry\PostgresqlEnhanced\Support\Phpstan\Values\ReflectedMethod;
24-
use Tpetry\PostgresqlEnhanced\Support\Phpstan\Values\ReflectedParameter;
25-
use UnexpectedValueException;
11+
use PHPStan\Reflection\ReflectionProvider;
12+
use Tpetry\PostgresqlEnhanced\Schema\IndexDefinition;
2613

2714
class SchemaIndexDefinitionExtension implements MethodsClassReflectionExtension
2815
{
16+
public function __construct(
17+
private ReflectionProvider $reflectionProvider,
18+
) {
19+
}
20+
2921
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
3022
{
31-
return match ($methodName) {
32-
'include' => new ReflectedMethod($classReflection, $methodName, [
33-
$this->createFunctionVariant([new ReflectedParameter('columns', new StringType())]),
34-
$this->createFunctionVariant([new ReflectedParameter('columns', new ArrayType(new IntegerType(), new StringType()))]),
35-
]),
36-
'nullsNotDistinct' => new ReflectedMethod($classReflection, $methodName, [
37-
$this->createFunctionVariant([]),
38-
]),
39-
'weight' => new ReflectedMethod($classReflection, $methodName, [
40-
$this->createFunctionVariant([new ReflectedParameter('labels', new ArrayType(new IntegerType(), new StringType()))]),
41-
]),
42-
'where' => new ReflectedMethod($classReflection, $methodName, [
43-
$this->createFunctionVariant([new ReflectedParameter('columns', new StringType())]),
44-
$this->createFunctionVariant([new ReflectedParameter('columns', new CallableType([new ReflectedParameter('builder', new ObjectType(BuilderContract::class))], new ObjectType(BuilderContract::class), false))]),
45-
$this->createFunctionVariant([new ReflectedParameter('columns', new CallableType([new ReflectedParameter('builder', new ObjectType(BuilderQuery::class))], new ObjectType(BuilderContract::class), false))]),
46-
]),
47-
'with' => new ReflectedMethod($classReflection, $methodName, [
48-
$this->createFunctionVariant([new ReflectedParameter('options', new ArrayType(new StringType(), TypeCombinator::union(new BooleanType(), new FloatType(), new IntegerType(), new StringType())))]),
49-
]),
50-
default => throw new UnexpectedValueException("'{$methodName}' is not defined for IndexDefinition."),
51-
};
23+
return $this->reflectionProvider->getClass(IndexDefinition::class)->getNativeMethod($methodName);
5224
}
5325

5426
public function hasMethod(ClassReflection $classReflection, string $methodName): bool
5527
{
56-
if (IndexDefinition::class !== $classReflection->getName()) {
28+
if (BaseIndexDefinition::class !== $classReflection->getName()) {
5729
return false;
5830
}
5931

60-
return \in_array($methodName, ['include', 'nullsNotDistinct', 'weight', 'where', 'with']);
61-
}
62-
63-
/**
64-
* @param array<int, \PHPStan\Reflection\ParameterReflection> $parameters
65-
*/
66-
private function createFunctionVariant(array $parameters): FunctionVariant
67-
{
68-
return new FunctionVariant(
69-
templateTypeMap: TemplateTypeMap::createEmpty(),
70-
resolvedTemplateTypeMap: null,
71-
parameters: $parameters,
72-
isVariadic: false,
73-
returnType: new ObjectType(IndexDefinition::class),
74-
);
32+
return $this->reflectionProvider->getClass(IndexDefinition::class)->hasNativeMethod($methodName);
7533
}
7634
}

0 commit comments

Comments
 (0)