I have the following two classes:
package geometer;
class Vector2Impl {
public var x: Float;
public var y: Float;
... operations and methods...
package geometer;
@:forward(x, y)
abstract Vector2(Vector2Impl) from Vector2Impl to Vector2Impl {
public
function new(x: Float, y: Float) {
this = new Vector2Impl(x, y);
}
... operator overloads ...
}
I did this so I could overload operators in Vector2
. This all works fine from inside of Haxe, however, we compile from Haxe to JavaScript. Our output JavaScript is then used in mocha tests.
Unfortunately, classes declared abstract
are completely omitted from the JS code (well, this isn't entirely true, but they do look something like:
var geometer__$Vector2_Vector2_$Impl_$ = {};
geometer__$Vector2_Vector2_$Impl_$.__name__ = true;
geometer__$Vector2_Vector2_$Impl_$._new = function(x,y) {
return new geometer_Vector2Impl(x,y);
};
So, in my tests, instead of using Vector2
, I am forced to use Vector2Impl
. This is a bit of a pain, because a) it requires more typing, and b) it exposes an inconsistent interface between Haxe clients and JavaScript clients. I could deal with it, but since Haxe isn't completely compiling out the type Vector2
, I'm wondering if there is a way I can alias Vector2Impl
to Vector2
inside of the generated .js
file. That way, instead of doing the following in my tests:
'use strict';
let expect = require('chai').expect;
let library = require('../../dist/library.js');
let geometer = library.geometer;
// Unfortunately, abstract classes (Vector2) are not available in JS-land.
let Vector2Impl = geometer.Vector2Impl;
require('../nyc-reporter');
describe('Vector2Impl', function() {
describe ('#new', function() {
it ('should create a new Vector2Impl object', function() {
let v = new Vector2Impl(20.5, 100.0);
expect(v.x).to.eq(20.5);
expect(v.y).to.eq(100.0);
});
});
});
I could do this:
'use strict';
let expect = require('chai').expect;
let library = require('../../dist/library.js');
let geometer = library.geometer;
// Unfortunately, abstract classes (Vector2) are not available in JS-land.
let Vector2 = geometer.Vector2;
require('../nyc-reporter');
describe('Vector2', function() {
describe ('#new', function() {
it ('should create a new Vector2 object', function() {
let v = new Vector2(20.5, 100.0);
expect(v.x).to.eq(20.5);
expect(v.y).to.eq(100.0);
});
});
});
Obviously, I know that I can't use the operator overloads in JavaScript, since the language doesn't support it, but if I could use all the other methods available in Vector2Impl
by calling it Vector2
, that would be awesome.
NOTE: I know I could just do this:
let Vector2 = geometer.Vector2Impl;
But, I'd rather the client not even be aware of the Vector2Impl
class, if possible.
You could simply annotate Vector2DImpl
with @:expose
metadata:
@:expose("geometer.Vector2D")
class Vector2Impl {
...
}
This includes it in $hx_exports
as geometer.Vector2D
.
©2020 All rights reserved.