Skip to content

JS: Monorepo support: bugfixes and separate from dependency installation #3731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 26, 2020
69 changes: 58 additions & 11 deletions javascript/extractor/lib/typescript/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,26 @@ import { Project } from "./common";
import { TypeTable } from "./type_table";
import { VirtualSourceRoot } from "./virtual_source_root";

// Remove limit on stack trace depth.
Error.stackTraceLimit = Infinity;

interface ParseCommand {
command: "parse";
filename: string;
}
interface OpenProjectCommand {
command: "open-project";
interface LoadCommand {
tsConfig: string;
sourceRoot: string | null;
virtualSourceRoot: string | null;
packageEntryPoints: [string, string][];
packageJsonFiles: [string, string][];
}
interface OpenProjectCommand extends LoadCommand {
command: "open-project";
}
interface GetOwnFilesCommand extends LoadCommand {
command: "get-own-files";
}
interface CloseProjectCommand {
command: "close-project";
tsConfig: string;
Expand All @@ -72,7 +81,7 @@ interface PrepareFilesCommand {
interface GetMetadataCommand {
command: "get-metadata";
}
type Command = ParseCommand | OpenProjectCommand | CloseProjectCommand
type Command = ParseCommand | OpenProjectCommand | GetOwnFilesCommand | CloseProjectCommand
| GetTypeTableCommand | ResetCommand | QuitCommand | PrepareFilesCommand | GetMetadataCommand;

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

function handleOpenProjectCommand(command: OpenProjectCommand) {
Error.stackTraceLimit = Infinity;
let tsConfigFilename = String(command.tsConfig);
let tsConfig = ts.readConfigFile(tsConfigFilename, ts.sys.readFile);
let basePath = pathlib.dirname(tsConfigFilename);
interface LoadedConfig {
config: ts.ParsedCommandLine;
basePath: string;
packageEntryPoints: Map<string, string>;
packageJsonFiles: Map<string, string>;
virtualSourceRoot: VirtualSourceRoot;
ownFiles: string[];
}

function loadTsConfig(command: LoadCommand): LoadedConfig {
let tsConfig = ts.readConfigFile(command.tsConfig, ts.sys.readFile);
let basePath = pathlib.dirname(command.tsConfig);

let packageEntryPoints = new Map(command.packageEntryPoints);
let packageJsonFiles = new Map(command.packageJsonFiles);
let virtualSourceRoot = new VirtualSourceRoot(process.cwd(), command.virtualSourceRoot);
let virtualSourceRoot = new VirtualSourceRoot(command.sourceRoot, command.virtualSourceRoot);

/**
* Rewrites path segments of form `node_modules/PACK/suffix` to be relative to
Expand Down Expand Up @@ -415,7 +431,29 @@ function handleOpenProjectCommand(command: OpenProjectCommand) {
}
};
let config = ts.parseJsonConfigFileContent(tsConfig.config, parseConfigHost, basePath);
let project = new Project(tsConfigFilename, config, state.typeTable, packageEntryPoints, virtualSourceRoot);

let ownFiles = config.fileNames.map(file => pathlib.resolve(file));

return { config, basePath, packageJsonFiles, packageEntryPoints, virtualSourceRoot, ownFiles };
}

/**
* Returns the list of files included in the given tsconfig.json file's include pattern,
* (not including those only references through imports).
*/
function handleGetFileListCommand(command: GetOwnFilesCommand) {
let { config, ownFiles } = loadTsConfig(command);

console.log(JSON.stringify({
type: "file-list",
ownFiles,
}));
}

function handleOpenProjectCommand(command: OpenProjectCommand) {
let { config, packageEntryPoints, virtualSourceRoot, basePath, ownFiles } = loadTsConfig(command);

let project = new Project(command.tsConfig, config, state.typeTable, packageEntryPoints, virtualSourceRoot);
project.load();

state.project = project;
Expand Down Expand Up @@ -587,9 +625,14 @@ function handleOpenProjectCommand(command: OpenProjectCommand) {
return symbol;
}

// Unlike in the get-own-files command, this command gets all files we can possibly
// extract type information for, including files referenced outside the tsconfig's inclusion pattern.
let allFiles = program.getSourceFiles().map(sf => pathlib.resolve(sf.fileName));

console.log(JSON.stringify({
type: "project-opened",
files: program.getSourceFiles().map(sf => pathlib.resolve(sf.fileName)),
ownFiles,
allFiles,
}));
}

Expand Down Expand Up @@ -685,6 +728,9 @@ function runReadLineInterface() {
case "open-project":
handleOpenProjectCommand(req);
break;
case "get-own-files":
handleGetFileListCommand(req);
break;
case "close-project":
handleCloseProjectCommand(req);
break;
Expand Down Expand Up @@ -720,6 +766,7 @@ if (process.argv.length > 2) {
tsConfig: argument,
packageEntryPoints: [],
packageJsonFiles: [],
sourceRoot: null,
virtualSourceRoot: null,
});
for (let sf of state.project.program.getSourceFiles()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ import * as ts from "./typescript";
*/
export class VirtualSourceRoot {
constructor(
private sourceRoot: string,
private sourceRoot: string | null,

/**
* Directory whose folder structure mirrors the real source root, but with `node_modules` installed,
* or undefined if no virtual source root exists.
*/
private virtualSourceRoot: string,
private virtualSourceRoot: string | null,
) {}

/**
* Maps a path under the real source root to the corresponding path in the virtual source root.
*/
public toVirtualPath(path: string) {
if (!this.virtualSourceRoot) return null;
if (!this.virtualSourceRoot || !this.sourceRoot) return null;
let relative = pathlib.relative(this.sourceRoot, path);
if (relative.startsWith('..') || pathlib.isAbsolute(relative)) return null;
return pathlib.join(this.virtualSourceRoot, relative);
Expand Down
Loading