diff -pruN 2.1.0-1/.github/workflows/apiref.yml 2.2.0-1/.github/workflows/apiref.yml
--- 2.1.0-1/.github/workflows/apiref.yml	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/.github/workflows/apiref.yml	2025-07-13 07:04:09.000000000 +0000
@@ -5,7 +5,7 @@ name: "Deploy API Reference"
 on:
   push:
     branches:
-      - "2.1.x"
+      - "2.2.x"
 
 concurrency:
   group: "pages"
@@ -22,6 +22,7 @@ jobs:
           - "1.23.x"
           - "2.0.x"
           - "2.1.x"
+          - "2.2.x"
 
     steps:
       - name: "Checkout"
diff -pruN 2.1.0-1/.github/workflows/backward-compatibility.yml 2.2.0-1/.github/workflows/backward-compatibility.yml
--- 2.1.0-1/.github/workflows/backward-compatibility.yml	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/.github/workflows/backward-compatibility.yml	2025-07-13 07:04:09.000000000 +0000
@@ -6,7 +6,7 @@ on:
   pull_request:
   push:
     branches:
-      - "2.1.x"
+      - "2.2.x"
 
 jobs:
   backward-compatibility:
diff -pruN 2.1.0-1/.github/workflows/build.yml 2.2.0-1/.github/workflows/build.yml
--- 2.1.0-1/.github/workflows/build.yml	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/.github/workflows/build.yml	2025-07-13 07:04:09.000000000 +0000
@@ -6,7 +6,7 @@ on:
   pull_request:
   push:
     branches:
-      - "2.1.x"
+      - "2.2.x"
 
 jobs:
   lint:
diff -pruN 2.1.0-1/.github/workflows/release.yml 2.2.0-1/.github/workflows/release.yml
--- 2.1.0-1/.github/workflows/release.yml	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/.github/workflows/release.yml	2025-07-13 07:04:09.000000000 +0000
@@ -18,7 +18,7 @@ jobs:
 
       - name: Generate changelog
         id: changelog
-        uses: metcalfc/changelog-generator@v4.3.1
+        uses: metcalfc/changelog-generator@v4.6.2
         with:
           myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }}
 
diff -pruN 2.1.0-1/.github/workflows/test-slevomat-coding-standard.yml 2.2.0-1/.github/workflows/test-slevomat-coding-standard.yml
--- 2.1.0-1/.github/workflows/test-slevomat-coding-standard.yml	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/.github/workflows/test-slevomat-coding-standard.yml	2025-07-13 07:04:09.000000000 +0000
@@ -6,7 +6,7 @@ on:
   pull_request:
   push:
     branches:
-      - "2.1.x"
+      - "2.2.x"
 
 jobs:
   tests:
