Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ivy): remove ngBaseDef #33264

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions integration/ngcc/test.sh
Expand Up @@ -95,12 +95,12 @@ assertSucceeded "Expected 'ngcc' to log 'Compiling'."
assertSucceeded "Expected 'ngcc' to generate a base factory for 'MatTable' in '@angular/material' (esm5)."


# Did it generate a base definition for undecorated classes with inputs and view queries?
grep "_MatMenuBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ inputs: {" node_modules/@angular/material/esm2015/menu.js
assertSucceeded "Expected 'ngcc' to generate a base definition for 'MatMenuBase' in '@angular/material' (esm2015)."
# Did it generate an abstract directive definition for undecorated classes with inputs and view queries?
grep "_MatMenuBase.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: _MatMenuBase" node_modules/@angular/material/esm2015/menu.js
assertSucceeded "Expected 'ngcc' to generate an abstract directive definition for 'MatMenuBase' in '@angular/material' (esm2015)."

grep "_MatMenuBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ inputs: {" node_modules/@angular/material/esm5/menu.es5.js
assertSucceeded "Expected 'ngcc' to generate a base definition for 'MatMenuBase' in '@angular/material' (esm5)."
grep "_MatMenuBase.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: _MatMenuBase" node_modules/@angular/material/esm5/menu.es5.js
assertSucceeded "Expected 'ngcc' to generate an abstract directive definition for 'MatMenuBase' in '@angular/material' (esm5)."


# Did it handle namespace imported decorators in UMD using `__decorate` syntax?
Expand Down
Expand Up @@ -7,8 +7,7 @@
*/
import {ConstantPool} from '@angular/compiler';
import * as ts from 'typescript';

import {BaseDefDecoratorHandler, ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, PipeDecoratorHandler, ReferencesRegistry, ResourceLoader} from '../../../src/ngtsc/annotations';
import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, PipeDecoratorHandler, ReferencesRegistry, ResourceLoader} from '../../../src/ngtsc/annotations';
import {CycleAnalyzer, ImportGraph} from '../../../src/ngtsc/cycles';
import {isFatalDiagnosticError} from '../../../src/ngtsc/diagnostics';
import {FileSystem, LogicalFileSystem, absoluteFrom, dirname, resolve} from '../../../src/ngtsc/file_system';
Expand Down Expand Up @@ -85,7 +84,6 @@ export class DecorationAnalyzer {
importGraph = new ImportGraph(this.moduleResolver);
cycleAnalyzer = new CycleAnalyzer(this.importGraph);
handlers: DecoratorHandler<any, any>[] = [
new BaseDefDecoratorHandler(this.reflectionHost, this.evaluator, this.isCore),
new ComponentDecoratorHandler(
this.reflectionHost, this.evaluator, this.fullRegistry, this.fullMetaReader,
this.scopeRegistry, this.scopeRegistry, this.isCore, this.resourceManager, this.rootDirs,
Expand Down
5 changes: 3 additions & 2 deletions packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts
Expand Up @@ -284,7 +284,7 @@ A.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: A, selectors: [["", "a", ""]] });
.toBeGreaterThan(ngInjectorDef, 'setClassMetadata should follow ɵinj');
});

