fix(ivy): don't accidently read the inherited definition (#25736)

Create getter methods `getXXXDef` for each definition which
uses `hasOwnProperty` to verify that we don't accidently read form the
parent class.

Fixes: #24011
Fixes: #25026

PR Close #25736
This commit is contained in:
Miško Hevery
2018-08-29 16:34:44 -07:00
committed by Igor Minar
parent a9099e8f70
commit d5bd86ae5d
29 changed files with 245 additions and 103 deletions

View File

@ -13,9 +13,9 @@ import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from
import {ViewEncapsulation} from '../../metadata/view';
import {Type} from '../../type';
import {stringify} from '../../util';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from '../fields';
import {angularCoreEnv} from './environment';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from './fields';
import {patchComponentDefWithScope, transitiveScopesFor} from './module';
import {getReflect, reflectDependencies} from './util';

View File

@ -1,18 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {getClosureSafeProperty} from '../../util/property';
const TARGET = {} as any;
export const NG_COMPONENT_DEF = getClosureSafeProperty({ngComponentDef: TARGET}, TARGET);
export const NG_DIRECTIVE_DEF = getClosureSafeProperty({ngDirectiveDef: TARGET}, TARGET);
export const NG_INJECTABLE_DEF = getClosureSafeProperty({ngInjectableDef: TARGET}, TARGET);
export const NG_INJECTOR_DEF = getClosureSafeProperty({ngInjectorDef: TARGET}, TARGET);
export const NG_PIPE_DEF = getClosureSafeProperty({ngPipeDef: TARGET}, TARGET);
export const NG_MODULE_DEF = getClosureSafeProperty({ngModuleDef: TARGET}, TARGET);

View File

@ -12,9 +12,9 @@ import {Injectable} from '../../di/injectable';
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
import {Type} from '../../type';
import {getClosureSafeProperty} from '../../util/property';
import {NG_INJECTABLE_DEF} from '../fields';
import {angularCoreEnv} from './environment';
import {NG_INJECTABLE_DEF} from './fields';
import {convertDependencies, reflectDependencies} from './util';
@ -106,9 +106,8 @@ function isUseClassProvider(meta: Injectable): meta is UseClassProvider {
return (meta as UseClassProvider).useClass !== undefined;
}
const GET_PROPERTY_NAME = {} as any;
const USE_VALUE = getClosureSafeProperty<ValueProvider>(
{provide: String, useValue: GET_PROPERTY_NAME}, GET_PROPERTY_NAME);
const USE_VALUE =
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
function isUseValueProvider(meta: Injectable): meta is Injectable&ValueSansProvider {
return USE_VALUE in meta;

View File

@ -10,10 +10,11 @@ import {Expression, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, Wrapped
import {ModuleWithProviders, NgModule, NgModuleDefInternal, NgModuleTransitiveScopes} from '../../metadata/ng_module';
import {Type} from '../../type';
import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../definition';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields';
import {ComponentDefInternal} from '../interfaces/definition';
import {angularCoreEnv} from './environment';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields';
import {reflectDependencies} from './util';
const EMPTY_ARRAY: Type<any>[] = [];
@ -100,7 +101,7 @@ function setScopeOnDeclaredComponents(moduleType: Type<any>, ngModule: NgModule)
if (declaration.hasOwnProperty(NG_COMPONENT_DEF)) {
// An `ngComponentDef` field exists - go ahead and patch the component directly.
const component = declaration as Type<any>& {ngComponentDef: ComponentDefInternal<any>};
const componentDef = component.ngComponentDef;
const componentDef = getComponentDef(component) !;
patchComponentDefWithScope(componentDef, transitiveScopes);
} else if (
!declaration.hasOwnProperty(NG_DIRECTIVE_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
@ -117,10 +118,10 @@ function setScopeOnDeclaredComponents(moduleType: Type<any>, ngModule: NgModule)
export function patchComponentDefWithScope<C>(
componentDef: ComponentDefInternal<C>, transitiveScopes: NgModuleTransitiveScopes) {
componentDef.directiveDefs = () => Array.from(transitiveScopes.compilation.directives)
.map(dir => dir.ngDirectiveDef || dir.ngComponentDef)
.map(dir => getDirectiveDef(dir) || getComponentDef(dir) !)
.filter(def => !!def);
componentDef.pipeDefs = () =>
Array.from(transitiveScopes.compilation.pipes).map(pipe => pipe.ngPipeDef);
Array.from(transitiveScopes.compilation.pipes).map(pipe => getPipeDef(pipe) !);
}
/**
@ -134,7 +135,7 @@ export function transitiveScopesFor<T>(moduleType: Type<T>): NgModuleTransitiveS
if (!isNgModule(moduleType)) {
throw new Error(`${moduleType.name} does not have an ngModuleDef`);
}
const def = moduleType.ngModuleDef;
const def = getNgModuleDef(moduleType) !;
if (def.transitiveCompileScopes !== null) {
return def.transitiveCompileScopes;
@ -154,7 +155,7 @@ export function transitiveScopesFor<T>(moduleType: Type<T>): NgModuleTransitiveS
def.declarations.forEach(declared => {
const declaredWithDefs = declared as Type<any>& { ngPipeDef?: any; };
if (declaredWithDefs.ngPipeDef !== undefined) {
if (getPipeDef(declaredWithDefs)) {
scopes.compilation.pipes.add(declared);
} else {
// Either declared has an ngComponentDef or ngDirectiveDef, or it's a component which hasn't
@ -204,7 +205,7 @@ export function transitiveScopesFor<T>(moduleType: Type<T>): NgModuleTransitiveS
scopes.compilation.pipes.add(entry);
scopes.exported.pipes.add(entry);
});
} else if (exportedTyped.ngPipeDef !== undefined) {
} else if (getNgModuleDef(exportedTyped)) {
scopes.exported.pipes.add(exportedTyped);
} else {
scopes.exported.directives.add(exportedTyped);
@ -248,5 +249,5 @@ function isModuleWithProviders(value: any): value is ModuleWithProviders {
}
function isNgModule<T>(value: Type<T>): value is Type<T>&{ngModuleDef: NgModuleDefInternal<T>} {
return (value as{ngModuleDef?: NgModuleDefInternal<T>}).ngModuleDef !== undefined;
return !!getNgModuleDef(value);
}

View File

@ -10,10 +10,10 @@ import {WrappedNodeExpr, compilePipeFromMetadata, jitExpression} from '@angular/
import {Pipe} from '../../metadata/directives';
import {Type} from '../../type';
import {NG_PIPE_DEF} from '../fields';
import {stringify} from '../util';
import {angularCoreEnv} from './environment';
import {NG_PIPE_DEF} from './fields';
import {reflectDependencies} from './util';
export function compilePipe(type: Type<any>, meta: Pipe): void {