@@ -74,7 +74,7 @@ function stringifyFn(fn) {
74
74
// Support: Chrome 50-51 only
75
75
// Creating a new string by adding `' '` at the end, to hack around some bug in Chrome v50/51
76
76
// (See https://github.com/angular/angular.js/issues/14487.)
77
- // TODO (gkalpak): Remove workaround when Chrome v52 is released
77
+ // TODO(gkalpak): Remove workaround when Chrome v52 is released
78
78
return Function . prototype . toString . call ( fn ) + ' ' ;
79
79
}
80
80
@@ -129,6 +129,10 @@ function annotate(fn, strictDi, name) {
129
129
return $inject ;
130
130
}
131
131
132
+ function stringifyServiceId ( id , suffix ) {
133
+ return ( isUndefined ( id ) || isString ( id ) ) ? id : id + suffix ;
134
+ }
135
+
132
136
///////////////////////////////////////
133
137
134
138
/**
@@ -649,34 +653,34 @@ function createInjector(modulesToLoad, strictDi) {
649
653
var INSTANTIATING = { } ,
650
654
providerSuffix = 'Provider' ,
651
655
path = [ ] ,
652
- loadedModules = new HashMap ( [ ] , true ) ,
653
- providerCache = {
656
+ loadedModules = new HashMap ( null , true ) ,
657
+ providerCache = new HashMap ( {
654
658
$provide : {
655
- provider : supportObject ( provider ) ,
656
- factory : supportObject ( factory ) ,
657
- service : supportObject ( service ) ,
658
- value : supportObject ( value ) ,
659
- constant : supportObject ( constant ) ,
660
- decorator : decorator
661
- }
662
- } ,
663
- providerInjector = ( providerCache . $injector =
664
- createInternalInjector ( providerCache , function ( serviceName , caller ) {
665
- if ( angular . isString ( caller ) ) {
666
- path . push ( caller ) ;
667
- }
659
+ provider : supportObject ( provider ) ,
660
+ factory : supportObject ( factory ) ,
661
+ service : supportObject ( service ) ,
662
+ value : supportObject ( value ) ,
663
+ constant : supportObject ( constant ) ,
664
+ decorator : decorator
665
+ }
666
+ } ) ,
667
+ instanceCache = new HashMap ( ) ,
668
+ providerInjector =
669
+ createInternalInjector ( providerCache , function ( serviceName ) {
668
670
throw $injectorMinErr ( 'unpr' , "Unknown provider: {0}" , path . join ( ' <- ' ) ) ;
669
- } ) ) ,
670
- instanceCache = { } ,
671
+ } , ' (provider)' ) ,
671
672
protoInstanceInjector =
672
- createInternalInjector ( instanceCache , function ( serviceName , caller ) {
673
- var provider = providerInjector . get ( serviceName + providerSuffix , caller ) ;
674
- return instanceInjector . invoke (
675
- provider . $get , provider , undefined , serviceName ) ;
673
+ createInternalInjector ( instanceCache , function ( serviceName ) {
674
+ var providerId = ! isString ( serviceName ) ? serviceName : serviceName + providerSuffix ;
675
+ var provider = providerInjector . get ( providerId ) ;
676
+
677
+ return instanceInjector . invoke ( provider . $get , provider , undefined , serviceName ) ;
676
678
} ) ,
677
679
instanceInjector = protoInstanceInjector ;
678
680
679
- providerCache [ '$injector' + providerSuffix ] = { $get : valueFn ( protoInstanceInjector ) } ;
681
+ providerCache . put ( '$injector' , providerInjector ) ;
682
+ providerCache . put ( '$injector' + providerSuffix , { $get : valueFn ( protoInstanceInjector ) } ) ;
683
+
680
684
var runBlocks = loadModules ( modulesToLoad ) ;
681
685
instanceInjector = protoInstanceInjector . get ( '$injector' ) ;
682
686
instanceInjector . strictDi = strictDi ;
@@ -690,7 +694,7 @@ function createInjector(modulesToLoad, strictDi) {
690
694
691
695
function supportObject ( delegate ) {
692
696
return function ( key , value ) {
693
- if ( isObject ( key ) ) {
697
+ if ( ( arguments . length === 1 ) && isObject ( key ) ) {
694
698
forEach ( key , reverseParams ( delegate ) ) ;
695
699
} else {
696
700
return delegate ( key , value ) ;
@@ -706,7 +710,11 @@ function createInjector(modulesToLoad, strictDi) {
706
710
if ( ! provider_ . $get ) {
707
711
throw $injectorMinErr ( 'pget' , "Provider '{0}' must define $get factory method." , name ) ;
708
712
}
709
- return ( providerCache [ name + providerSuffix ] = provider_ ) ;
713
+
714
+ var providerId = ! isString ( name ) ? name : name + providerSuffix ;
715
+ providerCache . put ( providerId , provider_ ) ;
716
+
717
+ return provider_ ;
710
718
}
711
719
712
720
function enforceReturnValue ( name , factory ) {
@@ -726,21 +734,24 @@ function createInjector(modulesToLoad, strictDi) {
726
734
}
727
735
728
736
function service ( name , constructor ) {
729
- return factory ( name , [ '$injector' , function ( $injector ) {
730
- return $injector . instantiate ( constructor ) ;
731
- } ] ) ;
737
+ return factory ( name , function ( ) {
738
+ return instanceInjector . instantiate ( constructor ) ;
739
+ } ) ;
732
740
}
733
741
734
- function value ( name , val ) { return factory ( name , valueFn ( val ) , false ) ; }
742
+ function value ( name , val ) {
743
+ return factory ( name , valueFn ( val ) , false ) ;
744
+ }
735
745
736
746
function constant ( name , value ) {
737
747
assertNotHasOwnProperty ( name , 'constant' ) ;
738
- providerCache [ name ] = value ;
739
- instanceCache [ name ] = value ;
748
+ providerCache . put ( name , value ) ;
749
+ instanceCache . put ( name , value ) ;
740
750
}
741
751
742
752
function decorator ( serviceName , decorFn ) {
743
- var origProvider = providerInjector . get ( serviceName + providerSuffix ) ,
753
+ var providerId = ! isString ( serviceName ) ? serviceName : serviceName + providerSuffix ;
754
+ var origProvider = providerInjector . get ( providerId ) ,
744
755
orig$get = origProvider . $get ;
745
756
746
757
origProvider . $get = function ( ) {
@@ -775,9 +786,7 @@ function createInjector(modulesToLoad, strictDi) {
775
786
runBlocks = runBlocks . concat ( loadModules ( moduleFn . requires ) ) . concat ( moduleFn . _runBlocks ) ;
776
787
runInvokeQueue ( moduleFn . _invokeQueue ) ;
777
788
runInvokeQueue ( moduleFn . _configBlocks ) ;
778
- } else if ( isFunction ( module ) ) {
779
- runBlocks . push ( providerInjector . invoke ( module ) ) ;
780
- } else if ( isArray ( module ) ) {
789
+ } else if ( isFunction ( module ) || isArray ( module ) ) {
781
790
runBlocks . push ( providerInjector . invoke ( module ) ) ;
782
791
} else {
783
792
assertArgFn ( module , 'module' ) ;
@@ -805,29 +814,44 @@ function createInjector(modulesToLoad, strictDi) {
805
814
// internal Injector
806
815
////////////////////////////////////
807
816
808
- function createInternalInjector ( cache , factory ) {
817
+ function createInternalInjector ( cache , factory , suffix ) {
818
+ suffix = suffix || '' ;
809
819
810
820
function getService ( serviceName , caller ) {
811
- if ( cache . hasOwnProperty ( serviceName ) ) {
812
- if ( cache [ serviceName ] === INSTANTIATING ) {
813
- throw $injectorMinErr ( 'cdep' , 'Circular dependency found: {0}' ,
814
- serviceName + ' <- ' + path . join ( ' <- ' ) ) ;
815
- }
816
- return cache [ serviceName ] ;
817
- } else {
818
- try {
819
- path . unshift ( serviceName ) ;
820
- cache [ serviceName ] = INSTANTIATING ;
821
- cache [ serviceName ] = factory ( serviceName , caller ) ;
822
- return cache [ serviceName ] ;
823
- } catch ( err ) {
824
- if ( cache [ serviceName ] === INSTANTIATING ) {
825
- delete cache [ serviceName ] ;
821
+ var callerStr = stringifyServiceId ( caller , suffix ) ;
822
+ var hasCaller = callerStr && ( path [ 0 ] !== callerStr ) ;
823
+ var instance ;
824
+
825
+ if ( hasCaller ) path . unshift ( callerStr ) ;
826
+ path . unshift ( stringifyServiceId ( serviceName , suffix ) ) ;
827
+
828
+ try {
829
+ if ( cache . has ( serviceName ) ) {
830
+ instance = cache . get ( serviceName ) ;
831
+
832
+ if ( instance === INSTANTIATING ) {
833
+ throw $injectorMinErr ( 'cdep' , 'Circular dependency found: {0}' , path . join ( ' <- ' ) ) ;
834
+ }
835
+
836
+ return instance ;
837
+ } else {
838
+ try {
839
+ cache . put ( serviceName , INSTANTIATING ) ;
840
+
841
+ instance = factory ( serviceName ) ;
842
+ cache . put ( serviceName , instance ) ;
843
+
844
+ return instance ;
845
+ } catch ( err ) {
846
+ if ( cache . get ( serviceName ) === INSTANTIATING ) {
847
+ cache . remove ( serviceName ) ;
848
+ }
849
+ throw err ;
826
850
}
827
- throw err ;
828
- } finally {
829
- path . shift ( ) ;
830
851
}
852
+ } finally {
853
+ path . shift ( ) ;
854
+ if ( hasCaller ) path . shift ( ) ;
831
855
}
832
856
}
833
857
@@ -838,12 +862,13 @@ function createInjector(modulesToLoad, strictDi) {
838
862
839
863
for ( var i = 0 , length = $inject . length ; i < length ; i ++ ) {
840
864
var key = $inject [ i ] ;
841
- if ( typeof key !== 'string' ) {
842
- throw $injectorMinErr ( 'itkn' ,
843
- 'Incorrect injection token! Expected service name as string, got {0}' , key ) ;
844
- }
845
- args . push ( locals && locals . hasOwnProperty ( key ) ? locals [ key ] :
846
- getService ( key , serviceName ) ) ;
865
+ // TODO(gkalpak): Remove this and the corresponding error (?)
866
+ // if (typeof key !== 'string') {
867
+ // throw $injectorMinErr('itkn',
868
+ // 'Incorrect injection token! Expected service name as string, got {0}', key);
869
+ // }
870
+ var localsHasKey = locals && isString ( key ) && locals . hasOwnProperty ( key ) ;
871
+ args . push ( localsHasKey ? locals [ key ] : getService ( key , serviceName ) ) ;
847
872
}
848
873
return args ;
849
874
}
@@ -901,7 +926,8 @@ function createInjector(modulesToLoad, strictDi) {
901
926
get : getService ,
902
927
annotate : createInjector . $$annotate ,
903
928
has : function ( name ) {
904
- return providerCache . hasOwnProperty ( name + providerSuffix ) || cache . hasOwnProperty ( name ) ;
929
+ return cache . has ( name ) ||
930
+ providerCache . has ( ! isString ( name ) ? name : name + providerSuffix ) ;
905
931
}
906
932
} ;
907
933
}
0 commit comments