Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions packages/bazel/src/ngc-wrapped/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,23 +191,8 @@ export function compile({
fileLoader = new UncachedFileLoader();
}

compilerOpts.annotationsAs = 'static fields';
if (!bazelOpts.es5Mode) {
if (bazelOpts.workspaceName === 'google3') {
compilerOpts.annotateForClosureCompiler = true;
} else {
compilerOpts.annotateForClosureCompiler = false;
}
}

// Detect from compilerOpts whether the entrypoint is being invoked in Ivy mode.
const isInIvyMode = !!compilerOpts.enableIvy;

// Disable downleveling and Closure annotation if in Ivy mode.
if (isInIvyMode) {
compilerOpts.annotationsAs = 'decorators';
}

if (!compilerOpts.rootDirs) {
throw new Error('rootDirs is not set!');
}
Expand Down Expand Up @@ -264,9 +249,6 @@ export function compile({
}

if (isInIvyMode) {
// Also need to disable decorator downleveling in the BazelHost in Ivy mode.
bazelHost.transformDecorators = false;

const delegate = bazelHost.shouldSkipTsickleProcessing.bind(bazelHost);
bazelHost.shouldSkipTsickleProcessing = (fileName: string) => {
// The base implementation of shouldSkipTsickleProcessing checks whether `fileName` is part of
Expand All @@ -277,12 +259,36 @@ export function compile({
};
}

// By default, disable tsickle decorator transforming in the tsickle compiler host.
// The Angular compilers have their own logic for decorator processing and we wouldn't
// want tsickle to interfere with that.
bazelHost.transformDecorators = false;

// By default in the `prodmode` output, we do not add annotations for closure compiler.
// Though, if we are building inside `google3`, closure annotations are desired for
// prodmode output, so we enable it by default. The defaults can be overridden by
// setting the `annotateForClosureCompiler` compiler option in the user tsconfig.
if (!bazelOpts.es5Mode) {
if (bazelOpts.workspaceName === 'google3') {
compilerOpts.annotateForClosureCompiler = true;
// Enable the tsickle decorator transform in google3 with Ivy mode enabled. The tsickle
// decorator transformation is still needed. This might be because of custom decorators
// with the `@Annotation` JSDoc that will be processed by the tsickle decorator transform.
// TODO: Figure out why this is needed in g3 and how we can improve this. FW-2225
if (isInIvyMode) {
bazelHost.transformDecorators = true;
}
} else {
compilerOpts.annotateForClosureCompiler = false;
}
}

// The `annotateForClosureCompiler` Angular compiler option is not respected by default
// as ngc-wrapped handles tsickle emit on its own. This means that we need to update
// the tsickle compiler host based on the `annotateForClosureCompiler` flag.
if (compilerOpts.annotateForClosureCompiler) {
bazelHost.transformTypesToClosure = true;
}
if (compilerOpts.annotateForClosureCompiler || compilerOpts.annotationsAs === 'static fields') {
bazelHost.transformDecorators = true;
}

const origBazelHostFileExist = bazelHost.fileExists;
bazelHost.fileExists = (fileName: string) => {
Expand Down
23 changes: 10 additions & 13 deletions packages/bazel/test/ng_package/example_package.golden
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,10 @@ Hello
var MySecondService = /** @class */ (function () {
function MySecondService() {
}
MySecondService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MySecondService_Factory() { return new MySecondService(); }, token: MySecondService, providedIn: "root" });
MySecondService.decorators = [
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
];
MySecondService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MySecondService_Factory() { return new MySecondService(); }, token: MySecondService, providedIn: "root" });
return MySecondService;
}());

Expand All @@ -271,14 +271,13 @@ Hello
function MyService(secondService) {
this.secondService = secondService;
}
MyService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MyService_Factory() { return new MyService(i0.ɵɵinject(MySecondService)); }, token: MyService, providedIn: "root" });
MyService.decorators = [
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
];
/** @nocollapse */
MyService.ctorParameters = function () { return [
{ type: MySecondService }
]; };
MyService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MyService_Factory() { return new MyService(i0.ɵɵinject(MySecondService)); }, token: MyService, providedIn: "root" });
return MyService;
}());

