Skip to content
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

Intelligently convert C/C++ comments to Rust #791

Merged
merged 1 commit into from
Jul 8, 2017

Conversation

dylanmckay
Copy link
Contributor

With this change, we can correctly parse C++ block comments.

/**
 * Does a thing
 *
 * More documentation. This test does something
 * useful.
 */

into

/// Does a thing
///
/// More documentation. This test does something
/// useful.

Fixes #426.

@dylanmckay
Copy link
Contributor Author

Note that this does not implement the ///< doxygen syntax (which causes the doc comment to apply to the previous item).

As far as I can tell, this is currently already broken and is causing us to emit the wrong doc comments off by one on struct fields/enum variants which use the syntax.

@dylanmckay dylanmckay changed the title Intelligently convert C/C++ comments to Rust WIP: Intelligently convert C/C++ comments to Rust Jul 6, 2017
@dylanmckay
Copy link
Contributor Author

I need to modify this so that it also treats regular comments (//) as doc comments, will do so later today.

@emilio
Copy link
Contributor

emilio commented Jul 6, 2017

This is lovely, thank you!

Could we also add the test-case from #426?

@dylanmckay
Copy link
Contributor Author

I can do that.

Also, I'm going to refactor this so that rather than doing the C++ -> Rust comment conversion at the codegen level, we do it when building the AST. As far as I understand it, that would be a more appropriate place and (depending on how we build the AST - I haven't looked at it yet), we may be able to have a single call which converts comments rather than having multiple over the place.

@emilio
Copy link
Contributor

emilio commented Jul 6, 2017

Yeah, I think that's fine, though if it gets nasty we could also move the preprocess call to attributes::doc, and use it where it's not currently used. That'd remove the duplication too.

@dylanmckay dylanmckay force-pushed the preprocess-doc-comments branch 2 times, most recently from 78d2166 to 233f5db Compare July 6, 2017 10:06
@dylanmckay dylanmckay changed the title WIP: Intelligently convert C/C++ comments to Rust Intelligently convert C/C++ comments to Rust Jul 6, 2017
@dylanmckay
Copy link
Contributor Author

I've added the test case from #426 and also moved the preprocessing to the IR stage.

Let me know if you'd like me to change anything in order to merge :)

@dylanmckay dylanmckay force-pushed the preprocess-doc-comments branch 2 times, most recently from ae79118 to aefffc6 Compare July 6, 2017 10:22
Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

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

I'm thinking that handling comment processing in code generation makes sense, actually, because we can re-indent depending on the nesting level of the item, etc... However, that's followup work in any case, and it's easy enough to move it so... This can land with r=me with Travis fixed:

error: missing documentation for a module
 --> src/ir/mod.rs:8:1
  |
8 | pub mod comment;
  | ^^^^^^^^^^^^^^^^
  |

@emilio
Copy link
Contributor

emilio commented Jul 6, 2017

Thanks again for doing this btw! :)

@dylanmckay dylanmckay force-pushed the preprocess-doc-comments branch 2 times, most recently from bc15759 to 4dca1b1 Compare July 6, 2017 12:38
@dylanmckay
Copy link
Contributor Author

Thanks again for doing this btw! :)

No problem, thanks for working on the project :)

I've fixed the comment issue but I can't get the convert-cpp-comments-to-rust test I added to match the expected header file.

Here is a part of the diff from the travis run

It seems as if it's related to environment differences between my computer and CI, but I can't really replicate the exact same build setup as them.

pub const _STDINT_H: ::std::os::raw::c_uint = 1;
 pub const _FEATURES_H: ::std::os::raw::c_uint = 1;
+pub const __USE_ANSI: ::std::os::raw::c_uint = 1;
 pub const _ISOC95_SOURCE: ::std::os::raw::c_uint = 1;
 pub const _ISOC99_SOURCE: ::std::os::raw::c_uint = 1;
-pub const _ISOC11_SOURCE: ::std::os::raw::c_uint = 1;
 pub const _POSIX_SOURCE: ::std::os::raw::c_uint = 1;
 pub const _POSIX_C_SOURCE: ::std::os::raw::c_uint = 200809;
 pub const _XOPEN_SOURCE: ::std::os::raw::c_uint = 700;
 pub const _XOPEN_SOURCE_EXTENDED: ::std::os::raw::c_uint = 1;
 pub const _LARGEFILE64_SOURCE: ::std::os::raw::c_uint = 1;
-pub const _DEFAULT_SOURCE: ::std::os::raw::c_uint = 1;
+pub const _BSD_SOURCE: ::std::os::raw::c_uint = 1;
+pub const _SVID_SOURCE: ::std::os::raw::c_uint = 1;
 pub const _ATFILE_SOURCE: ::std::os::raw::c_uint = 1;