diff -pruN 2.1.0-1/README.md 2.2.0-1/README.md
--- 2.1.0-1/README.md	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/README.md	2025-07-13 07:04:09.000000000 +0000
@@ -13,7 +13,7 @@ For the complete list of supported PHPDo
 
 * [PHPDoc Basics](https://phpstan.org/writing-php-code/phpdocs-basics) (list of PHPDoc tags)
 * [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types) (list of PHPDoc types)
-* [phpdoc-parser API Reference](https://phpstan.github.io/phpdoc-parser/2.1.x/namespace-PHPStan.PhpDocParser.html) with all the AST node types etc.
+* [phpdoc-parser API Reference](https://phpstan.github.io/phpdoc-parser/2.2.x/namespace-PHPStan.PhpDocParser.html) with all the AST node types etc.
 
 This parser also supports parsing [Doctrine Annotations](https://github.com/doctrine/annotations). The AST nodes live in the [PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine namespace](https://phpstan.github.io/phpdoc-parser/2.1.x/namespace-PHPStan.PhpDocParser.Ast.PhpDoc.Doctrine.html).
 
diff -pruN 2.1.0-1/debian/changelog 2.2.0-1/debian/changelog
--- 2.1.0-1/debian/changelog	2025-02-19 17:25:16.000000000 +0000
+++ 2.2.0-1/debian/changelog	2025-07-19 08:06:00.000000000 +0000
@@ -1,3 +1,18 @@
+php-phpstan-phpdoc-parser (2.2.0-1) experimental; urgency=medium
+
+  * Upload to experimental during the freeze
+
+  [ Ondrej Mirtes ]
+  * Prepare 2.2.x
+
+  [ Vincent Langlet ]
+  * Add support for `@psalm-inheritors` and `@phpstan-sealed` tag
+
+  [ David Prévot ]
+  * Update Standards-Version to 4.7.2
+
+ -- David Prévot <taffit@debian.org>  Sat, 19 Jul 2025 10:06:00 +0200
+
 php-phpstan-phpdoc-parser (2.1.0-1) unstable; urgency=medium
 
   [ Ondrej Mirtes ]
diff -pruN 2.1.0-1/debian/control 2.2.0-1/debian/control
--- 2.1.0-1/debian/control	2024-06-03 05:18:07.000000000 +0000
+++ 2.2.0-1/debian/control	2025-07-19 08:04:53.000000000 +0000
@@ -9,7 +9,7 @@ Build-Depends: debhelper-compat (= 13),
                php-symfony-process,
                phpab,
                phpunit
-Standards-Version: 4.7.0
+Standards-Version: 4.7.2
 Vcs-Git: https://salsa.debian.org/php-team/pear/php-phpstan-phpdoc-parser.git
 Vcs-Browser: https://salsa.debian.org/php-team/pear/php-phpstan-phpdoc-parser
 Homepage: https://phpstan.org/
diff -pruN 2.1.0-1/debian/patches/0002-Adapt-to-recent-version-of-PHPUnit-10.patch 2.2.0-1/debian/patches/0002-Adapt-to-recent-version-of-PHPUnit-10.patch
--- 2.1.0-1/debian/patches/0002-Adapt-to-recent-version-of-PHPUnit-10.patch	2025-02-19 17:25:00.000000000 +0000
+++ 2.2.0-1/debian/patches/0002-Adapt-to-recent-version-of-PHPUnit-10.patch	2025-07-19 08:01:05.000000000 +0000
@@ -6,12 +6,12 @@ Subject: Adapt to recent version of PHPU
  tests/PHPStan/Ast/NodeTraverserTest.php            |  2 +-
  tests/PHPStan/Parser/ConstExprParserTest.php       | 16 ++---
  tests/PHPStan/Parser/FuzzyTest.php                 | 10 +--
- tests/PHPStan/Parser/PhpDocParserTest.php          | 74 +++++++++++-----------
+ tests/PHPStan/Parser/PhpDocParserTest.php          | 76 +++++++++++-----------
  tests/PHPStan/Parser/TypeParserTest.php            |  4 +-
  tests/PHPStan/Printer/DifferTest.php               |  4 +-
  .../IntegrationPrinterWithPhpParserTest.php        |  2 +-
  tests/PHPStan/Printer/PrinterTest.php              |  6 +-
- 8 files changed, 59 insertions(+), 59 deletions(-)
+ 8 files changed, 60 insertions(+), 60 deletions(-)
 
 diff --git a/tests/PHPStan/Ast/NodeTraverserTest.php b/tests/PHPStan/Ast/NodeTraverserTest.php
 index 49f3646..1c66cff 100644
@@ -135,10 +135,10 @@ index 9491bf6..6c4f2ae 100644
  		$inputsDirectory = sprintf('%s/fuzzy/%s', __DIR__ . '/../../../temp', $startSymbol);
  
 diff --git a/tests/PHPStan/Parser/PhpDocParserTest.php b/tests/PHPStan/Parser/PhpDocParserTest.php
-index abe69b8..d41798d 100644
+index b2857b2..1ec1dc6 100644
 --- a/tests/PHPStan/Parser/PhpDocParserTest.php
 +++ b/tests/PHPStan/Parser/PhpDocParserTest.php
-@@ -154,7 +154,7 @@ class PhpDocParserTest extends TestCase
+@@ -156,7 +156,7 @@ class PhpDocParserTest extends TestCase
  	}
  
  
@@ -147,7 +147,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -534,7 +534,7 @@ class PhpDocParserTest extends TestCase
+@@ -536,7 +536,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -156,7 +156,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -617,7 +617,7 @@ class PhpDocParserTest extends TestCase
+@@ -619,7 +619,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -165,7 +165,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -648,7 +648,7 @@ class PhpDocParserTest extends TestCase
+@@ -650,7 +650,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -174,7 +174,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -679,7 +679,7 @@ class PhpDocParserTest extends TestCase
+@@ -681,7 +681,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -183,7 +183,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -727,7 +727,7 @@ class PhpDocParserTest extends TestCase
+@@ -729,7 +729,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -192,7 +192,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -758,7 +758,7 @@ class PhpDocParserTest extends TestCase
+@@ -760,7 +760,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -201,7 +201,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description and variable name',
-@@ -1153,7 +1153,7 @@ class PhpDocParserTest extends TestCase
+@@ -1155,7 +1155,7 @@ class PhpDocParserTest extends TestCase
  	}
  
  
@@ -210,7 +210,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -1355,7 +1355,7 @@ class PhpDocParserTest extends TestCase
+@@ -1357,7 +1357,7 @@ class PhpDocParserTest extends TestCase
  	}
  
  
@@ -219,7 +219,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -1886,7 +1886,7 @@ class PhpDocParserTest extends TestCase
+@@ -1888,7 +1888,7 @@ class PhpDocParserTest extends TestCase
  	}
  
  
