
rxjs 6.0.0 breaks strictMetadataEmit as they now publish a .d.ts file with a structure like: declare export class Subscription { static EMPTY: Subscription; } This generates metadata which contains an error, and fails the strictMetadataEmit validation. There is nothing a library author can do in this situation except to set strictMetadataEmit to false. The spirit of strictMetadataEmit is to validate that the author's library doesn't do anything that will break downstream users. This failure is a corner case which causes more harm than good, so this commit disables validation for metadata collected from .d.ts files. Fixes #22210 PR Close #23275
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
/**
|
|
* @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 * as ts from 'typescript';
|
|
|
|
import {MetadataCollector, MetadataValue, ModuleMetadata} from '../metadata/index';
|
|
|
|
import {MetadataProvider} from './compiler_host';
|
|
import {TS} from './util';
|
|
|
|
export type ValueTransform = (value: MetadataValue, node: ts.Node) => MetadataValue;
|
|
|
|
export interface MetadataTransformer {
|
|
connect?(cache: MetadataCache): void;
|
|
start(sourceFile: ts.SourceFile): ValueTransform|undefined;
|
|
}
|
|
|
|
/**
|
|
* Cache, and potentially transform, metadata as it is being collected.
|
|
*/
|
|
export class MetadataCache implements MetadataProvider {
|
|
private metadataCache = new Map<string, ModuleMetadata|undefined>();
|
|
|
|
constructor(
|
|
private collector: MetadataCollector, private readonly strict: boolean,
|
|
private transformers: MetadataTransformer[]) {
|
|
for (let transformer of transformers) {
|
|
if (transformer.connect) {
|
|
transformer.connect(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
getMetadata(sourceFile: ts.SourceFile): ModuleMetadata|undefined {
|
|
if (this.metadataCache.has(sourceFile.fileName)) {
|
|
return this.metadataCache.get(sourceFile.fileName);
|
|
}
|
|
let substitute: ValueTransform|undefined = undefined;
|
|
|
|
// Only process transformers on modules that are not declaration files.
|
|
const declarationFile = sourceFile.isDeclarationFile;
|
|
const moduleFile = ts.isExternalModule(sourceFile);
|
|
if (!declarationFile && moduleFile) {
|
|
for (let transform of this.transformers) {
|
|
const transformSubstitute = transform.start(sourceFile);
|
|
if (transformSubstitute) {
|
|
if (substitute) {
|
|
const previous: ValueTransform = substitute;
|
|
substitute = (value: MetadataValue, node: ts.Node) =>
|
|
transformSubstitute(previous(value, node), node);
|
|
} else {
|
|
substitute = transformSubstitute;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const isTsFile = TS.test(sourceFile.fileName);
|
|
const result = this.collector.getMetadata(sourceFile, this.strict && isTsFile, substitute);
|
|
this.metadataCache.set(sourceFile.fileName, result);
|
|
return result;
|
|
}
|
|
} |