refactor(ivy): remove ngBaseDef (#33264)
Removes `ngBaseDef` from the compiler and any runtime code that was still referring to it. In the cases where we'd previously generate a base def we now generate a definition for an abstract directive. PR Close #33264
This commit is contained in:
@ -16,8 +16,8 @@ import {initNgDevMode} from '../util/ng_dev_mode';
|
||||
import {stringify} from '../util/stringify';
|
||||
|
||||
import {EMPTY_ARRAY, EMPTY_OBJ} from './empty';
|
||||
import {NG_BASE_DEF, NG_COMP_DEF, NG_DIR_DEF, NG_FACTORY_DEF, NG_LOC_ID_DEF, NG_MOD_DEF, NG_PIPE_DEF} from './fields';
|
||||
import {ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, ContentQueriesFunction, DirectiveDef, DirectiveDefFeature, DirectiveType, DirectiveTypesOrFactory, FactoryFn, HostBindingsFunction, PipeDef, PipeType, PipeTypesOrFactory, ViewQueriesFunction, ɵɵBaseDef} from './interfaces/definition';
|
||||
import {NG_COMP_DEF, NG_DIR_DEF, NG_FACTORY_DEF, NG_LOC_ID_DEF, NG_MOD_DEF, NG_PIPE_DEF} from './fields';
|
||||
import {ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, ContentQueriesFunction, DirectiveDef, DirectiveDefFeature, DirectiveTypesOrFactory, FactoryFn, HostBindingsFunction, PipeDef, PipeType, PipeTypesOrFactory, ViewQueriesFunction} from './interfaces/definition';
|
||||
import {TAttributes} from './interfaces/node';
|
||||
// while SelectorFlags is unused here, it's required so that types don't get resolved lazily
|
||||
// see: https://github.com/Microsoft/web-build-tools/issues/1050
|
||||
@ -484,107 +484,6 @@ function invertObject<T>(
|
||||
return newLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a base definition
|
||||
*
|
||||
* # Example
|
||||
* ```ts
|
||||
* class ShouldBeInherited {
|
||||
* static ngBaseDef = ɵɵdefineBase({
|
||||
* ...
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param baseDefinition The base definition parameters
|
||||
*
|
||||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵdefineBase<T>(baseDefinition: {
|
||||
/**
|
||||
* A map of input names.
|
||||
*
|
||||
* The format is in: `{[actualPropertyName: string]:(string|[string, string])}`.
|
||||
*
|
||||
* Given:
|
||||
* ```
|
||||
* class MyComponent {
|
||||
* @Input()
|
||||
* publicInput1: string;
|
||||
*
|
||||
* @Input('publicInput2')
|
||||
* declaredInput2: string;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* is described as:
|
||||
* ```
|
||||
* {
|
||||
* publicInput1: 'publicInput1',
|
||||
* declaredInput2: ['declaredInput2', 'publicInput2'],
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Which the minifier may translate to:
|
||||
* ```
|
||||
* {
|
||||
* minifiedPublicInput1: 'publicInput1',
|
||||
* minifiedDeclaredInput2: [ 'declaredInput2', 'publicInput2'],
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* This allows the render to re-construct the minified, public, and declared names
|
||||
* of properties.
|
||||
*
|
||||
* NOTE:
|
||||
* - Because declared and public name are usually same we only generate the array
|
||||
* `['declared', 'public']` format when they differ.
|
||||
* - The reason why this API and `outputs` API is not the same is that `NgOnChanges` has
|
||||
* inconsistent behavior in that it uses declared names rather than minified or public. For
|
||||
* this reason `NgOnChanges` will be deprecated and removed in future version and this
|
||||
* API will be simplified to be consistent with `outputs`.
|
||||
*/
|
||||
inputs?: {[P in keyof T]?: string | [string, string]};
|
||||
|
||||
/**
|
||||
* A map of output names.
|
||||
*
|
||||
* The format is in: `{[actualPropertyName: string]:string}`.
|
||||
*
|
||||
* Which the minifier may translate to: `{[minifiedPropertyName: string]:string}`.
|
||||
*
|
||||
* This allows the render to re-construct the minified and non-minified names
|
||||
* of properties.
|
||||
*/
|
||||
outputs?: {[P in keyof T]?: string};
|
||||
|
||||
/**
|
||||
* Function to create instances of content queries associated with a given directive.
|
||||
*/
|
||||
contentQueries?: ContentQueriesFunction<T>| null;
|
||||
|
||||
/**
|
||||
* Additional set of instructions specific to view query processing. This could be seen as a
|
||||
* set of instructions to be inserted into the template function.
|
||||
*/
|
||||
viewQuery?: ViewQueriesFunction<T>| null;
|
||||
|
||||
/**
|
||||
* Function executed by the parent template to allow children to apply host bindings.
|
||||
*/
|
||||
hostBindings?: HostBindingsFunction<T>;
|
||||
}): ɵɵBaseDef<T> {
|
||||
const declaredInputs: {[P in keyof T]: string} = {} as any;
|
||||
return {
|
||||
inputs: invertObject<T>(baseDefinition.inputs as any, declaredInputs),
|
||||
declaredInputs: declaredInputs,
|
||||
outputs: invertObject<T>(baseDefinition.outputs as any),
|
||||
viewQuery: baseDefinition.viewQuery || null,
|
||||
contentQueries: baseDefinition.contentQueries || null,
|
||||
hostBindings: baseDefinition.hostBindings || null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directive definition object.
|
||||
*
|
||||
@ -751,10 +650,6 @@ export function getPipeDef<T>(type: any): PipeDef<T>|null {
|
||||
return type[NG_PIPE_DEF] || null;
|
||||
}
|
||||
|
||||
export function getBaseDef<T>(type: any): ɵɵBaseDef<T>|null {
|
||||
return type[NG_BASE_DEF] || null;
|
||||
}
|
||||
|
||||
export function getFactoryDef<T>(type: any, throwNotFound: true): FactoryFn<T>;
|
||||
export function getFactoryDef<T>(type: any): FactoryFn<T>|null;
|
||||
export function getFactoryDef<T>(type: any, throwNotFound?: boolean): FactoryFn<T>|null {
|
||||
|
@ -12,8 +12,6 @@ import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty';
|
||||
import {ComponentDef, ContentQueriesFunction, DirectiveDef, DirectiveDefFeature, HostBindingsFunction, RenderFlags, ViewQueriesFunction} from '../interfaces/definition';
|
||||
import {isComponentDef} from '../interfaces/type_checks';
|
||||
|
||||
import {ɵɵNgOnChangesFeature} from './ng_onchanges_feature';
|
||||
|
||||
export function getSuperType(type: Type<any>): Type<any>&
|
||||
{ɵcmp?: ComponentDef<any>, ɵdir?: DirectiveDef<any>} {
|
||||
return Object.getPrototypeOf(type.prototype).constructor;
|
||||
@ -41,30 +39,14 @@ export function ɵɵInheritDefinitionFeature(definition: DirectiveDef<any>| Comp
|
||||
superDef = superType.ɵdir;
|
||||
}
|
||||
|
||||
const baseDef = (superType as any).ngBaseDef;
|
||||
|
||||
// Some fields in the definition may be empty, if there were no values to put in them that
|
||||
// would've justified object creation. Unwrap them if necessary.
|
||||
if (baseDef || superDef) {
|
||||
if (superDef) {
|
||||
// Some fields in the definition may be empty, if there were no values to put in them that
|
||||
// would've justified object creation. Unwrap them if necessary.
|
||||
const writeableDef = definition as any;
|
||||
writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
|
||||
writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
|
||||
writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
|
||||
}
|
||||
|
||||
if (baseDef) {
|
||||
const baseViewQuery = baseDef.viewQuery;
|
||||
const baseContentQueries = baseDef.contentQueries;
|
||||
const baseHostBindings = baseDef.hostBindings;
|
||||
baseHostBindings && inheritHostBindings(definition, baseHostBindings);
|
||||
baseViewQuery && inheritViewQuery(definition, baseViewQuery);
|
||||
baseContentQueries && inheritContentQueries(definition, baseContentQueries);
|
||||
fillProperties(definition.inputs, baseDef.inputs);
|
||||
fillProperties(definition.declaredInputs, baseDef.declaredInputs);
|
||||
fillProperties(definition.outputs, baseDef.outputs);
|
||||
}
|
||||
|
||||
if (superDef) {
|
||||
// Merge hostBindings
|
||||
const superHostBindings = superDef.hostBindings;
|
||||
superHostBindings && inheritHostBindings(definition, superHostBindings);
|
||||
@ -101,25 +83,6 @@ export function ɵɵInheritDefinitionFeature(definition: DirectiveDef<any>| Comp
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Even if we don't have a definition, check the type for the hooks and use those if need be
|
||||
const superPrototype = superType.prototype;
|
||||
if (superPrototype) {
|
||||
definition.afterContentChecked =
|
||||
definition.afterContentChecked || superPrototype.ngAfterContentChecked;
|
||||
definition.afterContentInit =
|
||||
definition.afterContentInit || superPrototype.ngAfterContentInit;
|
||||
definition.afterViewChecked =
|
||||
definition.afterViewChecked || superPrototype.ngAfterViewChecked;
|
||||
definition.afterViewInit = definition.afterViewInit || superPrototype.ngAfterViewInit;
|
||||
definition.doCheck = definition.doCheck || superPrototype.ngDoCheck;
|
||||
definition.onDestroy = definition.onDestroy || superPrototype.ngOnDestroy;
|
||||
definition.onInit = definition.onInit || superPrototype.ngOnInit;
|
||||
|
||||
if (superPrototype.ngOnChanges) {
|
||||
ɵɵNgOnChangesFeature()(definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
superType = Object.getPrototypeOf(superType);
|
||||
|
@ -13,7 +13,6 @@ export const NG_DIR_DEF = getClosureSafeProperty({ɵdir: getClosureSafeProperty}
|
||||
export const NG_PIPE_DEF = getClosureSafeProperty({ɵpipe: getClosureSafeProperty});
|
||||
export const NG_MOD_DEF = getClosureSafeProperty({ɵmod: getClosureSafeProperty});
|
||||
export const NG_LOC_ID_DEF = getClosureSafeProperty({ɵloc: getClosureSafeProperty});
|
||||
export const NG_BASE_DEF = getClosureSafeProperty({ngBaseDef: getClosureSafeProperty});
|
||||
export const NG_FACTORY_DEF = getClosureSafeProperty({ɵfac: getClosureSafeProperty});
|
||||
|
||||
/**
|
||||
|
@ -6,12 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {LifecycleHooksFeature, renderComponent, whenRendered} from './component';
|
||||
import {ɵɵdefineBase, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵsetComponentScope, ɵɵsetNgModuleScope} from './definition';
|
||||
import {ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵsetComponentScope, ɵɵsetNgModuleScope} from './definition';
|
||||
import {ɵɵCopyDefinitionFeature} from './features/copy_definition_feature';
|
||||
import {ɵɵInheritDefinitionFeature} from './features/inherit_definition_feature';
|
||||
import {ɵɵNgOnChangesFeature} from './features/ng_onchanges_feature';
|
||||
import {ɵɵProvidersFeature} from './features/providers_feature';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PipeDef, ɵɵBaseDef, ɵɵComponentDefWithMeta, ɵɵDirectiveDefWithMeta, ɵɵFactoryDef, ɵɵPipeDefWithMeta} from './interfaces/definition';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PipeDef, ɵɵComponentDefWithMeta, ɵɵDirectiveDefWithMeta, ɵɵFactoryDef, ɵɵPipeDefWithMeta} from './interfaces/definition';
|
||||
import {getComponent, getDirectives, getHostElement, getRenderedText} from './util/discovery_utils';
|
||||
|
||||
export {ComponentFactory, ComponentFactoryResolver, ComponentRef, injectComponentFactoryResolver} from './component_ref';
|
||||
@ -99,7 +99,7 @@ export {
|
||||
|
||||
ɵɵreference,
|
||||
|
||||
// TODO: remove `select` once we're refactored all of the tests not to use it.
|
||||
// TODO: remove `select` once we've refactored all of the tests not to use it.
|
||||
ɵɵselect,
|
||||
ɵɵadvance,
|
||||
ɵɵstyleMap,
|
||||
@ -202,7 +202,6 @@ export {ɵɵresolveWindow, ɵɵresolveDocument, ɵɵresolveBody} from './util/mi
|
||||
// clang-format on
|
||||
|
||||
export {
|
||||
ɵɵBaseDef,
|
||||
ComponentDef,
|
||||
ɵɵComponentDefWithMeta,
|
||||
ɵɵFactoryDef,
|
||||
@ -221,7 +220,6 @@ export {
|
||||
ɵɵdefineComponent,
|
||||
ɵɵdefineDirective,
|
||||
ɵɵdefineNgModule,
|
||||
ɵɵdefineBase,
|
||||
ɵɵdefinePipe,
|
||||
getHostElement,
|
||||
getComponent,
|
||||
|
@ -97,17 +97,20 @@ export type ɵɵDirectiveDefWithMeta<
|
||||
OutputMap extends{[key: string]: string}, QueryFields extends string[]> = DirectiveDef<T>;
|
||||
|
||||
/**
|
||||
* Runtime information for classes that are inherited by components or directives
|
||||
* that aren't defined as components or directives.
|
||||
* Runtime link information for Directives.
|
||||
*
|
||||
* This is an internal data structure used by the renderer to determine what inputs
|
||||
* and outputs should be inherited.
|
||||
* This is an internal data structure used by the render to link
|
||||
* directives into templates.
|
||||
*
|
||||
* See: {@link defineBase}
|
||||
* NOTE: Always use `defineDirective` function to create this object,
|
||||
* never create the object directly since the shape of this object
|
||||
* can change between versions.
|
||||
*
|
||||
* @codeGenApi
|
||||
* @param Selector type metadata specifying the selector of the directive or component
|
||||
*
|
||||
* See: {@link defineDirective}
|
||||
*/
|
||||
export interface ɵɵBaseDef<T> {
|
||||
export interface DirectiveDef<T> {
|
||||
/**
|
||||
* A dictionary mapping the inputs' minified property names to their public API names, which
|
||||
* are their aliases if any, or their original unminified property names
|
||||
@ -144,23 +147,7 @@ export interface ɵɵBaseDef<T> {
|
||||
* Refreshes host bindings on the associated directive.
|
||||
*/
|
||||
hostBindings: HostBindingsFunction<T>|null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime link information for Directives.
|
||||
*
|
||||
* This is internal data structure used by the render to link
|
||||
* directives into templates.
|
||||
*
|
||||
* NOTE: Always use `defineDirective` function to create this object,
|
||||
* never create the object directly since the shape of this object
|
||||
* can change between versions.
|
||||
*
|
||||
* @param Selector type metadata specifying the selector of the directive or component
|
||||
*
|
||||
* See: {@link defineDirective}
|
||||
*/
|
||||
export interface DirectiveDef<T> extends ɵɵBaseDef<T> {
|
||||
/** Token representing the directive. Used by DI. */
|
||||
type: Type<T>;
|
||||
|
||||
@ -219,7 +206,7 @@ export type ɵɵFactoryDef<T> = () => T;
|
||||
/**
|
||||
* Runtime link information for Components.
|
||||
*
|
||||
* This is internal data structure used by the render to link
|
||||
* This is an internal data structure used by the render to link
|
||||
* components into templates.
|
||||
*
|
||||
* NOTE: Always use `defineComponent` function to create this object,
|
||||
@ -331,7 +318,7 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
/**
|
||||
* Runtime link information for Pipes.
|
||||
*
|
||||
* This is internal data structure used by the renderer to link
|
||||
* This is an internal data structure used by the renderer to link
|
||||
* pipes into templates.
|
||||
*
|
||||
* NOTE: Always use `definePipe` function to create this object,
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {R3DirectiveMetadataFacade, getCompilerFacade} from '../../compiler/compiler_facade';
|
||||
import {R3BaseMetadataFacade, R3ComponentMetadataFacade, R3QueryMetadataFacade} from '../../compiler/compiler_facade_interface';
|
||||
import {R3ComponentMetadataFacade, R3QueryMetadataFacade} from '../../compiler/compiler_facade_interface';
|
||||
import {resolveForwardRef} from '../../di/forward_ref';
|
||||
import {getReflect, reflectDependencies} from '../../di/jit/util';
|
||||
import {Type} from '../../interface/type';
|
||||
@ -16,9 +16,9 @@ import {Component, Directive, Input} from '../../metadata/directives';
|
||||
import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from '../../metadata/resource_loading';
|
||||
import {ViewEncapsulation} from '../../metadata/view';
|
||||
import {initNgDevMode} from '../../util/ng_dev_mode';
|
||||
import {getBaseDef, getComponentDef, getDirectiveDef} from '../definition';
|
||||
import {getComponentDef, getDirectiveDef} from '../definition';
|
||||
import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty';
|
||||
import {NG_BASE_DEF, NG_COMP_DEF, NG_DIR_DEF, NG_FACTORY_DEF} from '../fields';
|
||||
import {NG_COMP_DEF, NG_DIR_DEF, NG_FACTORY_DEF} from '../fields';
|
||||
import {ComponentType} from '../interfaces/definition';
|
||||
import {stringifyForError} from '../util/misc_utils';
|
||||
|
||||
@ -84,7 +84,7 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
|
||||
viewProviders: metadata.viewProviders || null,
|
||||
};
|
||||
if (meta.usesInheritance) {
|
||||
addBaseDefToUndecoratedParents(type);
|
||||
addDirectiveDefToUndecoratedParents(type);
|
||||
}
|
||||
|
||||
ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
|
||||
@ -153,7 +153,7 @@ function getDirectiveMetadata(type: Type<any>, metadata: Directive) {
|
||||
const facade = directiveMetadata(type as ComponentType<any>, metadata);
|
||||
facade.typeSourceSpan = compiler.createParseSourceSpan('Directive', name, sourceMapUrl);
|
||||
if (facade.usesInheritance) {
|
||||
addBaseDefToUndecoratedParents(type);
|
||||
addDirectiveDefToUndecoratedParents(type);
|
||||
}
|
||||
return {metadata: facade, sourceMapUrl};
|
||||
}
|
||||
@ -202,7 +202,7 @@ export function directiveMetadata(type: Type<any>, metadata: Directive): R3Direc
|
||||
inputs: metadata.inputs || EMPTY_ARRAY,
|
||||
outputs: metadata.outputs || EMPTY_ARRAY,
|
||||
queries: extractQueriesMetadata(type, propMetadata, isContentQuery),
|
||||
lifecycle: {usesOnChanges: type.prototype.hasOwnProperty('ngOnChanges')},
|
||||
lifecycle: {usesOnChanges: usesLifecycleHook(type, 'ngOnChanges')},
|
||||
typeSourceSpan: null !,
|
||||
usesInheritance: !extendsDirectlyFromObject(type),
|
||||
exportAs: extractExportAs(metadata.exportAs),
|
||||
@ -212,76 +212,24 @@ export function directiveMetadata(type: Type<any>, metadata: Directive): R3Direc
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an `ngBaseDef` to all parent classes of a type that don't have an Angular decorator.
|
||||
* Adds a directive definition to all parent classes of a type that don't have an Angular decorator.
|
||||
*/
|
||||
function addBaseDefToUndecoratedParents(type: Type<any>) {
|
||||
function addDirectiveDefToUndecoratedParents(type: Type<any>) {
|
||||
const objPrototype = Object.prototype;
|
||||
let parent = Object.getPrototypeOf(type);
|
||||
|
||||
// Go up the prototype until we hit `Object`.
|
||||
while (parent && parent !== objPrototype) {
|
||||
// Since inheritance works if the class was annotated already, we only need to add
|
||||
// the base def if there are no annotations and the base def hasn't been created already.
|
||||
if (!getDirectiveDef(parent) && !getComponentDef(parent) && !getBaseDef(parent)) {
|
||||
const facade = extractBaseDefMetadata(parent);
|
||||
facade && compileBase(parent, facade);
|
||||
// the def if there are no annotations and the def hasn't been created already.
|
||||
if (!getDirectiveDef(parent) && !getComponentDef(parent) &&
|
||||
shouldAddAbstractDirective(parent)) {
|
||||
compileDirective(parent, null);
|
||||
}
|
||||
parent = Object.getPrototypeOf(parent);
|
||||
}
|
||||
}
|
||||
|
||||
/** Compiles the base metadata into a base definition. */
|
||||
function compileBase(type: Type<any>, facade: R3BaseMetadataFacade): void {
|
||||
let ngBaseDef: any = null;
|
||||
Object.defineProperty(type, NG_BASE_DEF, {
|
||||
get: () => {
|
||||
if (ngBaseDef === null) {
|
||||
const name = type && type.name;
|
||||
const sourceMapUrl = `ng://${name}/ngBaseDef.js`;
|
||||
const compiler = getCompilerFacade();
|
||||
ngBaseDef = compiler.compileBase(angularCoreEnv, sourceMapUrl, facade);
|
||||
}
|
||||
return ngBaseDef;
|
||||
},
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
});
|
||||
}
|
||||
|
||||
/** Extracts the metadata necessary to construct an `ngBaseDef` from a class. */
|
||||
function extractBaseDefMetadata(type: Type<any>): R3BaseMetadataFacade|null {
|
||||
const propMetadata = getReflect().ownPropMetadata(type);
|
||||
const viewQueries = extractQueriesMetadata(type, propMetadata, isViewQuery);
|
||||
const queries = extractQueriesMetadata(type, propMetadata, isContentQuery);
|
||||
let inputs: {[key: string]: string | [string, string]}|undefined;
|
||||
let outputs: {[key: string]: string}|undefined;
|
||||
// We only need to know whether there are any HostListener or HostBinding
|
||||
// decorators present, the parsing logic is in the compiler already.
|
||||
let hasHostDecorators = false;
|
||||
|
||||
for (const field in propMetadata) {
|
||||
propMetadata[field].forEach(ann => {
|
||||
const metadataName = ann.ngMetadataName;
|
||||
if (metadataName === 'Input') {
|
||||
inputs = inputs || {};
|
||||
inputs[field] = ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field;
|
||||
} else if (metadataName === 'Output') {
|
||||
outputs = outputs || {};
|
||||
outputs[field] = ann.bindingPropertyName || field;
|
||||
} else if (metadataName === 'HostBinding' || metadataName === 'HostListener') {
|
||||
hasHostDecorators = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Only generate the base def if there's any info inside it.
|
||||
if (inputs || outputs || viewQueries.length || queries.length || hasHostDecorators) {
|
||||
return {name: type.name, type, inputs, outputs, viewQueries, queries, propMetadata};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function convertToR3QueryPredicate(selector: any): any|string[] {
|
||||
return typeof selector === 'string' ? splitByComma(selector) : resolveForwardRef(selector);
|
||||
}
|
||||
@ -310,7 +258,7 @@ function extractQueriesMetadata(
|
||||
`Can't construct a query for the property "${field}" of ` +
|
||||
`"${stringifyForError(type)}" since the query selector wasn't defined.`);
|
||||
}
|
||||
if (annotations.some(isInputAnn)) {
|
||||
if (annotations.some(isInputAnnotation)) {
|
||||
throw new Error(`Cannot combine @Input decorators with query decorators`);
|
||||
}
|
||||
queriesMeta.push(convertToR3QueryMetadata(field, ann));
|
||||
@ -322,11 +270,7 @@ function extractQueriesMetadata(
|
||||
}
|
||||
|
||||
function extractExportAs(exportAs: string | undefined): string[]|null {
|
||||
if (exportAs === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return exportAs.split(',').map(part => part.trim());
|
||||
return exportAs === undefined ? null : splitByComma(exportAs);
|
||||
}
|
||||
|
||||
function isContentQuery(value: any): value is Query {
|
||||
@ -339,10 +283,45 @@ function isViewQuery(value: any): value is Query {
|
||||
return name === 'ViewChild' || name === 'ViewChildren';
|
||||
}
|
||||
|
||||
function isInputAnn(value: any): value is Input {
|
||||
function isInputAnnotation(value: any): value is Input {
|
||||
return value.ngMetadataName === 'Input';
|
||||
}
|
||||
|
||||
function splitByComma(value: string): string[] {
|
||||
return value.split(',').map(piece => piece.trim());
|
||||
}
|
||||
|
||||
function usesLifecycleHook(type: Type<any>, name: string): boolean {
|
||||
const prototype = type.prototype;
|
||||
return prototype && prototype.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
const LIFECYCLE_HOOKS = [
|
||||
'ngOnChanges', 'ngOnInit', 'ngOnDestroy', 'ngDoCheck', 'ngAfterViewInit', 'ngAfterViewChecked',
|
||||
'ngAfterContentInit', 'ngAfterContentChecked'
|
||||
];
|
||||
|
||||
function shouldAddAbstractDirective(type: Type<any>): boolean {
|
||||
if (LIFECYCLE_HOOKS.some(hookName => usesLifecycleHook(type, hookName))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const propMetadata = getReflect().ownPropMetadata(type);
|
||||
|
||||
for (const field in propMetadata) {
|
||||
const annotations = propMetadata[field];
|
||||
|
||||
for (let i = 0; i < annotations.length; i++) {
|
||||
const current = annotations[i];
|
||||
const metadataName = current.ngMetadataName;
|
||||
|
||||
if (isInputAnnotation(current) || isContentQuery(current) || isViewQuery(current) ||
|
||||
metadataName === 'Output' || metadataName === 'HostBinding' ||
|
||||
metadataName === 'HostListener') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ export const angularCoreEnv: {[name: string]: Function} =
|
||||
'ɵɵattributeInterpolate7': r3.ɵɵattributeInterpolate7,
|
||||
'ɵɵattributeInterpolate8': r3.ɵɵattributeInterpolate8,
|
||||
'ɵɵattributeInterpolateV': r3.ɵɵattributeInterpolateV,
|
||||
'ɵɵdefineBase': r3.ɵɵdefineBase,
|
||||
'ɵɵdefineComponent': r3.ɵɵdefineComponent,
|
||||
'ɵɵdefineDirective': r3.ɵɵdefineDirective,
|
||||
'ɵɵdefineInjectable': ɵɵdefineInjectable,
|
||||
|
Reference in New Issue
Block a user