fix(compiler): update to metadata version 3 (#13464)
This change retracts support for metadata version 2. The collector used to produce version 2 metadata was incomplete and can cause the AOT compiler to fail to resolve symbols or produce other spurious errors. All libraries compiled and published with 2.3.0 ngc will need to be recompiled and updated with this change.
This commit is contained in:

committed by
Victor Berchet

parent
c65b4fa9dc
commit
b6078f5887
@ -17,6 +17,11 @@ import {Symbols} from './symbols';
|
||||
* A set of collector options to use when collecting metadata.
|
||||
*/
|
||||
export class CollectorOptions {
|
||||
/**
|
||||
* Version of the metadata to collect.
|
||||
*/
|
||||
version?: number;
|
||||
|
||||
/**
|
||||
* Collect a hidden field "$quoted$" in objects literals that record when the key was quoted in
|
||||
* the source.
|
||||
@ -430,7 +435,10 @@ export class MetadataCollector {
|
||||
else if (strict) {
|
||||
validateMetadata(sourceFile, nodeMap, metadata);
|
||||
}
|
||||
const result: ModuleMetadata = {__symbolic: 'module', version: VERSION, metadata};
|
||||
const result: ModuleMetadata = {
|
||||
__symbolic: 'module',
|
||||
version: this.options.version || VERSION, metadata
|
||||
};
|
||||
if (exports) result.exports = exports;
|
||||
return result;
|
||||
}
|
||||
|
@ -110,7 +110,8 @@ export class TsickleCompilerHost extends DelegatingHost {
|
||||
const IGNORED_FILES = /\.ngfactory\.js$|\.ngstyle\.js$/;
|
||||
|
||||
export class MetadataWriterHost extends DelegatingHost {
|
||||
private metadataCollector = new MetadataCollector();
|
||||
private metadataCollector = new MetadataCollector({quotedNames: true});
|
||||
private metadataCollector1 = new MetadataCollector({version: 1});
|
||||
constructor(delegate: ts.CompilerHost, private ngOptions: NgOptions) { super(delegate); }
|
||||
|
||||
private writeMetadata(emitFilePath: string, sourceFile: ts.SourceFile) {
|
||||
@ -120,18 +121,9 @@ export class MetadataWriterHost extends DelegatingHost {
|
||||
const path = emitFilePath.replace(/*DTS*/ /\.js$/, '.metadata.json');
|
||||
const metadata =
|
||||
this.metadataCollector.getMetadata(sourceFile, !!this.ngOptions.strictMetadataEmit);
|
||||
const metadatas: ModuleMetadata[] = [metadata];
|
||||
if (metadata && metadata.metadata) {
|
||||
if (metadata.version === 2) {
|
||||
// Also emit a version 1 so that older clients can consume new metadata files as well.
|
||||
// We can write the same data as version 2 is a strict super set.
|
||||
metadatas.push({
|
||||
__symbolic: metadata.__symbolic,
|
||||
exports: metadata.exports,
|
||||
metadata: metadata.metadata,
|
||||
version: 1
|
||||
});
|
||||
}
|
||||
const metadata1 = this.metadataCollector1.getMetadata(sourceFile, false);
|
||||
const metadatas: ModuleMetadata[] = [metadata, metadata1].filter(e => !!e);
|
||||
if (metadatas.length) {
|
||||
const metadataText = JSON.stringify(metadatas);
|
||||
writeFileSync(path, metadataText, {encoding: 'utf-8'});
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
// semantics of the file in an array. For example, when generating a version 2 file, if version 1
|
||||
// can accurately represent the metadata, generate both version 1 and version 2 in an array.
|
||||
|
||||
export const VERSION = 2;
|
||||
export const VERSION = 3;
|
||||
|
||||
export type MetadataEntry = ClassMetadata | FunctionMetadata | MetadataValue;
|
||||
|
||||
|
@ -67,7 +67,7 @@ describe('Collector', () => {
|
||||
const metadata = collector.getMetadata(sourceFile);
|
||||
expect(metadata).toEqual({
|
||||
__symbolic: 'module',
|
||||
version: 2,
|
||||
version: 3,
|
||||
metadata: {
|
||||
HeroDetailComponent: {
|
||||
__symbolic: 'class',
|
||||
@ -108,7 +108,7 @@ describe('Collector', () => {
|
||||
const metadata = collector.getMetadata(sourceFile);
|
||||
expect(metadata).toEqual({
|
||||
__symbolic: 'module',
|
||||
version: 2,
|
||||
version: 3,
|
||||
metadata: {
|
||||
AppComponent: {
|
||||
__symbolic: 'class',
|
||||
@ -162,7 +162,7 @@ describe('Collector', () => {
|
||||
const metadata = collector.getMetadata(sourceFile);
|
||||
expect(metadata).toEqual({
|
||||
__symbolic: 'module',
|
||||
version: 2,
|
||||
version: 3,
|
||||
metadata: {
|
||||
HEROES: [
|
||||
{'id': 11, 'name': 'Mr. Nice', '$quoted$': ['id', 'name']},
|
||||
@ -241,7 +241,7 @@ describe('Collector', () => {
|
||||
const metadata = collector.getMetadata(unsupported1);
|
||||
expect(metadata).toEqual({
|
||||
__symbolic: 'module',
|
||||
version: 2,
|
||||
version: 3,
|
||||
metadata: {
|
||||
a: {__symbolic: 'error', message: 'Destructuring not supported', line: 1, character: 16},
|
||||
b: {__symbolic: 'error', message: 'Destructuring not supported', line: 1, character: 19},
|
||||
@ -283,7 +283,7 @@ describe('Collector', () => {
|
||||
const metadata = collector.getMetadata(sourceFile);
|
||||
expect(metadata).toEqual({
|
||||
__symbolic: 'module',
|
||||
version: 2,
|
||||
version: 3,
|
||||
metadata: {
|
||||
SimpleClass: {__symbolic: 'class'},
|
||||
AbstractClass: {__symbolic: 'class'},
|
||||
@ -297,7 +297,7 @@ describe('Collector', () => {
|
||||
const metadata = collector.getMetadata(exportedFunctions);
|
||||
expect(metadata).toEqual({
|
||||
__symbolic: 'module',
|
||||
version: 2,
|
||||
version: 3,
|
||||
metadata: {
|
||||
one: {
|
||||
__symbolic: 'function',
|
||||
|
Reference in New Issue
Block a user