forked from angular/angular
/
inheritance.ts
57 lines (51 loc) · 1.83 KB
/
inheritance.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* @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 {Reference} from '../../imports';
import {BaseMeta, DirectiveMeta, MetadataReader} from '../../metadata';
import {ClassDeclaration} from '../../reflection';
/**
* Given a reference to a directive, return a flattened version of its `DirectiveMeta` metadata
* which includes metadata from its entire inheritance chain.
*
* The returned `DirectiveMeta` will either have `baseClass: null` if the inheritance chain could be
* fully resolved, or `baseClass: 'dynamic'` if the inheritance chain could not be completely
* followed.
*/
export function flattenInheritedDirectiveMetadata(
reader: MetadataReader, dir: Reference<ClassDeclaration>): DirectiveMeta {
const topMeta = reader.getDirectiveMetadata(dir);
if (topMeta === null) {
throw new Error(`Metadata not found for directive: ${dir.debugName}`);
}
let inputs: {[key: string]: string | [string, string]} = {};
let outputs: {[key: string]: string} = {};
let isDynamic = false;
const addMetadata = (meta: DirectiveMeta | BaseMeta): void => {
if (meta.baseClass === 'dynamic') {
isDynamic = true;
} else if (meta.baseClass !== null) {
const baseMeta =
reader.getDirectiveMetadata(meta.baseClass) || reader.getBaseMetadata(meta.baseClass);
if (baseMeta !== null) {
addMetadata(baseMeta);
} else {
// Missing metadata for the base class means it's effectively dynamic.
isDynamic = true;
}
}
inputs = {...inputs, ...meta.inputs};
outputs = {...outputs, ...meta.outputs};
};
addMetadata(topMeta);
return {
...topMeta,
inputs,
outputs,
baseClass: isDynamic ? 'dynamic' : null,
};
}