diff --git a/modules/@angular/compiler-cli/integrationtest/src/basic.html b/modules/@angular/compiler-cli/integrationtest/src/basic.html index f36206577f..081304bf01 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/basic.html +++ b/modules/@angular/compiler-cli/integrationtest/src/basic.html @@ -2,3 +2,4 @@
+

Welcome

diff --git a/modules/@angular/compiler-cli/integrationtest/src/basic.ts b/modules/@angular/compiler-cli/integrationtest/src/basic.ts index 8c06cf3798..5a39f83126 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/basic.ts +++ b/modules/@angular/compiler-cli/integrationtest/src/basic.ts @@ -7,7 +7,7 @@ */ import {NgFor, NgIf} from '@angular/common'; -import {Component, Inject} from '@angular/core'; +import {Component, Inject, LOCALE_ID, TRANSLATIONS_FORMAT} from '@angular/core'; import {FORM_DIRECTIVES} from '@angular/forms'; import {MultipleComponentsMyComp} from './a/multiple_components'; @@ -23,5 +23,9 @@ export class BasicComp { ctxProp: string; ctxBool: boolean; ctxArr: any[] = []; - constructor() { this.ctxProp = 'initialValue'; } + constructor( + @Inject(LOCALE_ID) public localeId: string, + @Inject(TRANSLATIONS_FORMAT) public translationsFormat: string) { + this.ctxProp = 'initialValue'; + } } diff --git a/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb b/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb new file mode 100644 index 0000000000..7b3b157e47 --- /dev/null +++ b/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb @@ -0,0 +1,4 @@ + + käännä teksti + tervetuloa + diff --git a/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts b/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts index c2c6820b92..c4b2dcf5b8 100644 --- a/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts +++ b/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts @@ -44,24 +44,45 @@ describe('template codegen output', () => { it('should support ngIf', () => { var compFixture = createComponent(BasicComp); var debugElement = compFixture.debugElement; - expect(debugElement.children.length).toBe(2); + expect(debugElement.children.length).toBe(3); compFixture.componentInstance.ctxBool = true; compFixture.detectChanges(); - expect(debugElement.children.length).toBe(3); + expect(debugElement.children.length).toBe(4); expect(debugElement.children[2].injector.get(MultipleComponentsMyComp)).toBeTruthy(); }); it('should support ngFor', () => { var compFixture = createComponent(BasicComp); var debugElement = compFixture.debugElement; - expect(debugElement.children.length).toBe(2); + expect(debugElement.children.length).toBe(3); // test NgFor compFixture.componentInstance.ctxArr = [1, 2]; compFixture.detectChanges(); - expect(debugElement.children.length).toBe(4); + expect(debugElement.children.length).toBe(5); expect(debugElement.children[2].attributes['value']).toBe('1'); expect(debugElement.children[3].attributes['value']).toBe('2'); }); + + describe('i18n', () => { + it('should inject the locale into the component', () => { + const compFixture = createComponent(BasicComp); + expect(compFixture.componentInstance.localeId).toEqual('fi'); + }); + + it('should inject the translations format into the component', () => { + const compFixture = createComponent(BasicComp); + expect(compFixture.componentInstance.translationsFormat).toEqual('xtb'); + }); + + it('should support i18n for content tags', () => { + const compFixture = createComponent(BasicComp); + const debugElement = compFixture.debugElement; + const containerElement = debugElement.nativeElement; + const pElement = containerElement.children.find((c: any) => c.name == 'p'); + const pText = pElement.children.map((c: any) => c.data).join('').trim(); + expect(pText).toBe('tervetuloa'); + }); + }); }); diff --git a/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts b/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts index e065f3f742..55a95f11f2 100644 --- a/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts +++ b/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts @@ -39,6 +39,7 @@ describe('template i18n extraction output', () => { ]> translate me + Welcome `; const xmbOutput = path.join(outDir, 'messages.xmb'); diff --git a/modules/@angular/compiler-cli/src/codegen.ts b/modules/@angular/compiler-cli/src/codegen.ts index 377c325ac1..399d281b75 100644 --- a/modules/@angular/compiler-cli/src/codegen.ts +++ b/modules/@angular/compiler-cli/src/codegen.ts @@ -12,7 +12,7 @@ */ import * as compiler from '@angular/compiler'; import {ComponentMetadata, NgModuleMetadata, ViewEncapsulation} from '@angular/core'; -import {AngularCompilerOptions} from '@angular/tsc-wrapped'; +import {AngularCompilerOptions, NgcCliOptions} from '@angular/tsc-wrapped'; import * as path from 'path'; import * as ts from 'typescript'; @@ -22,6 +22,8 @@ import {GENERATED_FILES, ReflectorHost, ReflectorHostContext} from './reflector_ import {StaticAndDynamicReflectionCapabilities} from './static_reflection_capabilities'; import {StaticReflector, StaticSymbol} from './static_reflector'; +const nodeFs = require('fs'); + const PREAMBLE = `/** * This file is generated by the Angular 2 template compiler. * Do not edit. @@ -117,8 +119,9 @@ export class CodeGenerator { } static create( - options: AngularCompilerOptions, program: ts.Program, compilerHost: ts.CompilerHost, - reflectorHostContext?: ReflectorHostContext, xhr?: compiler.XHR): CodeGenerator { + options: AngularCompilerOptions, cliOptions: NgcCliOptions, program: ts.Program, + compilerHost: ts.CompilerHost, reflectorHostContext?: ReflectorHostContext, + xhr?: compiler.XHR): CodeGenerator { xhr = xhr || { get: (s: string) => { if (!compilerHost.fileExists(s)) { @@ -128,11 +131,18 @@ export class CodeGenerator { return Promise.resolve(compilerHost.readFile(s)); } }; + const transFile = cliOptions.i18nFile; + const locale = cliOptions.locale; + let transContent: string = ''; + if (transFile && locale) { + transContent = nodeFs.readFileSync(transFile, 'utf8'); + } + const urlResolver: compiler.UrlResolver = compiler.createOfflineCompileUrlResolver(); const reflectorHost = new ReflectorHost(program, compilerHost, options, reflectorHostContext); const staticReflector = new StaticReflector(reflectorHost); StaticAndDynamicReflectionCapabilities.install(staticReflector); - const htmlParser = new compiler.i18n.HtmlParser(new HtmlParser()); + const htmlParser = new compiler.i18n.HtmlParser(new HtmlParser(), transContent); const config = new compiler.CompilerConfig({ genDebugInfo: options.debug === true, defaultEncapsulation: ViewEncapsulation.Emulated, @@ -151,7 +161,8 @@ export class CodeGenerator { config, console, elementSchemaRegistry, staticReflector); const offlineCompiler = new compiler.OfflineCompiler( resolver, normalizer, tmplParser, new StyleCompiler(urlResolver), new ViewCompiler(config), - new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost)); + new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost), cliOptions.locale, + cliOptions.i18nFormat); return new CodeGenerator( options, program, compilerHost, staticReflector, offlineCompiler, reflectorHost); diff --git a/modules/@angular/compiler-cli/src/extract_i18n.ts b/modules/@angular/compiler-cli/src/extract_i18n.ts index 1372dd9730..75676aef2f 100644 --- a/modules/@angular/compiler-cli/src/extract_i18n.ts +++ b/modules/@angular/compiler-cli/src/extract_i18n.ts @@ -28,8 +28,9 @@ import {StaticAndDynamicReflectionCapabilities} from './static_reflection_capabi import {StaticReflector, StaticSymbol} from './static_reflector'; function extract( - ngOptions: tsc.AngularCompilerOptions, program: ts.Program, host: ts.CompilerHost) { - const extractor = Extractor.create(ngOptions, program, host); + ngOptions: tsc.AngularCompilerOptions, cliOptions: tsc.I18nExtractionCliOptions, + program: ts.Program, host: ts.CompilerHost) { + const extractor = Extractor.create(ngOptions, cliOptions.i18nFormat, program, host); const bundlePromise: Promise = extractor.extract(); return (bundlePromise).then(messageBundle => { @@ -126,8 +127,8 @@ export class Extractor { } static create( - options: tsc.AngularCompilerOptions, program: ts.Program, compilerHost: ts.CompilerHost, - reflectorHostContext?: ReflectorHostContext): Extractor { + options: tsc.AngularCompilerOptions, translationsFormat: string, program: ts.Program, + compilerHost: ts.CompilerHost, reflectorHostContext?: ReflectorHostContext): Extractor { const xhr: compiler.XHR = { get: (s: string) => { if (!compilerHost.fileExists(s)) { @@ -163,7 +164,7 @@ export class Extractor { config, console, elementSchemaRegistry, staticReflector); const offlineCompiler = new compiler.OfflineCompiler( resolver, normalizer, tmplParser, new StyleCompiler(urlResolver), new ViewCompiler(config), - new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost)); + new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost), null, null); // TODO(vicb): implicit tags & attributes let messageBundle = new compiler.i18n.MessageBundle(htmlParser, [], {}); @@ -183,11 +184,13 @@ interface FileMetadata { // Entry point if (require.main === module) { const args = require('minimist')(process.argv.slice(2)); - tsc.main(args.p || args.project || '.', args.basePath, extract) - .then(exitCode => process.exit(exitCode)) - .catch(e => { + const project = args.p || args.project || '.'; + const cliOptions = new tsc.I18nExtractionCliOptions(args); + tsc.main(project, cliOptions, extract) + .then((exitCode: any) => process.exit(exitCode)) + .catch((e: any) => { console.error(e.stack); console.error('Extraction failed'); process.exit(1); }); -} \ No newline at end of file +} diff --git a/modules/@angular/compiler-cli/src/main.ts b/modules/@angular/compiler-cli/src/main.ts index 79d69b74eb..265687c6e0 100644 --- a/modules/@angular/compiler-cli/src/main.ts +++ b/modules/@angular/compiler-cli/src/main.ts @@ -17,18 +17,19 @@ import * as tsc from '@angular/tsc-wrapped'; import {CodeGenerator} from './codegen'; function codegen( - ngOptions: tsc.AngularCompilerOptions, program: ts.Program, host: ts.CompilerHost) { - return CodeGenerator.create(ngOptions, program, host).codegen(); + ngOptions: tsc.AngularCompilerOptions, cliOptions: tsc.NgcCliOptions, program: ts.Program, + host: ts.CompilerHost) { + return CodeGenerator.create(ngOptions, cliOptions, program, host).codegen(); } // CLI entry point if (require.main === module) { const args = require('minimist')(process.argv.slice(2)); - tsc.main(args.p || args.project || '.', args.basePath, codegen) - .then(exitCode => process.exit(exitCode)) - .catch(e => { - console.error(e.stack); - console.error('Compilation failed'); - process.exit(1); - }); + const project = args.p || args.project || '.'; + const cliOptions = new tsc.NgcCliOptions(args); + tsc.main(project, cliOptions, codegen).then(exitCode => process.exit(exitCode)).catch(e => { + console.error(e.stack); + console.error('Compilation failed'); + process.exit(1); + }); } diff --git a/modules/@angular/compiler/src/compiler.ts b/modules/@angular/compiler/src/compiler.ts index 5d9803dbcf..93a2172700 100644 --- a/modules/@angular/compiler/src/compiler.ts +++ b/modules/@angular/compiler/src/compiler.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Component, Inject, Injectable, OptionalMetadata, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, PlatformRef, Provider, ReflectiveInjector, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; +import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Component, Inject, Injectable, OptionalMetadata, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, PlatformRef, Provider, ReflectiveInjector, TRANSLATIONS, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore} from '@angular/core'; export * from './template_parser/template_ast'; export {TEMPLATE_TRANSFORMS} from './template_parser/template_parser'; @@ -65,7 +65,7 @@ export const COMPILER_PROVIDERS: Array|{[k: string]: any}|any[]> = provide: i18n.HtmlParser, useFactory: (parser: HtmlParser, translations: string) => new i18n.HtmlParser(parser, translations), - deps: [HtmlParser, [new OptionalMetadata(), new Inject(i18n.TRANSLATIONS)]] + deps: [HtmlParser, [new OptionalMetadata(), new Inject(TRANSLATIONS)]] }, TemplateParser, DirectiveNormalizer, diff --git a/modules/@angular/compiler/src/i18n/index.ts b/modules/@angular/compiler/src/i18n/index.ts index b1f41f0edb..6c43336835 100644 --- a/modules/@angular/compiler/src/i18n/index.ts +++ b/modules/@angular/compiler/src/i18n/index.ts @@ -6,12 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {OpaqueToken} from '@angular/core'; - export {HtmlParser} from './html_parser'; export {MessageBundle} from './message_bundle'; export {Serializer} from './serializers/serializer'; export {Xmb} from './serializers/xmb'; export {Xtb} from './serializers/xtb'; - -export const TRANSLATIONS = new OpaqueToken('Translations'); diff --git a/modules/@angular/compiler/src/identifiers.ts b/modules/@angular/compiler/src/identifiers.ts index 19bf2c41b6..df77099d85 100644 --- a/modules/@angular/compiler/src/identifiers.ts +++ b/modules/@angular/compiler/src/identifiers.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core'; - +import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, LOCALE_ID as LOCALE_ID_, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT as TRANSLATIONS_FORMAT_, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core'; import {AnimationGroupPlayer as AnimationGroupPlayer_, AnimationKeyframe as AnimationKeyframe_, AnimationSequencePlayer as AnimationSequencePlayer_, AnimationStyles as AnimationStyles_, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer as NoOpAnimationPlayer_, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes as impBalanceAnimationKeyframes, castByValue, checkBinding, clearStyles as impClearStyles, collectAndResolveStyles as impCollectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles as impBalanceAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, renderStyles as impRenderStyles} from '../core_private'; import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata'; @@ -252,6 +251,13 @@ export class Identifiers { moduleUrl: ANIMATION_STYLE_UTIL_ASSET_URL, runtime: impCollectAndResolveStyles }); + static LOCALE_ID = new CompileIdentifierMetadata( + {name: 'LOCALE_ID', moduleUrl: assetUrl('core', 'i18n/tokens'), runtime: LOCALE_ID_}); + static TRANSLATIONS_FORMAT = new CompileIdentifierMetadata({ + name: 'TRANSLATIONS_FORMAT', + moduleUrl: assetUrl('core', 'i18n/tokens'), + runtime: TRANSLATIONS_FORMAT_ + }); } export function identifierToken(identifier: CompileIdentifierMetadata): CompileTokenMetadata { diff --git a/modules/@angular/compiler/src/offline_compiler.ts b/modules/@angular/compiler/src/offline_compiler.ts index 29dc11e3cb..ae94fcb67c 100644 --- a/modules/@angular/compiler/src/offline_compiler.ts +++ b/modules/@angular/compiler/src/offline_compiler.ts @@ -8,7 +8,7 @@ import {BaseException, SchemaMetadata} from '@angular/core'; -import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata'; +import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, CompileProviderMetadata, CompileTokenMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata'; import {DirectiveNormalizer} from './directive_normalizer'; import {ListWrapper} from './facade/collection'; import {Identifiers} from './identifiers'; @@ -33,7 +33,8 @@ export class OfflineCompiler { private _metadataResolver: CompileMetadataResolver, private _directiveNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler, - private _ngModuleCompiler: NgModuleCompiler, private _outputEmitter: OutputEmitter) {} + private _ngModuleCompiler: NgModuleCompiler, private _outputEmitter: OutputEmitter, + private _localeId: string, private _translationFormat: string) {} analyzeModules(ngModules: StaticSymbol[]): NgModulesSummary { const ngModuleByComponent = new Map(); @@ -107,7 +108,16 @@ export class OfflineCompiler { private _compileModule(ngModuleType: StaticSymbol, targetStatements: o.Statement[]): string { const ngModule = this._metadataResolver.getNgModuleMetadata(ngModuleType); - let appCompileResult = this._ngModuleCompiler.compile(ngModule, []); + let appCompileResult = this._ngModuleCompiler.compile(ngModule, [ + new CompileProviderMetadata({ + token: new CompileTokenMetadata({identifier: Identifiers.LOCALE_ID}), + useValue: this._localeId + }), + new CompileProviderMetadata({ + token: new CompileTokenMetadata({identifier: Identifiers.TRANSLATIONS_FORMAT}), + useValue: this._translationFormat + }) + ]); appCompileResult.dependencies.forEach((dep) => { dep.placeholder.name = _componentFactoryName(dep.comp); dep.placeholder.moduleUrl = _ngfactoryModuleUrl(dep.comp.moduleUrl); diff --git a/modules/@angular/compiler/test/i18n/integration_spec.ts b/modules/@angular/compiler/test/i18n/integration_spec.ts index a7a60bf40f..24b3179b36 100644 --- a/modules/@angular/compiler/test/i18n/integration_spec.ts +++ b/modules/@angular/compiler/test/i18n/integration_spec.ts @@ -8,8 +8,9 @@ import {DirectiveResolver, XHR, i18n} from '@angular/compiler'; import {MockDirectiveResolver} from '@angular/compiler/testing'; -import {Compiler, Component, DebugElement, Injector} from '@angular/core'; +import {Compiler, Component, DebugElement, Injector, TRANSLATIONS} from '@angular/core'; import {TestBed, TestComponentBuilder, fakeAsync} from '@angular/core/testing'; + import {beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit,} from '@angular/core/testing/testing_internal'; import {expect} from '@angular/platform-browser/testing/matchers'; import {By} from '@angular/platform-browser/src/dom/debug/by'; @@ -30,7 +31,7 @@ export function main() { providers: [ {provide: XHR, useClass: SpyXHR}, {provide: NgLocalization, useClass: FrLocalization}, - {provide: i18n.TRANSLATIONS, useValue: XTB}, + {provide: TRANSLATIONS, useValue: XTB}, ] }); }); @@ -213,4 +214,4 @@ const XMB = ` <div></div> it <b>should</b> work -`; \ No newline at end of file +`; diff --git a/modules/@angular/core/index.ts b/modules/@angular/core/index.ts index 923dbd5b2d..6704835aa9 100644 --- a/modules/@angular/core/index.ts +++ b/modules/@angular/core/index.ts @@ -25,6 +25,7 @@ export * from './src/testability/testability'; export * from './src/change_detection'; export * from './src/platform_directives_and_pipes'; export * from './src/platform_core_providers'; +export {TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID} from './src/i18n/tokens'; export {APPLICATION_COMMON_PROVIDERS, ApplicationModule} from './src/application_module'; export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/profile/profile'; diff --git a/modules/@angular/core/src/i18n/tokens.ts b/modules/@angular/core/src/i18n/tokens.ts new file mode 100644 index 0000000000..0eba286a09 --- /dev/null +++ b/modules/@angular/core/src/i18n/tokens.ts @@ -0,0 +1,24 @@ +/** + * @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 + */ + +import {OpaqueToken} from '../di/opaque_token'; + +/** + * @experimental i18n support is experimental. + */ +export const LOCALE_ID = new OpaqueToken('LocaleId'); + +/** + * @experimental i18n support is experimental. + */ +export const TRANSLATIONS = new OpaqueToken('Translations'); + +/** + * @experimental i18n support is experimental. + */ +export const TRANSLATIONS_FORMAT = new OpaqueToken('TranslationsFormat'); diff --git a/scripts/ci-lite/offline_compiler_test.sh b/scripts/ci-lite/offline_compiler_test.sh index 421a5a4ca1..0bfc6ac4ae 100755 --- a/scripts/ci-lite/offline_compiler_test.sh +++ b/scripts/ci-lite/offline_compiler_test.sh @@ -33,7 +33,7 @@ cp -v package.json $TMP ./node_modules/.bin/tsc --version # Compile the compiler-cli integration tests - ./node_modules/.bin/ngc + ./node_modules/.bin/ngc --i18nFile=src/messages.fi.xtb --locale=fi --i18nFormat=xtb ./node_modules/.bin/ng-xi18n ./node_modules/.bin/jasmine init diff --git a/tools/@angular/tsc-wrapped/index.ts b/tools/@angular/tsc-wrapped/index.ts index 20a85116e6..42b3685ca4 100644 --- a/tools/@angular/tsc-wrapped/index.ts +++ b/tools/@angular/tsc-wrapped/index.ts @@ -2,5 +2,6 @@ export {MetadataWriterHost, TsickleHost} from './src/compiler_host'; export {CodegenExtension, main} from './src/main'; export {default as AngularCompilerOptions} from './src/options'; +export * from './src/cli_options'; export * from './src/collector'; export * from './src/schema'; diff --git a/tools/@angular/tsc-wrapped/src/cli_options.ts b/tools/@angular/tsc-wrapped/src/cli_options.ts new file mode 100644 index 0000000000..60d26fe45f --- /dev/null +++ b/tools/@angular/tsc-wrapped/src/cli_options.ts @@ -0,0 +1,34 @@ +/** + * @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 + */ +export class CliOptions { + public basePath: string; + constructor({basePath = null}: {basePath?: string}) { this.basePath = basePath; } +} + +export class I18nExtractionCliOptions extends CliOptions { + public i18nFormat: string; + + constructor({i18nFormat = null}: {i18nFormat?: string}) { + super({}); + this.i18nFormat = i18nFormat; + } +} + +export class NgcCliOptions extends CliOptions { + public i18nFormat: string; + public i18nFile: string; + public locale: string; + + constructor({i18nFormat = null, i18nFile = null, locale = null, basePath = null}: + {i18nFormat?: string, i18nFile?: string, locale?: string, basePath?: string}) { + super({basePath: basePath}); + this.i18nFormat = i18nFormat; + this.i18nFile = i18nFile; + this.locale = locale; + } +} diff --git a/tools/@angular/tsc-wrapped/src/main.ts b/tools/@angular/tsc-wrapped/src/main.ts index 73104d8ff3..4fcf328554 100644 --- a/tools/@angular/tsc-wrapped/src/main.ts +++ b/tools/@angular/tsc-wrapped/src/main.ts @@ -6,11 +6,14 @@ import {check, tsc} from './tsc'; import NgOptions from './options'; import {MetadataWriterHost, TsickleHost} from './compiler_host'; +import {CliOptions} from './cli_options'; -export type CodegenExtension = (ngOptions: NgOptions, program: ts.Program, host: ts.CompilerHost) => - Promise; +export type CodegenExtension = + (ngOptions: NgOptions, cliOptions: CliOptions, program: ts.Program, host: ts.CompilerHost) => + Promise; -export function main(project: string, basePath?: string, codegen?: CodegenExtension): Promise { +export function main( + project: string, cliOptions: CliOptions, codegen?: CodegenExtension): Promise { try { let projectDir = project; if (fs.lstatSync(project).isFile()) { @@ -18,7 +21,7 @@ export function main(project: string, basePath?: string, codegen?: CodegenExtens } // file names in tsconfig are resolved relative to this absolute path - basePath = path.resolve(process.cwd(), basePath || projectDir); + const basePath = path.resolve(process.cwd(), cliOptions.basePath || projectDir); // read the configuration options from wherever you store them const {parsed, ngOptions} = tsc.readConfiguration(project, basePath); @@ -32,7 +35,7 @@ export function main(project: string, basePath?: string, codegen?: CodegenExtens if (ngOptions.skipTemplateCodegen || !codegen) { codegen = () => Promise.resolve(null); } - return codegen(ngOptions, program, host).then(() => { + return codegen(ngOptions, cliOptions, program, host).then(() => { // Create a new program since codegen files were created after making the old program const newProgram = ts.createProgram(parsed.fileNames, parsed.options, host, program); tsc.typeCheck(host, newProgram); @@ -59,11 +62,11 @@ export function main(project: string, basePath?: string, codegen?: CodegenExtens // CLI entry point if (require.main === module) { const args = require('minimist')(process.argv.slice(2)); - main(args.p || args.project || '.', args.basePath) - .then(exitCode => process.exit(exitCode)) - .catch(e => { - console.error(e.stack); - console.error('Compilation failed'); - process.exit(1); - }); + const project = args.p || args.project || '.'; + const cliOptions = new CliOptions(args); + main(project, cliOptions).then((exitCode: any) => process.exit(exitCode)).catch((e: any) => { + console.error(e.stack); + console.error('Compilation failed'); + process.exit(1); + }); } diff --git a/tools/public_api_guard/core/index.d.ts b/tools/public_api_guard/core/index.d.ts index dfcc8948a2..8327d118a2 100644 --- a/tools/public_api_guard/core/index.d.ts +++ b/tools/public_api_guard/core/index.d.ts @@ -780,6 +780,9 @@ export declare class KeyValueDiffers { static extend(factories: KeyValueDifferFactory[]): Provider; } +/** @experimental */ +export declare const LOCALE_ID: OpaqueToken; + /** @deprecated */ export declare function lockRunMode(): void; @@ -1330,6 +1333,12 @@ export interface TrackByFn { /** @experimental */ export declare function transition(stateChangeExpr: string, steps: AnimationMetadata | AnimationMetadata[]): AnimationStateTransitionMetadata; +/** @experimental */ +export declare const TRANSLATIONS: OpaqueToken; + +/** @experimental */ +export declare const TRANSLATIONS_FORMAT: OpaqueToken; + /** @experimental */ export declare function trigger(name: string, animation: AnimationMetadata[]): AnimationEntryMetadata;