Skip to content

Commit

Permalink
refactor(core): remove deprecated @Component.directives and @Componen…
Browse files Browse the repository at this point in the history
…t.pipes

BREAKING CHANGE: previously deprecated @Component.directives and @Component.pipes support was removed.

All the components and pipes now must be declarated via an NgModule. NgModule is the basic
compilation block passed into the Angular compiler via Compiler#compileModuleSync or #compileModuleAsync.

Because of this change, the Compiler#compileComponentAsync and #compileComponentSync were removed as well -
any code doing compilation should compile module instead using the apis mentioned above.

Lastly, since modules are the basic compilation unit, the ngUpgrade module was modified to always require
an NgModule to be passed into the UpgradeAdapter's constructor - previously this was optional.
  • Loading branch information
IgorMinar committed Aug 23, 2016
1 parent a782232 commit 4a740f2
Show file tree
Hide file tree
Showing 18 changed files with 389 additions and 665 deletions.
12 changes: 2 additions & 10 deletions modules/@angular/compiler/src/compile_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ export class CompileTemplateMetadata {
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host, providers,
viewProviders, queries, viewQueries, entryComponents, viewDirectives, viewPipes, template}: {
viewProviders, queries, viewQueries, entryComponents, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
Expand Down Expand Up @@ -479,8 +479,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
queries,
viewQueries,
entryComponents,
viewDirectives,
viewPipes,
template,
});
}
Expand All @@ -500,17 +498,13 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
viewQueries: CompileQueryMetadata[];
// Note: Need to keep types here to prevent cycles!
entryComponents: CompileTypeMetadata[];
// Note: Need to keep types here to prevent cycles!
viewDirectives: CompileTypeMetadata[];
// Note: Need to keep types here to prevent cycles!
viewPipes: CompileTypeMetadata[];

template: CompileTemplateMetadata;

constructor(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners,
hostProperties, hostAttributes, providers, viewProviders, queries, viewQueries,
entryComponents, viewDirectives, viewPipes, template}: {
entryComponents, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
Expand Down Expand Up @@ -547,8 +541,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
this.queries = _normalizeArray(queries);
this.viewQueries = _normalizeArray(viewQueries);
this.entryComponents = _normalizeArray(entryComponents);
this.viewDirectives = _normalizeArray(viewDirectives);
this.viewPipes = _normalizeArray(viewPipes);

this.template = template;
}
Expand Down
2 changes: 0 additions & 2 deletions modules/@angular/compiler/src/directive_resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ export class DirectiveResolver {
providers: dm.providers,
viewProviders: dm.viewProviders,
entryComponents: dm.entryComponents,
directives: dm.directives,
pipes: dm.pipes,
template: dm.template,
templateUrl: dm.templateUrl,
styles: dm.styles,
Expand Down
102 changes: 10 additions & 92 deletions modules/@angular/compiler/src/metadata_resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@

import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, AttributeMetadata, ChangeDetectionStrategy, ComponentMetadata, HostMetadata, InjectMetadata, Injectable, ModuleWithProviders, OptionalMetadata, Provider, QueryMetadata, SchemaMetadata, SelfMetadata, SkipSelfMetadata, Type, ViewQueryMetadata, resolveForwardRef} from '@angular/core';

