| 
									
										
										
										
											2017-06-09 14:50:57 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {GeneratedFile} from '@angular/compiler'; | 
					
						
							|  |  |  | import * as ts from 'typescript'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {TypeScriptNodeEmitter} from './node_emitter'; | 
					
						
							| 
									
										
										
										
											2017-09-29 15:02:11 -07:00
										 |  |  | import {GENERATED_FILES} from './util'; | 
					
						
							| 
									
										
										
										
											2017-06-09 14:50:57 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:52:16 +01:00
										 |  |  | function getPreamble(original: string) { | 
					
						
							|  |  |  |   return `/**
 | 
					
						
							|  |  |  |  * @fileoverview This file was generated by the Angular template compiler. Do not edit. | 
					
						
							|  |  |  |  * ${original} | 
					
						
							|  |  |  |  * @suppress {suspiciousCode,uselessCode,missingProperties,missingOverride,checkTypes} | 
					
						
							|  |  |  |  * tslint:disable | 
					
						
							|  |  |  |  */`; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-09-01 16:27:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 17:52:16 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Returns a transformer that does two things for generated files (ngfactory etc): | 
					
						
							|  |  |  |  * - adds a fileoverview JSDoc comment containing Closure Compiler specific "suppress"ions in JSDoc. | 
					
						
							|  |  |  |  *   The new comment will contain any fileoverview comment text from the original source file this | 
					
						
							|  |  |  |  *   file was generated from. | 
					
						
							|  |  |  |  * - updates generated files that are not in the given map of generatedFiles to have an empty | 
					
						
							|  |  |  |  *   list of statements as their body. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export function getAngularEmitterTransformFactory( | 
					
						
							|  |  |  |     generatedFiles: Map<string, GeneratedFile>, program: ts.Program): () => | 
					
						
							| 
									
										
										
										
											2017-06-09 14:50:57 -07:00
										 |  |  |     (sourceFile: ts.SourceFile) => ts.SourceFile { | 
					
						
							|  |  |  |   return function() { | 
					
						
							|  |  |  |     const emitter = new TypeScriptNodeEmitter(); | 
					
						
							|  |  |  |     return function(sourceFile: ts.SourceFile): ts.SourceFile { | 
					
						
							| 
									
										
										
										
											2017-10-12 16:09:49 -07:00
										 |  |  |       const g = generatedFiles.get(sourceFile.fileName); | 
					
						
							| 
									
										
										
										
											2017-12-07 17:52:16 +01:00
										 |  |  |       const orig = g && program.getSourceFile(g.srcFileUrl); | 
					
						
							|  |  |  |       let originalComment = ''; | 
					
						
							|  |  |  |       if (orig) originalComment = getFileoverviewComment(orig); | 
					
						
							|  |  |  |       const preamble = getPreamble(originalComment); | 
					
						
							| 
									
										
										
										
											2017-06-09 14:50:57 -07:00
										 |  |  |       if (g && g.stmts) { | 
					
						
							| 
									
										
										
										
											2017-12-07 17:52:16 +01:00
										 |  |  |         const orig = program.getSourceFile(g.srcFileUrl); | 
					
						
							|  |  |  |         let originalComment = ''; | 
					
						
							|  |  |  |         if (orig) originalComment = getFileoverviewComment(orig); | 
					
						
							|  |  |  |         const [newSourceFile] = emitter.updateSourceFile(sourceFile, g.stmts, preamble); | 
					
						
							| 
									
										
										
										
											2017-06-09 14:50:57 -07:00
										 |  |  |         return newSourceFile; | 
					
						
							| 
									
										
										
										
											2017-09-29 15:02:11 -07:00
										 |  |  |       } else if (GENERATED_FILES.test(sourceFile.fileName)) { | 
					
						
							| 
									
										
										
										
											2017-12-07 17:52:16 +01:00
										 |  |  |         // The file should be empty, but emitter.updateSourceFile would still add imports
 | 
					
						
							|  |  |  |         // and various minutiae.
 | 
					
						
							|  |  |  |         // Clear out the source file entirely, only including the preamble comment, so that
 | 
					
						
							|  |  |  |         // ngc produces an empty .js file.
 | 
					
						
							|  |  |  |         return ts.updateSourceFileNode( | 
					
						
							|  |  |  |             sourceFile, [emitter.createCommentStatement(sourceFile, preamble)]); | 
					
						
							| 
									
										
										
										
											2017-06-09 14:50:57 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |       return sourceFile; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-09-01 16:27:02 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-07 17:52:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Parses and returns the comment text (without start and end markers) of a \@fileoverview comment | 
					
						
							|  |  |  |  * in the given source file. Returns the empty string if no such comment can be found. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function getFileoverviewComment(sourceFile: ts.SourceFile): string { | 
					
						
							|  |  |  |   const trivia = sourceFile.getFullText().substring(0, sourceFile.getStart()); | 
					
						
							|  |  |  |   const leadingComments = ts.getLeadingCommentRanges(trivia, 0); | 
					
						
							|  |  |  |   if (!leadingComments || leadingComments.length === 0) return ''; | 
					
						
							|  |  |  |   const comment = leadingComments[0]; | 
					
						
							|  |  |  |   if (comment.kind !== ts.SyntaxKind.MultiLineCommentTrivia) return ''; | 
					
						
							|  |  |  |   // Only comments separated with a \n\n from the file contents are considered file-level comments
 | 
					
						
							|  |  |  |   // in TypeScript.
 | 
					
						
							|  |  |  |   if (sourceFile.getFullText().substring(comment.end, comment.end + 2) !== '\n\n') return ''; | 
					
						
							|  |  |  |   const commentText = sourceFile.getFullText().substring(comment.pos, comment.end); | 
					
						
							|  |  |  |   // Closure Compiler ignores @suppress and similar if the comment contains @license.
 | 
					
						
							|  |  |  |   if (commentText.indexOf('@license') !== -1) return ''; | 
					
						
							|  |  |  |   return commentText.replace(/^\/\*\*/, '').replace(/ ?\*\/$/, ''); | 
					
						
							|  |  |  | } |