parse()

in typescript/src/services/TsParser/index.ts [36:76]


  parse(fileNames: string[], baseDir: string) {

    // "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.
    const host = new CustomCompilerHost(this.options, baseDir, this.extensions, this.log);
    const program: Program = createProgram(fileNames, this.options, host);
    const typeChecker = program.getTypeChecker();

    // Create an array of module symbols for each file we were given
    const moduleSymbols: ModuleSymbols = [];
    fileNames.forEach(fileName => {
      const sourceFile = program.getSourceFile(fileName);

      if (!sourceFile) {
        throw new Error('Invalid source file: ' + fileName);
      } else if (!(sourceFile as any).symbol) {
        // Some files contain only a comment and no actual module code
        this.log.warn('No module code found in ' + fileName);
      } else {
        moduleSymbols.push((sourceFile as any).symbol);
      }
    });

    moduleSymbols.forEach(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) as AugmentedSymbol[];

      tsModule.exportArray.forEach(moduleExport => {
        // 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.
        if (moduleExport.flags & 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 { host, moduleSymbols, program, typeChecker };
  }