@@ -228,7 +228,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -1973,7 +1973,7 @@ class PhpDocParserTest extends TestCase
+@@ -1975,7 +1975,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -237,7 +237,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -2078,7 +2078,7 @@ class PhpDocParserTest extends TestCase
+@@ -2080,7 +2080,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -246,7 +246,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -2144,7 +2144,7 @@ class PhpDocParserTest extends TestCase
+@@ -2146,7 +2146,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -255,7 +255,16 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description',
-@@ -2210,7 +2210,7 @@ class PhpDocParserTest extends TestCase
+@@ -2212,7 +2212,7 @@ class PhpDocParserTest extends TestCase
+ 		];
+ 	}
+ 
+-	public function provideSealedTagsData(): Iterator
++	public static function provideSealedTagsData(): Iterator
+ 	{
+ 		yield [
+ 			'OK without description',
+@@ -2287,7 +2287,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -264,7 +273,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK with no description',
-@@ -2316,7 +2316,7 @@ class PhpDocParserTest extends TestCase
+@@ -2393,7 +2393,7 @@ class PhpDocParserTest extends TestCase
  		];
  	}
  
@@ -273,7 +282,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK non-static, without return type',
-@@ -2830,7 +2830,7 @@ class PhpDocParserTest extends TestCase
+@@ -2907,7 +2907,7 @@ class PhpDocParserTest extends TestCase
  	}
  
  
@@ -282,7 +291,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'empty',
-@@ -4425,7 +4425,7 @@ test',
+@@ -4502,7 +4502,7 @@ test',
  		];
  	}
  
@@ -291,7 +300,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without bound and description',
-@@ -4657,7 +4657,7 @@ test',
+@@ -4734,7 +4734,7 @@ test',
  		];
  	}
  
@@ -300,7 +309,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK with one argument',
-@@ -4876,7 +4876,7 @@ test',
+@@ -4953,7 +4953,7 @@ test',
  		];
  	}
  
@@ -309,7 +318,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -5079,7 +5079,7 @@ test',
+@@ -5156,7 +5156,7 @@ test',
  		];
  	}
  
@@ -318,7 +327,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -5217,7 +5217,7 @@ test',
+@@ -5294,7 +5294,7 @@ test',
  		];
  	}
  
@@ -327,7 +336,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK',
-@@ -5507,7 +5507,7 @@ test',
+@@ -5584,7 +5584,7 @@ test',
  		];
  	}
  
@@ -336,7 +345,7 @@ index abe69b8..d41798d 100644
  	{
  		$sample = '/**
  			 * Returns the schema for the field.
-@@ -5533,7 +5533,7 @@ Computed fields having no schema should return an empty array.'),
+@@ -5610,7 +5610,7 @@ Computed fields having no schema should return an empty array.'),
  		];
  	}
  
