diff --git a/src/Alias.php b/src/Alias.php index 38c1fa5..9a70ab0 100644 --- a/src/Alias.php +++ b/src/Alias.php @@ -101,7 +101,7 @@ class Alias } if ($facade === '\Illuminate\Database\Eloquent\Model') { - $this->usedMethods = ['decrement', 'increment']; + $this->usedMethods = ['decrement' => true, 'increment' => true]; } } @@ -381,7 +381,7 @@ class Alias $method = new \ReflectionMethod($className, $name); $class = new ReflectionClass($className); - if (!in_array($magic, $this->usedMethods)) { + if (!isset($this->usedMethods[$magic])) { if ($class !== $this->root) { $this->methods[] = new Method( $method, @@ -393,7 +393,7 @@ class Alias $this->getTemplateNames() ); } - $this->usedMethods[] = $magic; + $this->usedMethods[$magic] = true; } } } @@ -410,7 +410,7 @@ class Alias $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); if ($methods) { foreach ($methods as $method) { - if (!in_array($method->name, $this->usedMethods)) { + if (!isset($this->usedMethods[$method->name])) { // Only add the methods to the output when the root is not the same as the class. // And don't add the __*() methods if ($this->extends !== $class && substr($method->name, 0, 2) !== '__') { @@ -424,7 +424,7 @@ class Alias $this->getTemplateNames(), ); } - $this->usedMethods[] = $method->name; + $this->usedMethods[$method->name] = true; } } } @@ -435,7 +435,7 @@ class Alias $properties = $reflection->getStaticProperties(); $macros = isset($properties['macros']) ? $properties['macros'] : []; foreach ($macros as $macro_name => $macro_func) { - if (!in_array($macro_name, $this->usedMethods)) { + if (!isset($this->usedMethods[$macro_name])) { try { $method = $this->getMacroFunction($macro_func); } catch (Throwable $e) { @@ -451,7 +451,7 @@ class Alias $this->classAliases, $this->getReturnTypeNormalizers($reflection) ); - $this->usedMethods[] = $macro_name; + $this->usedMethods[$macro_name] = true; } } } @@ -589,12 +589,13 @@ class Alias */ protected function removeDuplicateMethodsFromPhpDoc() { - $methodNames = array_map(function (Method $method) { - return $method->getName(); - }, $this->getMethods()); + $methodNames = []; + foreach ($this->getMethods() as $method) { + $methodNames[$method->getName()] = true; + } foreach ($this->phpdoc->getTags() as $tag) { - if ($tag instanceof MethodTag && in_array($tag->getMethodName(), $methodNames)) { + if ($tag instanceof MethodTag && isset($methodNames[$tag->getMethodName()])) { $this->phpdoc->deleteTag($tag); } } diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index a09aeda..be35b39 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -123,6 +123,14 @@ class ModelsCommand extends Command protected $reset; protected $phpstorm_noinspections; protected $write_model_external_builder_methods; + /** + * @var array + */ + protected $fileCache = []; + /** + * @var array + */ + protected $contextCache = []; /** * @var array */ @@ -721,14 +729,19 @@ class ModelsCommand extends Command $type = (string)$this->getReturnTypeFromDocBlock($reflection); } - $file = new \SplFileObject($reflection->getFileName()); + $fileName = $reflection->getFileName(); + if (!isset($this->fileCache[$fileName])) { + $this->fileCache[$fileName] = new \SplFileObject($fileName); + } + $file = $this->fileCache[$fileName]; $file->seek($reflection->getStartLine() - 1); - $code = ''; + $lines = []; while ($file->key() < $reflection->getEndLine()) { - $code .= $file->current(); + $lines[] = $file->current(); $file->next(); } + $code = implode('', $lines); $code = trim(preg_replace('/\s\s+/', '', $code)); $begin = strpos($code, 'function('); $code = substr($code, $begin, strrpos($code, '}') - $begin + 1); @@ -1275,13 +1288,18 @@ class ModelsCommand extends Command } } + protected ?array $cachedRelationTypes = null; + protected ?array $cachedRelationReturnTypes = null; + /** * Returns the available relation types */ protected function getRelationTypes(): array { - $configuredRelations = $this->laravel['config']->get('ide-helper.additional_relation_types', []); - return array_merge(self::RELATION_TYPES, $configuredRelations); + return $this->cachedRelationTypes ??= array_merge( + self::RELATION_TYPES, + $this->laravel['config']->get('ide-helper.additional_relation_types', []) + ); } /** @@ -1289,7 +1307,7 @@ class ModelsCommand extends Command */ protected function getRelationReturnTypes(): array { - return $this->laravel['config']->get('ide-helper.additional_relation_return_types', []); + return $this->cachedRelationReturnTypes ??= $this->laravel['config']->get('ide-helper.additional_relation_return_types', []); } /** @@ -1364,11 +1382,7 @@ class ModelsCommand extends Command */ protected function getCommentFromDocBlock(\ReflectionMethod $reflection) { - $phpDocContext = (new ContextFactory())->createFromReflector($reflection); - $context = new Context( - $phpDocContext->getNamespace(), - $phpDocContext->getNamespaceAliases() - ); + $context = $this->getDocBlockContext($reflection); $comment = ''; $phpdoc = new DocBlock($reflection, $context); @@ -1389,11 +1403,7 @@ class ModelsCommand extends Command */ protected function getReturnTypeFromDocBlock(\ReflectionMethod $reflection, ?\Reflector $reflectorForContext = null) { - $phpDocContext = (new ContextFactory())->createFromReflector($reflectorForContext ?? $reflection); - $context = new Context( - $phpDocContext->getNamespace(), - $phpDocContext->getNamespaceAliases() - ); + $context = $this->getDocBlockContext($reflectorForContext ?? $reflection); $type = null; $phpdoc = new DocBlock($reflection, $context); @@ -1411,6 +1421,31 @@ class ModelsCommand extends Command return $type; } + protected function getDocBlockContext(\Reflector $reflector): Context + { + if ($reflector instanceof \ReflectionMethod) { + $key = $reflector->getDeclaringClass()->getName(); + } elseif ($reflector instanceof ReflectionClass) { + $key = $reflector->getName(); + } else { + $phpDocContext = (new ContextFactory())->createFromReflector($reflector); + return new Context( + $phpDocContext->getNamespace(), + $phpDocContext->getNamespaceAliases() + ); + } + + if (!isset($this->contextCache[$key])) { + $phpDocContext = (new ContextFactory())->createFromReflector($reflector); + $this->contextCache[$key] = new Context( + $phpDocContext->getNamespace(), + $phpDocContext->getNamespaceAliases() + ); + } + + return $this->contextCache[$key]; + } + protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?string { $returnType = $reflection->getReturnType(); @@ -1616,9 +1651,10 @@ class ModelsCommand extends Command */ protected function getUsedClassNames(ReflectionClass $reflection): array { + $context = $this->getDocBlockContext($reflection); $namespaceAliases = array_flip(array_map(function ($alias) { return ltrim($alias, '\\'); - }, (new ContextFactory())->createFromReflector($reflection)->getNamespaceAliases())); + }, $context->getNamespaceAliases())); $namespaceAliases[$reflection->getName()] = $reflection->getShortName(); return $namespaceAliases;