Compare commits

...
40 Commits
Author SHA1 Message Date
Barry vd. Heuvel eda37f3442 Catch PDO errors when getting drivers/connections 2013-07-12 14:39:12 +02:00
Barry vd. Heuvel e9cbd7e732 Allow 4.1 (and future version) 2013-07-04 14:30:33 +02:00
Barry vd. Heuvel ac6740f59f Change aliasing way back
Not really nice in NetBeans.
Also reference the calling class and show the implementing class in
comments (phpStorm will understand it anyways)
2013-07-04 14:26:17 +02:00
Barry vd. Heuvel 60ec740b15 Update CodeIntel link 2013-07-02 22:22:56 +02:00
Barry vd. Heuvel aedd2ee127 Get classes from managers 2013-07-02 22:13:47 +02:00
Barry vd. Heuvel 007a96ef3f Update way of creating aliases
Again.. Sublime didn't really understand it. Passing null as parameters
to avoid errors.
2013-07-02 21:10:55 +02:00
Barry vd. Heuvel 63b1026fc3 Update phpDocs 2013-06-28 14:29:11 +02:00
Barry vd. Heuvel d042c6ea8e Only scan public methods
__call magic kicks in if the function is protected.
2013-06-28 13:24:24 +02:00
Barry vd. Heuvel ae0dce2abd Remove static overrides, because Laravel fixed this. 2013-06-28 13:22:28 +02:00
Barry vd. Heuvel 7f17da57b2 Update readme 2013-06-24 14:51:08 +02:00
Barry vd. Heuvel 0f22941e51 Update readme 2013-06-24 14:48:16 +02:00
Barry vd. Heuvel f7f0e025f3 Add reset option for Model command 2013-06-24 14:48:10 +02:00
Barry vd. Heuvel 4790413752 Add poser badges 2013-06-23 14:11:13 +02:00
Barry vd. Heuvel 4f31e98467 Remove non-static 2013-06-22 13:07:27 +02:00
Barry vd. Heuvel 17ae13ce56 Update default text 2013-06-22 12:59:33 +02:00
Barry vd. Heuvel fedae6542b Change die (no more namespace) 2013-06-22 12:58:23 +02:00
Barry vd. Heuvel e8b1c367d0 Remove namespaces
As they aren't used.
If anyone does use them, let me know!
2013-06-22 12:56:00 +02:00
Barry vd. Heuvel 66feb564e1 Refactor 2013-06-22 12:54:45 +02:00
Barry vd. Heuvel 15bf867658 Extend instead of redefining functions
For methods that are not a facade (like Eloquent/Controller), avoids
duplicate code and better autocomplete (also variables etc).
No more need for extra config settings, only the magic calls still.
2013-06-21 11:01:13 +02:00
Barry vd. Heuvel c4de6e80c9 Remove nohelpers option 2013-06-18 15:45:10 +02:00
Barry vd. Heuvel 6f03c4c5ff Move some logic to ReflectionDocblock 2013-06-09 14:17:24 +02:00
Barry vd. Heuvel 8db4443879 Use fork of ReflectionDocblock
So I can use a stable version.. Fixes #21
2013-06-08 13:02:28 +02:00
Barry vd. Heuvel 1d01f5b278 Update Eloquent Builder 2013-06-07 12:26:54 +02:00
Barry vd. Heuvel 2466f5a5a4 Update readme 2013-06-07 11:33:12 +02:00
Barry vd. Heuvel bbbdd02708 Refactor and add comments 2013-06-07 11:26:57 +02:00
Barry vd. Heuvel d8a6bfbf21 Update readme 2013-06-06 15:13:02 +02:00
Barry vd. Heuvel ce4e9804ef Use full namespace 2013-06-06 13:48:53 +02:00
Barry vd. Heuvel 12845b38f0 Use declaring class
When function is inherited, link to the original class.
2013-06-06 13:45:32 +02:00
Barry vd. Heuvel 0b3b8b95cd Merge sublime and netbeans/phpstorm
Gives some warnings for phpStorm, but only in the helper file, so
doesn't affect the autocomplete / warnings in application code.
2013-06-06 13:45:05 +02:00
Barry vd. Heuvel 2ee05260d5 Simplify sublime output 2013-06-06 13:19:15 +02:00
Barry vd. Heuvel ec302acc3f Make __construct return @self 2013-06-05 17:45:24 +02:00
Barry vd. Heuvel e0b47835f4 roll back static for relations 2013-06-04 15:36:39 +02:00
Barry vd. Heuvel a0f6a370e1 Tweak return values 2013-06-04 15:34:56 +02:00
Barry vd. Heuvel 77c8bfa05a Fix default model path 2013-06-04 14:46:18 +02:00
Barry vd. Heuvel 62deba4171 Make builder work for relations
Fixes #22
2013-06-04 14:12:47 +02:00
Barry vd. Heuvel 32918908fc Add delete to non-static methods 2013-06-04 14:12:23 +02:00
Barry vd. Heuvel cca1b5896e Only allow relative path 2013-05-30 21:26:02 +02:00
Barry vd. Heuvel 3afc4a3ade Add dir option and fix namespace for models 2013-05-30 21:22:00 +02:00
Barry vd. Heuvel 3ac68d5446 Change order 2013-05-30 21:40:02 +03:00
Barry vd. Heuvel 26f09bccbf Throw error when compiled.php exists 2013-05-30 21:39:12 +03:00
5 changed files with 292 additions and 247 deletions
+5 -5
View File
@@ -11,11 +11,11 @@
], ],
"require": { "require": {
"php": ">=5.3.0", "php": ">=5.3.0",
"illuminate/support": "4.0.x", "illuminate/support": "4.x",
"illuminate/console": "4.0.x", "illuminate/console": "4.x",
"illuminate/filesystem": "4.0.x", "illuminate/filesystem": "4.x",
"phpdocumentor/reflection-docblock": "dev-master#6d705c1a0f9e2a6d73d2e9ec0e538b9dfaf4315f", "barryvdh/reflection-docblock": ">=2.0.1",
"symfony/class-loader": "2.3.*" "symfony/class-loader": "~2.3"
}, },
"autoload": { "autoload": {
"psr-0": { "psr-0": {
+33 -23
View File
@@ -1,19 +1,22 @@
## Laravel IDE Helper Generator ## Laravel IDE Helper Generator
[![Latest Stable Version](https://poser.pugx.org/barryvdh/laravel-ide-helper/version.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper) [![Total Downloads](https://poser.pugx.org/barryvdh/laravel-ide-helper/d/total.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
### Complete phpDocs, directly from the source ### Complete phpDocs, directly from the source
Add the helper file to your laravel folder (not in a public folder). The file isn't used by Laravel, but it has to be indexed by your IDE. This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are alway up-to-date.
If you don't want to generate it, you can add a pre-generated file to the root folder of your laravel project. (But this isn't as up-to-date as self generated files)
* Netbeans and PHPStorm version: https://gist.github.com/barryvdh/5227822 * Generated version: https://gist.github.com/barryvdh/5227822
* SublimeText CodeIntel version: https://gist.github.com/barryvdh/5227814
Note: You do need CodeIntel for Sublime Text: https://github.com/SublimeCodeIntel/SublimeCodeIntel
### Automatic phpDoc generation for Laravel Facades ### Automatic phpDoc generation for Laravel Facades
Require this package in your composer.json: Require this package in your composer.json and run composer update (or run `composer require barryvdh/laravel-ide-helper:1.*` directly):
"barryvdh/laravel-ide-helper": "1.*" "barryvdh/laravel-ide-helper": "1.*"
And add the ServiceProvider to the providers array in app/config/app.php After updating composer, add the ServiceProvider to the providers array in app/config/app.php
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
@@ -21,18 +24,14 @@ You can now re-generate the docs yourself (for future updates) in artisan
php artisan ide-helper:generate php artisan ide-helper:generate
If you use SublimeText CodeIntel, the format is a bit different. So add --sublime (or -S) to your command Note: bootstrap/compiled.php has to be cleared first, so run `php artisan clear-compiled` before generating (and `php artisan optimize` after..)
php artisan ide-helper:generate -S
Note: You do need CodeIntel for Sublime Text: https://github.com/Kronuz/SublimeCodeIntel
You can configure your composer.json to do this after each commit: You can configure your composer.json to do this after each commit:
"scripts":{ "scripts":{
"post-update-cmd":[ "post-update-cmd":[
"php artisan optimize",
"php artisan ide-helper:generate", "php artisan ide-helper:generate",
"php artisan optimize",
] ]
}, },
@@ -49,26 +48,37 @@ You can choose to include helper files. This is not enabled by default, but you
The Illuminate/Support/helpers.php is already set-up, but you can add/remove your own files in the config file. The Illuminate/Support/helpers.php is already set-up, but you can add/remove your own files in the config file.
### Work in progress: Model docs ### Automatic phpDocs for Models
If you don't want to write your properties yourself, you can use the (experimental) command `ide-helper:models` to generate If you don't want to write your properties yourself, you can use the command `ide-helper:models` to generate
phpDocs, based on table columns, relations and getters/setters. Still in beta, so please provide feedback if you want. phpDocs, based on table columns, relations and getters/setters. Still in beta, so please provide feedback if you want.
Docs are written to a phpfile (_ide_helper_models.php) in the root of the project, so you can move the docs to the real model. Docs are written to a phpfile (_ide_helper_models.php) in the root of the project, so you can move the docs to the real model.
You can now also write the comments directly to your Model file, using the -W argument. Please make sure to backup your models, before writing the info. You can now also write the comments directly to your Model file, using the `--write (-W)` option. Please make sure to backup your models, before writing the info.
It should keep the existing comments and only append new properties/methods. It should keep the existing comments and only append new properties/methods. The existing phpdoc is replaced, or added if not found.
With the `--reset (-R)` option, the existing phpdocs are ignored, only the newly found columns/relations are saved as phpdocs.
php artisan ide-helper:models Post
/**
* An Eloquent Model: 'Post'
*
* @property integer $id
* @property integer $author_id
* @property string $title
* @property string $text
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property-read \User $author
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
For now, only models in app/models are scanned. The optional argument tells what models to use (also outside app/models). For now, only models in app/models are scanned. The optional argument tells what models to use (also outside app/models).
`php artisan ide-helper:models Post,User`
Note: With namespaces, uses \\ instead of \ php artisan ide-helper:models Post,User
`php artisan ide-helper:models API\\User`
This creates a file with the phpDocs for each Model. You should check and change them to be more accurate.
Also, all relations are Eloquent|Eloquent[] by default, you can change them to the actual Model.
After copying the phpdocs to your model, you can clear the file, so your IDE only uses the real source.
Note: With namespaces, uses `\\` instead of `\`: `php artisan ide-helper:models API\\User`
### License ### License
The Laravel IDE Helper Generator is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) The Laravel IDE Helper Generator is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
+227 -161
View File
@@ -13,10 +13,10 @@ use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Illuminate\Foundation\AliasLoader; use Illuminate\Foundation\AliasLoader;
use phpDocumentor\Reflection\DocBlock; use Barryvdh\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context; use Barryvdh\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag; use Barryvdh\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer; use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
/** /**
* A command to generate autocomplete information for your IDE * A command to generate autocomplete information for your IDE
* *
@@ -39,10 +39,8 @@ class GeneratorCommand extends Command {
protected $description = 'Generate a new IDE Helper file.'; protected $description = 'Generate a new IDE Helper file.';
protected $extra; protected $extra;
protected $nonstatic;
protected $onlyExtend; protected $onlyExtend;
protected $helpers; protected $helpers;
protected $sublime;
/** /**
@@ -52,34 +50,33 @@ class GeneratorCommand extends Command {
*/ */
public function fire() public function fire()
{ {
$filename = $this->argument('filename'); if (file_exists($compiled = base_path().'/bootstrap/compiled.php')){
$this->error('Error generating IDE Helper: first delete bootstrap/compiled.php (php artisan clear-compiled)');
if($this->option('memory')){
$this->useMemoryDriver();
}
$this->extra = \Config::get('laravel-ide-helper::extra');
$this->nonstatic = \Config::get('laravel-ide-helper::nonstatic');
$this->onlyExtend = \Config::get('laravel-ide-helper::only_extend');
if( $this->option('helpers') || (\Config::get('laravel-ide-helper::include_helpers') && ! $this->option('nohelpers'))){
$this->helpers = \Config::get('laravel-ide-helper::helper_files');
}else{ }else{
$this->helpers = array(); $filename = $this->argument('filename');
}
if($this->option('memory')){
$this->useMemoryDriver();
}
$this->extra = \Config::get('laravel-ide-helper::extra');
$this->sublime = $this->option('sublime') || \Config::get('laravel-ide-helper::sublime'); if( $this->option('helpers') || (\Config::get('laravel-ide-helper::include_helpers') )){
$this->helpers = \Config::get('laravel-ide-helper::helper_files');
$content = $this->generateDocs(); }else{
$this->helpers = array();
$written = \File::put($filename, $content); }
if($written !== false){
$this->info("A new helper file was written to $filename");
}else{
$this->error("The helper file could not be created at $filename");
}
$content = $this->generateDocs();
$written = \File::put($filename, $content);
if($written !== false){
$this->info("A new helper file was written to $filename");
}else{
$this->error("The helper file could not be created at $filename");
}
}
} }
protected function useMemoryDriver(){ protected function useMemoryDriver(){
@@ -113,7 +110,7 @@ class GeneratorCommand extends Command {
return array( return array(
array('helpers', "H", InputOption::VALUE_NONE, 'Include the helper files'), array('helpers', "H", InputOption::VALUE_NONE, 'Include the helper files'),
array('memory', "M", InputOption::VALUE_NONE, 'Use sqlite memory driver'), array('memory', "M", InputOption::VALUE_NONE, 'Use sqlite memory driver'),
array('sublime', "S", InputOption::VALUE_NONE, 'Use different style for SublimeText CodeIntel'), array('sublime', "S", InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
); );
} }
@@ -133,103 +130,46 @@ class GeneratorCommand extends Command {
* *
* @author Barry vd. Heuvel <[email protected]> * @author Barry vd. Heuvel <[email protected]>
*/ */
namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n"; exit('Only to be used as an helper for your IDE');\n\n";
//Get all aliases
$aliases = $aliasLoader->getAliases(); $aliases = $aliasLoader->getAliases();
foreach($aliases as $alias => $facade){ foreach($aliases as $alias => $facade){
try{ $root = $this->getRoot($facade);
if(method_exists($facade, 'getFacadeRoot')){ if(!$root){
$root = get_class($facade::getFacadeRoot());
}else{
$root = $facade;
}
if(!class_exists($root) && !interface_exists($root)){
$this->error("Class $root is not found.");
continue;
}
}catch(\PDOException $e){
$this->error("PDOException: ".$e->getMessage()."\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade.");
continue;
}catch(\Exception $e){
$this->error("Exception: ".$e->getMessage()."\nSkipping $facade.");
continue; continue;
} }
if(strpos($alias, '\\') !== false){
$parts = explode('\\', $alias);
$alias = array_pop($parts);
$namespace = implode($parts, '\\');
}else{
$namespace = '';
}
try{ try{
$reflection = new \ReflectionClass($root);
$output .= "namespace $namespace {\n"; //Some classes extend the facade
if(class_exists($facade)){
if($root !== $facade or in_array($alias, $this->onlyExtend)){ $output .= "class $alias extends $facade{\n";
//If the root class is not the same as the facade extend it.
$output .= " class $alias extends $facade{\n";
}else{ }else{
$output .= " class $alias{\n"; $output .= "class $alias{\n";
} }
$output .= "\t/**\n\t * @var \\$root \$root\n\t */\n\t static private \$root;\n\n";
if(!in_array($alias, $this->onlyExtend)) $usedMethods = array();
{
$usedMethods = array(); //Only add the methods to the output when the root is not the same as the facade.
if(array_key_exists($alias, $this->nonstatic) ){ $addOutput = ($root !== $facade);
$nonstaticMethods = $this->nonstatic[$alias]; $output .= $this->getMethods($root, $alias, $usedMethods, $addOutput);
}else{
$nonstaticMethods = array();
}
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); $driver = $this->getDriver($alias);
if($methods) if($driver){
{ $output .= $this->getMethods($driver, $alias, $usedMethods);
foreach ($methods as $method)
{
if(!in_array($method->name, $usedMethods)){
$static = !in_array($method->name, $nonstaticMethods);
$output .= $this->parseMethod($method, $alias, $root, $static);
$usedMethods[] = $method->name;
}
}
}
if(array_key_exists($alias, $this->extra)){
$i = 2;
foreach($this->extra[$alias] as $extraClass){
if(!class_exists($extraClass) && !interface_exists($extraClass)){
continue;
}
$reflection = new \ReflectionClass($extraClass);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
if($methods)
{
$rootParam = "root".$i++;
$output .= "\t/**\n\t * @var \\$extraClass \$$rootParam\n\t */\n\t static private \$$rootParam;\n\n";
foreach ($methods as $method)
{
if(!in_array($method->name, $usedMethods)){
$static = !in_array($method->name, $nonstaticMethods);
$output .= $this->parseMethod($method, $alias, $extraClass, $static, $rootParam);
$usedMethods[] = $method->name;
}
}
}
}
}
} }
$output .= " }\n}\n\n";
//Add extra methods, from other classes (magic static calls)
if(array_key_exists($alias, $this->extra)){
$output .= $this->getMethods($this->extra[$alias], $alias, $usedMethods);
}
$output .= "}\n\n";
}catch(\Exception $e){ }catch(\Exception $e){
$this->error("Exception: ".$e->getMessage()."\nCould not analyze $root."); $this->error("Exception: ".$e->getMessage()."\nCould not analyze $root.");
@@ -237,6 +177,7 @@ namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n";
} }
//Include the helper file, if requested
if(!empty($helpers)){ if(!empty($helpers)){
foreach($helpers as $helper){ foreach($helpers as $helper){
if (file_exists($helper)){ if (file_exists($helper)){
@@ -249,26 +190,165 @@ namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n";
} }
/** /**
* @param \ReflectionMethod $method * Get the real root of a facade
* @param string $alias *
* @param string $root * @param $facade
* @param bool $static * @return bool|string
* @param string $rootParam */
protected function getRoot($facade){
try{
//If possible, get the facade root
if(method_exists($facade, 'getFacadeRoot')){
$root = get_class($facade::getFacadeRoot());
}else{
$root = $facade;
}
//If it doesn't exist, skip it
if(!class_exists($root) && !interface_exists($root)){
$this->error("Class $root is not found.");
return false;
}
return $root;
//When the database connection is not set, some classes will be skipped
}catch(\PDOException $e){
$this->error("PDOException: ".$e->getMessage()."\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade.");
return false;
}catch(\Exception $e){
$this->error("Exception: ".$e->getMessage()."\nSkipping $facade.");
return false;
}
}
public function getDriver($alias){
try{
if($alias == "Auth"){
$driver = \Auth::driver();
}elseif($alias == "DB"){
$driver = \DB::connection();
}elseif($alias == "Cache"){
$driver = \Cache::driver();
}elseif($alias == "Queue"){
$driver = \Queue::connection();
}else{
return false;
}
return get_class($driver);
}catch(\Exception $e){
$this->error("Could not determine driver/connection for $alias.");
return false;
}
}
/**
* Get the methods for one or multiple classes.
*
* @param $classes
* @param $alias
* @param $usedMethods
* @param bool $addOutput
* @return string * @return string
*/ */
protected function parseMethod($method, $alias, $root, $static = true, $rootParam = 'root'){ protected function getMethods($classes, $alias, &$usedMethods, $addOutput = true){
if(!is_array($classes)){
$classes = array($classes);
}
$output = ''; $output = '';
foreach($classes as $class){
if(!class_exists($class) && !interface_exists($class)){
continue;
}
$reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
if($methods)
{
foreach ($methods as $method)
{
if(!in_array($method->name, $usedMethods)){
if( $addOutput){
$output .= $this->parseMethod($method, $alias, $reflection);
}
$usedMethods[] = $method->name;
}
}
}
}
return $output;
}
/**
* @param \ReflectionMethod $method
* @param string $alias
* @return string
*/
protected function parseMethod($method, $alias, $class){
$output = '';
// Don't add the __clone() functions
if($method->name === '__clone'){ if($method->name === '__clone'){
return $output; return $output;
} }
$namespace = $method->getDeclaringClass()->getNamespaceName(); $namespace = $method->getDeclaringClass()->getNamespaceName();
//Create a DocBlock and serializer instance
$phpdoc = new DocBlock($method, new Context($namespace)); $phpdoc = new DocBlock($method, new Context($namespace));
$serializer = new DocBlockSerializer(1, "\t"); $serializer = new DocBlockSerializer(1, "\t");
//Normalize the description and inherit the docs from parents/interfaces
$this->normalizeDescription($phpdoc, $method);
//Correct the return values
$returnValue = $this->normalizeReturn($phpdoc, $method, $alias);
//Get the parameters, including formatted default values
list($params, $paramsWithDefault) = $this->getParameters($method);
//Make the method static
$phpdoc->appendTag(Tag::createInstance('@static', $phpdoc));
//Write the output, using the DocBlock serializer
$output .= $serializer->getDocComment($phpdoc) ."\n\t public static function ".$method->name."(";
$output .= implode($paramsWithDefault, ", ");
$output .= "){\r\n";
//Only return when not a constructor and not void.
$return = ($returnValue && $returnValue !== "void" && $method->name !== "__construct") ? 'return' : '';
//Reference the 'real' function in the declaringclass
$declaringClass = $method->getDeclaringClass();
$root = $class->getName();
if($declaringClass->name != $root){
$output .= "\t\t//Method inherited from $declaringClass->name\r\n";
}
$output .= "\t\t$return $root::";
//Write the default parameters in the function call
$output .= $method->name."(".implode($params, ", ").");\r\n";
$output .= "\t }\n\n";
return $output;
}
/**
* Get the description and get the inherited docs.
*
* @param $phpdoc
* @param $method
*/
protected function normalizeDescription(&$phpdoc, $method){
//Get the short + long description from the DocBlock
$description = $phpdoc->getText(); $description = $phpdoc->getText();
//Loop through parents/interfaces, to fill in {@inheritdoc}
if(strpos($description, '{@inheritdoc}') !== false){ if(strpos($description, '{@inheritdoc}') !== false){
$inheritdoc = $this->getInheritDoc($method); $inheritdoc = $this->getInheritDoc($method);
$inheritDescription = $inheritdoc->getText(); $inheritDescription = $inheritdoc->getText();
@@ -276,6 +356,7 @@ namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n";
$description = str_replace('{@inheritdoc}', $inheritDescription, $description); $description = str_replace('{@inheritdoc}', $inheritDescription, $description);
$phpdoc->setText($description); $phpdoc->setText($description);
//Add the tags that are inherited
$inheritTags = $inheritdoc->getTags(); $inheritTags = $inheritdoc->getTags();
if($inheritTags){ if($inheritTags){
foreach($inheritTags as $tag){ foreach($inheritTags as $tag){
@@ -284,45 +365,43 @@ namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n";
} }
} }
} }
}
$phpdoc->appendTag(Tag::createInstance('@static', $phpdoc)); /**
* Make some changes to the return types, if needed.
//Looping through the parameters and re-setting the type, to get the expanded type (with namespace) *
//Should be fixed in a future version of ReflectionDocBlock I hope.. * @param $phpdoc
$paramTags = $phpdoc->getTagsByName('param'); * @param $method
if($paramTags){ * @param $alias
/** @var $tag */ * @return null
foreach($paramTags as $tag){ */
$content = $tag->getContent(); protected function normalizeReturn(&$phpdoc, $method, $alias){
//Closure should be \Closure.. //Get the return type and adjust them for beter autocomplete
$content = str_replace('\Closure', 'Closure', $content);
$content = str_replace('Closure', '\Closure', $content);
$tag->setContent($content);
$tag->setContent($tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription());
}
}
$returnTags = $phpdoc->getTagsByName('return'); $returnTags = $phpdoc->getTagsByName('return');
if($returnTags){ if($returnTags){
/** @var $tag */ /** @var $tag */
$tag = reset($returnTags); $tag = reset($returnTags);
$returnValue = $tag->getType(); $returnValue = $tag->getType();
if(!$this->sublime and $alias == 'Eloquent' and if($method->name == "__construct"){
(in_array($method->name, array('pluck', 'first', 'fill', 'newInstance', 'newFromBuilder', 'create', 'find', 'findOrFail')) $tag->setType('self');
or $returnValue === '\Illuminate\Database\Query\Builder')){ }elseif($alias == 'Eloquent' and in_array($method->name, array('hasOne', 'hasMany', 'belongsTo', 'belongsToMany', 'morphOne', 'morphTo', 'morphMany'))){
//Reference the calling class, to provide more accurate auto-complete $tag->addType('\Eloquent');
$returnValue = "static";
}elseif(!$this->sublime and $alias == 'Eloquent' and in_array($method->name, array('all', 'get'))){
$returnValue .= "|\Eloquent[]|static[]";
} }
$tag->setContent($returnValue . " ". $tag->getDescription());
}else{ }else{
$returnValue = null; $returnValue = null;
} }
return $returnValue;
}
$output .= $serializer->getDocComment($phpdoc) ."\n\t public ".($static ? 'static' : '')." function ".$method->name."("; /**
* Get the parameters and format them correctly
*
* @param $method
* @return array
*/
public function getParameters($method){
//Loop through the default values for paremeters, and make the correct output string
$params = array(); $params = array();
$paramsWithDefault = array(); $paramsWithDefault = array();
foreach ($method->getParameters() as $param) { foreach ($method->getParameters() as $param) {
@@ -345,21 +424,7 @@ namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n";
} }
$paramsWithDefault[] = $paramStr; $paramsWithDefault[] = $paramStr;
} }
$output .= implode($paramsWithDefault, ", "); return array($params, $paramsWithDefault);
$output .= "){\r\n";
$return = ($returnValue && $returnValue !== "void") ? 'return' : '';
if($this->sublime){
$output .= "\t\t\$$rootParam = new $root();\r\n";
$output .= "\t\t$return \$$rootParam->";
}else{
$output .= "\t\t$return static::\$$rootParam->";
}
$output .= $method->name."(".implode($params, ", ").");\r\n";
$output .= "\t }\n\n";
return $output;
} }
/** /**
@@ -369,6 +434,7 @@ namespace {\n\tdie('Only to be used as an helper for your IDE');\n}\n\n";
protected function getInheritDoc($reflectionMethod){ protected function getInheritDoc($reflectionMethod){
$parentClass = $reflectionMethod->getDeclaringClass()->getParentClass(); $parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
//Get either a parent or the interface
if($parentClass){ if($parentClass){
$method = $parentClass->getMethod($reflectionMethod->getName()); $method = $parentClass->getMethod($reflectionMethod->getName());
}else{ }else{
+26 -14
View File
@@ -13,10 +13,10 @@ use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\ClassLoader\ClassMapGenerator; use Symfony\Component\ClassLoader\ClassMapGenerator;
use phpDocumentor\Reflection\DocBlock; use Barryvdh\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context; use Barryvdh\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag; use Barryvdh\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer; use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
/** /**
* A command to generate autocomplete information for your IDE * A command to generate autocomplete information for your IDE
* *
@@ -40,8 +40,9 @@ class ModelsCommand extends Command {
protected $properties = array(); protected $properties = array();
protected $methods = array(); protected $methods = array();
protected $write = false; protected $write = false;
protected $dir;
protected $reset;
@@ -54,7 +55,9 @@ class ModelsCommand extends Command {
{ {
$filename = $this->option('filename'); $filename = $this->option('filename');
$this->write = $this->option('write'); $this->write = $this->option('write');
$this->dir = $this->option('dir');
$model = $this->argument('model'); $model = $this->argument('model');
$this->reset = $this->option('reset');
$content = $this->generateDocs($model); $content = $this->generateDocs($model);
@@ -67,8 +70,6 @@ class ModelsCommand extends Command {
} }
} }
} }
@@ -94,7 +95,9 @@ class ModelsCommand extends Command {
{ {
return array( return array(
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file', '_ide_helper_models.php'), array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file', '_ide_helper_models.php'),
array('dir', 'D', InputOption::VALUE_OPTIONAL, 'The model dir','app/models'),
array('write', 'W', InputOption::VALUE_NONE, 'Write to Model file'), array('write', 'W', InputOption::VALUE_NONE, 'Write to Model file'),
array('reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'),
); );
} }
@@ -141,9 +144,12 @@ class ModelsCommand extends Command {
protected function loadModels(){ protected function loadModels(){
$dir = base_path().'/'.$this->dir;
$models = array(); $models = array();
foreach(ClassMapGenerator::createMap(app_path().'/models') as $model=> $path){ if(file_exists($dir)){
$models[] = $model; foreach(ClassMapGenerator::createMap($dir) as $model=> $path){
$models[] = $model;
}
} }
return $models; return $models;
} }
@@ -305,11 +311,17 @@ class ModelsCommand extends Command {
$reflection = new \ReflectionClass($class); $reflection = new \ReflectionClass($class);
$namespace = $reflection->getNamespaceName(); $namespace = $reflection->getNamespaceName();
$classname = $reflection->getShortName();
$originalDoc = $reflection->getDocComment(); $originalDoc = $reflection->getDocComment();
$phpdoc = new DocBlock($reflection, new Context($namespace));
if($this->reset){
$phpdoc = new DocBlock('', new Context($namespace));
}else{
$phpdoc = new DocBlock($reflection, new Context($namespace));
}
if(!$phpdoc->getText()){ if(!$phpdoc->getText()){
$phpdoc->setText("Generated properties for $class"); $phpdoc->setText("An Eloquent Model: '$class'");
} }
$properties = array(); $properties = array();
@@ -359,8 +371,8 @@ class ModelsCommand extends Command {
if($originalDoc){ if($originalDoc){
$contents = str_replace($originalDoc, $docComment, $contents); $contents = str_replace($originalDoc, $docComment, $contents);
}else{ }else{
$needle = "class {$class}"; $needle = "class {$classname}";
$replace = "{$docComment}\nclass {$class}"; $replace = "{$docComment}\nclass {$classname}";
$pos = strpos($contents,$needle); $pos = strpos($contents,$needle);
if ($pos !== false) { if ($pos !== false) {
$contents = substr_replace($contents,$replace,$pos,strlen($needle)); $contents = substr_replace($contents,$replace,$pos,strlen($needle));
@@ -371,7 +383,7 @@ class ModelsCommand extends Command {
} }
} }
$output = "namespace {$namespace}{\n{$docComment}\n\tclass {$class} {}\n}\n\n"; $output = "namespace {$namespace}{\n{$docComment}\n\tclass {$classname} {}\n}\n\n";
return $output; return $output;
} }
+1 -44
View File
@@ -13,18 +13,6 @@ return array(
'filename' => '_ide_helper.php', 'filename' => '_ide_helper.php',
/*
|--------------------------------------------------------------------------
| Sublime version
|--------------------------------------------------------------------------
|
| Use a different code format, better for SublimeText (instead of Netbeans/phpStorm)
| Can also be used with the --sublime (-S) option.
|
*/
'sublime' => false,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Helper files to include | Helper files to include
@@ -52,38 +40,7 @@ return array(
*/ */
'extra' => array( 'extra' => array(
'Auth' => array('Illuminate\Auth\Guard'), 'Eloquent' => array('Illuminate\Database\Eloquent\Builder', 'Illuminate\Database\Query\Builder'),
'Cache' => array('Illuminate\Cache\StoreInterface', 'Illuminate\Cache\Repository'),
'DB' => array('Illuminate\Database\Connection'),
'Eloquent' => array('Illuminate\Database\Query\Builder'),
'Queue' => array('Illuminate\Queue\QueueInterface'),
),
/*
|--------------------------------------------------------------------------
| Non-static methods
|--------------------------------------------------------------------------
|
| These functions aren't actually facade calls, so don't make them static
|
*/
'nonstatic' => array(
'Eloquent' => array('freshTimestamp', 'newCollection', 'toArray', 'toJson', 'toSql'),
),
/*
|--------------------------------------------------------------------------
| Only extend
|--------------------------------------------------------------------------
|
| These implementations aren't called static, so only extend them.
|
*/
'only_extend' => array(
'Seeder',
), ),
); );