{"action":"created","comment":{"url":"https://api.github.com/repos/symfony/symfony/pulls/comments/41006571","id":41006571,"diff_hunk":"@@ -0,0 +1,253 @@\n+<?php\n+\n+/*\n+ * This file is part of the Symfony package.\n+ *\n+ * (c) Fabien Potencier <fabien@symfony.com>\n+ *\n+ * For the full copyright and license information, please view the LICENSE\n+ * file that was distributed with this source code.\n+ */\n+\n+namespace Symfony\\Component\\DependencyInjection\\Compiler;\n+\n+use Symfony\\Component\\DependencyInjection\\ContainerBuilder;\n+use Symfony\\Component\\DependencyInjection\\Definition;\n+use Symfony\\Component\\DependencyInjection\\Exception\\RuntimeException;\n+use Symfony\\Component\\DependencyInjection\\Reference;\n+\n+/**\n+ * Guesses constructor arguments of services definitions and try to instantiate services if necessary.\n+ *\n+ * @author Kévin Dunglas <dunglas@gmail.com>\n+ */\n+class AutowirePass implements CompilerPassInterface\n+{\n+    private $container;\n+    private $reflectionClasses = array();\n+    private $definedTypes = array();\n+    private $types;\n+    private $notGuessableTypes = array();\n+\n+    /**\n+     * {@inheritdoc}\n+     */\n+    public function process(ContainerBuilder $container)\n+    {\n+        $this->container = $container;\n+        foreach ($container->getDefinitions() as $id => $definition) {\n+            if ($definition->isAutowired()) {\n+                $this->completeDefinition($id, $definition);\n+            }\n+        }\n+\n+        // Free memory and remove circular reference to container\n+        $this->container = null;\n+        $this->reflectionClasses = array();\n+        $this->definedTypes = array();\n+        $this->types = null;\n+        $this->notGuessableTypes = array();\n+    }\n+\n+    /**\n+     * Wires the given definition.\n+     *\n+     * @param string     $id\n+     * @param Definition $definition\n+     *\n+     * @throws RuntimeException\n+     */\n+    private function completeDefinition($id, Definition $definition)\n+    {\n+        if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {\n+            return;\n+        }\n+\n+        $this->container->addClassResource($reflectionClass);\n+\n+        if (!$constructor = $reflectionClass->getConstructor()) {\n+            return;\n+        }\n+\n+        $arguments = $definition->getArguments();\n+        foreach ($constructor->getParameters() as $index => $parameter) {\n+            if (!$typeHint = $parameter->getClass()) {","path":"src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php","position":74,"original_position":74,"commit_id":"3b7f5538643a5b25e8e5c4060a50826fc34d59f9","original_commit_id":"3b7f5538643a5b25e8e5c4060a50826fc34d59f9","user":{"login":"stof","id":439401,"avatar_url":"https://avatars.githubusercontent.com/u/439401?v=3","gravatar_id":"","url":"https://api.github.com/users/stof","html_url":"https://github.com/stof","followers_url":"https://api.github.com/users/stof/followers","following_url":"https://api.github.com/users/stof/following{/other_user}","gists_url":"https://api.github.com/users/stof/gists{/gist_id}","starred_url":"https://api.github.com/users/stof/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stof/subscriptions","organizations_url":"https://api.github.com/users/stof/orgs","repos_url":"https://api.github.com/users/stof/repos","events_url":"https://api.github.com/users/stof/events{/privacy}","received_events_url":"https://api.github.com/users/stof/received_events","type":"User","site_admin":false},"body":"the case of non-existent classes still need to be handled","created_at":"2015-10-02T09:54:33Z","updated_at":"2015-10-02T09:54:33Z","html_url":"https://github.com/symfony/symfony/pull/15613#discussion_r41006571","pull_request_url":"https://api.github.com/repos/symfony/symfony/pulls/15613","_links":{"self":{"href":"https://api.github.com/repos/symfony/symfony/pulls/comments/41006571"},"html":{"href":"https://github.com/symfony/symfony/pull/15613#discussion_r41006571"},"pull_request":{"href":"https://api.github.com/repos/symfony/symfony/pulls/15613"}}},"pull_request":{"url":"https://api.github.com/repos/symfony/symfony/pulls/15613","id":43281728,"html_url":"https://github.com/symfony/symfony/pull/15613","diff_url":"https://github.com/symfony/symfony/pull/15613.diff","patch_url":"https://github.com/symfony/symfony/pull/15613.patch","issue_url":"https://api.github.com/repos/symfony/symfony/issues/15613","number":15613,"state":"open","locked":false,"title":"[DependencyInjection] Add autowiring capabilities","user":{"login":"dunglas","id":57224,"avatar_url":"https://avatars.githubusercontent.com/u/57224?v=3","gravatar_id":"","url":"https://api.github.com/users/dunglas","html_url":"https://github.com/dunglas","followers_url":"https://api.github.com/users/dunglas/followers","following_url":"https://api.github.com/users/dunglas/following{/other_user}","gists_url":"https://api.github.com/users/dunglas/gists{/gist_id}","starred_url":"https://api.github.com/users/dunglas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dunglas/subscriptions","organizations_url":"https://api.github.com/users/dunglas/orgs","repos_url":"https://api.github.com/users/dunglas/repos","events_url":"https://api.github.com/users/dunglas/events{/privacy}","received_events_url":"https://api.github.com/users/dunglas/received_events","type":"User","site_admin":false},"body":"| Q             | A\r\n| ------------- | ---\r\n| Bug fix?      | no\r\n| New feature?  | yes\r\n| BC breaks?    | no\r\n| Deprecations? | no\r\n| Tests pass?   | yes\r\n| Fixed tickets | n/a\r\n| License       | MIT\r\n| Doc PR        | not yet\r\n\r\nThis PR adds autowiring capabilities to the Dependency Injection component. It eases service registration by letting the component guessing dependencies to inject and even (under certain conditions) registering them using typehints of the constructor parameters.\r\n\r\nThe following usages are supported:\r\n\r\n# Automatic dependency registration\r\n\r\n```php\r\nclass Foo\r\n{\r\n}\r\n\r\nclass Bar\r\n{\r\n    public function __construct(Foo $f)\r\n    {\r\n    }\r\n}\r\n```\r\n\r\n```yaml\r\nservices:\r\n    bar:\r\n        class: Bar\r\n        autowire: true\r\n```\r\n\r\nIt will register `Foo` as a private service (`autowired.foo`) and injects it as the first argument of the `bar` constructor.\r\nThis method works only for typehints corresponding to instantiable classes (interfaces and abstract classes are not supported).\r\n\r\n# Autocompletion of definition arguments\r\n\r\n```php\r\ninterface A\r\n{\r\n}\r\n\r\ninterface B extends A\r\n{\r\n}\r\n\r\nclass Foo implements B\r\n{\r\n}\r\n\r\nclass Bar\r\n{\r\n}\r\n\r\nclass Baz extends Bar\r\n{\r\n}\r\n\r\nclass LesTilleuls\r\n{\r\n    public function __construct(A $a, Bar $bar)\r\n    {\r\n    }\r\n}\r\n```\r\n\r\n```yaml\r\nservices:\r\n    foo:\r\n        class: Foo\r\n\r\n    baz:\r\n        class: Baz\r\n\r\n    les_tilleuls:\r\n        class: LesTilleuls\r\n        autowire: true\r\n```\r\n\r\nThe autowiring system will find types of all services and completes constructor arguments of the `les_tilleuls` service definition using typehints.\r\n\r\nIt works only if there is one service registered for a given type (if there are several services available for the same type and no explicit type definition, a `RuntimeException` is thrown).\r\n\r\n# Explicit type definition\r\n\r\n```php\r\ninterface A\r\n{\r\n}\r\n\r\nclass A1 implements A\r\n{\r\n}\r\n\r\nclass A2 implements A\r\n{\r\n}\r\n\r\nclass B\r\n{\r\n     public function __construct(A $a)\r\n     {\r\n     }\r\n}\r\n```\r\n\r\n```yaml\r\nservices:\r\n    a1:\r\n        class: A1\r\n        types: [ A ]\r\n\r\n    a2:\r\n        class: A2\r\n\r\n    # Will be autowired with A1\r\n    class b:\r\n        class: B\r\n        autowire: true\r\n\r\n    # Not autowired\r\n    class another_b:\r\n        class: B\r\n        arguments: [ @a2 ]\r\n        autowire: true\r\n```\r\n\r\nWhen a service is explicitly associated with a type, it is always used to fill a definition depending of this type, even if several services have this type. If several services are associated with the same type, the last definition takes the priority.\r\n\r\nOf course explicit definitions are still supported.\r\nYAML, XML and PHP loaders have been updated to supports the new `type` parameter.","created_at":"2015-08-25T12:53:02Z","updated_at":"2015-10-02T09:54:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"550d490b2601a17f7d5932f67fa614ad507f8fad","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/symfony/symfony/pulls/15613/commits","review_comments_url":"https://api.github.com/repos/symfony/symfony/pulls/15613/comments","review_comment_url":"https://api.github.com/repos/symfony/symfony/pulls/comments{/number}","comments_url":"https://api.github.com/repos/symfony/symfony/issues/15613/comments","statuses_url":"https://api.github.com/repos/symfony/symfony/statuses/3b7f5538643a5b25e8e5c4060a50826fc34d59f9","head":{"label":"dunglas:autowiring","ref":"autowiring","sha":"3b7f5538643a5b25e8e5c4060a50826fc34d59f9","user":{"login":"dunglas","id":57224,"avatar_url":"https://avatars.githubusercontent.com/u/57224?v=3","gravatar_id":"","url":"https://api.github.com/users/dunglas","html_url":"https://github.com/dunglas","followers_url":"https://api.github.com/users/dunglas/followers","following_url":"https://api.github.com/users/dunglas/following{/other_user}","gists_url":"https://api.github.com/users/dunglas/gists{/gist_id}","starred_url":"https://api.github.com/users/dunglas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dunglas/subscriptions","organizations_url":"https://api.github.com/users/dunglas/orgs","repos_url":"https://api.github.com/users/dunglas/repos","events_url":"https://api.github.com/users/dunglas/events{/privacy}","received_events_url":"https://api.github.com/users/dunglas/received_events","type":"User","site_admin":false},"repo":{"id":1124839,"name":"symfony","full_name":"dunglas/symfony","owner":{"login":"dunglas","id":57224,"avatar_url":"https://avatars.githubusercontent.com/u/57224?v=3","gravatar_id":"","url":"https://api.github.com/users/dunglas","html_url":"https://github.com/dunglas","followers_url":"https://api.github.com/users/dunglas/followers","following_url":"https://api.github.com/users/dunglas/following{/other_user}","gists_url":"https://api.github.com/users/dunglas/gists{/gist_id}","starred_url":"https://api.github.com/users/dunglas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dunglas/subscriptions","organizations_url":"https://api.github.com/users/dunglas/orgs","repos_url":"https://api.github.com/users/dunglas/repos","events_url":"https://api.github.com/users/dunglas/events{/privacy}","received_events_url":"https://api.github.com/users/dunglas/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dunglas/symfony","description":"The Symfony2 PHP framework (PHP 5.3 only -- not yet stable) -- documentation for master is at http://docs.symfony-reloaded.org/master/","fork":true,"url":"https://api.github.com/repos/dunglas/symfony","forks_url":"https://api.github.com/repos/dunglas/symfony/forks","keys_url":"https://api.github.com/repos/dunglas/symfony/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dunglas/symfony/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dunglas/symfony/teams","hooks_url":"https://api.github.com/repos/dunglas/symfony/hooks","issue_events_url":"https://api.github.com/repos/dunglas/symfony/issues/events{/number}","events_url":"https://api.github.com/repos/dunglas/symfony/events","assignees_url":"https://api.github.com/repos/dunglas/symfony/assignees{/user}","branches_url":"https://api.github.com/repos/dunglas/symfony/branches{/branch}","tags_url":"https://api.github.com/repos/dunglas/symfony/tags","blobs_url":"https://api.github.com/repos/dunglas/symfony/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dunglas/symfony/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dunglas/symfony/git/refs{/sha}","trees_url":"https://api.github.com/repos/dunglas/symfony/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dunglas/symfony/statuses/{sha}","languages_url":"https://api.github.com/repos/dunglas/symfony/languages","stargazers_url":"https://api.github.com/repos/dunglas/symfony/stargazers","contributors_url":"https://api.github.com/repos/dunglas/symfony/contributors","subscribers_url":"https://api.github.com/repos/dunglas/symfony/subscribers","subscription_url":"https://api.github.com/repos/dunglas/symfony/subscription","commits_url":"https://api.github.com/repos/dunglas/symfony/commits{/sha}","git_commits_url":"https://api.github.com/repos/dunglas/symfony/git/commits{/sha}","comments_url":"https://api.github.com/repos/dunglas/symfony/comments{/number}","issue_comment_url":"https://api.github.com/repos/dunglas/symfony/issues/comments{/number}","contents_url":"https://api.github.com/repos/dunglas/symfony/contents/{+path}","compare_url":"https://api.github.com/repos/dunglas/symfony/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dunglas/symfony/merges","archive_url":"https://api.github.com/repos/dunglas/symfony/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dunglas/symfony/downloads","issues_url":"https://api.github.com/repos/dunglas/symfony/issues{/number}","pulls_url":"https://api.github.com/repos/dunglas/symfony/pulls{/number}","milestones_url":"https://api.github.com/repos/dunglas/symfony/milestones{/number}","notifications_url":"https://api.github.com/repos/dunglas/symfony/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dunglas/symfony/labels{/name}","releases_url":"https://api.github.com/repos/dunglas/symfony/releases{/id}","created_at":"2010-11-30T08:18:04Z","updated_at":"2014-06-03T21:19:58Z","pushed_at":"2015-10-02T09:51:06Z","git_url":"git://github.com/dunglas/symfony.git","ssh_url":"git@github.com:dunglas/symfony.git","clone_url":"https://github.com/dunglas/symfony.git","svn_url":"https://github.com/dunglas/symfony","homepage":"http://www.symfony-project.org/","size":61122,"stargazers_count":1,"watchers_count":1,"language":"PHP","has_issues":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"symfony:2.8","ref":"2.8","sha":"56fa973514d2e008a2c1835cae525c0065fccccf","user":{"login":"symfony","id":143937,"avatar_url":"https://avatars.githubusercontent.com/u/143937?v=3","gravatar_id":"","url":"https://api.github.com/users/symfony","html_url":"https://github.com/symfony","followers_url":"https://api.github.com/users/symfony/followers","following_url":"https://api.github.com/users/symfony/following{/other_user}","gists_url":"https://api.github.com/users/symfony/gists{/gist_id}","starred_url":"https://api.github.com/users/symfony/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/symfony/subscriptions","organizations_url":"https://api.github.com/users/symfony/orgs","repos_url":"https://api.github.com/users/symfony/repos","events_url":"https://api.github.com/users/symfony/events{/privacy}","received_events_url":"https://api.github.com/users/symfony/received_events","type":"Organization","site_admin":false},"repo":{"id":458058,"name":"symfony","full_name":"symfony/symfony","owner":{"login":"symfony","id":143937,"avatar_url":"https://avatars.githubusercontent.com/u/143937?v=3","gravatar_id":"","url":"https://api.github.com/users/symfony","html_url":"https://github.com/symfony","followers_url":"https://api.github.com/users/symfony/followers","following_url":"https://api.github.com/users/symfony/following{/other_user}","gists_url":"https://api.github.com/users/symfony/gists{/gist_id}","starred_url":"https://api.github.com/users/symfony/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/symfony/subscriptions","organizations_url":"https://api.github.com/users/symfony/orgs","repos_url":"https://api.github.com/users/symfony/repos","events_url":"https://api.github.com/users/symfony/events{/privacy}","received_events_url":"https://api.github.com/users/symfony/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/symfony/symfony","description":"The Symfony PHP framework","fork":false,"url":"https://api.github.com/repos/symfony/symfony","forks_url":"https://api.github.com/repos/symfony/symfony/forks","keys_url":"https://api.github.com/repos/symfony/symfony/keys{/key_id}","collaborators_url":"https://api.github.com/repos/symfony/symfony/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/symfony/symfony/teams","hooks_url":"https://api.github.com/repos/symfony/symfony/hooks","issue_events_url":"https://api.github.com/repos/symfony/symfony/issues/events{/number}","events_url":"https://api.github.com/repos/symfony/symfony/events","assignees_url":"https://api.github.com/repos/symfony/symfony/assignees{/user}","branches_url":"https://api.github.com/repos/symfony/symfony/branches{/branch}","tags_url":"https://api.github.com/repos/symfony/symfony/tags","blobs_url":"https://api.github.com/repos/symfony/symfony/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/symfony/symfony/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/symfony/symfony/git/refs{/sha}","trees_url":"https://api.github.com/repos/symfony/symfony/git/trees{/sha}","statuses_url":"https://api.github.com/repos/symfony/symfony/statuses/{sha}","languages_url":"https://api.github.com/repos/symfony/symfony/languages","stargazers_url":"https://api.github.com/repos/symfony/symfony/stargazers","contributors_url":"https://api.github.com/repos/symfony/symfony/contributors","subscribers_url":"https://api.github.com/repos/symfony/symfony/subscribers","subscription_url":"https://api.github.com/repos/symfony/symfony/subscription","commits_url":"https://api.github.com/repos/symfony/symfony/commits{/sha}","git_commits_url":"https://api.github.com/repos/symfony/symfony/git/commits{/sha}","comments_url":"https://api.github.com/repos/symfony/symfony/comments{/number}","issue_comment_url":"https://api.github.com/repos/symfony/symfony/issues/comments{/number}","contents_url":"https://api.github.com/repos/symfony/symfony/contents/{+path}","compare_url":"https://api.github.com/repos/symfony/symfony/compare/{base}...{head}","merges_url":"https://api.github.com/repos/symfony/symfony/merges","archive_url":"https://api.github.com/repos/symfony/symfony/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/symfony/symfony/downloads","issues_url":"https://api.github.com/repos/symfony/symfony/issues{/number}","pulls_url":"https://api.github.com/repos/symfony/symfony/pulls{/number}","milestones_url":"https://api.github.com/repos/symfony/symfony/milestones{/number}","notifications_url":"https://api.github.com/repos/symfony/symfony/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/symfony/symfony/labels{/name}","releases_url":"https://api.github.com/repos/symfony/symfony/releases{/id}","created_at":"2010-01-04T14:21:21Z","updated_at":"2015-10-02T09:43:10Z","pushed_at":"2015-10-02T09:51:08Z","git_url":"git://github.com/symfony/symfony.git","ssh_url":"git@github.com:symfony/symfony.git","clone_url":"https://github.com/symfony/symfony.git","svn_url":"https://github.com/symfony/symfony","homepage":"symfony.com","size":250257,"stargazers_count":10880,"watchers_count":10880,"language":"PHP","has_issues":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":4283,"mirror_url":null,"open_issues_count":889,"forks":4283,"open_issues":889,"watchers":10880,"default_branch":"2.8"}},"_links":{"self":{"href":"https://api.github.com/repos/symfony/symfony/pulls/15613"},"html":{"href":"https://github.com/symfony/symfony/pull/15613"},"issue":{"href":"https://api.github.com/repos/symfony/symfony/issues/15613"},"comments":{"href":"https://api.github.com/repos/symfony/symfony/issues/15613/comments"},"review_comments":{"href":"https://api.github.com/repos/symfony/symfony/pulls/15613/comments"},"review_comment":{"href":"https://api.github.com/repos/symfony/symfony/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/symfony/symfony/pulls/15613/commits"},"statuses":{"href":"https://api.github.com/repos/symfony/symfony/statuses/3b7f5538643a5b25e8e5c4060a50826fc34d59f9"}}}}