Skip to content

Commit c8672fd

Browse files
authored
feat: implement analysis include/exclude (#172)
* implement analysis include/exclude * add safety check
1 parent 29a86de commit c8672fd

File tree

2 files changed

+57
-34
lines changed

2 files changed

+57
-34
lines changed

libraries/analysis-javascript/lib/RootContext.ts

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { DependencyFactory } from "./dependency/DependencyFactory";
2727
import { Export } from "./target/export/Export";
2828
import { TargetFactory } from "./target/TargetFactory";
2929
import { TypeModelFactory } from "./type/resolving/TypeModelFactory";
30-
import { getAllFiles, readFile } from "./utils/fileSystem";
30+
import { readFile } from "./utils/fileSystem";
3131
import { ExportFactory } from "./target/export/ExportFactory";
3232
import { TypeExtractor } from "./type/discovery/TypeExtractor";
3333
import { TypeModel } from "./type/resolving/TypeModel";
@@ -51,7 +51,9 @@ export class RootContext extends CoreRootContext<t.Node> {
5151

5252
protected _constantPoolFactory: ConstantPoolFactory;
5353

54-
protected _files: string[];
54+
protected _targetFiles: Set<string>;
55+
protected _analysisFiles: Set<string>;
56+
5557
// filepath -> id -> element
5658
protected _elementMap: Map<string, Map<string, Element>>;
5759
// filepath -> id -> relation
@@ -67,6 +69,8 @@ export class RootContext extends CoreRootContext<t.Node> {
6769

6870
constructor(
6971
rootPath: string,
72+
targetFiles: Set<string>,
73+
analysisFiles: Set<string>,
7074
abstractSyntaxTreeFactory: AbstractSyntaxTreeFactory,
7175
controlFlowGraphFactory: ControlFlowGraphFactory,
7276
targetFactory: TargetFactory,
@@ -85,6 +89,8 @@ export class RootContext extends CoreRootContext<t.Node> {
8589
dependencyFactory
8690
);
8791
RootContext.LOGGER = getLogger("RootContext");
92+
this._targetFiles = targetFiles;
93+
this._analysisFiles = analysisFiles;
8894
this._exportFactory = exportFactory;
8995
this._typeExtractor = typeExtractor;
9096
this._typeResolver = typeResolver;
@@ -95,21 +101,6 @@ export class RootContext extends CoreRootContext<t.Node> {
95101
return this._rootPath;
96102
}
97103

98-
// TODO something with the types
99-
100-
getFiles() {
101-
if (!this._files) {
102-
this._files = getAllFiles(this.rootPath, ".js").filter(
103-
(x) =>
104-
!x.includes("/test/") &&
105-
!x.includes(".test.js") &&
106-
!x.includes("node_modules")
107-
); // maybe we should also take those into account
108-
}
109-
110-
return this._files;
111-
}
112-
113104
override getSource(filePath: string) {
114105
let absoluteTargetPath = this.resolvePath(filePath);
115106

@@ -172,7 +163,7 @@ export class RootContext extends CoreRootContext<t.Node> {
172163
if (!this._exportMap) {
173164
this._exportMap = new Map();
174165

175-
for (const filepath of this.getFiles()) {
166+
for (const filepath of this._analysisFiles) {
176167
this._exportMap.set(filepath, this.getExports(filepath));
177168
}
178169
}
@@ -208,7 +199,7 @@ export class RootContext extends CoreRootContext<t.Node> {
208199
if (!this._elementMap) {
209200
this._elementMap = new Map();
210201

211-
for (const filepath of this.getFiles()) {
202+
for (const filepath of this._analysisFiles) {
212203
this._elementMap.set(filepath, this.getElements(filepath));
213204
}
214205
}
@@ -244,7 +235,7 @@ export class RootContext extends CoreRootContext<t.Node> {
244235
if (!this._relationMap) {
245236
this._relationMap = new Map();
246237

247-
for (const filepath of this.getFiles()) {
238+
for (const filepath of this._analysisFiles) {
248239
this._relationMap.set(filepath, this.getRelations(filepath));
249240
}
250241
}
@@ -280,7 +271,7 @@ export class RootContext extends CoreRootContext<t.Node> {
280271
if (!this._objectMap) {
281272
this._objectMap = new Map();
282273

283-
for (const filepath of this.getFiles()) {
274+
for (const filepath of this._analysisFiles) {
284275
this._objectMap.set(filepath, this.getObjectTypes(filepath));
285276
}
286277
}
@@ -332,7 +323,7 @@ export class RootContext extends CoreRootContext<t.Node> {
332323
// TODO cache
333324
private _getContextConstantPool(): ConstantPool {
334325
const constantPool = new ConstantPool();
335-
for (const filepath of this.getFiles()) {
326+
for (const filepath of this._analysisFiles) {
336327
const ast = this.getAbstractSyntaxTree(filepath);
337328
this._constantPoolFactory.extract(filepath, ast, constantPool);
338329
}

tools/javascript/lib/JavaScriptLauncher.ts

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
ProcreationPlugin,
4545
TerminationTriggerPlugin,
4646
PropertyName,
47+
FileSelector,
4748
} from "@syntest/base-language";
4849
import {
4950
UserInterface,
@@ -170,8 +171,35 @@ export class JavaScriptLauncher extends Launcher {
170171
(<JavaScriptArguments>this.arguments_).syntaxForgiving
171172
);
172173

174+
const fileSelector = new FileSelector();
175+
const targetFiles = fileSelector.loadFilePaths(
176+
this.arguments_.targetInclude,
177+
this.arguments_.targetExclude
178+
);
179+
180+
if (this.arguments_.analysisInclude.length === 0) {
181+
JavaScriptLauncher.LOGGER.warn(
182+
"'analysis-include' config parameter is empty so we only use the target files for analysis"
183+
);
184+
}
185+
186+
for (const target of targetFiles) {
187+
if (this.arguments_.analysisExclude.includes(target)) {
188+
throw new Error(
189+
`Target files cannot be excluded from analysis. Target file: ${target}`
190+
);
191+
}
192+
}
193+
194+
const analysisFiles = fileSelector.loadFilePaths(
195+
[...targetFiles, ...this.arguments_.analysisInclude],
196+
this.arguments_.analysisExclude
197+
);
198+
173199
this.rootContext = new RootContext(
174200
this.arguments_.targetRootDirectory,
201+
targetFiles,
202+
analysisFiles,
175203
abstractSyntaxTreeFactory,
176204
controlFlowGraphFactory,
177205
targetFactory,
@@ -184,15 +212,6 @@ export class JavaScriptLauncher extends Launcher {
184212

185213
this.userInterface.printHeader("GENERAL INFO");
186214

187-
// TODO ui info messages
188-
189-
// this.userInterface.report("property-set", [
190-
// "Target Settings",
191-
// <string>(
192-
// (<unknown>[["Target Root Directory", this.arguments_.targetRootDirectory]])
193-
// ),
194-
// ]);
195-
196215
const timeInMs = (Date.now() - start) / 1000;
197216
this.metricManager.recordProperty(
198217
PropertyName.INITIALIZATION_TIME,
@@ -209,8 +228,8 @@ export class JavaScriptLauncher extends Launcher {
209228
const startTargetSelection = Date.now();
210229
const targetSelector = new TargetSelector(this.rootContext);
211230
this.targets = targetSelector.loadTargets(
212-
this.arguments_.include,
213-
this.arguments_.exclude
231+
this.arguments_.targetInclude,
232+
this.arguments_.targetExclude
214233
);
215234
let timeInMs = (Date.now() - startTargetSelection) / 1000;
216235
this.metricManager.recordProperty(
@@ -221,7 +240,7 @@ export class JavaScriptLauncher extends Launcher {
221240
if (this.targets.length === 0) {
222241
// Shut server down
223242
this.userInterface.printError(
224-
`No targets where selected! Try changing the 'include' parameter`
243+
`No targets where selected! Try changing the 'target-include' parameter`
225244
);
226245
await this.exit();
227246
// eslint-disable-next-line unicorn/no-process-exit
@@ -243,6 +262,19 @@ export class JavaScriptLauncher extends Launcher {
243262

244263
this.userInterface.printItemization("TARGETS", itemization);
245264

265+
const selectionSettings: TableObject = {
266+
headers: ["Setting", "Value"],
267+
rows: [
268+
["Target Root Directory", this.arguments_.targetRootDirectory],
269+
["Target Include", `${this.arguments_.targetInclude.join(", ")}`],
270+
["Target Exclude", `${this.arguments_.targetExclude.join(", ")}`],
271+
["Analysis Include", `${this.arguments_.analysisInclude.join(", ")}`],
272+
["Analysis Exclude", `${this.arguments_.analysisExclude.join(", ")}`],
273+
],
274+
footers: ["", ""],
275+
};
276+
this.userInterface.printTable("SELECTION SETTINGS", selectionSettings);
277+
246278
const settings: TableObject = {
247279
headers: ["Setting", "Value"],
248280
rows: [

0 commit comments

Comments
 (0)