Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically switch API naming conventions

Background

The FreeLing API defines an interface that does not adhere to standard Java naming conventions. For example:

package freeling;

public class sentence extends ListWord {
  public void set_parse_tree(parse_tree arg0) {

The interface is defined using SWIG, which is similar to IDL:

class sentence : public std::list<word> {
 public:
  sentence(void);

  void set_parse_tree(const parse_tree &);

Problem

Academically speaking, how would you map the interface to conventional Java naming standards (e.g., class Sentence and setParseTree( parseTree arg0 ))?

Ideas

  1. Convert the 650+ line interface file manually (and send a patch to the developers).
  2. Regex search and replace voodoo (using vi): :1,$s/_\([a-z]\)/\u\1/g
  3. Create wrapper classes from the 53 auto-generated Java source files.

Thank you!

like image 447
Dave Jarvis Avatar asked May 28 '12 21:05

Dave Jarvis


People also ask

What is naming convention of API?

Names used in APIs should be in correct American English. For example, license (instead of licence), color (instead of colour). Commonly accepted short forms or abbreviations of long words may be used for brevity. For example, API is preferred over Application Programming Interface.

What are naming conventions examples?

What is an example of a good naming convention? Good naming examples include: [Project number] - Data Use Agreement - [Title of research project] Approval - Change to employee travel policy - February 2014.

What are naming conventions in programming?

In computer programming, a naming convention is a set of rules for choosing the character sequence to be used for identifiers which denote variables, types, functions, and other entities in source code and documentation.


1 Answers

SWIG provides a %rename directive that allows the names to be different in the client and implementation languages. But doing this will nearly double the length of the interface file.

Actually, SWIG provides bulk renaming. See the documentation

5.4.7.2 Advanced renaming support

While writing %rename for specific declarations is simple enough, sometimes the same renaming rule needs to be applied to many, maybe all, identifiers in the SWIG input. For example, it may be necessary to apply some transformation to all the names in the target language to better follow its naming conventions, like adding a specific prefix to all wrapped functions. Doing it individually for each function is impractical so SWIG supports applying a renaming rule to all declarations if the name of the identifier to be renamed is not specified:

%rename("myprefix_%s") ""; // print -> myprefix_print

This also shows that the argument of %rename doesn't have to be a literal string but can be a printf()-like format string. In the simplest form, "%s" is replaced with the name of the original declaration, as shown above. However this is not always enough and SWIG provides extensions to the usual format string syntax to allow applying a (SWIG-defined) function to the argument. For example, to wrap all C functions do_something_long() as more Java-like doSomethingLong() you can use the "lowercamelcase" extended format specifier like this:

%rename("%(lowercamelcase)s") ""; // foo_bar -> fooBar; FooBar -> fooBar

Some functions can be parametrized, for example the "strip" one strips the provided prefix from its argument. The prefix is specified as part of the format string, following a colon after the function name:

%rename("%(strip:[wx])s") ""; // wxHello -> Hello; FooBar -> FooBar

My recommendation is just to leave it as-is. You're calling C++ functions, they have C++ names. If anything, this helps you remember that you're calling out to C++ and need to follow C++ rules for object lifetime management, there's a slight JNI performance penalty, etc.

like image 95
Ben Voigt Avatar answered Oct 25 '22 04:10

Ben Voigt