Skip to content

[api-documenter/-extractor/-model] Support 'abstract' Modifier - #3662

Merged
Pete Gonzalez (octogonz) merged 13 commits into
microsoft:mainfrom
fwienber:fwienber/support-abstract-modifier
Jan 25, 2023
Merged

Pete Gonzalez (octogonz) merged 13 commits into
microsoft:mainfrom
fwienber:fwienber/support-abstract-modifier

Conversation

@fwienber

@fwienber Frank Wienberg (fwienber) commented Sep 29, 2022 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #3661

Proposal implementation of issue #3661.

Fully supporting the abstract modifier in api-documenter involves extending the model (api-extractor-model) and letting api-extractor extract the information into the model.

Then, api-documenter can check whether API items have the new ApiAbstractMixin and if the new isAbstract property is true, add the modifier to the output. On the fly, the order of modifiers has been slightly adjusted to match the required order in TypeScript syntax.

For abstract classes, instead of adding a "Modifier" column for just this one modifier, a dedicated table has been added, because as an API designer, I think of abstract classes as a third category in between interfaces and (non-abstract) classes. Like interfaces, they cannot be instantiated, but like classes, you can subclass them.

use as type subclass instantiate
interface ✅ ❌ ❌
abstract class ✅ ✅ ❌
class ✅ ✅ ✅

Details

There are separate commits for the changes in api-extractor(-model) and api-documenter.
Adding a property to the model affects many generated *.api.json model files.

The last commit implements the second alternative mentioned in #3661: Instead of adding a "Modifiers" column to the "Classes" overview table, a separate table for "Abstract Classes" is added to the Markdown output.

Note that other output targets beyond Markdown are not yet handled explicitly. Please advise if there is anything left to do.

How it was tested

Tests for the changes have been complemented in an existing test scenario (api-extractor) or added as a new one (api-documenter). A new API schema version has been added. (This also updates several *.api.json model files.)

A change log entry has been added.

Analogous to other ApiItem mixins, the new ApiAbstractMixin
adds 'isAbstract' as a property aspect. It is mixed into
ApiClass and ApiMethod, the only models that may have an
'abstract' modifier. ApiModelGenerator detects the modifier
and adds it to the models.
This change updates all generated *.api.json files to
include the new "isAbstract" property.
Generate "abstract" if an API item has the ApiAbstractMixin
and 'isAbstract' is true.
So far, this only works for methods, since the classes
overview table does not have a "Modifiers" column.
Split classes into abstract and non-abstract classes
and add a separate overview table for "Abstract Classes".
The alternative would be to add a "Modifiers" column to
the existing "Classes" overview table.
Comment thread libraries/api-extractor-model/src/mixins/ApiAbstractMixin.ts
Comment thread apps/api-documenter/src/documenters/MarkdownDocumenter.ts
Comment thread apps/api-documenter/src/documenters/MarkdownDocumenter.ts

@zelliott Zack Elliott (zelliott) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Two final comments;

  • You'll want to bump the .api.json version in DeserializerContext.ts. See previous edits to that file for examples.
  • It'd be great to have at least one test in build-tests/ where isAbstract is true. If we already have one - great - if not, let's add one.

@fwienber

Copy link
Copy Markdown
Contributor Author

Just FYI, I did not forget about this PR, but I'm busy with another project for a couple of days.

…also for ApiProperty

When adding 'abstract' for classes and methods, @zelliott
mentioned that properties can have this modifier, too.
Thus, ApiProperty must be extended just like ApiMethod and
ApiClass, and ApiModelGenerator must extract the 'abstract'
modifier into the ApiProperty model.
Expected test results change accordingly.
@fwienber

Copy link
Copy Markdown
Contributor Author
  • It'd be great to have at least one test in build-tests/ where isAbstract is true. If we already have one - great - if not, let's add one.

There already was an abstract class with an abstract method, now resulting in an "isAbstract": true entry in the expected API JSON.
Do you think we need to complement test data for an abstract property?

