musictheory / NilScript

Objective-C-style language superset of JavaScript with a tiny, simple runtime
Other
50 stars 5 forks source link

Support global functions #68

Closed iccir closed 8 years ago

iccir commented 8 years ago

In our source base, we have a lot of the following:

var geometry  = require("geometry");
var RectMake  = geometry.RectMake;
var RectClone = geometry.RectClone;
var RectZero  = geometry.RectZero;

var MTStaff = require("MTStaff");
var MTStaffGetMetrics = MTStaff.MTStaffGetMetrics;
var MTStaffGetVectorData = MTStaff.MTStaffGetVectorData;

This has the following disadvantages:

  1. We have to explicitly pull in each function used.
  2. Type information is lost unless we manually declare the types for RectMake/etc in our defs.d.ts file and also declare a string overload of require.
  3. The use of functions in this way cannot be squeezed, leaking unobfuscated names into our final .js file.

1 (and 2) would be better solved by ES6 if an import * from "geometry" syntax were supported. Unfortunately, the closest we can get is import * as geometry from geometry, which requires us to prefix all Rect function (geometry.RectMake). I realize that's acceptable for a lot of projects, but it makes syncing Obj-C/oj source bases harder.


Hence, the following new syntax in oj 1.2:

@global function RectMake(x : Number, y : Number, w : Number, h : Number) : Rect {
…
}
…
var r = RectMake(0, 0, 0, 0);

which will transform into:

$oj_oj._g.RectMake = function(x, y, w, h) {
…
}
…
var r = $oj_oj._g.RectMake(0, 0, 0, 0);

and will add a signature of (x:number,y:number,w:number,h:number) => (Rect) to the TypeScript defs file.

RectMake will be properly squeezed when the squeezer is turned on.

This should only affect identifiers not part of a member expression. Hence:

var foo = { RectMake: 0 }, bar = foo.RectMake;

Will not be transformed.