refactor(core): rename ngInjectableDef to ɵprov (#33151)
Injectable defs are not considered public API, so the property that contains them should be prefixed with Angular's marker for "private" ('ɵ') to discourage apps from relying on def APIs directly. This commit adds the prefix and shortens the name from ngInjectableDef to "prov" (for "provider", since injector defs are known as "inj"). This is because property names cannot be minified by Uglify without turning on property mangling (which most apps have turned off) and are thus size-sensitive. PR Close #33151
This commit is contained in:
parent
cda9248b33
commit
86104b82b8
@ -179,7 +179,7 @@ module.exports =
|
|||||||
|
|
||||||
.config(function(filterMembers) {
|
.config(function(filterMembers) {
|
||||||
filterMembers.notAllowedPatterns.push(
|
filterMembers.notAllowedPatterns.push(
|
||||||
/^ng[A-Z].*Def$/, /^ɵ/
|
/^ɵ/
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -126,9 +126,9 @@ describe('@angular/core ng_package', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (ivyEnabled) {
|
if (ivyEnabled) {
|
||||||
it('should have decorators downleveled to static props e.g. ngInjectableDef', () => {
|
it('should have decorators downleveled to static props e.g. ɵprov', () => {
|
||||||
expect(shx.cat('fesm5/core.js')).not.toContain('__decorate');
|
expect(shx.cat('fesm5/core.js')).not.toContain('__decorate');
|
||||||
expect(shx.cat('fesm5/core.js')).toContain('.ngInjectableDef = ');
|
expect(shx.cat('fesm5/core.js')).toContain('.ɵprov = ');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
it('should have decorators',
|
it('should have decorators',
|
||||||
|
@ -21,7 +21,7 @@ export abstract class ViewportScroller {
|
|||||||
// De-sugared tree-shakable injection
|
// De-sugared tree-shakable injection
|
||||||
// See #23917
|
// See #23917
|
||||||
/** @nocollapse */
|
/** @nocollapse */
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ViewportScroller,
|
token: ViewportScroller,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new BrowserViewportScroller(ɵɵinject(DOCUMENT), window, ɵɵinject(ErrorHandler))
|
factory: () => new BrowserViewportScroller(ɵɵinject(DOCUMENT), window, ɵɵinject(ErrorHandler))
|
||||||
|
@ -125,14 +125,14 @@ describe('ngInjectableDef Bazel Integration', () => {
|
|||||||
expect(TestBed.inject(Service).value).toEqual('overridden');
|
expect(TestBed.inject(Service).value).toEqual('overridden');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not override existing ngInjectableDef', () => {
|
it('does not override existing ɵprov', () => {
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
useValue: new Service(false),
|
useValue: new Service(false),
|
||||||
})
|
})
|
||||||
class Service {
|
class Service {
|
||||||
constructor(public value: boolean) {}
|
constructor(public value: boolean) {}
|
||||||
static ngInjectableDef = {
|
static ɵprov = {
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new Service(true),
|
factory: () => new Service(true),
|
||||||
token: Service,
|
token: Service,
|
||||||
@ -143,7 +143,7 @@ describe('ngInjectableDef Bazel Integration', () => {
|
|||||||
expect(TestBed.inject(Service).value).toEqual(true);
|
expect(TestBed.inject(Service).value).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not override existing ngInjectableDef in case of inheritance', () => {
|
it('does not override existing ɵprov in case of inheritance', () => {
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
useValue: new ParentService(false),
|
useValue: new ParentService(false),
|
||||||
|
@ -423,7 +423,7 @@ export class MetadataBundler {
|
|||||||
result[key] = this.convertFunction(moduleName, value);
|
result[key] = this.convertFunction(moduleName, value);
|
||||||
} else if (isMetadataSymbolicCallExpression(value)) {
|
} else if (isMetadataSymbolicCallExpression(value)) {
|
||||||
// Class members can also contain static members that call a function with module
|
// Class members can also contain static members that call a function with module
|
||||||
// references. e.g. "static ngInjectableDef = ɵɵdefineInjectable(..)". We also need to
|
// references. e.g. "static ɵprov = ɵɵdefineInjectable(..)". We also need to
|
||||||
// convert these module references because otherwise these resolve to non-existent files.
|
// convert these module references because otherwise these resolve to non-existent files.
|
||||||
result[key] = this.convertValue(moduleName, value);
|
result[key] = this.convertValue(moduleName, value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,7 +92,7 @@ export class InjectableDecoratorHandler implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
results.push({
|
results.push({
|
||||||
name: 'ngInjectableDef',
|
name: 'ɵprov',
|
||||||
initializer: res.expression, statements,
|
initializer: res.expression, statements,
|
||||||
type: res.type,
|
type: res.type,
|
||||||
});
|
});
|
||||||
@ -214,8 +214,7 @@ function extractInjectableCtorDeps(
|
|||||||
// Angular's DI.
|
// Angular's DI.
|
||||||
//
|
//
|
||||||
// To deal with this, @Injectable() without an argument is more lenient, and if the
|
// To deal with this, @Injectable() without an argument is more lenient, and if the
|
||||||
// constructor
|
// constructor signature does not work for DI then a provider def (ɵprov) that throws.
|
||||||
// signature does not work for DI then an ngInjectableDef that throws.
|
|
||||||
if (strictCtorDeps) {
|
if (strictCtorDeps) {
|
||||||
ctorDeps = getValidConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore);
|
ctorDeps = getValidConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Closure compiler transforms the form `Service.ngInjectableDef = X` into
|
// Closure compiler transforms the form `Service.ɵprov = X` into
|
||||||
// `Service$ngInjectableDef = X`. To prevent this transformation, such assignments need to be
|
// `Service$ɵprov = X`. To prevent this transformation, such assignments need to be
|
||||||
// annotated with @nocollapse. Unfortunately, a bug in Typescript where comments aren't propagated
|
// annotated with @nocollapse. Unfortunately, a bug in Typescript where comments aren't propagated
|
||||||
// through the TS transformations precludes adding the comment via the AST. This workaround detects
|
// through the TS transformations precludes adding the comment via the AST. This workaround detects
|
||||||
// the static assignments to R3 properties such as ngInjectableDef using a regex, as output files
|
// the static assignments to R3 properties such as ɵprov using a regex, as output files
|
||||||
// are written, and applies the annotation through regex replacement.
|
// are written, and applies the annotation through regex replacement.
|
||||||
//
|
//
|
||||||
// TODO(alxhub): clean up once fix for TS transformers lands in upstream
|
// TODO(alxhub): clean up once fix for TS transformers lands in upstream
|
||||||
@ -22,7 +22,7 @@ const R3_DEF_NAME_PATTERN = [
|
|||||||
'ngBaseDef',
|
'ngBaseDef',
|
||||||
'ɵcmp',
|
'ɵcmp',
|
||||||
'ɵdir',
|
'ɵdir',
|
||||||
'ngInjectableDef',
|
'ɵprov',
|
||||||
'ɵinj',
|
'ɵinj',
|
||||||
'ɵmod',
|
'ɵmod',
|
||||||
'ɵpipe',
|
'ɵpipe',
|
||||||
|
@ -88,7 +88,7 @@ describe('compiler compliance: dependency injection', () => {
|
|||||||
}`;
|
}`;
|
||||||
|
|
||||||
const def = `
|
const def = `
|
||||||
MyService.ngInjectableDef = $r3$.ɵɵdefineInjectable({
|
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
factory: function(t) {
|
factory: function(t) {
|
||||||
return MyService.ɵfac(t);
|
return MyService.ɵfac(t);
|
||||||
@ -144,7 +144,7 @@ describe('compiler compliance: dependency injection', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const def = `
|
const def = `
|
||||||
MyService.ngInjectableDef = $r3$.ɵɵdefineInjectable({
|
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
factory: function() {
|
factory: function() {
|
||||||
return alternateFactory();
|
return alternateFactory();
|
||||||
@ -178,7 +178,7 @@ describe('compiler compliance: dependency injection', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const def = `
|
const def = `
|
||||||
MyService.ngInjectableDef = $r3$.ɵɵdefineInjectable({
|
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
factory: function MyService_Factory(t) {
|
factory: function MyService_Factory(t) {
|
||||||
var r = null;
|
var r = null;
|
||||||
@ -217,7 +217,7 @@ describe('compiler compliance: dependency injection', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const factory = `
|
const factory = `
|
||||||
MyService.ngInjectableDef = $r3$.ɵɵdefineInjectable({
|
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
factory: function(t) {
|
factory: function(t) {
|
||||||
return MyAlternateService.ɵfac(t);
|
return MyAlternateService.ɵfac(t);
|
||||||
@ -253,7 +253,7 @@ describe('compiler compliance: dependency injection', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const factory = `
|
const factory = `
|
||||||
MyService.ngInjectableDef = $r3$.ɵɵdefineInjectable({
|
MyService.ɵprov = $r3$.ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
factory: function MyService_Factory(t) {
|
factory: function MyService_Factory(t) {
|
||||||
var r = null;
|
var r = null;
|
||||||
@ -290,7 +290,7 @@ describe('compiler compliance: dependency injection', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const factory = `
|
const factory = `
|
||||||
SomeProvider.ngInjectableDef = $r3$.ɵɵdefineInjectable({
|
SomeProvider.ɵprov = $r3$.ɵɵdefineInjectable({
|
||||||
token: SomeProvider,
|
token: SomeProvider,
|
||||||
factory: function(t) {
|
factory: function(t) {
|
||||||
return SomeProviderImpl.ɵfac(t);
|
return SomeProviderImpl.ɵfac(t);
|
||||||
|
@ -231,7 +231,7 @@ describe('metadata bundler', () => {
|
|||||||
import {sharedFn} from '../shared';
|
import {sharedFn} from '../shared';
|
||||||
|
|
||||||
export class MyClass {
|
export class MyClass {
|
||||||
static ngInjectableDef = sharedFn();
|
static ɵprov = sharedFn();
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ describe('metadata bundler', () => {
|
|||||||
// The unbundled metadata should reference symbols using the relative module path.
|
// The unbundled metadata should reference symbols using the relative module path.
|
||||||
expect(deepIndexMetadata.metadata['MyClass']).toEqual(jasmine.objectContaining<MetadataEntry>({
|
expect(deepIndexMetadata.metadata['MyClass']).toEqual(jasmine.objectContaining<MetadataEntry>({
|
||||||
statics: {
|
statics: {
|
||||||
ngInjectableDef: {
|
ɵprov: {
|
||||||
__symbolic: 'call',
|
__symbolic: 'call',
|
||||||
expression: {
|
expression: {
|
||||||
__symbolic: 'reference',
|
__symbolic: 'reference',
|
||||||
@ -260,7 +260,7 @@ describe('metadata bundler', () => {
|
|||||||
// anywhere and it's not guaranteed that the relatively referenced files are present.
|
// anywhere and it's not guaranteed that the relatively referenced files are present.
|
||||||
expect(bundledMetadata.metadata['MyClass']).toEqual(jasmine.objectContaining<MetadataEntry>({
|
expect(bundledMetadata.metadata['MyClass']).toEqual(jasmine.objectContaining<MetadataEntry>({
|
||||||
statics: {
|
statics: {
|
||||||
ngInjectableDef: {
|
ɵprov: {
|
||||||
__symbolic: 'call',
|
__symbolic: 'call',
|
||||||
expression: {
|
expression: {
|
||||||
__symbolic: 'reference',
|
__symbolic: 'reference',
|
||||||
|
@ -2082,7 +2082,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
})
|
})
|
||||||
export class ServiceModule {}
|
export class ServiceModule {}
|
||||||
`);
|
`);
|
||||||
expect(source).not.toMatch(/ngInjectableDef/);
|
expect(source).not.toMatch(/ɵprov/);
|
||||||
});
|
});
|
||||||
it('on a service with a base class service', () => {
|
it('on a service with a base class service', () => {
|
||||||
const source = compileService(`
|
const source = compileService(`
|
||||||
@ -2102,7 +2102,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
})
|
})
|
||||||
export class ServiceModule {}
|
export class ServiceModule {}
|
||||||
`);
|
`);
|
||||||
expect(source).not.toMatch(/ngInjectableDef/);
|
expect(source).not.toMatch(/ɵprov/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2116,13 +2116,12 @@ describe('ngc transformer command-line', () => {
|
|||||||
})
|
})
|
||||||
export class Service {}
|
export class Service {}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef = .+\.ɵɵdefineInjectable\(/);
|
expect(source).toMatch(/ɵprov = .+\.ɵɵdefineInjectable\(/);
|
||||||
expect(source).toMatch(/ngInjectableDef.*token: Service/);
|
expect(source).toMatch(/ɵprov.*token: Service/);
|
||||||
expect(source).toMatch(/ngInjectableDef.*providedIn: .+\.Module/);
|
expect(source).toMatch(/ɵprov.*providedIn: .+\.Module/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ngInjectableDef in es5 mode is annotated @nocollapse when closure options are enabled',
|
it('ɵprov in es5 mode is annotated @nocollapse when closure options are enabled', () => {
|
||||||
() => {
|
|
||||||
writeConfig(`{
|
writeConfig(`{
|
||||||
"extends": "./tsconfig-base.json",
|
"extends": "./tsconfig-base.json",
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
@ -2139,7 +2138,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
})
|
})
|
||||||
export class Service {}
|
export class Service {}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/\/\*\* @nocollapse \*\/ Service\.ngInjectableDef =/);
|
expect(source).toMatch(/\/\*\* @nocollapse \*\/ Service\.ɵprov =/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiles a useValue InjectableDef', () => {
|
it('compiles a useValue InjectableDef', () => {
|
||||||
@ -2155,7 +2154,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
})
|
})
|
||||||
export class Service {}
|
export class Service {}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef.*return CONST_SERVICE/);
|
expect(source).toMatch(/ɵprov.*return CONST_SERVICE/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiles a useExisting InjectableDef', () => {
|
it('compiles a useExisting InjectableDef', () => {
|
||||||
@ -2172,7 +2171,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
})
|
})
|
||||||
export class Service {}
|
export class Service {}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef.*return ..\.ɵɵinject\(Existing\)/);
|
expect(source).toMatch(/ɵprov.*return ..\.ɵɵinject\(Existing\)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiles a useFactory InjectableDef with optional dep', () => {
|
it('compiles a useFactory InjectableDef with optional dep', () => {
|
||||||
@ -2192,7 +2191,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
constructor(e: Existing|null) {}
|
constructor(e: Existing|null) {}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef.*return ..\(..\.ɵɵinject\(Existing, 8\)/);
|
expect(source).toMatch(/ɵprov.*return ..\(..\.ɵɵinject\(Existing, 8\)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiles a useFactory InjectableDef with skip-self dep', () => {
|
it('compiles a useFactory InjectableDef with skip-self dep', () => {
|
||||||
@ -2212,7 +2211,7 @@ describe('ngc transformer command-line', () => {
|
|||||||
constructor(e: Existing) {}
|
constructor(e: Existing) {}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef.*return ..\(..\.ɵɵinject\(Existing, 4\)/);
|
expect(source).toMatch(/ɵprov.*return ..\(..\.ɵɵinject\(Existing, 4\)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiles a service that depends on a token', () => {
|
it('compiles a service that depends on a token', () => {
|
||||||
@ -2229,9 +2228,9 @@ describe('ngc transformer command-line', () => {
|
|||||||
constructor(@Inject(TOKEN) value: boolean) {}
|
constructor(@Inject(TOKEN) value: boolean) {}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef = .+\.ɵɵdefineInjectable\(/);
|
expect(source).toMatch(/ɵprov = .+\.ɵɵdefineInjectable\(/);
|
||||||
expect(source).toMatch(/ngInjectableDef.*token: Service/);
|
expect(source).toMatch(/ɵprov.*token: Service/);
|
||||||
expect(source).toMatch(/ngInjectableDef.*providedIn: .+\.Module/);
|
expect(source).toMatch(/ɵprov.*providedIn: .+\.Module/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('generates exports.* references when outputting commonjs', () => {
|
it('generates exports.* references when outputting commonjs', () => {
|
||||||
|
@ -61,12 +61,12 @@ runInEachFileSystem(os => {
|
|||||||
|
|
||||||
|
|
||||||
const jsContents = env.getContents('test.js');
|
const jsContents = env.getContents('test.js');
|
||||||
expect(jsContents).toContain('Dep.ngInjectableDef =');
|
expect(jsContents).toContain('Dep.ɵprov =');
|
||||||
expect(jsContents).toContain('Service.ngInjectableDef =');
|
expect(jsContents).toContain('Service.ɵprov =');
|
||||||
expect(jsContents).not.toContain('__decorate');
|
expect(jsContents).not.toContain('__decorate');
|
||||||
const dtsContents = env.getContents('test.d.ts');
|
const dtsContents = env.getContents('test.d.ts');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Dep>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Dep>;');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Service>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Service>;');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Dep>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Dep>;');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
||||||
});
|
});
|
||||||
@ -83,10 +83,10 @@ runInEachFileSystem(os => {
|
|||||||
|
|
||||||
|
|
||||||
const jsContents = env.getContents('test.js');
|
const jsContents = env.getContents('test.js');
|
||||||
expect(jsContents).toContain('Store.ngInjectableDef =');
|
expect(jsContents).toContain('Store.ɵprov =');
|
||||||
const dtsContents = env.getContents('test.d.ts');
|
const dtsContents = env.getContents('test.d.ts');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Store<any>>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Store<any>>;');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Store<any>>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Store<any>>;');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile Injectables with providedIn without errors', () => {
|
it('should compile Injectables with providedIn without errors', () => {
|
||||||
@ -106,16 +106,16 @@ runInEachFileSystem(os => {
|
|||||||
|
|
||||||
|
|
||||||
const jsContents = env.getContents('test.js');
|
const jsContents = env.getContents('test.js');
|
||||||
expect(jsContents).toContain('Dep.ngInjectableDef =');
|
expect(jsContents).toContain('Dep.ɵprov =');
|
||||||
expect(jsContents).toContain('Service.ngInjectableDef =');
|
expect(jsContents).toContain('Service.ɵprov =');
|
||||||
expect(jsContents)
|
expect(jsContents)
|
||||||
.toContain(
|
.toContain(
|
||||||
'Service.ɵfac = function Service_Factory(t) { return new (t || Service)(i0.ɵɵinject(Dep)); };');
|
'Service.ɵfac = function Service_Factory(t) { return new (t || Service)(i0.ɵɵinject(Dep)); };');
|
||||||
expect(jsContents).toContain('providedIn: \'root\' })');
|
expect(jsContents).toContain('providedIn: \'root\' })');
|
||||||
expect(jsContents).not.toContain('__decorate');
|
expect(jsContents).not.toContain('__decorate');
|
||||||
const dtsContents = env.getContents('test.d.ts');
|
const dtsContents = env.getContents('test.d.ts');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Dep>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Dep>;');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Service>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Service>;');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Dep>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Dep>;');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
||||||
});
|
});
|
||||||
@ -134,14 +134,14 @@ runInEachFileSystem(os => {
|
|||||||
|
|
||||||
|
|
||||||
const jsContents = env.getContents('test.js');
|
const jsContents = env.getContents('test.js');
|
||||||
expect(jsContents).toContain('Service.ngInjectableDef =');
|
expect(jsContents).toContain('Service.ɵprov =');
|
||||||
expect(jsContents)
|
expect(jsContents)
|
||||||
.toContain('factory: function () { return (function () { return new Service(); })(); }');
|
.toContain('factory: function () { return (function () { return new Service(); })(); }');
|
||||||
expect(jsContents).toContain('Service_Factory(t) { return new (t || Service)(); }');
|
expect(jsContents).toContain('Service_Factory(t) { return new (t || Service)(); }');
|
||||||
expect(jsContents).toContain(', providedIn: \'root\' });');
|
expect(jsContents).toContain(', providedIn: \'root\' });');
|
||||||
expect(jsContents).not.toContain('__decorate');
|
expect(jsContents).not.toContain('__decorate');
|
||||||
const dtsContents = env.getContents('test.d.ts');
|
const dtsContents = env.getContents('test.d.ts');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Service>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Service>;');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ runInEachFileSystem(os => {
|
|||||||
|
|
||||||
|
|
||||||
const jsContents = env.getContents('test.js');
|
const jsContents = env.getContents('test.js');
|
||||||
expect(jsContents).toContain('Service.ngInjectableDef =');
|
expect(jsContents).toContain('Service.ɵprov =');
|
||||||
expect(jsContents).toContain('factory: function Service_Factory(t) { var r = null; if (t) {');
|
expect(jsContents).toContain('factory: function Service_Factory(t) { var r = null; if (t) {');
|
||||||
expect(jsContents).toContain('return new (t || Service)(i0.ɵɵinject(Dep));');
|
expect(jsContents).toContain('return new (t || Service)(i0.ɵɵinject(Dep));');
|
||||||
expect(jsContents)
|
expect(jsContents)
|
||||||
@ -170,7 +170,7 @@ runInEachFileSystem(os => {
|
|||||||
expect(jsContents).toContain('return r; }, providedIn: \'root\' });');
|
expect(jsContents).toContain('return r; }, providedIn: \'root\' });');
|
||||||
expect(jsContents).not.toContain('__decorate');
|
expect(jsContents).not.toContain('__decorate');
|
||||||
const dtsContents = env.getContents('test.d.ts');
|
const dtsContents = env.getContents('test.d.ts');
|
||||||
expect(dtsContents).toContain('static ngInjectableDef: i0.ɵɵInjectableDef<Service>;');
|
expect(dtsContents).toContain('static ɵprov: i0.ɵɵInjectableDef<Service>;');
|
||||||
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
expect(dtsContents).toContain('static ɵfac: i0.ɵɵFactoryDef<Service>;');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ runInEachFileSystem(os => {
|
|||||||
expect(jsContents).toContain('TestComponent.ɵcmp = i0.ɵɵdefineComponent');
|
expect(jsContents).toContain('TestComponent.ɵcmp = i0.ɵɵdefineComponent');
|
||||||
expect(jsContents).toContain('TestDirective.ɵdir = i0.ɵɵdefineDirective');
|
expect(jsContents).toContain('TestDirective.ɵdir = i0.ɵɵdefineDirective');
|
||||||
expect(jsContents).toContain('TestPipe.ɵpipe = i0.ɵɵdefinePipe');
|
expect(jsContents).toContain('TestPipe.ɵpipe = i0.ɵɵdefinePipe');
|
||||||
expect(jsContents).toContain('TestInjectable.ngInjectableDef = i0.ɵɵdefineInjectable');
|
expect(jsContents).toContain('TestInjectable.ɵprov = i0.ɵɵdefineInjectable');
|
||||||
expect(jsContents).toContain('MyModule.ɵmod = i0.ɵɵdefineNgModule');
|
expect(jsContents).toContain('MyModule.ɵmod = i0.ɵɵdefineNgModule');
|
||||||
expect(jsContents).toContain('MyModule.ɵinj = i0.ɵɵdefineInjector');
|
expect(jsContents).toContain('MyModule.ɵinj = i0.ɵɵdefineInjector');
|
||||||
expect(jsContents).toContain('inputs: { input: "input" }');
|
expect(jsContents).toContain('inputs: { input: "input" }');
|
||||||
@ -1183,10 +1183,10 @@ runInEachFileSystem(os => {
|
|||||||
expect(jsContents).toContain('TestNgModule.ɵmod =');
|
expect(jsContents).toContain('TestNgModule.ɵmod =');
|
||||||
|
|
||||||
// Validate that each class also has an injectable definition.
|
// Validate that each class also has an injectable definition.
|
||||||
expect(jsContents).toContain('TestCmp.ngInjectableDef =');
|
expect(jsContents).toContain('TestCmp.ɵprov =');
|
||||||
expect(jsContents).toContain('TestDir.ngInjectableDef =');
|
expect(jsContents).toContain('TestDir.ɵprov =');
|
||||||
expect(jsContents).toContain('TestPipe.ngInjectableDef =');
|
expect(jsContents).toContain('TestPipe.ɵprov =');
|
||||||
expect(jsContents).toContain('TestNgModule.ngInjectableDef =');
|
expect(jsContents).toContain('TestNgModule.ɵprov =');
|
||||||
|
|
||||||
// Validate that each class's .d.ts declaration has the primary definition.
|
// Validate that each class's .d.ts declaration has the primary definition.
|
||||||
expect(dtsContents).toContain('ComponentDefWithMeta<TestCmp');
|
expect(dtsContents).toContain('ComponentDefWithMeta<TestCmp');
|
||||||
|
@ -9,7 +9,7 @@ This document details the new architecture of the Angular compiler in a post-Ivy
|
|||||||
|
|
||||||
### The Ivy Compilation Model
|
### The Ivy Compilation Model
|
||||||
|
|
||||||
Broadly speaking, The Ivy model is that Angular decorators (`@Injectable`, etc) are compiled to static properties on the classes (`ngInjectableDef`). This operation must take place without global program knowledge, and in most cases only with knowledge of that single decorator.
|
Broadly speaking, The Ivy model is that Angular decorators (`@Injectable`, etc) are compiled to static properties on the classes (`ɵprov`). This operation must take place without global program knowledge, and in most cases only with knowledge of that single decorator.
|
||||||
|
|
||||||
The one exception is `@Component`, which requires knowledge of the metadata from the `@NgModule` which declares the component in order to properly generate the component def (`ɵcmp`). In particular, the selectors which are applicable during compilation of a component template are determined by the module that declares that component, and the transitive closure of the exports of that module's imports.
|
The one exception is `@Component`, which requires knowledge of the metadata from the `@NgModule` which declares the component in order to properly generate the component def (`ɵcmp`). In particular, the selectors which are applicable during compilation of a component template are determined by the module that declares that component, and the transitive closure of the exports of that module's imports.
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class:
|
|||||||
|
|
||||||
Only one definition is generated per class. All components are directives so a
|
Only one definition is generated per class. All components are directives so a
|
||||||
`ɵcmp` contains all the `ɵdir` information. All directives
|
`ɵcmp` contains all the `ɵdir` information. All directives
|
||||||
are injectable so `ɵcmp` and `ɵdir` contain `ngInjectableDef`
|
are injectable so `ɵcmp` and `ɵdir` contain `ɵprov`
|
||||||
information.
|
information.
|
||||||
|
|
||||||
For `CompilePipeSummary` the table looks like:
|
For `CompilePipeSummary` the table looks like:
|
||||||
|
@ -17,7 +17,7 @@ import {CssSelector} from './selector';
|
|||||||
export interface Inject { token: any; }
|
export interface Inject { token: any; }
|
||||||
export const createInject = makeMetadataFactory<Inject>('Inject', (token: any) => ({token}));
|
export const createInject = makeMetadataFactory<Inject>('Inject', (token: any) => ({token}));
|
||||||
export const createInjectionToken = makeMetadataFactory<object>(
|
export const createInjectionToken = makeMetadataFactory<object>(
|
||||||
'InjectionToken', (desc: string) => ({_desc: desc, ngInjectableDef: undefined}));
|
'InjectionToken', (desc: string) => ({_desc: desc, ɵprov: undefined}));
|
||||||
|
|
||||||
export interface Attribute { attributeName?: string; }
|
export interface Attribute { attributeName?: string; }
|
||||||
export const createAttribute =
|
export const createAttribute =
|
||||||
|
@ -126,7 +126,7 @@ export class InjectableCompiler {
|
|||||||
className, null,
|
className, null,
|
||||||
[
|
[
|
||||||
new o.ClassField(
|
new o.ClassField(
|
||||||
'ngInjectableDef', o.INFERRED_TYPE, [o.StmtModifier.Static],
|
'ɵprov', o.INFERRED_TYPE, [o.StmtModifier.Static],
|
||||||
this.injectableDef(injectable, ctx)),
|
this.injectableDef(injectable, ctx)),
|
||||||
],
|
],
|
||||||
[], new o.ClassMethod(null, [], []), []);
|
[], new o.ClassMethod(null, [], []), []);
|
||||||
|
@ -143,7 +143,7 @@ export interface IterableDifferFactory {
|
|||||||
*/
|
*/
|
||||||
export class IterableDiffers {
|
export class IterableDiffers {
|
||||||
/** @nocollapse */
|
/** @nocollapse */
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: IterableDiffers,
|
token: IterableDiffers,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new IterableDiffers([new DefaultIterableDifferFactory()])
|
factory: () => new IterableDiffers([new DefaultIterableDifferFactory()])
|
||||||
|
@ -118,7 +118,7 @@ export interface KeyValueDifferFactory {
|
|||||||
*/
|
*/
|
||||||
export class KeyValueDiffers {
|
export class KeyValueDiffers {
|
||||||
/** @nocollapse */
|
/** @nocollapse */
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: KeyValueDiffers,
|
token: KeyValueDiffers,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new KeyValueDiffers([new DefaultKeyValueDifferFactory()])
|
factory: () => new KeyValueDiffers([new DefaultKeyValueDifferFactory()])
|
||||||
|
@ -229,7 +229,7 @@ export {
|
|||||||
} from './render3/fields';
|
} from './render3/fields';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
NG_INJECTABLE_DEF as ɵNG_INJECTABLE_DEF,
|
NG_PROV_DEF as ɵNG_PROV_DEF,
|
||||||
NG_INJ_DEF as ɵNG_INJ_DEF,
|
NG_INJ_DEF as ɵNG_INJ_DEF,
|
||||||
} from './di/interface/defs';
|
} from './di/interface/defs';
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ export const Injectable: InjectableDecorator = makeDecorator(
|
|||||||
*
|
*
|
||||||
* @publicApi
|
* @publicApi
|
||||||
*/
|
*/
|
||||||
export interface InjectableType<T> extends Type<T> { ngInjectableDef: ɵɵInjectableDef<T>; }
|
export interface InjectableType<T> extends Type<T> { ɵprov: ɵɵInjectableDef<T>; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supports @Injectable() in JIT mode for Render2.
|
* Supports @Injectable() in JIT mode for Render2.
|
||||||
@ -100,7 +100,7 @@ function render2CompileInjectable(injectableType: Type<any>, options?: {
|
|||||||
providedIn?: Type<any>| 'root' | 'platform' | 'any' | null
|
providedIn?: Type<any>| 'root' | 'platform' | 'any' | null
|
||||||
} & InjectableProvider): void {
|
} & InjectableProvider): void {
|
||||||
if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) {
|
if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) {
|
||||||
(injectableType as InjectableType<any>).ngInjectableDef = ɵɵdefineInjectable({
|
(injectableType as InjectableType<any>).ɵprov = ɵɵdefineInjectable({
|
||||||
token: injectableType,
|
token: injectableType,
|
||||||
providedIn: options.providedIn,
|
providedIn: options.providedIn,
|
||||||
factory: convertInjectableProviderToFactory(injectableType, options),
|
factory: convertInjectableProviderToFactory(injectableType, options),
|
||||||
|
@ -54,20 +54,20 @@ export class InjectionToken<T> {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
readonly ngMetadataName = 'InjectionToken';
|
readonly ngMetadataName = 'InjectionToken';
|
||||||
|
|
||||||
readonly ngInjectableDef: never|undefined;
|
readonly ɵprov: never|undefined;
|
||||||
|
|
||||||
constructor(protected _desc: string, options?: {
|
constructor(protected _desc: string, options?: {
|
||||||
providedIn?: Type<any>| 'root' | 'platform' | 'any' | null,
|
providedIn?: Type<any>| 'root' | 'platform' | 'any' | null,
|
||||||
factory: () => T
|
factory: () => T
|
||||||
}) {
|
}) {
|
||||||
this.ngInjectableDef = undefined;
|
this.ɵprov = undefined;
|
||||||
if (typeof options == 'number') {
|
if (typeof options == 'number') {
|
||||||
// This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
|
// This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
|
||||||
// __NG_ELEMENT_ID__ is Used by Ivy to determine bloom filter id.
|
// __NG_ELEMENT_ID__ is Used by Ivy to determine bloom filter id.
|
||||||
// We are using it to assign `-1` which is used to identify `Injector`.
|
// We are using it to assign `-1` which is used to identify `Injector`.
|
||||||
(this as any).__NG_ELEMENT_ID__ = options;
|
(this as any).__NG_ELEMENT_ID__ = options;
|
||||||
} else if (options !== undefined) {
|
} else if (options !== undefined) {
|
||||||
this.ngInjectableDef = ɵɵdefineInjectable({
|
this.ɵprov = ɵɵdefineInjectable({
|
||||||
token: this,
|
token: this,
|
||||||
providedIn: options.providedIn || 'root',
|
providedIn: options.providedIn || 'root',
|
||||||
factory: options.factory,
|
factory: options.factory,
|
||||||
@ -78,4 +78,4 @@ export class InjectionToken<T> {
|
|||||||
toString(): string { return `InjectionToken ${this._desc}`; }
|
toString(): string { return `InjectionToken ${this._desc}`; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InjectableDefToken<T> extends InjectionToken<T> { ngInjectableDef: never; }
|
export interface InjectableDefToken<T> extends InjectionToken<T> { ɵprov: never; }
|
||||||
|
@ -90,7 +90,7 @@ export abstract class Injector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @nocollapse */
|
/** @nocollapse */
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: Injector,
|
token: Injector,
|
||||||
providedIn: 'any' as any,
|
providedIn: 'any' as any,
|
||||||
factory: () => ɵɵinject(INJECTOR),
|
factory: () => ɵɵinject(INJECTOR),
|
||||||
|
@ -71,7 +71,7 @@ export interface ɵɵInjectorDef<T> {
|
|||||||
factory: () => T;
|
factory: () => T;
|
||||||
|
|
||||||
// TODO(alxhub): Narrow down the type here once decorators properly change the return type of the
|
// TODO(alxhub): Narrow down the type here once decorators properly change the return type of the
|
||||||
// class they are decorating (to add the ngInjectableDef property for example).
|
// class they are decorating (to add the ɵprov property for example).
|
||||||
providers: (Type<any>|ValueProvider|ExistingProvider|FactoryProvider|ConstructorProvider|
|
providers: (Type<any>|ValueProvider|ExistingProvider|FactoryProvider|ConstructorProvider|
|
||||||
StaticClassProvider|ClassProvider|any[])[];
|
StaticClassProvider|ClassProvider|any[])[];
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ export interface InjectableType<T> extends Type<T> {
|
|||||||
/**
|
/**
|
||||||
* Opaque type whose structure is highly version dependent. Do not rely on any properties.
|
* Opaque type whose structure is highly version dependent. Do not rely on any properties.
|
||||||
*/
|
*/
|
||||||
ngInjectableDef: never;
|
ɵprov: never;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +126,7 @@ export interface InjectorTypeWithProviders<T> {
|
|||||||
* Construct an `InjectableDef` which defines how a token will be constructed by the DI system, and
|
* Construct an `InjectableDef` which defines how a token will be constructed by the DI system, and
|
||||||
* in which injectors (if any) it will be available.
|
* in which injectors (if any) it will be available.
|
||||||
*
|
*
|
||||||
* This should be assigned to a static `ngInjectableDef` field on a type, which will then be an
|
* This should be assigned to a static `ɵprov` field on a type, which will then be an
|
||||||
* `InjectableType`.
|
* `InjectableType`.
|
||||||
*
|
*
|
||||||
* Options:
|
* Options:
|
||||||
@ -168,7 +168,7 @@ export const defineInjectable = ɵɵdefineInjectable;
|
|||||||
* create the type must be provided. If that factory function needs to inject arguments, it can
|
* create the type must be provided. If that factory function needs to inject arguments, it can
|
||||||
* use the `inject` function.
|
* use the `inject` function.
|
||||||
* * `providers`: an optional array of providers to add to the injector. Each provider must
|
* * `providers`: an optional array of providers to add to the injector. Each provider must
|
||||||
* either have a factory or point to a type which has an `ngInjectableDef` static property (the
|
* either have a factory or point to a type which has a `ɵprov` static property (the
|
||||||
* type must be an `InjectableType`).
|
* type must be an `InjectableType`).
|
||||||
* * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
|
* * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
|
||||||
* whose providers will also be added to the injector. Locally provided types will override
|
* whose providers will also be added to the injector. Locally provided types will override
|
||||||
@ -184,39 +184,40 @@ export function ɵɵdefineInjector(options: {factory: () => any, providers?: any
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the `ngInjectableDef` for `type` in a way which is immune to accidentally reading inherited
|
* Read the injectable def (`ɵprov`) for `type` in a way which is immune to accidentally reading
|
||||||
* value.
|
* inherited value.
|
||||||
*
|
*
|
||||||
* @param type A type which may have its own (non-inherited) `ngInjectableDef`.
|
* @param type A type which may have its own (non-inherited) `ɵprov`.
|
||||||
*/
|
*/
|
||||||
export function getInjectableDef<T>(type: any): ɵɵInjectableDef<T>|null {
|
export function getInjectableDef<T>(type: any): ɵɵInjectableDef<T>|null {
|
||||||
const def = type[NG_INJECTABLE_DEF] as ɵɵInjectableDef<T>;
|
const def = (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]) as ɵɵInjectableDef<T>;
|
||||||
// The definition read above may come from a base class. `hasOwnProperty` is not sufficient to
|
// The definition read above may come from a base class. `hasOwnProperty` is not sufficient to
|
||||||
// distinguish this case, as in older browsers (e.g. IE10) static property inheritance is
|
// distinguish this case, as in older browsers (e.g. IE10) static property inheritance is
|
||||||
// implemented by copying the properties.
|
// implemented by copying the properties.
|
||||||
//
|
//
|
||||||
// Instead, the ngInjectableDef's token is compared to the type, and if they don't match then the
|
// Instead, the ɵprov's token is compared to the type, and if they don't match then the
|
||||||
// property was not defined directly on the type itself, and was likely inherited. The definition
|
// property was not defined directly on the type itself, and was likely inherited. The definition
|
||||||
// is only returned if the type matches the def.token.
|
// is only returned if the type matches the def.token.
|
||||||
return def && def.token === type ? def : null;
|
return def && def.token === type ? def : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the `ngInjectableDef` for `type` or read the `ngInjectableDef` from one of its ancestors.
|
* Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
|
||||||
*
|
*
|
||||||
* @param type A type which may have `ngInjectableDef`, via inheritance.
|
* @param type A type which may have `ɵprov`, via inheritance.
|
||||||
*
|
*
|
||||||
* @deprecated Will be removed in v10, where an error will occur in the scenario if we find the
|
* @deprecated Will be removed in v10, where an error will occur in the scenario if we find the
|
||||||
* `ngInjectableDef` on an ancestor only.
|
* `ɵprov` on an ancestor only.
|
||||||
*/
|
*/
|
||||||
export function getInheritedInjectableDef<T>(type: any): ɵɵInjectableDef<T>|null {
|
export function getInheritedInjectableDef<T>(type: any): ɵɵInjectableDef<T>|null {
|
||||||
if (type && type[NG_INJECTABLE_DEF]) {
|
const def = type && (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]);
|
||||||
|
if (def) {
|
||||||
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
||||||
// ngDevMode &&
|
// ngDevMode &&
|
||||||
console.warn(
|
console.warn(
|
||||||
`DEPRECATED: DI is instantiating a token "${type.name}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
`DEPRECATED: DI is instantiating a token "${type.name}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
||||||
`This will become an error in v10. Please add @Injectable() to the "${type.name}" class.`);
|
`This will become an error in v10. Please add @Injectable() to the "${type.name}" class.`);
|
||||||
return type[NG_INJECTABLE_DEF];
|
return def;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -228,8 +229,14 @@ export function getInheritedInjectableDef<T>(type: any): ɵɵInjectableDef<T>|nu
|
|||||||
* @param type type which may have an injector def (`ɵinj`)
|
* @param type type which may have an injector def (`ɵinj`)
|
||||||
*/
|
*/
|
||||||
export function getInjectorDef<T>(type: any): ɵɵInjectorDef<T>|null {
|
export function getInjectorDef<T>(type: any): ɵɵInjectorDef<T>|null {
|
||||||
return type && type.hasOwnProperty(NG_INJ_DEF) ? (type as any)[NG_INJ_DEF] : null;
|
return type && (type.hasOwnProperty(NG_INJ_DEF) || type.hasOwnProperty(NG_INJECTOR_DEF)) ?
|
||||||
|
(type as any)[NG_INJ_DEF] :
|
||||||
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NG_INJECTABLE_DEF = getClosureSafeProperty({ngInjectableDef: getClosureSafeProperty});
|
export const NG_PROV_DEF = getClosureSafeProperty({ɵprov: getClosureSafeProperty});
|
||||||
export const NG_INJ_DEF = getClosureSafeProperty({ɵinj: getClosureSafeProperty});
|
export const NG_INJ_DEF = getClosureSafeProperty({ɵinj: getClosureSafeProperty});
|
||||||
|
|
||||||
|
// We need to keep these around so we can read off old defs if new defs are unavailable
|
||||||
|
export const NG_INJECTABLE_DEF = getClosureSafeProperty({ngInjectableDef: getClosureSafeProperty});
|
||||||
|
export const NG_INJECTOR_DEF = getClosureSafeProperty({ngInjectorDef: getClosureSafeProperty});
|
||||||
|
@ -12,7 +12,7 @@ import {NG_FACTORY_DEF} from '../../render3/fields';
|
|||||||
import {getClosureSafeProperty} from '../../util/property';
|
import {getClosureSafeProperty} from '../../util/property';
|
||||||
import {resolveForwardRef} from '../forward_ref';
|
import {resolveForwardRef} from '../forward_ref';
|
||||||
import {Injectable} from '../injectable';
|
import {Injectable} from '../injectable';
|
||||||
import {NG_INJECTABLE_DEF} from '../interface/defs';
|
import {NG_PROV_DEF} from '../interface/defs';
|
||||||
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, ValueProvider, ValueSansProvider} from '../interface/provider';
|
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, ValueProvider, ValueSansProvider} from '../interface/provider';
|
||||||
|
|
||||||
import {angularCoreDiEnv} from './environment';
|
import {angularCoreDiEnv} from './environment';
|
||||||
@ -22,19 +22,19 @@ import {convertDependencies, reflectDependencies} from './util';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
|
* Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
|
||||||
* `ngInjectableDef` onto the injectable type.
|
* injectable def (`ɵprov`) onto the injectable type.
|
||||||
*/
|
*/
|
||||||
export function compileInjectable(type: Type<any>, srcMeta?: Injectable): void {
|
export function compileInjectable(type: Type<any>, srcMeta?: Injectable): void {
|
||||||
let ngInjectableDef: any = null;
|
let ngInjectableDef: any = null;
|
||||||
let ngFactoryDef: any = null;
|
let ngFactoryDef: any = null;
|
||||||
|
|
||||||
// if NG_INJECTABLE_DEF is already defined on this class then don't overwrite it
|
// if NG_PROV_DEF is already defined on this class then don't overwrite it
|
||||||
if (!type.hasOwnProperty(NG_INJECTABLE_DEF)) {
|
if (!type.hasOwnProperty(NG_PROV_DEF)) {
|
||||||
Object.defineProperty(type, NG_INJECTABLE_DEF, {
|
Object.defineProperty(type, NG_PROV_DEF, {
|
||||||
get: () => {
|
get: () => {
|
||||||
if (ngInjectableDef === null) {
|
if (ngInjectableDef === null) {
|
||||||
ngInjectableDef = getCompilerFacade().compileInjectable(
|
ngInjectableDef = getCompilerFacade().compileInjectable(
|
||||||
angularCoreDiEnv, `ng:///${type.name}/ngInjectableDef.js`,
|
angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`,
|
||||||
getInjectableMetadata(type, srcMeta));
|
getInjectableMetadata(type, srcMeta));
|
||||||
}
|
}
|
||||||
return ngInjectableDef;
|
return ngInjectableDef;
|
||||||
|
@ -176,11 +176,11 @@ export class R3Injector {
|
|||||||
// SkipSelf isn't set, check if the record belongs to this injector.
|
// SkipSelf isn't set, check if the record belongs to this injector.
|
||||||
let record: Record<T>|undefined|null = this.records.get(token);
|
let record: Record<T>|undefined|null = this.records.get(token);
|
||||||
if (record === undefined) {
|
if (record === undefined) {
|
||||||
// No record, but maybe the token is scoped to this injector. Look for an ngInjectableDef
|
// No record, but maybe the token is scoped to this injector. Look for an injectable
|
||||||
// with a scope matching this injector.
|
// def with a scope matching this injector.
|
||||||
const def = couldBeInjectableType(token) && getInjectableDef(token);
|
const def = couldBeInjectableType(token) && getInjectableDef(token);
|
||||||
if (def && this.injectableDefInScope(def)) {
|
if (def && this.injectableDefInScope(def)) {
|
||||||
// Found an ngInjectableDef and it's scoped to this injector. Pretend as if it was here
|
// Found an injectable def and it's scoped to this injector. Pretend as if it was here
|
||||||
// all along.
|
// all along.
|
||||||
record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
|
record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
|
||||||
} else {
|
} else {
|
||||||
@ -408,7 +408,7 @@ export class R3Injector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function injectableDefOrInjectorDefFactory(token: Type<any>| InjectionToken<any>): () => any {
|
function injectableDefOrInjectorDefFactory(token: Type<any>| InjectionToken<any>): () => any {
|
||||||
// Most tokens will have an ngInjectableDef directly on them, which specifies a factory directly.
|
// Most tokens will have an injectable def directly on them, which specifies a factory directly.
|
||||||
const injectableDef = getInjectableDef(token);
|
const injectableDef = getInjectableDef(token);
|
||||||
const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);
|
const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);
|
||||||
|
|
||||||
@ -423,10 +423,10 @@ function injectableDefOrInjectorDefFactory(token: Type<any>| InjectionToken<any>
|
|||||||
return injectorDef.factory;
|
return injectorDef.factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// InjectionTokens should have an ngInjectableDef and thus should be handled above.
|
// InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
|
||||||
// If it's missing that, it's an error.
|
// If it's missing that, it's an error.
|
||||||
if (token instanceof InjectionToken) {
|
if (token instanceof InjectionToken) {
|
||||||
throw new Error(`Token ${stringify(token)} is missing an ngInjectableDef definition.`);
|
throw new Error(`Token ${stringify(token)} is missing a ɵprov definition.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undecorated types can sometimes be created if they have no constructor arguments.
|
// Undecorated types can sometimes be created if they have no constructor arguments.
|
||||||
@ -447,8 +447,8 @@ function getUndecoratedInjectableFactory(token: Function) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The constructor function appears to have no parameters.
|
// The constructor function appears to have no parameters.
|
||||||
// This might be because it inherits from a super-class. In which case, use an ngInjectableDef
|
// This might be because it inherits from a super-class. In which case, use an injectable
|
||||||
// from an ancestor if there is one.
|
// def from an ancestor if there is one.
|
||||||
// Otherwise this really is a simple class with no dependencies, so return a factory that
|
// Otherwise this really is a simple class with no dependencies, so return a factory that
|
||||||
// just instantiates the zero-arg constructor.
|
// just instantiates the zero-arg constructor.
|
||||||
const inheritedInjectableDef = getInheritedInjectableDef(token);
|
const inheritedInjectableDef = getInheritedInjectableDef(token);
|
||||||
|
@ -333,7 +333,7 @@ The above will create the following layout:
|
|||||||
| | *sub-section: `component` and `directives`*
|
| | *sub-section: `component` and `directives`*
|
||||||
| 19 | `factory(Child.ɵcmp.factory)`* | `Child`
|
| 19 | `factory(Child.ɵcmp.factory)`* | `Child`
|
||||||
| | *sub-section: `providers`*
|
| | *sub-section: `providers`*
|
||||||
| 20 | `factory(ServiceA.ngInjectableDef.factory)`* | `ServiceA`
|
| 20 | `factory(ServiceA.ɵprov.factory)`* | `ServiceA`
|
||||||
| 22 | `'someServiceBValue'`* | `ServiceB`
|
| 22 | `'someServiceBValue'`* | `ServiceB`
|
||||||
| | *sub-section: `viewProviders`*
|
| | *sub-section: `viewProviders`*
|
||||||
| 22 | `factory(()=> new Service())`* | `ServiceC`
|
| 22 | `factory(()=> new Service())`* | `ServiceC`
|
||||||
@ -420,7 +420,7 @@ A pseudo-implementation of `inject` function.
|
|||||||
```typescript
|
```typescript
|
||||||
function inject(token: any): any {
|
function inject(token: any): any {
|
||||||
let injectableDef;
|
let injectableDef;
|
||||||
if (typeof token === 'function' && injectableDef = token.ngInjectableDef) {
|
if (typeof token === 'function' && injectableDef = token.ɵprov) {
|
||||||
const provideIn = injectableDef.provideIn;
|
const provideIn = injectableDef.provideIn;
|
||||||
if (provideIn === '__node_injector__') {
|
if (provideIn === '__node_injector__') {
|
||||||
// if we are injecting `Injector` than create a wrapper object around the inject but which
|
// if we are injecting `Injector` than create a wrapper object around the inject but which
|
||||||
|
@ -17,7 +17,7 @@ import {SecurityContext} from './security';
|
|||||||
export abstract class Sanitizer {
|
export abstract class Sanitizer {
|
||||||
abstract sanitize(context: SecurityContext, value: {}|string|null): string|null;
|
abstract sanitize(context: SecurityContext, value: {}|string|null): string|null;
|
||||||
/** @nocollapse */
|
/** @nocollapse */
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: Sanitizer,
|
token: Sanitizer,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => null,
|
factory: () => null,
|
||||||
|
@ -29,9 +29,15 @@
|
|||||||
{
|
{
|
||||||
"name": "NG_INJECTABLE_DEF"
|
"name": "NG_INJECTABLE_DEF"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTOR_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_INJ_DEF"
|
"name": "NG_INJ_DEF"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_PROV_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_TEMP_TOKEN_PATH"
|
"name": "NG_TEMP_TOKEN_PATH"
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import {Injector, ɵcreateInjector as createInjector, ɵɵdefineInjectable, ɵɵdefineInjector} from '@angular/core';
|
import {Injector, ɵcreateInjector as createInjector, ɵɵdefineInjectable, ɵɵdefineInjector} from '@angular/core';
|
||||||
|
|
||||||
export class RootService {
|
export class RootService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: RootService,
|
token: RootService,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new RootService(),
|
factory: () => new RootService(),
|
||||||
@ -17,7 +17,7 @@ export class RootService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ScopedService {
|
export class ScopedService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ScopedService,
|
token: ScopedService,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new ScopedService(),
|
factory: () => new ScopedService(),
|
||||||
|
@ -140,6 +140,9 @@
|
|||||||
{
|
{
|
||||||
"name": "NG_PIPE_DEF"
|
"name": "NG_PIPE_DEF"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_PROV_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_TEMPLATE_SELECTOR"
|
"name": "NG_TEMPLATE_SELECTOR"
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
|||||||
|
|
||||||
describe('InjectorDef-based createInjector()', () => {
|
describe('InjectorDef-based createInjector()', () => {
|
||||||
class CircularA {
|
class CircularA {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: CircularA,
|
token: CircularA,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => ɵɵinject(CircularB),
|
factory: () => ɵɵinject(CircularB),
|
||||||
@ -20,7 +20,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CircularB {
|
class CircularB {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: CircularB,
|
token: CircularB,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => ɵɵinject(CircularA),
|
factory: () => ɵɵinject(CircularA),
|
||||||
@ -28,7 +28,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Service {
|
class Service {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: Service,
|
token: Service,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new Service(),
|
factory: () => new Service(),
|
||||||
@ -36,7 +36,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class OptionalService {
|
class OptionalService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: OptionalService,
|
token: OptionalService,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new OptionalService(),
|
factory: () => new OptionalService(),
|
||||||
@ -59,7 +59,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
class ServiceWithDep {
|
class ServiceWithDep {
|
||||||
constructor(readonly service: Service) {}
|
constructor(readonly service: Service) {}
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ServiceWithDep,
|
token: ServiceWithDep,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
// ChildService is derived from ServiceWithDep, so the factory function here must do the right
|
// ChildService is derived from ServiceWithDep, so the factory function here must do the right
|
||||||
@ -71,7 +71,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
class ServiceWithOptionalDep {
|
class ServiceWithOptionalDep {
|
||||||
constructor(@Optional() readonly service: OptionalService|null) {}
|
constructor(@Optional() readonly service: OptionalService|null) {}
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ServiceWithOptionalDep,
|
token: ServiceWithOptionalDep,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new ServiceWithOptionalDep(ɵɵinject(OptionalService, InjectFlags.Optional)),
|
factory: () => new ServiceWithOptionalDep(ɵɵinject(OptionalService, InjectFlags.Optional)),
|
||||||
@ -81,7 +81,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
class ServiceWithMissingDep {
|
class ServiceWithMissingDep {
|
||||||
constructor(readonly service: Service) {}
|
constructor(readonly service: Service) {}
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ServiceWithMissingDep,
|
token: ServiceWithMissingDep,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new ServiceWithMissingDep(ɵɵinject(Service)),
|
factory: () => new ServiceWithMissingDep(ɵɵinject(Service)),
|
||||||
@ -91,7 +91,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
class ServiceWithMultiDep {
|
class ServiceWithMultiDep {
|
||||||
constructor(readonly locale: string[]) {}
|
constructor(readonly locale: string[]) {}
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ServiceWithMultiDep,
|
token: ServiceWithMultiDep,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new ServiceWithMultiDep(ɵɵinject(LOCALE)),
|
factory: () => new ServiceWithMultiDep(ɵɵinject(LOCALE)),
|
||||||
@ -99,7 +99,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ServiceTwo {
|
class ServiceTwo {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ServiceTwo,
|
token: ServiceTwo,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new ServiceTwo(),
|
factory: () => new ServiceTwo(),
|
||||||
@ -108,7 +108,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
|
|
||||||
let deepServiceDestroyed = false;
|
let deepServiceDestroyed = false;
|
||||||
class DeepService {
|
class DeepService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: DeepService,
|
token: DeepService,
|
||||||
providedIn: null,
|
providedIn: null,
|
||||||
factory: () => new DeepService(),
|
factory: () => new DeepService(),
|
||||||
@ -119,7 +119,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
|
|
||||||
let eagerServiceCreated: boolean = false;
|
let eagerServiceCreated: boolean = false;
|
||||||
class EagerService {
|
class EagerService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: EagerService,
|
token: EagerService,
|
||||||
providedIn: undefined,
|
providedIn: undefined,
|
||||||
factory: () => new EagerService(),
|
factory: () => new EagerService(),
|
||||||
@ -218,7 +218,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
|
|
||||||
let scopedServiceDestroyed = false;
|
let scopedServiceDestroyed = false;
|
||||||
class ScopedService {
|
class ScopedService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: ScopedService,
|
token: ScopedService,
|
||||||
providedIn: Module,
|
providedIn: Module,
|
||||||
factory: () => new ScopedService(),
|
factory: () => new ScopedService(),
|
||||||
@ -228,7 +228,7 @@ describe('InjectorDef-based createInjector()', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WrongScopeService {
|
class WrongScopeService {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: WrongScopeService,
|
token: WrongScopeService,
|
||||||
providedIn: OtherModule,
|
providedIn: OtherModule,
|
||||||
factory: () => new WrongScopeService(),
|
factory: () => new WrongScopeService(),
|
||||||
|
@ -1387,7 +1387,7 @@ function declareTests(config?: {useJit: boolean}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Bar {
|
class Bar {
|
||||||
static ngInjectableDef: ɵɵInjectableDef<Bar> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<Bar> = ɵɵdefineInjectable({
|
||||||
token: Bar,
|
token: Bar,
|
||||||
factory: () => new Bar(),
|
factory: () => new Bar(),
|
||||||
providedIn: SomeModule,
|
providedIn: SomeModule,
|
||||||
@ -1420,7 +1420,7 @@ function declareTests(config?: {useJit: boolean}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Bar {
|
class Bar {
|
||||||
static ngInjectableDef: ɵɵInjectableDef<Bar> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<Bar> = ɵɵdefineInjectable({
|
||||||
token: Bar,
|
token: Bar,
|
||||||
factory: () => new Bar(),
|
factory: () => new Bar(),
|
||||||
providedIn: SomeModule,
|
providedIn: SomeModule,
|
||||||
|
@ -63,7 +63,7 @@ describe('component', () => {
|
|||||||
|
|
||||||
class MyService {
|
class MyService {
|
||||||
constructor(public value: string) {}
|
constructor(public value: string) {}
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new MyService('no-injector'),
|
factory: () => new MyService('no-injector'),
|
||||||
|
@ -43,8 +43,8 @@ ivyEnabled && describe('render3 jit', () => {
|
|||||||
}
|
}
|
||||||
const ServiceAny = Service as any;
|
const ServiceAny = Service as any;
|
||||||
|
|
||||||
expect(ServiceAny.ngInjectableDef).toBeDefined();
|
expect(ServiceAny.ɵprov).toBeDefined();
|
||||||
expect(ServiceAny.ngInjectableDef.providedIn).toBe('root');
|
expect(ServiceAny.ɵprov.providedIn).toBe('root');
|
||||||
expect(ɵɵinject(Service) instanceof Service).toBe(true);
|
expect(ɵɵinject(Service) instanceof Service).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ ivyEnabled && describe('render3 jit', () => {
|
|||||||
|
|
||||||
it('compiles a module to an ɵinj with the providers', () => {
|
it('compiles a module to an ɵinj with the providers', () => {
|
||||||
class Token {
|
class Token {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: Token,
|
token: Token,
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => 'default',
|
factory: () => 'default',
|
||||||
|
@ -58,7 +58,7 @@ describe('providers', () => {
|
|||||||
public greet: string;
|
public greet: string;
|
||||||
constructor(private provider: GreeterProvider) { this.greet = this.provider.provide(); }
|
constructor(private provider: GreeterProvider) { this.greet = this.provider.provide(); }
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: GreeterInj,
|
token: GreeterInj,
|
||||||
factory: () => new GreeterInj(ɵɵinject(GreeterProvider as any)),
|
factory: () => new GreeterInj(ɵɵinject(GreeterProvider as any)),
|
||||||
});
|
});
|
||||||
@ -816,7 +816,7 @@ describe('providers', () => {
|
|||||||
it('should work with root', () => {
|
it('should work with root', () => {
|
||||||
@Injectable({providedIn: 'root'})
|
@Injectable({providedIn: 'root'})
|
||||||
class FooForRoot {
|
class FooForRoot {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: FooForRoot,
|
token: FooForRoot,
|
||||||
factory: () => new FooForRoot(),
|
factory: () => new FooForRoot(),
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@ -841,7 +841,7 @@ describe('providers', () => {
|
|||||||
|
|
||||||
@Injectable({providedIn: MyModule})
|
@Injectable({providedIn: MyModule})
|
||||||
class FooForModule {
|
class FooForModule {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: FooForModule,
|
token: FooForModule,
|
||||||
factory: () => new FooForModule(),
|
factory: () => new FooForModule(),
|
||||||
providedIn: MyModule,
|
providedIn: MyModule,
|
||||||
@ -1168,7 +1168,7 @@ describe('providers', () => {
|
|||||||
class MyService {
|
class MyService {
|
||||||
constructor(public value: String) {}
|
constructor(public value: String) {}
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: MyService,
|
token: MyService,
|
||||||
factory: () => new MyService(ɵɵinject(String)),
|
factory: () => new MyService(ɵɵinject(String)),
|
||||||
});
|
});
|
||||||
@ -1188,7 +1188,7 @@ describe('providers', () => {
|
|||||||
|
|
||||||
it('should make sure that parent service does not see overrides in child directives', () => {
|
it('should make sure that parent service does not see overrides in child directives', () => {
|
||||||
class Greeter {
|
class Greeter {
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: Greeter,
|
token: Greeter,
|
||||||
factory: () => new Greeter(ɵɵinject(String)),
|
factory: () => new Greeter(ɵɵinject(String)),
|
||||||
});
|
});
|
||||||
@ -1233,7 +1233,7 @@ describe('providers', () => {
|
|||||||
class SomeInj implements Some {
|
class SomeInj implements Some {
|
||||||
constructor(public location: String) {}
|
constructor(public location: String) {}
|
||||||
|
|
||||||
static ngInjectableDef = ɵɵdefineInjectable({
|
static ɵprov = ɵɵdefineInjectable({
|
||||||
token: SomeInj,
|
token: SomeInj,
|
||||||
factory: () => new SomeInj(ɵɵinject(String)),
|
factory: () => new SomeInj(ɵɵinject(String)),
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ class MyChildModule {}
|
|||||||
class NotMyModule {}
|
class NotMyModule {}
|
||||||
|
|
||||||
class Bar {
|
class Bar {
|
||||||
static ngInjectableDef: ɵɵInjectableDef<Bar> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<Bar> = ɵɵdefineInjectable({
|
||||||
token: Bar,
|
token: Bar,
|
||||||
factory: () => new Bar(),
|
factory: () => new Bar(),
|
||||||
providedIn: MyModule,
|
providedIn: MyModule,
|
||||||
@ -33,7 +33,7 @@ class Bar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Baz {
|
class Baz {
|
||||||
static ngInjectableDef: ɵɵInjectableDef<Baz> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<Baz> = ɵɵdefineInjectable({
|
||||||
token: Baz,
|
token: Baz,
|
||||||
factory: () => new Baz(),
|
factory: () => new Baz(),
|
||||||
providedIn: NotMyModule,
|
providedIn: NotMyModule,
|
||||||
@ -43,7 +43,7 @@ class Baz {
|
|||||||
class HasNormalDep {
|
class HasNormalDep {
|
||||||
constructor(public foo: Foo) {}
|
constructor(public foo: Foo) {}
|
||||||
|
|
||||||
static ngInjectableDef: ɵɵInjectableDef<HasNormalDep> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<HasNormalDep> = ɵɵdefineInjectable({
|
||||||
token: HasNormalDep,
|
token: HasNormalDep,
|
||||||
factory: () => new HasNormalDep(inject(Foo)),
|
factory: () => new HasNormalDep(inject(Foo)),
|
||||||
providedIn: MyModule,
|
providedIn: MyModule,
|
||||||
@ -53,7 +53,7 @@ class HasNormalDep {
|
|||||||
class HasDefinedDep {
|
class HasDefinedDep {
|
||||||
constructor(public bar: Bar) {}
|
constructor(public bar: Bar) {}
|
||||||
|
|
||||||
static ngInjectableDef: ɵɵInjectableDef<HasDefinedDep> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<HasDefinedDep> = ɵɵdefineInjectable({
|
||||||
token: HasDefinedDep,
|
token: HasDefinedDep,
|
||||||
factory: () => new HasDefinedDep(inject(Bar)),
|
factory: () => new HasDefinedDep(inject(Bar)),
|
||||||
providedIn: MyModule,
|
providedIn: MyModule,
|
||||||
@ -63,7 +63,7 @@ class HasDefinedDep {
|
|||||||
class HasOptionalDep {
|
class HasOptionalDep {
|
||||||
constructor(public baz: Baz|null) {}
|
constructor(public baz: Baz|null) {}
|
||||||
|
|
||||||
static ngInjectableDef: ɵɵInjectableDef<HasOptionalDep> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<HasOptionalDep> = ɵɵdefineInjectable({
|
||||||
token: HasOptionalDep,
|
token: HasOptionalDep,
|
||||||
factory: () => new HasOptionalDep(inject(Baz, InjectFlags.Optional)),
|
factory: () => new HasOptionalDep(inject(Baz, InjectFlags.Optional)),
|
||||||
providedIn: MyModule,
|
providedIn: MyModule,
|
||||||
@ -71,7 +71,7 @@ class HasOptionalDep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ChildDep {
|
class ChildDep {
|
||||||
static ngInjectableDef: ɵɵInjectableDef<ChildDep> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<ChildDep> = ɵɵdefineInjectable({
|
||||||
token: ChildDep,
|
token: ChildDep,
|
||||||
factory: () => new ChildDep(),
|
factory: () => new ChildDep(),
|
||||||
providedIn: MyChildModule,
|
providedIn: MyChildModule,
|
||||||
@ -80,7 +80,7 @@ class ChildDep {
|
|||||||
|
|
||||||
class FromChildWithOptionalDep {
|
class FromChildWithOptionalDep {
|
||||||
constructor(public baz: Baz|null) {}
|
constructor(public baz: Baz|null) {}
|
||||||
static ngInjectableDef: ɵɵInjectableDef<FromChildWithOptionalDep> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<FromChildWithOptionalDep> = ɵɵdefineInjectable({
|
||||||
token: FromChildWithOptionalDep,
|
token: FromChildWithOptionalDep,
|
||||||
factory: () => new FromChildWithOptionalDep(inject(Baz, InjectFlags.Default)),
|
factory: () => new FromChildWithOptionalDep(inject(Baz, InjectFlags.Default)),
|
||||||
providedIn: MyChildModule,
|
providedIn: MyChildModule,
|
||||||
@ -91,7 +91,7 @@ class FromChildWithSkipSelfDep {
|
|||||||
constructor(
|
constructor(
|
||||||
public skipSelfChildDep: ChildDep|null, public selfChildDep: ChildDep|null,
|
public skipSelfChildDep: ChildDep|null, public selfChildDep: ChildDep|null,
|
||||||
public optionalSelfBar: Bar|null) {}
|
public optionalSelfBar: Bar|null) {}
|
||||||
static ngInjectableDef: ɵɵInjectableDef<FromChildWithSkipSelfDep> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<FromChildWithSkipSelfDep> = ɵɵdefineInjectable({
|
||||||
token: FromChildWithSkipSelfDep,
|
token: FromChildWithSkipSelfDep,
|
||||||
factory: () => new FromChildWithSkipSelfDep(
|
factory: () => new FromChildWithSkipSelfDep(
|
||||||
inject(ChildDep, InjectFlags.SkipSelf|InjectFlags.Optional),
|
inject(ChildDep, InjectFlags.SkipSelf|InjectFlags.Optional),
|
||||||
@ -215,7 +215,7 @@ describe('NgModuleRef_ injector', () => {
|
|||||||
|
|
||||||
ngOnDestroy(): void { Service.destroyed++; }
|
ngOnDestroy(): void { Service.destroyed++; }
|
||||||
|
|
||||||
static ngInjectableDef: ɵɵInjectableDef<Service> = ɵɵdefineInjectable({
|
static ɵprov: ɵɵInjectableDef<Service> = ɵɵdefineInjectable({
|
||||||
token: Service,
|
token: Service,
|
||||||
factory: () => new Service(),
|
factory: () => new Service(),
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
@ -14,10 +14,10 @@ class MockRootScopeInjector implements Injector {
|
|||||||
get<T>(
|
get<T>(
|
||||||
token: Type<T>|InjectionToken<T>, defaultValue?: any,
|
token: Type<T>|InjectionToken<T>, defaultValue?: any,
|
||||||
flags: InjectFlags = InjectFlags.Default): T {
|
flags: InjectFlags = InjectFlags.Default): T {
|
||||||
if ((token as any).ngInjectableDef && (token as any).ngInjectableDef.providedIn === 'root') {
|
if ((token as any).ɵprov && (token as any).ɵprov.providedIn === 'root') {
|
||||||
const old = setCurrentInjector(this);
|
const old = setCurrentInjector(this);
|
||||||
try {
|
try {
|
||||||
return (token as any).ngInjectableDef.factory();
|
return (token as any).ɵprov.factory();
|
||||||
} finally {
|
} finally {
|
||||||
setCurrentInjector(old);
|
setCurrentInjector(old);
|
||||||
}
|
}
|
||||||
|
2
tools/public_api_guard/common/common.d.ts
vendored
2
tools/public_api_guard/common/common.d.ts
vendored
@ -446,7 +446,7 @@ export declare abstract class ViewportScroller {
|
|||||||
abstract scrollToPosition(position: [number, number]): void;
|
abstract scrollToPosition(position: [number, number]): void;
|
||||||
abstract setHistoryScrollRestoration(scrollRestoration: 'auto' | 'manual'): void;
|
abstract setHistoryScrollRestoration(scrollRestoration: 'auto' | 'manual'): void;
|
||||||
abstract setOffset(offset: [number, number] | (() => [number, number])): void;
|
abstract setOffset(offset: [number, number] | (() => [number, number])): void;
|
||||||
static ngInjectableDef: never;
|
static ɵprov: never;
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare enum WeekDay {
|
export declare enum WeekDay {
|
||||||
|
12
tools/public_api_guard/core/core.d.ts
vendored
12
tools/public_api_guard/core/core.d.ts
vendored
@ -428,7 +428,7 @@ export interface InjectableDecorator {
|
|||||||
export declare type InjectableProvider = ValueSansProvider | ExistingSansProvider | StaticClassSansProvider | ConstructorSansProvider | FactorySansProvider | ClassSansProvider;
|
export declare type InjectableProvider = ValueSansProvider | ExistingSansProvider | StaticClassSansProvider | ConstructorSansProvider | FactorySansProvider | ClassSansProvider;
|
||||||
|
|
||||||
export interface InjectableType<T> extends Type<T> {
|
export interface InjectableType<T> extends Type<T> {
|
||||||
ngInjectableDef: never;
|
ɵprov: never;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InjectDecorator {
|
export interface InjectDecorator {
|
||||||
@ -446,7 +446,7 @@ export declare enum InjectFlags {
|
|||||||
|
|
||||||
export declare class InjectionToken<T> {
|
export declare class InjectionToken<T> {
|
||||||
protected _desc: string;
|
protected _desc: string;
|
||||||
readonly ngInjectableDef: never | undefined;
|
readonly ɵprov: never | undefined;
|
||||||
constructor(_desc: string, options?: {
|
constructor(_desc: string, options?: {
|
||||||
providedIn?: Type<any> | 'root' | 'platform' | 'any' | null;
|
providedIn?: Type<any> | 'root' | 'platform' | 'any' | null;
|
||||||
factory: () => T;
|
factory: () => T;
|
||||||
@ -459,7 +459,7 @@ export declare abstract class Injector {
|
|||||||
/** @deprecated */ abstract get(token: any, notFoundValue?: any): any;
|
/** @deprecated */ abstract get(token: any, notFoundValue?: any): any;
|
||||||
static NULL: Injector;
|
static NULL: Injector;
|
||||||
static THROW_IF_NOT_FOUND: Object;
|
static THROW_IF_NOT_FOUND: Object;
|
||||||
static ngInjectableDef: never;
|
static ɵprov: never;
|
||||||
/** @deprecated */ static create(providers: StaticProvider[], parent?: Injector): Injector;
|
/** @deprecated */ static create(providers: StaticProvider[], parent?: Injector): Injector;
|
||||||
static create(options: {
|
static create(options: {
|
||||||
providers: StaticProvider[];
|
providers: StaticProvider[];
|
||||||
@ -517,7 +517,7 @@ export declare class IterableDiffers {
|
|||||||
/** @deprecated */ factories: IterableDifferFactory[];
|
/** @deprecated */ factories: IterableDifferFactory[];
|
||||||
constructor(factories: IterableDifferFactory[]);
|
constructor(factories: IterableDifferFactory[]);
|
||||||
find(iterable: any): IterableDifferFactory;
|
find(iterable: any): IterableDifferFactory;
|
||||||
static ngInjectableDef: never;
|
static ɵprov: never;
|
||||||
static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers;
|
static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers;
|
||||||
static extend(factories: IterableDifferFactory[]): StaticProvider;
|
static extend(factories: IterableDifferFactory[]): StaticProvider;
|
||||||
}
|
}
|
||||||
@ -552,7 +552,7 @@ export declare class KeyValueDiffers {
|
|||||||
/** @deprecated */ factories: KeyValueDifferFactory[];
|
/** @deprecated */ factories: KeyValueDifferFactory[];
|
||||||
constructor(factories: KeyValueDifferFactory[]);
|
constructor(factories: KeyValueDifferFactory[]);
|
||||||
find(kv: any): KeyValueDifferFactory;
|
find(kv: any): KeyValueDifferFactory;
|
||||||
static ngInjectableDef: never;
|
static ɵprov: never;
|
||||||
static create<S>(factories: KeyValueDifferFactory[], parent?: KeyValueDiffers): KeyValueDiffers;
|
static create<S>(factories: KeyValueDifferFactory[], parent?: KeyValueDiffers): KeyValueDiffers;
|
||||||
static extend<S>(factories: KeyValueDifferFactory[]): StaticProvider;
|
static extend<S>(factories: KeyValueDifferFactory[]): StaticProvider;
|
||||||
}
|
}
|
||||||
@ -1270,7 +1270,7 @@ export declare function resolveForwardRef<T>(type: T): T;
|
|||||||
|
|
||||||
export declare abstract class Sanitizer {
|
export declare abstract class Sanitizer {
|
||||||
abstract sanitize(context: SecurityContext, value: {} | string | null): string | null;
|
abstract sanitize(context: SecurityContext, value: {} | string | null): string | null;
|
||||||
static ngInjectableDef: never;
|
static ɵprov: never;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SchemaMetadata {
|
export interface SchemaMetadata {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user