import {Console, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from '../core_private';
import {LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from '../core_private';
import {StringMapWrapper} from '../src/facade/collection';

import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
import * as cpl from './compile_metadata';
import {CompilerConfig} from './config';
import {DirectiveResolver} from './directive_resolver';
import {BaseException} from './facade/exceptions';
import {isArray, isBlank, isPresent, isString, stringify} from './facade/lang';
Expand All @@ -36,8 +35,7 @@ export class CompileMetadataResolver {

constructor(
private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
private _pipeResolver: PipeResolver, private _config: CompilerConfig,
private _console: Console, private _schemaRegistry: ElementSchemaRegistry,
private _pipeResolver: PipeResolver, private _schemaRegistry: ElementSchemaRegistry,
private _reflector: ReflectorReader = reflector) {}

private sanitizeTokenName(token: any): string {
Expand Down Expand Up @@ -124,9 +122,7 @@ export class CompileMetadataResolver {
var changeDetectionStrategy: ChangeDetectionStrategy = null;
var viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
var moduleUrl = staticTypeModuleUrl(directiveType);
var viewDirectiveTypes: cpl.CompileTypeMetadata[] = [];
var viewPipeTypes: cpl.CompileTypeMetadata[] = [];
var entryComponentTypes: cpl.CompileTypeMetadata[] = [];
var entryComponentMetadata: cpl.CompileTypeMetadata[] = [];
let selector = dirMeta.selector;
if (dirMeta instanceof ComponentMetadata) {
var cmpMeta = <ComponentMetadata>dirMeta;
Expand All @@ -150,32 +146,15 @@ export class CompileMetadataResolver {
changeDetectionStrategy = cmpMeta.changeDetection;
if (isPresent(dirMeta.viewProviders)) {
viewProviders = this.getProvidersMetadata(
verifyNonBlankProviders(directiveType, dirMeta.viewProviders, 'viewProviders'), []);
verifyNonBlankProviders(directiveType, dirMeta.viewProviders, 'viewProviders'),
entryComponentMetadata);
}
moduleUrl = componentModuleUrl(this._reflector, directiveType, cmpMeta);
if (cmpMeta.entryComponents) {
entryComponentTypes =
entryComponentMetadata =
flattenArray(cmpMeta.entryComponents)
.map((type) => this.getTypeMetadata(type, staticTypeModuleUrl(type)));
}
if (cmpMeta.directives) {
viewDirectiveTypes = flattenArray(cmpMeta.directives).map((type) => {
if (!type) {
throw new BaseException(
`Unexpected directive value '${type}' on the View of component '${stringify(directiveType)}'`);
}

return this.getTypeMetadata(type, staticTypeModuleUrl(type));
});
}
if (cmpMeta.pipes) {
viewPipeTypes = flattenArray(cmpMeta.pipes).map((type) => {
if (!type) {
throw new BaseException(
`Unexpected pipe value '${type}' on the View of component '${stringify(directiveType)}'`);
}
return this.getTypeMetadata(type, staticTypeModuleUrl(type));
});
.map((type) => this.getTypeMetadata(type, staticTypeModuleUrl(type)))
.concat(entryComponentMetadata);
}
if (!selector) {
selector = this._schemaRegistry.getDefaultComponentElementName();
Expand All @@ -191,7 +170,7 @@ export class CompileMetadataResolver {
if (isPresent(dirMeta.providers)) {
providers = this.getProvidersMetadata(
verifyNonBlankProviders(directiveType, dirMeta.providers, 'providers'),
entryComponentTypes);
entryComponentMetadata);
}
var queries: cpl.CompileQueryMetadata[] = [];
var viewQueries: cpl.CompileQueryMetadata[] = [];
Expand All @@ -213,9 +192,7 @@ export class CompileMetadataResolver {
viewProviders: viewProviders,
queries: queries,
viewQueries: viewQueries,
viewDirectives: viewDirectiveTypes,
viewPipes: viewPipeTypes,
entryComponents: entryComponentTypes
entryComponents: entryComponentMetadata
});
this._directiveCache.set(directiveType, meta);
}
Expand Down Expand Up @@ -359,19 +336,6 @@ export class CompileMetadataResolver {
return compileMeta;
}

addComponentToModule(moduleType: Type<any>, compType: Type<any>) {
const moduleMeta = this.getNgModuleMetadata(moduleType);
// Collect @Component.directives/pipes/entryComponents into our declared directives/pipes.
const compMeta = this.getDirectiveMetadata(compType, false);
this._addDirectiveToModule(
compMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
moduleMeta.declaredDirectives);

moduleMeta.transitiveModule.entryComponents.push(compMeta.type);
moduleMeta.entryComponents.push(compMeta.type);

this._verifyModule(moduleMeta);
}

private _verifyModule(moduleMeta: cpl.CompileNgModuleMetadata) {
moduleMeta.exportedDirectives.forEach((dirMeta) => {
Expand All @@ -386,17 +350,6 @@ export class CompileMetadataResolver {
`Can't export pipe ${stringify(pipeMeta.type.runtime)} from ${stringify(moduleMeta.type.runtime)} as it was neither declared nor imported!`);
}
});
moduleMeta.entryComponents.forEach((entryComponentType) => {
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponentType.runtime)) {
throw new BaseException(
`NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported! If ${stringify(entryComponentType.runtime)} is declared in an imported module, make sure it is exported.`);
}
});
// Collect @Component.directives/pipes/entryComponents into our declared
// directives/pipes. Do this last so that directives added by previous steps
// are considered as well!
moduleMeta.declaredDirectives.forEach(
(dirMeta) => { this._getTransitiveViewDirectivesAndPipes(dirMeta, moduleMeta); });
}

private _getTypeDescriptor(type: Type<any>): string {
Expand All @@ -422,41 +375,6 @@ export class CompileMetadataResolver {
this._ngModuleOfTypes.set(type, moduleType);
}


private _getTransitiveViewDirectivesAndPipes(
compMeta: cpl.CompileDirectiveMetadata, moduleMeta: cpl.CompileNgModuleMetadata) {
if (!compMeta.isComponent) {
return;
}
const addPipe = (pipeType: Type<any>) => {
const pipeMeta = this.getPipeMetadata(pipeType);
this._addPipeToModule(
pipeMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule, moduleMeta.declaredPipes);
};

const addDirective = (dirType: Type<any>) => {
const dirMeta = this.getDirectiveMetadata(dirType);
if (this._addDirectiveToModule(
dirMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
moduleMeta.declaredDirectives)) {
this._getTransitiveViewDirectivesAndPipes(dirMeta, moduleMeta);
}
};
if (compMeta.viewPipes) {
compMeta.viewPipes.forEach((cplType) => addPipe(cplType.runtime));
}
if (compMeta.viewDirectives) {
compMeta.viewDirectives.forEach((cplType) => addDirective(cplType.runtime));
}
compMeta.entryComponents.forEach((entryComponentType) => {
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponentType.runtime)) {
this._console.warn(
`Component ${stringify(compMeta.type.runtime)} in NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported into the module! This warning will become an error after final.`);
addDirective(entryComponentType.runtime);
}
});
}

private _getTransitiveNgModuleMetadata(
importedModules: cpl.CompileNgModuleMetadata[],
exportedModules: cpl.CompileNgModuleMetadata[]): cpl.TransitiveCompileNgModuleMetadata {
Expand Down
52 changes: 11 additions & 41 deletions modules/@angular/compiler/src/runtime_compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ export class RuntimeCompiler implements Compiler {
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig,
private _console: Console) {}
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig) {}

get injector(): Injector { return this._injector; }

Expand All @@ -68,23 +67,6 @@ export class RuntimeCompiler implements Compiler {
return this._compileModuleAndAllComponents(moduleType, false).asyncResult;
}

compileComponentAsync<T>(compType: Type<T>, ngModule: Type<any> = null):
Promise<ComponentFactory<T>> {
if (!ngModule) {
throw new BaseException(
`Calling compileComponentAsync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
}
return this._compileComponentInModule(compType, false, ngModule).asyncResult;
}

compileComponentSync<T>(compType: Type<T>, ngModule: Type<any> = null): ComponentFactory<T> {
if (!ngModule) {
throw new BaseException(
`Calling compileComponentSync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
}
return this._compileComponentInModule(compType, true, ngModule).syncResult;
}

private _compileModuleAndComponents<T>(moduleType: Type<T>, isSync: boolean):
SyncAsyncResult<NgModuleFactory<T>> {
const componentPromise = this._compileComponents(moduleType, isSync);
Expand Down Expand Up @@ -146,17 +128,6 @@ export class RuntimeCompiler implements Compiler {
return ngModuleFactory;
}

private _compileComponentInModule<T>(compType: Type<T>, isSync: boolean, moduleType: Type<any>):
SyncAsyncResult<ComponentFactory<T>> {
this._metadataResolver.addComponentToModule(moduleType, compType);

const componentPromise = this._compileComponents(moduleType, isSync);
const componentFactory: ComponentFactory<T> =
this._assertComponentKnown(compType, true).proxyComponentFactory;

return new SyncAsyncResult(componentFactory, componentPromise.then(() => componentFactory));
}

/**
* @internal
*/
Expand All @@ -172,10 +143,13 @@ export class RuntimeCompiler implements Compiler {
dirMeta.entryComponents.forEach((entryComponentType) => {
templates.add(this._createCompiledHostTemplate(entryComponentType.runtime));
});
// TODO: what about entryComponents of entryComponents? maybe skip here and just do the
// below?
}
});
localModuleMeta.entryComponents.forEach((entryComponentType) => {
templates.add(this._createCompiledHostTemplate(entryComponentType.runtime));
// TODO: what about entryComponents of entryComponents?
});
});
templates.forEach((template) => {
Expand Down Expand Up @@ -248,8 +222,13 @@ export class RuntimeCompiler implements Compiler {
const compiledTemplate = isHost ? this._compiledHostTemplateCache.get(compType) :
this._compiledTemplateCache.get(compType);
if (!compiledTemplate) {
throw new BaseException(
`Illegal state: CompiledTemplate for ${stringify(compType)} (isHost: ${isHost}) does not exist!`);
if (isHost) {
throw new BaseException(
`Illegal state: Compiled view for component ${stringify(compType)} does not exist!`);
} else {
throw new BaseException(
`Component ${stringify(compType)} is not part of any NgModule or the module has not been imported into your module.`);
}
}
return compiledTemplate;
}
Expand Down Expand Up @@ -403,15 +382,6 @@ class ModuleBoundCompiler implements Compiler {

get _injector(): Injector { return this._delegate.injector; }

compileComponentAsync<T>(compType: Type<T>, ngModule: Type<any> = null):
Promise<ComponentFactory<T>> {
return this._delegate.compileComponentAsync(compType, ngModule ? ngModule : this._ngModule);
}

compileComponentSync<T>(compType: Type<T>, ngModule: Type<any> = null): ComponentFactory<T> {
return this._delegate.compileComponentSync(compType, ngModule ? ngModule : this._ngModule);
}

compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
return this._delegate.compileModuleSync(moduleType);
}
Expand Down
Loading

1 comment on commit 4a740f2

@dolanmiu
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the guides online has been using .directives. Was driving me insane!

Please sign in to comment.