…ract-modifier

# Conflicts:
#	apps/api-extractor/src/generators/ApiModelGenerator.ts
The support to track and render 'abstract' modifiers on
classes, methods, and properties affects api-extractor-model,
api-extractor, and api-documenter.
Unlike other languages like Java, in TypeScript, the order of
modifiers is defined strictly. Currently, it looks like api-documenter
uses alphabetical order, which is not the correct TypeScript modifier
order. It seems the correct order is

(`public` | `protected` | `private`)? (`static`? | `abstract`?) `override`? `readonly`?

No member can be `static` and `abstract` at the same time, so the
order of these two does not matter. api-documenter currently only
uses `protected`, `static`, `abstract` (new in this PR) and `readonly`,
so `public` (default!), `private` (no API!) and `override` (maybe
interesting for navigation, but not as a modifier) do not apply.

Added a code comment about the order and moved `readonly` to the
last position so that the overall modifier output order now matches
TypeScript syntax.
@fwienber

Frank Wienberg (fwienber) commented Oct 18, 2022 •

Copy link
Copy Markdown
Contributor Author

I guess I now addressed all review issues and thus resolved the conversations above. Zack Elliott (@zelliott), please re-review and of course feel free to re-open any resolved conversation to comment!

@fwienber

Copy link
Copy Markdown
Contributor Author

If you don't like the merge commit that resolves the conflict with "main", I can also rebase my branch, but didn't want to do so while there are comments on the commits that would be lost when force-pushing the rebased branch.

 The schema version was updated from 1010 to 1011 in 2088fd3,
 so this changed should be squashed with 2088fd3.
@fwienber

Copy link
Copy Markdown
Contributor Author

I had a bit more time and added more tests:

  • added an abstract property to api-extractor-scenarios
  • added an abstract class with an abstract method & property to api-documentor-scenarios

Diff in regenerated report files looks good.

@fwienber

Copy link
Copy Markdown
Contributor Author

ping

@zelliott

Zack Elliott (zelliott) commented Oct 26, 2022 •

Copy link
Copy Markdown
Contributor

Hoping to take a look this weekend... maybe sooner. Sorry for the delay!

@zelliott

Copy link
Copy Markdown
Contributor

There already was an abstract class with an abstract method, now resulting in an "isAbstract": true entry in the expected API JSON.
Do you think we need to complement test data for an abstract property?

No, I think that's good enough then. Thanks for checking!

Comment thread build-tests/api-documenter-scenarios/src/inheritedMembers/index.ts Outdated

@zelliott Zack Elliott (zelliott) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the very long delay, have been busy with other work (as we all are!). LGTM!

@zelliott

Copy link
Copy Markdown
Contributor

Zack Elliott (@zelliott) Sorry, this time I missed the notification, then was out of office last week. I moved the test (last unresolved conversation) as you recommended. Next step is to find a code owner for review?

Yep! LGTM

@fwienber

Copy link
Copy Markdown
Contributor Author

So how is the process here? Are the four mentioned code owners supposed to notice that this PR is ready for review, or do I have to ping (any of) them?

@zelliott

Copy link
Copy Markdown
Contributor

I don't think there's any well defined process unfortunately, Pete Gonzalez (@octogonz) to correct me otherwise. I typically ping Pete Gonzalez (@octogonz) over Zulip chat or on the PR itself.

@fwienber

Copy link
Copy Markdown
Contributor Author

Okay, magic spell "ping Pete Gonzalez (@octogonz)" 🧞

@octogonz

Copy link
Copy Markdown
Collaborator

Sorry I overlooked this PR! 😅 (In the future, you can ping me personally on Zulip if needed.)

@octogonz
Pete Gonzalez (octogonz) merged commit e75bca0 into microsoft:main Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[api-documenter] 'abstract' missing in "Methods" overview table's "Modifiers" column

3 participants