Skip to content

Commit

Permalink
Merge branch 'master' into fix-244-performance
Browse files Browse the repository at this point in the history
  • Loading branch information
lptn authored Jan 25, 2023
2 parents a170cb7 + b09df6b commit 6a22877
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 40 deletions.
13 changes: 7 additions & 6 deletions src/Fakes/FakeModelsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Str;
use Psalm\LaravelPlugin\Handlers\Eloquent\Schema\SchemaAggregator;
use Psalm\LaravelPlugin\Handlers\Eloquent\Schema\SchemaColumn;

use function config;
use function get_class;
Expand Down Expand Up @@ -85,13 +86,13 @@ public function getPropertiesFromTable($model): void
$get_type = $set_type = '\Illuminate\Support\Carbon';
} else {
switch ($column->type) {
case 'string':
case 'int':
case 'float':
case SchemaColumn::TYPE_STRING:
case SchemaColumn::TYPE_INT:
case SchemaColumn::TYPE_FLOAT:
$get_type = $set_type = $column->type;
break;

case 'bool':
case SchemaColumn::TYPE_BOOL:
switch (config('database.default')) {
case 'sqlite':
case 'mysql':
Expand All @@ -105,7 +106,7 @@ public function getPropertiesFromTable($model): void

break;

case 'enum':
case SchemaColumn::TYPE_ENUM:
if (!$column->options) {
$get_type = $set_type = 'string';
} else {
Expand All @@ -115,7 +116,7 @@ public function getPropertiesFromTable($model): void
break;

default:
$get_type = $set_type = 'mixed';
$get_type = $set_type = SchemaColumn::TYPE_MIXED;
break;
}
}
Expand Down
1 change: 0 additions & 1 deletion src/Handlers/Eloquent/ModelPropertyAccessorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public static function getClassLikeNames(): array
return ModelStubProvider::getModelClasses();
}


public static function doesPropertyExist(PropertyExistenceProviderEvent $event): ?bool
{
$source = $event->getSource();
Expand Down
62 changes: 31 additions & 31 deletions src/Handlers/Eloquent/Schema/SchemaAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use PhpParser\NodeFinder;
use PhpParser;

use function array_key_exists;
Expand Down Expand Up @@ -53,16 +54,13 @@ class SchemaAggregator
*/
public function addStatements(array $stmts): void
{
foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Class_) {
$this->addClassStatements($stmt->stmts);
} elseif (
$stmt instanceof PhpParser\Node\Stmt\Return_ &&
$stmt->expr instanceof PhpParser\Node\Expr\New_ &&
$stmt->expr->class instanceof PhpParser\Node\Stmt\Class_
) {
$this->addClassStatements($stmt->expr->class->stmts);
}
$nodeFinder = new NodeFinder();

/** @var PhpParser\Node\Stmt\Class_[] $classes */
$classes = $nodeFinder->findInstanceOf($stmts, PhpParser\Node\Stmt\Class_::class);

foreach ($classes as $stmt) {
$this->addClassStatements($stmt->stmts);
}
}

Expand All @@ -88,30 +86,32 @@ private function addClassStatements(array $stmts): void
private function addUpMethodStatements(array $stmts): void
{
foreach ($stmts as $stmt) {
if (
$stmt instanceof PhpParser\Node\Stmt\Expression
$is_schema_method_call = $stmt instanceof PhpParser\Node\Stmt\Expression
&& $stmt->expr instanceof PhpParser\Node\Expr\StaticCall
&& $stmt->expr->class instanceof PhpParser\Node\Name
&& $stmt->expr->name instanceof PhpParser\Node\Identifier
&& $stmt->expr->class->getAttribute('resolvedName') === Schema::class
) {
switch ($stmt->expr->name->name) {
case 'create':
$this->alterTable($stmt->expr, true);
break;

case 'table':
$this->alterTable($stmt->expr, false);
break;

case 'drop':
case 'dropIfExists':
$this->dropTable($stmt->expr);
break;

case 'rename':
$this->renameTable($stmt->expr);
}
&& in_array($stmt->expr->class->getAttribute('resolvedName'), [Schema::class, 'Schema'], true);

if (! $is_schema_method_call) {
continue;
}

switch ($stmt->expr->name->name) {
case 'create':
$this->alterTable($stmt->expr, true);
break;

case 'table':
$this->alterTable($stmt->expr, false);
break;

case 'drop':
case 'dropIfExists':
$this->dropTable($stmt->expr);
break;

case 'rename':
$this->renameTable($stmt->expr);
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/Handlers/Eloquent/Schema/SchemaColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

class SchemaColumn
{
public const TYPE_STRING = 'string';
public const TYPE_INT = 'int';
public const TYPE_FLOAT = 'float';
public const TYPE_BOOL = 'bool';
public const TYPE_ENUM = 'enum';
public const TYPE_MIXED = 'mixed';

/** @var string */
public $name;

Expand Down
25 changes: 23 additions & 2 deletions tests/Unit/Handlers/Eloquent/Schema/DefaultUserTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,31 @@
final class DefaultUserTableTest extends AbstractSchemaAggregatorTest
{
/** @test */
public function it_detects_all_columns(): void
public function it_detects_all_columns_from_anonymous_class_migration(): void
{
$schemaAggregator = $this->instantiateSchemaAggregator(__DIR__ . '/migrations/simple');
$schemaAggregator = $this->instantiateSchemaAggregator(__DIR__ . '/migrations/default_users_table_anon');

$this->assertAllDefaultUsersTableColumnsDetectedProperly($schemaAggregator);
}

/** @test */
public function it_detects_all_columns_from_named_class_migration(): void
{
$schemaAggregator = $this->instantiateSchemaAggregator(__DIR__ . '/migrations/default_users_table_named');

$this->assertAllDefaultUsersTableColumnsDetectedProperly($schemaAggregator);
}

/** @test */
public function it_detects_all_columns_from_migration_that_uses_root_namespace_facades(): void
{
$schemaAggregator = $this->instantiateSchemaAggregator(__DIR__ . '/migrations/default_users_table_root_ns_facade');

$this->assertAllDefaultUsersTableColumnsDetectedProperly($schemaAggregator);
}

private function assertAllDefaultUsersTableColumnsDetectedProperly(SchemaAggregator $schemaAggregator): void
{
$this->assertSchemaHasTableAndNotNullableColumnOfType('users.id', 'int', $schemaAggregator);
$this->assertSchemaHasTableAndNotNullableColumnOfType('users.email', 'string', $schemaAggregator);
$this->assertSchemaHasTableAndNotNullableColumnOfType('users.password', 'string', $schemaAggregator);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};

0 comments on commit 6a22877

Please sign in to comment.