2016-05-03 17:31:40 -07:00
|
|
|
|
#!/usr/bin/env node
|
2016-06-23 09:47:54 -07:00
|
|
|
|
/**
|
|
|
|
|
* @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
|
|
|
|
|
*/
|
|
|
|
|
|
2017-03-27 09:44:35 -07:00
|
|
|
|
// Must be imported first, because Angular decorators throw on load.
|
2016-04-29 10:35:36 -07:00
|
|
|
|
import 'reflect-metadata';
|
|
|
|
|
|
|
|
|
|
import * as ts from 'typescript';
|
2016-05-27 16:22:16 -07:00
|
|
|
|
import * as tsc from '@angular/tsc-wrapped';
|
2017-08-02 11:20:07 -07:00
|
|
|
|
import * as fs from 'fs';
|
|
|
|
|
import * as path from 'path';
|
2017-08-16 15:35:19 -07:00
|
|
|
|
import * as tsickle from 'tsickle';
|
2017-08-09 13:45:45 -07:00
|
|
|
|
import * as api from './transformers/api';
|
|
|
|
|
import * as ngc from './transformers/entry_points';
|
2017-08-02 11:20:07 -07:00
|
|
|
|
|
2017-09-12 15:53:17 -07:00
|
|
|
|
import {exitCodeFromResult, performCompilation, readConfiguration, formatDiagnostics, Diagnostics, ParsedConfiguration, PerformCompilationResult} from './perform_compile';
|
2017-08-18 14:03:59 -07:00
|
|
|
|
import {performWatchCompilation, createPerformWatchHost} from './perform_watch';
|
2017-01-27 13:19:00 -08:00
|
|
|
|
import {isSyntaxError} from '@angular/compiler';
|
2017-08-09 13:45:45 -07:00
|
|
|
|
import {CodeGenerator} from './codegen';
|
2016-05-01 11:22:39 -07:00
|
|
|
|
|
2017-09-12 15:53:17 -07:00
|
|
|
|
// TODO(tbosch): remove this old entrypoint once we drop `disableTransformerPipeline`.
|
2017-08-09 13:45:45 -07:00
|
|
|
|
export function main(
|
|
|
|
|
args: string[], consoleError: (s: string) => void = console.error): Promise<number> {
|
2017-09-12 15:53:17 -07:00
|
|
|
|
let {project, rootNames, options, errors: configErrors, watch} =
|
|
|
|
|
readNgcCommandLineAndConfiguration(args);
|
2017-08-09 13:45:45 -07:00
|
|
|
|
if (configErrors.length) {
|
|
|
|
|
return Promise.resolve(reportErrorsAndExit(options, configErrors, consoleError));
|
|
|
|
|
}
|
2017-09-12 15:53:17 -07:00
|
|
|
|
if (watch) {
|
|
|
|
|
const result = watchMode(project, options, consoleError);
|
|
|
|
|
return Promise.resolve(reportErrorsAndExit({}, result.firstCompileResult, consoleError));
|
|
|
|
|
}
|
2017-08-09 13:45:45 -07:00
|
|
|
|
if (options.disableTransformerPipeline) {
|
2017-09-12 15:53:17 -07:00
|
|
|
|
return disabledTransformerPipelineNgcMain(args, consoleError);
|
2017-08-09 13:45:45 -07:00
|
|
|
|
}
|
2017-08-16 15:35:19 -07:00
|
|
|
|
const {diagnostics: compileDiags} =
|
|
|
|
|
performCompilation({rootNames, options, emitCallback: createEmitCallback(options)});
|
2017-08-09 13:45:45 -07:00
|
|
|
|
return Promise.resolve(reportErrorsAndExit(options, compileDiags, consoleError));
|
|
|
|
|
}
|
2017-08-02 11:20:07 -07:00
|
|
|
|
|
2017-08-09 13:45:45 -07:00
|
|
|
|
export function mainSync(
|
2017-09-12 15:53:17 -07:00
|
|
|
|
args: string[], consoleError: (s: string) => void = console.error,
|
|
|
|
|
config?: NgcParsedConfiguration): number {
|
|
|
|
|
let {project, rootNames, options, errors: configErrors, watch, emitFlags} =
|
|
|
|
|
config || readNgcCommandLineAndConfiguration(args);
|
2017-08-09 13:45:45 -07:00
|
|
|
|
if (configErrors.length) {
|
|
|
|
|
return reportErrorsAndExit(options, configErrors, consoleError);
|
|
|
|
|
}
|
2017-09-12 15:53:17 -07:00
|
|
|
|
if (watch) {
|
|
|
|
|
const result = watchMode(project, options, consoleError);
|
|
|
|
|
return reportErrorsAndExit({}, result.firstCompileResult, consoleError);
|
|
|
|
|
}
|
|
|
|
|
const {diagnostics: compileDiags} = performCompilation(
|
|
|
|
|
{rootNames, options, emitFlags, emitCallback: createEmitCallback(options)});
|
2017-08-09 13:45:45 -07:00
|
|
|
|
return reportErrorsAndExit(options, compileDiags, consoleError);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 15:35:19 -07:00
|
|
|
|
function createEmitCallback(options: api.CompilerOptions): api.TsEmitCallback {
|
2017-09-08 18:40:32 -07:00
|
|
|
|
const tsickleHost: tsickle.TsickleHost = {
|
|
|
|
|
shouldSkipTsickleProcessing: (fileName) => /\.d\.ts$/.test(fileName),
|
|
|
|
|
pathToModuleName: (context, importPath) => '',
|
|
|
|
|
shouldIgnoreWarningsForPath: (filePath) => false,
|
|
|
|
|
fileNameToModuleId: (fileName) => fileName,
|
2017-08-16 15:35:19 -07:00
|
|
|
|
googmodule: false,
|
|
|
|
|
untyped: true,
|
|
|
|
|
convertIndexImportShorthand: true,
|
|
|
|
|
transformDecorators: options.annotationsAs !== 'decorators',
|
|
|
|
|
transformTypesToClosure: options.annotateForClosureCompiler,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return ({
|
|
|
|
|
program,
|
|
|
|
|
targetSourceFile,
|
|
|
|
|
writeFile,
|
|
|
|
|
cancellationToken,
|
|
|
|
|
emitOnlyDtsFiles,
|
|
|
|
|
customTransformers = {},
|
|
|
|
|
host,
|
|
|
|
|
options
|
|
|
|
|
}) =>
|
|
|
|
|
tsickle.emitWithTsickle(
|
2017-09-08 18:40:32 -07:00
|
|
|
|
program, tsickleHost, host, options, targetSourceFile, writeFile,
|
2017-08-16 15:35:19 -07:00
|
|
|
|
cancellationToken, emitOnlyDtsFiles, {
|
|
|
|
|
beforeTs: customTransformers.before,
|
|
|
|
|
afterTs: customTransformers.after,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 15:53:17 -07:00
|
|
|
|
export interface NgcParsedConfiguration extends ParsedConfiguration { watch?: boolean; }
|
|
|
|
|
|
|
|
|
|
function readNgcCommandLineAndConfiguration(args: string[]): NgcParsedConfiguration {
|
|
|
|
|
const options: api.CompilerOptions = {};
|
|
|
|
|
const parsedArgs = require('minimist')(args);
|
|
|
|
|
if (parsedArgs.i18nFile) options.i18nInFile = parsedArgs.i18nFile;
|
|
|
|
|
if (parsedArgs.i18nFormat) options.i18nInFormat = parsedArgs.i18nFormat;
|
|
|
|
|
if (parsedArgs.locale) options.i18nInLocale = parsedArgs.locale;
|
|
|
|
|
const mt = parsedArgs.missingTranslation;
|
|
|
|
|
if (mt === 'error' || mt === 'warning' || mt === 'ignore') {
|
|
|
|
|
options.i18nInMissingTranslations = mt;
|
|
|
|
|
}
|
|
|
|
|
const config = readCommandLineAndConfiguration(
|
|
|
|
|
args, options, ['i18nFile', 'i18nFormat', 'locale', 'missingTranslation', 'watch']);
|
|
|
|
|
const watch = parsedArgs.w || parsedArgs.watch;
|
|
|
|
|
return {...config, watch};
|
2017-08-18 14:03:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 15:53:17 -07:00
|
|
|
|
export function readCommandLineAndConfiguration(
|
|
|
|
|
args: string[], existingOptions: api.CompilerOptions = {},
|
|
|
|
|
ngCmdLineOptions: string[] = []): ParsedConfiguration {
|
|
|
|
|
let cmdConfig = ts.parseCommandLine(args);
|
|
|
|
|
const project = cmdConfig.options.project || '.';
|
|
|
|
|
const cmdErrors = cmdConfig.errors.filter(e => {
|
|
|
|
|
if (typeof e.messageText === 'string') {
|
|
|
|
|
const msg = e.messageText;
|
|
|
|
|
return !ngCmdLineOptions.some(o => msg.indexOf(o) >= 0);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
if (cmdErrors.length) {
|
|
|
|
|
return {
|
|
|
|
|
project,
|
|
|
|
|
rootNames: [],
|
|
|
|
|
options: cmdConfig.options,
|
|
|
|
|
errors: cmdErrors,
|
|
|
|
|
emitFlags: api.EmitFlags.Default
|
|
|
|
|
};
|
|
|
|
|
}
|
2017-08-09 13:45:45 -07:00
|
|
|
|
const allDiagnostics: Diagnostics = [];
|
2017-09-12 15:53:17 -07:00
|
|
|
|
const config = readConfiguration(project, cmdConfig.options);
|
|
|
|
|
const options = {...config.options, ...existingOptions};
|
2017-08-31 23:11:29 +02:00
|
|
|
|
if (options.locale) {
|
|
|
|
|
options.i18nInLocale = options.locale;
|
|
|
|
|
}
|
2017-09-12 15:53:17 -07:00
|
|
|
|
return {
|
|
|
|
|
project,
|
|
|
|
|
rootNames: config.rootNames, options,
|
|
|
|
|
errors: config.errors,
|
|
|
|
|
emitFlags: config.emitFlags
|
|
|
|
|
};
|
2017-08-09 13:45:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reportErrorsAndExit(
|
|
|
|
|
options: api.CompilerOptions, allDiagnostics: Diagnostics,
|
|
|
|
|
consoleError: (s: string) => void = console.error): number {
|
|
|
|
|
if (allDiagnostics.length) {
|
|
|
|
|
consoleError(formatDiagnostics(options, allDiagnostics));
|
|
|
|
|
}
|
2017-09-12 15:53:17 -07:00
|
|
|
|
return exitCodeFromResult(allDiagnostics);
|
2017-08-18 14:03:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 15:53:17 -07:00
|
|
|
|
export function watchMode(
|
|
|
|
|
project: string, options: api.CompilerOptions, consoleError: (s: string) => void) {
|
|
|
|
|
return performWatchCompilation(createPerformWatchHost(project, diagnostics => {
|
|
|
|
|
consoleError(formatDiagnostics(options, diagnostics));
|
|
|
|
|
}, options, options => createEmitCallback(options)));
|
2017-08-09 13:45:45 -07:00
|
|
|
|
}
|
2016-05-01 11:22:39 -07:00
|
|
|
|
|
2017-08-09 13:45:45 -07:00
|
|
|
|
function disabledTransformerPipelineNgcMain(
|
2017-09-12 15:53:17 -07:00
|
|
|
|
args: string[], consoleError: (s: string) => void = console.error): Promise<number> {
|
|
|
|
|
const parsedArgs = require('minimist')(args);
|
|
|
|
|
const cliOptions = new tsc.NgcCliOptions(parsedArgs);
|
|
|
|
|
const project = parsedArgs.p || parsedArgs.project || '.';
|
2017-08-09 13:45:45 -07:00
|
|
|
|
return tsc.main(project, cliOptions, disabledTransformerPipelineCodegen)
|
|
|
|
|
.then(() => 0)
|
|
|
|
|
.catch(e => {
|
|
|
|
|
if (e instanceof tsc.UserError || isSyntaxError(e)) {
|
|
|
|
|
consoleError(e.message);
|
|
|
|
|
} else {
|
|
|
|
|
consoleError(e.stack);
|
|
|
|
|
}
|
|
|
|
|
return Promise.resolve(1);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function disabledTransformerPipelineCodegen(
|
2017-09-12 15:53:17 -07:00
|
|
|
|
ngOptions: api.CompilerOptions, cliOptions: tsc.NgcCliOptions, program: ts.Program,
|
2016-08-12 14:45:36 -07:00
|
|
|
|
host: ts.CompilerHost) {
|
2017-06-09 14:00:03 -07:00
|
|
|
|
if (ngOptions.enableSummariesForJit === undefined) {
|
|
|
|
|
// default to false
|
|
|
|
|
ngOptions.enableSummariesForJit = false;
|
|
|
|
|
}
|
2016-11-15 13:57:25 -08:00
|
|
|
|
return CodeGenerator.create(ngOptions, cliOptions, program, host).codegen();
|
2016-04-29 10:35:36 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 13:59:53 -08:00
|
|
|
|
// CLI entry point
|
|
|
|
|
if (require.main === module) {
|
2017-08-02 11:20:07 -07:00
|
|
|
|
const args = process.argv.slice(2);
|
2017-09-12 15:53:17 -07:00
|
|
|
|
process.exitCode = mainSync(args);
|
2016-11-30 16:45:40 -08:00
|
|
|
|
}
|