Expand Down Expand Up @@ -317,7 +316,7 @@ Hello
*
* 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
*/var n=function(){function e(){}return e.decorators=[{type:t.Injectable,args:[{providedIn:"root"}]}],e.ɵprov=t.ɵɵdefineInjectable({factory:function t(){return new e},token:e,providedIn:"root"}),e}(),r=function(){function e(e){this.secondService=e}return e.decorators=[{type:t.Injectable,args:[{providedIn:"root"}]}],e.ctorParameters=function(){return[{type:n}]},e.ɵprov=t.ɵɵdefineInjectable({factory:function r(){return new e(t.ɵɵinject(n))},token:e,providedIn:"root"}),e}();
*/var n=function(){function e(){}return e.ɵprov=t.ɵɵdefineInjectable({factory:function t(){return new e},token:e,providedIn:"root"}),e.decorators=[{type:t.Injectable,args:[{providedIn:"root"}]}],e}(),r=function(){function e(e){this.secondService=e}return e.ɵprov=t.ɵɵdefineInjectable({factory:function r(){return new e(t.ɵɵinject(n))},token:e,providedIn:"root"}),e.decorators=[{type:t.Injectable,args:[{providedIn:"root"}]}],e.ctorParameters=function(){return[{type:n}]},e}();
/**
* @license
* Copyright Google LLC All Rights Reserved.
Expand Down Expand Up @@ -602,18 +601,17 @@ let MyService = /** @class */ (() => {
this.secondService = secondService;
}
}
MyService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MyService_Factory() { return new MyService(i0.ɵɵinject(i1.MySecondService)); }, token: MyService, providedIn: "root" });
MyService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
/** @nocollapse */
MyService.ctorParameters = () => [
{ type: MySecondService }
];
MyService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MyService_Factory() { return new MyService(i0.ɵɵinject(i1.MySecondService)); }, token: MyService, providedIn: "root" });
return MyService;
})();
export { MyService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2JhemVsL3Rlc3QvbmdfcGFja2FnZS9leGFtcGxlL2ltcG9ydHMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxVQUFVLENBQUM7OztBQUV6QztJQUFBLE1BQ2EsU0FBUztRQUNwQixZQUFtQixhQUE4QjtZQUE5QixrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7UUFBRyxDQUFDOzs7Z0JBRnRELFVBQVUsU0FBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUM7Ozs7Z0JBRnhCLGVBQWU7OztvQkFUdkI7S0FjQztTQUZZLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7TXlTZWNvbmRTZXJ2aWNlfSBmcm9tICcuL3NlY29uZCc7XG5cbkBJbmplY3RhYmxlKHtwcm92aWRlZEluOiAncm9vdCd9KVxuZXhwb3J0IGNsYXNzIE15U2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzZWNvbmRTZXJ2aWNlOiBNeVNlY29uZFNlcnZpY2UpIHt9XG59XG4iXX0=
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2JhemVsL3Rlc3QvbmdfcGFja2FnZS9leGFtcGxlL2ltcG9ydHMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxVQUFVLENBQUM7OztBQUV6QztJQUFBLE1BQ2EsU0FBUztRQUNwQixZQUFtQixhQUE4QjtZQUE5QixrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7UUFBRyxDQUFDOzs7O2dCQUZ0RCxVQUFVLFNBQUMsRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFDOzs7Z0JBRnhCLGVBQWU7O29CQVR2QjtLQWNDO1NBRlksU0FBUyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0luamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtNeVNlY29uZFNlcnZpY2V9IGZyb20gJy4vc2Vjb25kJztcblxuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXG5leHBvcnQgY2xhc3MgTXlTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IocHVibGljIHNlY29uZFNlcnZpY2U6IE15U2Vjb25kU2VydmljZSkge31cbn1cbiJdfQ==

@devversion devversion Jun 9, 2020

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for reviewer: You might wonder why this commit changed the source map. This is because before this commit, the actual parameter type identifier was used for ctorParameters. Now since we use the import alias though for ctorParameters, the source map will change back to what it was with tsickle too (except for the move of the factory and removal of @nocollapse).


--- esm2015/imports/second.js ---

Expand All @@ -629,14 +627,14 @@ import * as i0 from "@angular/core";
let MySecondService = /** @class */ (() => {
class MySecondService {
}
MySecondService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MySecondService_Factory() { return new MySecondService(); }, token: MySecondService, providedIn: "root" });
MySecondService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
MySecondService.ɵprov = i0.ɵɵdefineInjectable({ factory: function MySecondService_Factory() { return new MySecondService(); }, token: MySecondService, providedIn: "root" });
return MySecondService;
})();
export { MySecondService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vjb25kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYmF6ZWwvdGVzdC9uZ19wYWNrYWdlL2V4YW1wbGUvaW1wb3J0cy9zZWNvbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQzs7QUFFekM7SUFBQSxNQUNhLGVBQWU7OztnQkFEM0IsVUFBVSxTQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQzs7OzBCQVZoQztLQVlDO1NBRFksZUFBZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0luamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcbmV4cG9ydCBjbGFzcyBNeVNlY29uZFNlcnZpY2Uge1xufVxuIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vjb25kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYmF6ZWwvdGVzdC9uZ19wYWNrYWdlL2V4YW1wbGUvaW1wb3J0cy9zZWNvbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQzs7QUFFekM7SUFBQSxNQUNhLGVBQWU7Ozs7Z0JBRDNCLFVBQVUsU0FBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUM7OzBCQVZoQztLQVlDO1NBRFksZUFBZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0luamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcbmV4cG9ydCBjbGFzcyBNeVNlY29uZFNlcnZpY2Uge1xufVxuIl19

--- esm2015/index.js ---

Expand Down Expand Up @@ -800,7 +798,7 @@ export { A11yModule };
* License: MIT
*/

import { Injectable, ɵɵdefineInjectable, ɵɵinject } from '@angular/core';
import { ɵɵdefineInjectable, Injectable, ɵɵinject } from '@angular/core';

/**
* @license
Expand All @@ -812,10 +810,10 @@ import { Injectable, ɵɵdefineInjectable, ɵɵinject } from '@angular/core';
let MySecondService = /** @class */ (() => {
class MySecondService {
}
MySecondService.ɵprov = ɵɵdefineInjectable({ factory: function MySecondService_Factory() { return new MySecondService(); }, token: MySecondService, providedIn: "root" });
MySecondService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
MySecondService.ɵprov = ɵɵdefineInjectable({ factory: function MySecondService_Factory() { return new MySecondService(); }, token: MySecondService, providedIn: "root" });
return MySecondService;
})();

Expand All @@ -832,14 +830,13 @@ let MyService = /** @class */ (() => {
this.secondService = secondService;
}
}
MyService.ɵprov = ɵɵdefineInjectable({ factory: function MyService_Factory() { return new MyService(ɵɵinject(MySecondService)); }, token: MyService, providedIn: "root" });
MyService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
/** @nocollapse */
MyService.ctorParameters = () => [
{ type: MySecondService }
];
MyService.ɵprov = ɵɵdefineInjectable({ factory: function MyService_Factory() { return new MyService(ɵɵinject(MySecondService)); }, token: MyService, providedIn: "root" });
return MyService;
})();

