Code conversion is a menial, laborious, and fairly uninteresting task, but you take any time savers you can. When I’ve written code that works, rewriting it by hand on another platform is more of a drag than a bit of syntax wrangling.
Needless to say, there are many hours of swapping “var x:Thing” declarations, moving ivars into headers and their default values into .m inits, then the methods; () to [] - even more time consuming when I bother to use the descriptive method style in obj c, which I generally do. Subtle pattern swapping, none of it difficult, just a hell of a lot of it.
Until now I’ve had projects small enough (at least in transferred code-volume terms) that I’ve been able to stand the manual work, but my latest Flash game finally put me over the tipping point.
I spent a little time on a tool to take care of the menial changes - nothing too advanced yet, but already very helpful.
Here’s an example conversion:
original class |
.h output |
.m output |
What it does so far:
- all variable declarations converted to obj c style - atomic types detected first, then pointer/object style assumed for anything else.
- find public instance variables, declare them in the header and set up @property/synthesize
- private/protected variables found and added to header
- all instance variables declared in header are given their default values in the -(id)init method of the .m, or NULL/false/0 if none was specified in the AS3 class.
- find static variables and recreate them in the .m (doesn’t yet create external access in the case of things that were public static)
- convert all class methods to objective C syntax - build descriptive methods where more than one parameter exists
- replace math calls - e.g. Math.floor() -- floorf()
- identify method calls on this/self and replace syntax (currently very limited - I’ve only coded this to respond to calls without parameters so far as this area gets a bit more complex)
what it doesn’t do yet (or maybe ever):
- method calls on objects - e.g. instanceOfThing.doSomething() - is left alone. This simple example would be ok - but looking at another example: instanceOfThing.getSubThingMatching(banana.whatColourAmI(UniverseConstants.ON_TUESDAYS)).x = 5; ...it’s kind of getting deeper than I really need to go for my purposes.
- object/instance creation e.g. var a:Thing = new Thing(); - I think I’ll probably add this, at least just with a default [[alloc] init] case that should be ok a lot of the time.
- various other edge-cases I haven’t gotten to, and probably lots I’ve forgotten.
So that’s about it so far. Already very handy for my current project
With a little more work and some tidying up, it may possibly make it’s way into shoebox as a droplet tool. Currently in testing, you can drop a .as file on and be given .h and .m files in the source directory.
I’m undecided as to whether it’d be worth the trouble of loading a full directory and exploring an entire class hierarchy to better convert method calls and the like - would be a fun challenge, but total overkill.