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
|
|
|
|
*/
|
|
|
|
|
2016-04-28 21:57:16 -07:00
|
|
|
/**
|
|
|
|
* Transform template html and css into executable code.
|
|
|
|
* Intended to be used in a build step.
|
|
|
|
*/
|
2016-04-28 17:50:03 -07:00
|
|
|
import * as compiler from '@angular/compiler';
|
2016-10-25 16:28:22 -07:00
|
|
|
import {ViewEncapsulation} from '@angular/core';
|
2016-08-12 14:45:36 -07:00
|
|
|
import {AngularCompilerOptions, NgcCliOptions} from '@angular/tsc-wrapped';
|
2016-11-09 15:17:24 -08:00
|
|
|
import {readFileSync} from 'fs';
|
2016-06-08 16:38:52 -07:00
|
|
|
import * as path from 'path';
|
|
|
|
import * as ts from 'typescript';
|
2016-04-28 21:57:16 -07:00
|
|
|
|
2016-12-01 13:24:51 -08:00
|
|
|
import {CompilerHost, CompilerHostContext, ModuleResolutionHostAdapter} from './compiler_host';
|
2016-11-17 12:24:33 -08:00
|
|
|
import {PathMappedCompilerHost} from './path_mapped_compiler_host';
|
2016-08-30 18:07:40 -07:00
|
|
|
import {Console} from './private_import_core';
|
2016-04-28 21:57:16 -07:00
|
|
|
|
2016-08-12 17:38:29 -07:00
|
|
|
const GENERATED_FILES = /\.ngfactory\.ts$|\.css\.ts$|\.css\.shim\.ts$/;
|
2016-08-23 16:26:35 -07:00
|
|
|
const GENERATED_OR_DTS_FILES = /\.d\.ts$|\.ngfactory\.ts$|\.css\.ts$|\.css\.shim\.ts$/;
|
2016-08-12 17:38:29 -07:00
|
|
|
|
2016-04-28 21:57:16 -07:00
|
|
|
const PREAMBLE = `/**
|
2016-11-02 21:11:30 -07:00
|
|
|
* @fileoverview This file is generated by the Angular 2 template compiler.
|
2016-04-28 21:57:16 -07:00
|
|
|
* Do not edit.
|
2016-11-04 15:18:05 -07:00
|
|
|
* @suppress {suspiciousCode,uselessCode,missingProperties}
|
2016-04-28 21:57:16 -07:00
|
|
|
*/
|
2016-05-27 09:16:46 -07:00
|
|
|
/* tslint:disable */
|
|
|
|
|
2016-04-28 21:57:16 -07:00
|
|
|
`;
|
|
|
|
|
2016-10-06 15:10:44 -07:00
|
|
|
export class CodeGenerator {
|
|
|
|
constructor(
|
|
|
|
private options: AngularCompilerOptions, private program: ts.Program,
|
2016-11-18 08:40:41 -08:00
|
|
|
public host: ts.CompilerHost, private compiler: compiler.AotCompiler,
|
|
|
|
private ngCompilerHost: CompilerHost) {}
|
2016-04-28 21:57:16 -07:00
|
|
|
|
2016-05-03 11:50:55 -06:00
|
|
|
// Write codegen in a directory structure matching the sources.
|
2016-08-09 14:58:19 -07:00
|
|
|
private calculateEmitPath(filePath: string): string {
|
2016-05-24 10:53:48 -07:00
|
|
|
let root = this.options.basePath;
|
2016-10-24 13:28:23 -07:00
|
|
|
for (const eachRootDir of this.options.rootDirs || []) {
|
2016-05-24 10:53:48 -07:00
|
|
|
if (this.options.trace) {
|
2016-11-22 13:29:53 -08:00
|
|
|
console.error(`Check if ${filePath} is under rootDirs element ${eachRootDir}`);
|
2016-05-03 11:50:55 -06:00
|
|
|
}
|
|
|
|
if (path.relative(eachRootDir, filePath).indexOf('.') !== 0) {
|
|
|
|
root = eachRootDir;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-03 21:34:03 -07:00
|
|
|
// transplant the codegen path to be inside the `genDir`
|
2016-10-24 13:28:23 -07:00
|
|
|
let relativePath: string = path.relative(root, filePath);
|
2016-08-03 21:34:03 -07:00
|
|
|
while (relativePath.startsWith('..' + path.sep)) {
|
|
|
|
// Strip out any `..` path such as: `../node_modules/@foo` as we want to put everything
|
|
|
|
// into `genDir`.
|
|
|
|
relativePath = relativePath.substr(3);
|
|
|
|
}
|
2016-10-24 13:28:23 -07:00
|
|
|
|
2016-08-03 21:34:03 -07:00
|
|
|
return path.join(this.options.genDir, relativePath);
|
2016-05-03 11:50:55 -06:00
|
|
|
}
|
|
|
|
|
2016-11-15 13:57:25 -08:00
|
|
|
codegen(): Promise<any> {
|
|
|
|
return this.compiler
|
2016-11-17 12:24:33 -08:00
|
|
|
.compileAll(this.program.getSourceFiles().map(
|
|
|
|
sf => this.ngCompilerHost.getCanonicalFileName(sf.fileName)))
|
2016-11-15 13:57:25 -08:00
|
|
|
.then(generatedModules => {
|
|
|
|
generatedModules.forEach(generatedModule => {
|
|
|
|
const sourceFile = this.program.getSourceFile(generatedModule.fileUrl);
|
|
|
|
const emitPath = this.calculateEmitPath(generatedModule.moduleUrl);
|
|
|
|
this.host.writeFile(
|
|
|
|
emitPath, PREAMBLE + generatedModule.source, false, () => {}, [sourceFile]);
|
|
|
|
});
|
|
|
|
});
|
2016-04-28 21:57:16 -07:00
|
|
|
}
|
|
|
|
|
2016-06-08 16:38:52 -07:00
|
|
|
static create(
|
2016-08-12 14:45:36 -07:00
|
|
|
options: AngularCompilerOptions, cliOptions: NgcCliOptions, program: ts.Program,
|
2016-11-17 12:24:33 -08:00
|
|
|
tsCompilerHost: ts.CompilerHost, compilerHostContext?: CompilerHostContext,
|
|
|
|
ngCompilerHost?: CompilerHost): CodeGenerator {
|
|
|
|
if (!ngCompilerHost) {
|
2016-11-15 13:57:25 -08:00
|
|
|
const usePathMapping = !!options.rootDirs && options.rootDirs.length > 0;
|
2016-12-01 13:24:51 -08:00
|
|
|
const context = compilerHostContext || new ModuleResolutionHostAdapter(tsCompilerHost);
|
|
|
|
ngCompilerHost = usePathMapping ? new PathMappedCompilerHost(program, options, context) :
|
|
|
|
new CompilerHost(program, options, context);
|
2016-11-15 13:57:25 -08:00
|
|
|
}
|
2016-08-12 14:45:36 -07:00
|
|
|
const transFile = cliOptions.i18nFile;
|
|
|
|
const locale = cliOptions.locale;
|
|
|
|
let transContent: string = '';
|
2016-08-26 15:38:48 -07:00
|
|
|
if (transFile) {
|
|
|
|
if (!locale) {
|
|
|
|
throw new Error(
|
|
|
|
`The translation file (${transFile}) locale must be provided. Use the --locale option.`);
|
|
|
|
}
|
2016-11-09 15:17:24 -08:00
|
|
|
transContent = readFileSync(transFile, 'utf8');
|
2016-08-12 14:45:36 -07:00
|
|
|
}
|
2016-11-18 08:40:41 -08:00
|
|
|
const {compiler: aotCompiler} = compiler.createAotCompiler(ngCompilerHost, {
|
2016-11-15 11:13:20 -08:00
|
|
|
debug: options.debug === true,
|
|
|
|
translations: transContent,
|
|
|
|
i18nFormat: cliOptions.i18nFormat,
|
2016-11-15 13:57:25 -08:00
|
|
|
locale: cliOptions.locale,
|
|
|
|
excludeFilePattern: options.generateCodeForLibraries === false ? GENERATED_OR_DTS_FILES :
|
|
|
|
GENERATED_FILES
|
2016-06-13 10:06:40 -07:00
|
|
|
});
|
2016-11-18 08:40:41 -08:00
|
|
|
return new CodeGenerator(options, program, tsCompilerHost, aotCompiler, ngCompilerHost);
|
2016-04-28 21:57:16 -07:00
|
|
|
}
|
|
|
|
}
|
2016-10-25 16:28:22 -07:00
|
|
|
|
2016-11-18 08:40:41 -08:00
|
|
|
export function excludeFilePattern(options: AngularCompilerOptions): RegExp {
|
|
|
|
return options.generateCodeForLibraries === false ? GENERATED_OR_DTS_FILES : GENERATED_FILES;
|
2016-11-08 15:45:30 -08:00
|
|
|
}
|