This is an archive of the discontinued LLVM Phabricator instance.

[clang][ExtractAPI] Add support for Objective-C categories
ClosedPublic

Authored by Ruturaj4 on Jun 12 2023, 8:45 PM.

Details

Summary

Introducing support for Objective-C Categories for ExtractAPI. The suuport for Objective-C Categories is currently lacking
in terms of categories that extend a type defined in current module and categories that extend types that belong to external
modules such as NSString. Thus the objective of this patch is two fold, to fix former and the later.

This is achieved by introducing two new symbols ->

  1. objective-c.module.extension.
  2. objective-c.class.extension.

Note that the extension represents objective-c "category" (orienting well with Swift's Extension, which in spite that fact
that is different, however "broadly" serves similar purpose). The original idea is inspired by Max's @theMomax initial
post - https://forums.swift.org/t/symbol-graph-adaptions-for-documenting-extensions-to-external-types-in-docc/56684,
and Daniel's helpful comments and feedback. The implementation nonetheless is different serving purpose for this project.

The following diagram well represents the purpose ->

Diff Detail

Event Timeline

Ruturaj4 created this revision.Jun 12 2023, 8:45 PM
Herald added a project: Restricted Project. · View Herald Transcript
Ruturaj4 edited the summary of this revision. (Show Details)Jun 12 2023, 8:58 PM
Ruturaj4 edited the summary of this revision. (Show Details)Jun 12 2023, 9:03 PM
Ruturaj4 updated this revision to Diff 537064.Jul 4 2023, 5:36 AM
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Introducing support for Objective-C Categories for ExtractAPI. The suuport for Objective-C Categories is currently lacking
in terms of categories that extend a type defined in current module and categories that extend types that belong to external
modules such as NSString. Thus the objective of this patch is two fold, to fix former and the later.

This is achieved by introducing two new symbols ->

objective-c.module.extension.
objective-c.class.extension.
Note that the extension represents objective-c "category" (orienting well with Swift's Extension, which in spite that fact
that is different, however "broadly" serves similar purpose). The original idea is inspired by Max's @theMomax initial
post - https://forums.swift.org/t/symbol-graph-adaptions-for-documenting-extensions-to-external-types-in-docc/56684,
and Daniel's helpful comments and feedback. The implementation nonetheless is different serving purpose for this project.

Ruturaj4 edited the summary of this revision. (Show Details)Jul 4 2023, 5:37 AM
Ruturaj4 published this revision for review.Jul 4 2023, 5:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 4 2023, 5:46 AM

Thanks for the patch!

Like I mentioned in the inline comments, I'm not sure I understand the need of the "abstract" (in the sense that it's not really a concrete API) subtype of APIRecord. The design doesn't feel right within the existing structure.
If I recall the original issue correctly the problem is that a category might extend an interface that is not declared within the current compilation unit and the SymbolGraph output has references to an USR it cannot resolve. But that's why we have the SymbolReference Interface for the category record, and all the information we could possibly have from extract-api for that interface is already in the SymbolReference. Couldn't we use that to design an output format to indicate the external reference?

Also a side note that the word "module" has been overloaded, especially within LLVM/clang where "module" is used for clang modules or C++ modules. I would avoid creating a *ModuleRecord without qualifying it like *ExtractAPIModule and providing documentation to clarify the meaning.

clang/include/clang/ExtractAPI/API.h
148–150

I would really try to avoid patching the base APIRecord to get ways of creating "fake" records. The API records in the API set should really be all concrete symbols mapping back to an entity that is an API.
This doesn't feel right and might open up to future bad designs and bugs.

497–510

I'm still not convinced by this concept and design. Why do we need to have a subtype of APIRecord to represent relationships with external types from another "module"? We have SymbolReference for that purpose with the name and USR information.

Even if this is necessary, the name is extremely confusing. By the look of the rest of the change and the test cases, I believe this is meant to represent the external *interface* that a category is extending, not a category.

clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
128–135

This looks very concerning..
It's way too generic for its name and it's not doing what it's describing.
By the look of the call site below, this seems to be supposed to check if an *interface*, not category, is recorded in this API set. There's no reason to have a separate template function for that. You can just do the check inline and also probably covered by one of the existing llvm STLExtra utilities.

Ruturaj4 updated this revision to Diff 543982.Jul 25 2023, 7:59 AM
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Thanks for your comments and sorry for delay. I have changed the design and moved everything in SymbolGraphSerializer.cpp.

Ruturaj4 marked 3 inline comments as done.Jul 25 2023, 8:00 AM
Ruturaj4 updated this revision to Diff 546074.Aug 1 2023, 8:14 AM
  • [clang][ExtractAPI] Add support for Objective-C categories
  • [clang][ExtractAPI] Add support for Objective-C categories
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Upload the correct patch and update.

dang added inline comments.Aug 2 2023, 8:58 AM
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
488

I think this is fine for now but there must be a better way of doing this that doesn't involve traversing the whole APISet

clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
219

I don't think this is right. My expectation is that category records that need to get emitted would still have their own unique USR.

759

What happens when there are multiple categories to the same type though?

775

I would expect this to be a new relationship kind that reads as "extensionTo"

Ruturaj4 updated this revision to Diff 546682.Aug 2 2023, 8:31 PM
Ruturaj4 marked 4 inline comments as done.
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Made all the changes according to comments.

  1. Removed check on line #219 to include unique USR for categories.
  2. Explained how multiple categories to the same type are supported.
  3. Added new relationship "extensionTo".
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
488

I looked at different api methods, but still not able to figure it out. I will do it once this gets approved. In a following patch.

clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
219

Thanks. I removed the check.

759

Yes! I added this check keeping that in mind. If the parent symbol of the category is not added before then it pushes it to serialize (but skips if already present). Otherwise, just adds the category.

For e.g. in example test - objc_various_categories.m, there are two categories extending the same type:

@interface NSString (Category1)
-(void) StringMethod;
@end

@interface NSString (Category2)
-(void) StringMethod2;
@end

In this case, it adds the symbol for NSString (parent of categories Category1 and Category2). I fixed the comments to make that clear.

775

Thanks, that makes sense. I fixed it.

Ruturaj4 updated this revision to Diff 546683.Aug 2 2023, 8:33 PM
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Upload the correct patch and update.

dang accepted this revision.Aug 9 2023, 3:32 AM

LGTM

This revision is now accepted and ready to land.Aug 9 2023, 3:32 AM
Ruturaj4 updated this revision to Diff 548825.Aug 9 2023, 5:10 PM
  • [clang][ExtractAPI] Add support for Objective-C categories
  • [clang][ExtractAPI] Add support for Objective-C categories
  • [clang][ExtractAPI] Add support for Objective-C categories
  • [clang][ExtractAPI] Add support for Objective-C categories
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Fix test cases, and simulate the library interface.

dang added inline comments.Aug 15 2023, 4:55 AM
clang/test/ExtractAPI/objc_various_categories.m
9

I don't think you need to have MyClass2 and the associated myclass2.h. It's fine to check that everything looks right just for the NSString categories.

Ruturaj4 updated this revision to Diff 550303.Aug 15 2023, 6:10 AM
Ruturaj4 marked an inline comment as done.
  • [clang][ExtractAPI] Add support for Objective-C categories
  1. Updating D152770: [clang][ExtractAPI] Add support for Objective-C categories #
  2. Enter a brief description of the changes included in this update.
  3. The first line is used as subject, next lines as comment. #
  4. If you intended to create a new revision, use:
  5. $ arc diff --create

Update test to remove MyClass2.

dang accepted this revision.Aug 15 2023, 6:12 AM

LGTM