Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

Write YAML in-line with class definition #1

Open
kevinushey opened this issue Aug 13, 2014 · 6 comments
Open

Write YAML in-line with class definition #1

kevinushey opened this issue Aug 13, 2014 · 6 comments

Comments

@kevinushey
Copy link

Perhaps instead of maintaining a YAML file separately, one could include it as a comment block alongside the class definition. For example:

/** R6
 * module: circle
 * constructor: ...
 * methods: ...
 * active: ...
 */
class circle {
public:
  double radius;
  circle(double r) : radius(r) {}
  double area() const {
    return M_PI * r * r;
  }
  double circumference() const {
    return M_PI * 2 * r;
  }
  void set_circumference(double c) {
    if (c < 0) {
      Rcpp::stop("Circumference must be positive");
    }
    radius = c / (2 * M_PI);
  }
};

Or, depending on how ambitious you are, you could imagine annotating specific fields and parsing from that:

// [[R6::module]]
class circle {
public:
  double radius;
  circle(double r) : radius(r) {}

  // [[R6::export]]
  double area() const {
    return M_PI * r * r;
  }

  // [[R6::export]]
  double circumference() const {
    return M_PI * 2 * r;
  }

  // [[R6::export]]
  void set_circumference(double c) {
    if (c < 0) {
      Rcpp::stop("Circumference must be positive");
    }
    radius = c / (2 * M_PI);
  }
};

but that would be a more long-term goal.

@richfitz
Copy link
Owner

Yes, extracting the YAML from the source would keep things nicely together. But as you say, because that could write it into the YAML file itself it can be done in a way that's backwards compatible with what is currently there, so getting that right is my focus. But it should be really easy to do, and is definitely on my radar.

The second version is a bit harder to get right: I'm trying as much as possible to avoid write anything that looks like a C++ parser. But if I can get something like libclang integration working then it'd be possible to haul out enough information to make that work. This article shows what might be possible.

One reason why neither of these has been part of the first bit of coding is my interest is largely in wrapping library code that is defined elsewhere and so annotating it is not possible.

@richfitz
Copy link
Owner

OK, having a bit of success with gcc-xml. This might actually be useful for Rcpp attributes and remove some of the issues it has with parsing prototypes and the root namespace restriction.

@richfitz
Copy link
Owner

It looks really easy to get type information with gcc-xml except for templated types (item 5). Unfortunately, that's one of the things I'm trying to get working nicely, and no information about templates is emitted in the output. That kind of makes sense because it would be a huge amount of information.

libclang promises to be able to get that working, but there is almost no documentation and nothing particularly nice to use.

@kevinushey
Copy link
Author

That's a shame :( libclang is definitely the de-facto way of parsing / handling C++ code nowadays, but you're right that tutorials / learning resources are a bit sparse (I'm still trying to take that dive myself).

Very excited to see the work you're doing here, I think that this package could really be the modern reboot that Rcpp modules needs :)

@richfitz
Copy link
Owner

I think I can get everything needed from doxygen, which is at least easy to install. I'm going to try and wire it up so that it can be swapped out for libclang though, if I can get that working (I might use RcppR6 generate an interface to libclang, even 😛).

@richfitz
Copy link
Owner

Another update: I think I can get all the required information using doxygen, gccxml or libclang,with varying levels of hassle and corner cases where one or the other won't work. I'm doing this in richfitz/cppinfo to keep this repo tidy.

However, it looks pretty straightforward to do all sorts of fun things with this information:

  • Simply filling in the boring boilerplate information, converting a very minimal yml file containing just the names of things to the full RcppR6 set.
  • @kevinushey's idea of tagging methods should be super easy. I've set things up to store line numbers so finding the line above is not a problem. This idea could be extended to add lines like [[R6::export(<classname>)]] or something to add functions to classes as pseudo-methods.
  • We could go one step further and export whole classes using something like this approach. I'm not sure how often that will be ideal, but it would not be hard to do "all functions except these".

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants