Skip to content

Commit

Permalink
feat: #7 - Specified compiler options and tsconfig path are both used…
Browse files Browse the repository at this point in the history
… to determine added files.
  • Loading branch information
dsherret committed Jan 13, 2018
1 parent 2a95bc2 commit 20e7b77
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 175 deletions.
18 changes: 18 additions & 0 deletions docs/setup/adding-source-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ title: Adding Source Files

You will need to populate the `ast` object with source files.

### By a *tsconfig.json*

Source files will be added when instantiating with a `tsConfigFilePath`:

```ts
const ast = new Ast({
tsConfigFilePath: "path/to/tsconfig.json"
});
```

...and this can be disabled by setting `addFilesFromTsConfig: false`.

Alternatively, populate the `ast` object by calling `addSourceFilesFromTsConfig`:

```ts
ast.addSourceFilesFromTsConfig("path/to/tsconfig.json");
```

### By file globs or file paths

Specify as many file globs or file paths as you wish:
Expand Down
17 changes: 13 additions & 4 deletions docs/setup/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Ast from "ts-simple-ast";
const ast = new Ast();
```

### Custom compiler options
### Compiler options

```typescript
import * as ts from "typescript";
Expand All @@ -24,14 +24,23 @@ const ast = new Ast({
});
```

### Custom tsconfig.json
### tsconfig.json

If you would like to manually specify the path to a *tsconfig.json* file then specify that:

```typescript
```ts
const ast = new Ast({
tsConfigFilePath: "path/to/tsconfig.json"
});
```

Note: You can override any `tsconfig.json` options by also providing a `compilerOptions` object.
*Note:* You can override any `tsconfig.json` options by also providing a `compilerOptions` object.

For your convenience, this will automatically add all the associated source files from the *tsconfig.json*. If you don't wish to do that, then you will need to explicitly set `addFilesFromTsConfig` to `false`:

```ts
const ast = new Ast({
tsConfigFilePath: "path/to/tsconfig.json",
addFilesFromTsConfig: false
});
```
5 changes: 4 additions & 1 deletion docs/utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ Get the compiler options from a file by using the `getCompilerOptionsFromTsConfi
```typescript
import {getCompilerOptionsFromTsConfig} from "ts-simple-ast";

const compilerOptions = getCompilerOptionsFromTsConfig("file/path/to/tsconfig.json");
const result = getCompilerOptionsFromTsConfig("file/path/to/tsconfig.json");

result.options; // compiler options
result.errors; // diagnostics
```

### Type Guards
Expand Down
47 changes: 27 additions & 20 deletions src/TsSimpleAst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import * as errors from "./errors";
import * as compiler from "./compiler";
import * as factories from "./factories";
import {SourceFileStructure} from "./structures";
import {getInfoFromTsConfig, TsConfigInfo, FileUtils, ArrayUtils} from "./utils";
import {getTsConfigParseResult, getCompilerOptionsFromTsConfigParseResult, getFilePathsFromTsConfigParseResult, TsConfigParseResult,
FileUtils, ArrayUtils} from "./utils";
import {DefaultFileSystemHost, VirtualFileSystemHost, FileSystemHost, Directory} from "./fileSystem";
import {ManipulationSettings, ManipulationSettingsContainer} from "./ManipulationSettings";
import {GlobalContainer} from "./GlobalContainer";
Expand Down Expand Up @@ -44,23 +45,33 @@ export class TsSimpleAst {
fileSystem = new DefaultFileSystemHost();

// get tsconfig info
const tsConfigInfo = getTsConfigInfo();
const tsConfigParseResult = options.tsConfigFilePath == null ? undefined : getTsConfigParseResult(options.tsConfigFilePath, fileSystem);
const compilerOptions = getCompilerOptions();

// setup global container
this.global = new GlobalContainer(fileSystem, getCompilerOptions(options, tsConfigInfo), { createLanguageService: true });
this.global = new GlobalContainer(fileSystem, compilerOptions, { createLanguageService: true });

// initialize manipulation settings
if (options.manipulationSettings != null)
this.global.manipulationSettings.set(options.manipulationSettings);

// add any file paths from the tsconfig if necessary
if (tsConfigInfo != null && tsConfigInfo.filePaths != null)
tsConfigInfo.filePaths.forEach(filePath => this.addExistingSourceFile(filePath));
if (tsConfigParseResult != null && options.addFilesFromTsConfig !== false) {
for (const filePath of getFilePathsFromTsConfigParseResult(options.tsConfigFilePath!, fileSystem, tsConfigParseResult, compilerOptions))
this.addExistingSourceFile(filePath);
}

function getCompilerOptions(): ts.CompilerOptions {
return {
...getTsConfigCompilerOptions(),
...(options.compilerOptions || {}) as ts.CompilerOptions
};
}

function getTsConfigInfo() {
if (options.tsConfigFilePath == null)
return undefined;
return getInfoFromTsConfig(options.tsConfigFilePath, fileSystem!, { shouldGetFilePaths: options.addFilesFromTsConfig !== false });
function getTsConfigCompilerOptions() {
if (tsConfigParseResult == null)
return {};
return getCompilerOptionsFromTsConfigParseResult(options.tsConfigFilePath!, fileSystem!, tsConfigParseResult).options;
}
}

Expand Down Expand Up @@ -197,10 +208,13 @@ export class TsSimpleAst {
* addFilesFromTsConfig option to false.
* @param tsConfigFilePath - File path to the tsconfig.json file.
*/
addSourceFilesFromTsConfig(tsConfigFilePath: string) {
const info = getInfoFromTsConfig(tsConfigFilePath, this.global.fileSystem, { shouldGetFilePaths: true });
for (const filePath of info.filePaths!)
this.addExistingSourceFile(filePath);
addSourceFilesFromTsConfig(tsConfigFilePath: string): compiler.SourceFile[] {
tsConfigFilePath = FileUtils.getStandardizedAbsolutePath(this.global.fileSystem, tsConfigFilePath);
const parseResult = getTsConfigParseResult(tsConfigFilePath, this.global.fileSystem);
const compilerOptions = getCompilerOptionsFromTsConfigParseResult(tsConfigFilePath, this.global.fileSystem, parseResult);
const filePaths = getFilePathsFromTsConfigParseResult(tsConfigFilePath, this.global.fileSystem, parseResult, compilerOptions.options);

return filePaths.map(path => this.addExistingSourceFile(path));
}

/**
Expand Down Expand Up @@ -436,10 +450,3 @@ export class TsSimpleAst {
return this.global.compilerFactory.forgetNodesCreatedInBlock(block);
}
}

function getCompilerOptions(options: Options, tsConfigInfo: TsConfigInfo | undefined): ts.CompilerOptions {
return {
...(tsConfigInfo == null ? {} : tsConfigInfo.compilerOptions),
...(options.compilerOptions || {}) as ts.CompilerOptions
};
}
17 changes: 15 additions & 2 deletions src/tests/tsSimpleAstTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ describe(nameof(TsSimpleAst), () => {
expect(ast.getSourceFiles().map(s => s.getFilePath()).sort()).to.deep.equal(["/test/file.ts", "/test/test2/file2.ts"].sort());
});

it("should add the files from tsconfig.json by default and also take into account the passed in compiler options", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "target": "ES5" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
const ast = new TsSimpleAst({ tsConfigFilePath: "tsconfig.json", compilerOptions: { rootDir: "/test/test2" } }, fs);
expect(ast.getSourceFiles().map(s => s.getFilePath()).sort()).to.deep.equal(["/test/test2/file2.ts"].sort());
});

it("should not add the files from tsconfig.json when specifying not to", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test", "target": "ES5" } }`);
Expand Down Expand Up @@ -225,12 +235,15 @@ describe(nameof(TsSimpleAst), () => {
it("should add the files from tsconfig.json", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test", "target": "ES5" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
const ast = new TsSimpleAst({}, fs);
expect(ast.getSourceFiles().map(s => s.getFilePath()).sort()).to.deep.equal([].sort());
ast.addSourceFilesFromTsConfig("tsconfig.json");
expect(ast.getSourceFiles().map(s => s.getFilePath()).sort()).to.deep.equal(["/test/file.ts", "/test/test2/file2.ts"].sort());
const returnedFiles = ast.addSourceFilesFromTsConfig("tsconfig.json");
const expectedFiles = ["/test/file.ts", "/test/test2/file2.ts"].sort();
expect(ast.getSourceFiles().map(s => s.getFilePath()).sort()).to.deep.equal(expectedFiles);
expect(returnedFiles.map(s => s.getFilePath()).sort()).to.deep.equal(expectedFiles);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {expect} from "chai";
import {VirtualFileSystemHost} from "./../../../fileSystem";
import {getFilePathsFromTsConfigParseResult, getTsConfigParseResult, getCompilerOptionsFromTsConfigParseResult, FileUtils} from "./../../../utils";
import * as errors from "./../../../errors";

describe(nameof(getFilePathsFromTsConfigParseResult), () => {
function getFilePaths(fileSystem: VirtualFileSystemHost) {
const parseResult = getTsConfigParseResult("tsconfig.json", fileSystem);
const compilerOptions = getCompilerOptionsFromTsConfigParseResult("tsconfig.json", fileSystem, parseResult);
return getFilePathsFromTsConfigParseResult("tsconfig.json", fileSystem, parseResult, compilerOptions.options);
}

function doTest(fileSystem: VirtualFileSystemHost, expectedPaths: string[]) {
expect(getFilePaths(fileSystem).sort()).to.deep.equal(expectedPaths.sort());
}

it("should get the file paths when there are none", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test", "target": "ES5" } }`);
doTest(fs, []);
});

it("should add the files from tsconfig.json, but exclude the outDir", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "outDir": "test2" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test2/file2.ts", "");
doTest(fs, ["/otherFile.ts", "/test/file.ts"]);
});

it("should add the files from tsconfig.json, but exclude the specified exclude", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "exclude": ["test2"] }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test2/file2.ts", "");
doTest(fs, ["/otherFile.ts", "/test/file.ts"]);
});

it("should add the files from tsconfig.json, but only include the specified include", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "include": ["test2"] }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test2/file2.ts", "");
doTest(fs, ["/test2/file2.ts"]);
});

it("should add the files from tsconfig.json when using rootDir", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
doTest(fs, ["/test/file.ts", "/test/test2/file2.ts"]);
});

it("should add the files from tsconfig.json when using rootDirs", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDirs": ["/test/test1", "/test/test2"] } }`);
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test1/file1.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
doTest(fs, ["/test/test1/file1.ts", "/test/test2/file2.ts"]);
});

it("should add the files from tsconfig.json when using rootDir and rootDirs", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "/test/test1", "rootDirs": ["/test/test2"] } }`);
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test1/file1.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
doTest(fs, ["/test/test1/file1.ts", "/test/test2/file2.ts"]);
});
});
92 changes: 0 additions & 92 deletions src/tests/utils/tsconfig/getInfoFromTsConfigTests.ts

This file was deleted.

11 changes: 11 additions & 0 deletions src/tests/utils/tsconfig/getTsConfigParseResultTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {expect} from "chai";
import {VirtualFileSystemHost} from "./../../../fileSystem";
import {getTsConfigParseResult, FileUtils} from "./../../../utils";
import * as errors from "./../../../errors";

describe(nameof(getTsConfigParseResult), () => {
it("should throw an error when the path doesn't exist", () => {
const fs = new VirtualFileSystemHost();
expect(() => getTsConfigParseResult("tsconfig.json", fs)).to.throw(errors.FileNotFoundError, `File not found: /tsconfig.json`);
});
});
7 changes: 4 additions & 3 deletions src/utils/tsconfig/getCompilerOptionsFromTsConfig.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as ts from "typescript";
import {Diagnostic} from "./../../compiler";
import {DefaultFileSystemHost, FileSystemHost} from "./../../fileSystem";
import {getInfoFromTsConfig} from "./getInfoFromTsConfig";
import {FileUtils} from "./../../utils";
import {getTsConfigParseResult, getCompilerOptionsFromTsConfigParseResult} from "./getInfoFromTsConfig";

/**
* Gets the compiler options from a specified tsconfig.json
Expand All @@ -11,6 +12,6 @@ import {getInfoFromTsConfig} from "./getInfoFromTsConfig";
export function getCompilerOptionsFromTsConfig(filePath: string, fileSystemHost?: FileSystemHost): { options: ts.CompilerOptions; errors: Diagnostic[]; } {
// remember, this is a public function
fileSystemHost = fileSystemHost || new DefaultFileSystemHost();
const result = getInfoFromTsConfig(filePath, fileSystemHost, { shouldGetFilePaths: false });
return { options: result.compilerOptions, errors: result.errors };
const parseResult = getTsConfigParseResult(filePath, fileSystemHost);
return getCompilerOptionsFromTsConfigParseResult(filePath, fileSystemHost, parseResult);
}

0 comments on commit 20e7b77

Please sign in to comment.