[libclang] Allow pretty printing declarations
ClosedPublic

Authored by nik on Nov 10 2017, 8:12 AM.

Details

Summary

Introduce clang_getCursorPrettyPrinted() for pretty printing
declarations. Expose also PrintingPolicy, so the user gets more
fine-grained control of the entities being printed.

The already existing clang_getCursorDisplayName() is pretty limited -
for example, it does not handle return types, parameter names or default
arguments for function declarations. Addressing these issues in
clang_getCursorDisplayName() would mean to duplicate existing code
(e.g. clang::DeclPrinter), so rather expose new API to access the
existing functionality.

Diff Detail

nik created this revision.Nov 10 2017, 8:12 AM

I'm not too happy with the current version because of all the getters/setters/dispose functions. Has anyone a better idea? :) PrintingPolicy can be (mostly) mapped to an enum, but unfortunately PrintingPolicy::Indentation does not play well with that. Also, the enum probably wouldn't be too future proof, so I chose the opaque pointer approach.

The "See \c clang::PrintingPolicy for more information." references might be another issue. But this felt better than duplicating the already existing documentation...

nik added a subscriber: cfe-commits.
nik added a comment.Nov 16 2017, 11:26 PM

Ping, please review :)

jbcoe resigned from this revision.Nov 21 2017, 12:22 PM
nik added a comment.Nov 23 2017, 12:23 AM

Ping, please review or add more appropriate reviewers.

nik added a comment.Nov 28 2017, 12:56 AM

Ping III - is there anything I can do to get this reviewed faster? 3 weeks passed.

nik updated this revision to Diff 125129.Dec 1 2017, 6:37 AM

Rebased only.

Locally we've done something similar (adding a clang_getCursorPrettyPrintedDeclaration function, though without exposing the PrintingPolicy) and overhauled DeclPrinter to produce proper pretty names. This is a hack that works well for us, but can never be upstreamed since it breaks too much existing code (and some of the printing decisions are subjective). Your way is better.

I can point out differences in our implementations if you like. The diff is rather long, though.

ilya-biryukov resigned from this revision.Dec 6 2017, 1:29 AM
nik added a comment.Dec 8 2017, 5:47 AM

Locally we've done something similar (adding a clang_getCursorPrettyPrintedDeclaration function, though without exposing the PrintingPolicy) and overhauled DeclPrinter to produce proper pretty names. This is a hack that works well for us, but can never be upstreamed since it breaks too much existing code (and some of the printing decisions are subjective). Your way is better.

You might consider to enhance PrintingPolicy for your use cases?

I can point out differences in our implementations if you like. The diff is rather long, though.

That would be interesting, yes, but rather later.

First I would like to get a review for this one...

Ping.

nik updated this revision to Diff 129258.Jan 10 2018, 5:22 AM

Rebased only, please review.

jbcoe added inline comments.Jan 11 2018, 12:29 AM
include/clang-c/Index.h
4118

Could one use an enum to get/set different properties of the policy?

clang_PrintingPolicy_get(CXPrintingPolicy Policy, unsigned Property);
clang_PrintingPolicy_set(CXPrintingPolicy Policy, unsigned Property, unsigned Value);

I've seen other C-API's (for Linear and Quadratic programming) follow a similar approach quite extensibly.

It would significantly reduce the size of the API.

nik updated this revision to Diff 129426.Jan 11 2018, 3:51 AM

Could one use an enum to get/set different properties of the policy?

I've seen other C-API's (for Linear and Quadratic programming) follow a similar approach quite extensibly.

It would significantly reduce the size of the API.

You are right and rethinking this, I see no problem with it. I thought of that too (see my very first comment to this change), but then for some reason the PrintingPolicy::Indentation (unsigned : 8) has driven me to this version. I probably have only thought of strictly false/true values to set/get.

OK, adapted to enum version.

nik updated this revision to Diff 129427.Jan 11 2018, 4:05 AM

Used macros as in a previous version to make it less verbose and error prone.

jbcoe added a comment.Jan 11 2018, 8:31 AM

It might be worth adding some very simple get/set tests to ensure that properties are set as intended.

