mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
Adds support for TypeScript 4.4. High-level overview of the changes made in this PR: * Bumps the various packages to `typescript@4.4.2` and `tslib@2.3.0`. * The `useUnknownInCatchVariables` compiler option has been disabled so that we don't have to cast error objects explicitly everywhere. * TS now passes in a third argument to the `__spreadArray` call inside child class constructors. I had to update a couple of places in the runtime and ngcc to be able to pick up the calls correctly. * TS now generates code like `(0, foo)(arg1, arg2)` for imported function calls. I had to update a few of our tests to account for it. See https://github.com/microsoft/TypeScript/pull/44624. * Our `ngtsc` test setup calls the private `matchFiles` function from TS. I had to update our usage, because a new parameter was added. * There was one place where we were setting the readonly `hasTrailingComma` property. I updated the usage to pass in the value when constructing the object instead. * Some browser types were updated which meant that I had to resolve some trivial type errors. * The downlevel decorators tranform was running into an issue where the Closure synthetic comments were being emitted twice. I've worked around it by recreating the class declaration node instead of cloning it. PR Close #43281
110 lines
3.4 KiB
TypeScript
110 lines
3.4 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC 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 {Component, Directive, NgModule, Pipe, Type, ɵReflectionCapabilities as ReflectionCapabilities} from '@angular/core';
|
|
|
|
import {MetadataOverride} from './metadata_override';
|
|
import {MetadataOverrider} from './metadata_overrider';
|
|
|
|
const reflection = new ReflectionCapabilities();
|
|
|
|
/**
|
|
* Base interface to resolve `@Component`, `@Directive`, `@Pipe` and `@NgModule`.
|
|
*/
|
|
export interface Resolver<T> {
|
|
addOverride(type: Type<any>, override: MetadataOverride<T>): void;
|
|
setOverrides(overrides: Array<[Type<any>, MetadataOverride<T>]>): void;
|
|
resolve(type: Type<any>): T|null;
|
|
}
|
|
|
|
/**
|
|
* Allows to override ivy metadata for tests (via the `TestBed`).
|
|
*/
|
|
abstract class OverrideResolver<T> implements Resolver<T> {
|
|
private overrides = new Map<Type<any>, MetadataOverride<T>[]>();
|
|
private resolved = new Map<Type<any>, T|null>();
|
|
|
|
abstract get type(): any;
|
|
|
|
addOverride(type: Type<any>, override: MetadataOverride<T>) {
|
|
const overrides = this.overrides.get(type) || [];
|
|
overrides.push(override);
|
|
this.overrides.set(type, overrides);
|
|
this.resolved.delete(type);
|
|
}
|
|
|
|
setOverrides(overrides: Array<[Type<any>, MetadataOverride<T>]>) {
|
|
this.overrides.clear();
|
|
overrides.forEach(([type, override]) => {
|
|
this.addOverride(type, override);
|
|
});
|
|
}
|
|
|
|
getAnnotation(type: Type<any>): T|null {
|
|
const annotations = reflection.annotations(type);
|
|
// Try to find the nearest known Type annotation and make sure that this annotation is an
|
|
// instance of the type we are looking for, so we can use it for resolution. Note: there might
|
|
// be multiple known annotations found due to the fact that Components can extend Directives (so
|
|
// both Directive and Component annotations would be present), so we always check if the known
|
|
// annotation has the right type.
|
|
for (let i = annotations.length - 1; i >= 0; i--) {
|
|
const annotation = annotations[i];
|
|
const isKnownType = annotation instanceof Directive || annotation instanceof Component ||
|
|
annotation instanceof Pipe || annotation instanceof NgModule;
|
|
if (isKnownType) {
|
|
return annotation instanceof this.type ? annotation as T : null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
resolve(type: Type<any>): T|null {
|
|
let resolved = this.resolved.get(type) || null;
|
|
|
|
if (!resolved) {
|
|
resolved = this.getAnnotation(type);
|
|
if (resolved) {
|
|
const overrides = this.overrides.get(type);
|
|
if (overrides) {
|
|
const overrider = new MetadataOverrider();
|
|
overrides.forEach(override => {
|
|
resolved = overrider.overrideMetadata(this.type, resolved!, override);
|
|
});
|
|
}
|
|
}
|
|
this.resolved.set(type, resolved);
|
|
}
|
|
|
|
return resolved;
|
|
}
|
|
}
|
|
|
|
|
|
export class DirectiveResolver extends OverrideResolver<Directive> {
|
|
override get type() {
|
|
return Directive;
|
|
}
|
|
}
|
|
|
|
export class ComponentResolver extends OverrideResolver<Component> {
|
|
override get type() {
|
|
return Component;
|
|
}
|
|
}
|
|
|
|
export class PipeResolver extends OverrideResolver<Pipe> {
|
|
override get type() {
|
|
return Pipe;
|
|
}
|
|
}
|
|
|
|
export class NgModuleResolver extends OverrideResolver<NgModule> {
|
|
override get type() {
|
|
return NgModule;
|
|
}
|
|
}
|