it('should render classes without decorators if handler matches', () => {
it('should render classes without decorators if class fields are decorated', () => {
const {renderer, decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses,
testFormatter} =
createTestRenderer('test-package', [{
Expand All @@ -309,7 +309,8 @@ A.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: A, selectors: [["", "a", ""]] });
const addDefinitionsSpy = testFormatter.addDefinitions as jasmine.Spy;
expect(addDefinitionsSpy.calls.first().args[2])
.toEqual(
`UndecoratedBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ viewQuery: function (rf, ctx) { if (rf & 1) {
`UndecoratedBase.ɵfac = function UndecoratedBase_Factory(t) { return new (t || UndecoratedBase)(); };
UndecoratedBase.ɵdir = ɵngcc0.ɵɵdefineDirective({ type: UndecoratedBase, selectors: [], viewQuery: function UndecoratedBase_Query(rf, ctx) { if (rf & 1) {
ɵngcc0.ɵɵstaticViewQuery(_c0, true);
} if (rf & 2) {
var _t;
Expand Down
1 change: 0 additions & 1 deletion packages/compiler-cli/src/ngtsc/annotations/index.ts
Expand Up @@ -9,7 +9,6 @@
/// <reference types="node" />

export {ResourceLoader} from './src/api';
export {BaseDefDecoratorHandler} from './src/base_def';
export {ComponentDecoratorHandler} from './src/component';
export {DirectiveDecoratorHandler} from './src/directive';
export {InjectableDecoratorHandler} from './src/injectable';
Expand Down
173 changes: 0 additions & 173 deletions packages/compiler-cli/src/ngtsc/annotations/src/base_def.ts

This file was deleted.

53 changes: 37 additions & 16 deletions packages/compiler-cli/src/ngtsc/annotations/src/directive.ts
Expand Up @@ -19,44 +19,66 @@ import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerFl

import {compileNgFactoryDefField} from './factory';
import {generateSetClassMetadataCall} from './metadata';
import {findAngularDecorator, getConstructorDependencies, readBaseClass, unwrapConstructorDependencies, unwrapExpression, unwrapForwardRef, validateConstructorDependencies} from './util';
import {findAngularDecorator, getConstructorDependencies, isAngularDecorator, readBaseClass, unwrapConstructorDependencies, unwrapExpression, unwrapForwardRef, validateConstructorDependencies} from './util';

const EMPTY_OBJECT: {[key: string]: string} = {};
const FIELD_DECORATORS = [
'Input', 'Output', 'ViewChild', 'ViewChildren', 'ContentChild', 'ContentChildren', 'HostBinding',
'HostListener'
];
const LIFECYCLE_HOOKS = new Set([
'ngOnChanges', 'ngOnInit', 'ngOnDestroy', 'ngDoCheck', 'ngAfterViewInit', 'ngAfterViewChecked',
'ngAfterContentInit', 'ngAfterContentChecked'
]);

export interface DirectiveHandlerData {
meta: R3DirectiveMetadata;
metadataStmt: Statement|null;
}
export class DirectiveDecoratorHandler implements
DecoratorHandler<DirectiveHandlerData, Decorator> {
DecoratorHandler<DirectiveHandlerData, Decorator|null> {
constructor(
private reflector: ReflectionHost, private evaluator: PartialEvaluator,
private metaRegistry: MetadataRegistry, private defaultImportRecorder: DefaultImportRecorder,
private isCore: boolean) {}

readonly precedence = HandlerPrecedence.PRIMARY;

detect(node: ClassDeclaration, decorators: Decorator[]|null): DetectResult<Decorator>|undefined {
if (!decorators) {
detect(node: ClassDeclaration, decorators: Decorator[]|null):
DetectResult<Decorator|null>|undefined {
// Compiling declaration files is invalid.
if (node.getSourceFile().isDeclarationFile) {
return undefined;
}
const decorator = findAngularDecorator(decorators, 'Directive', this.isCore);
if (decorator !== undefined) {
return {
trigger: decorator.node,
metadata: decorator,
};
// If the class is undecorated, check if any of the fields have Angular decorators or lifecycle
// hooks, and if they do, label the class as an abstract directive.
if (!decorators) {
const angularField = this.reflector.getMembersOfClass(node).find(member => {
if (!member.isStatic && member.kind === ClassMemberKind.Method &&
LIFECYCLE_HOOKS.has(member.name)) {
return true;
}
if (member.decorators) {
return member.decorators.some(
decorator => FIELD_DECORATORS.some(
decoratorName => isAngularDecorator(decorator, decoratorName, this.isCore)));
}
return false;
});
return angularField ? {trigger: angularField.node, metadata: null} : undefined;
} else {
return undefined;
const decorator = findAngularDecorator(decorators, 'Directive', this.isCore);
return decorator ? {trigger: decorator.node, metadata: decorator} : undefined;
}
}

analyze(node: ClassDeclaration, decorator: Decorator, flags = HandlerFlags.NONE):
analyze(node: ClassDeclaration, decorator: Decorator|null, flags = HandlerFlags.NONE):
AnalysisOutput<DirectiveHandlerData> {
const directiveResult = extractDirectiveMetadata(
node, decorator, this.reflector, this.evaluator, this.defaultImportRecorder, this.isCore,
flags);
const analysis = directiveResult && directiveResult.metadata;

if (analysis === undefined) {
return {};
}
Expand Down Expand Up @@ -112,15 +134,14 @@ export class DirectiveDecoratorHandler implements
* the module.
*/
export function extractDirectiveMetadata(
clazz: ClassDeclaration, decorator: Decorator, reflector: ReflectionHost,
clazz: ClassDeclaration, decorator: Decorator | null, reflector: ReflectionHost,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
clazz: ClassDeclaration, decorator: Decorator | null, reflector: ReflectionHost,
clazz: ClassDeclaration, decorator: Decorator|null, reflector: ReflectionHost,

Surprised clang-format doesn't do this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually it seems to reformat it to the one with spaces when I remove the space. I'll leave it as is.

evaluator: PartialEvaluator, defaultImportRecorder: DefaultImportRecorder, isCore: boolean,
flags: HandlerFlags, defaultSelector: string | null = null): {
decorator: Map<string, ts.Expression>,
metadata: R3DirectiveMetadata,
decoratedElements: ClassMember[],
}|undefined {
let directive: Map<string, ts.Expression>;
if (decorator.args === null || decorator.args.length === 0) {
if (decorator === null || decorator.args === null || decorator.args.length === 0) {
directive = new Map<string, ts.Expression>();
} else if (decorator.args.length !== 1) {
throw new FatalDiagnosticError(
Expand Down Expand Up @@ -256,7 +277,7 @@ export function extractDirectiveMetadata(
typeArgumentCount: reflector.getGenericArityOfClass(clazz) || 0,
typeSourceSpan: EMPTY_SOURCE_SPAN, usesInheritance, exportAs, providers
};
return {decoratedElements, decorator: directive, metadata};
return {decorator: directive, metadata};
}

export function extractQueryMetadata(
Expand Down
2 changes: 0 additions & 2 deletions packages/compiler-cli/src/ngtsc/program.ts
Expand Up @@ -14,7 +14,6 @@ import {nocollapseHack} from '../transformers/nocollapse_hack';
import {verifySupportedTypeScriptVersion} from '../typescript_support';

import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, NoopReferencesRegistry, PipeDecoratorHandler, ReferencesRegistry} from './annotations';
import {BaseDefDecoratorHandler} from './annotations/src/base_def';
import {CycleAnalyzer, ImportGraph} from './cycles';
import {ErrorCode, ngErrorCode} from './diagnostics';
import {FlatIndexGenerator, ReferenceGraph, checkForPrivateExports, findFlatIndexEntryPoint} from './entry_point';
Expand Down Expand Up @@ -587,7 +586,6 @@ export class NgtscProgram implements api.Program {

// Set up the IvyCompilation, which manages state for the Ivy transformer.
const handlers = [
new BaseDefDecoratorHandler(this.reflector, evaluator, this.isCore),
new ComponentDecoratorHandler(
this.reflector, evaluator, metaRegistry, this.metaReader !, scopeReader, scopeRegistry,
this.isCore, this.resourceManager, this.rootDirs,
Expand Down
1 change: 0 additions & 1 deletion packages/compiler-cli/src/transformers/nocollapse_hack.ts
Expand Up @@ -19,7 +19,6 @@

// Pattern matching all Render3 property names.
const R3_DEF_NAME_PATTERN = [
'ngBaseDef',
'ɵcmp',
'ɵdir',
'ɵprov',
Expand Down