-pub const __USE_ISOC11: ::std::os::raw::c_uint = 1;
 pub const __USE_ISOC99: ::std::os::raw::c_uint = 1;
 pub const __USE_ISOC95: ::std::os::raw::c_uint = 1;
 pub const __USE_POSIX: ::std::os::raw::c_uint = 1;
 pub const __USE_POSIX2: ::std::os::raw::c_uint = 1;
 pub const __USE_POSIX199309: ::std::os::raw::c_uint = 1;
 pub const __USE_POSIX199506: ::std::os::raw::c_uint = 1;
 pub const __USE_XOPEN2K: ::std::os::raw::c_uint = 1;
 pub const __USE_XOPEN2K8: ::std::os::raw::c_uint = 1;
 pub const __USE_XOPEN: ::std::os::raw::c_uint = 1;
 pub const __USE_XOPEN_EXTENDED: ::std::os::raw::c_uint = 1;
 pub const __USE_UNIX98: ::std::os::raw::c_uint = 1;
 pub const _LARGEFILE_SOURCE: ::std::os::raw::c_uint = 1;
 pub const __USE_XOPEN2K8XSI: ::std::os::raw::c_uint = 1;
 pub const __USE_XOPEN2KXSI: ::std::os::raw::c_uint = 1;
 pub const __USE_LARGEFILE: ::std::os::raw::c_uint = 1;
 pub const __USE_LARGEFILE64: ::std::os::raw::c_uint = 1;
 pub const __USE_MISC: ::std::os::raw::c_uint = 1;
+pub const __USE_BSD: ::std::os::raw::c_uint = 1;
+pub const __USE_SVID: ::std::os::raw::c_uint = 1;

Does this ring any bells @emilio?

@@ -0,0 +1,16 @@
#include <stddef.h>
#include <stdint.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, tests can't have system includes to pass, since these are machine-dependent.

#include <stddef.h>
#include <stdint.h>

typedef uint32_t mbedtls_mpi_uint;
Copy link
Contributor

Choose a reason for hiding this comment

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

instead you can remove them and, let's say, replace uint32_t for unsigned, and size_t for unsigned long. they're irrelevant to the test-case anyway, so it seems sensible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very helpful, thanks!

With this change, we can correctly parse C++ block comments.

```
/**
 * Does a thing
 *
 * More documentation. This test does something
 * useful.
 */
```

into

```
/// Does a thing
///
/// More documentation. This test does something
/// useful.
```

Fixes rust-lang#426.
@dylanmckay
Copy link
Contributor Author

Tests are now green @emilio, thanks for the help!

@emilio
Copy link
Contributor

emilio commented Jul 8, 2017

Looks great, thanks again for this!

@bors-servo r+

@bors-servo
Copy link

📌 Commit 239a015 has been approved by emilio

@bors-servo
Copy link

⌛ Testing commit 239a015 with merge f19e576...

bors-servo pushed a commit that referenced this pull request Jul 8, 2017
Intelligently convert C/C++ comments to Rust

With this change, we can correctly parse C++ block comments.

```cpp
/**
 * Does a thing
 *
 * More documentation. This test does something
 * useful.
 */
```

into

```rust
/// Does a thing
///
/// More documentation. This test does something
/// useful.
```

Fixes #426.
@bors-servo
Copy link

☀️ Test successful - status-travis
Approved by: emilio
Pushing f19e576 to master...

@bors-servo bors-servo merged commit 239a015 into rust-lang:master Jul 8, 2017
@jethrogb
Copy link
Contributor

jethrogb commented Jul 8, 2017

Author of #426 here. I didn't get a notification when this PR was opened.

Why are you converting into Rust doc comments? It seems highly unlikely that rustdoc or rustdoc --test will be able to deal with random C++ comments correctly.

@emilio
Copy link
Contributor

emilio commented Jul 8, 2017

Why are you converting into Rust doc comments? It seems highly unlikely that rustdoc or rustdoc --test will be able to deal with random C++ comments correctly.

Well, sure, but that's followup work anyway. I think it's nice to have the comment in a processable format, which is what this PR enables. This PR also fixes the most common cases where people doesn't use markdown for their C/C++ docs.

If we want to support fully rustdoc, etc, there may be more followup work needed. An easy way to generate comments and make rustdoc not complain is making comments normal // comments.

Anyway, I've followed up in #799 with fixes and a few features that this PR enabled. I think Markdown/Doxygen support can be discussed in a new issue. Will file one to that effect.

@emilio
Copy link
Contributor

emilio commented Jul 8, 2017

I opened #800 for that.

@dylanmckay
Copy link
Contributor Author

@emilio would it be possible for a new revision to be published so I can use this in one of my own crates?

@dylanmckay dylanmckay deleted the preprocess-doc-comments branch July 8, 2017 23:06
@emilio
Copy link
Contributor

emilio commented Jul 9, 2017

@dylanmckay sure, though I'd wait for #799 to merge to fix the panic when a class is documented with an empty multiline comment (/**/), I don't want to release known panics. I'll push a version bump to that PR :)

@dylanmckay
Copy link
Contributor Author

Sounds good to me, thanks @emilio :)

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.

5 participants