Skip to content

Commit 1b4df57

Browse files
authored
Merge pull request github#3731 from asger-semmle/js/monorepo-bugfixes
Approved by erik-krogh
2 parents beb6629 + e28284b commit 1b4df57

File tree

8 files changed

+264
-88
lines changed

8 files changed

+264
-88
lines changed

javascript/extractor/lib/typescript/src/main.ts

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,26 @@ import { Project } from "./common";
4141
import { TypeTable } from "./type_table";
4242
import { VirtualSourceRoot } from "./virtual_source_root";
4343

44+
// Remove limit on stack trace depth.
45+
Error.stackTraceLimit = Infinity;
46+
4447
interface ParseCommand {
4548
command: "parse";
4649
filename: string;
4750
}
48-
interface OpenProjectCommand {
49-
command: "open-project";
51+
interface LoadCommand {
5052
tsConfig: string;
53+
sourceRoot: string | null;
5154
virtualSourceRoot: string | null;
5255
packageEntryPoints: [string, string][];
5356
packageJsonFiles: [string, string][];
5457
}
58+
interface OpenProjectCommand extends LoadCommand {
59+
command: "open-project";
60+
}
61+
interface GetOwnFilesCommand extends LoadCommand {
62+
command: "get-own-files";
63+
}
5564
interface CloseProjectCommand {
5665
command: "close-project";
5766
tsConfig: string;
@@ -72,7 +81,7 @@ interface PrepareFilesCommand {
7281
interface GetMetadataCommand {
7382
command: "get-metadata";
7483
}
75-
type Command = ParseCommand | OpenProjectCommand | CloseProjectCommand
84+
type Command = ParseCommand | OpenProjectCommand | GetOwnFilesCommand | CloseProjectCommand
7685
| GetTypeTableCommand | ResetCommand | QuitCommand | PrepareFilesCommand | GetMetadataCommand;
7786

7887
/** The state to be shared between commands. */
@@ -362,15 +371,22 @@ function parseSingleFile(filename: string): {ast: ts.SourceFile, code: string} {
362371
*/
363372
const nodeModulesRex = /[/\\]node_modules[/\\]((?:@[\w.-]+[/\\])?\w[\w.-]*)[/\\](.*)/;
364373

365-
function handleOpenProjectCommand(command: OpenProjectCommand) {
366-
Error.stackTraceLimit = Infinity;
367-
let tsConfigFilename = String(command.tsConfig);
368-
let tsConfig = ts.readConfigFile(tsConfigFilename, ts.sys.readFile);
369-
let basePath = pathlib.dirname(tsConfigFilename);
374+
interface LoadedConfig {
375+
config: ts.ParsedCommandLine;
376+
basePath: string;
377+
packageEntryPoints: Map<string, string>;
378+
packageJsonFiles: Map<string, string>;
379+
virtualSourceRoot: VirtualSourceRoot;
380+
ownFiles: string[];
381+
}
382+
383+
function loadTsConfig(command: LoadCommand): LoadedConfig {
384+
let tsConfig = ts.readConfigFile(command.tsConfig, ts.sys.readFile);
385+
let basePath = pathlib.dirname(command.tsConfig);
370386

371387
let packageEntryPoints = new Map(command.packageEntryPoints);
372388
let packageJsonFiles = new Map(command.packageJsonFiles);
373-
let virtualSourceRoot = new VirtualSourceRoot(process.cwd(), command.virtualSourceRoot);
389+
let virtualSourceRoot = new VirtualSourceRoot(command.sourceRoot, command.virtualSourceRoot);
374390

375391
/**
376392
* Rewrites path segments of form `node_modules/PACK/suffix` to be relative to
@@ -415,7 +431,29 @@ function handleOpenProjectCommand(command: OpenProjectCommand) {
415431
}
416432
};
417433
let config = ts.parseJsonConfigFileContent(tsConfig.config, parseConfigHost, basePath);
418-
let project = new Project(tsConfigFilename, config, state.typeTable, packageEntryPoints, virtualSourceRoot);
434+
435+
let ownFiles = config.fileNames.map(file => pathlib.resolve(file));
436+
437+
return { config, basePath, packageJsonFiles, packageEntryPoints, virtualSourceRoot, ownFiles };
438+
}
439+
440+
/**
441+
* Returns the list of files included in the given tsconfig.json file's include pattern,
442+
* (not including those only references through imports).
443+
*/
444+
function handleGetFileListCommand(command: GetOwnFilesCommand) {
445+
let { config, ownFiles } = loadTsConfig(command);
446+
447+
console.log(JSON.stringify({
448+
type: "file-list",
449+
ownFiles,
450+
}));
451+
}
452+
453+
function handleOpenProjectCommand(command: OpenProjectCommand) {
454+
let { config, packageEntryPoints, virtualSourceRoot, basePath, ownFiles } = loadTsConfig(command);
455+
456+
let project = new Project(command.tsConfig, config, state.typeTable, packageEntryPoints, virtualSourceRoot);
419457
project.load();
420458

421459
state.project = project;
@@ -587,9 +625,14 @@ function handleOpenProjectCommand(command: OpenProjectCommand) {
587625
return symbol;
588626
}
589627

628+
// Unlike in the get-own-files command, this command gets all files we can possibly
629+
// extract type information for, including files referenced outside the tsconfig's inclusion pattern.
630+
let allFiles = program.getSourceFiles().map(sf => pathlib.resolve(sf.fileName));
631+
590632
console.log(JSON.stringify({
591633
type: "project-opened",
592-
files: program.getSourceFiles().map(sf => pathlib.resolve(sf.fileName)),
634+
ownFiles,
635+
allFiles,
593636
}));
594637
}
595638

@@ -685,6 +728,9 @@ function runReadLineInterface() {
685728
case "open-project":
686729
handleOpenProjectCommand(req);
687730
break;
731+
case "get-own-files":
732+
handleGetFileListCommand(req);
733+
break;
688734
case "close-project":
689735
handleCloseProjectCommand(req);
690736
break;
@@ -720,6 +766,7 @@ if (process.argv.length > 2) {
720766
tsConfig: argument,
721767
packageEntryPoints: [],
722768
packageJsonFiles: [],
769+
sourceRoot: null,
723770
virtualSourceRoot: null,
724771
});
725772
for (let sf of state.project.program.getSourceFiles()) {

javascript/extractor/lib/typescript/src/virtual_source_root.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ import * as ts from "./typescript";
77
*/
88
export class VirtualSourceRoot {
99
constructor(
10-
private sourceRoot: string,
10+
private sourceRoot: string | null,
1111

1212
/**
1313
* Directory whose folder structure mirrors the real source root, but with `node_modules` installed,
1414
* or undefined if no virtual source root exists.
1515
*/
16-
private virtualSourceRoot: string,
16+
private virtualSourceRoot: string | null,
1717
) {}
1818

1919
/**
2020
* Maps a path under the real source root to the corresponding path in the virtual source root.
2121
*/
2222
public toVirtualPath(path: string) {
23-
if (!this.virtualSourceRoot) return null;
23+
if (!this.virtualSourceRoot || !this.sourceRoot) return null;
2424
let relative = pathlib.relative(this.sourceRoot, path);
2525
if (relative.startsWith('..') || pathlib.isAbsolute(relative)) return null;
2626
return pathlib.join(this.virtualSourceRoot, relative);

0 commit comments

Comments
 (0)