Usages of `NgTools_InternalApi_NG_2` from `@angular/compiler-cli` will now throw an error. Adds `listLazyRoutes` to `@angular/compiler-cli/ngtools2.ts` for getting the lazy routes of a `ng.Program`. PR Close #19836
		
			
				
	
	
		
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @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 * as ts from 'typescript';
 | |
| 
 | |
| import {METADATA_VERSION, ModuleMetadata} from '../metadata';
 | |
| 
 | |
| import {DTS} from './util';
 | |
| 
 | |
| export interface MetadataReaderHost {
 | |
|   getSourceFileMetadata(filePath: string): ModuleMetadata|undefined;
 | |
|   cacheMetadata?(fileName: string): boolean;
 | |
|   fileExists(filePath: string): boolean;
 | |
|   readFile(filePath: string): string;
 | |
| }
 | |
| 
 | |
| export interface MetadataReaderCache {
 | |
|   /**
 | |
|    * @internal
 | |
|    */
 | |
|   data: Map<string, ModuleMetadata[]|undefined>;
 | |
| }
 | |
| 
 | |
| export function createMetadataReaderCache(): MetadataReaderCache {
 | |
|   const data = new Map<string, ModuleMetadata[]|undefined>();
 | |
|   return {data};
 | |
| }
 | |
| 
 | |
| export function readMetadata(
 | |
|     filePath: string, host: MetadataReaderHost, cache?: MetadataReaderCache): ModuleMetadata[]|
 | |
|     undefined {
 | |
|   let metadatas = cache && cache.data.get(filePath);
 | |
|   if (metadatas) {
 | |
|     return metadatas;
 | |
|   }
 | |
|   if (host.fileExists(filePath)) {
 | |
|     // If the file doesn't exists then we cannot return metadata for the file.
 | |
|     // This will occur if the user referenced a declared module for which no file
 | |
|     // exists for the module (i.e. jQuery or angularjs).
 | |
|     if (DTS.test(filePath)) {
 | |
|       metadatas = readMetadataFile(host, filePath);
 | |
|       if (!metadatas) {
 | |
|         // If there is a .d.ts file but no metadata file we need to produce a
 | |
|         // metadata from the .d.ts file as metadata files capture reexports
 | |
|         // (starting with v3).
 | |
|         metadatas = [upgradeMetadataWithDtsData(
 | |
|             host, {'__symbolic': 'module', 'version': 1, 'metadata': {}}, filePath)];
 | |
|       }
 | |
|     } else {
 | |
|       const metadata = host.getSourceFileMetadata(filePath);
 | |
|       metadatas = metadata ? [metadata] : [];
 | |
|     }
 | |
|   }
 | |
|   if (cache && (!host.cacheMetadata || host.cacheMetadata(filePath))) {
 | |
|     cache.data.set(filePath, metadatas);
 | |
|   }
 | |
|   return metadatas;
 | |
| }
 | |
| 
 | |
| 
 | |
| function readMetadataFile(host: MetadataReaderHost, dtsFilePath: string): ModuleMetadata[]|
 | |
|     undefined {
 | |
|   const metadataPath = dtsFilePath.replace(DTS, '.metadata.json');
 | |
|   if (!host.fileExists(metadataPath)) {
 | |
|     return undefined;
 | |
|   }
 | |
|   try {
 | |
|     const metadataOrMetadatas = JSON.parse(host.readFile(metadataPath));
 | |
|     const metadatas: ModuleMetadata[] = metadataOrMetadatas ?
 | |
|         (Array.isArray(metadataOrMetadatas) ? metadataOrMetadatas : [metadataOrMetadatas]) :
 | |
|         [];
 | |
|     if (metadatas.length) {
 | |
|       let maxMetadata = metadatas.reduce((p, c) => p.version > c.version ? p : c);
 | |
|       if (maxMetadata.version < METADATA_VERSION) {
 | |
|         metadatas.push(upgradeMetadataWithDtsData(host, maxMetadata, dtsFilePath));
 | |
|       }
 | |
|     }
 | |
|     return metadatas;
 | |
|   } catch (e) {
 | |
|     console.error(`Failed to read JSON file ${metadataPath}`);
 | |
|     throw e;
 | |
|   }
 | |
| }
 | |
| 
 | |
| function upgradeMetadataWithDtsData(
 | |
|     host: MetadataReaderHost, oldMetadata: ModuleMetadata, dtsFilePath: string): ModuleMetadata {
 | |
|   // patch v1 to v3 by adding exports and the `extends` clause.
 | |
|   // patch v3 to v4 by adding `interface` symbols for TypeAlias
 | |
|   let newMetadata: ModuleMetadata = {
 | |
|     '__symbolic': 'module',
 | |
|     'version': METADATA_VERSION,
 | |
|     'metadata': {...oldMetadata.metadata},
 | |
|   };
 | |
|   if (oldMetadata.exports) {
 | |
|     newMetadata.exports = oldMetadata.exports;
 | |
|   }
 | |
|   if (oldMetadata.importAs) {
 | |
|     newMetadata.importAs = oldMetadata.importAs;
 | |
|   }
 | |
|   if (oldMetadata.origins) {
 | |
|     newMetadata.origins = oldMetadata.origins;
 | |
|   }
 | |
|   const dtsMetadata = host.getSourceFileMetadata(dtsFilePath);
 | |
|   if (dtsMetadata) {
 | |
|     for (let prop in dtsMetadata.metadata) {
 | |
|       if (!newMetadata.metadata[prop]) {
 | |
|         newMetadata.metadata[prop] = dtsMetadata.metadata[prop];
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // Only copy exports from exports from metadata prior to version 3.
 | |
|     // Starting with version 3 the collector began collecting exports and
 | |
|     // this should be redundant. Also, with bundler will rewrite the exports
 | |
|     // which will hoist the exports from modules referenced indirectly causing
 | |
|     // the imports to be different than the .d.ts files and using the .d.ts file
 | |
|     // exports would cause the StaticSymbolResolver to redirect symbols to the
 | |
|     // incorrect location.
 | |
|     if ((!oldMetadata.version || oldMetadata.version < 3) && dtsMetadata.exports) {
 | |
|       newMetadata.exports = dtsMetadata.exports;
 | |
|     }
 | |
|   }
 | |
|   return newMetadata;
 | |
| }
 |