@@ -345,7 +354,7 @@ index abe69b8..d41798d 100644
  	{
  			$sample = "/**
  			 * Returns the schema for the field.
-@@ -6105,7 +6105,7 @@ Finder::findFiles('*.php')
+@@ -6182,7 +6182,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -354,7 +363,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'Description with HTML tags in @return tag (close tags together)',
-@@ -6182,7 +6182,7 @@ Finder::findFiles('*.php')
+@@ -6259,7 +6259,7 @@ Finder::findFiles('*.php')
  	/**
  	 * @return array<mixed>
  	 */
@@ -363,7 +372,7 @@ index abe69b8..d41798d 100644
  	{
  		return [
  			[
-@@ -6214,7 +6214,7 @@ Finder::findFiles('*.php')
+@@ -6291,7 +6291,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -372,7 +381,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description and tag with number in it',
-@@ -6228,7 +6228,7 @@ Finder::findFiles('*.php')
+@@ -6305,7 +6305,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -381,7 +390,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK without description and tag with backslashes in it',
-@@ -6256,7 +6256,7 @@ Finder::findFiles('*.php')
+@@ -6333,7 +6333,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -390,7 +399,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK phpstan-self-out',
-@@ -6329,7 +6329,7 @@ Finder::findFiles('*.php')
+@@ -6406,7 +6406,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -399,7 +408,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'Comment after @param',
-@@ -6464,7 +6464,7 @@ Finder::findFiles('*.php')
+@@ -6541,7 +6541,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -408,7 +417,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'Inline @link tag in @copyright',
-@@ -6485,7 +6485,7 @@ Finder::findFiles('*.php')
+@@ -6562,7 +6562,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -417,7 +426,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'OK param-out',
-@@ -6518,7 +6518,7 @@ Finder::findFiles('*.php')
+@@ -6595,7 +6595,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -426,7 +435,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'single tag node with empty parameters',
-@@ -7073,7 +7073,7 @@ Finder::findFiles('*.php')
+@@ -7150,7 +7150,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -435,7 +444,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'Dummy 1',
-@@ -7362,7 +7362,7 @@ Finder::findFiles('*.php')
+@@ -7439,7 +7439,7 @@ Finder::findFiles('*.php')
  		];
  	}
  
@@ -444,7 +453,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'Ok specialized tag',
-@@ -7430,7 +7430,7 @@ Finder::findFiles('*.php')
+@@ -7507,7 +7507,7 @@ Finder::findFiles('*.php')
  	/**
  	 * @return array<mixed>
  	 */
@@ -453,7 +462,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'/** @param Foo $a */',
-@@ -7554,7 +7554,7 @@ Finder::findFiles('*.php')
+@@ -7631,7 +7631,7 @@ Finder::findFiles('*.php')
  	/**
  	 * @return iterable<array{string, list<array{int, int, int, int}>}>
  	 */
@@ -462,7 +471,7 @@ index abe69b8..d41798d 100644
  	{
  		yield [
  			'/**' . PHP_EOL .
-@@ -7639,7 +7639,7 @@ Finder::findFiles('*.php')
+@@ -7716,7 +7716,7 @@ Finder::findFiles('*.php')
  	/**
  	 * @return array<mixed>
  	 */
diff -pruN 2.1.0-1/debian/patches/0003-Make-provider-function-static-PHPUnit-11-Fix.patch 2.2.0-1/debian/patches/0003-Make-provider-function-static-PHPUnit-11-Fix.patch
--- 2.1.0-1/debian/patches/0003-Make-provider-function-static-PHPUnit-11-Fix.patch	2025-02-19 17:25:00.000000000 +0000
+++ 2.2.0-1/debian/patches/0003-Make-provider-function-static-PHPUnit-11-Fix.patch	2025-07-19 08:01:05.000000000 +0000
@@ -34,10 +34,10 @@ index 23404a2..9d91ba5 100644
      <testsuites>
          <testsuite name="PHPStan PHPDoc Parser">
 diff --git a/tests/PHPStan/Parser/PhpDocParserTest.php b/tests/PHPStan/Parser/PhpDocParserTest.php
-index d41798d..59b2419 100644
+index 1ec1dc6..3d1bf70 100644
 --- a/tests/PHPStan/Parser/PhpDocParserTest.php
 +++ b/tests/PHPStan/Parser/PhpDocParserTest.php
-@@ -2997,7 +2997,7 @@ class PhpDocParserTest extends TestCase
+@@ -3074,7 +3074,7 @@ class PhpDocParserTest extends TestCase
  	/**
  	 * @return iterable<array<mixed>>
  	 */
@@ -46,7 +46,7 @@ index d41798d..59b2419 100644
  	{
  		yield from [
  			[
-@@ -7779,7 +7779,7 @@ Finder::findFiles('*.php')
+@@ -7856,7 +7856,7 @@ Finder::findFiles('*.php')
  	/**
  	 * @return iterable<array{string, PhpDocNode}>
  	 */
diff -pruN 2.1.0-1/debian/patches/0005-Compatibility-with-recent-PHPUnit-12.patch 2.2.0-1/debian/patches/0005-Compatibility-with-recent-PHPUnit-12.patch
--- 2.1.0-1/debian/patches/0005-Compatibility-with-recent-PHPUnit-12.patch	2025-02-19 17:25:00.000000000 +0000
+++ 2.2.0-1/debian/patches/0005-Compatibility-with-recent-PHPUnit-12.patch	2025-07-19 08:01:05.000000000 +0000
@@ -5,17 +5,17 @@ Subject: Compatibility with recent PHPUn
 ---
  tests/PHPStan/Ast/NodeTraverserTest.php            |  2 +
  .../PHPStan/Ast/ToString/ConstExprToStringTest.php |  3 +
- tests/PHPStan/Ast/ToString/PhpDocToStringTest.php  | 13 +++++
+ tests/PHPStan/Ast/ToString/PhpDocToStringTest.php  | 13 ++++
  tests/PHPStan/Ast/ToString/TypeToStringTest.php    |  7 +++
- tests/PHPStan/Parser/ConstExprParserTest.php       | 17 ++++++
+ tests/PHPStan/Parser/ConstExprParserTest.php       | 19 +++++-
  tests/PHPStan/Parser/FuzzyTest.php                 |  3 +
- tests/PHPStan/Parser/PhpDocParserTest.php          | 68 ++++++++++++++++++++++
+ tests/PHPStan/Parser/PhpDocParserTest.php          | 73 +++++++++++++++++++++-
  tests/PHPStan/Parser/TokenIteratorTest.php         |  2 +
- tests/PHPStan/Parser/TypeParserTest.php            |  4 ++
+ tests/PHPStan/Parser/TypeParserTest.php            |  6 +-
  tests/PHPStan/Printer/DifferTest.php               |  3 +
  .../IntegrationPrinterWithPhpParserTest.php        |  2 +
  tests/PHPStan/Printer/PrinterTest.php              |  4 ++
- 12 files changed, 128 insertions(+)
+ 12 files changed, 133 insertions(+), 4 deletions(-)
 
 diff --git a/tests/PHPStan/Ast/NodeTraverserTest.php b/tests/PHPStan/Ast/NodeTraverserTest.php
 index 1c66cff..6ef230f 100644
@@ -143,7 +143,7 @@ index 6716e43..eb0bd88 100644
  	{
  		$this->assertSame($expected, (string) $node);
 diff --git a/tests/PHPStan/Parser/ConstExprParserTest.php b/tests/PHPStan/Parser/ConstExprParserTest.php
-index f800135..19db4a7 100644
+index f800135..1779586 100644
 --- a/tests/PHPStan/Parser/ConstExprParserTest.php
 +++ b/tests/PHPStan/Parser/ConstExprParserTest.php
 @@ -17,6 +17,7 @@ use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode;
@@ -169,10 +169,11 @@ index f800135..19db4a7 100644
  	public function testParse(string $input, ConstExprNode $expectedExpr, int $nextTokenType = Lexer::TOKEN_END): void
  	{
  		$tokens = new TokenIterator($this->lexer->tokenize($input));
-@@ -66,6 +75,14 @@ class ConstExprParserTest extends TestCase
+@@ -66,7 +75,15 @@ class ConstExprParserTest extends TestCase
  	 * @dataProvider provideArrayNodeParseData
  	 * @dataProvider provideFetchNodeParseData
  	 */
+-	public function testVerifyAttributes(string $input): void
 +	#[DataProvider('provideTrueNodeParseData')]
 +	#[DataProvider('provideFalseNodeParseData')]
 +	#[DataProvider('provideNullNodeParseData')]
@@ -181,9 +182,10 @@ index f800135..19db4a7 100644
 +	#[DataProvider('provideStringNodeParseData')]
 +	#[DataProvider('provideArrayNodeParseData')]
 +	#[DataProvider('provideFetchNodeParseData')]
- 	public function testVerifyAttributes(string $input): void
++	public function testVerifyAttributes(string $input, ConstExprNode $expectedExpr, int $nextTokenType = Lexer::TOKEN_END): void
  	{
  		$tokens = new TokenIterator($this->lexer->tokenize($input));
+ 		$config = new ParserConfig([
 diff --git a/tests/PHPStan/Parser/FuzzyTest.php b/tests/PHPStan/Parser/FuzzyTest.php
 index 6c4f2ae..a0a0a91 100644
 --- a/tests/PHPStan/Parser/FuzzyTest.php
@@ -213,10 +215,10 @@ index 6c4f2ae..a0a0a91 100644
  	{
  		$tokens = new TokenIterator($this->lexer->tokenize($input));
 diff --git a/tests/PHPStan/Parser/PhpDocParserTest.php b/tests/PHPStan/Parser/PhpDocParserTest.php
-index 59b2419..785807f 100644
+index 3d1bf70..e7d466a 100644
 --- a/tests/PHPStan/Parser/PhpDocParserTest.php
 +++ b/tests/PHPStan/Parser/PhpDocParserTest.php
-@@ -69,6 +69,7 @@ use PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode;
+@@ -70,6 +70,7 @@ use PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode;
  use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
  use PHPStan\PhpDocParser\Lexer\Lexer;
  use PHPStan\PhpDocParser\ParserConfig;
@@ -224,7 +226,7 @@ index 59b2419..785807f 100644
  use PHPUnit\Framework\TestCase;
  use function count;
  use function sprintf;
-@@ -128,6 +129,39 @@ class PhpDocParserTest extends TestCase
+@@ -130,10 +131,44 @@ class PhpDocParserTest extends TestCase
  	 * @dataProvider provideCommentLikeDescriptions
  	 * @dataProvider provideInlineTags
  	 */
@@ -264,7 +266,13 @@ index 59b2419..785807f 100644
  	public function testParse(
  		string $label,
  		string $input,
-@@ -7382,6 +7416,7 @@ Finder::findFiles('*.php')
+-		PhpDocNode $expectedPhpDocNode
++		PhpDocNode $expectedPhpDocNode,
++		array $expectedAnnotations = [],
+ 	): void
+ 	{
+ 		$this->executeTestParse(
+@@ -7459,6 +7494,7 @@ Finder::findFiles('*.php')
  	 * @dataProvider dataParseTagValue
  	 * @param PhpDocNode $expectedPhpDocNode
  	 */
@@ -272,7 +280,7 @@ index 59b2419..785807f 100644
  	public function testParseTagValue(string $tag, string $phpDoc, Node $expectedPhpDocNode): void
  	{
  		$this->executeTestParseTagValue($this->phpDocParser, $tag, $phpDoc, $expectedPhpDocNode);
-@@ -7529,6 +7564,7 @@ Finder::findFiles('*.php')
+@@ -7606,6 +7642,7 @@ Finder::findFiles('*.php')
  	 * @dataProvider dataLinesAndIndexes
  	 * @param list<array{int, int, int, int}> $childrenLines
  	 */
@@ -280,7 +288,7 @@ index 59b2419..785807f 100644
  	public function testLinesAndIndexes(string $phpDoc, array $childrenLines): void
  	{
  		$tokens = new TokenIterator($this->lexer->tokenize($phpDoc));
-@@ -7613,6 +7649,7 @@ Finder::findFiles('*.php')
+@@ -7690,6 +7727,7 @@ Finder::findFiles('*.php')
  	 * @dataProvider dataDeepNodesLinesAndIndexes
  	 * @param list<array{int, int, int, int}> $nodeAttributes
  	 */
@@ -288,7 +296,7 @@ index 59b2419..785807f 100644
  	public function testDeepNodesLinesAndIndexes(string $phpDoc, array $nodeAttributes): void
  	{
  		$tokens = new TokenIterator($this->lexer->tokenize($phpDoc));
-@@ -7686,6 +7723,7 @@ Finder::findFiles('*.php')
+@@ -7763,6 +7801,7 @@ Finder::findFiles('*.php')
  	 * @dataProvider dataReturnTypeLinesAndIndexes
  	 * @param array{int, int, int, int} $lines
  	 */
@@ -296,10 +304,11 @@ index 59b2419..785807f 100644
  	public function testReturnTypeLinesAndIndexes(string $phpDoc, array $lines): void
  	{
  		$tokens = new TokenIterator($this->lexer->tokenize($phpDoc));
-@@ -7737,6 +7775,34 @@ Finder::findFiles('*.php')
+@@ -7814,7 +7853,35 @@ Finder::findFiles('*.php')
  	 * @dataProvider provideDoctrineData
  	 * @dataProvider provideDoctrineWithoutDoctrineCheckData
  	 */
+-	public function testVerifyAttributes(string $label, string $input): void
 +	#[DataProvider('provideTagsWithNumbers')]
 +	#[DataProvider('provideSpecializedTags')]
 +	#[DataProvider('provideParamTagsData')]
@@ -328,10 +337,11 @@ index 59b2419..785807f 100644
 +	#[DataProvider('provideParamOutTagsData')]
 +	#[DataProvider('provideDoctrineData')]
 +	#[DataProvider('provideDoctrineWithoutDoctrineCheckData')]
- 	public function testVerifyAttributes(string $label, string $input): void
++	public function testVerifyAttributes(string $label, string $input, PhpDocNode $expectedPhpDocNode, array $expectedAnnotations = []): void
  	{
  		$config = new ParserConfig([
-@@ -7764,6 +7830,7 @@ Finder::findFiles('*.php')
+ 			'lines' => true,
+@@ -7841,6 +7908,7 @@ Finder::findFiles('*.php')
  	 * @dataProvider provideDoctrineData
  	 * @param list<object> $expectedAnnotations
  	 */
@@ -339,7 +349,7 @@ index 59b2419..785807f 100644
  	public function testDoctrine(
  		string $label,
  		string $input,
-@@ -8106,6 +8173,7 @@ Finder::findFiles('*.php')
+@@ -8183,6 +8251,7 @@ Finder::findFiles('*.php')
  	/**
  	 * @dataProvider dataTextBetweenTagsBelongsToDescription
  	 */
@@ -368,7 +378,7 @@ index 99f9510..345056e 100644
  	{
  		$config = new ParserConfig([]);
 diff --git a/tests/PHPStan/Parser/TypeParserTest.php b/tests/PHPStan/Parser/TypeParserTest.php
-index cae31c1..b7191e9 100644
+index cae31c1..78bd68a 100644
 --- a/tests/PHPStan/Parser/TypeParserTest.php
 +++ b/tests/PHPStan/Parser/TypeParserTest.php
 @@ -37,6 +37,7 @@ use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
@@ -387,14 +397,16 @@ index cae31c1..b7191e9 100644
  	public function testParse(string $input, $expectedResult, int $nextTokenType = Lexer::TOKEN_END): void
  	{
  		if ($expectedResult instanceof Exception) {
-@@ -115,6 +117,7 @@ class TypeParserTest extends TestCase
+@@ -115,7 +117,8 @@ class TypeParserTest extends TestCase
  	 * @dataProvider provideParseData
  	 * @param TypeNode|Exception $expectedResult
  	 */
+-	public function testVerifyAttributes(string $input, $expectedResult): void
 +	#[DataProvider('provideParseData')]
- 	public function testVerifyAttributes(string $input, $expectedResult): void
++	public function testVerifyAttributes(string $input, $expectedResult, int $nextTokenType = Lexer::TOKEN_END): void
  	{
  		if ($expectedResult instanceof Exception) {
+ 			$this->expectException(get_class($expectedResult));
 @@ -3417,6 +3420,7 @@ class TypeParserTest extends TestCase
  	 * @dataProvider dataLinesAndIndexes
  	 * @param list<array{callable(Node): Node, string, int, int, int, int}> $assertions
diff -pruN 2.1.0-1/src/Ast/PhpDoc/PhpDocNode.php 2.2.0-1/src/Ast/PhpDoc/PhpDocNode.php
--- 2.1.0-1/src/Ast/PhpDoc/PhpDocNode.php	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/src/Ast/PhpDoc/PhpDocNode.php	2025-07-13 07:04:09.000000000 +0000
@@ -232,6 +232,17 @@ class PhpDocNode implements Node
 	}
 
 	/**
+	 * @return SealedTagValueNode[]
+	 */
+	public function getSealedTagValues(string $tagName = '@phpstan-sealed'): array
+	{
+		return array_filter(
+			array_column($this->getTagsByName($tagName), 'value'),
+			static fn (PhpDocTagValueNode $value): bool => $value instanceof SealedTagValueNode,
+		);
+	}
+
+	/**
 	 * @return DeprecatedTagValueNode[]
 	 */
 	public function getDeprecatedTagValues(): array
diff -pruN 2.1.0-1/src/Ast/PhpDoc/SealedTagValueNode.php 2.2.0-1/src/Ast/PhpDoc/SealedTagValueNode.php
--- 2.1.0-1/src/Ast/PhpDoc/SealedTagValueNode.php	1970-01-01 00:00:00.000000000 +0000
+++ 2.2.0-1/src/Ast/PhpDoc/SealedTagValueNode.php	2025-07-13 07:04:09.000000000 +0000
@@ -0,0 +1,31 @@
+<?php declare(strict_types = 1);
+
+namespace PHPStan\PhpDocParser\Ast\PhpDoc;
+
+use PHPStan\PhpDocParser\Ast\NodeAttributes;
+use PHPStan\PhpDocParser\Ast\Type\TypeNode;
+use function trim;
+
+class SealedTagValueNode implements PhpDocTagValueNode
+{
+
+	use NodeAttributes;
+
+	public TypeNode $type;
+
+	/** @var string (may be empty) */
+	public string $description;
+
+	public function __construct(TypeNode $type, string $description)
+	{
+		$this->type = $type;
+		$this->description = $description;
+	}
+
+
+	public function __toString(): string
+	{
+		return trim("{$this->type} {$this->description}");
+	}
+
+}
diff -pruN 2.1.0-1/src/Parser/PhpDocParser.php 2.2.0-1/src/Parser/PhpDocParser.php
--- 2.1.0-1/src/Parser/PhpDocParser.php	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/src/Parser/PhpDocParser.php	2025-07-13 07:04:09.000000000 +0000
@@ -403,6 +403,11 @@ class PhpDocParser
 					$tagValue = $this->parseRequireImplementsTagValue($tokens);
 					break;
 
+				case '@psalm-inheritors':
+				case '@phpstan-sealed':
+					$tagValue = $this->parseSealedTagValue($tokens);
+					break;
+
 				case '@deprecated':
 					$tagValue = $this->parseDeprecatedTagValue($tokens);
 					break;
@@ -933,6 +938,13 @@ class PhpDocParser
 		return new Ast\PhpDoc\RequireImplementsTagValueNode($type, $description);
 	}
 
+	private function parseSealedTagValue(TokenIterator $tokens): Ast\PhpDoc\SealedTagValueNode
+	{
+		$type = $this->typeParser->parse($tokens);
+		$description = $this->parseOptionalDescription($tokens, true);
+		return new Ast\PhpDoc\SealedTagValueNode($type, $description);
+	}
+
 	private function parseDeprecatedTagValue(TokenIterator $tokens): Ast\PhpDoc\DeprecatedTagValueNode
 	{
 		$description = $this->parseOptionalDescription($tokens, false);
diff -pruN 2.1.0-1/src/Printer/Printer.php 2.2.0-1/src/Printer/Printer.php
--- 2.1.0-1/src/Printer/Printer.php	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/src/Printer/Printer.php	2025-07-13 07:04:09.000000000 +0000
@@ -36,6 +36,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\Pure
 use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\SealedTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\SelfOutTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode;
@@ -327,6 +328,10 @@ final class Printer
 			$type = $this->printType($node->type);
 			return trim("{$type} {$node->description}");
 		}
+		if ($node instanceof SealedTagValueNode) {
+			$type = $this->printType($node->type);
+			return trim("{$type} {$node->description}");
+		}
 		if ($node instanceof ParamOutTagValueNode) {
 			$type = $this->printType($node->type);
 			return trim("{$type} {$node->parameterName} {$node->description}");
diff -pruN 2.1.0-1/tests/PHPStan/Parser/PhpDocParserTest.php 2.2.0-1/tests/PHPStan/Parser/PhpDocParserTest.php
--- 2.1.0-1/tests/PHPStan/Parser/PhpDocParserTest.php	2025-02-19 13:28:12.000000000 +0000
+++ 2.2.0-1/tests/PHPStan/Parser/PhpDocParserTest.php	2025-07-13 07:04:09.000000000 +0000
@@ -42,6 +42,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\Pure
 use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\SealedTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\SelfOutTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
 use PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode;
@@ -108,6 +109,7 @@ class PhpDocParserTest extends TestCase
 	 * @dataProvider provideMixinTagsData
 	 * @dataProvider provideRequireExtendsTagsData
 	 * @dataProvider provideRequireImplementsTagsData
+	 * @dataProvider provideSealedTagsData
 	 * @dataProvider provideDeprecatedTagsData
 	 * @dataProvider providePropertyTagsData
 	 * @dataProvider provideMethodTagsData
@@ -2203,6 +2205,81 @@ class PhpDocParserTest extends TestCase
 							Lexer::TOKEN_IDENTIFIER,
 							null,
 							1,
+						),
+					),
+				),
+			]),
+		];
+	}
+
+	public function provideSealedTagsData(): Iterator
+	{
+		yield [
+			'OK without description',
+			'/** @phpstan-sealed Foo|Bar */',
+			new PhpDocNode([
+				new PhpDocTagNode(
+					'@phpstan-sealed',
+					new SealedTagValueNode(
+						new UnionTypeNode([
+							new IdentifierTypeNode('Foo'),
+							new IdentifierTypeNode('Bar'),
+						]),
+						'',
+					),
+				),
+			]),
+		];
+
+		yield [
+			'OK with description',
+			'/** @phpstan-sealed Foo|Bar optional description */',
+			new PhpDocNode([
+				new PhpDocTagNode(
+					'@phpstan-sealed',
+					new SealedTagValueNode(
+						new UnionTypeNode([
+							new IdentifierTypeNode('Foo'),
+							new IdentifierTypeNode('Bar'),
+						]),
+						'optional description',
+					),
+				),
+			]),
+		];
+
+		yield [
+			'OK with psalm-prefix description',
+			'/** @psalm-inheritors Foo|Bar optional description */',
+			new PhpDocNode([
+				new PhpDocTagNode(
+					'@psalm-inheritors',
+					new SealedTagValueNode(
+						new UnionTypeNode([
+							new IdentifierTypeNode('Foo'),
+							new IdentifierTypeNode('Bar'),
+						]),
+						'optional description',
+					),
+				),
+			]),
+		];
+
+		yield [
+			'invalid without type and description',
+			'/** @phpstan-sealed */',
+			new PhpDocNode([
+				new PhpDocTagNode(
+					'@phpstan-sealed',
+					new InvalidTagValueNode(
+						'',
+						new ParserException(
+							'*/',
+							Lexer::TOKEN_CLOSE_PHPDOC,
+							20,
+							Lexer::TOKEN_IDENTIFIER,
+							null,
+							1,
 						),
 					),
 				),
