Open siegel opened 8 years ago
Here's the original "objc.c" from our hack on the old exuberant ctags source, in case that helps. objc.c.zip
(About foo.mm.zip and tags.zip we want you to put them inline. I don't want to open zip.)
C++/C parsers completely rewritten by @pragmaware. As far as I can remember he started this work to sp;lit them from Java/C#/D/Vala parsers. All of them are implemented in a source file and it was too complicated for maintaining.
Implementing ObjC parser based on the current C++/C parser looks natural for me because they really share their syntax. However, I'm not sure how @pragmaware will say about this.
If I am @pragmaware, I will say that I will accept reimplementing ObjC parser based on C++/C with following conditions: (0) the copyright of code is clarified, (1) you will maintaine the code, (2) compatiblity with old ObjC parser is considered well (breaking the compatibility is acceptable if there are enough reason, (3) you will provide enough test cases.
Here are the referenced files inline:
foo.mm
/foo.cp
:
static
void foo(int a, int b, int c)
{
}
@interface XYZ : NSObject
-(instancetype)initWithMumble: (NSObject*)mumble;
@end
@implementation XYZ
-(instancetype)initWithMumble: (NSObject*)mumble;
@end
Tags output for foo.mm:
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 0.0.0 /9434eb3/
XYZ foo.mm 13;" I line:13 interface:
XYZ foo.mm 7;" i line:7 interface:
foo foo.mm 2;" f line:2 interface:
initWithMumble: foo.mm 16;" m line:16 implementation:XYZ
initWithMumble: foo.mm 9;" m line:9 interface:XYZ
Tags output for foo.cp:
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 0.0.0 /9434eb3/
foo foo.cp 2;" f line:2 typeref:typename:void file: signature:(int a, int b, int c)
BTW, inteface:
field of foo, XYZ (implementation)and XYZ(interface) are broken.
static void prepareTag (tagEntryInfo * tag, vString const *name, objcKind kind)
{
initTagEntry (tag, vStringValue (name), &(ObjcKinds[kind]));
if (parentName != NULL)
{
This condition is not enough. vStringLength (parentName) > 0 is needed as additional condition.
I've been thinking a bit about this.
It's probably better to hack-in Objective-C support right into the new parser than doing a two pass analysis. Local variables, for instance, may appear both in C and Objective-C scopes. With two passes scoping will be just wrong.
I have done a couple of tests and it's rather feasible. However the C parser needs some refactoring before work on Objective-C can begin. The tag kinds are currently shared between C and C++ and I think they need to be split so, say, C enums are different from C++ enums and later Objective-C enums... (#977)
I think the approach you describe sounds reasonable.
As to enums, I'm not clear on what the issues are there. I know there's an "NS_ENUM
" macro and a related "CF_ENUM
" macro, which both do the same thing, and which both subtly alter the structure and discovery of enum detection. If that's what you meant by "Objective-C enums", then yeah, I agree there might be some additional work needed there.
It occurred to me that libclang
might be useful for writing a tags generator, but there are some real risks there; for one thing, it drags in an awful lot of external code; and for another, in my own experimentation I've seen some very strange (unexpected) results from parsing files with libclang. (Digging into that is on my to-do list, but I'm also trying to find someone who knows how libclang works to find some relevant expertise.)
From #1486:
This doesn't close #907.
So, reopen.
@k-takata, thank you.
See the attached "foo.mm", which contains a static C function as well as an interface and implementation section for an Objective-C class. foo.mm.zip
cd to where the file is, and then run this command:
ctags --excmd=number --tag-relative=no --fields=+a+m+n+S foo.mm
Then examine the resulting
tags
file. (Attached here: tags.zip.)The entry for
foo
has the following form:foo foo.mm 2;" f line:2 interface:
Note that the
signature
field is missing forfoo()
.Now, rename
foo.mm
tofoo.cp
and run the above command again:ctags --excmd=number --tag-relative=no --fields=+a+m+n+S foo.cp
Examine the generated tags again, and you'll see the expected entry for
foo()
:foo foo.cp 2;" f line:2 typeref:typename:void file: signature:(int a, int b, int c)
I have a hack on the old Exuberant Ctags source, which "supports" Objective-C/C++ by routing through the C parser, and then following up with some lightweight parsing to find Objective-C structures. It's different enough from the current code that it's probably impractical to integrate, but the overall strategy (layering Objective-C/C++ support on top of the C/C++ parser) might be feasible anyway.