75 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var ts = require('typescript');
 | |
| var path = require('canonical-path');
 | |
| 
 | |
| module.exports = function tsParser(createCompilerHost, log) {
 | |
| 
 | |
|   return {
 | |
| 
 | |
|     // These are the extension that we should consider when trying to load a module
 | |
|     // During migration from Traceur, there is a mix of `.ts`, `.es6` and `.js` (atScript)
 | |
|     // files in the project and the TypeScript compiler only looks for `.ts` files when trying
 | |
|     // to load imports.
 | |
|     extensions: ['.ts', '.js'],
 | |
| 
 | |
|     // The options for the TS compiler
 | |
|     options: {
 | |
|       allowNonTsExtensions: true,
 | |
|       charset: 'utf8'
 | |
|     },
 | |
| 
 | |
|     parse: function(fileNames, baseDir) {
 | |
| 
 | |
|       // "Compile" a program from the given module filenames, to get hold of a
 | |
|       // typeChecker that can be used to interrogate the modules, exports and so on.
 | |
|       var host = createCompilerHost(this.options, baseDir, this.extensions);
 | |
|       var program = ts.createProgram(fileNames, this.options, host);
 | |
|       var typeChecker = program.getTypeChecker();
 | |
| 
 | |
|       // Create an array of module symbols for each file we were given
 | |
|       var moduleSymbols = [];
 | |
|       fileNames.forEach(function(fileName) {
 | |
|         var sourceFile = program.getSourceFile(fileName);
 | |
| 
 | |
|         if (!sourceFile) {
 | |
|           throw new Error('Invalid source file: ' + fileName);
 | |
|         } else if (!sourceFile.symbol) {
 | |
|           // Some files contain only a comment and no actual module code
 | |
|           log.warn('No module code found in ' + fileName);
 | |
|         } else {
 | |
|           moduleSymbols.push(sourceFile.symbol);
 | |
|         }
 | |
|       });
 | |
| 
 | |
| 
 | |
|       moduleSymbols.forEach(function(tsModule) {
 | |
| 
 | |
|         // The type checker has a nice helper function that returns an array of Symbols
 | |
|         // representing the exports for a given module
 | |
|         tsModule.exportArray = typeChecker.getExportsOfModule(tsModule);
 | |
| 
 | |
|         // Although 'star' imports (e.g. `export * from 'some/module';) get resolved automatically
 | |
|         // by the compiler/binder, it seems that explicit imports (e.g. `export {SomeClass} from 'some/module'`)
 | |
|         // do not so we have to do a little work.
 | |
|         tsModule.exportArray.forEach(function(moduleExport) {
 | |
|           if (moduleExport.flags & ts.SymbolFlags.Alias) {
 | |
|             // To maintain the alias information (particularly the alias name)
 | |
|             // we just attach the original "resolved" symbol to the alias symbol
 | |
|             moduleExport.resolvedSymbol = typeChecker.getAliasedSymbol(moduleExport);
 | |
|           }
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       moduleSymbols.typeChecker = typeChecker;
 | |
| 
 | |
|       return {
 | |
|         moduleSymbols: moduleSymbols,
 | |
|         typeChecker: typeChecker,
 | |
|         program: program,
 | |
|         host: host
 | |
|       };
 | |
|     }
 | |
|   };
 | |
| 
 | |
| 
 | |
| };
 |