style(compiler): reformat of codebase with new clang-format version (#36520)
This commit reformats the packages/compiler tree using the new version of clang-format. PR Close #36520
This commit is contained in:
		
							parent
							
								
									0a69a2832b
								
							
						
					
					
						commit
						83a9159063
					
				| @ -11,7 +11,7 @@ import {CompilerConfig} from '../config'; | ||||
| import {ConstantPool} from '../constant_pool'; | ||||
| import {ViewEncapsulation} from '../core'; | ||||
| import {MessageBundle} from '../i18n/message_bundle'; | ||||
| import {Identifiers, createTokenForExternalReference} from '../identifiers'; | ||||
| import {createTokenForExternalReference, Identifiers} from '../identifiers'; | ||||
| import {InjectableCompiler} from '../injectable_compiler'; | ||||
| import {CompileMetadataResolver} from '../metadata_resolver'; | ||||
| import {HtmlParser} from '../ml_parser/html_parser'; | ||||
| @ -31,9 +31,9 @@ import {SummaryResolver} from '../summary_resolver'; | ||||
| import {BindingParser} from '../template_parser/binding_parser'; | ||||
| import {TemplateAst} from '../template_parser/template_ast'; | ||||
| import {TemplateParser} from '../template_parser/template_parser'; | ||||
| import {OutputContext, ValueVisitor, error, newArray, syntaxError, visitValue} from '../util'; | ||||
| import {error, newArray, OutputContext, syntaxError, ValueVisitor, visitValue} from '../util'; | ||||
| import {TypeCheckCompiler} from '../view_compiler/type_check_compiler'; | ||||
| import {ViewCompileResult, ViewCompiler} from '../view_compiler/view_compiler'; | ||||
| import {ViewCompiler, ViewCompileResult} from '../view_compiler/view_compiler'; | ||||
| 
 | ||||
| import {AotCompilerHost} from './compiler_host'; | ||||
| import {AotCompilerOptions} from './compiler_options'; | ||||
| @ -46,7 +46,11 @@ import {StaticSymbolResolver} from './static_symbol_resolver'; | ||||
| import {createForJitStub, serializeSummaries} from './summary_serializer'; | ||||
| import {ngfactoryFilePath, normalizeGenFileSuffix, splitTypescriptSuffix, summaryFileName, summaryForJitFileName} from './util'; | ||||
| 
 | ||||
| const enum StubEmitFlags { Basic = 1 << 0, TypeCheck = 1 << 1, All = TypeCheck | Basic } | ||||
| const enum StubEmitFlags { | ||||
|   Basic = 1 << 0, | ||||
|   TypeCheck = 1 << 1, | ||||
|   All = TypeCheck | Basic | ||||
| } | ||||
| 
 | ||||
| export class AotCompiler { | ||||
|   private _templateAstCache = | ||||
| @ -64,7 +68,9 @@ export class AotCompiler { | ||||
|       private _summaryResolver: SummaryResolver<StaticSymbol>, | ||||
|       private _symbolResolver: StaticSymbolResolver) {} | ||||
| 
 | ||||
|   clearCache() { this._metadataResolver.clearCache(); } | ||||
|   clearCache() { | ||||
|     this._metadataResolver.clearCache(); | ||||
|   } | ||||
| 
 | ||||
|   analyzeModulesSync(rootFiles: string[]): NgAnalyzedModules { | ||||
|     const analyzeResult = analyzeAndValidateNgModules( | ||||
| @ -123,7 +129,7 @@ export class AotCompiler { | ||||
|     const fileSuffix = normalizeGenFileSuffix(splitTypescriptSuffix(file.fileName, true)[1]); | ||||
|     file.directives.forEach((dirSymbol) => { | ||||
|       const compMeta = | ||||
|           this._metadataResolver.getNonNormalizedDirectiveMetadata(dirSymbol) !.metadata; | ||||
|           this._metadataResolver.getNonNormalizedDirectiveMetadata(dirSymbol)!.metadata; | ||||
|       if (!compMeta.isComponent) { | ||||
|         return; | ||||
|       } | ||||
| @ -149,7 +155,8 @@ export class AotCompiler { | ||||
|     if (genFileName.endsWith('.ngfactory.ts')) { | ||||
|       if (!originalFileName) { | ||||
|         throw new Error( | ||||
|             `Assertion error: require the original file for .ngfactory.ts stubs. File: ${genFileName}`); | ||||
|             `Assertion error: require the original file for .ngfactory.ts stubs. File: ${ | ||||
|                 genFileName}`);
 | ||||
|       } | ||||
|       const originalFile = this._analyzeFile(originalFileName); | ||||
|       this._createNgFactoryStub(outputCtx, originalFile, StubEmitFlags.Basic); | ||||
| @ -157,7 +164,8 @@ export class AotCompiler { | ||||
|       if (this._options.enableSummariesForJit) { | ||||
|         if (!originalFileName) { | ||||
|           throw new Error( | ||||
|               `Assertion error: require the original file for .ngsummary.ts stubs. File: ${genFileName}`); | ||||
|               `Assertion error: require the original file for .ngsummary.ts stubs. File: ${ | ||||
|                   genFileName}`);
 | ||||
|         } | ||||
|         const originalFile = this._analyzeFile(originalFileName); | ||||
|         _createEmptyStub(outputCtx); | ||||
| @ -319,10 +327,10 @@ export class AotCompiler { | ||||
|         const html = compMeta.template !.template !; | ||||
|         // Template URL points to either an HTML or TS file depending on whether
 | ||||
|         // the file is used with `templateUrl:` or `template:`, respectively.
 | ||||
|         const templateUrl = compMeta.template !.templateUrl !; | ||||
|         const templateUrl = compMeta.template !.templateUrl!; | ||||
|         const interpolationConfig = | ||||
|             InterpolationConfig.fromArray(compMeta.template !.interpolation); | ||||
|         errors.push(...messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig) !); | ||||
|         errors.push(...messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig)!); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
| @ -342,7 +350,7 @@ export class AotCompiler { | ||||
|       if (!contextMap.has(fileName)) { | ||||
|         contextMap.set(fileName, this._createOutputContext(fileName)); | ||||
|       } | ||||
|       return contextMap.get(fileName) !; | ||||
|       return contextMap.get(fileName)!; | ||||
|     }; | ||||
| 
 | ||||
|     files.forEach( | ||||
| @ -381,13 +389,13 @@ export class AotCompiler { | ||||
|     directives.forEach(directiveType => { | ||||
|       const directiveMetadata = this._metadataResolver.getDirectiveMetadata(directiveType); | ||||
|       if (directiveMetadata.isComponent) { | ||||
|         const module = ngModuleByPipeOrDirective.get(directiveType) !; | ||||
|         const module = ngModuleByPipeOrDirective.get(directiveType)!; | ||||
|         module || | ||||
|             error( | ||||
|                 `Cannot determine the module for component '${identifierName(directiveMetadata.type)}'`); | ||||
|             error(`Cannot determine the module for component '${ | ||||
|                 identifierName(directiveMetadata.type)}'`);
 | ||||
| 
 | ||||
|         let htmlAst = directiveMetadata.template !.htmlAst !; | ||||
|         const preserveWhitespaces = directiveMetadata !.template !.preserveWhitespaces; | ||||
|         let htmlAst = directiveMetadata.template !.htmlAst!; | ||||
|         const preserveWhitespaces = directiveMetadata!.template !.preserveWhitespaces; | ||||
| 
 | ||||
|         if (!preserveWhitespaces) { | ||||
|           htmlAst = removeWhitespaces(htmlAst); | ||||
| @ -412,7 +420,9 @@ export class AotCompiler { | ||||
|         const pipes = module.transitiveModule.pipes.map( | ||||
|             pipe => this._metadataResolver.getPipeSummary(pipe.reference)); | ||||
| 
 | ||||
|         pipes.forEach(pipe => { pipeTypeByName.set(pipe.name, pipe.type.reference); }); | ||||
|         pipes.forEach(pipe => { | ||||
|           pipeTypeByName.set(pipe.name, pipe.type.reference); | ||||
|         }); | ||||
| 
 | ||||
|         compileR3Component( | ||||
|             context, directiveMetadata, render3Ast, this.reflector, hostBindingParser, | ||||
| @ -484,8 +494,8 @@ export class AotCompiler { | ||||
|       } | ||||
|       const ngModule = ngModuleByPipeOrDirective.get(dirType); | ||||
|       if (!ngModule) { | ||||
|         throw new Error( | ||||
|             `Internal Error: cannot determine the module for component ${identifierName(compMeta.type)}!`); | ||||
|         throw new Error(`Internal Error: cannot determine the module for component ${ | ||||
|             identifierName(compMeta.type)}!`);
 | ||||
|       } | ||||
| 
 | ||||
|       // compile styles
 | ||||
| @ -524,27 +534,27 @@ export class AotCompiler { | ||||
|                                 .map(symbol => this._symbolResolver.resolveSymbol(symbol)); | ||||
|     const typeData: { | ||||
|       summary: CompileTypeSummary, | ||||
|       metadata: CompileNgModuleMetadata | CompileDirectiveMetadata | CompilePipeMetadata | | ||||
|       metadata: CompileNgModuleMetadata|CompileDirectiveMetadata|CompilePipeMetadata| | ||||
|       CompileTypeMetadata | ||||
|     }[] = | ||||
|         [ | ||||
|           ...ngModules.map( | ||||
|               meta => ({ | ||||
|                 summary: this._metadataResolver.getNgModuleSummary(meta.type.reference) !, | ||||
|                 metadata: this._metadataResolver.getNgModuleMetadata(meta.type.reference) ! | ||||
|                 summary: this._metadataResolver.getNgModuleSummary(meta.type.reference)!, | ||||
|                 metadata: this._metadataResolver.getNgModuleMetadata(meta.type.reference)! | ||||
|               })), | ||||
|           ...directives.map(ref => ({ | ||||
|                               summary: this._metadataResolver.getDirectiveSummary(ref) !, | ||||
|                               metadata: this._metadataResolver.getDirectiveMetadata(ref) ! | ||||
|                               summary: this._metadataResolver.getDirectiveSummary(ref)!, | ||||
|                               metadata: this._metadataResolver.getDirectiveMetadata(ref)! | ||||
|                             })), | ||||
|           ...pipes.map(ref => ({ | ||||
|                          summary: this._metadataResolver.getPipeSummary(ref) !, | ||||
|                          metadata: this._metadataResolver.getPipeMetadata(ref) ! | ||||
|                          summary: this._metadataResolver.getPipeSummary(ref)!, | ||||
|                          metadata: this._metadataResolver.getPipeMetadata(ref)! | ||||
|                        })), | ||||
|           ...injectables.map( | ||||
|               ref => ({ | ||||
|                 summary: this._metadataResolver.getInjectableSummary(ref.symbol) !, | ||||
|                 metadata: this._metadataResolver.getInjectableSummary(ref.symbol) !.type | ||||
|                 summary: this._metadataResolver.getInjectableSummary(ref.symbol)!, | ||||
|                 metadata: this._metadataResolver.getInjectableSummary(ref.symbol)!.type | ||||
|               })) | ||||
|         ]; | ||||
|     const forJitOutputCtx = this._options.enableSummariesForJit ? | ||||
| @ -621,7 +631,7 @@ export class AotCompiler { | ||||
|             .toDeclStmt( | ||||
|                 o.importType( | ||||
|                     Identifiers.ComponentFactory, | ||||
|                     [o.expressionType(outputCtx.importExpr(compMeta.type.reference)) !], | ||||
|                     [o.expressionType(outputCtx.importExpr(compMeta.type.reference))!], | ||||
|                     [o.TypeModifier.Const]), | ||||
|                 [o.StmtModifier.Final, o.StmtModifier.Exported])); | ||||
|   } | ||||
| @ -648,15 +658,15 @@ export class AotCompiler { | ||||
|       directiveIdentifiers: CompileIdentifierMetadata[]): | ||||
|       {template: TemplateAst[], pipes: CompilePipeSummary[]} { | ||||
|     if (this._templateAstCache.has(compMeta.type.reference)) { | ||||
|       return this._templateAstCache.get(compMeta.type.reference) !; | ||||
|       return this._templateAstCache.get(compMeta.type.reference)!; | ||||
|     } | ||||
|     const preserveWhitespaces = compMeta !.template !.preserveWhitespaces; | ||||
|     const preserveWhitespaces = compMeta!.template !.preserveWhitespaces; | ||||
|     const directives = | ||||
|         directiveIdentifiers.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference)); | ||||
|     const pipes = ngModule.transitiveModule.pipes.map( | ||||
|         pipe => this._metadataResolver.getPipeSummary(pipe.reference)); | ||||
|     const result = this._templateParser.parse( | ||||
|         compMeta, compMeta.template !.htmlAst !, directives, pipes, ngModule.schemas, | ||||
|         compMeta, compMeta.template !.htmlAst!, directives, pipes, ngModule.schemas, | ||||
|         templateSourceUrl(ngModule.type, compMeta, compMeta.template !), preserveWhitespaces); | ||||
|     this._templateAstCache.set(compMeta.type.reference, result); | ||||
|     return result; | ||||
| @ -664,8 +674,7 @@ export class AotCompiler { | ||||
| 
 | ||||
|   private _createOutputContext(genFilePath: string): OutputContext { | ||||
|     const importExpr = | ||||
|         (symbol: StaticSymbol, typeParams: o.Type[] | null = null, | ||||
|          useSummaries: boolean = true) => { | ||||
|         (symbol: StaticSymbol, typeParams: o.Type[]|null = null, useSummaries: boolean = true) => { | ||||
|           if (!(symbol instanceof StaticSymbol)) { | ||||
|             throw new Error(`Internal error: unknown identifier ${JSON.stringify(symbol)}`); | ||||
|           } | ||||
| @ -710,7 +719,7 @@ export class AotCompiler { | ||||
|       stylesheetMetadata: CompileStylesheetMetadata, isShimmed: boolean, | ||||
|       fileSuffix: string): GeneratedFile { | ||||
|     const outputCtx = this._createOutputContext( | ||||
|         _stylesModuleUrl(stylesheetMetadata.moduleUrl !, isShimmed, fileSuffix)); | ||||
|         _stylesModuleUrl(stylesheetMetadata.moduleUrl!, isShimmed, fileSuffix)); | ||||
|     const compiledStylesheet = | ||||
|         this._styleCompiler.compileStyles(outputCtx, compMeta, stylesheetMetadata, isShimmed); | ||||
|     _resolveStyleStatements(this._symbolResolver, compiledStylesheet, isShimmed, fileSuffix); | ||||
| @ -748,8 +757,8 @@ export class AotCompiler { | ||||
|         return allLazyRoutes; | ||||
|       } | ||||
|       seenRoutes.add(symbol); | ||||
|       const lazyRoutes = listLazyRoutes( | ||||
|           self._metadataResolver.getNgModuleMetadata(symbol, true) !, self.reflector); | ||||
|       const lazyRoutes = | ||||
|           listLazyRoutes(self._metadataResolver.getNgModuleMetadata(symbol, true)!, self.reflector); | ||||
|       for (const lazyRoute of lazyRoutes) { | ||||
|         allLazyRoutes.push(lazyRoute); | ||||
|         visitLazyRoute(lazyRoute.referencedModule, seenRoutes, allLazyRoutes); | ||||
| @ -803,7 +812,9 @@ export interface NgAnalyzedFile { | ||||
|   exportsNonSourceFiles: boolean; | ||||
| } | ||||
| 
 | ||||
| export interface NgAnalyzeModulesHost { isSourceFile(filePath: string): boolean; } | ||||
| export interface NgAnalyzeModulesHost { | ||||
|   isSourceFile(filePath: string): boolean; | ||||
| } | ||||
| 
 | ||||
| export function analyzeNgModules( | ||||
|     fileNames: string[], host: NgAnalyzeModulesHost, staticSymbolResolver: StaticSymbolResolver, | ||||
| @ -823,8 +834,8 @@ export function analyzeAndValidateNgModules( | ||||
| function validateAnalyzedModules(analyzedModules: NgAnalyzedModules): NgAnalyzedModules { | ||||
|   if (analyzedModules.symbolsMissingModule && analyzedModules.symbolsMissingModule.length) { | ||||
|     const messages = analyzedModules.symbolsMissingModule.map( | ||||
|         s => | ||||
|             `Cannot determine the module for class ${s.name} in ${s.filePath}! Add ${s.name} to the NgModule to fix it.`); | ||||
|         s => `Cannot determine the module for class ${s.name} in ${s.filePath}! Add ${ | ||||
|             s.name} to the NgModule to fix it.`);
 | ||||
|     throw syntaxError(messages.join('\n')); | ||||
|   } | ||||
|   return analyzedModules; | ||||
| @ -918,8 +929,13 @@ export function analyzeFile( | ||||
|     }); | ||||
|   } | ||||
|   return { | ||||
|       fileName,  directives,  abstractDirectives,    pipes, | ||||
|       ngModules, injectables, exportsNonSourceFiles, | ||||
|     fileName, | ||||
|     directives, | ||||
|     abstractDirectives, | ||||
|     pipes, | ||||
|     ngModules, | ||||
|     injectables, | ||||
|     exportsNonSourceFiles, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| @ -957,7 +973,9 @@ function isValueExportingNonSourceFile(host: NgAnalyzeModulesHost, metadata: any | ||||
|   let exportsNonSourceFiles = false; | ||||
| 
 | ||||
|   class Visitor implements ValueVisitor { | ||||
|     visitArray(arr: any[], context: any): any { arr.forEach(v => visitValue(v, this, context)); } | ||||
|     visitArray(arr: any[], context: any): any { | ||||
|       arr.forEach(v => visitValue(v, this, context)); | ||||
|     } | ||||
|     visitStringMap(map: {[key: string]: any}, context: any): any { | ||||
|       Object.keys(map).forEach((key) => visitValue(map[key], this, context)); | ||||
|     } | ||||
|  | ||||
| @ -36,9 +36,9 @@ import {StaticSymbol, StaticSymbolCache} from './static_symbol'; | ||||
| import {StaticSymbolResolver} from './static_symbol_resolver'; | ||||
| import {AotSummaryResolver} from './summary_resolver'; | ||||
| 
 | ||||
| export function createAotUrlResolver(host: { | ||||
|   resourceNameToFileName(resourceName: string, containingFileName: string): string | null; | ||||
| }): UrlResolver { | ||||
| export function createAotUrlResolver( | ||||
|     host: {resourceNameToFileName(resourceName: string, containingFileName: string): string|null;}): | ||||
|     UrlResolver { | ||||
|   return { | ||||
|     resolve: (basePath: string, url: string) => { | ||||
|       const filePath = host.resourceNameToFileName(url, basePath); | ||||
|  | ||||
| @ -20,7 +20,7 @@ export interface FormattedMessageChain { | ||||
|   next?: FormattedMessageChain[]; | ||||
| } | ||||
| 
 | ||||
| export type FormattedError = Error & { | ||||
| export type FormattedError = Error&{ | ||||
|   chain: FormattedMessageChain; | ||||
|   position?: Position; | ||||
| }; | ||||
| @ -34,10 +34,10 @@ function indentStr(level: number): string { | ||||
|   return half + half + (level % 2 === 1 ? ' ' : ''); | ||||
| } | ||||
| 
 | ||||
| function formatChain(chain: FormattedMessageChain | undefined, indent: number = 0): string { | ||||
| function formatChain(chain: FormattedMessageChain|undefined, indent: number = 0): string { | ||||
|   if (!chain) return ''; | ||||
|   const position = chain.position ? | ||||
|       `${chain.position.fileName}(${chain.position.line+1},${chain.position.column+1})` : | ||||
|       `${chain.position.fileName}(${chain.position.line + 1},${chain.position.column + 1})` : | ||||
|       ''; | ||||
|   const prefix = position && indent === 0 ? `${position}: ` : ''; | ||||
|   const postfix = position && indent !== 0 ? ` at ${position}` : ''; | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
|  * found in the LICENSE file at https://angular.io/license
 | ||||
|  */ | ||||
| 
 | ||||
| import {Statement, areAllEquivalent} from '../output/output_ast'; | ||||
| import {areAllEquivalent, Statement} from '../output/output_ast'; | ||||
| import {TypeScriptEmitter} from '../output/ts_emitter'; | ||||
| 
 | ||||
| export class GeneratedFile { | ||||
| @ -36,7 +36,7 @@ export class GeneratedFile { | ||||
|     } | ||||
|     // Note: the constructor guarantees that if this.source is not filled,
 | ||||
|     // then this.stmts is.
 | ||||
|     return areAllEquivalent(this.stmts !, other.stmts !); | ||||
|     return areAllEquivalent(this.stmts!, other.stmts!); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -34,7 +34,7 @@ export function listLazyRoutes( | ||||
|   return allLazyRoutes; | ||||
| } | ||||
| 
 | ||||
| function _collectLoadChildren(routes: string | Route | Route[], target: string[] = []): string[] { | ||||
| function _collectLoadChildren(routes: string|Route|Route[], target: string[] = []): string[] { | ||||
|   if (typeof routes === 'string') { | ||||
|     target.push(routes); | ||||
|   } else if (Array.isArray(routes)) { | ||||
|  | ||||
| @ -8,12 +8,12 @@ | ||||
| 
 | ||||
| import {CompileSummaryKind} from '../compile_metadata'; | ||||
| import {CompileReflector} from '../compile_reflector'; | ||||
| import {MetadataFactory, createAttribute, createComponent, createContentChild, createContentChildren, createDirective, createHost, createHostBinding, createHostListener, createInject, createInjectable, createInput, createNgModule, createOptional, createOutput, createPipe, createSelf, createSkipSelf, createViewChild, createViewChildren} from '../core'; | ||||
| import {createAttribute, createComponent, createContentChild, createContentChildren, createDirective, createHost, createHostBinding, createHostListener, createInject, createInjectable, createInput, createNgModule, createOptional, createOutput, createPipe, createSelf, createSkipSelf, createViewChild, createViewChildren, MetadataFactory} from '../core'; | ||||
| import * as o from '../output/output_ast'; | ||||
| import {SummaryResolver} from '../summary_resolver'; | ||||
| import {syntaxError} from '../util'; | ||||
| 
 | ||||
| import {FormattedMessageChain, formattedError} from './formatted_error'; | ||||
| import {formattedError, FormattedMessageChain} from './formatted_error'; | ||||
| import {StaticSymbol} from './static_symbol'; | ||||
| import {StaticSymbolResolver} from './static_symbol_resolver'; | ||||
| 
 | ||||
| @ -50,13 +50,13 @@ export class StaticReflector implements CompileReflector { | ||||
|   private conversionMap = new Map<StaticSymbol, (context: StaticSymbol, args: any[]) => any>(); | ||||
|   private resolvedExternalReferences = new Map<string, StaticSymbol>(); | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private injectionToken !: StaticSymbol; | ||||
|   private injectionToken!: StaticSymbol; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private opaqueToken !: StaticSymbol; | ||||
|   private opaqueToken!: StaticSymbol; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   ROUTES !: StaticSymbol; | ||||
|   ROUTES!: StaticSymbol; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private ANALYZE_FOR_ENTRY_COMPONENTS !: StaticSymbol; | ||||
|   private ANALYZE_FOR_ENTRY_COMPONENTS!: StaticSymbol; | ||||
|   private annotationForParentClassWithSummaryKind = | ||||
|       new Map<CompileSummaryKind, MetadataFactory<any>[]>(); | ||||
| 
 | ||||
| @ -110,10 +110,10 @@ export class StaticReflector implements CompileReflector { | ||||
|       if (declarationSymbol) return declarationSymbol; | ||||
|     } | ||||
|     const refSymbol = | ||||
|         this.symbolResolver.getSymbolByModule(ref.moduleName !, ref.name !, containingFile); | ||||
|         this.symbolResolver.getSymbolByModule(ref.moduleName!, ref.name!, containingFile); | ||||
|     const declarationSymbol = this.findSymbolDeclaration(refSymbol); | ||||
|     if (!containingFile) { | ||||
|       this.symbolResolver.recordModuleNameForFileName(refSymbol.filePath, ref.moduleName !); | ||||
|       this.symbolResolver.recordModuleNameForFileName(refSymbol.filePath, ref.moduleName!); | ||||
|       this.symbolResolver.recordImportAs(declarationSymbol, refSymbol); | ||||
|     } | ||||
|     if (key) { | ||||
| @ -192,16 +192,20 @@ export class StaticReflector implements CompileReflector { | ||||
|         const summary = this.summaryResolver.resolveSummary(parentType); | ||||
|         if (summary && summary.type) { | ||||
|           const requiredAnnotationTypes = | ||||
|               this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind !) !; | ||||
|               this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind!)!; | ||||
|           const typeHasRequiredAnnotation = requiredAnnotationTypes.some( | ||||
|               (requiredType) => ownAnnotations.some(ann => requiredType.isTypeOf(ann))); | ||||
|           if (!typeHasRequiredAnnotation) { | ||||
|             this.reportError( | ||||
|                 formatMetadataError( | ||||
|                     metadataError( | ||||
|                         `Class ${type.name} in ${type.filePath} extends from a ${CompileSummaryKind[summary.type.summaryKind!]} in another compilation unit without duplicating the decorator`, | ||||
|                         `Class ${type.name} in ${type.filePath} extends from a ${ | ||||
|                             CompileSummaryKind[summary.type.summaryKind! | ||||
|             ]} in another compilation unit without duplicating the decorator`,
 | ||||
|                         /* summary */ undefined, | ||||
|                         `Please add a ${requiredAnnotationTypes.map((type) => type.ngMetadataName).join(' or ')} decorator to the class`), | ||||
|                         `Please add a ${ | ||||
|                             requiredAnnotationTypes.map((type) => type.ngMetadataName) | ||||
|                                 .join(' or ')} decorator to the class`),
 | ||||
|                     type), | ||||
|                 type); | ||||
|           } | ||||
| @ -221,7 +225,7 @@ export class StaticReflector implements CompileReflector { | ||||
|       if (parentType) { | ||||
|         const parentPropMetadata = this.propMetadata(parentType); | ||||
|         Object.keys(parentPropMetadata).forEach((parentProp) => { | ||||
|           propMetadata ![parentProp] = parentPropMetadata[parentProp]; | ||||
|           propMetadata![parentProp] = parentPropMetadata[parentProp]; | ||||
|         }); | ||||
|       } | ||||
| 
 | ||||
| @ -231,10 +235,10 @@ export class StaticReflector implements CompileReflector { | ||||
|         const prop = (<any[]>propData) | ||||
|                          .find(a => a['__symbolic'] == 'property' || a['__symbolic'] == 'method'); | ||||
|         const decorators: any[] = []; | ||||
|         if (propMetadata ![propName]) { | ||||
|           decorators.push(...propMetadata ![propName]); | ||||
|         if (propMetadata![propName]) { | ||||
|           decorators.push(...propMetadata![propName]); | ||||
|         } | ||||
|         propMetadata ![propName] = decorators; | ||||
|         propMetadata![propName] = decorators; | ||||
|         if (prop && prop['decorators']) { | ||||
|           decorators.push(...this.simplify(type, prop['decorators'])); | ||||
|         } | ||||
| @ -271,7 +275,7 @@ export class StaticReflector implements CompileReflector { | ||||
|             if (decorators) { | ||||
|               nestedResult.push(...decorators); | ||||
|             } | ||||
|             parameters !.push(nestedResult); | ||||
|             parameters!.push(nestedResult); | ||||
|           }); | ||||
|         } else if (parentType) { | ||||
|           parameters = this.parameters(parentType); | ||||
| @ -297,7 +301,7 @@ export class StaticReflector implements CompileReflector { | ||||
|       if (parentType) { | ||||
|         const parentMethodNames = this._methodNames(parentType); | ||||
|         Object.keys(parentMethodNames).forEach((parentProp) => { | ||||
|           methodNames ![parentProp] = parentMethodNames[parentProp]; | ||||
|           methodNames![parentProp] = parentMethodNames[parentProp]; | ||||
|         }); | ||||
|       } | ||||
| 
 | ||||
| @ -305,7 +309,7 @@ export class StaticReflector implements CompileReflector { | ||||
|       Object.keys(members).forEach((propName) => { | ||||
|         const propData = members[propName]; | ||||
|         const isMethod = (<any[]>propData).some(a => a['__symbolic'] == 'method'); | ||||
|         methodNames ![propName] = methodNames ![propName] || isMethod; | ||||
|         methodNames![propName] = methodNames![propName] || isMethod; | ||||
|       }); | ||||
|       this.methodCache.set(type, methodNames); | ||||
|     } | ||||
| @ -485,7 +489,7 @@ export class StaticReflector implements CompileReflector { | ||||
|             // Propagate the message text up but add a message to the chain that explains how we got
 | ||||
|             // here.
 | ||||
|             // e.chain implies e.symbol
 | ||||
|             const summaryMsg = e.chain ? 'references \'' + e.symbol !.name + '\'' : errorSummary(e); | ||||
|             const summaryMsg = e.chain ? 'references \'' + e.symbol!.name + '\'' : errorSummary(e); | ||||
|             const summary = `'${nestedContext.name}' ${summaryMsg}`; | ||||
|             const chain = {message: summary, position: e.position, next: e.chain}; | ||||
|             // TODO(chuckj): retrieve the position information indirectly from the collectors node
 | ||||
| @ -494,7 +498,8 @@ export class StaticReflector implements CompileReflector { | ||||
|                 { | ||||
|                   message: e.message, | ||||
|                   advise: e.advise, | ||||
|                   context: e.context, chain, | ||||
|                   context: e.context, | ||||
|                   chain, | ||||
|                   symbol: nestedContext | ||||
|                 }, | ||||
|                 context); | ||||
| @ -566,7 +571,8 @@ export class StaticReflector implements CompileReflector { | ||||
|             { | ||||
|               message: FUNCTION_CALL_NOT_SUPPORTED, | ||||
|               context: functionSymbol, | ||||
|               value: targetFunction, position | ||||
|               value: targetFunction, | ||||
|               position | ||||
|             }, | ||||
|             context); | ||||
|       } | ||||
| @ -875,7 +881,7 @@ interface MetadataMessageChain { | ||||
|   next?: MetadataMessageChain; | ||||
| } | ||||
| 
 | ||||
| type MetadataError = Error & { | ||||
| type MetadataError = Error&{ | ||||
|   position?: Position; | ||||
|   advise?: string; | ||||
|   summary?: string; | ||||
| @ -916,7 +922,8 @@ function expandedMessage(message: string, context: any): string { | ||||
|   switch (message) { | ||||
|     case REFERENCE_TO_NONEXPORTED_CLASS: | ||||
|       if (context && context.className) { | ||||
|         return `References to a non-exported class are not supported in decorators but ${context.className} was referenced.`; | ||||
|         return `References to a non-exported class are not supported in decorators but ${ | ||||
|             context.className} was referenced.`;
 | ||||
|       } | ||||
|       break; | ||||
|     case VARIABLE_NOT_INITIALIZED: | ||||
| @ -935,7 +942,8 @@ function expandedMessage(message: string, context: any): string { | ||||
|       return 'Function calls are not supported in decorators'; | ||||
|     case REFERENCE_TO_LOCAL_SYMBOL: | ||||
|       if (context && context.name) { | ||||
|         return `Reference to a local (non-exported) symbols are not supported in decorators but '${context.name}' was referenced`; | ||||
|         return `Reference to a local (non-exported) symbols are not supported in decorators but '${ | ||||
|             context.name}' was referenced`;
 | ||||
|       } | ||||
|       break; | ||||
|     case LAMBDA_NOT_SUPPORTED: | ||||
| @ -1040,7 +1048,9 @@ abstract class BindingScope { | ||||
| } | ||||
| 
 | ||||
| class PopulatedScope extends BindingScope { | ||||
|   constructor(private bindings: Map<string, any>) { super(); } | ||||
|   constructor(private bindings: Map<string, any>) { | ||||
|     super(); | ||||
|   } | ||||
| 
 | ||||
|   resolve(name: string): any { | ||||
|     return this.bindings.has(name) ? this.bindings.get(name) : BindingScope.missing; | ||||
| @ -1048,7 +1058,7 @@ class PopulatedScope extends BindingScope { | ||||
| } | ||||
| 
 | ||||
| function formatMetadataMessageChain( | ||||
|     chain: MetadataMessageChain, advise: string | undefined): FormattedMessageChain { | ||||
|     chain: MetadataMessageChain, advise: string|undefined): FormattedMessageChain { | ||||
|   const expanded = expandedMessage(chain.message, chain.context); | ||||
|   const nesting = chain.symbol ? ` in '${chain.symbol.name}'` : ''; | ||||
|   const message = `${expanded}${nesting}`; | ||||
|  | ||||
| @ -31,7 +31,7 @@ export class StaticSymbolCache { | ||||
| 
 | ||||
|   get(declarationFile: string, name: string, members?: string[]): StaticSymbol { | ||||
|     members = members || []; | ||||
|     const memberSuffix = members.length ? `.${ members.join('.')}` : ''; | ||||
|     const memberSuffix = members.length ? `.${members.join('.')}` : ''; | ||||
|     const key = `"${declarationFile}".${name}${memberSuffix}`; | ||||
|     let result = this.cache.get(key); | ||||
|     if (!result) { | ||||
|  | ||||
| @ -76,12 +76,12 @@ export class StaticSymbolResolver { | ||||
| 
 | ||||
|   resolveSymbol(staticSymbol: StaticSymbol): ResolvedStaticSymbol { | ||||
|     if (staticSymbol.members.length > 0) { | ||||
|       return this._resolveSymbolMembers(staticSymbol) !; | ||||
|       return this._resolveSymbolMembers(staticSymbol)!; | ||||
|     } | ||||
|     // Note: always ask for a summary first,
 | ||||
|     // as we might have read shallow metadata via a .d.ts file
 | ||||
|     // for the symbol.
 | ||||
|     const resultFromSummary = this._resolveSymbolFromSummary(staticSymbol) !; | ||||
|     const resultFromSummary = this._resolveSymbolFromSummary(staticSymbol)!; | ||||
|     if (resultFromSummary) { | ||||
|       return resultFromSummary; | ||||
|     } | ||||
| @ -93,7 +93,7 @@ export class StaticSymbolResolver { | ||||
|     // have summaries, only .d.ts files. So we always need to check both, the summary
 | ||||
|     // and metadata.
 | ||||
|     this._createSymbolsOf(staticSymbol.filePath); | ||||
|     return this.resolvedSymbols.get(staticSymbol) !; | ||||
|     return this.resolvedSymbols.get(staticSymbol)!; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -119,15 +119,14 @@ export class StaticSymbolResolver { | ||||
|       const baseSymbol = | ||||
|           this.getStaticSymbol(summarizedFileName, summarizedName, staticSymbol.members); | ||||
|       const baseImportAs = this.getImportAs(baseSymbol, useSummaries); | ||||
|       return baseImportAs ? | ||||
|           this.getStaticSymbol( | ||||
|               summaryForJitFileName(baseImportAs.filePath), summaryForJitName(baseImportAs.name), | ||||
|               baseSymbol.members) : | ||||
|       return baseImportAs ? this.getStaticSymbol( | ||||
|                                 summaryForJitFileName(baseImportAs.filePath), | ||||
|                                 summaryForJitName(baseImportAs.name), baseSymbol.members) : | ||||
|                             null; | ||||
|     } | ||||
|     let result = (useSummaries && this.summaryResolver.getImportAs(staticSymbol)) || null; | ||||
|     if (!result) { | ||||
|       result = this.importAs.get(staticSymbol) !; | ||||
|       result = this.importAs.get(staticSymbol)!; | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
| @ -347,8 +346,8 @@ export class StaticSymbolResolver { | ||||
|           // correctly.
 | ||||
|           const originFilePath = this.resolveModule(origin, filePath); | ||||
|           if (!originFilePath) { | ||||
|             this.reportError(new Error( | ||||
|                 `Couldn't resolve original symbol for ${origin} from ${this.host.getOutputName(filePath)}`)); | ||||
|             this.reportError(new Error(`Couldn't resolve original symbol for ${origin} from ${ | ||||
|                 this.host.getOutputName(filePath)}`));
 | ||||
|           } else { | ||||
|             this.symbolResourcePaths.set(symbol, originFilePath); | ||||
|           } | ||||
| @ -413,7 +412,7 @@ export class StaticSymbolResolver { | ||||
|           } | ||||
|           let filePath: string; | ||||
|           if (module) { | ||||
|             filePath = self.resolveModule(module, sourceSymbol.filePath) !; | ||||
|             filePath = self.resolveModule(module, sourceSymbol.filePath)!; | ||||
|             if (!filePath) { | ||||
|               return { | ||||
|                 __symbolic: 'error', | ||||
| @ -501,8 +500,11 @@ export class StaticSymbolResolver { | ||||
|       } | ||||
|       if (moduleMetadata['version'] != SUPPORTED_SCHEMA_VERSION) { | ||||
|         const errorMessage = moduleMetadata['version'] == 2 ? | ||||
|             `Unsupported metadata version ${moduleMetadata['version']} for module ${module}. This module should be compiled with a newer version of ngc` : | ||||
|             `Metadata version mismatch for module ${this.host.getOutputName(module)}, found version ${moduleMetadata['version']}, expected ${SUPPORTED_SCHEMA_VERSION}`; | ||||
|             `Unsupported metadata version ${moduleMetadata['version']} for module ${ | ||||
|                 module}. This module should be compiled with a newer version of ngc` :
 | ||||
|             `Metadata version mismatch for module ${ | ||||
|                 this.host.getOutputName(module)}, found version ${ | ||||
|                 moduleMetadata['version']}, expected ${SUPPORTED_SCHEMA_VERSION}`;
 | ||||
|         this.reportError(new Error(errorMessage)); | ||||
|       } | ||||
|       this.metadataCache.set(module, moduleMetadata); | ||||
| @ -514,9 +516,8 @@ export class StaticSymbolResolver { | ||||
|   getSymbolByModule(module: string, symbolName: string, containingFile?: string): StaticSymbol { | ||||
|     const filePath = this.resolveModule(module, containingFile); | ||||
|     if (!filePath) { | ||||
|       this.reportError( | ||||
|           new Error(`Could not resolve module ${module}${containingFile ? ' relative to ' + | ||||
|             this.host.getOutputName(containingFile) : ''}`));
 | ||||
|       this.reportError(new Error(`Could not resolve module ${module}${ | ||||
|           containingFile ? ' relative to ' + this.host.getOutputName(containingFile) : ''}`));
 | ||||
|       return this.getStaticSymbol(`ERROR:${module}`, symbolName); | ||||
|     } | ||||
|     return this.getStaticSymbol(filePath, symbolName); | ||||
|  | ||||
| @ -71,7 +71,7 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> { | ||||
|     let summary = this.summaryCache.get(rootSymbol); | ||||
|     if (!summary) { | ||||
|       this._loadSummaryFile(staticSymbol.filePath); | ||||
|       summary = this.summaryCache.get(staticSymbol) !; | ||||
|       summary = this.summaryCache.get(staticSymbol)!; | ||||
|     } | ||||
|     return (rootSymbol === staticSymbol && summary) || null; | ||||
|   } | ||||
| @ -85,7 +85,7 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> { | ||||
| 
 | ||||
|   getImportAs(staticSymbol: StaticSymbol): StaticSymbol { | ||||
|     staticSymbol.assertNoMembers(); | ||||
|     return this.importAs.get(staticSymbol) !; | ||||
|     return this.importAs.get(staticSymbol)!; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -95,7 +95,9 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> { | ||||
|     return this.knownFileNameToModuleNames.get(importedFilePath) || null; | ||||
|   } | ||||
| 
 | ||||
|   addSummary(summary: Summary<StaticSymbol>) { this.summaryCache.set(summary.symbol, summary); } | ||||
|   addSummary(summary: Summary<StaticSymbol>) { | ||||
|     this.summaryCache.set(summary.symbol, summary); | ||||
|   } | ||||
| 
 | ||||
|   private _loadSummaryFile(filePath: string): boolean { | ||||
|     let hasSummary = this.loadedFilePaths.get(filePath); | ||||
| @ -121,7 +123,9 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> { | ||||
|       if (moduleName) { | ||||
|         this.knownFileNameToModuleNames.set(filePath, moduleName); | ||||
|       } | ||||
|       importAs.forEach((importAs) => { this.importAs.set(importAs.symbol, importAs.importAs); }); | ||||
|       importAs.forEach((importAs) => { | ||||
|         this.importAs.set(importAs.symbol, importAs.importAs); | ||||
|       }); | ||||
|     } | ||||
|     return hasSummary; | ||||
|   } | ||||
|  | ||||
| @ -15,11 +15,11 @@ import {ResolvedStaticSymbol, StaticSymbolResolver, unwrapResolvedMetadata} from | ||||
| import {isLoweredSymbol, ngfactoryFilePath, summaryForJitFileName, summaryForJitName} from './util'; | ||||
| 
 | ||||
| export function serializeSummaries( | ||||
|     srcFileName: string, forJitCtx: OutputContext | null, | ||||
|     srcFileName: string, forJitCtx: OutputContext|null, | ||||
|     summaryResolver: SummaryResolver<StaticSymbol>, symbolResolver: StaticSymbolResolver, | ||||
|     symbols: ResolvedStaticSymbol[], types: { | ||||
|       summary: CompileTypeSummary, | ||||
|       metadata: CompileNgModuleMetadata | CompileDirectiveMetadata | CompilePipeMetadata | | ||||
|       metadata: CompileNgModuleMetadata|CompileDirectiveMetadata|CompilePipeMetadata| | ||||
|       CompileTypeMetadata | ||||
|     }[], | ||||
|     createExternalSymbolReexports = | ||||
| @ -41,7 +41,9 @@ export function serializeSummaries( | ||||
|   const {json, exportAs} = toJsonSerializer.serialize(createExternalSymbolReexports); | ||||
|   if (forJitCtx) { | ||||
|     const forJitSerializer = new ForJitSerializer(forJitCtx, symbolResolver, summaryResolver); | ||||
|     types.forEach(({summary, metadata}) => { forJitSerializer.addSourceType(summary, metadata); }); | ||||
|     types.forEach(({summary, metadata}) => { | ||||
|       forJitSerializer.addSourceType(summary, metadata); | ||||
|     }); | ||||
|     toJsonSerializer.unprocessedSymbolSummariesBySymbol.forEach((summary) => { | ||||
|       if (summaryResolver.isLibraryFile(summary.symbol.filePath) && summary.type) { | ||||
|         forJitSerializer.addLibType(summary.type); | ||||
| @ -55,7 +57,7 @@ export function serializeSummaries( | ||||
| export function deserializeSummaries( | ||||
|     symbolCache: StaticSymbolCache, summaryResolver: SummaryResolver<StaticSymbol>, | ||||
|     libraryFileName: string, json: string): { | ||||
|   moduleName: string | null, | ||||
|   moduleName: string|null, | ||||
|   summaries: Summary<StaticSymbol>[], | ||||
|   importAs: {symbol: StaticSymbol, importAs: StaticSymbol}[] | ||||
| } { | ||||
| @ -144,7 +146,7 @@ class ToJsonSerializer extends ValueTransformer { | ||||
|       processedSummary.metadata = this.processValue(metadata, SerializationFlags.ResolveValue); | ||||
|       if (metadata instanceof StaticSymbol && | ||||
|           this.summaryResolver.isLibraryFile(metadata.filePath)) { | ||||
|         const declarationSymbol = this.symbols[this.indexBySymbol.get(metadata) !]; | ||||
|         const declarationSymbol = this.symbols[this.indexBySymbol.get(metadata)!]; | ||||
|         if (!isLoweredSymbol(declarationSymbol.name)) { | ||||
|           // Note: symbols that were introduced during codegen in the user file can have a reexport
 | ||||
|           // if a user used `export *`. However, we can't rely on this as tsickle will change
 | ||||
| @ -194,7 +196,7 @@ class ToJsonSerializer extends ValueTransformer { | ||||
|       summaries: this.processedSummaries, | ||||
|       symbols: this.symbols.map((symbol, index) => { | ||||
|         symbol.assertNoMembers(); | ||||
|         let importAs: string|number = undefined !; | ||||
|         let importAs: string|number = undefined!; | ||||
|         if (this.summaryResolver.isLibraryFile(symbol.filePath)) { | ||||
|           const reexportSymbol = this.reexportedBy.get(symbol); | ||||
|           if (reexportSymbol) { | ||||
| @ -202,7 +204,7 @@ class ToJsonSerializer extends ValueTransformer { | ||||
|             // user, we just proxy the external static symbol reference to the manual export.
 | ||||
|             // This ensures that the AOT compiler imports the external symbol through the
 | ||||
|             // user export and does not introduce another dependency which is not needed.
 | ||||
|             importAs = this.indexBySymbol.get(reexportSymbol) !; | ||||
|             importAs = this.indexBySymbol.get(reexportSymbol)!; | ||||
|           } else if (createExternalSymbolReexports) { | ||||
|             // In this case, the given external static symbol is *not* manually exported by
 | ||||
|             // the user, and we manually create a re-export in the factory file so that we
 | ||||
| @ -270,7 +272,7 @@ class ToJsonSerializer extends ValueTransformer { | ||||
|       if (this.unprocessedSymbolSummariesBySymbol.has(baseSymbol)) { | ||||
|         // the summary for this symbol was already added
 | ||||
|         // -> nothing to do.
 | ||||
|         return index !; | ||||
|         return index!; | ||||
|       } | ||||
|       summary = this.loadSummary(baseSymbol); | ||||
|       if (summary && summary.metadata instanceof StaticSymbol) { | ||||
| @ -324,8 +326,9 @@ class ForJitSerializer { | ||||
|       private summaryResolver: SummaryResolver<StaticSymbol>) {} | ||||
| 
 | ||||
|   addSourceType( | ||||
|       summary: CompileTypeSummary, metadata: CompileNgModuleMetadata|CompileDirectiveMetadata| | ||||
|       CompilePipeMetadata|CompileTypeMetadata) { | ||||
|       summary: CompileTypeSummary, | ||||
|       metadata: CompileNgModuleMetadata|CompileDirectiveMetadata|CompilePipeMetadata| | ||||
|       CompileTypeMetadata) { | ||||
|     this.data.push({summary, metadata, isLibrary: false}); | ||||
|   } | ||||
| 
 | ||||
| @ -356,7 +359,7 @@ class ForJitSerializer { | ||||
|         const fnName = summaryForJitName(summary.type.reference.name); | ||||
|         createSummaryForJitFunction( | ||||
|             this.outputCtx, summary.type.reference, | ||||
|             this.serializeSummaryWithDeps(summary, metadata !)); | ||||
|             this.serializeSummaryWithDeps(summary, metadata!)); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
| @ -372,8 +375,9 @@ class ForJitSerializer { | ||||
|   } | ||||
| 
 | ||||
|   private serializeSummaryWithDeps( | ||||
|       summary: CompileTypeSummary, metadata: CompileNgModuleMetadata|CompileDirectiveMetadata| | ||||
|       CompilePipeMetadata|CompileTypeMetadata): o.Expression { | ||||
|       summary: CompileTypeSummary, | ||||
|       metadata: CompileNgModuleMetadata|CompileDirectiveMetadata|CompilePipeMetadata| | ||||
|       CompileTypeMetadata): o.Expression { | ||||
|     const expressions: o.Expression[] = [this.serializeSummary(summary)]; | ||||
|     let providers: CompileProviderMetadata[] = []; | ||||
|     if (metadata instanceof CompileNgModuleMetadata) { | ||||
| @ -403,7 +407,8 @@ class ForJitSerializer { | ||||
|     // i.e. we didn't generate .ngsummary.ts files for these.
 | ||||
|     expressions.push( | ||||
|         ...providers.filter(provider => !!provider.useClass).map(provider => this.serializeSummary({ | ||||
|           summaryKind: CompileSummaryKind.Injectable, type: provider.useClass | ||||
|           summaryKind: CompileSummaryKind.Injectable, | ||||
|           type: provider.useClass | ||||
|         } as CompileTypeSummary))); | ||||
|     return o.literalArr(expressions); | ||||
|   } | ||||
| @ -425,7 +430,9 @@ class ForJitSerializer { | ||||
|         return new o.LiteralMapExpr(Object.keys(map).map( | ||||
|             (key) => new o.LiteralMapEntry(key, visitValue(map[key], this, context), false))); | ||||
|       } | ||||
|       visitPrimitive(value: any, context: any): any { return o.literal(value); } | ||||
|       visitPrimitive(value: any, context: any): any { | ||||
|         return o.literal(value); | ||||
|       } | ||||
|       visitOther(value: any, context: any): any { | ||||
|         if (value instanceof StaticSymbol) { | ||||
|           return outputCtx.importExpr(value); | ||||
| @ -441,7 +448,7 @@ class ForJitSerializer { | ||||
| 
 | ||||
| class FromJsonDeserializer extends ValueTransformer { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private symbols !: StaticSymbol[]; | ||||
|   private symbols!: StaticSymbol[]; | ||||
| 
 | ||||
|   constructor( | ||||
|       private symbolCache: StaticSymbolCache, | ||||
| @ -450,11 +457,11 @@ class FromJsonDeserializer extends ValueTransformer { | ||||
|   } | ||||
| 
 | ||||
|   deserialize(libraryFileName: string, json: string): { | ||||
|     moduleName: string | null, | ||||
|     moduleName: string|null, | ||||
|     summaries: Summary<StaticSymbol>[], | ||||
|     importAs: {symbol: StaticSymbol, importAs: StaticSymbol}[] | ||||
|   } { | ||||
|     const data: {moduleName: string | null, summaries: any[], symbols: any[]} = JSON.parse(json); | ||||
|     const data: {moduleName: string|null, summaries: any[], symbols: any[]} = JSON.parse(json); | ||||
|     const allImportAs: {symbol: StaticSymbol, importAs: StaticSymbol}[] = []; | ||||
|     this.symbols = data.symbols.map( | ||||
|         (serializedSymbol) => this.symbolCache.get( | ||||
|  | ||||
| @ -26,23 +26,35 @@ | ||||
| export class AstPath<T> { | ||||
|   constructor(private path: T[], public position: number = -1) {} | ||||
| 
 | ||||
|   get empty(): boolean { return !this.path || !this.path.length; } | ||||
|   get head(): T|undefined { return this.path[0]; } | ||||
|   get tail(): T|undefined { return this.path[this.path.length - 1]; } | ||||
|   get empty(): boolean { | ||||
|     return !this.path || !this.path.length; | ||||
|   } | ||||
|   get head(): T|undefined { | ||||
|     return this.path[0]; | ||||
|   } | ||||
|   get tail(): T|undefined { | ||||
|     return this.path[this.path.length - 1]; | ||||
|   } | ||||
| 
 | ||||
|   parentOf(node: T|undefined): T|undefined { | ||||
|     return node && this.path[this.path.indexOf(node) - 1]; | ||||
|   } | ||||
|   childOf(node: T): T|undefined { return this.path[this.path.indexOf(node) + 1]; } | ||||
|   childOf(node: T): T|undefined { | ||||
|     return this.path[this.path.indexOf(node) + 1]; | ||||
|   } | ||||
| 
 | ||||
|   first<N extends T>(ctor: {new (...args: any[]): N}): N|undefined { | ||||
|   first<N extends T>(ctor: {new(...args: any[]): N}): N|undefined { | ||||
|     for (let i = this.path.length - 1; i >= 0; i--) { | ||||
|       let item = this.path[i]; | ||||
|       if (item instanceof ctor) return <N>item; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   push(node: T) { this.path.push(node); } | ||||
|   push(node: T) { | ||||
|     this.path.push(node); | ||||
|   } | ||||
| 
 | ||||
|   pop(): T { return this.path.pop() !; } | ||||
|   pop(): T { | ||||
|     return this.path.pop()!; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -24,8 +24,8 @@ export function sanitizeIdentifier(name: string): string { | ||||
| 
 | ||||
| let _anonymousTypeIndex = 0; | ||||
| 
 | ||||
| export function identifierName(compileIdentifier: CompileIdentifierMetadata | null | undefined): | ||||
|     string|null { | ||||
| export function identifierName(compileIdentifier: CompileIdentifierMetadata|null|undefined): string| | ||||
|     null { | ||||
|   if (!compileIdentifier || !compileIdentifier.reference) { | ||||
|     return null; | ||||
|   } | ||||
| @ -72,9 +72,13 @@ export function componentFactoryName(compType: any): string { | ||||
|   return `${identifierName({reference: compType})}NgFactory`; | ||||
| } | ||||
| 
 | ||||
| export interface ProxyClass { setDelegate(delegate: any): void; } | ||||
| export interface ProxyClass { | ||||
|   setDelegate(delegate: any): void; | ||||
| } | ||||
| 
 | ||||
| export interface CompileIdentifierMetadata { reference: any; } | ||||
| export interface CompileIdentifierMetadata { | ||||
|   reference: any; | ||||
| } | ||||
| 
 | ||||
| export enum CompileSummaryKind { | ||||
|   Pipe, | ||||
| @ -175,8 +179,8 @@ export class CompileStylesheetMetadata { | ||||
|   styles: string[]; | ||||
|   styleUrls: string[]; | ||||
|   constructor( | ||||
|       {moduleUrl, styles, | ||||
|        styleUrls}: {moduleUrl?: string, styles?: string[], styleUrls?: string[]} = {}) { | ||||
|       {moduleUrl, styles, styleUrls}: | ||||
|           {moduleUrl?: string, styles?: string[], styleUrls?: string[]} = {}) { | ||||
|     this.moduleUrl = moduleUrl || null; | ||||
|     this.styles = _normalizeArray(styles); | ||||
|     this.styleUrls = _normalizeArray(styleUrls); | ||||
| @ -209,10 +213,21 @@ export class CompileTemplateMetadata { | ||||
|   ngContentSelectors: string[]; | ||||
|   interpolation: [string, string]|null; | ||||
|   preserveWhitespaces: boolean; | ||||
|   constructor({encapsulation, template, templateUrl, htmlAst, styles, styleUrls, | ||||
|                externalStylesheets, animations, ngContentSelectors, interpolation, isInline, | ||||
|                preserveWhitespaces}: { | ||||
|     encapsulation: ViewEncapsulation | null, | ||||
|   constructor({ | ||||
|     encapsulation, | ||||
|     template, | ||||
|     templateUrl, | ||||
|     htmlAst, | ||||
|     styles, | ||||
|     styleUrls, | ||||
|     externalStylesheets, | ||||
|     animations, | ||||
|     ngContentSelectors, | ||||
|     interpolation, | ||||
|     isInline, | ||||
|     preserveWhitespaces | ||||
|   }: { | ||||
|     encapsulation: ViewEncapsulation|null, | ||||
|     template: string|null, | ||||
|     templateUrl: string|null, | ||||
|     htmlAst: HtmlParseTreeResult|null, | ||||
| @ -286,9 +301,27 @@ export interface CompileDirectiveSummary extends CompileTypeSummary { | ||||
|  * Metadata regarding compilation of a directive. | ||||
|  */ | ||||
| export class CompileDirectiveMetadata { | ||||
|   static create({isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, | ||||
|                  host, providers, viewProviders, queries, guards, viewQueries, entryComponents, | ||||
|                  template, componentViewType, rendererType, componentFactory}: { | ||||
|   static create({ | ||||
|     isHost, | ||||
|     type, | ||||
|     isComponent, | ||||
|     selector, | ||||
|     exportAs, | ||||
|     changeDetection, | ||||
|     inputs, | ||||
|     outputs, | ||||
|     host, | ||||
|     providers, | ||||
|     viewProviders, | ||||
|     queries, | ||||
|     guards, | ||||
|     viewQueries, | ||||
|     entryComponents, | ||||
|     template, | ||||
|     componentViewType, | ||||
|     rendererType, | ||||
|     componentFactory | ||||
|   }: { | ||||
|     isHost: boolean, | ||||
|     type: CompileTypeMetadata, | ||||
|     isComponent: boolean, | ||||
| @ -347,7 +380,10 @@ export class CompileDirectiveMetadata { | ||||
|     return new CompileDirectiveMetadata({ | ||||
|       isHost, | ||||
|       type, | ||||
|       isComponent: !!isComponent, selector, exportAs, changeDetection, | ||||
|       isComponent: !!isComponent, | ||||
|       selector, | ||||
|       exportAs, | ||||
|       changeDetection, | ||||
|       inputs: inputsMap, | ||||
|       outputs: outputsMap, | ||||
|       hostListeners, | ||||
| @ -389,7 +425,8 @@ export class CompileDirectiveMetadata { | ||||
|   rendererType: StaticSymbol|object|null; | ||||
|   componentFactory: StaticSymbol|object|null; | ||||
| 
 | ||||
|   constructor({isHost, | ||||
|   constructor({ | ||||
|     isHost, | ||||
|     type, | ||||
|     isComponent, | ||||
|     selector, | ||||
| @ -409,7 +446,8 @@ export class CompileDirectiveMetadata { | ||||
|     template, | ||||
|     componentViewType, | ||||
|     rendererType, | ||||
|                componentFactory}: { | ||||
|     componentFactory | ||||
|   }: { | ||||
|     isHost: boolean, | ||||
|     type: CompileTypeMetadata, | ||||
|     isComponent: boolean, | ||||
| @ -534,7 +572,7 @@ export interface CompileNgModuleSummary extends CompileTypeSummary { | ||||
| 
 | ||||
| export class CompileShallowModuleMetadata { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   type !: CompileTypeMetadata; | ||||
|   type!: CompileTypeMetadata; | ||||
| 
 | ||||
|   rawExports: any; | ||||
|   rawImports: any; | ||||
| @ -562,9 +600,21 @@ export class CompileNgModuleMetadata { | ||||
| 
 | ||||
|   transitiveModule: TransitiveCompileNgModuleMetadata; | ||||
| 
 | ||||
|   constructor({type, providers, declaredDirectives, exportedDirectives, declaredPipes, | ||||
|                exportedPipes, entryComponents, bootstrapComponents, importedModules, | ||||
|                exportedModules, schemas, transitiveModule, id}: { | ||||
|   constructor({ | ||||
|     type, | ||||
|     providers, | ||||
|     declaredDirectives, | ||||
|     exportedDirectives, | ||||
|     declaredPipes, | ||||
|     exportedPipes, | ||||
|     entryComponents, | ||||
|     bootstrapComponents, | ||||
|     importedModules, | ||||
|     exportedModules, | ||||
|     schemas, | ||||
|     transitiveModule, | ||||
|     id | ||||
|   }: { | ||||
|     type: CompileTypeMetadata, | ||||
|     providers: CompileProviderMetadata[], | ||||
|     declaredDirectives: CompileIdentifierMetadata[], | ||||
| @ -595,7 +645,7 @@ export class CompileNgModuleMetadata { | ||||
|   } | ||||
| 
 | ||||
|   toSummary(): CompileNgModuleSummary { | ||||
|     const module = this.transitiveModule !; | ||||
|     const module = this.transitiveModule!; | ||||
|     return { | ||||
|       summaryKind: CompileSummaryKind.NgModule, | ||||
|       type: this.type, | ||||
| @ -666,7 +716,7 @@ export class TransitiveCompileNgModuleMetadata { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function _normalizeArray(obj: any[] | undefined | null): any[] { | ||||
| function _normalizeArray(obj: any[]|undefined|null): any[] { | ||||
|   return obj || []; | ||||
| } | ||||
| 
 | ||||
| @ -698,7 +748,7 @@ export class ProviderMeta { | ||||
| } | ||||
| 
 | ||||
| export function flatten<T>(list: Array<T|T[]>): T[] { | ||||
|   return list.reduce((flat: any[], item: T | T[]): T[] => { | ||||
|   return list.reduce((flat: any[], item: T|T[]): T[] => { | ||||
|     const flatItem = Array.isArray(item) ? flatten(item) : item; | ||||
|     return (<T[]>flat).concat(flatItem); | ||||
|   }, []); | ||||
| @ -712,7 +762,7 @@ function jitSourceUrl(url: string) { | ||||
| 
 | ||||
| export function templateSourceUrl( | ||||
|     ngModuleType: CompileIdentifierMetadata, compMeta: {type: CompileIdentifierMetadata}, | ||||
|     templateMeta: {isInline: boolean, templateUrl: string | null}) { | ||||
|     templateMeta: {isInline: boolean, templateUrl: string|null}) { | ||||
|   let url: string; | ||||
|   if (templateMeta.isInline) { | ||||
|     if (compMeta.type.reference instanceof StaticSymbol) { | ||||
| @ -723,13 +773,13 @@ export function templateSourceUrl( | ||||
|       url = `${identifierName(ngModuleType)}/${identifierName(compMeta.type)}.html`; | ||||
|     } | ||||
|   } else { | ||||
|     url = templateMeta.templateUrl !; | ||||
|     url = templateMeta.templateUrl!; | ||||
|   } | ||||
|   return compMeta.type.reference instanceof StaticSymbol ? url : jitSourceUrl(url); | ||||
| } | ||||
| 
 | ||||
| export function sharedStylesheetJitUrl(meta: CompileStylesheetMetadata, id: number) { | ||||
|   const pathParts = meta.moduleUrl !.split(/\/\\/g); | ||||
|   const pathParts = meta.moduleUrl!.split(/\/\\/g); | ||||
|   const baseName = pathParts[pathParts.length - 1]; | ||||
|   return jitSourceUrl(`css/${id}${baseName}.ngstyle.js`); | ||||
| } | ||||
|  | ||||
| @ -22,7 +22,9 @@ | ||||
|  * ``` | ||||
|  */ | ||||
| 
 | ||||
| export interface ExportedCompilerFacade { ɵcompilerFacade: CompilerFacade; } | ||||
| export interface ExportedCompilerFacade { | ||||
|   ɵcompilerFacade: CompilerFacade; | ||||
| } | ||||
| 
 | ||||
| export interface CompilerFacade { | ||||
|   compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade): | ||||
| @ -44,13 +46,15 @@ export interface CompilerFacade { | ||||
| 
 | ||||
|   R3ResolvedDependencyType: typeof R3ResolvedDependencyType; | ||||
|   R3FactoryTarget: typeof R3FactoryTarget; | ||||
|   ResourceLoader: {new (): ResourceLoader}; | ||||
|   ResourceLoader: {new(): ResourceLoader}; | ||||
| } | ||||
| 
 | ||||
| export interface CoreEnvironment { [name: string]: Function; } | ||||
| export interface CoreEnvironment { | ||||
|   [name: string]: Function; | ||||
| } | ||||
| 
 | ||||
| export type ResourceLoader = { | ||||
|   get(url: string): Promise<string>| string; | ||||
|   get(url: string): Promise<string>|string; | ||||
| }; | ||||
| 
 | ||||
| export type StringMap = { | ||||
| @ -58,7 +62,7 @@ export type StringMap = { | ||||
| }; | ||||
| 
 | ||||
| export type StringMapWithRename = { | ||||
|   [key: string]: string | [string, string]; | ||||
|   [key: string]: string|[string, string]; | ||||
| }; | ||||
| 
 | ||||
| export type Provider = any; | ||||
|  | ||||
| @ -11,7 +11,9 @@ import {Identifiers} from '../identifiers'; | ||||
| import * as o from '../output/output_ast'; | ||||
| import {ParseSourceSpan} from '../parse_util'; | ||||
| 
 | ||||
| export class EventHandlerVars { static event = o.variable('$event'); } | ||||
| export class EventHandlerVars { | ||||
|   static event = o.variable('$event'); | ||||
| } | ||||
| 
 | ||||
| export interface LocalResolver { | ||||
|   getLocal(name: string): o.Expression|null; | ||||
| @ -68,7 +70,7 @@ export type InterpolationFunction = (args: o.Expression[]) => o.Expression; | ||||
|  * used in an action binding (e.g. an event handler). | ||||
|  */ | ||||
| export function convertActionBinding( | ||||
|     localResolver: LocalResolver | null, implicitReceiver: o.Expression, action: cdAst.AST, | ||||
|     localResolver: LocalResolver|null, implicitReceiver: o.Expression, action: cdAst.AST, | ||||
|     bindingId: string, interpolationFunction?: InterpolationFunction, | ||||
|     baseSourceSpan?: ParseSourceSpan, | ||||
|     implicitReceiverAccesses?: Set<string>): ConvertActionBindingResult { | ||||
| @ -110,7 +112,7 @@ export function convertActionBinding( | ||||
|   } | ||||
| 
 | ||||
|   const lastIndex = actionStmts.length - 1; | ||||
|   let preventDefaultVar: o.ReadVarExpr = null !; | ||||
|   let preventDefaultVar: o.ReadVarExpr = null!; | ||||
|   if (lastIndex >= 0) { | ||||
|     const lastStatement = actionStmts[lastIndex]; | ||||
|     const returnExpr = convertStmtIntoExpression(lastStatement); | ||||
| @ -126,7 +128,9 @@ export function convertActionBinding( | ||||
|   return new ConvertActionBindingResult(actionStmts, preventDefaultVar); | ||||
| } | ||||
| 
 | ||||
| export interface BuiltinConverter { (args: o.Expression[]): o.Expression; } | ||||
| export interface BuiltinConverter { | ||||
|   (args: o.Expression[]): o.Expression; | ||||
| } | ||||
| 
 | ||||
| export interface BuiltinConverterFactory { | ||||
|   createLiteralArrayConverter(argCount: number): BuiltinConverter; | ||||
| @ -158,7 +162,7 @@ export enum BindingForm { | ||||
|  * `convertPropertyBindingBuiltins`. | ||||
|  */ | ||||
| export function convertPropertyBinding( | ||||
|     localResolver: LocalResolver | null, implicitReceiver: o.Expression, | ||||
|     localResolver: LocalResolver|null, implicitReceiver: o.Expression, | ||||
|     expressionWithoutBuiltins: cdAst.AST, bindingId: string, form: BindingForm, | ||||
|     interpolationFunction?: InterpolationFunction): ConvertPropertyBindingResult { | ||||
|   if (!localResolver) { | ||||
| @ -284,7 +288,9 @@ function convertToStatementIfNeeded(mode: _Mode, expr: o.Expression): o.Expressi | ||||
| } | ||||
| 
 | ||||
| class _BuiltinAstConverter extends cdAst.AstTransformer { | ||||
|   constructor(private _converterFactory: BuiltinConverterFactory) { super(); } | ||||
|   constructor(private _converterFactory: BuiltinConverterFactory) { | ||||
|     super(); | ||||
|   } | ||||
|   visitPipe(ast: cdAst.BindingPipe, context: any): any { | ||||
|     const args = [ast.exp, ...ast.args].map(ast => ast.visit(this, context)); | ||||
|     return new BuiltinFunctionCall( | ||||
| @ -384,9 +390,10 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|   visitConditional(ast: cdAst.Conditional, mode: _Mode): any { | ||||
|     const value: o.Expression = this._visit(ast.condition, _Mode.Expression); | ||||
|     return convertToStatementIfNeeded( | ||||
|         mode, value.conditional( | ||||
|                   this._visit(ast.trueExp, _Mode.Expression), | ||||
|                   this._visit(ast.falseExp, _Mode.Expression), this.convertSourceSpan(ast.span))); | ||||
|         mode, | ||||
|         value.conditional( | ||||
|             this._visit(ast.trueExp, _Mode.Expression), this._visit(ast.falseExp, _Mode.Expression), | ||||
|             this.convertSourceSpan(ast.span))); | ||||
|   } | ||||
| 
 | ||||
|   visitPipe(ast: cdAst.BindingPipe, mode: _Mode): any { | ||||
| @ -400,7 +407,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|     if (ast instanceof BuiltinFunctionCall) { | ||||
|       fnResult = ast.converter(convertedArgs); | ||||
|     } else { | ||||
|       fnResult = this._visit(ast.target !, _Mode.Expression) | ||||
|       fnResult = this._visit(ast.target!, _Mode.Expression) | ||||
|                      .callFn(convertedArgs, this.convertSourceSpan(ast.span)); | ||||
|     } | ||||
|     return convertToStatementIfNeeded(mode, fnResult); | ||||
| @ -467,7 +474,9 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|         mode, o.literal(ast.value, type, this.convertSourceSpan(ast.span))); | ||||
|   } | ||||
| 
 | ||||
|   private _getLocal(name: string): o.Expression|null { return this._localResolver.getLocal(name); } | ||||
|   private _getLocal(name: string): o.Expression|null { | ||||
|     return this._localResolver.getLocal(name); | ||||
|   } | ||||
| 
 | ||||
|   visitMethodCall(ast: cdAst.MethodCall, mode: _Mode): any { | ||||
|     if (ast.receiver instanceof cdAst.ImplicitReceiver && ast.name == '$any') { | ||||
| @ -558,8 +567,8 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|           // Otherwise it's an error.
 | ||||
|           const receiver = ast.name; | ||||
|           const value = (ast.value instanceof cdAst.PropertyRead) ? ast.value.name : undefined; | ||||
|           throw new Error( | ||||
|               `Cannot assign value "${value}" to template variable "${receiver}". Template variables are read-only.`); | ||||
|           throw new Error(`Cannot assign value "${value}" to template variable "${ | ||||
|               receiver}". Template variables are read-only.`);
 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| @ -579,7 +588,9 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|     return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode); | ||||
|   } | ||||
| 
 | ||||
|   visitAll(asts: cdAst.AST[], mode: _Mode): any { return asts.map(ast => this._visit(ast, mode)); } | ||||
|   visitAll(asts: cdAst.AST[], mode: _Mode): any { | ||||
|     return asts.map(ast => this._visit(ast, mode)); | ||||
|   } | ||||
| 
 | ||||
|   visitQuote(ast: cdAst.Quote, mode: _Mode): any { | ||||
|     throw new Error(`Quotes are not supported for evaluation!
 | ||||
| @ -634,7 +645,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|     // which comes in as leftMostSafe to this routine.
 | ||||
| 
 | ||||
|     let guardedExpression = this._visit(leftMostSafe.receiver, _Mode.Expression); | ||||
|     let temporary: o.ReadVarExpr = undefined !; | ||||
|     let temporary: o.ReadVarExpr = undefined!; | ||||
|     if (this.needsTemporary(leftMostSafe.receiver)) { | ||||
|       // If the expression has method calls or pipes then we need to save the result into a
 | ||||
|       // temporary variable to avoid calling stateful or impure code more than once.
 | ||||
| @ -652,12 +663,14 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|     // leftMostNode with its unguarded version in the call to `this.visit()`.
 | ||||
|     if (leftMostSafe instanceof cdAst.SafeMethodCall) { | ||||
|       this._nodeMap.set( | ||||
|           leftMostSafe, new cdAst.MethodCall( | ||||
|                             leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, | ||||
|                             leftMostSafe.name, leftMostSafe.args)); | ||||
|           leftMostSafe, | ||||
|           new cdAst.MethodCall( | ||||
|               leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, leftMostSafe.name, | ||||
|               leftMostSafe.args)); | ||||
|     } else { | ||||
|       this._nodeMap.set( | ||||
|           leftMostSafe, new cdAst.PropertyRead( | ||||
|           leftMostSafe, | ||||
|           new cdAst.PropertyRead( | ||||
|               leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, | ||||
|               leftMostSafe.name)); | ||||
|     } | ||||
| @ -690,25 +703,63 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|       return (this._nodeMap.get(ast) || ast).visit(visitor); | ||||
|     }; | ||||
|     return ast.visit({ | ||||
|       visitBinary(ast: cdAst.Binary) { return null; }, | ||||
|       visitChain(ast: cdAst.Chain) { return null; }, | ||||
|       visitConditional(ast: cdAst.Conditional) { return null; }, | ||||
|       visitFunctionCall(ast: cdAst.FunctionCall) { return null; }, | ||||
|       visitImplicitReceiver(ast: cdAst.ImplicitReceiver) { return null; }, | ||||
|       visitInterpolation(ast: cdAst.Interpolation) { return null; }, | ||||
|       visitKeyedRead(ast: cdAst.KeyedRead) { return visit(this, ast.obj); }, | ||||
|       visitKeyedWrite(ast: cdAst.KeyedWrite) { return null; }, | ||||
|       visitLiteralArray(ast: cdAst.LiteralArray) { return null; }, | ||||
|       visitLiteralMap(ast: cdAst.LiteralMap) { return null; }, | ||||
|       visitLiteralPrimitive(ast: cdAst.LiteralPrimitive) { return null; }, | ||||
|       visitMethodCall(ast: cdAst.MethodCall) { return visit(this, ast.receiver); }, | ||||
|       visitPipe(ast: cdAst.BindingPipe) { return null; }, | ||||
|       visitPrefixNot(ast: cdAst.PrefixNot) { return null; }, | ||||
|       visitNonNullAssert(ast: cdAst.NonNullAssert) { return null; }, | ||||
|       visitPropertyRead(ast: cdAst.PropertyRead) { return visit(this, ast.receiver); }, | ||||
|       visitPropertyWrite(ast: cdAst.PropertyWrite) { return null; }, | ||||
|       visitQuote(ast: cdAst.Quote) { return null; }, | ||||
|       visitSafeMethodCall(ast: cdAst.SafeMethodCall) { return visit(this, ast.receiver) || ast; }, | ||||
|       visitBinary(ast: cdAst.Binary) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitChain(ast: cdAst.Chain) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitConditional(ast: cdAst.Conditional) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitFunctionCall(ast: cdAst.FunctionCall) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitImplicitReceiver(ast: cdAst.ImplicitReceiver) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitInterpolation(ast: cdAst.Interpolation) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitKeyedRead(ast: cdAst.KeyedRead) { | ||||
|         return visit(this, ast.obj); | ||||
|       }, | ||||
|       visitKeyedWrite(ast: cdAst.KeyedWrite) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitLiteralArray(ast: cdAst.LiteralArray) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitLiteralMap(ast: cdAst.LiteralMap) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitLiteralPrimitive(ast: cdAst.LiteralPrimitive) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitMethodCall(ast: cdAst.MethodCall) { | ||||
|         return visit(this, ast.receiver); | ||||
|       }, | ||||
|       visitPipe(ast: cdAst.BindingPipe) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitPrefixNot(ast: cdAst.PrefixNot) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitNonNullAssert(ast: cdAst.NonNullAssert) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitPropertyRead(ast: cdAst.PropertyRead) { | ||||
|         return visit(this, ast.receiver); | ||||
|       }, | ||||
|       visitPropertyWrite(ast: cdAst.PropertyWrite) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitQuote(ast: cdAst.Quote) { | ||||
|         return null; | ||||
|       }, | ||||
|       visitSafeMethodCall(ast: cdAst.SafeMethodCall) { | ||||
|         return visit(this, ast.receiver) || ast; | ||||
|       }, | ||||
|       visitSafePropertyRead(ast: cdAst.SafePropertyRead) { | ||||
|         return visit(this, ast.receiver) || ast; | ||||
|       } | ||||
| @ -726,29 +777,66 @@ class _AstToIrVisitor implements cdAst.AstVisitor { | ||||
|       return ast.some(ast => visit(visitor, ast)); | ||||
|     }; | ||||
|     return ast.visit({ | ||||
|       visitBinary(ast: cdAst.Binary): | ||||
|           boolean{return visit(this, ast.left) || visit(this, ast.right);}, | ||||
|       visitChain(ast: cdAst.Chain) { return false; }, | ||||
|       visitConditional(ast: cdAst.Conditional): | ||||
|           boolean{return visit(this, ast.condition) || visit(this, ast.trueExp) || | ||||
|                       visit(this, ast.falseExp);}, | ||||
|       visitFunctionCall(ast: cdAst.FunctionCall) { return true; }, | ||||
|       visitImplicitReceiver(ast: cdAst.ImplicitReceiver) { return false; }, | ||||
|       visitInterpolation(ast: cdAst.Interpolation) { return visitSome(this, ast.expressions); }, | ||||
|       visitKeyedRead(ast: cdAst.KeyedRead) { return false; }, | ||||
|       visitKeyedWrite(ast: cdAst.KeyedWrite) { return false; }, | ||||
|       visitLiteralArray(ast: cdAst.LiteralArray) { return true; }, | ||||
|       visitLiteralMap(ast: cdAst.LiteralMap) { return true; }, | ||||
|       visitLiteralPrimitive(ast: cdAst.LiteralPrimitive) { return false; }, | ||||
|       visitMethodCall(ast: cdAst.MethodCall) { return true; }, | ||||
|       visitPipe(ast: cdAst.BindingPipe) { return true; }, | ||||
|       visitPrefixNot(ast: cdAst.PrefixNot) { return visit(this, ast.expression); }, | ||||
|       visitNonNullAssert(ast: cdAst.PrefixNot) { return visit(this, ast.expression); }, | ||||
|       visitPropertyRead(ast: cdAst.PropertyRead) { return false; }, | ||||
|       visitPropertyWrite(ast: cdAst.PropertyWrite) { return false; }, | ||||
|       visitQuote(ast: cdAst.Quote) { return false; }, | ||||
|       visitSafeMethodCall(ast: cdAst.SafeMethodCall) { return true; }, | ||||
|       visitSafePropertyRead(ast: cdAst.SafePropertyRead) { return false; } | ||||
|       visitBinary(ast: cdAst.Binary): boolean { | ||||
|         return visit(this, ast.left) || visit(this, ast.right); | ||||
|       }, | ||||
|       visitChain(ast: cdAst.Chain) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitConditional(ast: cdAst.Conditional): boolean { | ||||
|         return visit(this, ast.condition) || visit(this, ast.trueExp) || visit(this, ast.falseExp); | ||||
|       }, | ||||
|       visitFunctionCall(ast: cdAst.FunctionCall) { | ||||
|         return true; | ||||
|       }, | ||||
|       visitImplicitReceiver(ast: cdAst.ImplicitReceiver) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitInterpolation(ast: cdAst.Interpolation) { | ||||
|         return visitSome(this, ast.expressions); | ||||
|       }, | ||||
|       visitKeyedRead(ast: cdAst.KeyedRead) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitKeyedWrite(ast: cdAst.KeyedWrite) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitLiteralArray(ast: cdAst.LiteralArray) { | ||||
|         return true; | ||||
|       }, | ||||
|       visitLiteralMap(ast: cdAst.LiteralMap) { | ||||
|         return true; | ||||
|       }, | ||||
|       visitLiteralPrimitive(ast: cdAst.LiteralPrimitive) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitMethodCall(ast: cdAst.MethodCall) { | ||||
|         return true; | ||||
|       }, | ||||
|       visitPipe(ast: cdAst.BindingPipe) { | ||||
|         return true; | ||||
|       }, | ||||
|       visitPrefixNot(ast: cdAst.PrefixNot) { | ||||
|         return visit(this, ast.expression); | ||||
|       }, | ||||
|       visitNonNullAssert(ast: cdAst.PrefixNot) { | ||||
|         return visit(this, ast.expression); | ||||
|       }, | ||||
|       visitPropertyRead(ast: cdAst.PropertyRead) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitPropertyWrite(ast: cdAst.PropertyWrite) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitQuote(ast: cdAst.Quote) { | ||||
|         return false; | ||||
|       }, | ||||
|       visitSafeMethodCall(ast: cdAst.SafeMethodCall) { | ||||
|         return true; | ||||
|       }, | ||||
|       visitSafePropertyRead(ast: cdAst.SafePropertyRead) { | ||||
|         return false; | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -20,9 +20,14 @@ export class CompilerConfig { | ||||
|   public preserveWhitespaces: boolean; | ||||
|   public strictInjectionParameters: boolean; | ||||
| 
 | ||||
|   constructor( | ||||
|       {defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, jitDevMode = false, | ||||
|        missingTranslation = null, preserveWhitespaces, strictInjectionParameters}: { | ||||
|   constructor({ | ||||
|     defaultEncapsulation = ViewEncapsulation.Emulated, | ||||
|     useJit = true, | ||||
|     jitDevMode = false, | ||||
|     missingTranslation = null, | ||||
|     preserveWhitespaces, | ||||
|     strictInjectionParameters | ||||
|   }: { | ||||
|     defaultEncapsulation?: ViewEncapsulation, | ||||
|     useJit?: boolean, | ||||
|     jitDevMode?: boolean, | ||||
| @ -40,6 +45,6 @@ export class CompilerConfig { | ||||
| } | ||||
| 
 | ||||
| export function preserveWhitespacesDefault( | ||||
|     preserveWhitespacesOption: boolean | null, defaultSetting = false): boolean { | ||||
|     preserveWhitespacesOption: boolean|null, defaultSetting = false): boolean { | ||||
|   return preserveWhitespacesOption === null ? defaultSetting : preserveWhitespacesOption; | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import * as o from './output/output_ast'; | ||||
| import {OutputContext, error} from './util'; | ||||
| import {error, OutputContext} from './util'; | ||||
| 
 | ||||
| const CONSTANT_PREFIX = '_c'; | ||||
| 
 | ||||
| @ -21,7 +21,12 @@ const CONSTANT_PREFIX = '_c'; | ||||
|  */ | ||||
| const UNKNOWN_VALUE_KEY = o.variable('<unknown>'); | ||||
| 
 | ||||
| export const enum DefinitionKind {Injector, Directive, Component, Pipe} | ||||
| export const enum DefinitionKind { | ||||
|   Injector, | ||||
|   Directive, | ||||
|   Component, | ||||
|   Pipe | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Context to use when producing a key. | ||||
| @ -43,7 +48,7 @@ class FixupExpression extends o.Expression { | ||||
|   private original: o.Expression; | ||||
| 
 | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   shared !: boolean; | ||||
|   shared!: boolean; | ||||
| 
 | ||||
|   constructor(public resolved: o.Expression) { | ||||
|     super(resolved.type); | ||||
| @ -64,7 +69,9 @@ class FixupExpression extends o.Expression { | ||||
|     return e instanceof FixupExpression && this.resolved.isEquivalent(e.resolved); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return true; } | ||||
|   isConstant() { | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   fixup(expression: o.Expression) { | ||||
|     this.resolved = expression; | ||||
| @ -169,7 +176,7 @@ export class ConstantPool { | ||||
|       const resultExpressions = values.map( | ||||
|           (e, index) => e.isConstant() ? this.getConstLiteral(e, true) : o.variable(`a${index}`)); | ||||
|       const parameters = | ||||
|           resultExpressions.filter(isVariable).map(e => new o.FnParam(e.name !, o.DYNAMIC_TYPE)); | ||||
|           resultExpressions.filter(isVariable).map(e => new o.FnParam(e.name!, o.DYNAMIC_TYPE)); | ||||
|       const pureFunctionDeclaration = | ||||
|           o.fn(parameters, [new o.ReturnStatement(resultMap(resultExpressions))], o.INFERRED_TYPE); | ||||
|       const name = this.freshName(); | ||||
| @ -190,7 +197,9 @@ export class ConstantPool { | ||||
|    * a digit so the prefix should be a constant string (not based on user input) and | ||||
|    * must not end in a digit. | ||||
|    */ | ||||
|   uniqueName(prefix: string): string { return `${prefix}${this.nextNameIndex++}`; } | ||||
|   uniqueName(prefix: string): string { | ||||
|     return `${prefix}${this.nextNameIndex++}`; | ||||
|   } | ||||
| 
 | ||||
|   private definitionsOf(kind: DefinitionKind): Map<any, FixupExpression> { | ||||
|     switch (kind) { | ||||
| @ -222,7 +231,9 @@ export class ConstantPool { | ||||
|     return '<unknown>'; | ||||
|   } | ||||
| 
 | ||||
|   private freshName(): string { return this.uniqueName(CONSTANT_PREFIX); } | ||||
|   private freshName(): string { | ||||
|     return this.uniqueName(CONSTANT_PREFIX); | ||||
|   } | ||||
| 
 | ||||
|   private keyOf(expression: o.Expression) { | ||||
|     return expression.visitExpression(new KeyVisitor(), KEY_CONTEXT); | ||||
| @ -259,7 +270,9 @@ class KeyVisitor implements o.ExpressionVisitor { | ||||
|                                   `EX:${ast.value.runtime.name}`; | ||||
|   } | ||||
| 
 | ||||
|   visitReadVarExpr(node: o.ReadVarExpr) { return `VAR:${node.name}`; } | ||||
|   visitReadVarExpr(node: o.ReadVarExpr) { | ||||
|     return `VAR:${node.name}`; | ||||
|   } | ||||
| 
 | ||||
|   visitTypeofExpr(node: o.TypeofExpr, context: any): string { | ||||
|     return `TYPEOF:${node.expr.visitExpression(this, context)}`; | ||||
| @ -284,7 +297,7 @@ class KeyVisitor implements o.ExpressionVisitor { | ||||
|   visitLocalizedString = invalid; | ||||
| } | ||||
| 
 | ||||
| function invalid<T>(this: o.ExpressionVisitor, arg: o.Expression | o.Statement): never { | ||||
| function invalid<T>(this: o.ExpressionVisitor, arg: o.Expression|o.Statement): never { | ||||
|   throw new Error( | ||||
|       `Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`); | ||||
| } | ||||
|  | ||||
| @ -14,12 +14,16 @@ | ||||
| 
 | ||||
| import {CssSelector} from './selector'; | ||||
| 
 | ||||
| export interface Inject { token: any; } | ||||
| export interface Inject { | ||||
|   token: any; | ||||
| } | ||||
| export const createInject = makeMetadataFactory<Inject>('Inject', (token: any) => ({token})); | ||||
| export const createInjectionToken = makeMetadataFactory<object>( | ||||
|     'InjectionToken', (desc: string) => ({_desc: desc, ɵprov: undefined})); | ||||
| 
 | ||||
| export interface Attribute { attributeName?: string; } | ||||
| export interface Attribute { | ||||
|   attributeName?: string; | ||||
| } | ||||
| export const createAttribute = | ||||
|     makeMetadataFactory<Attribute>('Attribute', (attributeName?: string) => ({attributeName})); | ||||
| 
 | ||||
| @ -37,13 +41,16 @@ export const createContentChildren = makeMetadataFactory<Query>( | ||||
|     (selector?: any, data: any = {}) => | ||||
|         ({selector, first: false, isViewQuery: false, descendants: false, ...data})); | ||||
| export const createContentChild = makeMetadataFactory<Query>( | ||||
|     'ContentChild', (selector?: any, data: any = {}) => | ||||
|     'ContentChild', | ||||
|     (selector?: any, data: any = {}) => | ||||
|         ({selector, first: true, isViewQuery: false, descendants: true, ...data})); | ||||
| export const createViewChildren = makeMetadataFactory<Query>( | ||||
|     'ViewChildren', (selector?: any, data: any = {}) => | ||||
|     'ViewChildren', | ||||
|     (selector?: any, data: any = {}) => | ||||
|         ({selector, first: false, isViewQuery: true, descendants: true, ...data})); | ||||
| export const createViewChild = makeMetadataFactory<Query>( | ||||
|     'ViewChild', (selector: any, data: any) => | ||||
|     'ViewChild', | ||||
|     (selector: any, data: any) => | ||||
|         ({selector, first: true, isViewQuery: true, descendants: true, ...data})); | ||||
| 
 | ||||
| export interface Directive { | ||||
| @ -94,15 +101,21 @@ export interface Pipe { | ||||
| } | ||||
| export const createPipe = makeMetadataFactory<Pipe>('Pipe', (p: Pipe) => ({pure: true, ...p})); | ||||
| 
 | ||||
| export interface Input { bindingPropertyName?: string; } | ||||
| export interface Input { | ||||
|   bindingPropertyName?: string; | ||||
| } | ||||
| export const createInput = | ||||
|     makeMetadataFactory<Input>('Input', (bindingPropertyName?: string) => ({bindingPropertyName})); | ||||
| 
 | ||||
| export interface Output { bindingPropertyName?: string; } | ||||
| export interface Output { | ||||
|   bindingPropertyName?: string; | ||||
| } | ||||
| export const createOutput = makeMetadataFactory<Output>( | ||||
|     'Output', (bindingPropertyName?: string) => ({bindingPropertyName})); | ||||
| 
 | ||||
| export interface HostBinding { hostPropertyName?: string; } | ||||
| export interface HostBinding { | ||||
|   hostPropertyName?: string; | ||||
| } | ||||
| export const createHostBinding = makeMetadataFactory<HostBinding>( | ||||
|     'HostBinding', (hostPropertyName?: string) => ({hostPropertyName})); | ||||
| 
 | ||||
| @ -140,7 +153,9 @@ export interface Injectable { | ||||
| } | ||||
| export const createInjectable = | ||||
|     makeMetadataFactory('Injectable', (injectable: Injectable = {}) => injectable); | ||||
| export interface SchemaMetadata { name: string; } | ||||
| export interface SchemaMetadata { | ||||
|   name: string; | ||||
| } | ||||
| 
 | ||||
| export const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata = { | ||||
|   name: 'custom-elements' | ||||
| @ -155,7 +170,9 @@ export const createSelf = makeMetadataFactory('Self'); | ||||
| export const createSkipSelf = makeMetadataFactory('SkipSelf'); | ||||
| export const createHost = makeMetadataFactory('Host'); | ||||
| 
 | ||||
| export interface Type extends Function { new (...args: any[]): any; } | ||||
| export interface Type extends Function { | ||||
|   new(...args: any[]): any; | ||||
| } | ||||
| export const Type = Function; | ||||
| 
 | ||||
| export enum SecurityContext { | ||||
| @ -240,7 +257,10 @@ export const enum InjectFlags { | ||||
|   Optional = 1 << 3, | ||||
| } | ||||
| 
 | ||||
| export const enum ArgumentType {Inline = 0, Dynamic = 1} | ||||
| export const enum ArgumentType { | ||||
|   Inline = 0, | ||||
|   Dynamic = 1 | ||||
| } | ||||
| 
 | ||||
| export const enum BindingFlags { | ||||
|   TypeElementAttribute = 1 << 0, | ||||
| @ -255,7 +275,10 @@ export const enum BindingFlags { | ||||
|   Types = TypeElementAttribute | TypeElementClass | TypeElementStyle | TypeProperty | ||||
| } | ||||
| 
 | ||||
| export const enum QueryBindingType {First = 0, All = 1} | ||||
| export const enum QueryBindingType { | ||||
|   First = 0, | ||||
|   All = 1 | ||||
| } | ||||
| 
 | ||||
| export const enum QueryValueType { | ||||
|   ElementRef = 0, | ||||
| @ -324,7 +347,7 @@ export const enum SelectorFlags { | ||||
| 
 | ||||
| // These are a copy the CSS types from core/src/render3/interfaces/projection.ts
 | ||||
| // They are duplicated here as they cannot be directly referenced from core.
 | ||||
| export type R3CssSelector = (string | SelectorFlags)[]; | ||||
| export type R3CssSelector = (string|SelectorFlags)[]; | ||||
| export type R3CssSelectorList = R3CssSelector[]; | ||||
| 
 | ||||
| function parserSelectorToSimpleSelector(selector: CssSelector): R3CssSelector { | ||||
| @ -363,7 +386,7 @@ function parserSelectorToR3Selector(selector: CssSelector): R3CssSelector { | ||||
|   return positive.concat(...negative); | ||||
| } | ||||
| 
 | ||||
| export function parseSelectorToR3Selector(selector: string | null): R3CssSelectorList { | ||||
| export function parseSelectorToR3Selector(selector: string|null): R3CssSelectorList { | ||||
|   return selector ? CssSelector.parse(selector).map(parserSelectorToR3Selector) : []; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -46,8 +46,12 @@ export interface CssAstVisitor { | ||||
| 
 | ||||
| export abstract class CssAst { | ||||
|   constructor(public location: ParseSourceSpan) {} | ||||
|   get start(): ParseLocation { return this.location.start; } | ||||
|   get end(): ParseLocation { return this.location.end; } | ||||
|   get start(): ParseLocation { | ||||
|     return this.location.start; | ||||
|   } | ||||
|   get end(): ParseLocation { | ||||
|     return this.location.end; | ||||
|   } | ||||
|   abstract visit(visitor: CssAstVisitor, context?: any): any; | ||||
| } | ||||
| 
 | ||||
| @ -55,11 +59,15 @@ export class CssStyleValueAst extends CssAst { | ||||
|   constructor(location: ParseSourceSpan, public tokens: CssToken[], public strValue: string) { | ||||
|     super(location); | ||||
|   } | ||||
|   visit(visitor: CssAstVisitor, context?: any): any { return visitor.visitCssValue(this); } | ||||
|   visit(visitor: CssAstVisitor, context?: any): any { | ||||
|     return visitor.visitCssValue(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export abstract class CssRuleAst extends CssAst { | ||||
|   constructor(location: ParseSourceSpan) { super(location); } | ||||
|   constructor(location: ParseSourceSpan) { | ||||
|     super(location); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class CssBlockRuleAst extends CssRuleAst { | ||||
| @ -158,7 +166,9 @@ export class CssDefinitionAst extends CssAst { | ||||
| } | ||||
| 
 | ||||
| export abstract class CssSelectorPartAst extends CssAst { | ||||
|   constructor(location: ParseSourceSpan) { super(location); } | ||||
|   constructor(location: ParseSourceSpan) { | ||||
|     super(location); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class CssSelectorAst extends CssSelectorPartAst { | ||||
| @ -195,8 +205,12 @@ export class CssPseudoSelectorAst extends CssSelectorPartAst { | ||||
| } | ||||
| 
 | ||||
| export class CssBlockAst extends CssAst { | ||||
|   constructor(location: ParseSourceSpan, public entries: CssAst[]) { super(location); } | ||||
|   visit(visitor: CssAstVisitor, context?: any): any { return visitor.visitCssBlock(this, context); } | ||||
|   constructor(location: ParseSourceSpan, public entries: CssAst[]) { | ||||
|     super(location); | ||||
|   } | ||||
|   visit(visitor: CssAstVisitor, context?: any): any { | ||||
|     return visitor.visitCssBlock(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| @ -213,7 +227,9 @@ export class CssStylesBlockAst extends CssBlockAst { | ||||
| } | ||||
| 
 | ||||
| export class CssStyleSheetAst extends CssAst { | ||||
|   constructor(location: ParseSourceSpan, public rules: CssAst[]) { super(location); } | ||||
|   constructor(location: ParseSourceSpan, public rules: CssAst[]) { | ||||
|     super(location); | ||||
|   } | ||||
|   visit(visitor: CssAstVisitor, context?: any): any { | ||||
|     return visitor.visitCssStyleSheet(this, context); | ||||
|   } | ||||
|  | ||||
| @ -117,7 +117,7 @@ function _trackWhitespace(mode: CssLexerMode) { | ||||
| 
 | ||||
| export class CssScanner { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   peek !: number; | ||||
|   peek!: number; | ||||
|   peekPeek: number; | ||||
|   length: number = 0; | ||||
|   index: number = -1; | ||||
| @ -135,7 +135,9 @@ export class CssScanner { | ||||
|     this.advance(); | ||||
|   } | ||||
| 
 | ||||
|   getMode(): CssLexerMode { return this._currentMode; } | ||||
|   getMode(): CssLexerMode { | ||||
|     return this._currentMode; | ||||
|   } | ||||
| 
 | ||||
|   setMode(mode: CssLexerMode) { | ||||
|     if (this._currentMode != mode) { | ||||
| @ -198,7 +200,7 @@ export class CssScanner { | ||||
|     const previousLine = this.line; | ||||
|     const previousColumn = this.column; | ||||
| 
 | ||||
|     let next: CssToken = undefined !; | ||||
|     let next: CssToken = undefined!; | ||||
|     const output = this.scan(); | ||||
|     if (output != null) { | ||||
|       // just incase the inner scan method returned an error
 | ||||
| @ -236,7 +238,8 @@ export class CssScanner { | ||||
|       } | ||||
| 
 | ||||
|       error = cssScannerError( | ||||
|           next, generateErrorMessage( | ||||
|           next, | ||||
|           generateErrorMessage( | ||||
|               this.input, errorMessage, next.strValue, previousIndex, previousLine, | ||||
|               previousColumn)); | ||||
|     } | ||||
| @ -254,7 +257,7 @@ export class CssScanner { | ||||
|     const token = this._scan(); | ||||
|     if (token == null) return null; | ||||
| 
 | ||||
|     const error = this._currentError !; | ||||
|     const error = this._currentError!; | ||||
|     this._currentError = null; | ||||
| 
 | ||||
|     if (!trackWS) { | ||||
| @ -461,7 +464,7 @@ export class CssScanner { | ||||
|     const startingColumn = this.column; | ||||
|     this.advance(); | ||||
|     if (isIdentifierStart(this.peek, this.peekPeek)) { | ||||
|       const ident = this.scanIdentifier() !; | ||||
|       const ident = this.scanIdentifier()!; | ||||
|       const strValue = '@' + ident.strValue; | ||||
|       return new CssToken(start, startingColumn, this.line, CssTokenType.AtKeyword, strValue); | ||||
|     } else { | ||||
|  | ||||
| @ -9,7 +9,7 @@ | ||||
| import * as chars from '../chars'; | ||||
| import {ParseError, ParseLocation, ParseSourceFile, ParseSourceSpan} from '../parse_util'; | ||||
| 
 | ||||
| import {BlockType, CssAst, CssAtRulePredicateAst, CssBlockAst, CssBlockDefinitionRuleAst, CssBlockRuleAst, CssDefinitionAst, CssInlineRuleAst, CssKeyframeDefinitionAst, CssKeyframeRuleAst, CssMediaQueryRuleAst, CssPseudoSelectorAst, CssRuleAst, CssSelectorAst, CssSelectorRuleAst, CssSimpleSelectorAst, CssStyleSheetAst, CssStyleValueAst, CssStylesBlockAst, CssUnknownRuleAst, CssUnknownTokenListAst, mergeTokens} from './css_ast'; | ||||
| import {BlockType, CssAst, CssAtRulePredicateAst, CssBlockAst, CssBlockDefinitionRuleAst, CssBlockRuleAst, CssDefinitionAst, CssInlineRuleAst, CssKeyframeDefinitionAst, CssKeyframeRuleAst, CssMediaQueryRuleAst, CssPseudoSelectorAst, CssRuleAst, CssSelectorAst, CssSelectorRuleAst, CssSimpleSelectorAst, CssStylesBlockAst, CssStyleSheetAst, CssStyleValueAst, CssUnknownRuleAst, CssUnknownTokenListAst, mergeTokens} from './css_ast'; | ||||
| import {CssLexer, CssLexerMode, CssScanner, CssToken, CssTokenType, generateErrorMessage, getRawMessage, isNewline} from './css_lexer'; | ||||
| 
 | ||||
| const SPACE_OPERATOR = ' '; | ||||
| @ -84,11 +84,11 @@ export class ParsedCssResult { | ||||
| export class CssParser { | ||||
|   private _errors: CssParseError[] = []; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _file !: ParseSourceFile; | ||||
|   private _file!: ParseSourceFile; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _scanner !: CssScanner; | ||||
|   private _scanner!: CssScanner; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _lastToken !: CssToken; | ||||
|   private _lastToken!: CssToken; | ||||
| 
 | ||||
|   /** | ||||
|    * @param css the CSS code that will be parsed | ||||
| @ -125,11 +125,13 @@ export class CssParser { | ||||
|       // EOF token that was emitted sometime during the lexing
 | ||||
|       span = this._generateSourceSpan(firstRule, this._lastToken); | ||||
|     } | ||||
|     return new CssStyleSheetAst(span !, results); | ||||
|     return new CssStyleSheetAst(span!, results); | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _getSourceContent(): string { return this._scanner != null ? this._scanner.input : ''; } | ||||
|   _getSourceContent(): string { | ||||
|     return this._scanner != null ? this._scanner.input : ''; | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _extractSourceContent(start: number, end: number): string { | ||||
| @ -159,9 +161,9 @@ export class CssParser { | ||||
|     let endColumn: number = -1; | ||||
|     let endIndex: number = -1; | ||||
|     if (end instanceof CssAst) { | ||||
|       endLine = end.location.end.line !; | ||||
|       endColumn = end.location.end.col !; | ||||
|       endIndex = end.location.end.offset !; | ||||
|       endLine = end.location.end.line!; | ||||
|       endColumn = end.location.end.col!; | ||||
|       endIndex = end.location.end.offset!; | ||||
|     } else if (end instanceof CssToken) { | ||||
|       endLine = end.line; | ||||
|       endColumn = end.column; | ||||
| @ -253,7 +255,7 @@ export class CssParser { | ||||
| 
 | ||||
|       case BlockType.Viewport: | ||||
|       case BlockType.FontFace: | ||||
|         block = this._parseStyleBlock(delimiters) !; | ||||
|         block = this._parseStyleBlock(delimiters)!; | ||||
|         span = this._generateSourceSpan(startToken, block); | ||||
|         return new CssBlockRuleAst(span, type, block); | ||||
| 
 | ||||
| @ -293,7 +295,7 @@ export class CssParser { | ||||
|         span = this._generateSourceSpan(startToken, tokens[tokens.length - 1]); | ||||
|         query = new CssAtRulePredicateAst(span, strValue, tokens); | ||||
|         block = this._parseBlock(delimiters); | ||||
|         strValue = this._extractSourceContent(start, block.end.offset !); | ||||
|         strValue = this._extractSourceContent(start, block.end.offset!); | ||||
|         span = this._generateSourceSpan(startToken, block); | ||||
|         return new CssBlockDefinitionRuleAst(span, strValue, type, query, block); | ||||
| 
 | ||||
| @ -310,11 +312,15 @@ export class CssParser { | ||||
|             token); | ||||
| 
 | ||||
|         this._collectUntilDelim(delimiters | LBRACE_DELIM_FLAG | SEMICOLON_DELIM_FLAG) | ||||
|             .forEach((token) => { listOfTokens.push(token); }); | ||||
|             .forEach((token) => { | ||||
|               listOfTokens.push(token); | ||||
|             }); | ||||
|         if (this._scanner.peek == chars.$LBRACE) { | ||||
|           listOfTokens.push(this._consume(CssTokenType.Character, '{')); | ||||
|           this._collectUntilDelim(delimiters | RBRACE_DELIM_FLAG | LBRACE_DELIM_FLAG) | ||||
|               .forEach((token) => { listOfTokens.push(token); }); | ||||
|               .forEach((token) => { | ||||
|                 listOfTokens.push(token); | ||||
|               }); | ||||
|           listOfTokens.push(this._consume(CssTokenType.Character, '}')); | ||||
|         } | ||||
|         endToken = listOfTokens[listOfTokens.length - 1]; | ||||
| @ -339,7 +345,9 @@ export class CssParser { | ||||
|       const innerTokens: CssToken[] = []; | ||||
|       selectors.forEach((selector: CssSelectorAst) => { | ||||
|         selector.selectorParts.forEach((part: CssSimpleSelectorAst) => { | ||||
|           part.tokens.forEach((token: CssToken) => { innerTokens.push(token); }); | ||||
|           part.tokens.forEach((token: CssToken) => { | ||||
|             innerTokens.push(token); | ||||
|           }); | ||||
|         }); | ||||
|       }); | ||||
|       const endToken = innerTokens[innerTokens.length - 1]; | ||||
| @ -376,7 +384,7 @@ export class CssParser { | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _scan(): CssToken { | ||||
|     const output = this._scanner.scan() !; | ||||
|     const output = this._scanner.scan()!; | ||||
|     const token = output.token; | ||||
|     const error = output.error; | ||||
|     if (error != null) { | ||||
| @ -387,7 +395,9 @@ export class CssParser { | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _getScannerIndex(): number { return this._scanner.index; } | ||||
|   _getScannerIndex(): number { | ||||
|     return this._scanner.index; | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
|   _consume(type: CssTokenType, value: string|null = null): CssToken { | ||||
| @ -432,7 +442,7 @@ export class CssParser { | ||||
|     } | ||||
|     const stylesBlock = this._parseStyleBlock(delimiters | RBRACE_DELIM_FLAG); | ||||
|     const span = this._generateSourceSpan(stepTokens[0], stylesBlock); | ||||
|     const ast = new CssKeyframeDefinitionAst(span, stepTokens, stylesBlock !); | ||||
|     const ast = new CssKeyframeDefinitionAst(span, stepTokens, stylesBlock!); | ||||
| 
 | ||||
|     this._scanner.setMode(CssLexerMode.BLOCK); | ||||
|     return ast; | ||||
| @ -523,7 +533,7 @@ export class CssParser { | ||||
|     const selectorCssTokens: CssToken[] = []; | ||||
|     const pseudoSelectors: CssPseudoSelectorAst[] = []; | ||||
| 
 | ||||
|     let previousToken: CssToken = undefined !; | ||||
|     let previousToken: CssToken = undefined!; | ||||
| 
 | ||||
|     const selectorPartDelimiters = delimiters | SPACE_DELIM_FLAG; | ||||
|     let loopOverSelector = !characterContainsDelimiter(this._scanner.peek, selectorPartDelimiters); | ||||
| @ -576,7 +586,8 @@ export class CssParser { | ||||
|         hasAttributeError || this._scanner.getMode() == CssLexerMode.ATTRIBUTE_SELECTOR; | ||||
|     if (hasAttributeError) { | ||||
|       this._error( | ||||
|           `Unbalanced CSS attribute selector at column ${previousToken.line}:${previousToken.column}`, | ||||
|           `Unbalanced CSS attribute selector at column ${previousToken.line}:${ | ||||
|               previousToken.column}`,
 | ||||
|           previousToken); | ||||
|     } | ||||
| 
 | ||||
| @ -671,8 +682,8 @@ export class CssParser { | ||||
|       endTokenOrAst = operator; | ||||
|     } | ||||
| 
 | ||||
|     const span = this._generateSourceSpan(startTokenOrAst !, endTokenOrAst); | ||||
|     return new CssSimpleSelectorAst(span, selectorCssTokens, strValue, pseudoSelectors, operator !); | ||||
|     const span = this._generateSourceSpan(startTokenOrAst!, endTokenOrAst); | ||||
|     return new CssSimpleSelectorAst(span, selectorCssTokens, strValue, pseudoSelectors, operator!); | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
| @ -701,7 +712,7 @@ export class CssParser { | ||||
| 
 | ||||
|     const tokens: CssToken[] = []; | ||||
|     let wsStr = ''; | ||||
|     let previous: CssToken = undefined !; | ||||
|     let previous: CssToken = undefined!; | ||||
|     while (!characterContainsDelimiter(this._scanner.peek, delimiters)) { | ||||
|       let token: CssToken; | ||||
|       if (previous != null && previous.type == CssTokenType.Identifier && | ||||
| @ -841,7 +852,9 @@ export class CssParser { | ||||
|           const remainingTokens = this._collectUntilDelim( | ||||
|               delimiters | COLON_DELIM_FLAG | SEMICOLON_DELIM_FLAG, CssTokenType.Identifier); | ||||
|           if (remainingTokens.length > 0) { | ||||
|             remainingTokens.forEach((token) => { propStr.push(token.strValue); }); | ||||
|             remainingTokens.forEach((token) => { | ||||
|               propStr.push(token.strValue); | ||||
|             }); | ||||
|           } | ||||
| 
 | ||||
|           endToken = prop = | ||||
| @ -868,7 +881,7 @@ export class CssParser { | ||||
|     } | ||||
| 
 | ||||
|     const span = this._generateSourceSpan(prop, endToken); | ||||
|     return new CssDefinitionAst(span, prop, value !); | ||||
|     return new CssDefinitionAst(span, prop, value!); | ||||
|   } | ||||
| 
 | ||||
|   /** @internal */ | ||||
| @ -899,5 +912,7 @@ export class CssParseError extends ParseError { | ||||
|     return new CssParseError(span, 'CSS Parse Error: ' + errMsg); | ||||
|   } | ||||
| 
 | ||||
|   constructor(span: ParseSourceSpan, message: string) { super(span, message); } | ||||
|   constructor(span: ParseSourceSpan, message: string) { | ||||
|     super(span, message); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -17,7 +17,7 @@ import {ResourceLoader} from './resource_loader'; | ||||
| import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver'; | ||||
| import {PreparsedElementType, preparseElement} from './template_parser/template_preparser'; | ||||
| import {UrlResolver} from './url_resolver'; | ||||
| import {SyncAsync, isDefined, stringify, syntaxError} from './util'; | ||||
| import {isDefined, stringify, SyncAsync, syntaxError} from './util'; | ||||
| 
 | ||||
| export interface PrenormalizedTemplateMetadata { | ||||
|   ngModuleType: any; | ||||
| @ -40,16 +40,19 @@ export class DirectiveNormalizer { | ||||
|       private _resourceLoader: ResourceLoader, private _urlResolver: UrlResolver, | ||||
|       private _htmlParser: HtmlParser, private _config: CompilerConfig) {} | ||||
| 
 | ||||
|   clearCache(): void { this._resourceLoaderCache.clear(); } | ||||
|   clearCache(): void { | ||||
|     this._resourceLoaderCache.clear(); | ||||
|   } | ||||
| 
 | ||||
|   clearCacheFor(normalizedDirective: CompileDirectiveMetadata): void { | ||||
|     if (!normalizedDirective.isComponent) { | ||||
|       return; | ||||
|     } | ||||
|     const template = normalizedDirective.template !; | ||||
|     this._resourceLoaderCache.delete(template.templateUrl !); | ||||
|     template.externalStylesheets.forEach( | ||||
|         (stylesheet) => { this._resourceLoaderCache.delete(stylesheet.moduleUrl !); }); | ||||
|     this._resourceLoaderCache.delete(template.templateUrl!); | ||||
|     template.externalStylesheets.forEach((stylesheet) => { | ||||
|       this._resourceLoaderCache.delete(stylesheet.moduleUrl!); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   private _fetch(url: string): SyncAsync<string> { | ||||
| @ -65,17 +68,18 @@ export class DirectiveNormalizer { | ||||
|       SyncAsync<CompileTemplateMetadata> { | ||||
|     if (isDefined(prenormData.template)) { | ||||
|       if (isDefined(prenormData.templateUrl)) { | ||||
|         throw syntaxError( | ||||
|             `'${stringify(prenormData.componentType)}' component cannot define both template and templateUrl`); | ||||
|         throw syntaxError(`'${ | ||||
|             stringify(prenormData | ||||
|                           .componentType)}' component cannot define both template and templateUrl`);
 | ||||
|       } | ||||
|       if (typeof prenormData.template !== 'string') { | ||||
|         throw syntaxError( | ||||
|             `The template specified for component ${stringify(prenormData.componentType)} is not a string`); | ||||
|         throw syntaxError(`The template specified for component ${ | ||||
|             stringify(prenormData.componentType)} is not a string`);
 | ||||
|       } | ||||
|     } else if (isDefined(prenormData.templateUrl)) { | ||||
|       if (typeof prenormData.templateUrl !== 'string') { | ||||
|         throw syntaxError( | ||||
|             `The templateUrl specified for component ${stringify(prenormData.componentType)} is not a string`); | ||||
|         throw syntaxError(`The templateUrl specified for component ${ | ||||
|             stringify(prenormData.componentType)} is not a string`);
 | ||||
|       } | ||||
|     } else { | ||||
|       throw syntaxError( | ||||
| @ -84,8 +88,8 @@ export class DirectiveNormalizer { | ||||
| 
 | ||||
|     if (isDefined(prenormData.preserveWhitespaces) && | ||||
|         typeof prenormData.preserveWhitespaces !== 'boolean') { | ||||
|       throw syntaxError( | ||||
|           `The preserveWhitespaces option for component ${stringify(prenormData.componentType)} must be a boolean`); | ||||
|       throw syntaxError(`The preserveWhitespaces option for component ${ | ||||
|           stringify(prenormData.componentType)} must be a boolean`);
 | ||||
|     } | ||||
| 
 | ||||
|     return SyncAsync.then( | ||||
| @ -101,7 +105,7 @@ export class DirectiveNormalizer { | ||||
|       template = prenomData.template; | ||||
|       templateUrl = prenomData.moduleUrl; | ||||
|     } else { | ||||
|       templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl !); | ||||
|       templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl!); | ||||
|       template = this._fetch(templateUrl); | ||||
|     } | ||||
|     return SyncAsync.then( | ||||
| @ -112,7 +116,7 @@ export class DirectiveNormalizer { | ||||
|       prenormData: PrenormalizedTemplateMetadata, template: string, | ||||
|       templateAbsUrl: string): PreparsedTemplate { | ||||
|     const isInline = !!prenormData.template; | ||||
|     const interpolationConfig = InterpolationConfig.fromArray(prenormData.interpolation !); | ||||
|     const interpolationConfig = InterpolationConfig.fromArray(prenormData.interpolation!); | ||||
|     const templateUrl = templateSourceUrl( | ||||
|         {reference: prenormData.ngModuleType}, {type: {reference: prenormData.componentType}}, | ||||
|         {isInline, templateUrl: templateAbsUrl}); | ||||
| @ -140,8 +144,12 @@ export class DirectiveNormalizer { | ||||
|                           .styleUrls; | ||||
|     return { | ||||
|       template, | ||||
|       templateUrl: templateAbsUrl, isInline, | ||||
|       htmlAst: rootNodesAndErrors, styles, inlineStyleUrls, styleUrls, | ||||
|       templateUrl: templateAbsUrl, | ||||
|       isInline, | ||||
|       htmlAst: rootNodesAndErrors, | ||||
|       styles, | ||||
|       inlineStyleUrls, | ||||
|       styleUrls, | ||||
|       ngContentSelectors: visitor.ngContentSelectors, | ||||
|     }; | ||||
|   } | ||||
| @ -172,7 +180,7 @@ export class DirectiveNormalizer { | ||||
|     const styleUrls = preparsedTemplate.styleUrls; | ||||
| 
 | ||||
|     const externalStylesheets = styleUrls.map(styleUrl => { | ||||
|       const stylesheet = stylesheets.get(styleUrl) !; | ||||
|       const stylesheet = stylesheets.get(styleUrl)!; | ||||
|       const styles = [...stylesheet.styles]; | ||||
|       this._inlineStyles(stylesheet.styleUrls, stylesheets, styles); | ||||
|       return new CompileStylesheetMetadata({moduleUrl: styleUrl, styles: styles}); | ||||
| @ -190,11 +198,14 @@ export class DirectiveNormalizer { | ||||
|       encapsulation, | ||||
|       template: preparsedTemplate.template, | ||||
|       templateUrl: preparsedTemplate.templateUrl, | ||||
|       htmlAst: preparsedTemplate.htmlAst, styles, styleUrls, | ||||
|       htmlAst: preparsedTemplate.htmlAst, | ||||
|       styles, | ||||
|       styleUrls, | ||||
|       ngContentSelectors: preparsedTemplate.ngContentSelectors, | ||||
|       animations: prenormData.animations, | ||||
|       interpolation: prenormData.interpolation, | ||||
|       isInline: preparsedTemplate.isInline, externalStylesheets, | ||||
|       isInline: preparsedTemplate.isInline, | ||||
|       externalStylesheets, | ||||
|       preserveWhitespaces: preserveWhitespacesDefault( | ||||
|           prenormData.preserveWhitespaces, this._config.preserveWhitespaces), | ||||
|     }); | ||||
| @ -204,7 +215,7 @@ export class DirectiveNormalizer { | ||||
|       styleUrls: string[], stylesheets: Map<string, CompileStylesheetMetadata>, | ||||
|       targetStyles: string[]) { | ||||
|     styleUrls.forEach(styleUrl => { | ||||
|       const stylesheet = stylesheets.get(styleUrl) !; | ||||
|       const stylesheet = stylesheets.get(styleUrl)!; | ||||
|       stylesheet.styles.forEach(style => targetStyles.push(style)); | ||||
|       this._inlineStyles(stylesheet.styleUrls, stylesheets, targetStyles); | ||||
|     }); | ||||
| @ -232,7 +243,7 @@ export class DirectiveNormalizer { | ||||
|   } | ||||
| 
 | ||||
|   private _normalizeStylesheet(stylesheet: CompileStylesheetMetadata): CompileStylesheetMetadata { | ||||
|     const moduleUrl = stylesheet.moduleUrl !; | ||||
|     const moduleUrl = stylesheet.moduleUrl!; | ||||
|     const allStyleUrls = stylesheet.styleUrls.filter(isStyleUrlResolvable) | ||||
|                              .map(url => this._urlResolver.resolve(moduleUrl, url)); | ||||
| 
 | ||||
| @ -297,13 +308,21 @@ class TemplatePreparseVisitor implements html.Visitor { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(ast: html.Expansion, context: any): any { html.visitAll(this, ast.cases); } | ||||
|   visitExpansion(ast: html.Expansion, context: any): any { | ||||
|     html.visitAll(this, ast.cases); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(ast: html.ExpansionCase, context: any): any { | ||||
|     html.visitAll(this, ast.expression); | ||||
|   } | ||||
| 
 | ||||
|   visitComment(ast: html.Comment, context: any): any { return null; } | ||||
|   visitAttribute(ast: html.Attribute, context: any): any { return null; } | ||||
|   visitText(ast: html.Text, context: any): any { return null; } | ||||
|   visitComment(ast: html.Comment, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
|   visitAttribute(ast: html.Attribute, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
|   visitText(ast: html.Text, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import {CompileReflector} from './compile_reflector'; | ||||
| import {Component, Directive, Type, createComponent, createContentChild, createContentChildren, createDirective, createHostBinding, createHostListener, createInput, createOutput, createViewChild, createViewChildren} from './core'; | ||||
| import {Component, createComponent, createContentChild, createContentChildren, createDirective, createHostBinding, createHostListener, createInput, createOutput, createViewChild, createViewChildren, Directive, Type} from './core'; | ||||
| import {resolveForwardRef, splitAtColon, stringify} from './util'; | ||||
| 
 | ||||
| const QUERY_METADATA_IDENTIFIERS = [ | ||||
| @ -109,7 +109,9 @@ export class DirectiveResolver { | ||||
|     return this._merge(dm, inputs, outputs, host, queries, guards, directiveType); | ||||
|   } | ||||
| 
 | ||||
|   private _extractPublicName(def: string) { return splitAtColon(def, [null !, def])[1].trim(); } | ||||
|   private _extractPublicName(def: string) { | ||||
|     return splitAtColon(def, [null!, def])[1].trim(); | ||||
|   } | ||||
| 
 | ||||
|   private _dedupeBindings(bindings: string[]): string[] { | ||||
|     const names = new Set<string>(); | ||||
| @ -168,7 +170,8 @@ export class DirectiveResolver { | ||||
|         host: mergedHost, | ||||
|         exportAs: directive.exportAs, | ||||
|         queries: mergedQueries, | ||||
|         providers: directive.providers, guards | ||||
|         providers: directive.providers, | ||||
|         guards | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -31,8 +31,12 @@ export class AST { | ||||
|        * Absolute location of the expression AST in a source code file. | ||||
|        */ | ||||
|       public sourceSpan: AbsoluteSourceSpan) {} | ||||
|   visit(visitor: AstVisitor, context: any = null): any { return null; } | ||||
|   toString(): string { return 'AST'; } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { | ||||
|     return null; | ||||
|   } | ||||
|   toString(): string { | ||||
|     return 'AST'; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -54,8 +58,12 @@ export class Quote extends AST { | ||||
|       public uninterpretedExpression: string, public location: any) { | ||||
|     super(span, sourceSpan); | ||||
|   } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { return visitor.visitQuote(this, context); } | ||||
|   toString(): string { return 'Quote'; } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { | ||||
|     return visitor.visitQuote(this, context); | ||||
|   } | ||||
|   toString(): string { | ||||
|     return 'Quote'; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class EmptyExpr extends AST { | ||||
| @ -77,7 +85,9 @@ export class Chain extends AST { | ||||
|   constructor(span: ParseSpan, sourceSpan: AbsoluteSourceSpan, public expressions: any[]) { | ||||
|     super(span, sourceSpan); | ||||
|   } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { return visitor.visitChain(this, context); } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { | ||||
|     return visitor.visitChain(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Conditional extends AST { | ||||
| @ -148,7 +158,9 @@ export class BindingPipe extends AST { | ||||
|       public args: any[], public nameSpan: AbsoluteSourceSpan) { | ||||
|     super(span, sourceSpan); | ||||
|   } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { return visitor.visitPipe(this, context); } | ||||
|   visit(visitor: AstVisitor, context: any = null): any { | ||||
|     return visitor.visitPipe(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class LiteralPrimitive extends AST { | ||||
| @ -280,7 +292,9 @@ export class ASTWithSource extends AST { | ||||
|     } | ||||
|     return this.ast.visit(visitor, context); | ||||
|   } | ||||
|   toString(): string { return `${this.source} in ${this.location}`; } | ||||
|   toString(): string { | ||||
|     return `${this.source} in ${this.location}`; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -302,7 +316,7 @@ export class ASTWithSource extends AST { | ||||
|  * the LHS of a HTML attribute to the expression in the RHS. All other bindings | ||||
|  * in the example above are derived solely from the RHS. | ||||
|  */ | ||||
| export type TemplateBinding = VariableBinding | ExpressionBinding; | ||||
| export type TemplateBinding = VariableBinding|ExpressionBinding; | ||||
| 
 | ||||
| export class VariableBinding { | ||||
|   /** | ||||
| @ -379,7 +393,9 @@ export class RecursiveAstVisitor implements AstVisitor { | ||||
|     this.visit(ast.left, context); | ||||
|     this.visit(ast.right, context); | ||||
|   } | ||||
|   visitChain(ast: Chain, context: any): any { this.visitAll(ast.expressions, context); } | ||||
|   visitChain(ast: Chain, context: any): any { | ||||
|     this.visitAll(ast.expressions, context); | ||||
|   } | ||||
|   visitConditional(ast: Conditional, context: any): any { | ||||
|     this.visit(ast.condition, context); | ||||
|     this.visit(ast.trueExp, context); | ||||
| @ -411,15 +427,23 @@ export class RecursiveAstVisitor implements AstVisitor { | ||||
|   visitLiteralArray(ast: LiteralArray, context: any): any { | ||||
|     this.visitAll(ast.expressions, context); | ||||
|   } | ||||
|   visitLiteralMap(ast: LiteralMap, context: any): any { this.visitAll(ast.values, context); } | ||||
|   visitLiteralMap(ast: LiteralMap, context: any): any { | ||||
|     this.visitAll(ast.values, context); | ||||
|   } | ||||
|   visitLiteralPrimitive(ast: LiteralPrimitive, context: any): any {} | ||||
|   visitMethodCall(ast: MethodCall, context: any): any { | ||||
|     this.visit(ast.receiver, context); | ||||
|     this.visitAll(ast.args, context); | ||||
|   } | ||||
|   visitPrefixNot(ast: PrefixNot, context: any): any { this.visit(ast.expression, context); } | ||||
|   visitNonNullAssert(ast: NonNullAssert, context: any): any { this.visit(ast.expression, context); } | ||||
|   visitPropertyRead(ast: PropertyRead, context: any): any { this.visit(ast.receiver, context); } | ||||
|   visitPrefixNot(ast: PrefixNot, context: any): any { | ||||
|     this.visit(ast.expression, context); | ||||
|   } | ||||
|   visitNonNullAssert(ast: NonNullAssert, context: any): any { | ||||
|     this.visit(ast.expression, context); | ||||
|   } | ||||
|   visitPropertyRead(ast: PropertyRead, context: any): any { | ||||
|     this.visit(ast.receiver, context); | ||||
|   } | ||||
|   visitPropertyWrite(ast: PropertyWrite, context: any): any { | ||||
|     this.visit(ast.receiver, context); | ||||
|     this.visit(ast.value, context); | ||||
| @ -441,7 +465,9 @@ export class RecursiveAstVisitor implements AstVisitor { | ||||
| } | ||||
| 
 | ||||
| export class AstTransformer implements AstVisitor { | ||||
|   visitImplicitReceiver(ast: ImplicitReceiver, context: any): AST { return ast; } | ||||
|   visitImplicitReceiver(ast: ImplicitReceiver, context: any): AST { | ||||
|     return ast; | ||||
|   } | ||||
| 
 | ||||
|   visitInterpolation(ast: Interpolation, context: any): AST { | ||||
|     return new Interpolation(ast.span, ast.sourceSpan, ast.strings, this.visitAll(ast.expressions)); | ||||
| @ -476,7 +502,7 @@ export class AstTransformer implements AstVisitor { | ||||
| 
 | ||||
|   visitFunctionCall(ast: FunctionCall, context: any): AST { | ||||
|     return new FunctionCall( | ||||
|         ast.span, ast.sourceSpan, ast.target !.visit(this), this.visitAll(ast.args)); | ||||
|         ast.span, ast.sourceSpan, ast.target!.visit(this), this.visitAll(ast.args)); | ||||
|   } | ||||
| 
 | ||||
|   visitLiteralArray(ast: LiteralArray, context: any): AST { | ||||
| @ -542,7 +568,9 @@ export class AstTransformer implements AstVisitor { | ||||
| // A transformer that only creates new nodes if the transformer makes a change or
 | ||||
| // a change is made a child node.
 | ||||
| export class AstMemoryEfficientTransformer implements AstVisitor { | ||||
|   visitImplicitReceiver(ast: ImplicitReceiver, context: any): AST { return ast; } | ||||
|   visitImplicitReceiver(ast: ImplicitReceiver, context: any): AST { | ||||
|     return ast; | ||||
|   } | ||||
| 
 | ||||
|   visitInterpolation(ast: Interpolation, context: any): Interpolation { | ||||
|     const expressions = this.visitAll(ast.expressions); | ||||
| @ -551,7 +579,9 @@ export class AstMemoryEfficientTransformer implements AstVisitor { | ||||
|     return ast; | ||||
|   } | ||||
| 
 | ||||
|   visitLiteralPrimitive(ast: LiteralPrimitive, context: any): AST { return ast; } | ||||
|   visitLiteralPrimitive(ast: LiteralPrimitive, context: any): AST { | ||||
|     return ast; | ||||
|   } | ||||
| 
 | ||||
|   visitPropertyRead(ast: PropertyRead, context: any): AST { | ||||
|     const receiver = ast.receiver.visit(this); | ||||
| @ -704,7 +734,9 @@ export class AstMemoryEfficientTransformer implements AstVisitor { | ||||
|     return ast; | ||||
|   } | ||||
| 
 | ||||
|   visitQuote(ast: Quote, context: any): AST { return ast; } | ||||
|   visitQuote(ast: Quote, context: any): AST { | ||||
|     return ast; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Bindings
 | ||||
|  | ||||
| @ -42,37 +42,61 @@ export class Token { | ||||
|     return this.type == TokenType.Character && this.numValue == code; | ||||
|   } | ||||
| 
 | ||||
|   isNumber(): boolean { return this.type == TokenType.Number; } | ||||
|   isNumber(): boolean { | ||||
|     return this.type == TokenType.Number; | ||||
|   } | ||||
| 
 | ||||
|   isString(): boolean { return this.type == TokenType.String; } | ||||
|   isString(): boolean { | ||||
|     return this.type == TokenType.String; | ||||
|   } | ||||
| 
 | ||||
|   isOperator(operator: string): boolean { | ||||
|     return this.type == TokenType.Operator && this.strValue == operator; | ||||
|   } | ||||
| 
 | ||||
|   isIdentifier(): boolean { return this.type == TokenType.Identifier; } | ||||
|   isIdentifier(): boolean { | ||||
|     return this.type == TokenType.Identifier; | ||||
|   } | ||||
| 
 | ||||
|   isKeyword(): boolean { return this.type == TokenType.Keyword; } | ||||
|   isKeyword(): boolean { | ||||
|     return this.type == TokenType.Keyword; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordLet(): boolean { return this.type == TokenType.Keyword && this.strValue == 'let'; } | ||||
|   isKeywordLet(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'let'; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordAs(): boolean { return this.type == TokenType.Keyword && this.strValue == 'as'; } | ||||
|   isKeywordAs(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'as'; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordNull(): boolean { return this.type == TokenType.Keyword && this.strValue == 'null'; } | ||||
|   isKeywordNull(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'null'; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordUndefined(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'undefined'; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordTrue(): boolean { return this.type == TokenType.Keyword && this.strValue == 'true'; } | ||||
|   isKeywordTrue(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'true'; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordFalse(): boolean { return this.type == TokenType.Keyword && this.strValue == 'false'; } | ||||
|   isKeywordFalse(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'false'; | ||||
|   } | ||||
| 
 | ||||
|   isKeywordThis(): boolean { return this.type == TokenType.Keyword && this.strValue == 'this'; } | ||||
|   isKeywordThis(): boolean { | ||||
|     return this.type == TokenType.Keyword && this.strValue == 'this'; | ||||
|   } | ||||
| 
 | ||||
|   isError(): boolean { return this.type == TokenType.Error; } | ||||
|   isError(): boolean { | ||||
|     return this.type == TokenType.Error; | ||||
|   } | ||||
| 
 | ||||
|   toNumber(): number { return this.type == TokenType.Number ? this.numValue : -1; } | ||||
|   toNumber(): number { | ||||
|     return this.type == TokenType.Number ? this.numValue : -1; | ||||
|   } | ||||
| 
 | ||||
|   toString(): string|null { | ||||
|     switch (this.type) { | ||||
|  | ||||
| @ -10,8 +10,8 @@ import * as chars from '../chars'; | ||||
| import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../ml_parser/interpolation_config'; | ||||
| import {escapeRegExp} from '../util'; | ||||
| 
 | ||||
| import {AST, ASTWithSource, AbsoluteSourceSpan, AstVisitor, Binary, BindingPipe, Chain, Conditional, EmptyExpr, ExpressionBinding, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralMapKey, LiteralPrimitive, MethodCall, NonNullAssert, ParseSpan, ParserError, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead, TemplateBinding, TemplateBindingIdentifier, VariableBinding} from './ast'; | ||||
| import {EOF, Lexer, Token, TokenType, isIdentifier, isQuote} from './lexer'; | ||||
| import {AbsoluteSourceSpan, AST, AstVisitor, ASTWithSource, Binary, BindingPipe, Chain, Conditional, EmptyExpr, ExpressionBinding, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralMapKey, LiteralPrimitive, MethodCall, NonNullAssert, ParserError, ParseSpan, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead, TemplateBinding, TemplateBindingIdentifier, VariableBinding} from './ast'; | ||||
| import {EOF, isIdentifier, isQuote, Lexer, Token, TokenType} from './lexer'; | ||||
| 
 | ||||
| export class SplitInterpolation { | ||||
|   constructor(public strings: string[], public expressions: string[], public offsets: number[]) {} | ||||
| @ -253,7 +253,8 @@ export class Parser { | ||||
|     const parts = input.split(regexp); | ||||
|     if (parts.length > 1) { | ||||
|       this._reportError( | ||||
|           `Got interpolation (${interpolationConfig.start}${interpolationConfig.end}) where expression was expected`, | ||||
|           `Got interpolation (${interpolationConfig.start}${ | ||||
|               interpolationConfig.end}) where expression was expected`,
 | ||||
|           input, | ||||
|           `at column ${this._findInterpolationErrorColumn(parts, 1, interpolationConfig)} in`, | ||||
|           location); | ||||
| @ -300,7 +301,9 @@ export class _ParseAST { | ||||
|     return i < this.tokens.length ? this.tokens[i] : EOF; | ||||
|   } | ||||
| 
 | ||||
|   get next(): Token { return this.peek(0); } | ||||
|   get next(): Token { | ||||
|     return this.peek(0); | ||||
|   } | ||||
| 
 | ||||
|   get inputIndex(): number { | ||||
|     return (this.index < this.tokens.length) ? this.next.index + this.offset : | ||||
| @ -310,7 +313,9 @@ export class _ParseAST { | ||||
|   /** | ||||
|    * Returns the absolute offset of the start of the current token. | ||||
|    */ | ||||
|   get currentAbsoluteOffset(): number { return this.absoluteOffset + this.inputIndex; } | ||||
|   get currentAbsoluteOffset(): number { | ||||
|     return this.absoluteOffset + this.inputIndex; | ||||
|   } | ||||
| 
 | ||||
|   span(start: number) { | ||||
|     // `end` is either the
 | ||||
| @ -326,10 +331,12 @@ export class _ParseAST { | ||||
|     if (!this.sourceSpanCache.has(serial)) { | ||||
|       this.sourceSpanCache.set(serial, this.span(start).toAbsolute(this.absoluteOffset)); | ||||
|     } | ||||
|     return this.sourceSpanCache.get(serial) !; | ||||
|     return this.sourceSpanCache.get(serial)!; | ||||
|   } | ||||
| 
 | ||||
|   advance() { this.index++; } | ||||
|   advance() { | ||||
|     this.index++; | ||||
|   } | ||||
| 
 | ||||
|   consumeOptionalCharacter(code: number): boolean { | ||||
|     if (this.next.isCharacter(code)) { | ||||
| @ -340,8 +347,12 @@ export class _ParseAST { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   peekKeywordLet(): boolean { return this.next.isKeywordLet(); } | ||||
|   peekKeywordAs(): boolean { return this.next.isKeywordAs(); } | ||||
|   peekKeywordLet(): boolean { | ||||
|     return this.next.isKeywordLet(); | ||||
|   } | ||||
|   peekKeywordAs(): boolean { | ||||
|     return this.next.isKeywordAs(); | ||||
|   } | ||||
| 
 | ||||
|   expectCharacter(code: number) { | ||||
|     if (this.consumeOptionalCharacter(code)) return; | ||||
| @ -428,7 +439,9 @@ export class _ParseAST { | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   parseExpression(): AST { return this.parseConditional(); } | ||||
|   parseExpression(): AST { | ||||
|     return this.parseConditional(); | ||||
|   } | ||||
| 
 | ||||
|   parseConditional(): AST { | ||||
|     const start = this.inputIndex; | ||||
| @ -984,8 +997,8 @@ export class _ParseAST { | ||||
|            (this.rbracesExpected <= 0 || !n.isCharacter(chars.$RBRACE)) && | ||||
|            (this.rbracketsExpected <= 0 || !n.isCharacter(chars.$RBRACKET))) { | ||||
|       if (this.next.isError()) { | ||||
|         this.errors.push(new ParserError( | ||||
|             this.next.toString() !, this.input, this.locationText(), this.location)); | ||||
|         this.errors.push( | ||||
|             new ParserError(this.next.toString()!, this.input, this.locationText(), this.location)); | ||||
|       } | ||||
|       this.advance(); | ||||
|       n = this.next; | ||||
| @ -1014,9 +1027,13 @@ class SimpleExpressionChecker implements AstVisitor { | ||||
| 
 | ||||
|   visitFunctionCall(ast: FunctionCall, context: any) {} | ||||
| 
 | ||||
|   visitLiteralArray(ast: LiteralArray, context: any) { this.visitAll(ast.expressions); } | ||||
|   visitLiteralArray(ast: LiteralArray, context: any) { | ||||
|     this.visitAll(ast.expressions); | ||||
|   } | ||||
| 
 | ||||
|   visitLiteralMap(ast: LiteralMap, context: any) { this.visitAll(ast.values); } | ||||
|   visitLiteralMap(ast: LiteralMap, context: any) { | ||||
|     this.visitAll(ast.values); | ||||
|   } | ||||
| 
 | ||||
|   visitBinary(ast: Binary, context: any) {} | ||||
| 
 | ||||
| @ -1026,13 +1043,17 @@ class SimpleExpressionChecker implements AstVisitor { | ||||
| 
 | ||||
|   visitConditional(ast: Conditional, context: any) {} | ||||
| 
 | ||||
|   visitPipe(ast: BindingPipe, context: any) { this.errors.push('pipes'); } | ||||
|   visitPipe(ast: BindingPipe, context: any) { | ||||
|     this.errors.push('pipes'); | ||||
|   } | ||||
| 
 | ||||
|   visitKeyedRead(ast: KeyedRead, context: any) {} | ||||
| 
 | ||||
|   visitKeyedWrite(ast: KeyedWrite, context: any) {} | ||||
| 
 | ||||
|   visitAll(asts: any[]): any[] { return asts.map(node => node.visit(this)); } | ||||
|   visitAll(asts: any[]): any[] { | ||||
|     return asts.map(node => node.visit(this)); | ||||
|   } | ||||
| 
 | ||||
|   visitChain(ast: Chain, context: any) {} | ||||
| 
 | ||||
| @ -1052,5 +1073,7 @@ class IvySimpleExpressionChecker extends SimpleExpressionChecker { | ||||
|     ast.right.visit(this); | ||||
|   } | ||||
| 
 | ||||
|   visitPrefixNot(ast: PrefixNot, context: any) { ast.expression.visit(this); } | ||||
|   visitPrefixNot(ast: PrefixNot, context: any) { | ||||
|     ast.expression.visit(this); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -48,7 +48,9 @@ export function computeDecimalDigest(message: i18n.Message): string { | ||||
|  * @internal | ||||
|  */ | ||||
| class _SerializerVisitor implements i18n.Visitor { | ||||
|   visitText(text: i18n.Text, context: any): any { return text.value; } | ||||
|   visitText(text: i18n.Text, context: any): any { | ||||
|     return text.value; | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: i18n.Container, context: any): any { | ||||
|     return `[${container.children.map(child => child.visit(this)).join(', ')}]`; | ||||
| @ -63,7 +65,8 @@ class _SerializerVisitor implements i18n.Visitor { | ||||
|   visitTagPlaceholder(ph: i18n.TagPlaceholder, context: any): any { | ||||
|     return ph.isVoid ? | ||||
|         `<ph tag name="${ph.startName}"/>` : | ||||
|         `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`; | ||||
|         `<ph tag name="${ph.startName}">${ | ||||
|             ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`; | ||||
|   } | ||||
| 
 | ||||
|   visitPlaceholder(ph: i18n.Placeholder, context: any): any { | ||||
|  | ||||
| @ -78,11 +78,11 @@ export class Extractor { | ||||
|               // Template URL points to either an HTML or TS file depending on
 | ||||
|               // whether the file is used with `templateUrl:` or `template:`,
 | ||||
|               // respectively.
 | ||||
|               const templateUrl = compMeta.template !.templateUrl !; | ||||
|               const templateUrl = compMeta.template !.templateUrl!; | ||||
|               const interpolationConfig = | ||||
|                   InterpolationConfig.fromArray(compMeta.template !.interpolation); | ||||
|               errors.push(...this.messageBundle.updateFromTemplate( | ||||
|                   html, templateUrl, interpolationConfig) !); | ||||
|                   html, templateUrl, interpolationConfig)!); | ||||
|             }); | ||||
|           }); | ||||
| 
 | ||||
|  | ||||
| @ -9,8 +9,9 @@ | ||||
| import * as html from '../ml_parser/ast'; | ||||
| import {InterpolationConfig} from '../ml_parser/interpolation_config'; | ||||
| import {ParseTreeResult} from '../ml_parser/parser'; | ||||
| 
 | ||||
| import * as i18n from './i18n_ast'; | ||||
| import {I18nMessageFactory, createI18nMessageFactory} from './i18n_parser'; | ||||
| import {createI18nMessageFactory, I18nMessageFactory} from './i18n_parser'; | ||||
| import {I18nError} from './parse_util'; | ||||
| import {TranslationBundle} from './translation_bundle'; | ||||
| 
 | ||||
| @ -56,44 +57,44 @@ enum _VisitorMode { | ||||
|  */ | ||||
| class _Visitor implements html.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _depth !: number; | ||||
|   private _depth!: number; | ||||
| 
 | ||||
|   // <el i18n>...</el>
 | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _inI18nNode !: boolean; | ||||
|   private _inI18nNode!: boolean; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _inImplicitNode !: boolean; | ||||
|   private _inImplicitNode!: boolean; | ||||
| 
 | ||||
|   // <!--i18n-->...<!--/i18n-->
 | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _inI18nBlock !: boolean; | ||||
|   private _inI18nBlock!: boolean; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _blockMeaningAndDesc !: string; | ||||
|   private _blockMeaningAndDesc!: string; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _blockChildren !: html.Node[]; | ||||
|   private _blockChildren!: html.Node[]; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _blockStartDepth !: number; | ||||
|   private _blockStartDepth!: number; | ||||
| 
 | ||||
|   // {<icu message>}
 | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _inIcu !: boolean; | ||||
|   private _inIcu!: boolean; | ||||
| 
 | ||||
|   // set to void 0 when not in a section
 | ||||
|   private _msgCountAtSectionStart: number|undefined; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _mode !: _VisitorMode; | ||||
|   private _mode!: _VisitorMode; | ||||
| 
 | ||||
|   // _VisitorMode.Extract only
 | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _messages !: i18n.Message[]; | ||||
|   private _messages!: i18n.Message[]; | ||||
| 
 | ||||
|   // _VisitorMode.Merge only
 | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _translations !: TranslationBundle; | ||||
|   private _translations!: TranslationBundle; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _createI18nMessage !: I18nMessageFactory; | ||||
|   private _createI18nMessage!: I18nMessageFactory; | ||||
| 
 | ||||
| 
 | ||||
|   constructor(private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {} | ||||
| @ -123,7 +124,7 @@ class _Visitor implements html.Visitor { | ||||
|     this._translations = translations; | ||||
| 
 | ||||
|     // Construct a single fake root element
 | ||||
|     const wrapper = new html.Element('wrapper', [], nodes, undefined !, undefined, undefined); | ||||
|     const wrapper = new html.Element('wrapper', [], nodes, undefined!, undefined, undefined); | ||||
| 
 | ||||
|     const translatedNode = wrapper.visit(this, null); | ||||
| 
 | ||||
| @ -193,14 +194,14 @@ class _Visitor implements html.Visitor { | ||||
|             i18nCommentsWarned = true; | ||||
|             const details = comment.sourceSpan.details ? `, ${comment.sourceSpan.details}` : ''; | ||||
|             // TODO(ocombe): use a log service once there is a public one available
 | ||||
|             console.warn( | ||||
|                 `I18n comments are deprecated, use an <ng-container> element instead (${comment.sourceSpan.start}${details})`); | ||||
|             console.warn(`I18n comments are deprecated, use an <ng-container> element instead (${ | ||||
|                 comment.sourceSpan.start}${details})`);
 | ||||
|           } | ||||
|           this._inI18nBlock = true; | ||||
|           this._blockStartDepth = this._depth; | ||||
|           this._blockChildren = []; | ||||
|           this._blockMeaningAndDesc = | ||||
|               comment.value !.replace(_I18N_COMMENT_PREFIX_REGEXP, '').trim(); | ||||
|               comment.value!.replace(_I18N_COMMENT_PREFIX_REGEXP, '').trim(); | ||||
|           this._openTranslatableSection(comment); | ||||
|         } | ||||
|       } else { | ||||
| @ -208,7 +209,7 @@ class _Visitor implements html.Visitor { | ||||
|           if (this._depth == this._blockStartDepth) { | ||||
|             this._closeTranslatableSection(comment, this._blockChildren); | ||||
|             this._inI18nBlock = false; | ||||
|             const message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc) !; | ||||
|             const message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc)!; | ||||
|             // merge attributes in sections
 | ||||
|             const nodes = this._translateMessage(comment, message); | ||||
|             return html.visitAll(this, nodes); | ||||
| @ -234,7 +235,7 @@ class _Visitor implements html.Visitor { | ||||
|     const wasInI18nNode = this._inI18nNode; | ||||
|     const wasInImplicitNode = this._inImplicitNode; | ||||
|     let childNodes: html.Node[] = []; | ||||
|     let translatedChildNodes: html.Node[] = undefined !; | ||||
|     let translatedChildNodes: html.Node[] = undefined!; | ||||
| 
 | ||||
|     // Extract:
 | ||||
|     // - top level nodes with the (implicit) "i18n" attribute if not already in a section
 | ||||
| @ -249,7 +250,7 @@ class _Visitor implements html.Visitor { | ||||
|     if (!this._isInTranslatableSection && !this._inIcu) { | ||||
|       if (i18nAttr || isTopLevelImplicit) { | ||||
|         this._inI18nNode = true; | ||||
|         const message = this._addMessage(el.children, i18nMeta) !; | ||||
|         const message = this._addMessage(el.children, i18nMeta)!; | ||||
|         translatedChildNodes = this._translateMessage(el, message); | ||||
|       } | ||||
| 
 | ||||
| @ -400,12 +401,14 @@ class _Visitor implements html.Visitor { | ||||
|           } else { | ||||
|             this._reportError( | ||||
|                 el, | ||||
|                 `Unexpected translation for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`); | ||||
|                 `Unexpected translation for attribute "${attr.name}" (id="${ | ||||
|                     id || this._translations.digest(message)}")`);
 | ||||
|           } | ||||
|         } else { | ||||
|           this._reportError( | ||||
|               el, | ||||
|               `Translation unavailable for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`); | ||||
|               `Translation unavailable for attribute "${attr.name}" (id="${ | ||||
|                   id || this._translations.digest(message)}")`);
 | ||||
|         } | ||||
|       } else { | ||||
|         translatedAttributes.push(attr); | ||||
| @ -476,7 +479,7 @@ class _Visitor implements html.Visitor { | ||||
|         0); | ||||
| 
 | ||||
|     if (significantChildren == 1) { | ||||
|       for (let i = this._messages.length - 1; i >= startIndex !; i--) { | ||||
|       for (let i = this._messages.length - 1; i >= startIndex!; i--) { | ||||
|         const ast = this._messages[i].nodes; | ||||
|         if (!(ast.length == 1 && ast[0] instanceof i18n.Text)) { | ||||
|           this._messages.splice(i, 1); | ||||
| @ -489,7 +492,7 @@ class _Visitor implements html.Visitor { | ||||
|   } | ||||
| 
 | ||||
|   private _reportError(node: html.Node, msg: string): void { | ||||
|     this._errors.push(new I18nError(node.sourceSpan !, msg)); | ||||
|     this._errors.push(new I18nError(node.sourceSpan!, msg)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -57,24 +57,30 @@ export interface Node { | ||||
| export class Text implements Node { | ||||
|   constructor(public value: string, public sourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context?: any): any { return visitor.visitText(this, context); } | ||||
|   visit(visitor: Visitor, context?: any): any { | ||||
|     return visitor.visitText(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // TODO(vicb): do we really need this node (vs an array) ?
 | ||||
| export class Container implements Node { | ||||
|   constructor(public children: Node[], public sourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context?: any): any { return visitor.visitContainer(this, context); } | ||||
|   visit(visitor: Visitor, context?: any): any { | ||||
|     return visitor.visitContainer(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Icu implements Node { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   public expressionPlaceholder !: string; | ||||
|   public expressionPlaceholder!: string; | ||||
|   constructor( | ||||
|       public expression: string, public type: string, public cases: {[k: string]: Node}, | ||||
|       public sourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context?: any): any { return visitor.visitIcu(this, context); } | ||||
|   visit(visitor: Visitor, context?: any): any { | ||||
|     return visitor.visitIcu(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class TagPlaceholder implements Node { | ||||
| @ -83,13 +89,17 @@ export class TagPlaceholder implements Node { | ||||
|       public closeName: string, public children: Node[], public isVoid: boolean, | ||||
|       public sourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context?: any): any { return visitor.visitTagPlaceholder(this, context); } | ||||
|   visit(visitor: Visitor, context?: any): any { | ||||
|     return visitor.visitTagPlaceholder(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Placeholder implements Node { | ||||
|   constructor(public value: string, public name: string, public sourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context?: any): any { return visitor.visitPlaceholder(this, context); } | ||||
|   visit(visitor: Visitor, context?: any): any { | ||||
|     return visitor.visitPlaceholder(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class IcuPlaceholder implements Node { | ||||
| @ -97,7 +107,9 @@ export class IcuPlaceholder implements Node { | ||||
|   previousMessage?: Message; | ||||
|   constructor(public value: Icu, public name: string, public sourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context?: any): any { return visitor.visitIcuPlaceholder(this, context); } | ||||
|   visit(visitor: Visitor, context?: any): any { | ||||
|     return visitor.visitIcuPlaceholder(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -106,7 +118,7 @@ export class IcuPlaceholder implements Node { | ||||
|  * This information is either a `Message`, which indicates it is the root of an i18n message, or a | ||||
|  * `Node`, which indicates is it part of a containing `Message`. | ||||
|  */ | ||||
| export type I18nMeta = Message | Node; | ||||
| export type I18nMeta = Message|Node; | ||||
| 
 | ||||
| export interface Visitor { | ||||
|   visitText(text: Text, context?: any): any; | ||||
| @ -119,7 +131,9 @@ export interface Visitor { | ||||
| 
 | ||||
| // Clone the AST
 | ||||
| export class CloneVisitor implements Visitor { | ||||
|   visitText(text: Text, context?: any): Text { return new Text(text.value, text.sourceSpan); } | ||||
|   visitText(text: Text, context?: any): Text { | ||||
|     return new Text(text.value, text.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: Container, context?: any): Container { | ||||
|     const children = container.children.map(n => n.visit(this, context)); | ||||
| @ -158,7 +172,9 @@ export class RecurseVisitor implements Visitor { | ||||
|   } | ||||
| 
 | ||||
|   visitIcu(icu: Icu, context?: any): any { | ||||
|     Object.keys(icu.cases).forEach(k => { icu.cases[k].visit(this); }); | ||||
|     Object.keys(icu.cases).forEach(k => { | ||||
|       icu.cases[k].visit(this); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   visitTagPlaceholder(ph: TagPlaceholder, context?: any): any { | ||||
|  | ||||
| @ -83,7 +83,7 @@ class _I18nVisitor implements html.Visitor { | ||||
|     const isVoid: boolean = getHtmlTagDefinition(el.name).isVoid; | ||||
|     const startPhName = | ||||
|         context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid); | ||||
|     context.placeholderToContent[startPhName] = el.sourceSpan !.toString(); | ||||
|     context.placeholderToContent[startPhName] = el.sourceSpan!.toString(); | ||||
| 
 | ||||
|     let closePhName = ''; | ||||
| 
 | ||||
| @ -93,7 +93,7 @@ class _I18nVisitor implements html.Visitor { | ||||
|     } | ||||
| 
 | ||||
|     const node = new i18n.TagPlaceholder( | ||||
|         el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan !); | ||||
|         el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan!); | ||||
|     return context.visitNodeFn(el, node); | ||||
|   } | ||||
| 
 | ||||
| @ -103,7 +103,7 @@ class _I18nVisitor implements html.Visitor { | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: html.Text, context: I18nMessageVisitorContext): i18n.Node { | ||||
|     const node = this._visitTextWithInterpolation(text.value, text.sourceSpan !, context); | ||||
|     const node = this._visitTextWithInterpolation(text.value, text.sourceSpan!, context); | ||||
|     return context.visitNodeFn(text, node); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -47,7 +47,9 @@ export class MessageBundle { | ||||
| 
 | ||||
|   // Return the message in the internal format
 | ||||
|   // The public (serialized) format might be different, see the `write` method.
 | ||||
|   getMessages(): i18n.Message[] { return this._messages; } | ||||
|   getMessages(): i18n.Message[] { | ||||
|     return this._messages; | ||||
|   } | ||||
| 
 | ||||
|   write(serializer: Serializer, filterSources?: (path: string) => string): string { | ||||
|     const messages: {[id: string]: i18n.Message} = {}; | ||||
| @ -88,18 +90,18 @@ class MapPlaceholderNames extends i18n.CloneVisitor { | ||||
|   } | ||||
| 
 | ||||
|   visitTagPlaceholder(ph: i18n.TagPlaceholder, mapper: PlaceholderMapper): i18n.TagPlaceholder { | ||||
|     const startName = mapper.toPublicName(ph.startName) !; | ||||
|     const closeName = ph.closeName ? mapper.toPublicName(ph.closeName) ! : ph.closeName; | ||||
|     const startName = mapper.toPublicName(ph.startName)!; | ||||
|     const closeName = ph.closeName ? mapper.toPublicName(ph.closeName)! : ph.closeName; | ||||
|     const children = ph.children.map(n => n.visit(this, mapper)); | ||||
|     return new i18n.TagPlaceholder( | ||||
|         ph.tag, ph.attrs, startName, closeName, children, ph.isVoid, ph.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitPlaceholder(ph: i18n.Placeholder, mapper: PlaceholderMapper): i18n.Placeholder { | ||||
|     return new i18n.Placeholder(ph.value, mapper.toPublicName(ph.name) !, ph.sourceSpan); | ||||
|     return new i18n.Placeholder(ph.value, mapper.toPublicName(ph.name)!, ph.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitIcuPlaceholder(ph: i18n.IcuPlaceholder, mapper: PlaceholderMapper): i18n.IcuPlaceholder { | ||||
|     return new i18n.IcuPlaceholder(ph.value, mapper.toPublicName(ph.name) !, ph.sourceSpan); | ||||
|     return new i18n.IcuPlaceholder(ph.value, mapper.toPublicName(ph.name)!, ph.sourceSpan); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -12,5 +12,7 @@ import {ParseError, ParseSourceSpan} from '../parse_util'; | ||||
|  * An i18n error. | ||||
|  */ | ||||
| export class I18nError extends ParseError { | ||||
|   constructor(span: ParseSourceSpan, msg: string) { super(span, msg); } | ||||
|   constructor(span: ParseSourceSpan, msg: string) { | ||||
|     super(span, msg); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -106,7 +106,9 @@ export class PlaceholderRegistry { | ||||
|     return start + strAttrs + end; | ||||
|   } | ||||
| 
 | ||||
|   private _hashClosingTag(tag: string): string { return this._hashTag(`/${tag}`, {}, false); } | ||||
|   private _hashClosingTag(tag: string): string { | ||||
|     return this._hashTag(`/${tag}`, {}, false); | ||||
|   } | ||||
| 
 | ||||
|   private _generateUniqueName(base: string): string { | ||||
|     const seen = this._placeHolderNameCounts.hasOwnProperty(base); | ||||
|  | ||||
| @ -15,13 +15,15 @@ export abstract class Serializer { | ||||
|   abstract write(messages: i18n.Message[], locale: string|null): string; | ||||
| 
 | ||||
|   abstract load(content: string, url: string): | ||||
|       {locale: string | null, i18nNodesByMsgId: {[msgId: string]: i18n.Node[]}}; | ||||
|       {locale: string|null, i18nNodesByMsgId: {[msgId: string]: i18n.Node[]}}; | ||||
| 
 | ||||
|   abstract digest(message: i18n.Message): string; | ||||
| 
 | ||||
|   // Creates a name mapper, see `PlaceholderMapper`
 | ||||
|   // Returning `null` means that no name mapping is used.
 | ||||
|   createNameMapper(message: i18n.Message): PlaceholderMapper|null { return null; } | ||||
|   createNameMapper(message: i18n.Message): PlaceholderMapper|null { | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -61,7 +63,9 @@ export class SimplePlaceholderMapper extends i18n.RecurseVisitor implements Plac | ||||
|                                                               null; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: i18n.Text, context?: any): any { return null; } | ||||
|   visitText(text: i18n.Text, context?: any): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitTagPlaceholder(ph: i18n.TagPlaceholder, context?: any): any { | ||||
|     this.visitPlaceholderName(ph.startName); | ||||
| @ -69,7 +73,9 @@ export class SimplePlaceholderMapper extends i18n.RecurseVisitor implements Plac | ||||
|     this.visitPlaceholderName(ph.closeName); | ||||
|   } | ||||
| 
 | ||||
|   visitPlaceholder(ph: i18n.Placeholder, context?: any): any { this.visitPlaceholderName(ph.name); } | ||||
|   visitPlaceholder(ph: i18n.Placeholder, context?: any): any { | ||||
|     this.visitPlaceholderName(ph.name); | ||||
|   } | ||||
| 
 | ||||
|   visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): any { | ||||
|     this.visitPlaceholderName(ph.name); | ||||
|  | ||||
| @ -46,9 +46,9 @@ export class Xliff extends Serializer { | ||||
|             new xml.CR(10), | ||||
|             new xml.Tag( | ||||
|                 _CONTEXT_TAG, {'context-type': 'sourcefile'}, [new xml.Text(source.filePath)]), | ||||
|             new xml.CR(10), new xml.Tag( | ||||
|                                 _CONTEXT_TAG, {'context-type': 'linenumber'}, | ||||
|                                 [new xml.Text(`${source.startLine}`)]), | ||||
|             new xml.CR(10), | ||||
|             new xml.Tag(_CONTEXT_TAG, {'context-type': 'linenumber'}, [new xml.Text( | ||||
|                                                                           `${source.startLine}`)]), | ||||
|             new xml.CR(8)); | ||||
|         contextTags.push(new xml.CR(8), contextGroupTag); | ||||
|       }); | ||||
| @ -112,14 +112,18 @@ export class Xliff extends Serializer { | ||||
|       throw new Error(`xliff parse errors:\n${errors.join('\n')}`); | ||||
|     } | ||||
| 
 | ||||
|     return {locale: locale !, i18nNodesByMsgId}; | ||||
|     return {locale: locale!, i18nNodesByMsgId}; | ||||
|   } | ||||
| 
 | ||||
|   digest(message: i18n.Message): string { return digest(message); } | ||||
|   digest(message: i18n.Message): string { | ||||
|     return digest(message); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class _WriteVisitor implements i18n.Visitor { | ||||
|   visitText(text: i18n.Text, context?: any): xml.Node[] { return [new xml.Text(text.value)]; } | ||||
|   visitText(text: i18n.Text, context?: any): xml.Node[] { | ||||
|     return [new xml.Text(text.value)]; | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: i18n.Container, context?: any): xml.Node[] { | ||||
|     const nodes: xml.Node[] = []; | ||||
| @ -161,8 +165,8 @@ class _WriteVisitor implements i18n.Visitor { | ||||
|   } | ||||
| 
 | ||||
|   visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): xml.Node[] { | ||||
|     const equivText = | ||||
|         `{${ph.value.expression}, ${ph.value.type}, ${Object.keys(ph.value.cases).map((value: string) => value + ' {...}').join(' ')}}`; | ||||
|     const equivText = `{${ph.value.expression}, ${ph.value.type}, ${ | ||||
|         Object.keys(ph.value.cases).map((value: string) => value + ' {...}').join(' ')}}`;
 | ||||
|     return [new xml.Tag(_PLACEHOLDER_TAG, {id: ph.name, 'equiv-text': equivText})]; | ||||
|   } | ||||
| 
 | ||||
| @ -175,11 +179,11 @@ class _WriteVisitor implements i18n.Visitor { | ||||
| // Extract messages as xml nodes from the xliff file
 | ||||
| class XliffParser implements ml.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _unitMlString !: string | null; | ||||
|   private _unitMlString!: string|null; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _msgIdToHtml !: {[msgId: string]: string}; | ||||
|   private _msgIdToHtml!: {[msgId: string]: string}; | ||||
|   private _locale: string|null = null; | ||||
| 
 | ||||
|   parse(xliff: string, url: string) { | ||||
| @ -201,7 +205,7 @@ class XliffParser implements ml.Visitor { | ||||
|   visitElement(element: ml.Element, context: any): any { | ||||
|     switch (element.name) { | ||||
|       case _UNIT_TAG: | ||||
|         this._unitMlString = null !; | ||||
|         this._unitMlString = null!; | ||||
|         const idAttr = element.attrs.find((attr) => attr.name === 'id'); | ||||
|         if (!idAttr) { | ||||
|           this._addError(element, `<${_UNIT_TAG}> misses the "id" attribute`); | ||||
| @ -227,9 +231,9 @@ class XliffParser implements ml.Visitor { | ||||
|         break; | ||||
| 
 | ||||
|       case _TARGET_TAG: | ||||
|         const innerTextStart = element.startSourceSpan !.end.offset; | ||||
|         const innerTextEnd = element.endSourceSpan !.start.offset; | ||||
|         const content = element.startSourceSpan !.start.file.content; | ||||
|         const innerTextStart = element.startSourceSpan!.end.offset; | ||||
|         const innerTextEnd = element.endSourceSpan!.start.offset; | ||||
|         const content = element.startSourceSpan!.start.file.content; | ||||
|         const innerText = content.slice(innerTextStart, innerTextEnd); | ||||
|         this._unitMlString = innerText; | ||||
|         break; | ||||
| @ -260,14 +264,14 @@ class XliffParser implements ml.Visitor { | ||||
|   visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {} | ||||
| 
 | ||||
|   private _addError(node: ml.Node, message: string): void { | ||||
|     this._errors.push(new I18nError(node.sourceSpan !, message)); | ||||
|     this._errors.push(new I18nError(node.sourceSpan!, message)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Convert ml nodes (xliff syntax) to i18n nodes
 | ||||
| class XmlToI18n implements ml.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
| 
 | ||||
|   convert(message: string, url: string) { | ||||
|     const xmlIcu = new XmlParser().parse(message, url, {tokenizeExpansionForms: true}); | ||||
| @ -283,13 +287,15 @@ class XmlToI18n implements ml.Visitor { | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan !); } | ||||
|   visitText(text: ml.Text, context: any) { | ||||
|     return new i18n.Text(text.value, text.sourceSpan!); | ||||
|   } | ||||
| 
 | ||||
|   visitElement(el: ml.Element, context: any): i18n.Placeholder|ml.Node[]|null { | ||||
|     if (el.name === _PLACEHOLDER_TAG) { | ||||
|       const nameAttr = el.attrs.find((attr) => attr.name === 'id'); | ||||
|       if (nameAttr) { | ||||
|         return new i18n.Placeholder('', nameAttr.value, el.sourceSpan !); | ||||
|         return new i18n.Placeholder('', nameAttr.value, el.sourceSpan!); | ||||
|       } | ||||
| 
 | ||||
|       this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "id" attribute`); | ||||
| @ -326,7 +332,7 @@ class XmlToI18n implements ml.Visitor { | ||||
|   visitAttribute(attribute: ml.Attribute, context: any) {} | ||||
| 
 | ||||
|   private _addError(node: ml.Node, message: string): void { | ||||
|     this._errors.push(new I18nError(node.sourceSpan !, message)); | ||||
|     this._errors.push(new I18nError(node.sourceSpan!, message)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -54,8 +54,8 @@ export class Xliff2 extends Serializer { | ||||
| 
 | ||||
|       message.sources.forEach((source: i18n.MessageSpan) => { | ||||
|         notes.children.push(new xml.CR(8), new xml.Tag('note', {category: 'location'}, [ | ||||
|           new xml.Text( | ||||
|               `${source.filePath}:${source.startLine}${source.endLine !== source.startLine ? ',' + source.endLine : ''}`) | ||||
|           new xml.Text(`${source.filePath}:${source.startLine}${ | ||||
|               source.endLine !== source.startLine ? ',' + source.endLine : ''}`)
 | ||||
|         ])); | ||||
|       }); | ||||
| 
 | ||||
| @ -105,17 +105,21 @@ export class Xliff2 extends Serializer { | ||||
|       throw new Error(`xliff2 parse errors:\n${errors.join('\n')}`); | ||||
|     } | ||||
| 
 | ||||
|     return {locale: locale !, i18nNodesByMsgId}; | ||||
|     return {locale: locale!, i18nNodesByMsgId}; | ||||
|   } | ||||
| 
 | ||||
|   digest(message: i18n.Message): string { return decimalDigest(message); } | ||||
|   digest(message: i18n.Message): string { | ||||
|     return decimalDigest(message); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class _WriteVisitor implements i18n.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _nextPlaceholderId !: number; | ||||
|   private _nextPlaceholderId!: number; | ||||
| 
 | ||||
|   visitText(text: i18n.Text, context?: any): xml.Node[] { return [new xml.Text(text.value)]; } | ||||
|   visitText(text: i18n.Text, context?: any): xml.Node[] { | ||||
|     return [new xml.Text(text.value)]; | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: i18n.Container, context?: any): xml.Node[] { | ||||
|     const nodes: xml.Node[] = []; | ||||
| @ -192,11 +196,11 @@ class _WriteVisitor implements i18n.Visitor { | ||||
| // Extract messages as xml nodes from the xliff file
 | ||||
| class Xliff2Parser implements ml.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _unitMlString !: string | null; | ||||
|   private _unitMlString!: string|null; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _msgIdToHtml !: {[msgId: string]: string}; | ||||
|   private _msgIdToHtml!: {[msgId: string]: string}; | ||||
|   private _locale: string|null = null; | ||||
| 
 | ||||
|   parse(xliff: string, url: string) { | ||||
| @ -242,9 +246,9 @@ class Xliff2Parser implements ml.Visitor { | ||||
|         break; | ||||
| 
 | ||||
|       case _TARGET_TAG: | ||||
|         const innerTextStart = element.startSourceSpan !.end.offset; | ||||
|         const innerTextEnd = element.endSourceSpan !.start.offset; | ||||
|         const content = element.startSourceSpan !.start.file.content; | ||||
|         const innerTextStart = element.startSourceSpan!.end.offset; | ||||
|         const innerTextEnd = element.endSourceSpan!.start.offset; | ||||
|         const content = element.startSourceSpan!.start.file.content; | ||||
|         const innerText = content.slice(innerTextStart, innerTextEnd); | ||||
|         this._unitMlString = innerText; | ||||
|         break; | ||||
| @ -290,7 +294,7 @@ class Xliff2Parser implements ml.Visitor { | ||||
| // Convert ml nodes (xliff syntax) to i18n nodes
 | ||||
| class XmlToI18n implements ml.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
| 
 | ||||
|   convert(message: string, url: string) { | ||||
|     const xmlIcu = new XmlParser().parse(message, url, {tokenizeExpansionForms: true}); | ||||
| @ -306,7 +310,9 @@ class XmlToI18n implements ml.Visitor { | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan); } | ||||
|   visitText(text: ml.Text, context: any) { | ||||
|     return new i18n.Text(text.value, text.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitElement(el: ml.Element, context: any): i18n.Node[]|null { | ||||
|     switch (el.name) { | ||||
|  | ||||
| @ -57,10 +57,10 @@ export class Xmb extends Serializer { | ||||
| 
 | ||||
|       let sourceTags: xml.Tag[] = []; | ||||
|       message.sources.forEach((source: i18n.MessageSpan) => { | ||||
|         sourceTags.push(new xml.Tag(_SOURCE_TAG, {}, [ | ||||
|           new xml.Text( | ||||
|               `${source.filePath}:${source.startLine}${source.endLine !== source.startLine ? ',' + source.endLine : ''}`) | ||||
|         ])); | ||||
|         sourceTags.push(new xml.Tag( | ||||
|             _SOURCE_TAG, {}, | ||||
|             [new xml.Text(`${source.filePath}:${source.startLine}${ | ||||
|                 source.endLine !== source.startLine ? ',' + source.endLine : ''}`)]));
 | ||||
|       }); | ||||
| 
 | ||||
|       rootNode.children.push( | ||||
| @ -85,7 +85,9 @@ export class Xmb extends Serializer { | ||||
|     throw new Error('Unsupported'); | ||||
|   } | ||||
| 
 | ||||
|   digest(message: i18n.Message): string { return digest(message); } | ||||
|   digest(message: i18n.Message): string { | ||||
|     return digest(message); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   createNameMapper(message: i18n.Message): PlaceholderMapper { | ||||
| @ -94,7 +96,9 @@ export class Xmb extends Serializer { | ||||
| } | ||||
| 
 | ||||
| class _Visitor implements i18n.Visitor { | ||||
|   visitText(text: i18n.Text, context?: any): xml.Node[] { return [new xml.Text(text.value)]; } | ||||
|   visitText(text: i18n.Text, context?: any): xml.Node[] { | ||||
|     return [new xml.Text(text.value)]; | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: i18n.Container, context: any): xml.Node[] { | ||||
|     const nodes: xml.Node[] = []; | ||||
|  | ||||
| @ -25,7 +25,9 @@ class _Visitor implements IVisitor { | ||||
|     return `<${tag.name}${strAttrs}>${strChildren.join('')}</${tag.name}>`; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: Text): string { return text.value; } | ||||
|   visitText(text: Text): string { | ||||
|     return text.value; | ||||
|   } | ||||
| 
 | ||||
|   visitDeclaration(decl: Declaration): string { | ||||
|     return `<?xml${this._serializeAttributes(decl.attrs)} ?>`; | ||||
| @ -47,7 +49,9 @@ export function serialize(nodes: Node[]): string { | ||||
|   return nodes.map((node: Node): string => node.visit(_visitor)).join(''); | ||||
| } | ||||
| 
 | ||||
| export interface Node { visit(visitor: IVisitor): any; } | ||||
| export interface Node { | ||||
|   visit(visitor: IVisitor): any; | ||||
| } | ||||
| 
 | ||||
| export class Declaration implements Node { | ||||
|   public attrs: {[k: string]: string} = {}; | ||||
| @ -58,13 +62,17 @@ export class Declaration implements Node { | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   visit(visitor: IVisitor): any { return visitor.visitDeclaration(this); } | ||||
|   visit(visitor: IVisitor): any { | ||||
|     return visitor.visitDeclaration(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Doctype implements Node { | ||||
|   constructor(public rootTag: string, public dtd: string) {} | ||||
| 
 | ||||
|   visit(visitor: IVisitor): any { return visitor.visitDoctype(this); } | ||||
|   visit(visitor: IVisitor): any { | ||||
|     return visitor.visitDoctype(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Tag implements Node { | ||||
| @ -78,18 +86,26 @@ export class Tag implements Node { | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   visit(visitor: IVisitor): any { return visitor.visitTag(this); } | ||||
|   visit(visitor: IVisitor): any { | ||||
|     return visitor.visitTag(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Text implements Node { | ||||
|   value: string; | ||||
|   constructor(unescapedValue: string) { this.value = escapeXml(unescapedValue); } | ||||
|   constructor(unescapedValue: string) { | ||||
|     this.value = escapeXml(unescapedValue); | ||||
|   } | ||||
| 
 | ||||
|   visit(visitor: IVisitor): any { return visitor.visitText(this); } | ||||
|   visit(visitor: IVisitor): any { | ||||
|     return visitor.visitText(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class CR extends Text { | ||||
|   constructor(ws: number = 0) { super(`\n${new Array(ws + 1).join(' ')}`); } | ||||
|   constructor(ws: number = 0) { | ||||
|     super(`\n${new Array(ws + 1).join(' ')}`); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const _ESCAPED_CHARS: [RegExp, string][] = [ | ||||
|  | ||||
| @ -19,7 +19,9 @@ const _TRANSLATION_TAG = 'translation'; | ||||
| const _PLACEHOLDER_TAG = 'ph'; | ||||
| 
 | ||||
| export class Xtb extends Serializer { | ||||
|   write(messages: i18n.Message[], locale: string|null): string { throw new Error('Unsupported'); } | ||||
|   write(messages: i18n.Message[], locale: string|null): string { | ||||
|     throw new Error('Unsupported'); | ||||
|   } | ||||
| 
 | ||||
|   load(content: string, url: string): | ||||
|       {locale: string, i18nNodesByMsgId: {[msgId: string]: i18n.Node[]}} { | ||||
| @ -49,10 +51,12 @@ export class Xtb extends Serializer { | ||||
|       throw new Error(`xtb parse errors:\n${errors.join('\n')}`); | ||||
|     } | ||||
| 
 | ||||
|     return {locale: locale !, i18nNodesByMsgId}; | ||||
|     return {locale: locale!, i18nNodesByMsgId}; | ||||
|   } | ||||
| 
 | ||||
|   digest(message: i18n.Message): string { return digest(message); } | ||||
|   digest(message: i18n.Message): string { | ||||
|     return digest(message); | ||||
|   } | ||||
| 
 | ||||
|   createNameMapper(message: i18n.Message): PlaceholderMapper { | ||||
|     return new SimplePlaceholderMapper(message, toPublicName); | ||||
| @ -68,18 +72,20 @@ function createLazyProperty(messages: any, id: string, valueFn: () => any) { | ||||
|       Object.defineProperty(messages, id, {enumerable: true, value}); | ||||
|       return value; | ||||
|     }, | ||||
|     set: _ => { throw new Error('Could not overwrite an XTB translation'); }, | ||||
|     set: _ => { | ||||
|       throw new Error('Could not overwrite an XTB translation'); | ||||
|     }, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| // Extract messages as xml nodes from the xtb file
 | ||||
| class XtbParser implements ml.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _bundleDepth !: number; | ||||
|   private _bundleDepth!: number; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _msgIdToHtml !: {[msgId: string]: string}; | ||||
|   private _msgIdToHtml!: {[msgId: string]: string}; | ||||
|   private _locale: string|null = null; | ||||
| 
 | ||||
|   parse(xtb: string, url: string) { | ||||
| @ -124,10 +130,10 @@ class XtbParser implements ml.Visitor { | ||||
|           if (this._msgIdToHtml.hasOwnProperty(id)) { | ||||
|             this._addError(element, `Duplicated translations for msg ${id}`); | ||||
|           } else { | ||||
|             const innerTextStart = element.startSourceSpan !.end.offset; | ||||
|             const innerTextEnd = element.endSourceSpan !.start.offset; | ||||
|             const content = element.startSourceSpan !.start.file.content; | ||||
|             const innerText = content.slice(innerTextStart !, innerTextEnd !); | ||||
|             const innerTextStart = element.startSourceSpan!.end.offset; | ||||
|             const innerTextEnd = element.endSourceSpan!.start.offset; | ||||
|             const content = element.startSourceSpan!.start.file.content; | ||||
|             const innerText = content.slice(innerTextStart!, innerTextEnd!); | ||||
|             this._msgIdToHtml[id] = innerText; | ||||
|           } | ||||
|         } | ||||
| @ -149,14 +155,14 @@ class XtbParser implements ml.Visitor { | ||||
|   visitExpansionCase(expansionCase: ml.ExpansionCase, context: any): any {} | ||||
| 
 | ||||
|   private _addError(node: ml.Node, message: string): void { | ||||
|     this._errors.push(new I18nError(node.sourceSpan !, message)); | ||||
|     this._errors.push(new I18nError(node.sourceSpan!, message)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Convert ml nodes (xtb syntax) to i18n nodes
 | ||||
| class XmlToI18n implements ml.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _errors !: I18nError[]; | ||||
|   private _errors!: I18nError[]; | ||||
| 
 | ||||
|   convert(message: string, url: string) { | ||||
|     const xmlIcu = new XmlParser().parse(message, url, {tokenizeExpansionForms: true}); | ||||
| @ -172,7 +178,9 @@ class XmlToI18n implements ml.Visitor { | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: ml.Text, context: any) { return new i18n.Text(text.value, text.sourceSpan !); } | ||||
|   visitText(text: ml.Text, context: any) { | ||||
|     return new i18n.Text(text.value, text.sourceSpan!); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(icu: ml.Expansion, context: any) { | ||||
|     const caseMap: {[value: string]: i18n.Node} = {}; | ||||
| @ -195,7 +203,7 @@ class XmlToI18n implements ml.Visitor { | ||||
|     if (el.name === _PLACEHOLDER_TAG) { | ||||
|       const nameAttr = el.attrs.find((attr) => attr.name === 'name'); | ||||
|       if (nameAttr) { | ||||
|         return new i18n.Placeholder('', nameAttr.value, el.sourceSpan !); | ||||
|         return new i18n.Placeholder('', nameAttr.value, el.sourceSpan!); | ||||
|       } | ||||
| 
 | ||||
|       this._addError(el, `<${_PLACEHOLDER_TAG}> misses the "name" attribute`); | ||||
| @ -210,6 +218,6 @@ class XmlToI18n implements ml.Visitor { | ||||
|   visitAttribute(attribute: ml.Attribute, context: any) {} | ||||
| 
 | ||||
|   private _addError(node: ml.Node, message: string): void { | ||||
|     this._errors.push(new I18nError(node.sourceSpan !, message)); | ||||
|     this._errors.push(new I18nError(node.sourceSpan!, message)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -30,7 +30,7 @@ export class TranslationBundle { | ||||
|       missingTranslationStrategy: MissingTranslationStrategy = MissingTranslationStrategy.Warning, | ||||
|       console?: Console) { | ||||
|     this._i18nToHtml = new I18nToHtmlVisitor( | ||||
|         _i18nNodesByMsgId, locale, digest, mapperFactory !, missingTranslationStrategy, console); | ||||
|         _i18nNodesByMsgId, locale, digest, mapperFactory!, missingTranslationStrategy, console); | ||||
|   } | ||||
| 
 | ||||
|   // Creates a `TranslationBundle` by parsing the given `content` with the `serializer`.
 | ||||
| @ -40,7 +40,7 @@ export class TranslationBundle { | ||||
|       console?: Console): TranslationBundle { | ||||
|     const {locale, i18nNodesByMsgId} = serializer.load(content, url); | ||||
|     const digestFn = (m: i18n.Message) => serializer.digest(m); | ||||
|     const mapperFactory = (m: i18n.Message) => serializer.createNameMapper(m) !; | ||||
|     const mapperFactory = (m: i18n.Message) => serializer.createNameMapper(m)!; | ||||
|     return new TranslationBundle( | ||||
|         i18nNodesByMsgId, locale, digestFn, mapperFactory, missingTranslationStrategy, console); | ||||
|   } | ||||
| @ -56,16 +56,18 @@ export class TranslationBundle { | ||||
|     return html.nodes; | ||||
|   } | ||||
| 
 | ||||
|   has(srcMsg: i18n.Message): boolean { return this.digest(srcMsg) in this._i18nNodesByMsgId; } | ||||
|   has(srcMsg: i18n.Message): boolean { | ||||
|     return this.digest(srcMsg) in this._i18nNodesByMsgId; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| class I18nToHtmlVisitor implements i18n.Visitor { | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _srcMsg !: i18n.Message; | ||||
|   private _srcMsg!: i18n.Message; | ||||
|   private _contextStack: {msg: i18n.Message, mapper: (name: string) => string}[] = []; | ||||
|   private _errors: I18nError[] = []; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _mapper !: (name: string) => string; | ||||
|   private _mapper!: (name: string) => string; | ||||
| 
 | ||||
|   constructor( | ||||
|       private _i18nNodesByMsgId: {[msgId: string]: i18n.Node[]} = {}, private _locale: string|null, | ||||
| @ -166,7 +168,7 @@ class I18nToHtmlVisitor implements i18n.Visitor { | ||||
|       // When there is a translation use its nodes as the source
 | ||||
|       // And create a mapper to convert serialized placeholder names to internal names
 | ||||
|       nodes = this._i18nNodesByMsgId[id]; | ||||
|       this._mapper = (name: string) => mapper ? mapper.toInternalName(name) ! : name; | ||||
|       this._mapper = (name: string) => mapper ? mapper.toInternalName(name)! : name; | ||||
|     } else { | ||||
|       // When no translation has been found
 | ||||
|       // - report an error / a warning / nothing,
 | ||||
| @ -185,7 +187,7 @@ class I18nToHtmlVisitor implements i18n.Visitor { | ||||
|       this._mapper = (name: string) => name; | ||||
|     } | ||||
|     const text = nodes.map(node => node.visit(this)).join(''); | ||||
|     const context = this._contextStack.pop() !; | ||||
|     const context = this._contextStack.pop()!; | ||||
|     this._srcMsg = context.msg; | ||||
|     this._mapper = context.mapper; | ||||
|     return text; | ||||
|  | ||||
| @ -121,7 +121,7 @@ export class InjectableCompiler { | ||||
| 
 | ||||
|   compile(injectable: CompileInjectableMetadata, ctx: OutputContext): void { | ||||
|     if (this.alwaysGenerateDef || injectable.providedIn !== undefined) { | ||||
|       const className = identifierName(injectable.type) !; | ||||
|       const className = identifierName(injectable.type)!; | ||||
|       const clazz = new o.ClassStmt( | ||||
|           className, null, | ||||
|           [ | ||||
|  | ||||
| @ -8,8 +8,8 @@ | ||||
| 
 | ||||
| import {Identifiers} from './identifiers'; | ||||
| import * as o from './output/output_ast'; | ||||
| import {R3DependencyMetadata, R3FactoryDelegateType, R3FactoryMetadata, R3FactoryTarget, compileFactoryFunction} from './render3/r3_factory'; | ||||
| import {R3Reference, mapToMapExpression, typeWithParameters} from './render3/util'; | ||||
| import {compileFactoryFunction, R3DependencyMetadata, R3FactoryDelegateType, R3FactoryMetadata, R3FactoryTarget} from './render3/r3_factory'; | ||||
| import {mapToMapExpression, R3Reference, typeWithParameters} from './render3/util'; | ||||
| 
 | ||||
| export interface InjectableDef { | ||||
|   expression: o.Expression; | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
|  * found in the LICENSE file at https://angular.io/license
 | ||||
|  */ | ||||
| 
 | ||||
| import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeSummary, CompileProviderMetadata, CompileStylesheetMetadata, CompileTypeSummary, ProviderMeta, ProxyClass, identifierName, ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata'; | ||||
| import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeSummary, CompileProviderMetadata, CompileStylesheetMetadata, CompileTypeSummary, identifierName, ngModuleJitUrl, ProviderMeta, ProxyClass, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata'; | ||||
| import {CompileReflector} from '../compile_reflector'; | ||||
| import {CompilerConfig} from '../config'; | ||||
| import {ConstantPool} from '../constant_pool'; | ||||
| @ -20,7 +20,7 @@ import {CompiledStylesheet, StyleCompiler} from '../style_compiler'; | ||||
| import {SummaryResolver} from '../summary_resolver'; | ||||
| import {TemplateAst} from '../template_parser/template_ast'; | ||||
| import {TemplateParser} from '../template_parser/template_parser'; | ||||
| import {Console, OutputContext, SyncAsync, stringify} from '../util'; | ||||
| import {Console, OutputContext, stringify, SyncAsync} from '../util'; | ||||
| import {ViewCompiler} from '../view_compiler/view_compiler'; | ||||
| 
 | ||||
| export interface ModuleWithComponentFactories { | ||||
| @ -97,7 +97,9 @@ export class JitCompiler { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   hasAotSummary(ref: Type) { return !!this._summaryResolver.resolveSummary(ref); } | ||||
|   hasAotSummary(ref: Type) { | ||||
|     return !!this._summaryResolver.resolveSummary(ref); | ||||
|   } | ||||
| 
 | ||||
|   private _filterJitIdentifiers(ids: CompileIdentifierMetadata[]): any[] { | ||||
|     return ids.map(mod => mod.reference).filter((ref) => !this.hasAotSummary(ref)); | ||||
| @ -124,12 +126,12 @@ export class JitCompiler { | ||||
| 
 | ||||
|   private _loadModules(mainModule: any, isSync: boolean): SyncAsync<any> { | ||||
|     const loading: Promise<any>[] = []; | ||||
|     const mainNgModule = this._metadataResolver.getNgModuleMetadata(mainModule) !; | ||||
|     const mainNgModule = this._metadataResolver.getNgModuleMetadata(mainModule)!; | ||||
|     // Note: for runtime compilation, we want to transitively compile all modules,
 | ||||
|     // so we also need to load the declared directives / pipes for all nested modules.
 | ||||
|     this._filterJitIdentifiers(mainNgModule.transitiveModule.modules).forEach((nestedNgModule) => { | ||||
|       // getNgModuleMetadata only returns null if the value passed in is not an NgModule
 | ||||
|       const moduleMeta = this._metadataResolver.getNgModuleMetadata(nestedNgModule) !; | ||||
|       const moduleMeta = this._metadataResolver.getNgModuleMetadata(nestedNgModule)!; | ||||
|       this._filterJitIdentifiers(moduleMeta.declaredDirectives).forEach((ref) => { | ||||
|         const promise = | ||||
|             this._metadataResolver.loadDirectiveMetadata(moduleMeta.type.reference, ref, isSync); | ||||
| @ -144,9 +146,9 @@ export class JitCompiler { | ||||
|   } | ||||
| 
 | ||||
|   private _compileModule(moduleType: Type): object { | ||||
|     let ngModuleFactory = this._compiledNgModuleCache.get(moduleType) !; | ||||
|     let ngModuleFactory = this._compiledNgModuleCache.get(moduleType)!; | ||||
|     if (!ngModuleFactory) { | ||||
|       const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType) !; | ||||
|       const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType)!; | ||||
|       // Always provide a bound Compiler
 | ||||
|       const extraProviders = this.getExtraNgModuleProviders(moduleMeta.type.reference); | ||||
|       const outputCtx = createOutputContext(); | ||||
| @ -162,13 +164,13 @@ export class JitCompiler { | ||||
|    * @internal | ||||
|    */ | ||||
|   _compileComponents(mainModule: Type, allComponentFactories: object[]|null) { | ||||
|     const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule) !; | ||||
|     const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule)!; | ||||
|     const moduleByJitDirective = new Map<any, CompileNgModuleMetadata>(); | ||||
|     const templates = new Set<CompiledTemplate>(); | ||||
| 
 | ||||
|     const transJitModules = this._filterJitIdentifiers(ngModule.transitiveModule.modules); | ||||
|     transJitModules.forEach((localMod) => { | ||||
|       const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod) !; | ||||
|       const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod)!; | ||||
|       this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach((dirRef) => { | ||||
|         moduleByJitDirective.set(dirRef, localModuleMeta); | ||||
|         const dirMeta = this._metadataResolver.getDirectiveMetadata(dirRef); | ||||
| @ -184,12 +186,12 @@ export class JitCompiler { | ||||
|       }); | ||||
|     }); | ||||
|     transJitModules.forEach((localMod) => { | ||||
|       const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod) !; | ||||
|       const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod)!; | ||||
|       this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach((dirRef) => { | ||||
|         const dirMeta = this._metadataResolver.getDirectiveMetadata(dirRef); | ||||
|         if (dirMeta.isComponent) { | ||||
|           dirMeta.entryComponents.forEach((entryComponentType) => { | ||||
|             const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType) !; | ||||
|             const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType)!; | ||||
|             templates.add( | ||||
|                 this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta)); | ||||
|           }); | ||||
| @ -197,7 +199,7 @@ export class JitCompiler { | ||||
|       }); | ||||
|       localModuleMeta.entryComponents.forEach((entryComponentType) => { | ||||
|         if (!this.hasAotSummary(entryComponentType.componentType)) { | ||||
|           const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType) !; | ||||
|           const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType)!; | ||||
|           templates.add( | ||||
|               this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta)); | ||||
|         } | ||||
| @ -227,8 +229,9 @@ export class JitCompiler { | ||||
|   private _createCompiledHostTemplate(compType: Type, ngModule: CompileNgModuleMetadata): | ||||
|       CompiledTemplate { | ||||
|     if (!ngModule) { | ||||
|       throw new Error( | ||||
|           `Component ${stringify(compType)} is not part of any NgModule or the module has not been imported into your module.`); | ||||
|       throw new Error(`Component ${ | ||||
|           stringify( | ||||
|               compType)} is not part of any NgModule or the module has not been imported into your module.`);
 | ||||
|     } | ||||
|     let compiledTemplate = this._compiledHostTemplateCache.get(compType); | ||||
|     if (!compiledTemplate) { | ||||
| @ -267,7 +270,7 @@ export class JitCompiler { | ||||
|     compMeta.template !.externalStylesheets.forEach((stylesheetMeta) => { | ||||
|       const compiledStylesheet = | ||||
|           this._styleCompiler.compileStyles(createOutputContext(), compMeta, stylesheetMeta); | ||||
|       externalStylesheetsByModuleUrl.set(stylesheetMeta.moduleUrl !, compiledStylesheet); | ||||
|       externalStylesheetsByModuleUrl.set(stylesheetMeta.moduleUrl!, compiledStylesheet); | ||||
|     }); | ||||
|     this._resolveStylesCompileResult(componentStylesheet, externalStylesheetsByModuleUrl); | ||||
|     const pipes = template.ngModule.transitiveModule.pipes.map( | ||||
| @ -295,14 +298,14 @@ export class JitCompiler { | ||||
|     const pipes = ngModule.transitiveModule.pipes.map( | ||||
|         pipe => this._metadataResolver.getPipeSummary(pipe.reference)); | ||||
|     return this._templateParser.parse( | ||||
|         compMeta, compMeta.template !.htmlAst !, directives, pipes, ngModule.schemas, | ||||
|         compMeta, compMeta.template !.htmlAst!, directives, pipes, ngModule.schemas, | ||||
|         templateSourceUrl(ngModule.type, compMeta, compMeta.template !), preserveWhitespaces); | ||||
|   } | ||||
| 
 | ||||
|   private _resolveStylesCompileResult( | ||||
|       result: CompiledStylesheet, externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>) { | ||||
|     result.dependencies.forEach((dep, i) => { | ||||
|       const nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl) !; | ||||
|       const nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl)!; | ||||
|       const nestedStylesArr = this._resolveAndEvalStylesCompileResult( | ||||
|           nestedCompileResult, externalStylesheetsByModuleUrl); | ||||
|       dep.setValue(nestedStylesArr); | ||||
| @ -329,7 +332,7 @@ export class JitCompiler { | ||||
| } | ||||
| 
 | ||||
| class CompiledTemplate { | ||||
|   private _viewClass: Function = null !; | ||||
|   private _viewClass: Function = null!; | ||||
|   isCompiled = false; | ||||
| 
 | ||||
|   constructor( | ||||
|  | ||||
| @ -16,13 +16,13 @@ import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from './ml_parser/int | ||||
| import {DeclareVarStmt, Expression, LiteralExpr, Statement, StmtModifier, WrappedNodeExpr} from './output/output_ast'; | ||||
| import {JitEvaluator} from './output/output_jit'; | ||||
| import {ParseError, ParseSourceSpan, r3JitTypeSourceSpan} from './parse_util'; | ||||
| import {R3DependencyMetadata, R3FactoryTarget, R3ResolvedDependencyType, compileFactoryFunction} from './render3/r3_factory'; | ||||
| import {compileFactoryFunction, R3DependencyMetadata, R3FactoryTarget, R3ResolvedDependencyType} from './render3/r3_factory'; | ||||
| import {R3JitReflector} from './render3/r3_jit'; | ||||
| import {R3InjectorMetadata, R3NgModuleMetadata, compileInjector, compileNgModule} from './render3/r3_module_compiler'; | ||||
| import {R3PipeMetadata, compilePipeFromMetadata} from './render3/r3_pipe_compiler'; | ||||
| import {compileInjector, compileNgModule, R3InjectorMetadata, R3NgModuleMetadata} from './render3/r3_module_compiler'; | ||||
| import {compilePipeFromMetadata, R3PipeMetadata} from './render3/r3_pipe_compiler'; | ||||
| import {R3Reference} from './render3/util'; | ||||
| import {R3DirectiveMetadata, R3QueryMetadata} from './render3/view/api'; | ||||
| import {ParsedHostBindings, compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings, verifyHostBindings} from './render3/view/compiler'; | ||||
| import {compileComponentFromMetadata, compileDirectiveFromMetadata, ParsedHostBindings, parseHostBindings, verifyHostBindings} from './render3/view/compiler'; | ||||
| import {makeBindingParser, parseTemplate} from './render3/view/template'; | ||||
| import {ResourceLoader} from './resource_loader'; | ||||
| import {DomElementSchemaRegistry} from './schema/dom_element_schema_registry'; | ||||
| @ -277,7 +277,7 @@ function wrapExpression(obj: any, property: string): WrappedNodeExpr<any>|undefi | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function computeProvidedIn(providedIn: Type | string | null | undefined): Expression { | ||||
| function computeProvidedIn(providedIn: Type|string|null|undefined): Expression { | ||||
|   if (providedIn == null || typeof providedIn === 'string') { | ||||
|     return new LiteralExpr(providedIn); | ||||
|   } else { | ||||
| @ -305,8 +305,8 @@ function convertR3DependencyMetadata(facade: R3DependencyMetadataFacade): R3Depe | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| function convertR3DependencyMetadataArray(facades: R3DependencyMetadataFacade[] | null | undefined): | ||||
|     R3DependencyMetadata[]|null { | ||||
| function convertR3DependencyMetadataArray(facades: R3DependencyMetadataFacade[]|null| | ||||
|                                           undefined): R3DependencyMetadata[]|null { | ||||
|   return facades == null ? null : facades.map(convertR3DependencyMetadata); | ||||
| } | ||||
| 
 | ||||
| @ -356,13 +356,11 @@ function isOutput(value: any): value is Output { | ||||
| } | ||||
| 
 | ||||
| function parseInputOutputs(values: string[]): StringMap { | ||||
|   return values.reduce( | ||||
|       (map, value) => { | ||||
|   return values.reduce((map, value) => { | ||||
|     const [field, property] = value.split(',').map(piece => piece.trim()); | ||||
|     map[field] = property || field; | ||||
|     return map; | ||||
|       }, | ||||
|       {} as StringMap); | ||||
|   }, {} as StringMap); | ||||
| } | ||||
| 
 | ||||
| export function publishFacade(global: any) { | ||||
|  | ||||
| @ -12,7 +12,7 @@ import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions'; | ||||
| import * as cpl from './compile_metadata'; | ||||
| import {CompileReflector} from './compile_reflector'; | ||||
| import {CompilerConfig} from './config'; | ||||
| import {ChangeDetectionStrategy, Component, Directive, Injectable, ModuleWithProviders, Provider, Query, SchemaMetadata, Type, ViewEncapsulation, createAttribute, createComponent, createHost, createInject, createInjectable, createInjectionToken, createNgModule, createOptional, createSelf, createSkipSelf} from './core'; | ||||
| import {ChangeDetectionStrategy, Component, createAttribute, createComponent, createHost, createInject, createInjectable, createInjectionToken, createNgModule, createOptional, createSelf, createSkipSelf, Directive, Injectable, ModuleWithProviders, Provider, Query, SchemaMetadata, Type, ViewEncapsulation} from './core'; | ||||
| import {DirectiveNormalizer} from './directive_normalizer'; | ||||
| import {DirectiveResolver, findLast} from './directive_resolver'; | ||||
| import {Identifiers} from './identifiers'; | ||||
| @ -23,7 +23,7 @@ import {PipeResolver} from './pipe_resolver'; | ||||
| import {ElementSchemaRegistry} from './schema/element_schema_registry'; | ||||
| import {CssSelector} from './selector'; | ||||
| import {SummaryResolver} from './summary_resolver'; | ||||
| import {Console, SyncAsync, ValueTransformer, isPromise, noUndefined, resolveForwardRef, stringify, syntaxError, visitValue} from './util'; | ||||
| import {Console, isPromise, noUndefined, resolveForwardRef, stringify, SyncAsync, syntaxError, ValueTransformer, visitValue} from './util'; | ||||
| 
 | ||||
| export type ErrorCollector = (error: any, type?: any) => void; | ||||
| 
 | ||||
| @ -55,7 +55,9 @@ export class CompileMetadataResolver { | ||||
|       private _staticSymbolCache: StaticSymbolCache, private _reflector: CompileReflector, | ||||
|       private _errorCollector?: ErrorCollector) {} | ||||
| 
 | ||||
|   getReflector(): CompileReflector { return this._reflector; } | ||||
|   getReflector(): CompileReflector { | ||||
|     return this._reflector; | ||||
|   } | ||||
| 
 | ||||
|   clearCacheFor(type: Type) { | ||||
|     const dirMeta = this._directiveCache.get(type); | ||||
| @ -176,7 +178,7 @@ export class CompileMetadataResolver { | ||||
|     } | ||||
|     // Note: ! is ok here as this method should only be called with normalized directive
 | ||||
|     // metadata, which always fills in the selector.
 | ||||
|     const template = CssSelector.parse(compMeta.selector !)[0].getMatchingElementTemplate(); | ||||
|     const template = CssSelector.parse(compMeta.selector!)[0].getMatchingElementTemplate(); | ||||
|     const templateUrl = ''; | ||||
|     const htmlAst = this._htmlParser.parse(template, templateUrl); | ||||
|     return cpl.CompileDirectiveMetadata.create({ | ||||
| @ -209,8 +211,8 @@ export class CompileMetadataResolver { | ||||
|       guards: {}, | ||||
|       viewQueries: [], | ||||
|       componentViewType: hostViewType, | ||||
|       rendererType: | ||||
|           {id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}} as object, | ||||
|       rendererType: {id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}} as | ||||
|           object, | ||||
|       entryComponents: [], | ||||
|       componentFactory: null | ||||
|     }); | ||||
| @ -221,9 +223,9 @@ export class CompileMetadataResolver { | ||||
|       return null; | ||||
|     } | ||||
|     directiveType = resolveForwardRef(directiveType); | ||||
|     const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType) !; | ||||
|     const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType)!; | ||||
| 
 | ||||
|     const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata | null) => { | ||||
|     const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata|null) => { | ||||
|       const normalizedDirMeta = new cpl.CompileDirectiveMetadata({ | ||||
|         isHost: false, | ||||
|         type: metadata.type, | ||||
| @ -248,7 +250,7 @@ export class CompileMetadataResolver { | ||||
|         template: templateMetadata | ||||
|       }); | ||||
|       if (templateMetadata) { | ||||
|         this.initComponentFactory(metadata.componentFactory !, templateMetadata.ngContentSelectors); | ||||
|         this.initComponentFactory(metadata.componentFactory!, templateMetadata.ngContentSelectors); | ||||
|       } | ||||
|       this._directiveCache.set(directiveType, normalizedDirMeta); | ||||
|       this._summaryCache.set(directiveType, normalizedDirMeta.toSummary()); | ||||
| @ -296,7 +298,7 @@ export class CompileMetadataResolver { | ||||
|     if (!dirMeta) { | ||||
|       return null; | ||||
|     } | ||||
|     let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata = undefined !; | ||||
|     let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata = undefined!; | ||||
| 
 | ||||
|     if (createComponent.isTypeOf(dirMeta)) { | ||||
|       // component
 | ||||
| @ -323,7 +325,7 @@ export class CompileMetadataResolver { | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     let changeDetectionStrategy: ChangeDetectionStrategy = null !; | ||||
|     let changeDetectionStrategy: ChangeDetectionStrategy = null!; | ||||
|     let viewProviders: cpl.CompileProviderMetadata[] = []; | ||||
|     let entryComponentMetadata: cpl.CompileEntryComponentMetadata[] = []; | ||||
|     let selector = dirMeta.selector; | ||||
| @ -331,7 +333,7 @@ export class CompileMetadataResolver { | ||||
|     if (createComponent.isTypeOf(dirMeta)) { | ||||
|       // Component
 | ||||
|       const compMeta = dirMeta as Component; | ||||
|       changeDetectionStrategy = compMeta.changeDetection !; | ||||
|       changeDetectionStrategy = compMeta.changeDetection!; | ||||
|       if (compMeta.viewProviders) { | ||||
|         viewProviders = this._getProvidersMetadata( | ||||
|             compMeta.viewProviders, entryComponentMetadata, | ||||
| @ -339,7 +341,7 @@ export class CompileMetadataResolver { | ||||
|       } | ||||
|       if (compMeta.entryComponents) { | ||||
|         entryComponentMetadata = flattenAndDedupeArray(compMeta.entryComponents) | ||||
|                                      .map((type) => this._getEntryComponentMetadata(type) !) | ||||
|                                      .map((type) => this._getEntryComponentMetadata(type)!) | ||||
|                                      .concat(entryComponentMetadata); | ||||
|       } | ||||
|       if (!selector) { | ||||
| @ -348,7 +350,7 @@ export class CompileMetadataResolver { | ||||
|     } else { | ||||
|       // Directive
 | ||||
|       if (!selector) { | ||||
|         selector = null !; | ||||
|         selector = null!; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
| @ -401,11 +403,12 @@ export class CompileMetadataResolver { | ||||
|    * This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first. | ||||
|    */ | ||||
|   getDirectiveMetadata(directiveType: any): cpl.CompileDirectiveMetadata { | ||||
|     const dirMeta = this._directiveCache.get(directiveType) !; | ||||
|     const dirMeta = this._directiveCache.get(directiveType)!; | ||||
|     if (!dirMeta) { | ||||
|       this._reportError( | ||||
|           syntaxError( | ||||
|               `Illegal state: getDirectiveMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Directive ${stringifyType(directiveType)}.`), | ||||
|               `Illegal state: getDirectiveMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Directive ${ | ||||
|                   stringifyType(directiveType)}.`),
 | ||||
|           directiveType); | ||||
|     } | ||||
|     return dirMeta; | ||||
| @ -530,7 +533,7 @@ export class CompileMetadataResolver { | ||||
| 
 | ||||
|     if (meta.imports) { | ||||
|       flattenAndDedupeArray(meta.imports).forEach((importedType) => { | ||||
|         let importedModuleType: Type = undefined !; | ||||
|         let importedModuleType: Type = undefined!; | ||||
|         if (isValidType(importedType)) { | ||||
|           importedModuleType = importedType; | ||||
|         } else if (importedType && importedType.ngModule) { | ||||
| @ -549,8 +552,9 @@ export class CompileMetadataResolver { | ||||
|           if (!alreadyCollecting) alreadyCollecting = new Set(); | ||||
|           if (alreadyCollecting.has(importedModuleType)) { | ||||
|             this._reportError( | ||||
|                 syntaxError( | ||||
|                     `${this._getTypeDescriptor(importedModuleType)} '${stringifyType(importedType)}' is imported recursively by the module '${stringifyType(moduleType)}'.`), | ||||
|                 syntaxError(`${this._getTypeDescriptor(importedModuleType)} '${ | ||||
|                     stringifyType(importedType)}' is imported recursively by the module '${ | ||||
|                     stringifyType(moduleType)}'.`),
 | ||||
|                 moduleType); | ||||
|             return; | ||||
|           } | ||||
| @ -560,8 +564,9 @@ export class CompileMetadataResolver { | ||||
|           alreadyCollecting.delete(importedModuleType); | ||||
|           if (!importedModuleSummary) { | ||||
|             this._reportError( | ||||
|                 syntaxError( | ||||
|                     `Unexpected ${this._getTypeDescriptor(importedType)} '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'. Please add a @NgModule annotation.`), | ||||
|                 syntaxError(`Unexpected ${this._getTypeDescriptor(importedType)} '${ | ||||
|                     stringifyType(importedType)}' imported by the module '${ | ||||
|                     stringifyType(moduleType)}'. Please add a @NgModule annotation.`),
 | ||||
|                 moduleType); | ||||
|             return; | ||||
|           } | ||||
| @ -569,7 +574,8 @@ export class CompileMetadataResolver { | ||||
|         } else { | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `Unexpected value '${stringifyType(importedType)}' imported by the module '${stringifyType(moduleType)}'`), | ||||
|                   `Unexpected value '${stringifyType(importedType)}' imported by the module '${ | ||||
|                       stringifyType(moduleType)}'`),
 | ||||
|               moduleType); | ||||
|           return; | ||||
|         } | ||||
| @ -581,15 +587,17 @@ export class CompileMetadataResolver { | ||||
|         if (!isValidType(exportedType)) { | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `Unexpected value '${stringifyType(exportedType)}' exported by the module '${stringifyType(moduleType)}'`), | ||||
|                   `Unexpected value '${stringifyType(exportedType)}' exported by the module '${ | ||||
|                       stringifyType(moduleType)}'`),
 | ||||
|               moduleType); | ||||
|           return; | ||||
|         } | ||||
|         if (!alreadyCollecting) alreadyCollecting = new Set(); | ||||
|         if (alreadyCollecting.has(exportedType)) { | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `${this._getTypeDescriptor(exportedType)} '${stringify(exportedType)}' is exported recursively by the module '${stringifyType(moduleType)}'`), | ||||
|               syntaxError(`${this._getTypeDescriptor(exportedType)} '${ | ||||
|                   stringify(exportedType)}' is exported recursively by the module '${ | ||||
|                   stringifyType(moduleType)}'`),
 | ||||
|               moduleType); | ||||
|           return; | ||||
|         } | ||||
| @ -612,7 +620,8 @@ export class CompileMetadataResolver { | ||||
|         if (!isValidType(declaredType)) { | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `Unexpected value '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'`), | ||||
|                   `Unexpected value '${stringifyType(declaredType)}' declared by the module '${ | ||||
|                       stringifyType(moduleType)}'`),
 | ||||
|               moduleType); | ||||
|           return; | ||||
|         } | ||||
| @ -634,8 +643,10 @@ export class CompileMetadataResolver { | ||||
|           this._addTypeToModule(declaredType, moduleType); | ||||
|         } else { | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `Unexpected ${this._getTypeDescriptor(declaredType)} '${stringifyType(declaredType)}' declared by the module '${stringifyType(moduleType)}'. Please add a @Pipe/@Directive/@Component annotation.`), | ||||
|               syntaxError(`Unexpected ${this._getTypeDescriptor(declaredType)} '${ | ||||
|                   stringifyType(declaredType)}' declared by the module '${ | ||||
|                   stringifyType( | ||||
|                       moduleType)}'. Please add a @Pipe/@Directive/@Component annotation.`),
 | ||||
|               moduleType); | ||||
|           return; | ||||
|         } | ||||
| @ -653,8 +664,9 @@ export class CompileMetadataResolver { | ||||
|         transitiveModule.addExportedPipe(exportedId); | ||||
|       } else { | ||||
|         this._reportError( | ||||
|             syntaxError( | ||||
|                 `Can't export ${this._getTypeDescriptor(exportedId.reference)} ${stringifyType(exportedId.reference)} from ${stringifyType(moduleType)} as it was neither declared nor imported!`), | ||||
|             syntaxError(`Can't export ${this._getTypeDescriptor(exportedId.reference)} ${ | ||||
|                 stringifyType(exportedId.reference)} from ${ | ||||
|                 stringifyType(moduleType)} as it was neither declared nor imported!`),
 | ||||
|             moduleType); | ||||
|         return; | ||||
|       } | ||||
| @ -670,15 +682,16 @@ export class CompileMetadataResolver { | ||||
| 
 | ||||
|     if (meta.entryComponents) { | ||||
|       entryComponents.push(...flattenAndDedupeArray(meta.entryComponents) | ||||
|                                .map(type => this._getEntryComponentMetadata(type) !)); | ||||
|                                .map(type => this._getEntryComponentMetadata(type)!)); | ||||
|     } | ||||
| 
 | ||||
|     if (meta.bootstrap) { | ||||
|       flattenAndDedupeArray(meta.bootstrap).forEach(type => { | ||||
|         if (!isValidType(type)) { | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `Unexpected value '${stringifyType(type)}' used in the bootstrap property of module '${stringifyType(moduleType)}'`), | ||||
|               syntaxError(`Unexpected value '${ | ||||
|                   stringifyType(type)}' used in the bootstrap property of module '${ | ||||
|                   stringifyType(moduleType)}'`),
 | ||||
|               moduleType); | ||||
|           return; | ||||
|         } | ||||
| @ -687,7 +700,7 @@ export class CompileMetadataResolver { | ||||
|     } | ||||
| 
 | ||||
|     entryComponents.push( | ||||
|         ...bootstrapComponents.map(type => this._getEntryComponentMetadata(type.reference) !)); | ||||
|         ...bootstrapComponents.map(type => this._getEntryComponentMetadata(type.reference)!)); | ||||
| 
 | ||||
|     if (meta.schemas) { | ||||
|       schemas.push(...flattenAndDedupeArray(meta.schemas)); | ||||
| @ -710,7 +723,7 @@ export class CompileMetadataResolver { | ||||
|     }); | ||||
| 
 | ||||
|     entryComponents.forEach((id) => transitiveModule.addEntryComponent(id)); | ||||
|     providers.forEach((provider) => transitiveModule.addProvider(provider, compileMeta !.type)); | ||||
|     providers.forEach((provider) => transitiveModule.addProvider(provider, compileMeta!.type)); | ||||
|     transitiveModule.addModule(compileMeta.type); | ||||
|     this._ngModuleCache.set(moduleType, compileMeta); | ||||
|     return compileMeta; | ||||
| @ -753,9 +766,13 @@ export class CompileMetadataResolver { | ||||
|     if (oldModule && oldModule !== moduleType) { | ||||
|       this._reportError( | ||||
|           syntaxError( | ||||
|               `Type ${stringifyType(type)} is part of the declarations of 2 modules: ${stringifyType(oldModule)} and ${stringifyType(moduleType)}! ` + | ||||
|               `Please consider moving ${stringifyType(type)} to a higher module that imports ${stringifyType(oldModule)} and ${stringifyType(moduleType)}. ` + | ||||
|               `You can also create a new NgModule that exports and includes ${stringifyType(type)} then import that NgModule in ${stringifyType(oldModule)} and ${stringifyType(moduleType)}.`), | ||||
|               `Type ${stringifyType(type)} is part of the declarations of 2 modules: ${ | ||||
|                   stringifyType(oldModule)} and ${stringifyType(moduleType)}! ` +
 | ||||
|               `Please consider moving ${stringifyType(type)} to a higher module that imports ${ | ||||
|                   stringifyType(oldModule)} and ${stringifyType(moduleType)}. ` +
 | ||||
|               `You can also create a new NgModule that exports and includes ${ | ||||
|                   stringifyType(type)} then import that NgModule in ${ | ||||
|                   stringifyType(oldModule)} and ${stringifyType(moduleType)}.`),
 | ||||
|           moduleType); | ||||
|       return; | ||||
|     } | ||||
| @ -870,7 +887,8 @@ export class CompileMetadataResolver { | ||||
|     if (!pipeMeta) { | ||||
|       this._reportError( | ||||
|           syntaxError( | ||||
|               `Illegal state: getPipeMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Pipe ${stringifyType(pipeType)}.`), | ||||
|               `Illegal state: getPipeMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Pipe ${ | ||||
|                   stringifyType(pipeType)}.`),
 | ||||
|           pipeType); | ||||
|     } | ||||
|     return pipeMeta || null; | ||||
| @ -898,7 +916,7 @@ export class CompileMetadataResolver { | ||||
| 
 | ||||
|   private _loadPipeMetadata(pipeType: any): cpl.CompilePipeMetadata { | ||||
|     pipeType = resolveForwardRef(pipeType); | ||||
|     const pipeAnnotation = this._pipeResolver.resolve(pipeType) !; | ||||
|     const pipeAnnotation = this._pipeResolver.resolve(pipeType)!; | ||||
| 
 | ||||
|     const pipeMeta = new cpl.CompilePipeMetadata({ | ||||
|       type: this._getTypeMetadata(pipeType), | ||||
| @ -962,7 +980,6 @@ export class CompileMetadataResolver { | ||||
|         isOptional, | ||||
|         token: this._getTokenMetadata(token) | ||||
|       }; | ||||
| 
 | ||||
|     }); | ||||
| 
 | ||||
|     if (hasUnknownDeps) { | ||||
| @ -1000,7 +1017,7 @@ export class CompileMetadataResolver { | ||||
|         this._getProvidersMetadata(provider, targetEntryComponents, debugInfo, compileProviders); | ||||
|       } else { | ||||
|         provider = resolveForwardRef(provider); | ||||
|         let providerMeta: cpl.ProviderMeta = undefined !; | ||||
|         let providerMeta: cpl.ProviderMeta = undefined!; | ||||
|         if (provider && typeof provider === 'object' && provider.hasOwnProperty('provide')) { | ||||
|           this._validateProvider(provider); | ||||
|           providerMeta = new cpl.ProviderMeta(provider.provide, provider); | ||||
| @ -1027,8 +1044,11 @@ export class CompileMetadataResolver { | ||||
|                       []) | ||||
|                   .join(', '); | ||||
|           this._reportError( | ||||
|               syntaxError( | ||||
|                   `Invalid ${debugInfo ? debugInfo : 'provider'} - only instances of Provider and Type are allowed, got: [${providersInfo}]`), | ||||
|               syntaxError(`Invalid ${ | ||||
|                   debugInfo ? | ||||
|                       debugInfo : | ||||
|                       'provider'} - only instances of Provider and Type are allowed, got: [${ | ||||
|                   providersInfo}]`),
 | ||||
|               type); | ||||
|           return; | ||||
|         } | ||||
| @ -1045,8 +1065,8 @@ export class CompileMetadataResolver { | ||||
| 
 | ||||
|   private _validateProvider(provider: any): void { | ||||
|     if (provider.hasOwnProperty('useClass') && provider.useClass == null) { | ||||
|       this._reportError(syntaxError( | ||||
|           `Invalid provider for ${stringifyType(provider.provide)}. useClass cannot be ${provider.useClass}.
 | ||||
|       this._reportError(syntaxError(`Invalid provider for ${ | ||||
|           stringifyType(provider.provide)}. useClass cannot be ${provider.useClass}. | ||||
|            Usually it happens when: | ||||
|            1. There's a circular dependency (might be caused by using index.ts (barrel) files). | ||||
|            2. Class was used before it was declared. Use forwardRef in this case.`));
 | ||||
| @ -1085,12 +1105,12 @@ export class CompileMetadataResolver { | ||||
|       cpl.CompileEntryComponentMetadata|null { | ||||
|     const dirMeta = this.getNonNormalizedDirectiveMetadata(dirType); | ||||
|     if (dirMeta && dirMeta.metadata.isComponent) { | ||||
|       return {componentType: dirType, componentFactory: dirMeta.metadata.componentFactory !}; | ||||
|       return {componentType: dirType, componentFactory: dirMeta.metadata.componentFactory!}; | ||||
|     } | ||||
|     const dirSummary = | ||||
|         <cpl.CompileDirectiveSummary>this._loadSummary(dirType, cpl.CompileSummaryKind.Directive); | ||||
|     if (dirSummary && dirSummary.isComponent) { | ||||
|       return {componentType: dirType, componentFactory: dirSummary.componentFactory !}; | ||||
|       return {componentType: dirType, componentFactory: dirSummary.componentFactory!}; | ||||
|     } | ||||
|     if (throwIfNotFound) { | ||||
|       throw syntaxError(`${dirType.name} cannot be used as an entry component.`); | ||||
| @ -1108,9 +1128,9 @@ export class CompileMetadataResolver { | ||||
|   } | ||||
| 
 | ||||
|   getProviderMetadata(provider: cpl.ProviderMeta): cpl.CompileProviderMetadata { | ||||
|     let compileDeps: cpl.CompileDiDependencyMetadata[] = undefined !; | ||||
|     let compileTypeMetadata: cpl.CompileTypeMetadata = null !; | ||||
|     let compileFactoryMetadata: cpl.CompileFactoryMetadata = null !; | ||||
|     let compileDeps: cpl.CompileDiDependencyMetadata[] = undefined!; | ||||
|     let compileTypeMetadata: cpl.CompileTypeMetadata = null!; | ||||
|     let compileFactoryMetadata: cpl.CompileFactoryMetadata = null!; | ||||
|     let token: cpl.CompileTokenMetadata = this._getTokenMetadata(provider.token); | ||||
| 
 | ||||
|     if (provider.useClass) { | ||||
| @ -1152,7 +1172,9 @@ export class CompileMetadataResolver { | ||||
|     return res; | ||||
|   } | ||||
| 
 | ||||
|   private _queryVarBindings(selector: any): string[] { return selector.split(/\s*,\s*/); } | ||||
|   private _queryVarBindings(selector: any): string[] { | ||||
|     return selector.split(/\s*,\s*/); | ||||
|   } | ||||
| 
 | ||||
|   private _getQueryMetadata(q: Query, propertyName: string, typeOrFunc: Type|Function): | ||||
|       cpl.CompileQueryMetadata { | ||||
| @ -1163,8 +1185,8 @@ export class CompileMetadataResolver { | ||||
|     } else { | ||||
|       if (!q.selector) { | ||||
|         this._reportError( | ||||
|             syntaxError( | ||||
|                 `Can't construct a query for the property "${propertyName}" of "${stringifyType(typeOrFunc)}" since the query selector wasn't defined.`), | ||||
|             syntaxError(`Can't construct a query for the property "${propertyName}" of "${ | ||||
|                 stringifyType(typeOrFunc)}" since the query selector wasn't defined.`),
 | ||||
|             typeOrFunc); | ||||
|         selectors = []; | ||||
|       } else { | ||||
| @ -1175,8 +1197,9 @@ export class CompileMetadataResolver { | ||||
|     return { | ||||
|       selectors, | ||||
|       first: q.first, | ||||
|       descendants: q.descendants, propertyName, | ||||
|       read: q.read ? this._getTokenMetadata(q.read) : null !, | ||||
|       descendants: q.descendants, | ||||
|       propertyName, | ||||
|       read: q.read ? this._getTokenMetadata(q.read) : null!, | ||||
|       static: q.static | ||||
|     }; | ||||
|   } | ||||
|  | ||||
| @ -24,7 +24,9 @@ export class Text extends NodeWithI18n { | ||||
|   constructor(public value: string, sourceSpan: ParseSourceSpan, i18n?: I18nMeta) { | ||||
|     super(sourceSpan, i18n); | ||||
|   } | ||||
|   visit(visitor: Visitor, context: any): any { return visitor.visitText(this, context); } | ||||
|   visit(visitor: Visitor, context: any): any { | ||||
|     return visitor.visitText(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Expansion extends NodeWithI18n { | ||||
| @ -33,7 +35,9 @@ export class Expansion extends NodeWithI18n { | ||||
|       sourceSpan: ParseSourceSpan, public switchValueSourceSpan: ParseSourceSpan, i18n?: I18nMeta) { | ||||
|     super(sourceSpan, i18n); | ||||
|   } | ||||
|   visit(visitor: Visitor, context: any): any { return visitor.visitExpansion(this, context); } | ||||
|   visit(visitor: Visitor, context: any): any { | ||||
|     return visitor.visitExpansion(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class ExpansionCase implements Node { | ||||
| @ -41,7 +45,9 @@ export class ExpansionCase implements Node { | ||||
|       public value: string, public expression: Node[], public sourceSpan: ParseSourceSpan, | ||||
|       public valueSourceSpan: ParseSourceSpan, public expSourceSpan: ParseSourceSpan) {} | ||||
| 
 | ||||
|   visit(visitor: Visitor, context: any): any { return visitor.visitExpansionCase(this, context); } | ||||
|   visit(visitor: Visitor, context: any): any { | ||||
|     return visitor.visitExpansionCase(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Attribute extends NodeWithI18n { | ||||
| @ -50,7 +56,9 @@ export class Attribute extends NodeWithI18n { | ||||
|       public valueSpan?: ParseSourceSpan, i18n?: I18nMeta) { | ||||
|     super(sourceSpan, i18n); | ||||
|   } | ||||
|   visit(visitor: Visitor, context: any): any { return visitor.visitAttribute(this, context); } | ||||
|   visit(visitor: Visitor, context: any): any { | ||||
|     return visitor.visitAttribute(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Element extends NodeWithI18n { | ||||
| @ -60,12 +68,16 @@ export class Element extends NodeWithI18n { | ||||
|       public endSourceSpan: ParseSourceSpan|null = null, i18n?: I18nMeta) { | ||||
|     super(sourceSpan, i18n); | ||||
|   } | ||||
|   visit(visitor: Visitor, context: any): any { return visitor.visitElement(this, context); } | ||||
|   visit(visitor: Visitor, context: any): any { | ||||
|     return visitor.visitElement(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Comment implements Node { | ||||
|   constructor(public value: string|null, public sourceSpan: ParseSourceSpan) {} | ||||
|   visit(visitor: Visitor, context: any): any { return visitor.visitComment(this, context); } | ||||
|   visit(visitor: Visitor, context: any): any { | ||||
|     return visitor.visitComment(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export interface Visitor { | ||||
| @ -85,7 +97,7 @@ export function visitAll(visitor: Visitor, nodes: Node[], context: any = null): | ||||
|   const result: any[] = []; | ||||
| 
 | ||||
|   const visit = visitor.visit ? | ||||
|       (ast: Node) => visitor.visit !(ast, context) || ast.visit(visitor, context) : | ||||
|       (ast: Node) => visitor.visit!(ast, context) || ast.visit(visitor, context) : | ||||
|       (ast: Node) => ast.visit(visitor, context); | ||||
|   nodes.forEach(ast => { | ||||
|     const astResult = visit(ast); | ||||
| @ -111,7 +123,9 @@ export class RecursiveVisitor implements Visitor { | ||||
|   visitComment(ast: Comment, context: any): any {} | ||||
| 
 | ||||
|   visitExpansion(ast: Expansion, context: any): any { | ||||
|     return this.visitChildren(context, visit => { visit(ast.cases); }); | ||||
|     return this.visitChildren(context, visit => { | ||||
|       visit(ast.cases); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(ast: ExpansionCase, context: any): any {} | ||||
| @ -120,7 +134,7 @@ export class RecursiveVisitor implements Visitor { | ||||
|       context: any, cb: (visit: (<V extends Node>(children: V[]|undefined) => void)) => void) { | ||||
|     let results: any[][] = []; | ||||
|     let t = this; | ||||
|     function visit<T extends Node>(children: T[] | undefined) { | ||||
|     function visit<T extends Node>(children: T[]|undefined) { | ||||
|       if (children) results.push(visitAll(t, children, context)); | ||||
|     } | ||||
|     cb(visit); | ||||
|  | ||||
| @ -8,12 +8,14 @@ | ||||
| 
 | ||||
| import {getHtmlTagDefinition} from './html_tags'; | ||||
| import {TokenizeOptions} from './lexer'; | ||||
| import {ParseTreeResult, Parser} from './parser'; | ||||
| import {Parser, ParseTreeResult} from './parser'; | ||||
| 
 | ||||
| export {ParseTreeResult, TreeError} from './parser'; | ||||
| 
 | ||||
| export class HtmlParser extends Parser { | ||||
|   constructor() { super(getHtmlTagDefinition); } | ||||
|   constructor() { | ||||
|     super(getHtmlTagDefinition); | ||||
|   } | ||||
| 
 | ||||
|   parse(source: string, url: string, options?: TokenizeOptions): ParseTreeResult { | ||||
|     return super.parse(source, url, options); | ||||
|  | ||||
| @ -18,9 +18,14 @@ export class HtmlTagDefinition implements TagDefinition { | ||||
|   ignoreFirstLf: boolean; | ||||
|   canSelfClose: boolean = false; | ||||
| 
 | ||||
|   constructor( | ||||
|       {closedByChildren, implicitNamespacePrefix, contentType = TagContentType.PARSABLE_DATA, | ||||
|        closedByParent = false, isVoid = false, ignoreFirstLf = false}: { | ||||
|   constructor({ | ||||
|     closedByChildren, | ||||
|     implicitNamespacePrefix, | ||||
|     contentType = TagContentType.PARSABLE_DATA, | ||||
|     closedByParent = false, | ||||
|     isVoid = false, | ||||
|     ignoreFirstLf = false | ||||
|   }: { | ||||
|     closedByChildren?: string[], | ||||
|     closedByParent?: boolean, | ||||
|     implicitNamespacePrefix?: string, | ||||
| @ -43,11 +48,11 @@ export class HtmlTagDefinition implements TagDefinition { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| let _DEFAULT_TAG_DEFINITION !: HtmlTagDefinition; | ||||
| let _DEFAULT_TAG_DEFINITION!: HtmlTagDefinition; | ||||
| 
 | ||||
| // see http://www.w3.org/TR/html51/syntax.html#optional-tags
 | ||||
| // This implementation does not fully conform to the HTML5 spec.
 | ||||
| let TAG_DEFINITIONS !: {[key: string]: HtmlTagDefinition}; | ||||
| let TAG_DEFINITIONS!: {[key: string]: HtmlTagDefinition}; | ||||
| 
 | ||||
| export function getHtmlTagDefinition(tagName: string): HtmlTagDefinition { | ||||
|   if (!TAG_DEFINITIONS) { | ||||
|  | ||||
| @ -81,11 +81,17 @@ export class WhitespaceVisitor implements html.Visitor { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitComment(comment: html.Comment, context: any): any { return comment; } | ||||
|   visitComment(comment: html.Comment, context: any): any { | ||||
|     return comment; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(expansion: html.Expansion, context: any): any { return expansion; } | ||||
|   visitExpansion(expansion: html.Expansion, context: any): any { | ||||
|     return expansion; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { return expansionCase; } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { | ||||
|     return expansionCase; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function removeWhitespaces(htmlAstWithErrors: ParseTreeResult): ParseTreeResult { | ||||
|  | ||||
| @ -46,7 +46,9 @@ export class ExpansionResult { | ||||
| } | ||||
| 
 | ||||
| export class ExpansionError extends ParseError { | ||||
|   constructor(span: ParseSourceSpan, errorMsg: string) { super(span, errorMsg); } | ||||
|   constructor(span: ParseSourceSpan, errorMsg: string) { | ||||
|     super(span, errorMsg); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -64,11 +66,17 @@ class _Expander implements html.Visitor { | ||||
|         element.startSourceSpan, element.endSourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitAttribute(attribute: html.Attribute, context: any): any { return attribute; } | ||||
|   visitAttribute(attribute: html.Attribute, context: any): any { | ||||
|     return attribute; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: html.Text, context: any): any { return text; } | ||||
|   visitText(text: html.Text, context: any): any { | ||||
|     return text; | ||||
|   } | ||||
| 
 | ||||
|   visitComment(comment: html.Comment, context: any): any { return comment; } | ||||
|   visitComment(comment: html.Comment, context: any): any { | ||||
|     return comment; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(icu: html.Expansion, context: any): any { | ||||
|     this.isExpanded = true; | ||||
| @ -87,7 +95,7 @@ function _expandPluralForm(ast: html.Expansion, errors: ParseError[]): html.Elem | ||||
|     if (PLURAL_CASES.indexOf(c.value) == -1 && !c.value.match(/^=\d+$/)) { | ||||
|       errors.push(new ExpansionError( | ||||
|           c.valueSourceSpan, | ||||
|           `Plural cases should be "=<number>" or one of ${PLURAL_CASES.join(", ")}`)); | ||||
|           `Plural cases should be "=<number>" or one of ${PLURAL_CASES.join(', ')}`)); | ||||
|     } | ||||
| 
 | ||||
|     const expansionResult = expandNodes(c.expression); | ||||
|  | ||||
| @ -764,7 +764,7 @@ function mergeTextTokens(srcTokens: Token[]): Token[] { | ||||
|   for (let i = 0; i < srcTokens.length; i++) { | ||||
|     const token = srcTokens[i]; | ||||
|     if (lastDstToken && lastDstToken.type == TokenType.TEXT && token.type == TokenType.TEXT) { | ||||
|       lastDstToken.parts[0] ! += token.parts[0]; | ||||
|       lastDstToken.parts[0]! += token.parts[0]; | ||||
|       lastDstToken.sourceSpan.end = token.sourceSpan.end; | ||||
|     } else { | ||||
|       lastDstToken = token; | ||||
| @ -849,15 +849,27 @@ class PlainCharacterCursor implements CharacterCursor { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   clone(): PlainCharacterCursor { return new PlainCharacterCursor(this); } | ||||
|   clone(): PlainCharacterCursor { | ||||
|     return new PlainCharacterCursor(this); | ||||
|   } | ||||
| 
 | ||||
|   peek() { return this.state.peek; } | ||||
|   charsLeft() { return this.end - this.state.offset; } | ||||
|   diff(other: this) { return this.state.offset - other.state.offset; } | ||||
|   peek() { | ||||
|     return this.state.peek; | ||||
|   } | ||||
|   charsLeft() { | ||||
|     return this.end - this.state.offset; | ||||
|   } | ||||
|   diff(other: this) { | ||||
|     return this.state.offset - other.state.offset; | ||||
|   } | ||||
| 
 | ||||
|   advance(): void { this.advanceState(this.state); } | ||||
|   advance(): void { | ||||
|     this.advanceState(this.state); | ||||
|   } | ||||
| 
 | ||||
|   init(): void { this.updatePeek(this.state); } | ||||
|   init(): void { | ||||
|     this.updatePeek(this.state); | ||||
|   } | ||||
| 
 | ||||
|   getSpan(start?: this, leadingTriviaCodePoints?: number[]): ParseSourceSpan { | ||||
|     start = start || this; | ||||
| @ -880,7 +892,9 @@ class PlainCharacterCursor implements CharacterCursor { | ||||
|     return this.input.substring(start.state.offset, this.state.offset); | ||||
|   } | ||||
| 
 | ||||
|   charAt(pos: number): number { return this.input.charCodeAt(pos); } | ||||
|   charAt(pos: number): number { | ||||
|     return this.input.charCodeAt(pos); | ||||
|   } | ||||
| 
 | ||||
|   protected advanceState(state: CursorState) { | ||||
|     if (state.offset >= this.end) { | ||||
| @ -913,7 +927,7 @@ class EscapedCharacterCursor extends PlainCharacterCursor { | ||||
|       super(fileOrCursor); | ||||
|       this.internalState = {...fileOrCursor.internalState}; | ||||
|     } else { | ||||
|       super(fileOrCursor, range !); | ||||
|       super(fileOrCursor, range!); | ||||
|       this.internalState = this.state; | ||||
|     } | ||||
|   } | ||||
| @ -929,7 +943,9 @@ class EscapedCharacterCursor extends PlainCharacterCursor { | ||||
|     this.processEscapeSequence(); | ||||
|   } | ||||
| 
 | ||||
|   clone(): EscapedCharacterCursor { return new EscapedCharacterCursor(this); } | ||||
|   clone(): EscapedCharacterCursor { | ||||
|     return new EscapedCharacterCursor(this); | ||||
|   } | ||||
| 
 | ||||
|   getChars(start: this): string { | ||||
|     const cursor = start.clone(); | ||||
|  | ||||
| @ -10,7 +10,7 @@ import {ParseError, ParseSourceSpan} from '../parse_util'; | ||||
| 
 | ||||
| import * as html from './ast'; | ||||
| import * as lex from './lexer'; | ||||
| import {TagDefinition, getNsPrefix, isNgContainer, mergeNsAndName} from './tags'; | ||||
| import {getNsPrefix, isNgContainer, mergeNsAndName, TagDefinition} from './tags'; | ||||
| 
 | ||||
| export class TreeError extends ParseError { | ||||
|   static create(elementName: string|null, span: ParseSourceSpan, msg: string): TreeError { | ||||
| @ -43,7 +43,7 @@ export class Parser { | ||||
| class _TreeBuilder { | ||||
|   private _index: number = -1; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   private _peek !: lex.Token; | ||||
|   private _peek!: lex.Token; | ||||
| 
 | ||||
|   private _rootNodes: html.Node[] = []; | ||||
|   private _errors: TreeError[] = []; | ||||
| @ -283,7 +283,7 @@ class _TreeBuilder { | ||||
|         endTagToken.parts[0], endTagToken.parts[1], this._getParentElement()); | ||||
| 
 | ||||
|     if (this._getParentElement()) { | ||||
|       this._getParentElement() !.endSourceSpan = endTagToken.sourceSpan; | ||||
|       this._getParentElement()!.endSourceSpan = endTagToken.sourceSpan; | ||||
|     } | ||||
| 
 | ||||
|     if (this.getTagDefinition(fullName).isVoid) { | ||||
| @ -291,8 +291,8 @@ class _TreeBuilder { | ||||
|           fullName, endTagToken.sourceSpan, | ||||
|           `Void elements do not have end tags "${endTagToken.parts[1]}"`)); | ||||
|     } else if (!this._popElement(fullName)) { | ||||
|       const errMsg = | ||||
|           `Unexpected closing tag "${fullName}". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags`; | ||||
|       const errMsg = `Unexpected closing tag "${ | ||||
|           fullName}". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags`;
 | ||||
|       this._errors.push(TreeError.create(fullName, endTagToken.sourceSpan, errMsg)); | ||||
|     } | ||||
|   } | ||||
| @ -316,7 +316,7 @@ class _TreeBuilder { | ||||
|     const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]); | ||||
|     let end = attrName.sourceSpan.end; | ||||
|     let value = ''; | ||||
|     let valueSpan: ParseSourceSpan = undefined !; | ||||
|     let valueSpan: ParseSourceSpan = undefined!; | ||||
|     if (this._peek.type === lex.TokenType.ATTR_QUOTE) { | ||||
|       this._advance(); | ||||
|     } | ||||
| @ -344,7 +344,7 @@ class _TreeBuilder { | ||||
|    * `<ng-container>` elements are skipped as they are not rendered as DOM element. | ||||
|    */ | ||||
|   private _getParentElementSkippingContainers(): | ||||
|       {parent: html.Element | null, container: html.Element|null} { | ||||
|       {parent: html.Element|null, container: html.Element|null} { | ||||
|     let container: html.Element|null = null; | ||||
| 
 | ||||
|     for (let i = this._elementStack.length - 1; i >= 0; i--) { | ||||
|  | ||||
| @ -23,7 +23,7 @@ export interface TagDefinition { | ||||
|   isClosedByChild(name: string): boolean; | ||||
| } | ||||
| 
 | ||||
| export function splitNsName(elementName: string): [string | null, string] { | ||||
| export function splitNsName(elementName: string): [string|null, string] { | ||||
|   if (elementName[0] != ':') { | ||||
|     return [null, elementName]; | ||||
|   } | ||||
| @ -54,7 +54,7 @@ export function isNgTemplate(tagName: string): boolean { | ||||
| 
 | ||||
| export function getNsPrefix(fullName: string): string; | ||||
| export function getNsPrefix(fullName: null): null; | ||||
| export function getNsPrefix(fullName: string | null): string|null { | ||||
| export function getNsPrefix(fullName: string|null): string|null { | ||||
|   return fullName === null ? null : splitNsName(fullName)[0]; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -7,13 +7,15 @@ | ||||
|  */ | ||||
| 
 | ||||
| import {TokenizeOptions} from './lexer'; | ||||
| import {ParseTreeResult, Parser} from './parser'; | ||||
| import {Parser, ParseTreeResult} from './parser'; | ||||
| import {getXmlTagDefinition} from './xml_tags'; | ||||
| 
 | ||||
| export {ParseTreeResult, TreeError} from './parser'; | ||||
| 
 | ||||
| export class XmlParser extends Parser { | ||||
|   constructor() { super(getXmlTagDefinition); } | ||||
|   constructor() { | ||||
|     super(getXmlTagDefinition); | ||||
|   } | ||||
| 
 | ||||
|   parse(source: string, url: string, options?: TokenizeOptions): ParseTreeResult { | ||||
|     return super.parse(source, url, options); | ||||
|  | ||||
| @ -11,19 +11,23 @@ import {TagContentType, TagDefinition} from './tags'; | ||||
| export class XmlTagDefinition implements TagDefinition { | ||||
|   closedByParent: boolean = false; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   requiredParents !: {[key: string]: boolean}; | ||||
|   requiredParents!: {[key: string]: boolean}; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   parentToAdd !: string; | ||||
|   parentToAdd!: string; | ||||
|   // TODO(issue/24571): remove '!'.
 | ||||
|   implicitNamespacePrefix !: string; | ||||
|   implicitNamespacePrefix!: string; | ||||
|   contentType: TagContentType = TagContentType.PARSABLE_DATA; | ||||
|   isVoid: boolean = false; | ||||
|   ignoreFirstLf: boolean = false; | ||||
|   canSelfClose: boolean = true; | ||||
| 
 | ||||
|   requireExtraParent(currentParent: string): boolean { return false; } | ||||
|   requireExtraParent(currentParent: string): boolean { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   isClosedByChild(name: string): boolean { return false; } | ||||
|   isClosedByChild(name: string): boolean { | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const _TAG_DEFINITION = new XmlTagDefinition(); | ||||
|  | ||||
| @ -43,8 +43,8 @@ export class NgModuleCompiler { | ||||
|             }); | ||||
| 
 | ||||
|     const ngModuleDef = o.importExpr(Identifiers.moduleDef).callFn([o.literalArr(providerDefs)]); | ||||
|     const ngModuleDefFactory = o.fn( | ||||
|         [new o.FnParam(LOG_VAR.name !)], [new o.ReturnStatement(ngModuleDef)], o.INFERRED_TYPE); | ||||
|     const ngModuleDefFactory = | ||||
|         o.fn([new o.FnParam(LOG_VAR.name!)], [new o.ReturnStatement(ngModuleDef)], o.INFERRED_TYPE); | ||||
| 
 | ||||
|     const ngModuleFactoryVar = `${identifierName(ngModuleMeta.type)}NgFactory`; | ||||
|     this._createNgModuleFactory( | ||||
| @ -77,7 +77,7 @@ export class NgModuleCompiler { | ||||
|             .set(value) | ||||
|             .toDeclStmt( | ||||
|                 o.importType( | ||||
|                     Identifiers.NgModuleFactory, [o.expressionType(ctx.importExpr(reference)) !], | ||||
|                     Identifiers.NgModuleFactory, [o.expressionType(ctx.importExpr(reference))!], | ||||
|                     [o.TypeModifier.Const]), | ||||
|                 [o.StmtModifier.Final, o.StmtModifier.Exported]); | ||||
| 
 | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import {CompileReflector} from './compile_reflector'; | ||||
| import {NgModule, Type, createNgModule} from './core'; | ||||
| import {createNgModule, NgModule, Type} from './core'; | ||||
| import {findLast} from './directive_resolver'; | ||||
| import {stringify} from './util'; | ||||
| 
 | ||||
| @ -18,7 +18,9 @@ import {stringify} from './util'; | ||||
| export class NgModuleResolver { | ||||
|   constructor(private _reflector: CompileReflector) {} | ||||
| 
 | ||||
|   isNgModule(type: any) { return this._reflector.annotations(type).some(createNgModule.isTypeOf); } | ||||
|   isNgModule(type: any) { | ||||
|     return this._reflector.annotations(type).some(createNgModule.isTypeOf); | ||||
|   } | ||||
| 
 | ||||
|   resolve(type: Type, throwIfNotFound = true): NgModule|null { | ||||
|     const ngModuleMeta: NgModule = | ||||
|  | ||||
| @ -28,31 +28,39 @@ class _EmittedLine { | ||||
| } | ||||
| 
 | ||||
| export class EmitterVisitorContext { | ||||
|   static createRoot(): EmitterVisitorContext { return new EmitterVisitorContext(0); } | ||||
|   static createRoot(): EmitterVisitorContext { | ||||
|     return new EmitterVisitorContext(0); | ||||
|   } | ||||
| 
 | ||||
|   private _lines: _EmittedLine[]; | ||||
|   private _classes: o.ClassStmt[] = []; | ||||
|   private _preambleLineCount = 0; | ||||
| 
 | ||||
|   constructor(private _indent: number) { this._lines = [new _EmittedLine(_indent)]; } | ||||
|   constructor(private _indent: number) { | ||||
|     this._lines = [new _EmittedLine(_indent)]; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @internal strip this from published d.ts files due to | ||||
|    * https://github.com/microsoft/TypeScript/issues/36216
 | ||||
|    */ | ||||
|   private get _currentLine(): _EmittedLine { return this._lines[this._lines.length - 1]; } | ||||
|   private get _currentLine(): _EmittedLine { | ||||
|     return this._lines[this._lines.length - 1]; | ||||
|   } | ||||
| 
 | ||||
|   println(from?: {sourceSpan: ParseSourceSpan | null}|null, lastPart: string = ''): void { | ||||
|   println(from?: {sourceSpan: ParseSourceSpan|null}|null, lastPart: string = ''): void { | ||||
|     this.print(from || null, lastPart, true); | ||||
|   } | ||||
| 
 | ||||
|   lineIsEmpty(): boolean { return this._currentLine.parts.length === 0; } | ||||
|   lineIsEmpty(): boolean { | ||||
|     return this._currentLine.parts.length === 0; | ||||
|   } | ||||
| 
 | ||||
|   lineLength(): number { | ||||
|     return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength; | ||||
|   } | ||||
| 
 | ||||
|   print(from: {sourceSpan: ParseSourceSpan | null}|null, part: string, newLine: boolean = false) { | ||||
|   print(from: {sourceSpan: ParseSourceSpan|null}|null, part: string, newLine: boolean = false) { | ||||
|     if (part.length > 0) { | ||||
|       this._currentLine.parts.push(part); | ||||
|       this._currentLine.partsLength += part.length; | ||||
| @ -83,9 +91,13 @@ export class EmitterVisitorContext { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   pushClass(clazz: o.ClassStmt) { this._classes.push(clazz); } | ||||
|   pushClass(clazz: o.ClassStmt) { | ||||
|     this._classes.push(clazz); | ||||
|   } | ||||
| 
 | ||||
|   popClass(): o.ClassStmt { return this._classes.pop() !; } | ||||
|   popClass(): o.ClassStmt { | ||||
|     return this._classes.pop()!; | ||||
|   } | ||||
| 
 | ||||
|   get currentClass(): o.ClassStmt|null { | ||||
|     return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null; | ||||
| @ -135,7 +147,7 @@ export class EmitterVisitorContext { | ||||
|       } | ||||
| 
 | ||||
|       while (spanIdx < spans.length) { | ||||
|         const span = spans[spanIdx] !; | ||||
|         const span = spans[spanIdx]!; | ||||
|         const source = span.start.file; | ||||
|         const sourceLine = span.start.line; | ||||
|         const sourceCol = span.start.col; | ||||
| @ -156,7 +168,9 @@ export class EmitterVisitorContext { | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   setPreambleLineCount(count: number) { return this._preambleLineCount = count; } | ||||
|   setPreambleLineCount(count: number) { | ||||
|     return this._preambleLineCount = count; | ||||
|   } | ||||
| 
 | ||||
|   spanOf(line: number, column: number): ParseSourceSpan|null { | ||||
|     const emittedLine = this._lines[line - this._preambleLineCount]; | ||||
| @ -243,7 +257,9 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex | ||||
|     if (stmt.multiline) { | ||||
|       ctx.println(stmt, `/* ${stmt.comment} */`); | ||||
|     } else { | ||||
|       stmt.comment.split('\n').forEach((line) => { ctx.println(stmt, `// ${line}`); }); | ||||
|       stmt.comment.split('\n').forEach((line) => { | ||||
|         ctx.println(stmt, `// ${line}`); | ||||
|       }); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| @ -327,7 +343,7 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex | ||||
|     expr.expr.visitExpression(this, ctx); | ||||
|   } | ||||
|   visitReadVarExpr(ast: o.ReadVarExpr, ctx: EmitterVisitorContext): any { | ||||
|     let varName = ast.name !; | ||||
|     let varName = ast.name!; | ||||
|     if (ast.builtin != null) { | ||||
|       switch (ast.builtin) { | ||||
|         case o.BuiltinVar.Super: | ||||
| @ -337,10 +353,10 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex | ||||
|           varName = 'this'; | ||||
|           break; | ||||
|         case o.BuiltinVar.CatchError: | ||||
|           varName = CATCH_ERROR_VAR.name !; | ||||
|           varName = CATCH_ERROR_VAR.name!; | ||||
|           break; | ||||
|         case o.BuiltinVar.CatchStack: | ||||
|           varName = CATCH_STACK_VAR.name !; | ||||
|           varName = CATCH_STACK_VAR.name!; | ||||
|           break; | ||||
|         default: | ||||
|           throw new Error(`Unknown builtin variable ${ast.builtin}`); | ||||
| @ -388,7 +404,7 @@ export abstract class AbstractEmitterVisitor implements o.StatementVisitor, o.Ex | ||||
|     ctx.print(ast, '? '); | ||||
|     ast.trueCase.visitExpression(this, ctx); | ||||
|     ctx.print(ast, ': '); | ||||
|     ast.falseCase !.visitExpression(this, ctx); | ||||
|     ast.falseCase!.visitExpression(this, ctx); | ||||
|     ctx.print(ast, `)`); | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
| @ -11,7 +11,9 @@ import {AbstractEmitterVisitor, CATCH_ERROR_VAR, CATCH_STACK_VAR, EmitterVisitor | ||||
| import * as o from './output_ast'; | ||||
| 
 | ||||
| export abstract class AbstractJsEmitterVisitor extends AbstractEmitterVisitor { | ||||
|   constructor() { super(false); } | ||||
|   constructor() { | ||||
|     super(false); | ||||
|   } | ||||
|   visitDeclareClassStmt(stmt: o.ClassStmt, ctx: EmitterVisitorContext): any { | ||||
|     ctx.pushClass(stmt); | ||||
|     this._visitClassConstructor(stmt, ctx); | ||||
| @ -101,7 +103,7 @@ export abstract class AbstractJsEmitterVisitor extends AbstractEmitterVisitor { | ||||
|   visitInvokeFunctionExpr(expr: o.InvokeFunctionExpr, ctx: EmitterVisitorContext): string|null { | ||||
|     const fnExpr = expr.fn; | ||||
|     if (fnExpr instanceof o.ReadVarExpr && fnExpr.builtin === o.BuiltinVar.Super) { | ||||
|       ctx.currentClass !.parent !.visitExpression(this, ctx); | ||||
|       ctx.currentClass!.parent!.visitExpression(this, ctx); | ||||
|       ctx.print(expr, `.call(this`); | ||||
|       if (expr.args.length > 0) { | ||||
|         ctx.print(expr, `, `); | ||||
|  | ||||
| @ -51,7 +51,7 @@ class JsEmitterVisitor extends AbstractJsEmitterVisitor { | ||||
|       } | ||||
|       ctx.print(ast, `${prefix}.`); | ||||
|     } | ||||
|     ctx.print(ast, name !); | ||||
|     ctx.print(ast, name!); | ||||
|     return null; | ||||
|   } | ||||
|   visitDeclareVarStmt(stmt: o.DeclareVarStmt, ctx: EmitterVisitorContext): any { | ||||
|  | ||||
| @ -24,7 +24,9 @@ export abstract class Type { | ||||
|   } | ||||
|   abstract visitType(visitor: TypeVisitor, context: any): any; | ||||
| 
 | ||||
|   hasModifier(modifier: TypeModifier): boolean { return this.modifiers !.indexOf(modifier) !== -1; } | ||||
|   hasModifier(modifier: TypeModifier): boolean { | ||||
|     return this.modifiers!.indexOf(modifier) !== -1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export enum BuiltinTypeName { | ||||
| @ -60,7 +62,9 @@ export class ExpressionType extends Type { | ||||
| 
 | ||||
| 
 | ||||
| export class ArrayType extends Type { | ||||
|   constructor(public of : Type, modifiers: TypeModifier[]|null = null) { super(modifiers); } | ||||
|   constructor(public of: Type, modifiers: TypeModifier[]|null = null) { | ||||
|     super(modifiers); | ||||
|   } | ||||
|   visitType(visitor: TypeVisitor, context: any): any { | ||||
|     return visitor.visitArrayType(this, context); | ||||
|   } | ||||
| @ -73,7 +77,9 @@ export class MapType extends Type { | ||||
|     super(modifiers); | ||||
|     this.valueType = valueType || null; | ||||
|   } | ||||
|   visitType(visitor: TypeVisitor, context: any): any { return visitor.visitMapType(this, context); } | ||||
|   visitType(visitor: TypeVisitor, context: any): any { | ||||
|     return visitor.visitMapType(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export const DYNAMIC_TYPE = new BuiltinType(BuiltinTypeName.Dynamic); | ||||
| @ -113,15 +119,15 @@ export enum BinaryOperator { | ||||
|   BiggerEquals | ||||
| } | ||||
| 
 | ||||
| export function nullSafeIsEquivalent<T extends{isEquivalent(other: T): boolean}>( | ||||
|     base: T | null, other: T | null) { | ||||
| export function nullSafeIsEquivalent<T extends {isEquivalent(other: T): boolean}>( | ||||
|     base: T|null, other: T|null) { | ||||
|   if (base == null || other == null) { | ||||
|     return base == other; | ||||
|   } | ||||
|   return base.isEquivalent(other); | ||||
| } | ||||
| 
 | ||||
| export function areAllEquivalent<T extends{isEquivalent(other: T): boolean}>( | ||||
| export function areAllEquivalent<T extends {isEquivalent(other: T): boolean}>( | ||||
|     base: T[], other: T[]) { | ||||
|   const len = base.length; | ||||
|   if (len !== other.length) { | ||||
| @ -243,7 +249,9 @@ export abstract class Expression { | ||||
|     return new CastExpr(this, type, sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   toStmt(): Statement { return new ExpressionStatement(this, null); } | ||||
|   toStmt(): Statement { | ||||
|     return new ExpressionStatement(this, null); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export enum BuiltinVar { | ||||
| @ -272,7 +280,9 @@ export class ReadVarExpr extends Expression { | ||||
|     return e instanceof ReadVarExpr && this.name === e.name && this.builtin === e.builtin; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitReadVarExpr(this, context); | ||||
| @ -299,7 +309,9 @@ export class TypeofExpr extends Expression { | ||||
|     return e instanceof TypeofExpr && e.expr.isEquivalent(this.expr); | ||||
|   } | ||||
| 
 | ||||
|   isConstant(): boolean { return this.expr.isConstant(); } | ||||
|   isConstant(): boolean { | ||||
|     return this.expr.isConstant(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class WrappedNodeExpr<T> extends Expression { | ||||
| @ -311,7 +323,9 @@ export class WrappedNodeExpr<T> extends Expression { | ||||
|     return e instanceof WrappedNodeExpr && this.node === e.node; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitWrappedNodeExpr(this, context); | ||||
| @ -330,7 +344,9 @@ export class WriteVarExpr extends Expression { | ||||
|     return e instanceof WriteVarExpr && this.name === e.name && this.value.isEquivalent(e.value); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitWriteVarExpr(this, context); | ||||
| @ -340,7 +356,9 @@ export class WriteVarExpr extends Expression { | ||||
|     return new DeclareVarStmt(this.name, this.value, type, modifiers, this.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   toConstDecl(): DeclareVarStmt { return this.toDeclStmt(INFERRED_TYPE, [StmtModifier.Final]); } | ||||
|   toConstDecl(): DeclareVarStmt { | ||||
|     return this.toDeclStmt(INFERRED_TYPE, [StmtModifier.Final]); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -358,7 +376,9 @@ export class WriteKeyExpr extends Expression { | ||||
|         this.index.isEquivalent(e.index) && this.value.isEquivalent(e.value); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitWriteKeyExpr(this, context); | ||||
| @ -380,7 +400,9 @@ export class WritePropExpr extends Expression { | ||||
|         this.name === e.name && this.value.isEquivalent(e.value); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitWritePropExpr(this, context); | ||||
| @ -414,7 +436,9 @@ export class InvokeMethodExpr extends Expression { | ||||
|         this.name === e.name && this.builtin === e.builtin && areAllEquivalent(this.args, e.args); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitInvokeMethodExpr(this, context); | ||||
| @ -434,7 +458,9 @@ export class InvokeFunctionExpr extends Expression { | ||||
|         areAllEquivalent(this.args, e.args) && this.pure === e.pure; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitInvokeFunctionExpr(this, context); | ||||
| @ -454,7 +480,9 @@ export class InstantiateExpr extends Expression { | ||||
|         areAllEquivalent(this.args, e.args); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitInstantiateExpr(this, context); | ||||
| @ -473,7 +501,9 @@ export class LiteralExpr extends Expression { | ||||
|     return e instanceof LiteralExpr && this.value === e.value; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return true; } | ||||
|   isConstant() { | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitLiteralExpr(this, context); | ||||
| @ -494,7 +524,9 @@ export class LocalizedString extends Expression { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitLocalizedString(this, context); | ||||
| @ -521,8 +553,9 @@ export class LocalizedString extends Expression { | ||||
|       metaBlock = `${metaBlock}${ID_SEPARATOR}${this.metaBlock.customId}`; | ||||
|     } | ||||
|     if (this.metaBlock.legacyIds) { | ||||
|       this.metaBlock.legacyIds.forEach( | ||||
|           legacyId => { metaBlock = `${metaBlock}${LEGACY_ID_INDICATOR}${legacyId}`; }); | ||||
|       this.metaBlock.legacyIds.forEach(legacyId => { | ||||
|         metaBlock = `${metaBlock}${LEGACY_ID_INDICATOR}${legacyId}`; | ||||
|       }); | ||||
|     } | ||||
|     return createCookedRawString(metaBlock, this.messageParts[0]); | ||||
|   } | ||||
| @ -588,7 +621,9 @@ export class ExternalExpr extends Expression { | ||||
|         this.value.moduleName === e.value.moduleName && this.value.runtime === e.value.runtime; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitExternalExpr(this, context); | ||||
| @ -616,7 +651,9 @@ export class ConditionalExpr extends Expression { | ||||
|         this.trueCase.isEquivalent(e.trueCase) && nullSafeIsEquivalent(this.falseCase, e.falseCase); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitConditionalExpr(this, context); | ||||
| @ -633,7 +670,9 @@ export class NotExpr extends Expression { | ||||
|     return e instanceof NotExpr && this.condition.isEquivalent(e.condition); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitNotExpr(this, context); | ||||
| @ -649,7 +688,9 @@ export class AssertNotNull extends Expression { | ||||
|     return e instanceof AssertNotNull && this.condition.isEquivalent(e.condition); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitAssertNotNullExpr(this, context); | ||||
| @ -665,7 +706,9 @@ export class CastExpr extends Expression { | ||||
|     return e instanceof CastExpr && this.value.isEquivalent(e.value); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitCastExpr(this, context); | ||||
| @ -676,7 +719,9 @@ export class CastExpr extends Expression { | ||||
| export class FnParam { | ||||
|   constructor(public name: string, public type: Type|null = null) {} | ||||
| 
 | ||||
|   isEquivalent(param: FnParam): boolean { return this.name === param.name; } | ||||
|   isEquivalent(param: FnParam): boolean { | ||||
|     return this.name === param.name; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -692,7 +737,9 @@ export class FunctionExpr extends Expression { | ||||
|         areAllEquivalent(this.statements, e.statements); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitFunctionExpr(this, context); | ||||
| @ -719,7 +766,9 @@ export class BinaryOperatorExpr extends Expression { | ||||
|         this.lhs.isEquivalent(e.lhs) && this.rhs.isEquivalent(e.rhs); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitBinaryOperatorExpr(this, context); | ||||
| @ -739,7 +788,9 @@ export class ReadPropExpr extends Expression { | ||||
|         this.name === e.name; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitReadPropExpr(this, context); | ||||
| @ -763,7 +814,9 @@ export class ReadKeyExpr extends Expression { | ||||
|         this.index.isEquivalent(e.index); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitReadKeyExpr(this, context); | ||||
| @ -782,7 +835,9 @@ export class LiteralArrayExpr extends Expression { | ||||
|     this.entries = entries; | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return this.entries.every(e => e.isConstant()); } | ||||
|   isConstant() { | ||||
|     return this.entries.every(e => e.isConstant()); | ||||
|   } | ||||
| 
 | ||||
|   isEquivalent(e: Expression): boolean { | ||||
|     return e instanceof LiteralArrayExpr && areAllEquivalent(this.entries, e.entries); | ||||
| @ -813,7 +868,9 @@ export class LiteralMapExpr extends Expression { | ||||
|     return e instanceof LiteralMapExpr && areAllEquivalent(this.entries, e.entries); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return this.entries.every(e => e.value.isConstant()); } | ||||
|   isConstant() { | ||||
|     return this.entries.every(e => e.value.isConstant()); | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitLiteralMapExpr(this, context); | ||||
| @ -829,7 +886,9 @@ export class CommaExpr extends Expression { | ||||
|     return e instanceof CommaExpr && areAllEquivalent(this.parts, e.parts); | ||||
|   } | ||||
| 
 | ||||
|   isConstant() { return false; } | ||||
|   isConstant() { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   visitExpression(visitor: ExpressionVisitor, context: any): any { | ||||
|     return visitor.visitCommaExpr(this, context); | ||||
| @ -892,7 +951,9 @@ export abstract class Statement { | ||||
| 
 | ||||
|   abstract visitStatement(visitor: StatementVisitor, context: any): any; | ||||
| 
 | ||||
|   hasModifier(modifier: StmtModifier): boolean { return this.modifiers !.indexOf(modifier) !== -1; } | ||||
|   hasModifier(modifier: StmtModifier): boolean { | ||||
|     return this.modifiers!.indexOf(modifier) !== -1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -965,7 +1026,9 @@ export class AbstractClassPart { | ||||
|     } | ||||
|     this.type = type || null; | ||||
|   } | ||||
|   hasModifier(modifier: StmtModifier): boolean { return this.modifiers !.indexOf(modifier) !== -1; } | ||||
|   hasModifier(modifier: StmtModifier): boolean { | ||||
|     return this.modifiers!.indexOf(modifier) !== -1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class ClassField extends AbstractClassPart { | ||||
| @ -974,7 +1037,9 @@ export class ClassField extends AbstractClassPart { | ||||
|       public initializer?: Expression) { | ||||
|     super(type, modifiers); | ||||
|   } | ||||
|   isEquivalent(f: ClassField) { return this.name === f.name; } | ||||
|   isEquivalent(f: ClassField) { | ||||
|     return this.name === f.name; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -1044,7 +1109,9 @@ export class CommentStmt extends Statement { | ||||
|   constructor(public comment: string, public multiline = false, sourceSpan?: ParseSourceSpan|null) { | ||||
|     super(null, sourceSpan); | ||||
|   } | ||||
|   isEquivalent(stmt: Statement): boolean { return stmt instanceof CommentStmt; } | ||||
|   isEquivalent(stmt: Statement): boolean { | ||||
|     return stmt instanceof CommentStmt; | ||||
|   } | ||||
|   visitStatement(visitor: StatementVisitor, context: any): any { | ||||
|     return visitor.visitCommentStmt(this, context); | ||||
|   } | ||||
| @ -1060,7 +1127,9 @@ export class JSDocCommentStmt extends Statement { | ||||
|   visitStatement(visitor: StatementVisitor, context: any): any { | ||||
|     return visitor.visitJSDocCommentStmt(this, context); | ||||
|   } | ||||
|   toString(): string { return serializeTags(this.tags); } | ||||
|   toString(): string { | ||||
|     return serializeTags(this.tags); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class TryCatchStmt extends Statement { | ||||
| @ -1105,11 +1174,17 @@ export interface StatementVisitor { | ||||
| } | ||||
| 
 | ||||
| export class AstTransformer implements StatementVisitor, ExpressionVisitor { | ||||
|   transformExpr(expr: Expression, context: any): Expression { return expr; } | ||||
|   transformExpr(expr: Expression, context: any): Expression { | ||||
|     return expr; | ||||
|   } | ||||
| 
 | ||||
|   transformStmt(stmt: Statement, context: any): Statement { return stmt; } | ||||
|   transformStmt(stmt: Statement, context: any): Statement { | ||||
|     return stmt; | ||||
|   } | ||||
| 
 | ||||
|   visitReadVarExpr(ast: ReadVarExpr, context: any): any { return this.transformExpr(ast, context); } | ||||
|   visitReadVarExpr(ast: ReadVarExpr, context: any): any { | ||||
|     return this.transformExpr(ast, context); | ||||
|   } | ||||
| 
 | ||||
|   visitWrappedNodeExpr(ast: WrappedNodeExpr<any>, context: any): any { | ||||
|     return this.transformExpr(ast, context); | ||||
| @ -1148,7 +1223,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor { | ||||
|     const method = ast.builtin || ast.name; | ||||
|     return this.transformExpr( | ||||
|         new InvokeMethodExpr( | ||||
|             ast.receiver.visitExpression(this, context), method !, | ||||
|             ast.receiver.visitExpression(this, context), method!, | ||||
|             this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), | ||||
|         context); | ||||
|   } | ||||
| @ -1169,7 +1244,9 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor { | ||||
|         context); | ||||
|   } | ||||
| 
 | ||||
|   visitLiteralExpr(ast: LiteralExpr, context: any): any { return this.transformExpr(ast, context); } | ||||
|   visitLiteralExpr(ast: LiteralExpr, context: any): any { | ||||
|     return this.transformExpr(ast, context); | ||||
|   } | ||||
| 
 | ||||
|   visitLocalizedString(ast: LocalizedString, context: any): any { | ||||
|     return this.transformExpr( | ||||
| @ -1188,7 +1265,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor { | ||||
|         new ConditionalExpr( | ||||
|             ast.condition.visitExpression(this, context), | ||||
|             ast.trueCase.visitExpression(this, context), | ||||
|             ast.falseCase !.visitExpression(this, context), ast.type, ast.sourceSpan), | ||||
|             ast.falseCase!.visitExpression(this, context), ast.type, ast.sourceSpan), | ||||
|         context); | ||||
|   } | ||||
| 
 | ||||
| @ -1284,7 +1361,7 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor { | ||||
|   } | ||||
| 
 | ||||
|   visitDeclareClassStmt(stmt: ClassStmt, context: any): any { | ||||
|     const parent = stmt.parent !.visitExpression(this, context); | ||||
|     const parent = stmt.parent!.visitExpression(this, context); | ||||
|     const getters = stmt.getters.map( | ||||
|         getter => new ClassGetter( | ||||
|             getter.name, this.visitAllStatements(getter.body, context), getter.type, | ||||
| @ -1341,14 +1418,18 @@ export class AstTransformer implements StatementVisitor, ExpressionVisitor { | ||||
| 
 | ||||
| 
 | ||||
| export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor { | ||||
|   visitType(ast: Type, context: any): any { return ast; } | ||||
|   visitType(ast: Type, context: any): any { | ||||
|     return ast; | ||||
|   } | ||||
|   visitExpression(ast: Expression, context: any): any { | ||||
|     if (ast.type) { | ||||
|       ast.type.visitType(this, context); | ||||
|     } | ||||
|     return ast; | ||||
|   } | ||||
|   visitBuiltinType(type: BuiltinType, context: any): any { return this.visitType(type, context); } | ||||
|   visitBuiltinType(type: BuiltinType, context: any): any { | ||||
|     return this.visitType(type, context); | ||||
|   } | ||||
|   visitExpressionType(type: ExpressionType, context: any): any { | ||||
|     type.value.visitExpression(this, context); | ||||
|     if (type.typeParams !== null) { | ||||
| @ -1356,10 +1437,18 @@ export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor | ||||
|     } | ||||
|     return this.visitType(type, context); | ||||
|   } | ||||
|   visitArrayType(type: ArrayType, context: any): any { return this.visitType(type, context); } | ||||
|   visitMapType(type: MapType, context: any): any { return this.visitType(type, context); } | ||||
|   visitWrappedNodeExpr(ast: WrappedNodeExpr<any>, context: any): any { return ast; } | ||||
|   visitTypeofExpr(ast: TypeofExpr, context: any): any { return this.visitExpression(ast, context); } | ||||
|   visitArrayType(type: ArrayType, context: any): any { | ||||
|     return this.visitType(type, context); | ||||
|   } | ||||
|   visitMapType(type: MapType, context: any): any { | ||||
|     return this.visitType(type, context); | ||||
|   } | ||||
|   visitWrappedNodeExpr(ast: WrappedNodeExpr<any>, context: any): any { | ||||
|     return ast; | ||||
|   } | ||||
|   visitTypeofExpr(ast: TypeofExpr, context: any): any { | ||||
|     return this.visitExpression(ast, context); | ||||
|   } | ||||
|   visitReadVarExpr(ast: ReadVarExpr, context: any): any { | ||||
|     return this.visitExpression(ast, context); | ||||
|   } | ||||
| @ -1408,7 +1497,7 @@ export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor | ||||
|   visitConditionalExpr(ast: ConditionalExpr, context: any): any { | ||||
|     ast.condition.visitExpression(this, context); | ||||
|     ast.trueCase.visitExpression(this, context); | ||||
|     ast.falseCase !.visitExpression(this, context); | ||||
|     ast.falseCase!.visitExpression(this, context); | ||||
|     return this.visitExpression(ast, context); | ||||
|   } | ||||
|   visitNotExpr(ast: NotExpr, context: any): any { | ||||
| @ -1482,7 +1571,7 @@ export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor | ||||
|     return stmt; | ||||
|   } | ||||
|   visitDeclareClassStmt(stmt: ClassStmt, context: any): any { | ||||
|     stmt.parent !.visitExpression(this, context); | ||||
|     stmt.parent!.visitExpression(this, context); | ||||
|     stmt.getters.forEach(getter => this.visitAllStatements(getter.body, context)); | ||||
|     if (stmt.constructorMethod) { | ||||
|       this.visitAllStatements(stmt.constructorMethod.body, context); | ||||
| @ -1505,8 +1594,12 @@ export class RecursiveAstVisitor implements StatementVisitor, ExpressionVisitor | ||||
|     stmt.error.visitExpression(this, context); | ||||
|     return stmt; | ||||
|   } | ||||
|   visitCommentStmt(stmt: CommentStmt, context: any): any { return stmt; } | ||||
|   visitJSDocCommentStmt(stmt: JSDocCommentStmt, context: any): any { return stmt; } | ||||
|   visitCommentStmt(stmt: CommentStmt, context: any): any { | ||||
|     return stmt; | ||||
|   } | ||||
|   visitJSDocCommentStmt(stmt: JSDocCommentStmt, context: any): any { | ||||
|     return stmt; | ||||
|   } | ||||
|   visitAllStatements(stmts: Statement[], context: any): void { | ||||
|     stmts.forEach(stmt => stmt.visitStatement(this, context)); | ||||
|   } | ||||
| @ -1551,7 +1644,7 @@ class _FindExternalReferencesVisitor extends RecursiveAstVisitor { | ||||
| } | ||||
| 
 | ||||
| export function applySourceSpanToStatementIfNeeded( | ||||
|     stmt: Statement, sourceSpan: ParseSourceSpan | null): Statement { | ||||
|     stmt: Statement, sourceSpan: ParseSourceSpan|null): Statement { | ||||
|   if (!sourceSpan) { | ||||
|     return stmt; | ||||
|   } | ||||
| @ -1560,7 +1653,7 @@ export function applySourceSpanToStatementIfNeeded( | ||||
| } | ||||
| 
 | ||||
| export function applySourceSpanToExpressionIfNeeded( | ||||
|     expr: Expression, sourceSpan: ParseSourceSpan | null): Expression { | ||||
|     expr: Expression, sourceSpan: ParseSourceSpan|null): Expression { | ||||
|   if (!sourceSpan) { | ||||
|     return expr; | ||||
|   } | ||||
| @ -1569,7 +1662,9 @@ export function applySourceSpanToExpressionIfNeeded( | ||||
| } | ||||
| 
 | ||||
| class _ApplySourceSpanTransformer extends AstTransformer { | ||||
|   constructor(private sourceSpan: ParseSourceSpan) { super(); } | ||||
|   constructor(private sourceSpan: ParseSourceSpan) { | ||||
|     super(); | ||||
|   } | ||||
|   private _clone(obj: any): any { | ||||
|     const clone = Object.create(obj.constructor.prototype); | ||||
|     for (let prop of Object.keys(obj)) { | ||||
| @ -1596,25 +1691,25 @@ class _ApplySourceSpanTransformer extends AstTransformer { | ||||
| } | ||||
| 
 | ||||
| export function variable( | ||||
|     name: string, type?: Type | null, sourceSpan?: ParseSourceSpan | null): ReadVarExpr { | ||||
|     name: string, type?: Type|null, sourceSpan?: ParseSourceSpan|null): ReadVarExpr { | ||||
|   return new ReadVarExpr(name, type, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| export function importExpr( | ||||
|     id: ExternalReference, typeParams: Type[] | null = null, | ||||
|     sourceSpan?: ParseSourceSpan | null): ExternalExpr { | ||||
|     id: ExternalReference, typeParams: Type[]|null = null, | ||||
|     sourceSpan?: ParseSourceSpan|null): ExternalExpr { | ||||
|   return new ExternalExpr(id, null, typeParams, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| export function importType( | ||||
|     id: ExternalReference, typeParams: Type[] | null = null, | ||||
|     typeModifiers: TypeModifier[] | null = null): ExpressionType|null { | ||||
|     id: ExternalReference, typeParams: Type[]|null = null, | ||||
|     typeModifiers: TypeModifier[]|null = null): ExpressionType|null { | ||||
|   return id != null ? expressionType(importExpr(id, typeParams, null), typeModifiers) : null; | ||||
| } | ||||
| 
 | ||||
| export function expressionType( | ||||
|     expr: Expression, typeModifiers: TypeModifier[] | null = null, | ||||
|     typeParams: Type[] | null = null): ExpressionType { | ||||
|     expr: Expression, typeModifiers: TypeModifier[]|null = null, | ||||
|     typeParams: Type[]|null = null): ExpressionType { | ||||
|   return new ExpressionType(expr, typeModifiers, typeParams); | ||||
| } | ||||
| 
 | ||||
| @ -1623,30 +1718,28 @@ export function typeofExpr(expr: Expression) { | ||||
| } | ||||
| 
 | ||||
| export function literalArr( | ||||
|     values: Expression[], type?: Type | null, | ||||
|     sourceSpan?: ParseSourceSpan | null): LiteralArrayExpr { | ||||
|     values: Expression[], type?: Type|null, sourceSpan?: ParseSourceSpan|null): LiteralArrayExpr { | ||||
|   return new LiteralArrayExpr(values, type, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| export function literalMap( | ||||
|     values: {key: string, quoted: boolean, value: Expression}[], | ||||
|     type: MapType | null = null): LiteralMapExpr { | ||||
|     type: MapType|null = null): LiteralMapExpr { | ||||
|   return new LiteralMapExpr( | ||||
|       values.map(e => new LiteralMapEntry(e.key, e.value, e.quoted)), type, null); | ||||
| } | ||||
| 
 | ||||
| export function not(expr: Expression, sourceSpan?: ParseSourceSpan | null): NotExpr { | ||||
| export function not(expr: Expression, sourceSpan?: ParseSourceSpan|null): NotExpr { | ||||
|   return new NotExpr(expr, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| export function assertNotNull( | ||||
|     expr: Expression, sourceSpan?: ParseSourceSpan | null): AssertNotNull { | ||||
| export function assertNotNull(expr: Expression, sourceSpan?: ParseSourceSpan|null): AssertNotNull { | ||||
|   return new AssertNotNull(expr, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| export function fn( | ||||
|     params: FnParam[], body: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, | ||||
|     name?: string | null): FunctionExpr { | ||||
|     params: FnParam[], body: Statement[], type?: Type|null, sourceSpan?: ParseSourceSpan|null, | ||||
|     name?: string|null): FunctionExpr { | ||||
|   return new FunctionExpr(params, body, type, sourceSpan, name); | ||||
| } | ||||
| 
 | ||||
| @ -1655,13 +1748,13 @@ export function ifStmt(condition: Expression, thenClause: Statement[], elseClaus | ||||
| } | ||||
| 
 | ||||
| export function literal( | ||||
|     value: any, type?: Type | null, sourceSpan?: ParseSourceSpan | null): LiteralExpr { | ||||
|     value: any, type?: Type|null, sourceSpan?: ParseSourceSpan|null): LiteralExpr { | ||||
|   return new LiteralExpr(value, type, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| export function localizedString( | ||||
|     metaBlock: I18nMeta, messageParts: string[], placeholderNames: string[], | ||||
|     expressions: Expression[], sourceSpan?: ParseSourceSpan | null): LocalizedString { | ||||
|     expressions: Expression[], sourceSpan?: ParseSourceSpan|null): LocalizedString { | ||||
|   return new LocalizedString(metaBlock, messageParts, placeholderNames, expressions, sourceSpan); | ||||
| } | ||||
| 
 | ||||
| @ -1684,13 +1777,12 @@ export const enum JSDocTagName { | ||||
|  */ | ||||
| export type JSDocTag = { | ||||
|   // `tagName` is e.g. "param" in an `@param` declaration
 | ||||
|   tagName: JSDocTagName | string, | ||||
|   tagName: JSDocTagName|string, | ||||
|   // Any remaining text on the tag, e.g. the description
 | ||||
|   text?: string, | ||||
| } | { | ||||
| }|{ | ||||
|   // no `tagName` for plain text documentation that occurs before any `@param` lines
 | ||||
|   tagName?: undefined, | ||||
|   text: string, | ||||
|   tagName?: undefined, text: string, | ||||
| }; | ||||
| 
 | ||||
| /* | ||||
|  | ||||
| @ -15,7 +15,9 @@ export function interpretStatements( | ||||
|   const visitor = new StatementInterpreter(reflector); | ||||
|   visitor.visitAllStatements(statements, ctx); | ||||
|   const result: {[key: string]: any} = {}; | ||||
|   ctx.exports.forEach((exportName) => { result[exportName] = ctx.vars.get(exportName); }); | ||||
|   ctx.exports.forEach((exportName) => { | ||||
|     result[exportName] = ctx.vars.get(exportName); | ||||
|   }); | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| @ -63,7 +65,7 @@ function createDynamicClass( | ||||
|   _classStmt.methods.forEach(function(method: o.ClassMethod) { | ||||
|     const paramNames = method.params.map(param => param.name); | ||||
|     // Note: use `function` instead of arrow function to capture `this`
 | ||||
|     propertyDescriptors[method.name !] = { | ||||
|     propertyDescriptors[method.name!] = { | ||||
|       writable: false, | ||||
|       configurable: false, | ||||
|       value: function(...args: any[]) { | ||||
| @ -77,7 +79,9 @@ function createDynamicClass( | ||||
|   // Note: use `function` instead of arrow function to capture `this`
 | ||||
|   const ctor = function(this: Object, ...args: any[]) { | ||||
|     const instanceCtx = new _ExecutionContext(_ctx, this, _classStmt.name, _ctx.vars); | ||||
|     _classStmt.fields.forEach((field) => { (this as any)[field.name] = undefined; }); | ||||
|     _classStmt.fields.forEach((field) => { | ||||
|       (this as any)[field.name] = undefined; | ||||
|     }); | ||||
|     _executeFunctionStatements( | ||||
|         ctorParamNames, args, _classStmt.constructorMethod.body, instanceCtx, _visitor); | ||||
|   }; | ||||
| @ -88,7 +92,9 @@ function createDynamicClass( | ||||
| 
 | ||||
| class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|   constructor(private reflector: CompileReflector) {} | ||||
|   debugAst(ast: o.Expression|o.Statement|o.Type): string { return debugOutputAstAsTypeScript(ast); } | ||||
|   debugAst(ast: o.Expression|o.Statement|o.Type): string { | ||||
|     return debugOutputAstAsTypeScript(ast); | ||||
|   } | ||||
| 
 | ||||
|   visitDeclareVarStmt(stmt: o.DeclareVarStmt, ctx: _ExecutionContext): any { | ||||
|     const initialValue = stmt.value ? stmt.value.visitExpression(this, ctx) : undefined; | ||||
| @ -106,7 +112,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|         currCtx.vars.set(expr.name, value); | ||||
|         return value; | ||||
|       } | ||||
|       currCtx = currCtx.parent !; | ||||
|       currCtx = currCtx.parent!; | ||||
|     } | ||||
|     throw new Error(`Not declared variable ${expr.name}`); | ||||
|   } | ||||
| @ -117,7 +123,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|     throw new Error('Cannot interpret a TypeofExpr'); | ||||
|   } | ||||
|   visitReadVarExpr(ast: o.ReadVarExpr, ctx: _ExecutionContext): any { | ||||
|     let varName = ast.name !; | ||||
|     let varName = ast.name!; | ||||
|     if (ast.builtin != null) { | ||||
|       switch (ast.builtin) { | ||||
|         case o.BuiltinVar.Super: | ||||
| @ -139,7 +145,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|       if (currCtx.vars.has(varName)) { | ||||
|         return currCtx.vars.get(varName); | ||||
|       } | ||||
|       currCtx = currCtx.parent !; | ||||
|       currCtx = currCtx.parent!; | ||||
|     } | ||||
|     throw new Error(`Not declared variable ${varName}`); | ||||
|   } | ||||
| @ -176,7 +182,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|           throw new Error(`Unknown builtin method ${expr.builtin}`); | ||||
|       } | ||||
|     } else { | ||||
|       result = receiver[expr.name !].apply(receiver, args); | ||||
|       result = receiver[expr.name!].apply(receiver, args); | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
| @ -184,7 +190,7 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|     const args = this.visitAllExpressions(stmt.args, ctx); | ||||
|     const fnExpr = stmt.fn; | ||||
|     if (fnExpr instanceof o.ReadVarExpr && fnExpr.builtin === o.BuiltinVar.Super) { | ||||
|       ctx.instance !.constructor.prototype.constructor.apply(ctx.instance, args); | ||||
|       ctx.instance!.constructor.prototype.constructor.apply(ctx.instance, args); | ||||
|       return null; | ||||
|     } else { | ||||
|       const fn = stmt.fn.visitExpression(this, ctx); | ||||
| @ -227,15 +233,23 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor { | ||||
|   visitThrowStmt(stmt: o.ThrowStmt, ctx: _ExecutionContext): any { | ||||
|     throw stmt.error.visitExpression(this, ctx); | ||||
|   } | ||||
|   visitCommentStmt(stmt: o.CommentStmt, context?: any): any { return null; } | ||||
|   visitJSDocCommentStmt(stmt: o.JSDocCommentStmt, context?: any): any { return null; } | ||||
|   visitCommentStmt(stmt: o.CommentStmt, context?: any): any { | ||||
|     return null; | ||||
|   } | ||||
|   visitJSDocCommentStmt(stmt: o.JSDocCommentStmt, context?: any): any { | ||||
|     return null; | ||||
|   } | ||||
|   visitInstantiateExpr(ast: o.InstantiateExpr, ctx: _ExecutionContext): any { | ||||
|     const args = this.visitAllExpressions(ast.args, ctx); | ||||
|     const clazz = ast.classExpr.visitExpression(this, ctx); | ||||
|     return new clazz(...args); | ||||
|   } | ||||
|   visitLiteralExpr(ast: o.LiteralExpr, ctx: _ExecutionContext): any { return ast.value; } | ||||
|   visitLocalizedString(ast: o.LocalizedString, context: any): any { return null; } | ||||
|   visitLiteralExpr(ast: o.LiteralExpr, ctx: _ExecutionContext): any { | ||||
|     return ast.value; | ||||
|   } | ||||
|   visitLocalizedString(ast: o.LocalizedString, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
|   visitExternalExpr(ast: o.ExternalExpr, ctx: _ExecutionContext): any { | ||||
|     return this.reflector.resolveExternalReference(ast.value); | ||||
|   } | ||||
|  | ||||
| @ -87,7 +87,9 @@ export class JitEvaluator { | ||||
|    * @param args The arguments to pass to the function being executed. | ||||
|    * @returns The return value of the executed function. | ||||
|    */ | ||||
|   executeFunction(fn: Function, args: any[]) { return fn(...args); } | ||||
|   executeFunction(fn: Function, args: any[]) { | ||||
|     return fn(...args); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -98,7 +100,9 @@ export class JitEmitterVisitor extends AbstractJsEmitterVisitor { | ||||
|   private _evalArgValues: any[] = []; | ||||
|   private _evalExportedVars: string[] = []; | ||||
| 
 | ||||
|   constructor(private reflector: CompileReflector) { super(); } | ||||
|   constructor(private reflector: CompileReflector) { | ||||
|     super(); | ||||
|   } | ||||
| 
 | ||||
|   createReturnStmt(ctx: EmitterVisitorContext) { | ||||
|     const stmt = new o.ReturnStatement(new o.LiteralMapExpr(this._evalExportedVars.map( | ||||
|  | ||||
| @ -25,7 +25,7 @@ export type SourceMap = { | ||||
|   file?: string, | ||||
|       sourceRoot: string, | ||||
|       sources: string[], | ||||
|   sourcesContent: (string | null)[], | ||||
|       sourcesContent: (string|null)[], | ||||
|       mappings: string, | ||||
| }; | ||||
| 
 | ||||
| @ -78,7 +78,9 @@ export class SourceMapGenerator { | ||||
|    * @internal strip this from published d.ts files due to | ||||
|    * https://github.com/microsoft/TypeScript/issues/36216
 | ||||
|    */ | ||||
|   private get currentLine(): Segment[]|null { return this.lines.slice(-1)[0]; } | ||||
|   private get currentLine(): Segment[]|null { | ||||
|     return this.lines.slice(-1)[0]; | ||||
|   } | ||||
| 
 | ||||
|   toJSON(): SourceMap|null { | ||||
|     if (!this.hasMappings) { | ||||
| @ -87,7 +89,7 @@ export class SourceMapGenerator { | ||||
| 
 | ||||
|     const sourcesIndex = new Map<string, number>(); | ||||
|     const sources: string[] = []; | ||||
|     const sourcesContent: (string | null)[] = []; | ||||
|     const sourcesContent: (string|null)[] = []; | ||||
| 
 | ||||
|     Array.from(this.sourcesContent.keys()).forEach((url: string, i: number) => { | ||||
|       sourcesIndex.set(url, i); | ||||
| @ -113,14 +115,14 @@ export class SourceMapGenerator { | ||||
|                         if (segment.sourceUrl != null) { | ||||
|                           // zero-based index into the “sources” list
 | ||||
|                           segAsStr += | ||||
|                               toBase64VLQ(sourcesIndex.get(segment.sourceUrl) ! - lastSourceIndex); | ||||
|                           lastSourceIndex = sourcesIndex.get(segment.sourceUrl) !; | ||||
|                               toBase64VLQ(sourcesIndex.get(segment.sourceUrl)! - lastSourceIndex); | ||||
|                           lastSourceIndex = sourcesIndex.get(segment.sourceUrl)!; | ||||
|                           // the zero-based starting line in the original source
 | ||||
|                           segAsStr += toBase64VLQ(segment.sourceLine0 ! - lastSourceLine0); | ||||
|                           lastSourceLine0 = segment.sourceLine0 !; | ||||
|                           segAsStr += toBase64VLQ(segment.sourceLine0! - lastSourceLine0); | ||||
|                           lastSourceLine0 = segment.sourceLine0!; | ||||
|                           // the zero-based starting column in the original source
 | ||||
|                           segAsStr += toBase64VLQ(segment.sourceCol0 ! - lastSourceCol0); | ||||
|                           lastSourceCol0 = segment.sourceCol0 !; | ||||
|                           segAsStr += toBase64VLQ(segment.sourceCol0! - lastSourceCol0); | ||||
|                           lastSourceCol0 = segment.sourceCol0!; | ||||
|                         } | ||||
| 
 | ||||
|                         return segAsStr; | ||||
|  | ||||
| @ -15,8 +15,7 @@ import * as o from './output_ast'; | ||||
| 
 | ||||
| const _debugFilePath = '/debug/lib'; | ||||
| 
 | ||||
| export function debugOutputAstAsTypeScript(ast: o.Statement | o.Expression | o.Type | any[]): | ||||
|     string { | ||||
| export function debugOutputAstAsTypeScript(ast: o.Statement|o.Expression|o.Type|any[]): string { | ||||
|   const converter = new _TsEmitterVisitor(); | ||||
|   const ctx = EmitterVisitorContext.createRoot(); | ||||
|   const asts: any[] = Array.isArray(ast) ? ast : [ast]; | ||||
| @ -147,7 +146,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor | ||||
|           reexports = []; | ||||
|           this.reexports.set(moduleName, reexports); | ||||
|         } | ||||
|         reexports.push({name: name !, as: stmt.name}); | ||||
|         reexports.push({name: name!, as: stmt.name}); | ||||
|         return null; | ||||
|       } | ||||
|     } | ||||
| @ -175,7 +174,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor | ||||
| 
 | ||||
|   visitCastExpr(ast: o.CastExpr, ctx: EmitterVisitorContext): any { | ||||
|     ctx.print(ast, `(<`); | ||||
|     ast.type !.visitType(this, ctx); | ||||
|     ast.type!.visitType(this, ctx); | ||||
|     ctx.print(ast, `>`); | ||||
|     ast.value.visitExpression(this, ctx); | ||||
|     ctx.print(ast, `)`); | ||||
| @ -422,7 +421,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor | ||||
|       } | ||||
|       ctx.print(null, `${prefix}.`); | ||||
|     } | ||||
|     ctx.print(null, name !); | ||||
|     ctx.print(null, name!); | ||||
| 
 | ||||
|     if (this.typeExpression > 0) { | ||||
|       // If we are in a type expression that refers to a generic type then supply
 | ||||
| @ -433,7 +432,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor | ||||
|       const suppliedParameters = typeParams || []; | ||||
|       if (suppliedParameters.length > 0) { | ||||
|         ctx.print(null, `<`); | ||||
|         this.visitAllObjects(type => type.visitType(this, ctx), typeParams !, ctx, ','); | ||||
|         this.visitAllObjects(type => type.visitType(this, ctx), typeParams!, ctx, ','); | ||||
|         ctx.print(null, `>`); | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @ -14,7 +14,7 @@ import * as o from './output_ast'; | ||||
| export const QUOTED_KEYS = '$quoted$'; | ||||
| 
 | ||||
| export function convertValueToOutputAst( | ||||
|     ctx: OutputContext, value: any, type: o.Type | null = null): o.Expression { | ||||
|     ctx: OutputContext, value: any, type: o.Type|null = null): o.Expression { | ||||
|   return visitValue(value, new _ValueOutputAstTransformer(ctx), type); | ||||
| } | ||||
| 
 | ||||
| @ -43,7 +43,9 @@ class _ValueOutputAstTransformer implements ValueTransformer { | ||||
|     return new o.LiteralMapExpr(entries, type); | ||||
|   } | ||||
| 
 | ||||
|   visitPrimitive(value: any, type: o.Type): o.Expression { return o.literal(value, type); } | ||||
|   visitPrimitive(value: any, type: o.Type): o.Expression { | ||||
|     return o.literal(value, type); | ||||
|   } | ||||
| 
 | ||||
|   visitOther(value: any, type: o.Type): o.Expression { | ||||
|     if (value instanceof o.Expression) { | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import {CompileReflector} from './compile_reflector'; | ||||
| import {Pipe, Type, createPipe} from './core'; | ||||
| import {createPipe, Pipe, Type} from './core'; | ||||
| import {findLast} from './directive_resolver'; | ||||
| import {resolveForwardRef, stringify} from './util'; | ||||
| 
 | ||||
|  | ||||
| @ -9,12 +9,14 @@ | ||||
| 
 | ||||
| import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompileNgModuleMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata, tokenName, tokenReference} from './compile_metadata'; | ||||
| import {CompileReflector} from './compile_reflector'; | ||||
| import {Identifiers, createTokenForExternalReference} from './identifiers'; | ||||
| import {createTokenForExternalReference, Identifiers} from './identifiers'; | ||||
| import {ParseError, ParseSourceSpan} from './parse_util'; | ||||
| import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, QueryMatch, ReferenceAst} from './template_parser/template_ast'; | ||||
| 
 | ||||
| export class ProviderError extends ParseError { | ||||
|   constructor(message: string, span: ParseSourceSpan) { super(span, message); } | ||||
|   constructor(message: string, span: ParseSourceSpan) { | ||||
|     super(span, message); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export interface QueryWithId { | ||||
| @ -125,7 +127,9 @@ export class ProviderElementContext { | ||||
| 
 | ||||
|   get queryMatches(): QueryMatch[] { | ||||
|     const allMatches: QueryMatch[] = []; | ||||
|     this._queriedTokens.forEach((matches: QueryMatch[]) => { allMatches.push(...matches); }); | ||||
|     this._queriedTokens.forEach((matches: QueryMatch[]) => { | ||||
|       allMatches.push(...matches); | ||||
|     }); | ||||
|     return allMatches; | ||||
|   } | ||||
| 
 | ||||
| @ -171,7 +175,8 @@ export class ProviderElementContext { | ||||
|       requestingProviderType: ProviderAstType, token: CompileTokenMetadata, | ||||
|       eager: boolean): ProviderAst|null { | ||||
|     const resolvedProvider = this._allProviders.get(tokenReference(token)); | ||||
|     if (!resolvedProvider || ((requestingProviderType === ProviderAstType.Directive || | ||||
|     if (!resolvedProvider || | ||||
|         ((requestingProviderType === ProviderAstType.Directive || | ||||
|           requestingProviderType === ProviderAstType.PublicService) && | ||||
|          resolvedProvider.providerType === ProviderAstType.PrivateService) || | ||||
|         ((requestingProviderType === ProviderAstType.PrivateService || | ||||
| @ -191,25 +196,25 @@ export class ProviderElementContext { | ||||
|     this._seenProviders.set(tokenReference(token), true); | ||||
|     const transformedProviders = resolvedProvider.providers.map((provider) => { | ||||
|       let transformedUseValue = provider.useValue; | ||||
|       let transformedUseExisting = provider.useExisting !; | ||||
|       let transformedDeps: CompileDiDependencyMetadata[] = undefined !; | ||||
|       let transformedUseExisting = provider.useExisting!; | ||||
|       let transformedDeps: CompileDiDependencyMetadata[] = undefined!; | ||||
|       if (provider.useExisting != null) { | ||||
|         const existingDiDep = this._getDependency( | ||||
|             resolvedProvider.providerType, {token: provider.useExisting}, eager) !; | ||||
|             resolvedProvider.providerType, {token: provider.useExisting}, eager)!; | ||||
|         if (existingDiDep.token != null) { | ||||
|           transformedUseExisting = existingDiDep.token; | ||||
|         } else { | ||||
|           transformedUseExisting = null !; | ||||
|           transformedUseExisting = null!; | ||||
|           transformedUseValue = existingDiDep.value; | ||||
|         } | ||||
|       } else if (provider.useFactory) { | ||||
|         const deps = provider.deps || provider.useFactory.diDeps; | ||||
|         transformedDeps = | ||||
|             deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager) !); | ||||
|             deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager)!); | ||||
|       } else if (provider.useClass) { | ||||
|         const deps = provider.deps || provider.useClass.diDeps; | ||||
|         transformedDeps = | ||||
|             deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager) !); | ||||
|             deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep, eager)!); | ||||
|       } | ||||
|       return _transformProvider(provider, { | ||||
|         useExisting: transformedUseExisting, | ||||
| @ -227,7 +232,7 @@ export class ProviderElementContext { | ||||
|       requestingProviderType: ProviderAstType, dep: CompileDiDependencyMetadata, | ||||
|       eager: boolean = false): CompileDiDependencyMetadata|null { | ||||
|     if (dep.isAttribute) { | ||||
|       const attrValue = this._attrs[dep.token !.value]; | ||||
|       const attrValue = this._attrs[dep.token!.value]; | ||||
|       return {isValue: true, value: attrValue == null ? null : attrValue}; | ||||
|     } | ||||
| 
 | ||||
| @ -248,7 +253,7 @@ export class ProviderElementContext { | ||||
|         } | ||||
|         if (tokenReference(dep.token) === | ||||
|             this.viewContext.reflector.resolveExternalReference(Identifiers.ViewContainerRef)) { | ||||
|           (this as{transformedHasViewContainer: boolean}).transformedHasViewContainer = true; | ||||
|           (this as {transformedHasViewContainer: boolean}).transformedHasViewContainer = true; | ||||
|         } | ||||
|       } | ||||
|       // access the injector
 | ||||
| @ -290,8 +295,8 @@ export class ProviderElementContext { | ||||
|       // check @Host restriction
 | ||||
|       if (!result) { | ||||
|         if (!dep.isHost || this.viewContext.component.isHost || | ||||
|             this.viewContext.component.type.reference === tokenReference(dep.token !) || | ||||
|             this.viewContext.viewProviders.get(tokenReference(dep.token !)) != null) { | ||||
|             this.viewContext.component.type.reference === tokenReference(dep.token!) || | ||||
|             this.viewContext.viewProviders.get(tokenReference(dep.token!)) != null) { | ||||
|           result = dep; | ||||
|         } else { | ||||
|           result = dep.isOptional ? {isValue: true, value: null} : null; | ||||
| @ -368,15 +373,15 @@ export class NgModuleProviderAnalyzer { | ||||
|     this._seenProviders.set(tokenReference(token), true); | ||||
|     const transformedProviders = resolvedProvider.providers.map((provider) => { | ||||
|       let transformedUseValue = provider.useValue; | ||||
|       let transformedUseExisting = provider.useExisting !; | ||||
|       let transformedDeps: CompileDiDependencyMetadata[] = undefined !; | ||||
|       let transformedUseExisting = provider.useExisting!; | ||||
|       let transformedDeps: CompileDiDependencyMetadata[] = undefined!; | ||||
|       if (provider.useExisting != null) { | ||||
|         const existingDiDep = | ||||
|             this._getDependency({token: provider.useExisting}, eager, resolvedProvider.sourceSpan); | ||||
|         if (existingDiDep.token != null) { | ||||
|           transformedUseExisting = existingDiDep.token; | ||||
|         } else { | ||||
|           transformedUseExisting = null !; | ||||
|           transformedUseExisting = null!; | ||||
|           transformedUseValue = existingDiDep.value; | ||||
|         } | ||||
|       } else if (provider.useFactory) { | ||||
| @ -478,7 +483,8 @@ function _resolveProviders( | ||||
|     let resolvedProvider = targetProvidersByToken.get(tokenReference(provider.token)); | ||||
|     if (resolvedProvider != null && !!resolvedProvider.multiProvider !== !!provider.multi) { | ||||
|       targetErrors.push(new ProviderError( | ||||
|           `Mixing multi and non multi provider is not possible for token ${tokenName(resolvedProvider.token)}`, | ||||
|           `Mixing multi and non multi provider is not possible for token ${ | ||||
|               tokenName(resolvedProvider.token)}`,
 | ||||
|           sourceSpan)); | ||||
|     } | ||||
|     if (!resolvedProvider) { | ||||
|  | ||||
| @ -18,19 +18,25 @@ export interface Node { | ||||
| 
 | ||||
| export class Text implements Node { | ||||
|   constructor(public value: string, public sourceSpan: ParseSourceSpan) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitText(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitText(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class BoundText implements Node { | ||||
|   constructor(public value: AST, public sourceSpan: ParseSourceSpan, public i18n?: I18nMeta) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitBoundText(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitBoundText(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class TextAttribute implements Node { | ||||
|   constructor( | ||||
|       public name: string, public value: string, public sourceSpan: ParseSourceSpan, | ||||
|       public valueSpan?: ParseSourceSpan, public i18n?: I18nMeta) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitTextAttribute(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitTextAttribute(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class BoundAttribute implements Node { | ||||
| @ -45,7 +51,9 @@ export class BoundAttribute implements Node { | ||||
|         prop.valueSpan, i18n); | ||||
|   } | ||||
| 
 | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitBoundAttribute(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitBoundAttribute(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class BoundEvent implements Node { | ||||
| @ -62,7 +70,9 @@ export class BoundEvent implements Node { | ||||
|         event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan); | ||||
|   } | ||||
| 
 | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitBoundEvent(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitBoundEvent(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Element implements Node { | ||||
| @ -76,7 +86,9 @@ export class Element implements Node { | ||||
|       this.sourceSpan = new ParseSourceSpan(sourceSpan.start, endSourceSpan.end); | ||||
|     } | ||||
|   } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitElement(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitElement(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Template implements Node { | ||||
| @ -86,36 +98,46 @@ export class Template implements Node { | ||||
|       public children: Node[], public references: Reference[], public variables: Variable[], | ||||
|       public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null, | ||||
|       public endSourceSpan: ParseSourceSpan|null, public i18n?: I18nMeta) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitTemplate(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitTemplate(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Content implements Node { | ||||
|   constructor( | ||||
|       public selector: string, public attributes: TextAttribute[], | ||||
|       public sourceSpan: ParseSourceSpan, public i18n?: I18nMeta) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitContent(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitContent(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Variable implements Node { | ||||
|   constructor( | ||||
|       public name: string, public value: string, public sourceSpan: ParseSourceSpan, | ||||
|       public valueSpan?: ParseSourceSpan) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitVariable(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitVariable(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Reference implements Node { | ||||
|   constructor( | ||||
|       public name: string, public value: string, public sourceSpan: ParseSourceSpan, | ||||
|       public valueSpan?: ParseSourceSpan) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitReference(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitReference(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Icu implements Node { | ||||
|   constructor( | ||||
|       public vars: {[name: string]: BoundText}, | ||||
|       public placeholders: {[name: string]: Text | BoundText}, public sourceSpan: ParseSourceSpan, | ||||
|       public placeholders: {[name: string]: Text|BoundText}, public sourceSpan: ParseSourceSpan, | ||||
|       public i18n?: I18nMeta) {} | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { return visitor.visitIcu(this); } | ||||
|   visit<Result>(visitor: Visitor<Result>): Result { | ||||
|     return visitor.visitIcu(this); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export interface Visitor<Result = any> { | ||||
| @ -210,16 +232,34 @@ export class TransformVisitor implements Visitor<Node> { | ||||
|     return template; | ||||
|   } | ||||
| 
 | ||||
|   visitContent(content: Content): Node { return content; } | ||||
|   visitContent(content: Content): Node { | ||||
|     return content; | ||||
|   } | ||||
| 
 | ||||
|   visitVariable(variable: Variable): Node { return variable; } | ||||
|   visitReference(reference: Reference): Node { return reference; } | ||||
|   visitTextAttribute(attribute: TextAttribute): Node { return attribute; } | ||||
|   visitBoundAttribute(attribute: BoundAttribute): Node { return attribute; } | ||||
|   visitBoundEvent(attribute: BoundEvent): Node { return attribute; } | ||||
|   visitText(text: Text): Node { return text; } | ||||
|   visitBoundText(text: BoundText): Node { return text; } | ||||
|   visitIcu(icu: Icu): Node { return icu; } | ||||
|   visitVariable(variable: Variable): Node { | ||||
|     return variable; | ||||
|   } | ||||
|   visitReference(reference: Reference): Node { | ||||
|     return reference; | ||||
|   } | ||||
|   visitTextAttribute(attribute: TextAttribute): Node { | ||||
|     return attribute; | ||||
|   } | ||||
|   visitBoundAttribute(attribute: BoundAttribute): Node { | ||||
|     return attribute; | ||||
|   } | ||||
|   visitBoundEvent(attribute: BoundEvent): Node { | ||||
|     return attribute; | ||||
|   } | ||||
|   visitText(text: Text): Node { | ||||
|     return text; | ||||
|   } | ||||
|   visitBoundText(text: BoundText): Node { | ||||
|     return text; | ||||
|   } | ||||
|   visitIcu(icu: Icu): Node { | ||||
|     return icu; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function visitAll<Result>(visitor: Visitor<Result>, nodes: Node[]): Result[] { | ||||
|  | ||||
| @ -89,8 +89,8 @@ export interface R3ExpressionFactoryMetadata extends R3ConstructorFactoryMetadat | ||||
|   expression: o.Expression; | ||||
| } | ||||
| 
 | ||||
| export type R3FactoryMetadata = R3ConstructorFactoryMetadata | R3DelegatedFactoryMetadata | | ||||
|     R3DelegatedFnOrClassMetadata | R3ExpressionFactoryMetadata; | ||||
| export type R3FactoryMetadata = R3ConstructorFactoryMetadata|R3DelegatedFactoryMetadata| | ||||
|     R3DelegatedFnOrClassMetadata|R3ExpressionFactoryMetadata; | ||||
| 
 | ||||
| export enum R3FactoryTarget { | ||||
|   Directive = 0, | ||||
| @ -280,8 +280,7 @@ export function compileFactoryFunction(meta: R3FactoryMetadata): R3FactoryFn { | ||||
|         `${meta.name}_Factory`), | ||||
|     statements, | ||||
|     type: o.expressionType(o.importExpr( | ||||
|         R3.FactoryDef, | ||||
|         [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType])) | ||||
|         R3.FactoryDef, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType])) | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| @ -402,7 +401,8 @@ export function dependenciesFromGlobalMetadata( | ||||
|       // Construct the dependency.
 | ||||
|       deps.push({ | ||||
|         token, | ||||
|         attribute: null, resolved, | ||||
|         attribute: null, | ||||
|         resolved, | ||||
|         host: !!dependency.isHost, | ||||
|         optional: !!dependency.isOptional, | ||||
|         self: !!dependency.isSelf, | ||||
|  | ||||
| @ -21,28 +21,44 @@ export class R3JitReflector implements CompileReflector { | ||||
|   resolveExternalReference(ref: o.ExternalReference): any { | ||||
|     // This reflector only handles @angular/core imports.
 | ||||
|     if (ref.moduleName !== '@angular/core') { | ||||
|       throw new Error( | ||||
|           `Cannot resolve external reference to ${ref.moduleName}, only references to @angular/core are supported.`); | ||||
|       throw new Error(`Cannot resolve external reference to ${ | ||||
|           ref.moduleName}, only references to @angular/core are supported.`);
 | ||||
|     } | ||||
|     if (!this.context.hasOwnProperty(ref.name !)) { | ||||
|     if (!this.context.hasOwnProperty(ref.name!)) { | ||||
|       throw new Error(`No value provided for @angular/core symbol '${ref.name!}'.`); | ||||
|     } | ||||
|     return this.context[ref.name !]; | ||||
|     return this.context[ref.name!]; | ||||
|   } | ||||
| 
 | ||||
|   parameters(typeOrFunc: any): any[][] { throw new Error('Not implemented.'); } | ||||
|   parameters(typeOrFunc: any): any[][] { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   annotations(typeOrFunc: any): any[] { throw new Error('Not implemented.'); } | ||||
|   annotations(typeOrFunc: any): any[] { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   shallowAnnotations(typeOrFunc: any): any[] { throw new Error('Not implemented.'); } | ||||
|   shallowAnnotations(typeOrFunc: any): any[] { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   tryAnnotations(typeOrFunc: any): any[] { throw new Error('Not implemented.'); } | ||||
|   tryAnnotations(typeOrFunc: any): any[] { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   propMetadata(typeOrFunc: any): {[key: string]: any[];} { throw new Error('Not implemented.'); } | ||||
|   propMetadata(typeOrFunc: any): {[key: string]: any[];} { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   hasLifecycleHook(type: any, lcProperty: string): boolean { throw new Error('Not implemented.'); } | ||||
|   hasLifecycleHook(type: any, lcProperty: string): boolean { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   guards(typeOrFunc: any): {[key: string]: any;} { throw new Error('Not implemented.'); } | ||||
|   guards(typeOrFunc: any): {[key: string]: any;} { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| 
 | ||||
|   componentModuleUrl(type: any, cmpMetadata: any): string { throw new Error('Not implemented.'); } | ||||
|   componentModuleUrl(type: any, cmpMetadata: any): string { | ||||
|     throw new Error('Not implemented.'); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -12,9 +12,9 @@ import {mapLiteral} from '../output/map_util'; | ||||
| import * as o from '../output/output_ast'; | ||||
| import {OutputContext} from '../util'; | ||||
| 
 | ||||
| import {R3DependencyMetadata, R3FactoryTarget, compileFactoryFunction} from './r3_factory'; | ||||
| import {compileFactoryFunction, R3DependencyMetadata, R3FactoryTarget} from './r3_factory'; | ||||
| import {Identifiers as R3} from './r3_identifiers'; | ||||
| import {R3Reference, convertMetaToOutput, jitOnlyGuardedExpression, mapToMapExpression} from './util'; | ||||
| import {convertMetaToOutput, jitOnlyGuardedExpression, mapToMapExpression, R3Reference} from './util'; | ||||
| 
 | ||||
| export interface R3NgModuleDef { | ||||
|   expression: o.Expression; | ||||
| @ -108,9 +108,7 @@ export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef { | ||||
|   } = meta; | ||||
| 
 | ||||
|   const additionalStatements: o.Statement[] = []; | ||||
|   const definitionMap = { | ||||
|     type: internalType | ||||
|   } as{ | ||||
|   const definitionMap = {type: internalType} as { | ||||
|     type: o.Expression, | ||||
|     bootstrap: o.Expression, | ||||
|     declarations: o.Expression, | ||||
| @ -177,7 +175,7 @@ export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef { | ||||
| function generateSetNgModuleScopeCall(meta: R3NgModuleMetadata): o.Statement|null { | ||||
|   const {adjacentType: moduleType, declarations, imports, exports, containsForwardDecls} = meta; | ||||
| 
 | ||||
|   const scopeMap = {} as{ | ||||
|   const scopeMap = {} as { | ||||
|     declarations: o.Expression, | ||||
|     imports: o.Expression, | ||||
|     exports: o.Expression, | ||||
| @ -247,7 +245,7 @@ export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef { | ||||
|   }); | ||||
|   const definitionMap = { | ||||
|     factory: result.factory, | ||||
|   } as{factory: o.Expression, providers: o.Expression, imports: o.Expression}; | ||||
|   } as {factory: o.Expression, providers: o.Expression, imports: o.Expression}; | ||||
| 
 | ||||
|   if (meta.providers !== null) { | ||||
|     definitionMap.providers = meta.providers; | ||||
| @ -267,7 +265,7 @@ export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef { | ||||
| export function compileNgModuleFromRender2( | ||||
|     ctx: OutputContext, ngModule: CompileShallowModuleMetadata, | ||||
|     injectableCompiler: InjectableCompiler): void { | ||||
|   const className = identifierName(ngModule.type) !; | ||||
|   const className = identifierName(ngModule.type)!; | ||||
| 
 | ||||
|   const rawImports = ngModule.rawImports ? [ngModule.rawImports] : []; | ||||
|   const rawExports = ngModule.rawExports ? [ngModule.rawExports] : []; | ||||
| @ -288,7 +286,8 @@ export function compileNgModuleFromRender2( | ||||
|           /* name */ 'ɵinj', | ||||
|           /* type */ o.INFERRED_TYPE, | ||||
|           /* modifiers */[o.StmtModifier.Static], | ||||
|           /* initializer */ injectorDef, )], | ||||
|           /* initializer */ injectorDef, | ||||
|           )], | ||||
|       /* getters */[], | ||||
|       /* constructorMethod */ new o.ClassMethod(null, [], []), | ||||
|       /* methods */[])); | ||||
|  | ||||
| @ -10,9 +10,9 @@ import {CompilePipeMetadata, identifierName} from '../compile_metadata'; | ||||
| import {CompileReflector} from '../compile_reflector'; | ||||
| import {DefinitionKind} from '../constant_pool'; | ||||
| import * as o from '../output/output_ast'; | ||||
| import {OutputContext, error} from '../util'; | ||||
| import {error, OutputContext} from '../util'; | ||||
| 
 | ||||
| import {R3DependencyMetadata, R3FactoryTarget, compileFactoryFunction, dependenciesFromGlobalMetadata} from './r3_factory'; | ||||
| import {compileFactoryFunction, dependenciesFromGlobalMetadata, R3DependencyMetadata, R3FactoryTarget} from './r3_factory'; | ||||
| import {Identifiers as R3} from './r3_identifiers'; | ||||
| import {R3Reference, typeWithParameters, wrapReference} from './util'; | ||||
| 
 | ||||
|  | ||||
| @ -215,7 +215,7 @@ class HtmlAstToIvyAst implements html.Visitor { | ||||
|       // Moreover, if the node is an element, then we need to hoist its attributes to the template
 | ||||
|       // node for matching against content projection selectors.
 | ||||
|       const attrs = this.extractAttributes('ng-template', templateParsedProperties, i18nAttrsMeta); | ||||
|       const templateAttrs: (t.TextAttribute | t.BoundAttribute)[] = []; | ||||
|       const templateAttrs: (t.TextAttribute|t.BoundAttribute)[] = []; | ||||
|       attrs.literal.forEach(attr => templateAttrs.push(attr)); | ||||
|       attrs.bound.forEach(attr => templateAttrs.push(attr)); | ||||
|       const hoistedAttrs = parsedElement instanceof t.Element ? | ||||
| @ -260,12 +260,12 @@ class HtmlAstToIvyAst implements html.Visitor { | ||||
|       return null; | ||||
|     } | ||||
|     if (!isI18nRootNode(expansion.i18n)) { | ||||
|       throw new Error( | ||||
|           `Invalid type "${expansion.i18n.constructor}" for "i18n" property of ${expansion.sourceSpan.toString()}. Expected a "Message"`); | ||||
|       throw new Error(`Invalid type "${expansion.i18n.constructor}" for "i18n" property of ${ | ||||
|           expansion.sourceSpan.toString()}. Expected a "Message"`);
 | ||||
|     } | ||||
|     const message = expansion.i18n; | ||||
|     const vars: {[name: string]: t.BoundText} = {}; | ||||
|     const placeholders: {[name: string]: t.Text | t.BoundText} = {}; | ||||
|     const placeholders: {[name: string]: t.Text|t.BoundText} = {}; | ||||
|     // extract VARs from ICUs - we process them separately while
 | ||||
|     // assembling resulting message via goog.getMsg function, since
 | ||||
|     // we need to pass them to top-level goog.getMsg call
 | ||||
| @ -284,9 +284,13 @@ class HtmlAstToIvyAst implements html.Visitor { | ||||
|     return new t.Icu(vars, placeholders, expansion.sourceSpan, message); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase): null { return null; } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase): null { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitComment(comment: html.Comment): null { return null; } | ||||
|   visitComment(comment: html.Comment): null { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   // convert view engine `ParsedProperty` to a format suitable for IVY
 | ||||
|   private extractAttributes( | ||||
| @ -460,18 +464,26 @@ class NonBindableVisitor implements html.Visitor { | ||||
|         ast.startSourceSpan, ast.endSourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitComment(comment: html.Comment): any { return null; } | ||||
|   visitComment(comment: html.Comment): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitAttribute(attribute: html.Attribute): t.TextAttribute { | ||||
|     return new t.TextAttribute( | ||||
|         attribute.name, attribute.value, attribute.sourceSpan, undefined, attribute.i18n); | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: html.Text): t.Text { return new t.Text(text.value, text.sourceSpan); } | ||||
|   visitText(text: html.Text): t.Text { | ||||
|     return new t.Text(text.value, text.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(expansion: html.Expansion): any { return null; } | ||||
|   visitExpansion(expansion: html.Expansion): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase): any { return null; } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase): any { | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const NON_BINDABLE_VISITOR = new NonBindableVisitor(); | ||||
|  | ||||
| @ -13,14 +13,13 @@ import {OutputContext} from '../util'; | ||||
| /** | ||||
|  * Convert an object map with `Expression` values into a `LiteralMapExpr`. | ||||
|  */ | ||||
| export function mapToMapExpression(map: {[key: string]: o.Expression | undefined}): | ||||
|     o.LiteralMapExpr { | ||||
| export function mapToMapExpression(map: {[key: string]: o.Expression|undefined}): o.LiteralMapExpr { | ||||
|   const result = Object.keys(map).map( | ||||
|       key => ({ | ||||
|         key, | ||||
|         // The assertion here is because really TypeScript doesn't allow us to express that if the
 | ||||
|         // key is present, it will have a value, but this is true in reality.
 | ||||
|         value: map[key] !, | ||||
|         value: map[key]!, | ||||
|         quoted: false, | ||||
|       })); | ||||
|   return o.literalMap(result); | ||||
|  | ||||
| @ -88,7 +88,7 @@ export interface R3DirectiveMetadata { | ||||
|   /** | ||||
|    * A mapping of input field names to the property names. | ||||
|    */ | ||||
|   inputs: {[field: string]: string | [string, string]}; | ||||
|   inputs: {[field: string]: string|[string, string]}; | ||||
| 
 | ||||
|   /** | ||||
|    * A mapping of output field names to the property names. | ||||
|  | ||||
| @ -20,17 +20,17 @@ import {CssSelector, SelectorMatcher} from '../../selector'; | ||||
| import {ShadowCss} from '../../shadow_css'; | ||||
| import {CONTENT_ATTR, HOST_ATTR} from '../../style_compiler'; | ||||
| import {BindingParser} from '../../template_parser/binding_parser'; | ||||
| import {OutputContext, error} from '../../util'; | ||||
| import {error, OutputContext} from '../../util'; | ||||
| import {BoundEvent} from '../r3_ast'; | ||||
| import {R3DependencyMetadata, R3FactoryTarget, R3ResolvedDependencyType, compileFactoryFunction} from '../r3_factory'; | ||||
| import {compileFactoryFunction, R3DependencyMetadata, R3FactoryTarget, R3ResolvedDependencyType} from '../r3_factory'; | ||||
| import {Identifiers as R3} from '../r3_identifiers'; | ||||
| import {Render3ParseResult} from '../r3_template_transform'; | ||||
| import {prepareSyntheticListenerFunctionName, prepareSyntheticPropertyName, typeWithParameters} from '../util'; | ||||
| 
 | ||||
| import {R3ComponentDef, R3ComponentMetadata, R3DirectiveDef, R3DirectiveMetadata, R3HostMetadata, R3QueryMetadata} from './api'; | ||||
| import {MIN_STYLING_BINDING_SLOTS_REQUIRED, StylingBuilder, StylingInstructionCall} from './styling_builder'; | ||||
| import {BindingScope, TemplateDefinitionBuilder, ValueConverter, makeBindingParser, prepareEventListenerParameters, renderFlagCheckIfStmt, resolveSanitizationFn} from './template'; | ||||
| import {CONTEXT_NAME, DefinitionMap, RENDER_FLAGS, TEMPORARY_NAME, asLiteral, chainedInstruction, conditionallyCreateMapObjectLiteral, getQueryPredicate, temporaryAllocator} from './util'; | ||||
| import {BindingScope, makeBindingParser, prepareEventListenerParameters, renderFlagCheckIfStmt, resolveSanitizationFn, TemplateDefinitionBuilder, ValueConverter} from './template'; | ||||
| import {asLiteral, chainedInstruction, conditionallyCreateMapObjectLiteral, CONTEXT_NAME, DefinitionMap, getQueryPredicate, RENDER_FLAGS, TEMPORARY_NAME, temporaryAllocator} from './util'; | ||||
| 
 | ||||
| const EMPTY_ARRAY: any[] = []; | ||||
| 
 | ||||
| @ -65,9 +65,10 @@ function baseDirectiveFields( | ||||
| 
 | ||||
|   // e.g. `hostBindings: (rf, ctx) => { ... }
 | ||||
|   definitionMap.set( | ||||
|       'hostBindings', createHostBindingsFunction( | ||||
|                           meta.host, meta.typeSourceSpan, bindingParser, constantPool, | ||||
|                           meta.selector || '', meta.name, definitionMap)); | ||||
|       'hostBindings', | ||||
|       createHostBindingsFunction( | ||||
|           meta.host, meta.typeSourceSpan, bindingParser, constantPool, meta.selector || '', | ||||
|           meta.name, definitionMap)); | ||||
| 
 | ||||
|   // e.g 'inputs: {a: 'a'}`
 | ||||
|   definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true)); | ||||
| @ -85,8 +86,7 @@ function baseDirectiveFields( | ||||
| /** | ||||
|  * Add features to the definition map. | ||||
|  */ | ||||
| function addFeatures( | ||||
|     definitionMap: DefinitionMap, meta: R3DirectiveMetadata | R3ComponentMetadata) { | ||||
| function addFeatures(definitionMap: DefinitionMap, meta: R3DirectiveMetadata|R3ComponentMetadata) { | ||||
|   // e.g. `features: [NgOnChangesFeature]`
 | ||||
|   const features: o.Expression[] = []; | ||||
| 
 | ||||
| @ -148,7 +148,8 @@ export function compileComponentFromMetadata( | ||||
|     const selectorAttributes = firstSelector.getAttrs(); | ||||
|     if (selectorAttributes.length) { | ||||
|       definitionMap.set( | ||||
|           'attrs', constantPool.getConstLiteral( | ||||
|           'attrs', | ||||
|           constantPool.getConstLiteral( | ||||
|               o.literalArr(selectorAttributes.map( | ||||
|                   value => value != null ? o.literal(value) : o.literal(undefined))), | ||||
|               /* forceShared */ true)); | ||||
| @ -273,7 +274,7 @@ export function compileComponentFromMetadata( | ||||
| export function compileDirectiveFromRender2( | ||||
|     outputCtx: OutputContext, directive: CompileDirectiveMetadata, reflector: CompileReflector, | ||||
|     bindingParser: BindingParser) { | ||||
|   const name = identifierName(directive.type) !; | ||||
|   const name = identifierName(directive.type)!; | ||||
|   name || error(`Cannot resolver the name of ${directive.type}`); | ||||
| 
 | ||||
|   const definitionField = outputCtx.constantPool.propertyNameOf(DefinitionKind.Directive); | ||||
| @ -306,7 +307,7 @@ export function compileComponentFromRender2( | ||||
|     outputCtx: OutputContext, component: CompileDirectiveMetadata, render3Ast: Render3ParseResult, | ||||
|     reflector: CompileReflector, bindingParser: BindingParser, directiveTypeBySel: Map<string, any>, | ||||
|     pipeTypeByName: Map<string, any>) { | ||||
|   const name = identifierName(component.type) !; | ||||
|   const name = identifierName(component.type)!; | ||||
|   name || error(`Cannot resolver the name of ${component.type}`); | ||||
| 
 | ||||
|   const definitionField = outputCtx.constantPool.propertyNameOf(DefinitionKind.Component); | ||||
| @ -372,7 +373,8 @@ function queriesFromGlobalMetadata( | ||||
|       propertyName: query.propertyName, | ||||
|       first: query.first, | ||||
|       predicate: selectorsFromGlobalMetadata(query.selectors, outputCtx), | ||||
|       descendants: query.descendants, read, | ||||
|       descendants: query.descendants, | ||||
|       read, | ||||
|       static: !!query.static | ||||
|     }; | ||||
|   }); | ||||
| @ -464,7 +466,7 @@ function stringAsType(str: string): o.Type { | ||||
|   return o.expressionType(o.literal(str)); | ||||
| } | ||||
| 
 | ||||
| function stringMapAsType(map: {[key: string]: string | string[]}): o.Type { | ||||
| function stringMapAsType(map: {[key: string]: string|string[]}): o.Type { | ||||
|   const mapValues = Object.keys(map).map(key => { | ||||
|     const value = Array.isArray(map[key]) ? map[key][0] : map[key]; | ||||
|     return { | ||||
| @ -723,7 +725,7 @@ function convertStylingCall( | ||||
| function getBindingNameAndInstruction(binding: ParsedProperty): | ||||
|     {bindingName: string, instruction: o.ExternalReference, isAttribute: boolean} { | ||||
|   let bindingName = binding.name; | ||||
|   let instruction !: o.ExternalReference; | ||||
|   let instruction!: o.ExternalReference; | ||||
| 
 | ||||
|   // Check to see if this is an attr binding or a property binding
 | ||||
|   const attrMatches = bindingName.match(ATTR_REGEX); | ||||
| @ -817,8 +819,7 @@ export interface ParsedHostBindings { | ||||
|   specialAttributes: {styleAttr?: string; classAttr?: string;}; | ||||
| } | ||||
| 
 | ||||
| export function parseHostBindings(host: {[key: string]: string | o.Expression}): | ||||
|     ParsedHostBindings { | ||||
| export function parseHostBindings(host: {[key: string]: string|o.Expression}): ParsedHostBindings { | ||||
|   const attributes: {[key: string]: o.Expression} = {}; | ||||
|   const listeners: {[key: string]: string} = {}; | ||||
|   const properties: {[key: string]: string} = {}; | ||||
| @ -893,5 +894,7 @@ export function verifyHostBindings( | ||||
| 
 | ||||
| function compileStyles(styles: string[], selector: string, hostSelector: string): string[] { | ||||
|   const shadowCss = new ShadowCss(); | ||||
|   return styles.map(style => { return shadowCss !.shimCssText(style, selector, hostSelector); }); | ||||
|   return styles.map(style => { | ||||
|     return shadowCss!.shimCssText(style, selector, hostSelector); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| @ -46,7 +46,7 @@ export class I18nContext { | ||||
|   public placeholders = new Map<string, any[]>(); | ||||
|   public isEmitted: boolean = false; | ||||
| 
 | ||||
|   private _registry !: any; | ||||
|   private _registry!: any; | ||||
|   private _unresolvedCtxCount: number = 0; | ||||
| 
 | ||||
|   constructor( | ||||
| @ -66,9 +66,15 @@ export class I18nContext { | ||||
|     updatePlaceholderMap(this.placeholders, ph, content); | ||||
|   } | ||||
| 
 | ||||
|   get icus() { return this._registry.icus; } | ||||
|   get isRoot() { return this.level === 0; } | ||||
|   get isResolved() { return this._unresolvedCtxCount === 0; } | ||||
|   get icus() { | ||||
|     return this._registry.icus; | ||||
|   } | ||||
|   get isRoot() { | ||||
|     return this.level === 0; | ||||
|   } | ||||
|   get isResolved() { | ||||
|     return this._unresolvedCtxCount === 0; | ||||
|   } | ||||
| 
 | ||||
|   getSerializedPlaceholders() { | ||||
|     const result = new Map<string, any[]>(); | ||||
| @ -78,7 +84,9 @@ export class I18nContext { | ||||
|   } | ||||
| 
 | ||||
|   // public API to accumulate i18n-related content
 | ||||
|   appendBinding(binding: AST) { this.bindings.add(binding); } | ||||
|   appendBinding(binding: AST) { | ||||
|     this.bindings.add(binding); | ||||
|   } | ||||
|   appendIcu(name: string, ref: o.Expression) { | ||||
|     updatePlaceholderMap(this._registry.icus, name, ref); | ||||
|   } | ||||
| @ -181,7 +189,7 @@ function wrapTag(symbol: string, {index, ctx, isVoid}: any, closed?: boolean): s | ||||
|                   wrap(symbol, index, ctx, closed); | ||||
| } | ||||
| 
 | ||||
| function findTemplateFn(ctx: number, templateIndex: number | null) { | ||||
| function findTemplateFn(ctx: number, templateIndex: number|null) { | ||||
|   return (token: any) => typeof token === 'object' && token.type === TagType.TEMPLATE && | ||||
|       token.index === templateIndex && token.ctx === ctx; | ||||
| } | ||||
|  | ||||
| @ -47,23 +47,32 @@ export function createGoogleGetMsgStatements( | ||||
|  * placeholders in `{$placeholder}` (for plain messages) or `{PLACEHOLDER}` (inside ICUs) format. | ||||
|  */ | ||||
| class GetMsgSerializerVisitor implements i18n.Visitor { | ||||
|   private formatPh(value: string): string { return `{$${formatI18nPlaceholderName(value)}}`; } | ||||
|   private formatPh(value: string): string { | ||||
|     return `{$${formatI18nPlaceholderName(value)}}`; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: i18n.Text): any { return text.value; } | ||||
|   visitText(text: i18n.Text): any { | ||||
|     return text.value; | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: i18n.Container): any { | ||||
|     return container.children.map(child => child.visit(this)).join(''); | ||||
|   } | ||||
| 
 | ||||
|   visitIcu(icu: i18n.Icu): any { return serializeIcuNode(icu); } | ||||
|   visitIcu(icu: i18n.Icu): any { | ||||
|     return serializeIcuNode(icu); | ||||
|   } | ||||
| 
 | ||||
|   visitTagPlaceholder(ph: i18n.TagPlaceholder): any { | ||||
|     return ph.isVoid ? | ||||
|         this.formatPh(ph.startName) : | ||||
|         `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${this.formatPh(ph.closeName)}`; | ||||
|         `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${ | ||||
|             this.formatPh(ph.closeName)}`;
 | ||||
|   } | ||||
| 
 | ||||
|   visitPlaceholder(ph: i18n.Placeholder): any { return this.formatPh(ph.name); } | ||||
|   visitPlaceholder(ph: i18n.Placeholder): any { | ||||
|     return this.formatPh(ph.name); | ||||
|   } | ||||
| 
 | ||||
|   visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): any { | ||||
|     return this.formatPh(ph.name); | ||||
|  | ||||
| @ -11,7 +11,9 @@ import * as i18n from '../../../i18n/i18n_ast'; | ||||
| import {formatI18nPlaceholderName} from './util'; | ||||
| 
 | ||||
| class IcuSerializerVisitor implements i18n.Visitor { | ||||
|   visitText(text: i18n.Text): any { return text.value; } | ||||
|   visitText(text: i18n.Text): any { | ||||
|     return text.value; | ||||
|   } | ||||
| 
 | ||||
|   visitContainer(container: i18n.Container): any { | ||||
|     return container.children.map(child => child.visit(this)).join(''); | ||||
| @ -27,10 +29,13 @@ class IcuSerializerVisitor implements i18n.Visitor { | ||||
|   visitTagPlaceholder(ph: i18n.TagPlaceholder): any { | ||||
|     return ph.isVoid ? | ||||
|         this.formatPh(ph.startName) : | ||||
|         `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${this.formatPh(ph.closeName)}`; | ||||
|         `${this.formatPh(ph.startName)}${ph.children.map(child => child.visit(this)).join('')}${ | ||||
|             this.formatPh(ph.closeName)}`;
 | ||||
|   } | ||||
| 
 | ||||
|   visitPlaceholder(ph: i18n.Placeholder): any { return this.formatPh(ph.name); } | ||||
|   visitPlaceholder(ph: i18n.Placeholder): any { | ||||
|     return this.formatPh(ph.name); | ||||
|   } | ||||
| 
 | ||||
|   visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): any { | ||||
|     return this.formatPh(ph.name); | ||||
|  | ||||
| @ -28,7 +28,9 @@ class MessagePiece { | ||||
| } | ||||
| class LiteralPiece extends MessagePiece {} | ||||
| class PlaceholderPiece extends MessagePiece { | ||||
|   constructor(name: string) { super(formatI18nPlaceholderName(name, /* useCamelCase */ false)); } | ||||
|   constructor(name: string) { | ||||
|     super(formatI18nPlaceholderName(name, /* useCamelCase */ false)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | ||||
| @ -8,12 +8,12 @@ | ||||
| 
 | ||||
| import {computeDecimalDigest, computeDigest, decimalDigest} from '../../../i18n/digest'; | ||||
| import * as i18n from '../../../i18n/i18n_ast'; | ||||
| import {VisitNodeFn, createI18nMessageFactory} from '../../../i18n/i18n_parser'; | ||||
| import {createI18nMessageFactory, VisitNodeFn} from '../../../i18n/i18n_parser'; | ||||
| import * as html from '../../../ml_parser/ast'; | ||||
| import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../../ml_parser/interpolation_config'; | ||||
| import * as o from '../../../output/output_ast'; | ||||
| 
 | ||||
| import {I18N_ATTR, I18N_ATTR_PREFIX, hasI18nAttrs, icuFromI18nMessage} from './util'; | ||||
| import {hasI18nAttrs, I18N_ATTR, I18N_ATTR_PREFIX, icuFromI18nMessage} from './util'; | ||||
| 
 | ||||
| export type I18nMeta = { | ||||
|   id?: string, | ||||
| @ -134,10 +134,18 @@ export class I18nMetaVisitor implements html.Visitor { | ||||
|     return expansion; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: html.Text): any { return text; } | ||||
|   visitAttribute(attribute: html.Attribute): any { return attribute; } | ||||
|   visitComment(comment: html.Comment): any { return comment; } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase): any { return expansionCase; } | ||||
|   visitText(text: html.Text): any { | ||||
|     return text; | ||||
|   } | ||||
|   visitAttribute(attribute: html.Attribute): any { | ||||
|     return attribute; | ||||
|   } | ||||
|   visitComment(comment: html.Comment): any { | ||||
|     return comment; | ||||
|   } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase): any { | ||||
|     return expansionCase; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Parse the general form `meta` passed into extract the explicit metadata needed to create a | ||||
|  | ||||
| @ -49,7 +49,7 @@ export function icuFromI18nMessage(message: i18n.Message) { | ||||
|   return message.nodes[0] as i18n.IcuPlaceholder; | ||||
| } | ||||
| 
 | ||||
| export function wrapI18nPlaceholder(content: string | number, contextId: number = 0): string { | ||||
| export function wrapI18nPlaceholder(content: string|number, contextId: number = 0): string { | ||||
|   const blockId = contextId > 0 ? `:${contextId}` : ''; | ||||
|   return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`; | ||||
| } | ||||
| @ -147,7 +147,7 @@ export function formatI18nPlaceholderName(name: string, useCamelCase: boolean = | ||||
|   if (/^\d+$/.test(chunks[chunks.length - 1])) { | ||||
|     postfix = chunks.pop(); | ||||
|   } | ||||
|   let raw = chunks.shift() !.toLowerCase(); | ||||
|   let raw = chunks.shift()!.toLowerCase(); | ||||
|   if (chunks.length) { | ||||
|     raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join(''); | ||||
|   } | ||||
| @ -170,5 +170,5 @@ export function getTranslationConstPrefix(extra: string): string { | ||||
|  */ | ||||
| export function declareI18nVariable(variable: o.ReadVarExpr): o.Statement { | ||||
|   return new o.DeclareVarStmt( | ||||
|       variable.name !, undefined, o.INFERRED_TYPE, null, variable.sourceSpan); | ||||
|       variable.name!, undefined, o.INFERRED_TYPE, null, variable.sourceSpan); | ||||
| } | ||||
|  | ||||
| @ -110,7 +110,11 @@ export function stripUnnecessaryQuotes(value: string): string { | ||||
| } | ||||
| 
 | ||||
| export function hyphenate(value: string): string { | ||||
|   return value.replace(/[a-z][A-Z]/g, v => { | ||||
|   return value | ||||
|       .replace( | ||||
|           /[a-z][A-Z]/g, | ||||
|           v => { | ||||
|             return v.charAt(0) + '-' + v.charAt(1); | ||||
|               }).toLowerCase(); | ||||
|           }) | ||||
|       .toLowerCase(); | ||||
| } | ||||
|  | ||||
| @ -226,7 +226,10 @@ export class StylingBuilder { | ||||
|     const entry: BoundStylingEntry = { | ||||
|       name: property, | ||||
|       sanitize: property ? isStyleSanitizable(property) : true, | ||||
|       unit: unit || bindingUnit, value, sourceSpan, hasOverrideFlag | ||||
|       unit: unit || bindingUnit, | ||||
|       value, | ||||
|       sourceSpan, | ||||
|       hasOverrideFlag | ||||
|     }; | ||||
|     if (isMapBased) { | ||||
|       this._styleMapInput = entry; | ||||
| @ -385,7 +388,7 @@ export class StylingBuilder { | ||||
|         supportsInterpolation: true, | ||||
|         sourceSpan: stylingInput.sourceSpan, | ||||
|         allocateBindingSlots: totalBindingSlotsRequired, | ||||
|         params: (convertFn: (value: any) => o.Expression | o.Expression[]) => { | ||||
|         params: (convertFn: (value: any) => o.Expression|o.Expression[]) => { | ||||
|           const convertResult = convertFn(mapValue); | ||||
|           const params = Array.isArray(convertResult) ? convertResult : [convertResult]; | ||||
|           return params; | ||||
|  | ||||
| @ -22,7 +22,9 @@ import {BoundAttribute, BoundEvent, Element, Node, Reference, Template, TextAttr | ||||
| /** | ||||
|  * A logical target for analysis, which could contain a template or other types of bindings. | ||||
|  */ | ||||
| export interface Target { template?: Node[]; } | ||||
| export interface Target { | ||||
|   template?: Node[]; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Metadata regarding a directive that's needed to match it against template elements. This is | ||||
| @ -44,7 +46,7 @@ export interface DirectiveMeta { | ||||
|    * | ||||
|    * Goes from property names to field names. | ||||
|    */ | ||||
|   inputs: {[property: string]: string | [string, string]}; | ||||
|   inputs: {[property: string]: string|[string, string]}; | ||||
| 
 | ||||
|   /** | ||||
|    * Set of outputs which this directive claims. | ||||
| @ -67,7 +69,9 @@ export interface DirectiveMeta { | ||||
|  * | ||||
|  * The returned `BoundTarget` has an API for extracting information about the processed target. | ||||
|  */ | ||||
| export interface TargetBinder<D extends DirectiveMeta> { bind(target: Target): BoundTarget<D>; } | ||||
| export interface TargetBinder<D extends DirectiveMeta> { | ||||
|   bind(target: Target): BoundTarget<D>; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Result of performing the binding operation against a `Target`. | ||||
|  | ||||
| @ -152,7 +152,7 @@ class Scope implements Visitor { | ||||
|   lookup(name: string): Reference|Variable|null { | ||||
|     if (this.namedEntities.has(name)) { | ||||
|       // Found in the local scope.
 | ||||
|       return this.namedEntities.get(name) !; | ||||
|       return this.namedEntities.get(name)!; | ||||
|     } else if (this.parentScope !== undefined) { | ||||
|       // Not in the local scope, but there's a parent scope so check there.
 | ||||
|       return this.parentScope.lookup(name); | ||||
| @ -217,11 +217,17 @@ class DirectiveBinder<DirectiveT extends DirectiveMeta> implements Visitor { | ||||
|     return {directives, bindings, references}; | ||||
|   } | ||||
| 
 | ||||
|   private ingest(template: Node[]): void { template.forEach(node => node.visit(this)); } | ||||
|   private ingest(template: Node[]): void { | ||||
|     template.forEach(node => node.visit(this)); | ||||
|   } | ||||
| 
 | ||||
|   visitElement(element: Element): void { this.visitElementOrTemplate(element.name, element); } | ||||
|   visitElement(element: Element): void { | ||||
|     this.visitElementOrTemplate(element.name, element); | ||||
|   } | ||||
| 
 | ||||
|   visitTemplate(template: Template): void { this.visitElementOrTemplate('ng-template', template); } | ||||
|   visitTemplate(template: Template): void { | ||||
|     this.visitElementOrTemplate('ng-template', template); | ||||
|   } | ||||
| 
 | ||||
|   visitElementOrTemplate(elementName: string, node: Element|Template): void { | ||||
|     // First, determine the HTML shape of the node for the purpose of directive matching.
 | ||||
| @ -269,7 +275,7 @@ class DirectiveBinder<DirectiveT extends DirectiveMeta> implements Visitor { | ||||
|     }); | ||||
| 
 | ||||
|     // Associate attributes/bindings on the node with directives or with the node itself.
 | ||||
|     type BoundNode = BoundAttribute | BoundEvent | TextAttribute; | ||||
|     type BoundNode = BoundAttribute|BoundEvent|TextAttribute; | ||||
|     const setAttributeBinding = | ||||
|         (attribute: BoundNode, ioType: keyof Pick<DirectiveMeta, 'inputs'|'outputs'>) => { | ||||
|           const dir = directives.find(dir => dir[ioType].hasOwnProperty(attribute.name)); | ||||
| @ -432,11 +438,17 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor { | ||||
| 
 | ||||
|   // The remaining visitors are concerned with processing AST expressions within template bindings
 | ||||
| 
 | ||||
|   visitBoundAttribute(attribute: BoundAttribute) { attribute.value.visit(this); } | ||||
|   visitBoundAttribute(attribute: BoundAttribute) { | ||||
|     attribute.value.visit(this); | ||||
|   } | ||||
| 
 | ||||
|   visitBoundEvent(event: BoundEvent) { event.handler.visit(this); } | ||||
|   visitBoundEvent(event: BoundEvent) { | ||||
|     event.handler.visit(this); | ||||
|   } | ||||
| 
 | ||||
|   visitBoundText(text: BoundText) { text.value.visit(this); } | ||||
|   visitBoundText(text: BoundText) { | ||||
|     text.value.visit(this); | ||||
|   } | ||||
|   visitPipe(ast: BindingPipe, context: any): any { | ||||
|     this.usedPipes.add(ast.name); | ||||
|     return super.visitPipe(ast, context); | ||||
| @ -526,7 +538,9 @@ export class R3BoundTarget<DirectiveT extends DirectiveMeta> implements BoundTar | ||||
|     return this.symbols.get(symbol) || null; | ||||
|   } | ||||
| 
 | ||||
|   getNestingLevel(template: Template): number { return this.nestingLevel.get(template) || 0; } | ||||
|   getNestingLevel(template: Template): number { | ||||
|     return this.nestingLevel.get(template) || 0; | ||||
|   } | ||||
| 
 | ||||
|   getUsedDirectives(): DirectiveT[] { | ||||
|     const set = new Set<DirectiveT>(); | ||||
| @ -534,5 +548,7 @@ export class R3BoundTarget<DirectiveT extends DirectiveMeta> implements BoundTar | ||||
|     return Array.from(set.values()); | ||||
|   } | ||||
| 
 | ||||
|   getUsedPipes(): string[] { return Array.from(this.usedPipes); } | ||||
|   getUsedPipes(): string[] { | ||||
|     return Array.from(this.usedPipes); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  */ | ||||
| 
 | ||||
| import {flatten, sanitizeIdentifier} from '../../compile_metadata'; | ||||
| import {BindingForm, BuiltinFunctionCall, LocalResolver, convertActionBinding, convertPropertyBinding, convertUpdateArguments} from '../../compiler_util/expression_converter'; | ||||
| import {BindingForm, BuiltinFunctionCall, convertActionBinding, convertPropertyBinding, convertUpdateArguments, LocalResolver} from '../../compiler_util/expression_converter'; | ||||
| import {ConstantPool} from '../../constant_pool'; | ||||
| import * as core from '../../core'; | ||||
| import {AST, AstMemoryEfficientTransformer, BindingPipe, BindingType, FunctionCall, ImplicitReceiver, Interpolation, LiteralArray, LiteralMap, LiteralPrimitive, ParsedEventType, PropertyRead} from '../../expression_parser/ast'; | ||||
| @ -36,9 +36,9 @@ import {I18nContext} from './i18n/context'; | ||||
| import {createGoogleGetMsgStatements} from './i18n/get_msg_utils'; | ||||
| import {createLocalizeStatements} from './i18n/localize_utils'; | ||||
| import {I18nMetaVisitor} from './i18n/meta'; | ||||
| import {I18N_ICU_MAPPING_PREFIX, TRANSLATION_PREFIX, assembleBoundTextPlaceholders, assembleI18nBoundString, declareI18nVariable, getTranslationConstPrefix, i18nFormatPlaceholderNames, icuFromI18nMessage, isI18nRootNode, isSingleI18nIcu, placeholdersToParams, wrapI18nPlaceholder} from './i18n/util'; | ||||
| import {assembleBoundTextPlaceholders, assembleI18nBoundString, declareI18nVariable, getTranslationConstPrefix, I18N_ICU_MAPPING_PREFIX, i18nFormatPlaceholderNames, icuFromI18nMessage, isI18nRootNode, isSingleI18nIcu, placeholdersToParams, TRANSLATION_PREFIX, wrapI18nPlaceholder} from './i18n/util'; | ||||
| import {StylingBuilder, StylingInstruction} from './styling_builder'; | ||||
| import {CONTEXT_NAME, IMPLICIT_REFERENCE, NON_BINDABLE_ATTR, REFERENCE_PREFIX, RENDER_FLAGS, asLiteral, chainedInstruction, getAttrsForDirectiveMatching, getInterpolationArgsLength, invalid, trimTrailingNulls, unsupported} from './util'; | ||||
| import {asLiteral, chainedInstruction, CONTEXT_NAME, getAttrsForDirectiveMatching, getInterpolationArgsLength, IMPLICIT_REFERENCE, invalid, NON_BINDABLE_ATTR, REFERENCE_PREFIX, RENDER_FLAGS, trimTrailingNulls, unsupported} from './util'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -61,8 +61,8 @@ export function renderFlagCheckIfStmt( | ||||
| } | ||||
| 
 | ||||
| export function prepareEventListenerParameters( | ||||
|     eventAst: t.BoundEvent, handlerName: string | null = null, | ||||
|     scope: BindingScope | null = null): o.Expression[] { | ||||
|     eventAst: t.BoundEvent, handlerName: string|null = null, | ||||
|     scope: BindingScope|null = null): o.Expression[] { | ||||
|   const {type, name, target, phase, handler} = eventAst; | ||||
|   if (target && !GLOBAL_TARGET_RESOLVERS.has(target)) { | ||||
|     throw new Error(`Unexpected global target '${target}' defined for '${name}' event.
 | ||||
| @ -85,7 +85,7 @@ export function prepareEventListenerParameters( | ||||
|   statements.push(...bindingExpr.render3Stmts); | ||||
| 
 | ||||
|   const eventName: string = | ||||
|       type === ParsedEventType.Animation ? prepareSyntheticListenerName(name, phase !) : name; | ||||
|       type === ParsedEventType.Animation ? prepareSyntheticListenerName(name, phase!) : name; | ||||
|   const fnName = handlerName && sanitizeIdentifier(handlerName); | ||||
|   const fnArgs: o.FnParam[] = []; | ||||
| 
 | ||||
| @ -98,7 +98,7 @@ export function prepareEventListenerParameters( | ||||
|   if (target) { | ||||
|     params.push( | ||||
|         o.literal(false),  // `useCapture` flag, defaults to `false`
 | ||||
|         o.importExpr(GLOBAL_TARGET_RESOLVERS.get(target) !)); | ||||
|         o.importExpr(GLOBAL_TARGET_RESOLVERS.get(target)!)); | ||||
|   } | ||||
|   return params; | ||||
| } | ||||
| @ -207,12 +207,12 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     // - this template has parent i18n context
 | ||||
|     // - or the template has i18n meta associated with it,
 | ||||
|     //   but it's not initiated by the Element (e.g. <ng-template i18n>)
 | ||||
|     const initI18nContext = | ||||
|         this.i18nContext || (isI18nRootNode(i18n) && !isSingleI18nIcu(i18n) && | ||||
|     const initI18nContext = this.i18nContext || | ||||
|         (isI18nRootNode(i18n) && !isSingleI18nIcu(i18n) && | ||||
|          !(isSingleElementTemplate(nodes) && nodes[0].i18n === i18n)); | ||||
|     const selfClosingI18nInstruction = hasTextChildrenOnly(nodes); | ||||
|     if (initI18nContext) { | ||||
|       this.i18nStart(null, i18n !, selfClosingI18nInstruction); | ||||
|       this.i18nStart(null, i18n!, selfClosingI18nInstruction); | ||||
|     } | ||||
| 
 | ||||
|     // This is the initial pass through the nodes of this template. In this pass, we
 | ||||
| @ -295,10 +295,14 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|   } | ||||
| 
 | ||||
|   // LocalResolver
 | ||||
|   getLocal(name: string): o.Expression|null { return this._bindingScope.get(name); } | ||||
|   getLocal(name: string): o.Expression|null { | ||||
|     return this._bindingScope.get(name); | ||||
|   } | ||||
| 
 | ||||
|   // LocalResolver
 | ||||
|   notifyImplicitReceiverUse(): void { this._bindingScope.notifyImplicitReceiverUse(); } | ||||
|   notifyImplicitReceiverUse(): void { | ||||
|     this._bindingScope.notifyImplicitReceiverUse(); | ||||
|   } | ||||
| 
 | ||||
|   private i18nTranslate( | ||||
|       message: i18n.Message, params: {[name: string]: o.Expression} = {}, ref?: o.ReadVarExpr, | ||||
| @ -335,12 +339,11 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
| 
 | ||||
|   private i18nAppendBindings(expressions: AST[]) { | ||||
|     if (expressions.length > 0) { | ||||
|       expressions.forEach(expression => this.i18n !.appendBinding(expression)); | ||||
|       expressions.forEach(expression => this.i18n!.appendBinding(expression)); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   private i18nBindProps(props: {[key: string]: t.Text | t.BoundText}): | ||||
|       {[key: string]: o.Expression} { | ||||
|   private i18nBindProps(props: {[key: string]: t.Text|t.BoundText}): {[key: string]: o.Expression} { | ||||
|     const bound: {[key: string]: o.Expression} = {}; | ||||
|     Object.keys(props).forEach(key => { | ||||
|       const prop = props[key]; | ||||
| @ -351,7 +354,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|         this.allocateBindingSlots(value); | ||||
|         if (value instanceof Interpolation) { | ||||
|           const {strings, expressions} = value; | ||||
|           const {id, bindings} = this.i18n !; | ||||
|           const {id, bindings} = this.i18n!; | ||||
|           const label = assembleI18nBoundString(strings, bindings.size, id); | ||||
|           this.i18nAppendBindings(expressions); | ||||
|           bound[key] = o.literal(label); | ||||
| @ -424,7 +427,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|       void { | ||||
|     const index = this.allocateDataSlot(); | ||||
|     if (this.i18nContext) { | ||||
|       this.i18n = this.i18nContext.forkChildContext(index, this.templateIndex !, meta); | ||||
|       this.i18n = this.i18nContext.forkChildContext(index, this.templateIndex!, meta); | ||||
|     } else { | ||||
|       const ref = o.variable(this.constantPool.uniqueName(TRANSLATION_PREFIX)); | ||||
|       this.i18n = new I18nContext(index, ref, 0, this.templateIndex, meta); | ||||
| @ -479,7 +482,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     const i18nAttrArgs: o.Expression[] = []; | ||||
|     const bindings: ChainableBindingInstruction[] = []; | ||||
|     attrs.forEach(attr => { | ||||
|       const message = attr.i18n !as i18n.Message; | ||||
|       const message = attr.i18n! as i18n.Message; | ||||
|       if (attr instanceof t.TextAttribute) { | ||||
|         i18nAttrArgs.push(o.literal(attr.name), this.i18nTranslate(message)); | ||||
|       } else { | ||||
| @ -559,7 +562,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
| 
 | ||||
|     this.creationInstruction(ngContent.sourceSpan, R3.projection, parameters); | ||||
|     if (this.i18n) { | ||||
|       this.i18n.appendProjection(ngContent.i18n !, slot); | ||||
|       this.i18n.appendProjection(ngContent.i18n!, slot); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -571,7 +574,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     const isI18nRootElement: boolean = | ||||
|         isI18nRootNode(element.i18n) && !isSingleI18nIcu(element.i18n); | ||||
| 
 | ||||
|     const i18nAttrs: (t.TextAttribute | t.BoundAttribute)[] = []; | ||||
|     const i18nAttrs: (t.TextAttribute|t.BoundAttribute)[] = []; | ||||
|     const outputAttrs: t.TextAttribute[] = []; | ||||
| 
 | ||||
|     const [namespaceKey, elementName] = splitNsName(element.name); | ||||
| @ -633,7 +636,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     } | ||||
| 
 | ||||
|     if (this.i18n) { | ||||
|       this.i18n.appendElement(element.i18n !, elementIndex); | ||||
|       this.i18n.appendElement(element.i18n!, elementIndex); | ||||
|     } | ||||
| 
 | ||||
|     // Note that we do not append text node instructions and ICUs inside i18n section,
 | ||||
| @ -676,7 +679,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|       // Note: it's important to keep i18n/i18nStart instructions after i18nAttributes and
 | ||||
|       // listeners, to make sure i18nAttributes instruction targets current element at runtime.
 | ||||
|       if (isI18nRootElement) { | ||||
|         this.i18nStart(element.sourceSpan, element.i18n !, createSelfClosingI18nInstruction); | ||||
|         this.i18nStart(element.sourceSpan, element.i18n!, createSelfClosingI18nInstruction); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
| @ -757,7 +760,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|               propertyBindings.push({ | ||||
|                 name: attrName, | ||||
|                 sourceSpan: input.sourceSpan, | ||||
|                 value: () => this.convertPropertyBinding(value), params | ||||
|                 value: () => this.convertPropertyBinding(value), | ||||
|                 params | ||||
|               }); | ||||
|             } | ||||
|           } else if (inputType === BindingType.Attribute) { | ||||
| @ -773,7 +777,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|               attributeBindings.push({ | ||||
|                 name: attrName, | ||||
|                 sourceSpan: input.sourceSpan, | ||||
|                 value: () => this.convertPropertyBinding(boundValue), params | ||||
|                 value: () => this.convertPropertyBinding(boundValue), | ||||
|                 params | ||||
|               }); | ||||
|             } | ||||
|           } else { | ||||
| @ -801,7 +806,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     t.visitAll(this, element.children); | ||||
| 
 | ||||
|     if (!isI18nRootElement && this.i18n) { | ||||
|       this.i18n.appendElement(element.i18n !, elementIndex, true); | ||||
|       this.i18n.appendElement(element.i18n!, elementIndex, true); | ||||
|     } | ||||
| 
 | ||||
|     if (!createSelfClosingInstruction) { | ||||
| @ -823,7 +828,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     const templateIndex = this.allocateDataSlot(); | ||||
| 
 | ||||
|     if (this.i18n) { | ||||
|       this.i18n.appendTemplate(template.i18n !, templateIndex); | ||||
|       this.i18n.appendTemplate(template.i18n!, templateIndex); | ||||
|     } | ||||
| 
 | ||||
|     const tagName = sanitizeIdentifier(template.tagName || ''); | ||||
| @ -892,7 +897,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     // Only add normal input/output binding instructions on explicit <ng-template> elements.
 | ||||
|     if (template.tagName === NG_TEMPLATE_TAG_NAME) { | ||||
|       const inputs: t.BoundAttribute[] = []; | ||||
|       const i18nAttrs: (t.TextAttribute | t.BoundAttribute)[] = | ||||
|       const i18nAttrs: (t.TextAttribute|t.BoundAttribute)[] = | ||||
|           template.attributes.filter(attr => !!attr.i18n); | ||||
| 
 | ||||
|       template.inputs.forEach( | ||||
| @ -935,7 +940,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|       const value = text.value.visit(this._valueConverter); | ||||
|       this.allocateBindingSlots(value); | ||||
|       if (value instanceof Interpolation) { | ||||
|         this.i18n.appendBoundText(text.i18n !); | ||||
|         this.i18n.appendBoundText(text.i18n!); | ||||
|         this.i18nAppendBindings(value.expressions); | ||||
|       } | ||||
|       return; | ||||
| @ -975,15 +980,15 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     // to generate i18n context and the necessary instructions
 | ||||
|     if (!this.i18n) { | ||||
|       initWasInvoked = true; | ||||
|       this.i18nStart(null, icu.i18n !, true); | ||||
|       this.i18nStart(null, icu.i18n!, true); | ||||
|     } | ||||
| 
 | ||||
|     const i18n = this.i18n !; | ||||
|     const i18n = this.i18n!; | ||||
|     const vars = this.i18nBindProps(icu.vars); | ||||
|     const placeholders = this.i18nBindProps(icu.placeholders); | ||||
| 
 | ||||
|     // output ICU directly and keep ICU reference in context
 | ||||
|     const message = icu.i18n !as i18n.Message; | ||||
|     const message = icu.i18n! as i18n.Message; | ||||
| 
 | ||||
|     // we always need post-processing function for ICUs, to make sure that:
 | ||||
|     // - all placeholders in a form of {PLACEHOLDER} are replaced with actual values (note:
 | ||||
| @ -1016,13 +1021,21 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   private allocateDataSlot() { return this._dataIndex++; } | ||||
|   private allocateDataSlot() { | ||||
|     return this._dataIndex++; | ||||
|   } | ||||
| 
 | ||||
|   getConstCount() { return this._dataIndex; } | ||||
|   getConstCount() { | ||||
|     return this._dataIndex; | ||||
|   } | ||||
| 
 | ||||
|   getVarCount() { return this._pureFunctionSlots; } | ||||
|   getVarCount() { | ||||
|     return this._pureFunctionSlots; | ||||
|   } | ||||
| 
 | ||||
|   getConsts() { return this._constants; } | ||||
|   getConsts() { | ||||
|     return this._constants; | ||||
|   } | ||||
| 
 | ||||
|   getNgContentSelectors(): o.Expression|null { | ||||
|     return this._ngContentReservedSlots.length ? | ||||
| @ -1030,7 +1043,9 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|         null; | ||||
|   } | ||||
| 
 | ||||
|   private bindingContext() { return `${this._bindingContext++}`; } | ||||
|   private bindingContext() { | ||||
|     return `${this._bindingContext++}`; | ||||
|   } | ||||
| 
 | ||||
|   private templatePropertyBindings( | ||||
|       templateIndex: number, attrs: (t.BoundAttribute|t.TextAttribute)[]) { | ||||
| @ -1092,8 +1107,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|         calls.push({ | ||||
|           sourceSpan: call.sourceSpan, | ||||
|           value: () => { | ||||
|             return call | ||||
|                 .params( | ||||
|             return call.params( | ||||
|                        value => (call.supportsInterpolation && value instanceof Interpolation) ? | ||||
|                            this.getUpdateInstructionArguments(value) : | ||||
|                            this.convertPropertyBinding(value)) as o.Expression[]; | ||||
| @ -1114,7 +1128,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|   } | ||||
| 
 | ||||
|   private creationInstructionChain(reference: o.ExternalReference, calls: { | ||||
|     sourceSpan: ParseSourceSpan | null, | ||||
|     sourceSpan: ParseSourceSpan|null, | ||||
|     params: () => o.Expression[] | ||||
|   }[]) { | ||||
|     const span = calls.length ? calls[0].sourceSpan : null; | ||||
| @ -1228,8 +1242,9 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|   private matchDirectives(elementName: string, elOrTpl: t.Element|t.Template) { | ||||
|     if (this.directiveMatcher) { | ||||
|       const selector = createCssSelector(elementName, getAttrsForDirectiveMatching(elOrTpl)); | ||||
|       this.directiveMatcher.match( | ||||
|           selector, (cssSelector, staticType) => { this.directives.add(staticType); }); | ||||
|       this.directiveMatcher.match(selector, (cssSelector, staticType) => { | ||||
|         this.directives.add(staticType); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -1277,7 +1292,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|       attrExprs.push(...getNgProjectAsLiteral(ngProjectAsAttr)); | ||||
|     } | ||||
| 
 | ||||
|     function addAttrExpr(key: string | number, value?: o.Expression): void { | ||||
|     function addAttrExpr(key: string|number, value?: o.Expression): void { | ||||
|       if (typeof key === 'string') { | ||||
|         if (!alreadySeen.has(key)) { | ||||
|           attrExprs.push(...getAttributeNameLiterals(key)); | ||||
| @ -1390,7 +1405,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver | ||||
|       const eventName: string = outputAst.name; | ||||
|       const bindingFnName = outputAst.type === ParsedEventType.Animation ? | ||||
|           // synthetic @listener.foo values are treated the exact same as are standard listeners
 | ||||
|           prepareSyntheticListenerFunctionName(eventName, outputAst.phase !) : | ||||
|           prepareSyntheticListenerFunctionName(eventName, outputAst.phase!) : | ||||
|           sanitizeIdentifier(eventName); | ||||
|       const handlerName = `${this.templateName}_${tagName}_${bindingFnName}_${index}_listener`; | ||||
|       const scope = this._bindingScope.nestedScope(this._bindingScope.bindingLevel); | ||||
| @ -1492,7 +1507,7 @@ function pureFunctionCallInfo(args: o.Expression[]) { | ||||
| } | ||||
| 
 | ||||
| function instruction( | ||||
|     span: ParseSourceSpan | null, reference: o.ExternalReference, | ||||
|     span: ParseSourceSpan|null, reference: o.ExternalReference, | ||||
|     params: o.Expression[]): o.Expression { | ||||
|   return o.importExpr(reference, null, span).callFn(params, span); | ||||
| } | ||||
| @ -1504,7 +1519,7 @@ function generateNextContextExpr(relativeLevelDiff: number): o.Expression { | ||||
| } | ||||
| 
 | ||||
| function getLiteralFactory( | ||||
|     constantPool: ConstantPool, literal: o.LiteralArrayExpr | o.LiteralMapExpr, | ||||
|     constantPool: ConstantPool, literal: o.LiteralArrayExpr|o.LiteralMapExpr, | ||||
|     allocateSlots: (numSlots: number) => number): o.Expression { | ||||
|   const {literalFactory, literalFactoryArguments} = constantPool.getLiteralFactory(literal); | ||||
|   // Allocate 1 slot for the result plus 1 per argument
 | ||||
| @ -1570,9 +1585,8 @@ const SHARED_CONTEXT_KEY = '$$shared_ctx$$'; | ||||
|  * declaration should always come before the local ref declaration. | ||||
|  */ | ||||
| type BindingData = { | ||||
|   retrievalLevel: number; lhs: o.Expression; declareLocalCallback?: DeclareLocalVarCallback; | ||||
|   declare: boolean; | ||||
|   priority: number; | ||||
|   retrievalLevel: number; lhs: o.Expression; | ||||
|   declareLocalCallback?: DeclareLocalVarCallback; declare: boolean; priority: number; | ||||
|   localRef: boolean; | ||||
| }; | ||||
| 
 | ||||
| @ -1580,7 +1594,11 @@ type BindingData = { | ||||
|  * The sorting priority of a local variable declaration. Higher numbers | ||||
|  * mean the declaration will appear first in the generated code. | ||||
|  */ | ||||
| const enum DeclarationPriority { DEFAULT = 0, CONTEXT = 1, SHARED_CONTEXT = 2 } | ||||
| const enum DeclarationPriority { | ||||
|   DEFAULT = 0, | ||||
|   CONTEXT = 1, | ||||
|   SHARED_CONTEXT = 2 | ||||
| } | ||||
| 
 | ||||
| export class BindingScope implements LocalResolver { | ||||
|   /** Keeps a map from local variables to their BindingData. */ | ||||
| @ -1669,7 +1687,9 @@ export class BindingScope implements LocalResolver { | ||||
|   } | ||||
| 
 | ||||
|   // Implemented as part of LocalResolver.
 | ||||
|   getLocal(name: string): (o.Expression|null) { return this.get(name); } | ||||
|   getLocal(name: string): (o.Expression|null) { | ||||
|     return this.get(name); | ||||
|   } | ||||
| 
 | ||||
|   // Implemented as part of LocalResolver.
 | ||||
|   notifyImplicitReceiverUse(): void { | ||||
| @ -1677,7 +1697,7 @@ export class BindingScope implements LocalResolver { | ||||
|       // Since the implicit receiver is accessed in an embedded view, we need to
 | ||||
|       // ensure that we declare a shared context variable for the current template
 | ||||
|       // in the update variables.
 | ||||
|       this.map.get(SHARED_CONTEXT_KEY + 0) !.declare = true; | ||||
|       this.map.get(SHARED_CONTEXT_KEY + 0)!.declare = true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -1698,7 +1718,7 @@ export class BindingScope implements LocalResolver { | ||||
|       this.generateSharedContextVar(retrievalLevel); | ||||
|     } | ||||
|     // Shared context variables are always generated as "ReadVarExpr".
 | ||||
|     return this.map.get(bindingKey) !.lhs as o.ReadVarExpr; | ||||
|     return this.map.get(bindingKey)!.lhs as o.ReadVarExpr; | ||||
|   } | ||||
| 
 | ||||
|   getSharedContextName(retrievalLevel: number): o.ReadVarExpr|null { | ||||
| @ -1735,7 +1755,7 @@ export class BindingScope implements LocalResolver { | ||||
|   } | ||||
| 
 | ||||
|   getComponentProperty(name: string): o.Expression { | ||||
|     const componentValue = this.map.get(SHARED_CONTEXT_KEY + 0) !; | ||||
|     const componentValue = this.map.get(SHARED_CONTEXT_KEY + 0)!; | ||||
|     componentValue.declare = true; | ||||
|     this.maybeRestoreView(0, false); | ||||
|     return componentValue.lhs.prop(name); | ||||
| @ -1748,11 +1768,11 @@ export class BindingScope implements LocalResolver { | ||||
|     // 2 - we are looking up a local ref, which requires restoring the view where the local
 | ||||
|     // ref is stored
 | ||||
|     if (this.isListenerScope() && (retrievalLevel < this.bindingLevel || localRefLookup)) { | ||||
|       if (!this.parent !.restoreViewVariable) { | ||||
|       if (!this.parent!.restoreViewVariable) { | ||||
|         // parent saves variable to generate a shared `const $s$ = getCurrentView();` instruction
 | ||||
|         this.parent !.restoreViewVariable = o.variable(this.parent !.freshReferenceName()); | ||||
|         this.parent!.restoreViewVariable = o.variable(this.parent!.freshReferenceName()); | ||||
|       } | ||||
|       this.restoreViewVariable = this.parent !.restoreViewVariable; | ||||
|       this.restoreViewVariable = this.parent!.restoreViewVariable; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -1771,7 +1791,9 @@ export class BindingScope implements LocalResolver { | ||||
|         []; | ||||
|   } | ||||
| 
 | ||||
|   isListenerScope() { return this.parent && this.parent.bindingLevel === this.bindingLevel; } | ||||
|   isListenerScope() { | ||||
|     return this.parent && this.parent.bindingLevel === this.bindingLevel; | ||||
|   } | ||||
| 
 | ||||
|   variableDeclarations(): o.Statement[] { | ||||
|     let currentContextLevel = 0; | ||||
| @ -1780,7 +1802,8 @@ export class BindingScope implements LocalResolver { | ||||
|                .sort((a, b) => b.retrievalLevel - a.retrievalLevel || b.priority - a.priority) | ||||
|                .reduce((stmts: o.Statement[], value: BindingData) => { | ||||
|                  const levelDiff = this.bindingLevel - value.retrievalLevel; | ||||
|           const currStmts = value.declareLocalCallback !(this, levelDiff - currentContextLevel); | ||||
|                  const currStmts = | ||||
|                      value.declareLocalCallback!(this, levelDiff - currentContextLevel); | ||||
|                  currentContextLevel = levelDiff; | ||||
|                  return stmts.concat(currStmts); | ||||
|                }, []) as o.Statement[]; | ||||
| @ -2126,7 +2149,8 @@ export function getTranslationDeclStmts( | ||||
|   const statements: o.Statement[] = [ | ||||
|     declareI18nVariable(variable), | ||||
|     o.ifStmt( | ||||
|         createClosureModeGuard(), createGoogleGetMsgStatements( | ||||
|         createClosureModeGuard(), | ||||
|         createGoogleGetMsgStatements( | ||||
|             variable, message, closureVar, | ||||
|             i18nFormatPlaceholderNames(params, /* useCamelCase */ true)), | ||||
|         createLocalizeStatements( | ||||
|  | ||||
| @ -69,7 +69,7 @@ export function unsupported(this: void|Function, feature: string): never { | ||||
|   throw new Error(`Feature ${feature} is not supported yet`); | ||||
| } | ||||
| 
 | ||||
| export function invalid<T>(this: t.Visitor, arg: o.Expression | o.Statement | t.Node): never { | ||||
| export function invalid<T>(this: t.Visitor, arg: o.Expression|o.Statement|t.Node): never { | ||||
|   throw new Error( | ||||
|       `Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`); | ||||
| } | ||||
| @ -82,7 +82,7 @@ export function asLiteral(value: any): o.Expression { | ||||
| } | ||||
| 
 | ||||
| export function conditionallyCreateMapObjectLiteral( | ||||
|     keys: {[key: string]: string | string[]}, keepDeclared?: boolean): o.Expression|null { | ||||
|     keys: {[key: string]: string|string[]}, keepDeclared?: boolean): o.Expression|null { | ||||
|   if (Object.getOwnPropertyNames(keys).length > 0) { | ||||
|     return mapToExpression(keys, keepDeclared); | ||||
|   } | ||||
| @ -90,7 +90,7 @@ export function conditionallyCreateMapObjectLiteral( | ||||
| } | ||||
| 
 | ||||
| function mapToExpression( | ||||
|     map: {[key: string]: string | string[]}, keepDeclared?: boolean): o.Expression { | ||||
|     map: {[key: string]: string|string[]}, keepDeclared?: boolean): o.Expression { | ||||
|   return o.literalMap(Object.getOwnPropertyNames(map).map(key => { | ||||
|     // canonical syntax: `dirProp: publicProp`
 | ||||
|     // if there is no `:`, use dirProp = elProp
 | ||||
| @ -153,7 +153,9 @@ export class DefinitionMap { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   toLiteralMap(): o.LiteralMapExpr { return o.literalMap(this.values); } | ||||
|   toLiteralMap(): o.LiteralMapExpr { | ||||
|     return o.literalMap(this.values); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -165,8 +167,8 @@ export class DefinitionMap { | ||||
|  * object maps a property name to its (static) value. For any bindings, this map simply maps the | ||||
|  * property name to an empty string. | ||||
|  */ | ||||
| export function getAttrsForDirectiveMatching(elOrTpl: t.Element | t.Template): | ||||
|     {[name: string]: string} { | ||||
| export function getAttrsForDirectiveMatching(elOrTpl: t.Element| | ||||
|                                              t.Template): {[name: string]: string} { | ||||
|   const attributesMap: {[name: string]: string} = {}; | ||||
| 
 | ||||
| 
 | ||||
| @ -179,8 +181,12 @@ export function getAttrsForDirectiveMatching(elOrTpl: t.Element | t.Template): | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     elOrTpl.inputs.forEach(i => { attributesMap[i.name] = ''; }); | ||||
|     elOrTpl.outputs.forEach(o => { attributesMap[o.name] = ''; }); | ||||
|     elOrTpl.inputs.forEach(i => { | ||||
|       attributesMap[i.name] = ''; | ||||
|     }); | ||||
|     elOrTpl.outputs.forEach(o => { | ||||
|       attributesMap[o.name] = ''; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   return attributesMap; | ||||
| @ -188,7 +194,7 @@ export function getAttrsForDirectiveMatching(elOrTpl: t.Element | t.Template): | ||||
| 
 | ||||
| /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */ | ||||
| export function chainedInstruction( | ||||
|     reference: o.ExternalReference, calls: o.Expression[][], span?: ParseSourceSpan | null) { | ||||
|     reference: o.ExternalReference, calls: o.Expression[][], span?: ParseSourceSpan|null) { | ||||
|   let expression = o.importExpr(reference, null, span) as o.Expression; | ||||
| 
 | ||||
|   if (calls.length > 0) { | ||||
|  | ||||
| @ -11,5 +11,7 @@ | ||||
|  * to load templates. | ||||
|  */ | ||||
| export class ResourceLoader { | ||||
|   get(url: string): Promise<string>|string { return ''; } | ||||
|   get(url: string): Promise<string>|string { | ||||
|     return ''; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -253,7 +253,9 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry { | ||||
|       typeNames.split(',').forEach(tag => this._schema[tag.toLowerCase()] = type); | ||||
|       const superType = superName && this._schema[superName.toLowerCase()]; | ||||
|       if (superType) { | ||||
|         Object.keys(superType).forEach((prop: string) => { type[prop] = superType[prop]; }); | ||||
|         Object.keys(superType).forEach((prop: string) => { | ||||
|           type[prop] = superType[prop]; | ||||
|         }); | ||||
|       } | ||||
|       properties.forEach((property: string) => { | ||||
|         if (property.length > 0) { | ||||
| @ -350,9 +352,13 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry { | ||||
|     return ctx ? ctx : SecurityContext.NONE; | ||||
|   } | ||||
| 
 | ||||
|   getMappedPropName(propName: string): string { return _ATTR_TO_PROP[propName] || propName; } | ||||
|   getMappedPropName(propName: string): string { | ||||
|     return _ATTR_TO_PROP[propName] || propName; | ||||
|   } | ||||
| 
 | ||||
|   getDefaultComponentElementName(): string { return 'ng-component'; } | ||||
|   getDefaultComponentElementName(): string { | ||||
|     return 'ng-component'; | ||||
|   } | ||||
| 
 | ||||
|   validateProperty(name: string): {error: boolean, msg?: string} { | ||||
|     if (name.toLowerCase().startsWith('on')) { | ||||
| @ -376,7 +382,9 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   allKnownElementNames(): string[] { return Object.keys(this._schema); } | ||||
|   allKnownElementNames(): string[] { | ||||
|     return Object.keys(this._schema); | ||||
|   } | ||||
| 
 | ||||
|   normalizeAnimationStyleProperty(propName: string): string { | ||||
|     return dashCaseToCamelCase(propName); | ||||
| @ -386,7 +394,7 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry { | ||||
|       {error: string, value: string} { | ||||
|     let unit: string = ''; | ||||
|     const strVal = val.toString().trim(); | ||||
|     let errorMsg: string = null !; | ||||
|     let errorMsg: string = null!; | ||||
| 
 | ||||
|     if (_isPixelDimensionStyle(camelCaseProp) && val !== 0 && val !== '0') { | ||||
|       if (typeof val === 'number') { | ||||
|  | ||||
| @ -20,7 +20,7 @@ import {SecurityContext} from '../core'; | ||||
| // =================================================================================================
 | ||||
| 
 | ||||
| /** Map from tagName|propertyName SecurityContext. Properties applying to all tags use '*'. */ | ||||
| let _SECURITY_SCHEMA !: {[k: string]: SecurityContext}; | ||||
| let _SECURITY_SCHEMA!: {[k: string]: SecurityContext}; | ||||
| 
 | ||||
| export function SECURITY_SCHEMA(): {[k: string]: SecurityContext} { | ||||
|   if (!_SECURITY_SCHEMA) { | ||||
|  | ||||
| @ -118,9 +118,13 @@ export class CssSelector { | ||||
|         this.notSelectors.length === 0; | ||||
|   } | ||||
| 
 | ||||
|   hasElementSelector(): boolean { return !!this.element; } | ||||
|   hasElementSelector(): boolean { | ||||
|     return !!this.element; | ||||
|   } | ||||
| 
 | ||||
|   setElement(element: string|null = null) { this.element = element; } | ||||
|   setElement(element: string|null = null) { | ||||
|     this.element = element; | ||||
|   } | ||||
| 
 | ||||
|   /** Gets a template string for an element that matches the selector. */ | ||||
|   getMatchingElementTemplate(): string { | ||||
| @ -150,7 +154,9 @@ export class CssSelector { | ||||
|     this.attrs.push(name, value && value.toLowerCase() || ''); | ||||
|   } | ||||
| 
 | ||||
|   addClassName(name: string) { this.classNames.push(name.toLowerCase()); } | ||||
|   addClassName(name: string) { | ||||
|     this.classNames.push(name.toLowerCase()); | ||||
|   } | ||||
| 
 | ||||
|   toString(): string { | ||||
|     let res: string = this.element || ''; | ||||
| @ -189,7 +195,7 @@ export class SelectorMatcher<T = any> { | ||||
|   private _listContexts: SelectorListContext[] = []; | ||||
| 
 | ||||
|   addSelectables(cssSelectors: CssSelector[], callbackCtxt?: T) { | ||||
|     let listContext: SelectorListContext = null !; | ||||
|     let listContext: SelectorListContext = null!; | ||||
|     if (cssSelectors.length > 1) { | ||||
|       listContext = new SelectorListContext(cssSelectors); | ||||
|       this._listContexts.push(listContext); | ||||
| @ -287,7 +293,7 @@ export class SelectorMatcher<T = any> { | ||||
|    */ | ||||
|   match(cssSelector: CssSelector, matchedCallback: ((c: CssSelector, a: T) => void)|null): boolean { | ||||
|     let result = false; | ||||
|     const element = cssSelector.element !; | ||||
|     const element = cssSelector.element!; | ||||
|     const classNames = cssSelector.classNames; | ||||
|     const attrs = cssSelector.attrs; | ||||
| 
 | ||||
| @ -315,7 +321,7 @@ export class SelectorMatcher<T = any> { | ||||
|         const name = attrs[i]; | ||||
|         const value = attrs[i + 1]; | ||||
| 
 | ||||
|         const terminalValuesMap = this._attrValueMap.get(name) !; | ||||
|         const terminalValuesMap = this._attrValueMap.get(name)!; | ||||
|         if (value) { | ||||
|           result = | ||||
|               this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result; | ||||
| @ -323,7 +329,7 @@ export class SelectorMatcher<T = any> { | ||||
|         result = | ||||
|             this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result; | ||||
| 
 | ||||
|         const partialValuesMap = this._attrValuePartialMap.get(name) !; | ||||
|         const partialValuesMap = this._attrValuePartialMap.get(name)!; | ||||
|         if (value) { | ||||
|           result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result; | ||||
|         } | ||||
| @ -343,7 +349,7 @@ export class SelectorMatcher<T = any> { | ||||
|     } | ||||
| 
 | ||||
|     let selectables: SelectorContext<T>[] = map.get(name) || []; | ||||
|     const starSelectables: SelectorContext<T>[] = map.get('*') !; | ||||
|     const starSelectables: SelectorContext<T>[] = map.get('*')!; | ||||
|     if (starSelectables) { | ||||
|       selectables = selectables.concat(starSelectables); | ||||
|     } | ||||
|  | ||||
| @ -175,8 +175,9 @@ export class ShadowCss { | ||||
|    **/ | ||||
|   private _insertPolyfillDirectivesInCssText(cssText: string): string { | ||||
|     // Difference with webcomponents.js: does not handle comments
 | ||||
|     return cssText.replace( | ||||
|         _cssContentNextSelectorRe, function(...m: string[]) { return m[2] + '{'; }); | ||||
|     return cssText.replace(_cssContentNextSelectorRe, function(...m: string[]) { | ||||
|       return m[2] + '{'; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   /* | ||||
| @ -505,7 +506,9 @@ class SafeSelector { | ||||
|     return content.replace(/__ph-(\d+)__/g, (ph, index) => this.placeholders[+index]); | ||||
|   } | ||||
| 
 | ||||
|   content(): string { return this._content; } | ||||
|   content(): string { | ||||
|     return this._content; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const _cssContentNextSelectorRe = | ||||
|  | ||||
| @ -66,7 +66,7 @@ export class StyleCompiler { | ||||
|     stylesheet.styleUrls.forEach((styleUrl) => { | ||||
|       const exprIndex = styleExpressions.length; | ||||
|       // Note: This placeholder will be filled later.
 | ||||
|       styleExpressions.push(null !); | ||||
|       styleExpressions.push(null!); | ||||
|       dependencies.push(new StylesCompileDependency( | ||||
|           getStylesVarName(null), styleUrl, | ||||
|           (value) => styleExpressions[exprIndex] = outputCtx.importExpr(value))); | ||||
| @ -89,7 +89,7 @@ export class StyleCompiler { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function getStylesVarName(component: CompileDirectiveMetadata | null): string { | ||||
| function getStylesVarName(component: CompileDirectiveMetadata|null): string { | ||||
|   let result = `styles`; | ||||
|   if (component) { | ||||
|     result += `_${identifierName(component.type)}`; | ||||
|  | ||||
| @ -28,14 +28,28 @@ export abstract class SummaryResolver<T> { | ||||
| export class JitSummaryResolver implements SummaryResolver<Type> { | ||||
|   private _summaries = new Map<Type, Summary<Type>>(); | ||||
| 
 | ||||
|   isLibraryFile(): boolean { return false; } | ||||
|   toSummaryFileName(fileName: string): string { return fileName; } | ||||
|   fromSummaryFileName(fileName: string): string { return fileName; } | ||||
|   isLibraryFile(): boolean { | ||||
|     return false; | ||||
|   } | ||||
|   toSummaryFileName(fileName: string): string { | ||||
|     return fileName; | ||||
|   } | ||||
|   fromSummaryFileName(fileName: string): string { | ||||
|     return fileName; | ||||
|   } | ||||
|   resolveSummary(reference: Type): Summary<Type>|null { | ||||
|     return this._summaries.get(reference) || null; | ||||
|   } | ||||
|   getSymbolsOf(): Type[] { return []; } | ||||
|   getImportAs(reference: Type): Type { return reference; } | ||||
|   getKnownModuleName(fileName: string) { return null; } | ||||
|   addSummary(summary: Summary<Type>) { this._summaries.set(summary.symbol, summary); } | ||||
|   getSymbolsOf(): Type[] { | ||||
|     return []; | ||||
|   } | ||||
|   getImportAs(reference: Type): Type { | ||||
|     return reference; | ||||
|   } | ||||
|   getKnownModuleName(fileName: string) { | ||||
|     return null; | ||||
|   } | ||||
|   addSummary(summary: Summary<Type>) { | ||||
|     this._summaries.set(summary.symbol, summary); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
| 
 | ||||
| import {CompileDirectiveSummary, CompilePipeSummary} from '../compile_metadata'; | ||||
| import {SecurityContext} from '../core'; | ||||
| import {ASTWithSource, AbsoluteSourceSpan, BindingPipe, BindingType, BoundElementProperty, EmptyExpr, ParsedEvent, ParsedEventType, ParsedProperty, ParsedPropertyType, ParsedVariable, ParserError, RecursiveAstVisitor, TemplateBinding, VariableBinding} from '../expression_parser/ast'; | ||||
| import {AbsoluteSourceSpan, ASTWithSource, BindingPipe, BindingType, BoundElementProperty, EmptyExpr, ParsedEvent, ParsedEventType, ParsedProperty, ParsedPropertyType, ParsedVariable, ParserError, RecursiveAstVisitor, TemplateBinding, VariableBinding} from '../expression_parser/ast'; | ||||
| import {Parser} from '../expression_parser/parser'; | ||||
| import {InterpolationConfig} from '../ml_parser/interpolation_config'; | ||||
| import {mergeNsAndName} from '../ml_parser/tags'; | ||||
| @ -45,9 +45,13 @@ export class BindingParser { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   get interpolationConfig(): InterpolationConfig { return this._interpolationConfig; } | ||||
|   get interpolationConfig(): InterpolationConfig { | ||||
|     return this._interpolationConfig; | ||||
|   } | ||||
| 
 | ||||
|   getUsedPipes(): CompilePipeSummary[] { return Array.from(this._usedPipes.values()); } | ||||
|   getUsedPipes(): CompilePipeSummary[] { | ||||
|     return Array.from(this._usedPipes.values()); | ||||
|   } | ||||
| 
 | ||||
|   createBoundHostProperties(dirMeta: CompileDirectiveSummary, sourceSpan: ParseSourceSpan): | ||||
|       ParsedProperty[]|null { | ||||
| @ -61,7 +65,9 @@ export class BindingParser { | ||||
|               boundProps); | ||||
|         } else { | ||||
|           this._reportError( | ||||
|               `Value of the host property binding "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, | ||||
|               `Value of the host property binding "${ | ||||
|                   propName}" needs to be a string representing an expression but got "${ | ||||
|                   expression}" (${typeof expression})`,
 | ||||
|               sourceSpan); | ||||
|         } | ||||
|       }); | ||||
| @ -89,7 +95,9 @@ export class BindingParser { | ||||
|           this.parseEvent(propName, expression, sourceSpan, sourceSpan, [], targetEvents); | ||||
|         } else { | ||||
|           this._reportError( | ||||
|               `Value of the host listener "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, | ||||
|               `Value of the host listener "${ | ||||
|                   propName}" needs to be a string representing an expression but got "${ | ||||
|                   expression}" (${typeof expression})`,
 | ||||
|               sourceSpan); | ||||
|         } | ||||
|       }); | ||||
| @ -103,7 +111,7 @@ export class BindingParser { | ||||
| 
 | ||||
|     try { | ||||
|       const ast = this._exprParser.parseInterpolation( | ||||
|           value, sourceInfo, sourceSpan.start.offset, this._interpolationConfig) !; | ||||
|           value, sourceInfo, sourceSpan.start.offset, this._interpolationConfig)!; | ||||
|       if (ast) this._reportExpressionParserErrors(ast.errors, sourceSpan); | ||||
|       this._checkPipes(ast, sourceSpan); | ||||
|       return ast; | ||||
| @ -183,8 +191,9 @@ export class BindingParser { | ||||
|           this._checkPipes(binding.value, sourceSpan); | ||||
|         } | ||||
|       }); | ||||
|       bindingsResult.warnings.forEach( | ||||
|           (warning) => { this._reportError(warning, sourceSpan, ParseErrorLevel.WARNING); }); | ||||
|       bindingsResult.warnings.forEach((warning) => { | ||||
|         this._reportError(warning, sourceSpan, ParseErrorLevel.WARNING); | ||||
|       }); | ||||
|       return bindingsResult.templateBindings; | ||||
|     } catch (e) { | ||||
|       this._reportError(`${e}`, sourceSpan); | ||||
| @ -257,7 +266,7 @@ export class BindingParser { | ||||
|       name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan, | ||||
|       valueSpan: ParseSourceSpan|undefined, targetMatchableAttrs: string[][], | ||||
|       targetProps: ParsedProperty[]) { | ||||
|     targetMatchableAttrs.push([name, ast.source !]); | ||||
|     targetMatchableAttrs.push([name, ast.source!]); | ||||
|     targetProps.push( | ||||
|         new ParsedProperty(name, ast, ParsedPropertyType.DEFAULT, sourceSpan, valueSpan)); | ||||
|   } | ||||
| @ -275,7 +284,7 @@ export class BindingParser { | ||||
|     // states will be applied by angular when the element is attached/detached
 | ||||
|     const ast = this._parseBinding( | ||||
|         expression || 'undefined', false, valueSpan || sourceSpan, absoluteOffset); | ||||
|     targetMatchableAttrs.push([name, ast.source !]); | ||||
|     targetMatchableAttrs.push([name, ast.source!]); | ||||
|     targetProps.push( | ||||
|         new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, valueSpan)); | ||||
|   } | ||||
| @ -310,10 +319,10 @@ export class BindingParser { | ||||
|     } | ||||
| 
 | ||||
|     let unit: string|null = null; | ||||
|     let bindingType: BindingType = undefined !; | ||||
|     let bindingType: BindingType = undefined!; | ||||
|     let boundPropertyName: string|null = null; | ||||
|     const parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR); | ||||
|     let securityContexts: SecurityContext[] = undefined !; | ||||
|     let securityContexts: SecurityContext[] = undefined!; | ||||
| 
 | ||||
|     // Check for special cases (prefix style, attr, class)
 | ||||
|     if (parts.length > 1) { | ||||
| @ -401,13 +410,15 @@ export class BindingParser { | ||||
| 
 | ||||
|         default: | ||||
|           this._reportError( | ||||
|               `The provided animation output phase value "${phase}" for "@${eventName}" is not supported (use start or done)`, | ||||
|               `The provided animation output phase value "${phase}" for "@${ | ||||
|                   eventName}" is not supported (use start or done)`,
 | ||||
|               sourceSpan); | ||||
|           break; | ||||
|       } | ||||
|     } else { | ||||
|       this._reportError( | ||||
|           `The animation trigger output event (@${eventName}) is missing its phase value name (start or done are currently supported)`, | ||||
|           `The animation trigger output event (@${ | ||||
|               eventName}) is missing its phase value name (start or done are currently supported)`,
 | ||||
|           sourceSpan); | ||||
|     } | ||||
|   } | ||||
| @ -416,9 +427,9 @@ export class BindingParser { | ||||
|       name: string, expression: string, sourceSpan: ParseSourceSpan, handlerSpan: ParseSourceSpan, | ||||
|       targetMatchableAttrs: string[][], targetEvents: ParsedEvent[]) { | ||||
|     // long format: 'target: eventName'
 | ||||
|     const [target, eventName] = splitAtColon(name, [null !, name]); | ||||
|     const [target, eventName] = splitAtColon(name, [null!, name]); | ||||
|     const ast = this._parseAction(expression, handlerSpan); | ||||
|     targetMatchableAttrs.push([name !, ast.source !]); | ||||
|     targetMatchableAttrs.push([name!, ast.source!]); | ||||
|     targetEvents.push( | ||||
|         new ParsedEvent(eventName, target, ParsedEventType.Regular, ast, sourceSpan, handlerSpan)); | ||||
|     // Don't detect directives for event names for now,
 | ||||
| @ -465,7 +476,7 @@ export class BindingParser { | ||||
|       const collector = new PipeCollector(); | ||||
|       ast.visit(collector); | ||||
|       collector.pipes.forEach((ast, pipeName) => { | ||||
|         const pipeMeta = this.pipesByName !.get(pipeName); | ||||
|         const pipeMeta = this.pipesByName!.get(pipeName); | ||||
|         if (!pipeMeta) { | ||||
|           this._reportError( | ||||
|               `The pipe '${pipeName}' could not be found`, | ||||
| @ -488,7 +499,7 @@ export class BindingParser { | ||||
|     const report = isAttr ? this._schemaRegistry.validateAttribute(propName) : | ||||
|                             this._schemaRegistry.validateProperty(propName); | ||||
|     if (report.error) { | ||||
|       this._reportError(report.msg !, sourceSpan, ParseErrorLevel.ERROR); | ||||
|       this._reportError(report.msg!, sourceSpan, ParseErrorLevel.ERROR); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -36,7 +36,9 @@ export interface TemplateAst { | ||||
| export class TextAst implements TemplateAst { | ||||
|   constructor( | ||||
|       public value: string, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {} | ||||
|   visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); } | ||||
|   visit(visitor: TemplateAstVisitor, context: any): any { | ||||
|     return visitor.visitText(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -56,7 +58,9 @@ export class BoundTextAst implements TemplateAst { | ||||
|  */ | ||||
| export class AttrAst implements TemplateAst { | ||||
|   constructor(public name: string, public value: string, public sourceSpan: ParseSourceSpan) {} | ||||
|   visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitAttr(this, context); } | ||||
|   visit(visitor: TemplateAstVisitor, context: any): any { | ||||
|     return visitor.visitAttr(this, context); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export const enum PropertyBindingType { | ||||
| @ -319,7 +323,9 @@ export class NullTemplateVisitor implements TemplateAstVisitor { | ||||
|  * in an template ast recursively. | ||||
|  */ | ||||
| export class RecursiveTemplateAstVisitor extends NullTemplateVisitor implements TemplateAstVisitor { | ||||
|   constructor() { super(); } | ||||
|   constructor() { | ||||
|     super(); | ||||
|   } | ||||
| 
 | ||||
|   // Nodes with children
 | ||||
|   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { | ||||
| @ -358,7 +364,7 @@ export class RecursiveTemplateAstVisitor extends NullTemplateVisitor implements | ||||
|       cb: (visit: (<V extends TemplateAst>(children: V[]|undefined) => void)) => void) { | ||||
|     let results: any[][] = []; | ||||
|     let t = this; | ||||
|     function visit<T extends TemplateAst>(children: T[] | undefined) { | ||||
|     function visit<T extends TemplateAst>(children: T[]|undefined) { | ||||
|       if (children && children.length) results.push(templateVisitAll(t, children, context)); | ||||
|     } | ||||
|     cb(visit); | ||||
| @ -373,7 +379,7 @@ export function templateVisitAll( | ||||
|     visitor: TemplateAstVisitor, asts: TemplateAst[], context: any = null): any[] { | ||||
|   const result: any[] = []; | ||||
|   const visit = visitor.visit ? | ||||
|       (ast: TemplateAst) => visitor.visit !(ast, context) || ast.visit(visitor, context) : | ||||
|       (ast: TemplateAst) => visitor.visit!(ast, context) || ast.visit(visitor, context) : | ||||
|       (ast: TemplateAst) => ast.visit(visitor, context); | ||||
|   asts.forEach(ast => { | ||||
|     const astResult = visit(ast); | ||||
|  | ||||
| @ -12,7 +12,7 @@ import {CompilerConfig} from '../config'; | ||||
| import {SchemaMetadata} from '../core'; | ||||
| import {AST, ASTWithSource, EmptyExpr, ParsedEvent, ParsedProperty, ParsedVariable} from '../expression_parser/ast'; | ||||
| import {Parser} from '../expression_parser/parser'; | ||||
| import {Identifiers, createTokenForExternalReference, createTokenForReference} from '../identifiers'; | ||||
| import {createTokenForExternalReference, createTokenForReference, Identifiers} from '../identifiers'; | ||||
| import * as html from '../ml_parser/ast'; | ||||
| import {HtmlParser, ParseTreeResult} from '../ml_parser/html_parser'; | ||||
| import {removeWhitespaces, replaceNgsp} from '../ml_parser/html_whitespaces'; | ||||
| @ -57,7 +57,7 @@ const IDENT_EVENT_IDX = 10; | ||||
| const TEMPLATE_ATTR_PREFIX = '*'; | ||||
| const CLASS_ATTR = 'class'; | ||||
| 
 | ||||
| let _TEXT_CSS_SELECTOR !: CssSelector; | ||||
| let _TEXT_CSS_SELECTOR!: CssSelector; | ||||
| function TEXT_CSS_SELECTOR(): CssSelector { | ||||
|   if (!_TEXT_CSS_SELECTOR) { | ||||
|     _TEXT_CSS_SELECTOR = CssSelector.parse('*')[0]; | ||||
| @ -84,7 +84,9 @@ export class TemplateParser { | ||||
|       private _htmlParser: HtmlParser, private _console: Console, | ||||
|       public transforms: t.TemplateAstVisitor[]) {} | ||||
| 
 | ||||
|   public get expressionParser() { return this._exprParser; } | ||||
|   public get expressionParser() { | ||||
|     return this._exprParser; | ||||
|   } | ||||
| 
 | ||||
|   parse( | ||||
|       component: CompileDirectiveMetadata, template: string|ParseTreeResult, | ||||
| @ -93,9 +95,9 @@ export class TemplateParser { | ||||
|       preserveWhitespaces: boolean): {template: t.TemplateAst[], pipes: CompilePipeSummary[]} { | ||||
|     const result = this.tryParse( | ||||
|         component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces); | ||||
|     const warnings = result.errors !.filter(error => error.level === ParseErrorLevel.WARNING); | ||||
|     const warnings = result.errors!.filter(error => error.level === ParseErrorLevel.WARNING); | ||||
| 
 | ||||
|     const errors = result.errors !.filter(error => error.level === ParseErrorLevel.ERROR); | ||||
|     const errors = result.errors!.filter(error => error.level === ParseErrorLevel.ERROR); | ||||
| 
 | ||||
|     if (warnings.length > 0) { | ||||
|       this._console.warn(`Template parse warnings:\n${warnings.join('\n')}`); | ||||
| @ -106,7 +108,7 @@ export class TemplateParser { | ||||
|       throw syntaxError(`Template parse errors:\n${errorString}`, errors); | ||||
|     } | ||||
| 
 | ||||
|     return {template: result.templateAst !, pipes: result.usedPipes !}; | ||||
|     return {template: result.templateAst!, pipes: result.usedPipes!}; | ||||
|   } | ||||
| 
 | ||||
|   tryParse( | ||||
| @ -114,7 +116,7 @@ export class TemplateParser { | ||||
|       directives: CompileDirectiveSummary[], pipes: CompilePipeSummary[], schemas: SchemaMetadata[], | ||||
|       templateUrl: string, preserveWhitespaces: boolean): TemplateParseResult { | ||||
|     let htmlParseResult = typeof template === 'string' ? | ||||
|         this._htmlParser !.parse(template, templateUrl, { | ||||
|         this._htmlParser!.parse(template, templateUrl, { | ||||
|           tokenizeExpansionForms: true, | ||||
|           interpolationConfig: this.getInterpolationConfig(component) | ||||
|         }) : | ||||
| @ -139,7 +141,7 @@ export class TemplateParser { | ||||
|       const uniqDirectives = removeSummaryDuplicates(directives); | ||||
|       const uniqPipes = removeSummaryDuplicates(pipes); | ||||
|       const providerViewContext = new ProviderViewContext(this._reflector, component); | ||||
|       let interpolationConfig: InterpolationConfig = undefined !; | ||||
|       let interpolationConfig: InterpolationConfig = undefined!; | ||||
|       if (component.template && component.template.interpolation) { | ||||
|         interpolationConfig = { | ||||
|           start: component.template.interpolation[0], | ||||
| @ -147,7 +149,7 @@ export class TemplateParser { | ||||
|         }; | ||||
|       } | ||||
|       const bindingParser = new BindingParser( | ||||
|           this._exprParser, interpolationConfig !, this._schemaRegistry, uniqPipes, errors); | ||||
|           this._exprParser, interpolationConfig!, this._schemaRegistry, uniqPipes, errors); | ||||
|       const parseVisitor = new TemplateParseVisitor( | ||||
|           this._reflector, this._config, providerViewContext, uniqDirectives, bindingParser, | ||||
|           this._schemaRegistry, schemas, errors); | ||||
| @ -164,8 +166,9 @@ export class TemplateParser { | ||||
|     } | ||||
| 
 | ||||
|     if (this.transforms) { | ||||
|       this.transforms.forEach( | ||||
|           (transform: t.TemplateAstVisitor) => { result = t.templateVisitAll(transform, result); }); | ||||
|       this.transforms.forEach((transform: t.TemplateAstVisitor) => { | ||||
|         result = t.templateVisitAll(transform, result); | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     return new TemplateParseResult(result, usedPipes, errors); | ||||
| @ -224,29 +227,35 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|     // Note: queries start with id 1 so we can use the number in a Bloom filter!
 | ||||
|     this.contentQueryStartId = providerViewContext.component.viewQueries.length + 1; | ||||
|     directives.forEach((directive, index) => { | ||||
|       const selector = CssSelector.parse(directive.selector !); | ||||
|       const selector = CssSelector.parse(directive.selector!); | ||||
|       this.selectorMatcher.addSelectables(selector, directive); | ||||
|       this.directivesIndex.set(directive, index); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(expansion: html.Expansion, context: any): any { return null; } | ||||
|   visitExpansion(expansion: html.Expansion, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { return null; } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: html.Text, parent: ElementContext): any { | ||||
|     const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR()) !; | ||||
|     const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR())!; | ||||
|     const valueNoNgsp = replaceNgsp(text.value); | ||||
|     const expr = this._bindingParser.parseInterpolation(valueNoNgsp, text.sourceSpan !); | ||||
|     return expr ? new t.BoundTextAst(expr, ngContentIndex, text.sourceSpan !) : | ||||
|                   new t.TextAst(valueNoNgsp, ngContentIndex, text.sourceSpan !); | ||||
|     const expr = this._bindingParser.parseInterpolation(valueNoNgsp, text.sourceSpan!); | ||||
|     return expr ? new t.BoundTextAst(expr, ngContentIndex, text.sourceSpan!) : | ||||
|                   new t.TextAst(valueNoNgsp, ngContentIndex, text.sourceSpan!); | ||||
|   } | ||||
| 
 | ||||
|   visitAttribute(attribute: html.Attribute, context: any): any { | ||||
|     return new t.AttrAst(attribute.name, attribute.value, attribute.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitComment(comment: html.Comment, context: any): any { return null; } | ||||
|   visitComment(comment: html.Comment, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitElement(element: html.Element, parent: ElementContext): any { | ||||
|     const queryStartIndex = this.contentQueryStartId; | ||||
| @ -307,7 +316,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|         const parsedVariables: ParsedVariable[] = []; | ||||
|         const absoluteOffset = (attr.valueSpan || attr.sourceSpan).start.offset; | ||||
|         this._bindingParser.parseInlineTemplateBinding( | ||||
|             templateKey !, templateValue !, attr.sourceSpan, absoluteOffset, templateMatchableAttrs, | ||||
|             templateKey!, templateValue!, attr.sourceSpan, absoluteOffset, templateMatchableAttrs, | ||||
|             templateElementOrDirectiveProps, parsedVariables); | ||||
|         templateElementVars.push(...parsedVariables.map(v => t.VariableAst.fromParsedVariable(v))); | ||||
|       } | ||||
| @ -326,52 +335,51 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|     const boundDirectivePropNames = new Set<string>(); | ||||
|     const directiveAsts = this._createDirectiveAsts( | ||||
|         isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps, | ||||
|         elementOrDirectiveRefs, element.sourceSpan !, references, boundDirectivePropNames); | ||||
|         elementOrDirectiveRefs, element.sourceSpan!, references, boundDirectivePropNames); | ||||
|     const elementProps: t.BoundElementPropertyAst[] = this._createElementPropertyAsts( | ||||
|         element.name, elementOrDirectiveProps, boundDirectivePropNames); | ||||
|     const isViewRoot = parent.isTemplateElement || hasInlineTemplates; | ||||
| 
 | ||||
|     const providerContext = new ProviderElementContext( | ||||
|         this.providerViewContext, parent.providerContext !, isViewRoot, directiveAsts, attrs, | ||||
|         references, isTemplateElement, queryStartIndex, element.sourceSpan !); | ||||
|         this.providerViewContext, parent.providerContext!, isViewRoot, directiveAsts, attrs, | ||||
|         references, isTemplateElement, queryStartIndex, element.sourceSpan!); | ||||
| 
 | ||||
|     const children: t.TemplateAst[] = html.visitAll( | ||||
|         preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children, | ||||
|         ElementContext.create( | ||||
|             isTemplateElement, directiveAsts, | ||||
|             isTemplateElement ? parent.providerContext ! : providerContext)); | ||||
|             isTemplateElement ? parent.providerContext! : providerContext)); | ||||
|     providerContext.afterElement(); | ||||
|     // Override the actual selector when the `ngProjectAs` attribute is provided
 | ||||
|     const projectionSelector = preparsedElement.projectAs != '' ? | ||||
|         CssSelector.parse(preparsedElement.projectAs)[0] : | ||||
|         elementCssSelector; | ||||
|     const ngContentIndex = parent.findNgContentIndex(projectionSelector) !; | ||||
|     const ngContentIndex = parent.findNgContentIndex(projectionSelector)!; | ||||
|     let parsedElement: t.TemplateAst; | ||||
| 
 | ||||
|     if (preparsedElement.type === PreparsedElementType.NG_CONTENT) { | ||||
|       // `<ng-content>` element
 | ||||
|       if (element.children && !element.children.every(_isEmptyTextNode)) { | ||||
|         this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan !); | ||||
|         this._reportError(`<ng-content> element cannot have content.`, element.sourceSpan!); | ||||
|       } | ||||
| 
 | ||||
|       parsedElement = new t.NgContentAst( | ||||
|           this.ngContentCount++, hasInlineTemplates ? null ! : ngContentIndex, | ||||
|           element.sourceSpan !); | ||||
|           this.ngContentCount++, hasInlineTemplates ? null! : ngContentIndex, element.sourceSpan!); | ||||
|     } else if (isTemplateElement) { | ||||
|       // `<ng-template>` element
 | ||||
|       this._assertAllEventsPublishedByDirectives(directiveAsts, events); | ||||
|       this._assertNoComponentsNorElementBindingsOnTemplate( | ||||
|           directiveAsts, elementProps, element.sourceSpan !); | ||||
|           directiveAsts, elementProps, element.sourceSpan!); | ||||
| 
 | ||||
|       parsedElement = new t.EmbeddedTemplateAst( | ||||
|           attrs, events, references, elementVars, providerContext.transformedDirectiveAsts, | ||||
|           providerContext.transformProviders, providerContext.transformedHasViewContainer, | ||||
|           providerContext.queryMatches, children, hasInlineTemplates ? null ! : ngContentIndex, | ||||
|           element.sourceSpan !); | ||||
|           providerContext.queryMatches, children, hasInlineTemplates ? null! : ngContentIndex, | ||||
|           element.sourceSpan!); | ||||
|     } else { | ||||
|       // element other than `<ng-content>` and `<ng-template>`
 | ||||
|       this._assertElementExists(matchElement, element); | ||||
|       this._assertOnlyOneComponent(directiveAsts, element.sourceSpan !); | ||||
|       this._assertOnlyOneComponent(directiveAsts, element.sourceSpan!); | ||||
| 
 | ||||
|       const ngContentIndex = | ||||
|           hasInlineTemplates ? null : parent.findNgContentIndex(projectionSelector); | ||||
| @ -389,22 +397,22 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|       const {directives} = this._parseDirectives(this.selectorMatcher, templateSelector); | ||||
|       const templateBoundDirectivePropNames = new Set<string>(); | ||||
|       const templateDirectiveAsts = this._createDirectiveAsts( | ||||
|           true, elName, directives, templateElementOrDirectiveProps, [], element.sourceSpan !, [], | ||||
|           true, elName, directives, templateElementOrDirectiveProps, [], element.sourceSpan!, [], | ||||
|           templateBoundDirectivePropNames); | ||||
|       const templateElementProps: t.BoundElementPropertyAst[] = this._createElementPropertyAsts( | ||||
|           elName, templateElementOrDirectiveProps, templateBoundDirectivePropNames); | ||||
|       this._assertNoComponentsNorElementBindingsOnTemplate( | ||||
|           templateDirectiveAsts, templateElementProps, element.sourceSpan !); | ||||
|           templateDirectiveAsts, templateElementProps, element.sourceSpan!); | ||||
|       const templateProviderContext = new ProviderElementContext( | ||||
|           this.providerViewContext, parent.providerContext !, parent.isTemplateElement, | ||||
|           templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan !); | ||||
|           this.providerViewContext, parent.providerContext!, parent.isTemplateElement, | ||||
|           templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan!); | ||||
|       templateProviderContext.afterElement(); | ||||
| 
 | ||||
|       parsedElement = new t.EmbeddedTemplateAst( | ||||
|           [], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts, | ||||
|           templateProviderContext.transformProviders, | ||||
|           templateProviderContext.transformedHasViewContainer, templateProviderContext.queryMatches, | ||||
|           [parsedElement], ngContentIndex, element.sourceSpan !); | ||||
|           [parsedElement], ngContentIndex, element.sourceSpan!); | ||||
|     } | ||||
| 
 | ||||
|     return parsedElement; | ||||
| @ -538,7 +546,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|     let matchElement = false; | ||||
| 
 | ||||
|     selectorMatcher.match(elementCssSelector, (selector, directive) => { | ||||
|       directives[this.directivesIndex.get(directive) !] = directive; | ||||
|       directives[this.directivesIndex.get(directive)!] = directive; | ||||
|       matchElement = matchElement || selector.hasElementSelector(); | ||||
|     }); | ||||
| 
 | ||||
| @ -554,7 +562,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|       elementSourceSpan: ParseSourceSpan, targetReferences: t.ReferenceAst[], | ||||
|       targetBoundDirectivePropNames: Set<string>): t.DirectiveAst[] { | ||||
|     const matchedReferences = new Set<string>(); | ||||
|     let component: CompileDirectiveSummary = null !; | ||||
|     let component: CompileDirectiveSummary = null!; | ||||
| 
 | ||||
|     const directiveAsts = directives.map((directive) => { | ||||
|       const sourceSpan = new ParseSourceSpan( | ||||
| @ -566,15 +574,14 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|       } | ||||
|       const directiveProperties: t.BoundDirectivePropertyAst[] = []; | ||||
|       const boundProperties = | ||||
|           this._bindingParser.createDirectiveHostPropertyAsts(directive, elementName, sourceSpan) !; | ||||
|           this._bindingParser.createDirectiveHostPropertyAsts(directive, elementName, sourceSpan)!; | ||||
| 
 | ||||
|       let hostProperties = | ||||
|           boundProperties.map(prop => t.BoundElementPropertyAst.fromBoundProperty(prop)); | ||||
|       // Note: We need to check the host properties here as well,
 | ||||
|       // as we don't know the element name in the DirectiveWrapperCompiler yet.
 | ||||
|       hostProperties = this._checkPropertiesInSchema(elementName, hostProperties); | ||||
|       const parsedEvents = | ||||
|           this._bindingParser.createDirectiveHostEventAsts(directive, sourceSpan) !; | ||||
|       const parsedEvents = this._bindingParser.createDirectiveHostEventAsts(directive, sourceSpan)!; | ||||
|       this._createDirectivePropertyAsts( | ||||
|           directive.inputs, props, directiveProperties, targetBoundDirectivePropNames); | ||||
|       elementOrDirectiveRefs.forEach((elOrDirRef) => { | ||||
| @ -602,7 +609,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|               elOrDirRef.sourceSpan); | ||||
|         } | ||||
|       } else if (!component) { | ||||
|         let refToken: CompileTokenMetadata = null !; | ||||
|         let refToken: CompileTokenMetadata = null!; | ||||
|         if (isTemplateElement) { | ||||
|           refToken = createTokenForExternalReference(this.reflector, Identifiers.TemplateRef); | ||||
|         } | ||||
| @ -663,7 +670,7 @@ class TemplateParseVisitor implements html.Visitor { | ||||
| 
 | ||||
|   private _findComponentDirectiveNames(directives: t.DirectiveAst[]): string[] { | ||||
|     return this._findComponentDirectives(directives) | ||||
|         .map(directive => identifierName(directive.directive.type) !); | ||||
|         .map(directive => identifierName(directive.directive.type)!); | ||||
|   } | ||||
| 
 | ||||
|   private _assertOnlyOneComponent(directives: t.DirectiveAst[], sourceSpan: ParseSourceSpan) { | ||||
| @ -691,16 +698,16 @@ class TemplateParseVisitor implements html.Visitor { | ||||
| 
 | ||||
|     if (!matchElement && !this._schemaRegistry.hasElement(elName, this._schemas)) { | ||||
|       let errorMsg = `'${elName}' is not a known element:\n`; | ||||
|       errorMsg += | ||||
|           `1. If '${elName}' is an Angular component, then verify that it is part of this module.\n`; | ||||
|       errorMsg += `1. If '${ | ||||
|           elName}' is an Angular component, then verify that it is part of this module.\n`;
 | ||||
|       if (elName.indexOf('-') > -1) { | ||||
|         errorMsg += | ||||
|             `2. If '${elName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.`; | ||||
|         errorMsg += `2. If '${ | ||||
|             elName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.`;
 | ||||
|       } else { | ||||
|         errorMsg += | ||||
|             `2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`; | ||||
|       } | ||||
|       this._reportError(errorMsg, element.sourceSpan !); | ||||
|       this._reportError(errorMsg, element.sourceSpan!); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -714,7 +721,8 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|     } | ||||
|     elementProps.forEach(prop => { | ||||
|       this._reportError( | ||||
|           `Property binding ${prop.name} not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations".`, | ||||
|           `Property binding ${ | ||||
|               prop.name} not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations".`,
 | ||||
|           sourceSpan); | ||||
|     }); | ||||
|   } | ||||
| @ -733,7 +741,9 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|     events.forEach(event => { | ||||
|       if (event.target != null || !allDirectiveEvents.has(event.name)) { | ||||
|         this._reportError( | ||||
|             `Event binding ${event.fullName} not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations".`, | ||||
|             `Event binding ${ | ||||
|                 event | ||||
|                     .fullName} not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations".`,
 | ||||
|             event.sourceSpan); | ||||
|       } | ||||
|     }); | ||||
| @ -746,16 +756,20 @@ class TemplateParseVisitor implements html.Visitor { | ||||
|     return boundProps.filter((boundProp) => { | ||||
|       if (boundProp.type === t.PropertyBindingType.Property && | ||||
|           !this._schemaRegistry.hasProperty(elementName, boundProp.name, this._schemas)) { | ||||
|         let errorMsg = | ||||
|             `Can't bind to '${boundProp.name}' since it isn't a known property of '${elementName}'.`; | ||||
|         let errorMsg = `Can't bind to '${boundProp.name}' since it isn't a known property of '${ | ||||
|             elementName}'.`;
 | ||||
|         if (elementName.startsWith('ng-')) { | ||||
|           errorMsg += | ||||
|               `\n1. If '${boundProp.name}' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component.` + | ||||
|               `\n1. If '${ | ||||
|                   boundProp | ||||
|                       .name}' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component.` +
 | ||||
|               `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`; | ||||
|         } else if (elementName.indexOf('-') > -1) { | ||||
|           errorMsg += | ||||
|               `\n1. If '${elementName}' is an Angular component and it has '${boundProp.name}' input, then verify that it is part of this module.` + | ||||
|               `\n2. If '${elementName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.` + | ||||
|               `\n1. If '${elementName}' is an Angular component and it has '${ | ||||
|                   boundProp.name}' input, then verify that it is part of this module.` +
 | ||||
|               `\n2. If '${ | ||||
|                   elementName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.` +
 | ||||
|               `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`; | ||||
|         } | ||||
|         this._reportError(errorMsg, boundProp.sourceSpan); | ||||
| @ -791,20 +805,26 @@ class NonBindableVisitor implements html.Visitor { | ||||
|         ast.name, html.visitAll(this, ast.attrs), [], [], [], [], [], false, [], children, | ||||
|         ngContentIndex, ast.sourceSpan, ast.endSourceSpan); | ||||
|   } | ||||
|   visitComment(comment: html.Comment, context: any): any { return null; } | ||||
|   visitComment(comment: html.Comment, context: any): any { | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   visitAttribute(attribute: html.Attribute, context: any): t.AttrAst { | ||||
|     return new t.AttrAst(attribute.name, attribute.value, attribute.sourceSpan); | ||||
|   } | ||||
| 
 | ||||
|   visitText(text: html.Text, parent: ElementContext): t.TextAst { | ||||
|     const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR()) !; | ||||
|     return new t.TextAst(text.value, ngContentIndex, text.sourceSpan !); | ||||
|     const ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR())!; | ||||
|     return new t.TextAst(text.value, ngContentIndex, text.sourceSpan!); | ||||
|   } | ||||
| 
 | ||||
|   visitExpansion(expansion: html.Expansion, context: any): any { return expansion; } | ||||
|   visitExpansion(expansion: html.Expansion, context: any): any { | ||||
|     return expansion; | ||||
|   } | ||||
| 
 | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { return expansionCase; } | ||||
|   visitExpansionCase(expansionCase: html.ExpansionCase, context: any): any { | ||||
|     return expansionCase; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -824,7 +844,7 @@ class ElementOrDirectiveRef { | ||||
| } | ||||
| 
 | ||||
| /** Splits a raw, potentially comma-delimited `exportAs` value into an array of names. */ | ||||
| function splitExportAs(exportAs: string | null): string[] { | ||||
| function splitExportAs(exportAs: string|null): string[] { | ||||
|   return exportAs ? exportAs.split(',').map(e => e.trim()) : []; | ||||
| } | ||||
| 
 | ||||
| @ -837,7 +857,7 @@ class ElementContext { | ||||
|       isTemplateElement: boolean, directives: t.DirectiveAst[], | ||||
|       providerContext: ProviderElementContext): ElementContext { | ||||
|     const matcher = new SelectorMatcher(); | ||||
|     let wildcardNgContentIndex: number = null !; | ||||
|     let wildcardNgContentIndex: number = null!; | ||||
|     const component = directives.find(directive => directive.directive.isComponent); | ||||
|     if (component) { | ||||
|       const ngContentSelectors = component.directive.template !.ngContentSelectors; | ||||
| @ -859,8 +879,9 @@ class ElementContext { | ||||
| 
 | ||||
|   findNgContentIndex(selector: CssSelector): number|null { | ||||
|     const ngContentIndices: number[] = []; | ||||
|     this._ngContentIndexMatcher.match( | ||||
|         selector, (selector, ngContentIndex) => { ngContentIndices.push(ngContentIndex); }); | ||||
|     this._ngContentIndexMatcher.match(selector, (selector, ngContentIndex) => { | ||||
|       ngContentIndices.push(ngContentIndex); | ||||
|     }); | ||||
|     ngContentIndices.sort(); | ||||
|     if (this._wildcardNgContentIndex != null) { | ||||
|       ngContentIndices.push(this._wildcardNgContentIndex); | ||||
| @ -897,7 +918,7 @@ function _isEmptyTextNode(node: html.Node): boolean { | ||||
|   return node instanceof html.Text && node.value.trim().length == 0; | ||||
| } | ||||
| 
 | ||||
| export function removeSummaryDuplicates<T extends{type: CompileTypeMetadata}>(items: T[]): T[] { | ||||
| export function removeSummaryDuplicates<T extends {type: CompileTypeMetadata}>(items: T[]): T[] { | ||||
|   const map = new Map<any, T>(); | ||||
| 
 | ||||
|   items.forEach((item) => { | ||||
|  | ||||
| @ -20,9 +20,9 @@ const NG_NON_BINDABLE_ATTR = 'ngNonBindable'; | ||||
| const NG_PROJECT_AS = 'ngProjectAs'; | ||||
| 
 | ||||
| export function preparseElement(ast: html.Element): PreparsedElement { | ||||
|   let selectAttr: string = null !; | ||||
|   let hrefAttr: string = null !; | ||||
|   let relAttr: string = null !; | ||||
|   let selectAttr: string = null!; | ||||
|   let hrefAttr: string = null!; | ||||
|   let relAttr: string = null!; | ||||
|   let nonBindable = false; | ||||
|   let projectAs = ''; | ||||
|   ast.attrs.forEach(attr => { | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user