Expand Down
1 change: 1 addition & 0 deletions packages/compiler-cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ts_library(
"//packages/compiler-cli/src/ngtsc/file_system",
"//packages/compiler-cli/src/ngtsc/indexer",
"//packages/compiler-cli/src/ngtsc/perf",
"//packages/compiler-cli/src/ngtsc/reflection",
"//packages/compiler-cli/src/ngtsc/typecheck",
"@npm//@bazel/typescript",
"@npm//@types/node",
Expand Down
65 changes: 22 additions & 43 deletions packages/compiler-cli/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,9 @@ export function mainDiagnosticsForTest(
}

function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback|undefined {
const transformDecorators =
(options.enableIvy === false && options.annotationsAs !== 'decorators');
const transformTypesToClosure = options.annotateForClosureCompiler;
if (!transformDecorators && !transformTypesToClosure) {
if (!options.annotateForClosureCompiler) {
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: Pick<
tsickle.TsickleHost,
'shouldSkipTsickleProcessing'|'pathToModuleName'|'shouldIgnoreWarningsForPath'|
Expand All @@ -115,41 +106,29 @@ function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback|un
googmodule: false,
untyped: true,
convertIndexImportShorthand: false,
transformDecorators,
transformTypesToClosure,
// Decorators are transformed as part of the Angular compiler programs. To avoid
// conflicts, we disable decorator transformations for tsickle.
transformDecorators: false,
transformTypesToClosure: true,
};

if (options.annotateForClosureCompiler || options.annotationsAs === 'static fields') {
return ({
program,
targetSourceFile,
writeFile,
cancellationToken,
emitOnlyDtsFiles,
customTransformers = {},
host,
options
}) =>
// tslint:disable-next-line:no-require-imports only depend on tsickle if requested
require('tsickle').emitWithTsickle(
program, {...tsickleHost, options, host, moduleResolutionHost: host}, host, options,
targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, {
beforeTs: customTransformers.before,
afterTs: customTransformers.after,
});
} else {
return ({
program,
targetSourceFile,
writeFile,
cancellationToken,
emitOnlyDtsFiles,
customTransformers = {},
}) =>
program.emit(
targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles,
{after: customTransformers.after, before: customTransformers.before});
}
return ({
program,
targetSourceFile,
writeFile,
cancellationToken,
emitOnlyDtsFiles,
customTransformers = {},
host,
options
}) =>
// tslint:disable-next-line:no-require-imports only depend on tsickle if requested
require('tsickle').emitWithTsickle(
program, {...tsickleHost, options, host, moduleResolutionHost: host}, host, options,
targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, {
beforeTs: customTransformers.before,
afterTs: customTransformers.after,
});
}

export interface NgcParsedConfiguration extends ParsedConfiguration {
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-cli/src/ngtsc/core/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ export class NgCompiler {
/**
* Determine if the given `Program` is @angular/core.
*/
function isAngularCorePackage(program: ts.Program): boolean {
export function isAngularCorePackage(program: ts.Program): boolean {
// Look for its_just_angular.ts somewhere in the program.
const r3Symbols = getR3SymbolsFile(program);
if (r3Symbols === null) {
Expand Down
19 changes: 19 additions & 0 deletions packages/compiler-cli/src/tooling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
* Any changes to this file should be discussed with the Angular CLI team.
*/

import * as ts from 'typescript';

import {TypeScriptReflectionHost} from './ngtsc/reflection';
import {getDownlevelDecoratorsTransform} from './transformers/downlevel_decorators_transform';

/**
* Known values for global variables in `@angular/core` that Terser should set using
Expand All @@ -28,3 +31,19 @@ export const GLOBAL_DEFS_FOR_TERSER_WITH_AOT = {
...GLOBAL_DEFS_FOR_TERSER,
ngJitMode: false,
};

/**
* Transform for downleveling Angular decorators and Angular-decorated class constructor
* parameters for dependency injection. This transform can be used by the CLI for JIT-mode
* compilation where decorators should be preserved, but downleveled so that apps are not
* exposed to the ES2015 temporal dead zone limitation in TypeScript's metadata.
* See https://github.com/angular/angular-cli/pull/14473 for more details.
*/
export function decoratorDownlevelTransformerFactory(program: ts.Program):
ts.TransformerFactory<ts.SourceFile> {
const typeChecker = program.getTypeChecker();
const reflectionHost = new TypeScriptReflectionHost(typeChecker);
return getDownlevelDecoratorsTransform(
typeChecker, reflectionHost, [], /* isCore */ false,
/* enableClosureCompiler */ false);
}
Loading