Skip to content

Commit 76ea1eb

Browse files
committed
feat: add PhpDocNode.getSealedTagValues() (v2.2 sync)
Add getSealedTagValues() method to PhpDocNode for retrieving @phpstan-sealed and @psalm-inheritors tag values, matching upstream v2.2.0 API.
1 parent ecc72b4 commit 76ea1eb

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

src/phpdoc-parser/ast/php-doc/php-doc-node.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { PhpDocTagNode } from './php-doc-tag-node';
99
import type { PhpDocTagValueNode } from './php-doc-tag-value-node';
1010
import { PropertyTagValueNode } from './property-tag-value-node';
1111
import { ReturnTagValueNode } from './return-tag-value-node';
12+
import { SealedTagValueNode } from './sealed-tag-value-node';
1213
import { TemplateTagValueNode } from './template-tag-value-node';
1314
import { ThrowsTagValueNode } from './throws-tag-value-node';
1415
import { TypelessParamTagValueNode } from './typeless-param-tag-value-node';
@@ -135,6 +136,17 @@ export class PhpDocNode extends BaseNode {
135136
);
136137
}
137138

139+
public getSealedTagValues(
140+
tagName = '@phpstan-sealed',
141+
): SealedTagValueNode[] {
142+
return this.getTagsByName(tagName)
143+
.map((tag) => tag.value)
144+
.filter(
145+
(value: PhpDocTagValueNode): value is SealedTagValueNode =>
146+
value instanceof SealedTagValueNode,
147+
);
148+
}
149+
138150
public getDeprecatedTagValues(): DeprecatedTagValueNode[] {
139151
return this.getTagsByName('@deprecated')
140152
.map((tag) => tag.value)

tests/parser/upstream-2024-features.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ParamClosureThisTagValueNode,
1212
ParamImmediatelyInvokedCallableTagValueNode,
1313
ParamLaterInvokedCallableTagValueNode,
14+
PhpDocNode,
1415
PhpDocParser,
1516
PureUnlessCallableIsImpureTagValueNode,
1617
RequireExtendsTagValueNode,
@@ -112,6 +113,41 @@ describe('Upstream 2024 Features', () => {
112113
});
113114
});
114115

116+
describe('PhpDocNode.getSealedTagValues()', () => {
117+
it('should return sealed tag values', () => {
118+
const lexer = new Lexer();
119+
const constExprParser = new ConstExprParser();
120+
const typeParser = new TypeParser(constExprParser);
121+
const phpDocParser = new PhpDocParser(typeParser, constExprParser);
122+
123+
const tokens = new TokenIterator(
124+
lexer.tokenize('/** @phpstan-sealed ChildA|ChildB */'),
125+
);
126+
127+
const phpDoc = phpDocParser.parse(tokens);
128+
const sealedValues = phpDoc.getSealedTagValues();
129+
expect(sealedValues).toHaveLength(1);
130+
expect(sealedValues[0]).toBeInstanceOf(SealedTagValueNode);
131+
expect(sealedValues[0].type).toBeInstanceOf(UnionTypeNode);
132+
});
133+
134+
it('should return sealed tag values for @psalm-inheritors', () => {
135+
const lexer = new Lexer();
136+
const constExprParser = new ConstExprParser();
137+
const typeParser = new TypeParser(constExprParser);
138+
const phpDocParser = new PhpDocParser(typeParser, constExprParser);
139+
140+
const tokens = new TokenIterator(
141+
lexer.tokenize('/** @psalm-inheritors ChildA|ChildB */'),
142+
);
143+
144+
const phpDoc = phpDocParser.parse(tokens);
145+
const sealedValues = phpDoc.getSealedTagValues('@psalm-inheritors');
146+
expect(sealedValues).toHaveLength(1);
147+
expect(sealedValues[0]).toBeInstanceOf(SealedTagValueNode);
148+
});
149+
});
150+
115151
describe('@psalm-inheritors tag', () => {
116152
it('should parse @psalm-inheritors tag with type', () => {
117153
const lexer = new Lexer();

0 commit comments

Comments
 (0)