tools/libclang/CIndex.cpp
4720

I’m not convinced that the code replaced by the macro is sufficiently complicated to justify use of a macro.

4763

I’m not convinced that the code replaced by the macro is sufficiently complicated to justify use of a macro.

jbcoe removed a reviewer: jbcoe.Jan 11 2018, 8:31 AM
jbcoe added a reviewer: jbcoe.
jbcoe added inline comments.Jan 11 2018, 1:35 PM
tools/libclang/libclang.exports
365

clang_PrintingPolicy_setProperty and clang_PrintingPolicy_getProperty might be better names (I know the ones you have used were my earlier suggestions).

nik added a comment.Jan 12 2018, 1:54 AM

It might be worth adding some very simple get/set tests to ensure that properties are set as intended.

clang_PrintingPolicy_setProperty is already called in c-index-test.c and covered with test/Index/print-display-names.cpp. Do you have another kind of test in mind?

I'm not sure how to best test clang_PrintingPolicy_getProperty. I don't see how to get that cleanly covered within c-index-test.c, too. After calling the setter, one could call the getter and verify that it's the same. But c-index-test shouldn't do something like this. I've added a test in LibclangTest.cpp with which I'm not too happy (an extra parse just to test a getter feels wrong).

tools/libclang/CIndex.cpp
4720

I find it easier to read and verify (mapping to the wrong property can't happen), but I've no strong opinion here, fine with me - reverted to non-macro case.

tools/libclang/libclang.exports
365

Agree!

nik updated this revision to Diff 129591.Jan 12 2018, 1:55 AM

Addressed comments.

jbcoe added a comment.Jan 12 2018, 3:24 AM

Looking good, only a few nits.

tools/libclang/CIndex.cpp
4782

Might be worth asserting here.

unittests/libclang/LibclangTest.cpp
596 ↗(On Diff #129591)

It would be useful, albeit tedious, to add get/set test pairs for each property.

nik marked an inline comment as done.Jan 12 2018, 4:20 AM
nik added inline comments.
tools/libclang/CIndex.cpp
4782

Good idea. I've done the same for the setter.

unittests/libclang/LibclangTest.cpp
596 ↗(On Diff #129591)

I think we have the basic functionality of the getter and setter covered. Testing each getter/setter for each property would mostly help to verify the mapping in the getters/setters - initially I've ruled out that possibility with the macros (once the macro is correct - but that's much easier to check). I would prefer to go back to the macro version than adding a test here that goes over all properties.

nik updated this revision to Diff 129600.Jan 12 2018, 4:20 AM
nik marked an inline comment as done.

Added assert() for getter/setter.

jbcoe requested changes to this revision.Jan 12 2018, 5:54 AM
jbcoe added inline comments.
unittests/libclang/LibclangTest.cpp
596 ↗(On Diff #129591)

I think the macro in implementation harms readability and the tests are pretty simple to add (maybe even using a macro).

The current setup of a switch and no low-level tests leaves things open to breakage in future.

This revision now requires changes to proceed.Jan 12 2018, 5:54 AM
nik updated this revision to Diff 129635.Jan 12 2018, 8:20 AM

What about this? :)

jbcoe added inline comments.Jan 13 2018, 3:01 AM
tools/c-index-test/c-index-test.c
93

I'm not sure that joining the struct definition and variable definition like this gains much and does not aid readability.

nik marked an inline comment as done.Jan 14 2018, 11:45 PM
nik updated this revision to Diff 129805.Jan 14 2018, 11:46 PM

Addressed inline comment.

jbcoe accepted this revision.Jan 14 2018, 11:52 PM
This revision is now accepted and ready to land.Jan 14 2018, 11:52 PM
nik added a comment.Jan 14 2018, 11:55 PM

Can you submit this for me? I don't have the permissions.

I can merge this for you.

Please add me as reviewer in any follow-up patches and we can turn them around more quickly.

nik added a comment.Jan 16 2018, 12:36 AM

I can merge this for you.
Please add me as reviewer in any follow-up patches and we can turn them around more quickly.

That would be nice, thanks! I don't have any follow-up patches right now.

This revision was automatically updated to reflect the committed changes.