fix(compiler-cli): strictMetadataEmit should not break on non-compliant libraries (#23275)
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
This commit is contained in:
parent
60e8392722
commit
58143555bc
|
@ -11,6 +11,7 @@ import * as ts from 'typescript';
|
||||||
import {MetadataCollector, MetadataValue, ModuleMetadata} from '../metadata/index';
|
import {MetadataCollector, MetadataValue, ModuleMetadata} from '../metadata/index';
|
||||||
|
|
||||||
import {MetadataProvider} from './compiler_host';
|
import {MetadataProvider} from './compiler_host';
|
||||||
|
import {TS} from './util';
|
||||||
|
|
||||||
export type ValueTransform = (value: MetadataValue, node: ts.Node) => MetadataValue;
|
export type ValueTransform = (value: MetadataValue, node: ts.Node) => MetadataValue;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ export class MetadataCache implements MetadataProvider {
|
||||||
private metadataCache = new Map<string, ModuleMetadata|undefined>();
|
private metadataCache = new Map<string, ModuleMetadata|undefined>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private collector: MetadataCollector, private strict: boolean,
|
private collector: MetadataCollector, private readonly strict: boolean,
|
||||||
private transformers: MetadataTransformer[]) {
|
private transformers: MetadataTransformer[]) {
|
||||||
for (let transformer of transformers) {
|
for (let transformer of transformers) {
|
||||||
if (transformer.connect) {
|
if (transformer.connect) {
|
||||||
|
@ -59,7 +60,8 @@ export class MetadataCache implements MetadataProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = this.collector.getMetadata(sourceFile, this.strict, substitute);
|
const isTsFile = TS.test(sourceFile.fileName);
|
||||||
|
const result = this.collector.getMetadata(sourceFile, this.strict && isTsFile, substitute);
|
||||||
this.metadataCache.set(sourceFile.fileName, result);
|
this.metadataCache.set(sourceFile.fileName, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2420,4 +2420,31 @@ describe('ngc transformer command-line', () => {
|
||||||
expect(moduleSource).toMatch(/inject\(i0\.INJECTOR/);
|
expect(moduleSource).toMatch(/inject\(i0\.INJECTOR/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('libraries should not break strictMetadataEmit', () => {
|
||||||
|
// first only generate .d.ts / .js / .metadata.json files
|
||||||
|
writeConfig(`{
|
||||||
|
"extends": "./tsconfig-base.json",
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"skipTemplateCodegen": true,
|
||||||
|
"strictMetadataEmit": true,
|
||||||
|
"fullTemplateTypeCheck": true
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "lib"
|
||||||
|
},
|
||||||
|
"files": ["main.ts", "test.d.ts"]
|
||||||
|
}`);
|
||||||
|
write('main.ts', `
|
||||||
|
import {Test} from './test';
|
||||||
|
export const bar = Test.bar;
|
||||||
|
`);
|
||||||
|
write('test.d.ts', `
|
||||||
|
declare export class Test {
|
||||||
|
static bar: string;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
let exitCode = main(['-p', path.join(basePath, 'tsconfig.json')], errorSpy);
|
||||||
|
expect(exitCode).toEqual(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue