fix(compiler): automatically set `emitDecoratorMetadata` when `"annotationsAs": "static fields”` (#19927)

This is a workaround for https://github.com/angular/tsickle/issues/635.

Fixes #19916
PR Close #19927
This commit is contained in:
Tobias Bosch 2017-10-25 08:13:56 -07:00 committed by Matias Niemelä
parent 56b18ff063
commit d56724659f
2 changed files with 56 additions and 10 deletions

View File

@ -45,6 +45,12 @@ function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback|un
if (!transformDecorators && !transformTypesToClosure) { if (!transformDecorators && !transformTypesToClosure) {
return undefined; return undefined;
} }
if (transformDecorators) {
// This is needed as a workaround for https://github.com/angular/tsickle/issues/635
// Otherwise tsickle might emit references to non imported values
// as TypeScript elided the import.
options.emitDecoratorMetadata = true;
}
const tsickleHost: tsickle.TsickleHost = { const tsickleHost: tsickle.TsickleHost = {
shouldSkipTsickleProcessing: (fileName) => shouldSkipTsickleProcessing: (fileName) =>
/\.d\.ts$/.test(fileName) || GENERATED_FILES.test(fileName), /\.d\.ts$/.test(fileName) || GENERATED_FILES.test(fileName),

View File

@ -502,29 +502,69 @@ describe('ngc transformer command-line', () => {
it('should add metadata as decorators', () => { it('should add metadata as decorators', () => {
writeConfig(`{ writeConfig(`{
"extends": "./tsconfig-base.json", "extends": "./tsconfig-base.json",
"compilerOptions": {
"emitDecoratorMetadata": true
},
"angularCompilerOptions": { "angularCompilerOptions": {
"annotationsAs": "decorators" "annotationsAs": "decorators"
}, },
"files": ["mymodule.ts"] "files": ["mymodule.ts"]
}`); }`);
write('aclass.ts', `export class AClass {}`);
write('mymodule.ts', ` write('mymodule.ts', `
import {NgModule, Component} from '@angular/core'; import {NgModule} from '@angular/core';
import {AClass} from './aclass';
@Component({template: ''}) @NgModule({declarations: []})
export class MyComp { export class MyModule {
fn(p: any) {} constructor(importedClass: AClass) {}
} }
`);
@NgModule({declarations: [MyComp]})
export class MyModule {}
`);
const exitCode = main(['-p', basePath], errorSpy); const exitCode = main(['-p', basePath], errorSpy);
expect(exitCode).toEqual(0); expect(exitCode).toEqual(0);
const mymodulejs = path.resolve(outDir, 'mymodule.js'); const mymodulejs = path.resolve(outDir, 'mymodule.js');
const mymoduleSource = fs.readFileSync(mymodulejs, 'utf8'); const mymoduleSource = fs.readFileSync(mymodulejs, 'utf8');
expect(mymoduleSource).toContain('MyComp = __decorate(['); expect(mymoduleSource).toContain('MyModule = __decorate([');
expect(mymoduleSource).toContain(`import { AClass } from './aclass';`);
expect(mymoduleSource).toContain(`__metadata("design:paramtypes", [AClass])`);
});
it('should add metadata as static fields', () => {
// Note: Don't specify emitDecoratorMetadata here on purpose,
// as regression test for https://github.com/angular/angular/issues/19916.
writeConfig(`{
"extends": "./tsconfig-base.json",
"compilerOptions": {
"emitDecoratorMetadata": false
},
"angularCompilerOptions": {
"annotationsAs": "static fields"
},
"files": ["mymodule.ts"]
}`);
write('aclass.ts', `export class AClass {}`);
write('mymodule.ts', `
import {NgModule} from '@angular/core';
import {AClass} from './aclass';
@NgModule({declarations: []})
export class MyModule {
constructor(importedClass: AClass) {}
}
`);
const exitCode = main(['-p', basePath], errorSpy);
expect(exitCode).toEqual(0);
const mymodulejs = path.resolve(outDir, 'mymodule.js');
const mymoduleSource = fs.readFileSync(mymodulejs, 'utf8');
expect(mymoduleSource).not.toContain('__decorate');
expect(mymoduleSource).toContain('args: [{ declarations: [] },] }');
expect(mymoduleSource).not.toContain(`__metadata`);
expect(mymoduleSource).toContain(`import { AClass } from './aclass';`);
expect(mymoduleSource).toContain(`{ type: AClass, }`);
}); });
}); });