-
Notifications
You must be signed in to change notification settings - Fork 229
[js-api-parser] Property and property signature generator #13711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a new token generator for handling API properties and property signatures in the JavaScript API parser. It enables the parser to process both ApiProperty (for class properties) and ApiPropertySignature (for interface/type properties) and generate appropriate review tokens for them.
Changes:
- Added property token generator implementation with support for static, readonly, and optional modifiers
- Added comprehensive test coverage for property and property signature generation
- Integrated the new generator into the token generator registry
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
tools/apiview/parsers/js-api-parser/src/tokenGenerators/property.ts |
Implements the property token generator with logic to handle modifiers (static, readonly, optional) and type information |
tools/apiview/parsers/js-api-parser/test/tokenGenerators/property.spec.ts |
Comprehensive test suite covering various property configurations including static, readonly, optional, and deprecated properties |
tools/apiview/parsers/js-api-parser/src/tokenGenerators/index.ts |
Adds property generator to the registry and exports it for use |
|
|
||
| tokens.push({ Kind: TokenKind.Punctuation, Value: ":", HasSuffixSpace: true }); | ||
|
|
||
| tokens.push({ Kind: TokenKind.TypeName, Value: item.propertyTypeExcerpt.text.trim(), IsDeprecated: deprecated }); |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property type should use processExcerptTokens(item.propertyTypeExcerpt.spannedTokens, tokens, deprecated) instead of directly using .text.trim(). This is consistent with how method generators handle return types (method.ts:119) and function generators handle return types (function.ts:101). Using processExcerptTokens provides proper handling of type references with navigation links and correctly processes complex types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, for example, types with generic type parameters x: Record<string, string>
tools/apiview/parsers/js-api-parser/src/tokenGenerators/property.ts
Outdated
Show resolved
Hide resolved
| tokens.push({ Kind: TokenKind.Punctuation, Value: "?" }); | ||
| } | ||
|
|
||
| tokens.push({ Kind: TokenKind.Punctuation, Value: ":", HasSuffixSpace: true }); |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Punctuation tokens are missing the IsDeprecated flag. When the property is deprecated, all tokens including punctuation should be marked with IsDeprecated: deprecated for consistency with how other generators handle deprecated items.
| tokens.push({ Kind: TokenKind.Punctuation, Value: "?" }); | |
| } | |
| tokens.push({ Kind: TokenKind.Punctuation, Value: ":", HasSuffixSpace: true }); | |
| tokens.push({ Kind: TokenKind.Punctuation, Value: "?", IsDeprecated: deprecated }); | |
| } | |
| tokens.push({ Kind: TokenKind.Punctuation, Value: ":", HasSuffixSpace: true, IsDeprecated: deprecated }); |
| it("should mark tokens as deprecated when deprecated flag is set", () => { | ||
| const mockItem = { | ||
| kind: ApiItemKind.Property, | ||
| displayName: "deprecatedProp", | ||
| isReadonly: false, | ||
| isOptional: false, | ||
| propertyTypeExcerpt: { text: "string" }, | ||
| } as unknown as ApiProperty; | ||
|
|
||
| const tokens = propertyTokenGenerator.generate(mockItem, true); | ||
|
|
||
| expect(tokens[0]).to.deep.include({ Kind: TokenKind.MemberName, Value: "deprecatedProp", IsDeprecated: true }); | ||
| }); | ||
|
|
||
| it("should throw error for invalid item kind", () => { | ||
| const mockItem = { | ||
| kind: ApiItemKind.Method, | ||
| displayName: "invalidItem", | ||
| } as any; | ||
|
|
||
| expect(() => propertyTokenGenerator.generate(mockItem)).to.throw(); | ||
| }); | ||
| }); |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage for deprecated optional properties. The tests should verify that when a deprecated optional property is generated, the "?" punctuation token also has IsDeprecated set to true.
| it("should mark property signature tokens as deprecated", () => { | ||
| const mockItem = { | ||
| kind: ApiItemKind.PropertySignature, | ||
| displayName: "deprecatedSignature", | ||
| isReadonly: false, | ||
| isOptional: false, | ||
| propertyTypeExcerpt: { text: "string" }, | ||
| } as unknown as ApiPropertySignature; | ||
|
|
||
| const tokens = propertyTokenGenerator.generate(mockItem, true); | ||
|
|
||
| expect(tokens[0]).to.deep.include({ Kind: TokenKind.MemberName, Value: "deprecatedSignature", IsDeprecated: true }); | ||
| expect(tokens[2]).to.deep.include({ Kind: TokenKind.TypeName, Value: "string", IsDeprecated: true }); | ||
| }); |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete test coverage for deprecated tokens. The test should verify that all tokens (including punctuation at index 1) have IsDeprecated set to true when the property is deprecated, not just the MemberName and TypeName tokens.
| propertyTokenGenerator, | ||
| ]; | ||
|
|
||
| export { propertyTokenGenerator } from "./property"; |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The explicit export of propertyTokenGenerator is inconsistent with the pattern used for other token generators (method, class, function, interface, enum). Other generators are only imported and added to the generators array, but not re-exported. This export should be removed unless there's a specific need for it.
| function generate(item: ApiPropertyItem, deprecated?: boolean): ReviewToken[] { | ||
| const tokens: ReviewToken[] = []; | ||
| if (item.kind !== ApiItemKind.Property && item.kind !== ApiItemKind.PropertySignature) { | ||
| throw new Error(`Invalid item ${item.displayName} of kind ${item.kind} for Property token generator.`); | ||
| } | ||
|
|
||
| if (item instanceof ApiProperty && item.isStatic) { | ||
| tokens.push({ Kind: TokenKind.Keyword, Value: "static", HasSuffixSpace: true, IsDeprecated: deprecated }); | ||
| } | ||
|
|
||
| if (item.isReadonly) { | ||
| tokens.push({ Kind: TokenKind.Keyword, Value: "readonly", HasSuffixSpace: true, IsDeprecated: deprecated }); | ||
| } | ||
|
|
||
| tokens.push({ Kind: TokenKind.MemberName, Value: item.displayName, IsDeprecated: deprecated }); | ||
|
|
||
| if (item.isOptional) { | ||
| tokens.push({ Kind: TokenKind.Punctuation, Value: "?" }); | ||
| } | ||
|
|
||
| tokens.push({ Kind: TokenKind.Punctuation, Value: ":", HasSuffixSpace: true }); | ||
|
|
||
| tokens.push({ Kind: TokenKind.TypeName, Value: item.propertyTypeExcerpt.text.trim(), IsDeprecated: deprecated }); | ||
|
|
||
| return tokens; |
Copilot
AI
Jan 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property token generator should use the createToken helper function for consistency with other token generators (method, function, class, interface). This ensures consistent token creation and reduces code duplication.
|
|
||
| tokens.push({ Kind: TokenKind.Punctuation, Value: ":", HasSuffixSpace: true }); | ||
|
|
||
| tokens.push({ Kind: TokenKind.TypeName, Value: item.propertyTypeExcerpt.text.trim(), IsDeprecated: deprecated }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, for example, types with generic type parameters x: Record<string, string>
No description provided.