Skip to content

Commit 0e88eb1

Browse files
Support output to ES6
1 parent e07e54d commit 0e88eb1

File tree

3 files changed

+81
-16
lines changed

3 files changed

+81
-16
lines changed

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
{
22
"name": "typescript-ioc",
3-
"version": "0.2.7",
3+
"version": "0.2.8",
44
"description": "A Lightweight annotation-based dependency injection container for typescript.",
55
"author": "Thiago da Rosa de Bustamante <[email protected]>",
66
"dependencies": {
7-
"reflect-metadata": "^0.1.9"
7+
"reflect-metadata": "^0.1.10"
88
},
99
"devDependencies": {
10-
"@types/jasmine": "^2.5.41",
10+
"@types/jasmine": "^2.5.47",
1111
"del": "^2.2.2",
1212
"gulp": "^3.9.1",
1313
"gulp-jasmine": "^2.4.2",
1414
"gulp-rename": "^1.2.2",
15-
"gulp-sourcemaps": "^2.4.0",
15+
"gulp-sourcemaps": "^2.6.0",
1616
"gulp-typedoc": "^2.0.2",
17-
"gulp-typescript": "^3.1.4",
17+
"gulp-typescript": "^3.1.6",
1818
"jasmine-console-reporter": "^1.2.7",
1919
"merge2": "^1.0.3",
2020
"run-sequence": "^1.2.2",
21-
"typedoc": "^0.5.5",
22-
"typescript": "^2.1.5"
21+
"typedoc": "^0.5.10",
22+
"typescript": "^2.2.2"
2323
},
2424
"keywords": [
2525
"ioc",

src/typescript-ioc.ts

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export function Provides(target: Function) {
105105
}
106106
}
107107

108+
let construct;
108109
/**
109110
* A decorator to tell the container that this class should its instantiation always handled by the Container.
110111
*
@@ -140,23 +141,25 @@ export function AutoWired(target: Function) {
140141
existingInjectedParameters.reverse();
141142
const paramTypes: Array<any> =
142143
Reflect.getMetadata("design:paramtypes", target);
143-
newConstructor = InjectorHanlder.decorateConstructor(function(...args: any[]) {
144+
newConstructor = InjectorHanlder.decorateConstructor(function ioc_wrapper(...args: any[]) {
144145
IoCContainer.assertInstantiable(target);
145146
let newArgs: Array<any> = args ? args.concat() : new Array<any>();
146147
for (let index of existingInjectedParameters) {
147148
if (index >= newArgs.length) {
148149
newArgs.push(IoCContainer.get(paramTypes[index]));
149150
}
150151
}
151-
IoCContainer.applyInjections(this, target);
152-
target.apply(this, newArgs);
152+
let ret = construct(target, newArgs, ioc_wrapper);
153+
IoCContainer.applyInjections(ret, target);
154+
return ret;
153155
}, target);
154156
}
155157
else {
156-
newConstructor = InjectorHanlder.decorateConstructor(function(...args: any[]) {
158+
newConstructor = InjectorHanlder.decorateConstructor(function ioc_wrapper(...args: any[]) {
157159
IoCContainer.assertInstantiable(target);
158-
IoCContainer.applyInjections(this, target);
159-
target.apply(this, args);
160+
let ret = construct(target, args, ioc_wrapper);
161+
IoCContainer.applyInjections(ret, target);
162+
return ret;
160163
}, target);
161164
}
162165
let config: ConfigImpl = <ConfigImpl>IoCContainer.bind(target)
@@ -533,11 +536,11 @@ class InjectorHanlder {
533536

534537
static getConstructorFromType(target: Function): FunctionConstructor {
535538
let typeConstructor: Function = target;
536-
if (typeConstructor['name']) {
539+
if (typeConstructor['name'] && typeConstructor['name'] !== 'ioc_wrapper') {
537540
return <FunctionConstructor>typeConstructor;
538541
}
539542
while (typeConstructor = typeConstructor['__parent']) {
540-
if (typeConstructor['name']) {
543+
if (typeConstructor['name'] && typeConstructor['name'] !== 'ioc_wrapper') {
541544
return <FunctionConstructor>typeConstructor;
542545
}
543546
}
@@ -568,6 +571,7 @@ class InjectorHanlder {
568571
}
569572
}
570573

574+
// For compatibility with ES5
571575
interface Map<K, V> {
572576
clear(): void;
573577
delete(key: K): boolean;
@@ -584,3 +588,62 @@ interface MapConstructor {
584588
readonly prototype: Map<any, any>;
585589
}
586590
declare var Map: MapConstructor;
591+
592+
// Polyfill for Reflect.construct. Thanks to https://github.com/Mr0grog/newless
593+
function isSyntaxSupported(example) {
594+
try { return !!Function("", "'use strict';" + example); }
595+
catch (error) { return false; }
596+
}
597+
598+
construct = global['Reflect'] && global['Reflect'].construct || (function() {
599+
if (isSyntaxSupported("class Test {}")) {
600+
// The spread operator is *dramatically faster, so use it if we can:
601+
// http://jsperf.com/new-via-spread-vs-dynamic-function/4
602+
var supportsSpread = isSyntaxSupported("Object(...[{}])");
603+
604+
return Function("constructor, args, target",
605+
"'use strict';" +
606+
"target = target || constructor;" +
607+
608+
// extend target so the right prototype is constructed (or nearly the
609+
// right one; ideally we'd do instantiator.prototype = target.prototype,
610+
// but a class's prototype property is not writable)
611+
"class instantiator extends target {};" +
612+
// but ensure the *logic* is `constructor` for ES2015-compliant engines
613+
"Object.setPrototypeOf(instantiator, constructor);" +
614+
// ...and for Safari 9
615+
"instantiator.prototype.constructor = constructor;" +
616+
617+
(supportsSpread ?
618+
"var value = new instantiator(...([].slice.call(args)));" :
619+
620+
// otherwise, create a dynamic function in order to use `new`
621+
// Note using `function.bind` would be simpler, but is much slower:
622+
// http://jsperf.com/new-operator-with-dynamic-function-vs-bind
623+
"var argList = '';" +
624+
"for (var i = 0, len = args.length; i < len; i++) {" +
625+
"if (i > 0) argList += ',';" +
626+
"argList += 'args[' + i + ']';" +
627+
"}" +
628+
"var constructCall = Function('constructor, args'," +
629+
"'return new constructor(' + argList + ');'" +
630+
");" +
631+
"var value = constructCall(constructor, args);"
632+
) +
633+
634+
// fix up the prototype so it matches the intended one, not one who's
635+
// prototype is the intended one :P
636+
"Object.setPrototypeOf(value, target.prototype);" +
637+
"return value;"
638+
);
639+
}
640+
else {
641+
var instantiator = function() {};
642+
return function construct(constructor, args, target) {
643+
instantiator.prototype = (target || constructor).prototype;
644+
var instance = new instantiator();
645+
var value = constructor.apply(instance, args);
646+
return (typeof value === "object" && value) || instance;
647+
}
648+
}
649+
})();

tsconfig.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"outDir": "./release",
88
"removeComments": true,
99
"experimentalDecorators": true,
10-
"emitDecoratorMetadata": true
10+
"emitDecoratorMetadata": true,
11+
"sourceMap": true,
12+
"mapRoot": "release/lib"
1113
},
1214
"exclude": [
1315
"node_modules",

0 commit comments

Comments
 (0)