Repository: phpactor/phpactor (php)

Issue:
Wrong type inference for method
![image](https://user-images.githubusercontent.com/530801/218338535-06e3c181-8d8b-49f4-a66d-8fd2f3f15926.png)

for:

```
    /**
     * @return DocblockBuilder<$this>
     */
    public function docblock(): DocblockBuilder
    {
        return $this->docblockBuilder;
    }

````



Pull request description:
gh-2092: fix $this when used as generic argument
fixes #2092 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 45194f3b..3fcf72b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ Changelog
 Bug fixes:
 
   - Specify maximimum size (255 chars) for string literal types #2144
+  - Fix docblock parser with `$this` when used as generic argument #2092
 
 ## 2023.04.10
 
diff --git a/lib/DocblockParser/Parser.php b/lib/DocblockParser/Parser.php
index c5b626b8..f8995524 100644
--- a/lib/DocblockParser/Parser.php
+++ b/lib/DocblockParser/Parser.php
@@ -306,6 +306,9 @@ final class Parser
         if ($this->tokens->current->type === Token::T_BRACKET_ANGLE_OPEN) {
             $open = $this->tokens->chomp();
             $typeList = null;
+            if ($this->tokens->if(Token::T_VARIABLE)) {
+                $typeList = $this->parseTypeList();
+            }
             if ($this->tokens->if(Token::T_LABEL)) {
                 $typeList = $this->parseTypeList();
             }
@@ -424,6 +427,8 @@ final class Parser
                 $types[] = $this->parseTypes();
             } elseif ($this->tokens->if(Token::T_INTEGER)) {
                 $types[] = $this->parseTypes();
+            } elseif ($this->tokens->if(Token::T_VARIABLE)) {
+                $types[] = $this->parseTypes();
             }
             if ($this->tokens->if(Token::T_COMMA)) {
                 $types[] = $this->tokens->chomp();


Test patch:
diff --git a/lib/DocblockParser/Tests/Unit/Printer/examples/generic_this.test b/lib/DocblockParser/Tests/Unit/Printer/examples/generic_this.test
new file mode 100644
index 00000000..4b66d051
--- /dev/null
+++ b/lib/DocblockParser/Tests/Unit/Printer/examples/generic_this.test
@@ -0,0 +1,15 @@
+/**
+ * @param Foobar<$this> $foobar
+ */
+---
+Docblock: = 
+ ElementList: = /**
+ * 
+  ParamTag: = @param
+   GenericNode: = 
+    ClassNode: = Foobar<
+    TypeList: = 
+     ThisNode: = $this>
+   VariableNode: = $foobar
+   TextNode: = 
+ */
diff --git a/lib/WorseReflection/Tests/Inference/generics/generic_with_this.test b/lib/WorseReflection/Tests/Inference/generics/generic_with_this.test
new file mode 100644
index 00000000..cf541b46
--- /dev/null
+++ b/lib/WorseReflection/Tests/Inference/generics/generic_with_this.test
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @template T
+ */
+class DocblockBuilder
+{
+    /**
+     * @param T $parent
+     */
+    public function __contsruct($parent): void
+    {
+    }
+
+    /**
+     * @return T
+     */
+    public function parent() {}
+}
+
+class Parent {
+    /**
+     * @return DocblockBuilder<$this>
+     */
+    public function builder() {
+    }
+}
+
+wrAssertType('Parent', (new Parent())->builder()->parent());