Skip to content

Commit b837ebc

Browse files
authored
feat: allow unsupported syntax (#171)
* Add syntax-forgiving debug parameter to allow/disallow unsupported syntax * Add silence-test-output debug parameter to enable/disable test output to console * Move constant pool code from launcher to root context * Add common abstract factory for all analysis factories
1 parent 3552746 commit b837ebc

File tree

55 files changed

+609
-162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+609
-162
lines changed

libraries/analysis-javascript/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export * from "./lib/cfg/ControlFlowGraphFactory";
2222
export * from "./lib/cfg/ControlFlowGraphVisitor";
2323

2424
export * from "./lib/constant/ConstantPool";
25+
export * from "./lib/constant/ConstantPoolFactory";
2526
export * from "./lib/constant/ConstantPoolManager";
2627
export * from "./lib/constant/ConstantVisitor";
2728

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2020-2023 Delft University of Technology and SynTest contributors
3+
*
4+
* This file is part of SynTest Framework - SynTest JavaScript.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
export class Factory {
20+
private _syntaxForgiving: boolean;
21+
22+
constructor(syntaxForgiving: boolean) {
23+
this._syntaxForgiving = syntaxForgiving;
24+
}
25+
26+
get syntaxForgiving() {
27+
return this._syntaxForgiving;
28+
}
29+
}

libraries/analysis-javascript/lib/RootContext.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,20 @@ import { Relation } from "./type/discovery/relation/Relation";
3737
import { TypePool } from "./type/resolving/TypePool";
3838
import TypedEmitter from "typed-emitter";
3939
import { Events } from "./Events";
40+
import { ConstantPoolManager } from "./constant/ConstantPoolManager";
41+
import { Logger, getLogger } from "@syntest/logging";
42+
import { ConstantPoolFactory } from "./constant/ConstantPoolFactory";
43+
import { ConstantPool } from "./constant/ConstantPool";
4044

4145
export class RootContext extends CoreRootContext<t.Node> {
46+
protected static LOGGER: Logger;
47+
4248
protected _exportFactory: ExportFactory;
4349
protected _typeExtractor: TypeExtractor;
4450
protected _typeResolver: TypeModelFactory;
4551

52+
protected _constantPoolFactory: ConstantPoolFactory;
53+
4654
protected _files: string[];
4755
// filepath -> id -> element
4856
protected _elementMap: Map<string, Map<string, Element>>;
@@ -65,7 +73,8 @@ export class RootContext extends CoreRootContext<t.Node> {
6573
dependencyFactory: DependencyFactory,
6674
exportFactory: ExportFactory,
6775
typeExtractor: TypeExtractor,
68-
typeResolver: TypeModelFactory
76+
typeResolver: TypeModelFactory,
77+
constantPoolFactory: ConstantPoolFactory
6978
) {
7079
super(
7180
rootPath,
@@ -75,9 +84,11 @@ export class RootContext extends CoreRootContext<t.Node> {
7584
targetFactory,
7685
dependencyFactory
7786
);
87+
RootContext.LOGGER = getLogger("RootContext");
7888
this._exportFactory = exportFactory;
7989
this._typeExtractor = typeExtractor;
8090
this._typeResolver = typeResolver;
91+
this._constantPoolFactory = constantPoolFactory;
8192
}
8293

8394
get rootPath(): string {
@@ -317,4 +328,39 @@ export class RootContext extends CoreRootContext<t.Node> {
317328

318329
return this._typePool;
319330
}
331+
332+
// TODO cache
333+
private _getContextConstantPool(): ConstantPool {
334+
const constantPool = new ConstantPool();
335+
for (const filepath of this.getFiles()) {
336+
const ast = this.getAbstractSyntaxTree(filepath);
337+
this._constantPoolFactory.extract(filepath, ast, constantPool);
338+
}
339+
340+
return constantPool;
341+
}
342+
343+
// TODO cache
344+
getConstantPoolManager(filepath: string): ConstantPoolManager {
345+
const absolutePath = this.resolvePath(filepath);
346+
347+
RootContext.LOGGER.info("Extracting constants");
348+
const ast = this.getAbstractSyntaxTree(absolutePath);
349+
350+
const targetConstantPool = this._constantPoolFactory.extract(
351+
absolutePath,
352+
ast
353+
);
354+
const contextConstantPool = this._getContextConstantPool();
355+
const dynamicConstantPool = new ConstantPool();
356+
357+
const constantPoolManager = new ConstantPoolManager(
358+
targetConstantPool,
359+
contextConstantPool,
360+
dynamicConstantPool
361+
);
362+
363+
RootContext.LOGGER.info("Extracting constants done");
364+
return constantPoolManager;
365+
}
320366
}

libraries/analysis-javascript/lib/cfg/ControlFlowGraphFactory.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ import { ControlFlowGraphFactory as CoreControlFlowGraphFactory } from "@syntest
2121
import { ControlFlowProgram, contractControlFlowProgram } from "@syntest/cfg";
2222

2323
import { ControlFlowGraphVisitor } from "./ControlFlowGraphVisitor";
24+
import { Factory } from "../Factory";
2425

2526
export class ControlFlowGraphFactory
27+
extends Factory
2628
implements CoreControlFlowGraphFactory<t.Node>
2729
{
2830
convert(filePath: string, AST: t.Node): ControlFlowProgram {
29-
const visitor = new ControlFlowGraphVisitor(filePath);
31+
const visitor = new ControlFlowGraphVisitor(filePath, this.syntaxForgiving);
3032
traverse(AST, visitor);
3133

3234
return contractControlFlowProgram(visitor.cfg);

libraries/analysis-javascript/lib/cfg/ControlFlowGraphVisitor.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ export class ControlFlowGraphVisitor extends AbstractSyntaxTreeVisitor {
127127
};
128128
}
129129

130-
constructor(filePath: string) {
131-
super(filePath);
130+
constructor(filePath: string, syntaxForgiving: boolean) {
131+
super(filePath, syntaxForgiving);
132132
ControlFlowGraphVisitor.LOGGER = getLogger("ControlFlowGraphVisitor");
133133

134134
this._nodesList = [];
@@ -365,7 +365,10 @@ export class ControlFlowGraphVisitor extends AbstractSyntaxTreeVisitor {
365365
this._currentParents = [node.id];
366366
}
367367

368-
const subVisitor = new ControlFlowGraphVisitor(this.filePath);
368+
const subVisitor = new ControlFlowGraphVisitor(
369+
this.filePath,
370+
this.syntaxForgiving
371+
);
369372
path.traverse(subVisitor);
370373

371374
if (!subVisitor._nodes.has("ENTRY")) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2020-2023 Delft University of Technology and SynTest contributors
3+
*
4+
* This file is part of SynTest Framework - SynTest JavaScript.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
import { traverse } from "@babel/core";
19+
import * as t from "@babel/types";
20+
21+
import { Factory } from "../Factory";
22+
import { ConstantVisitor } from "./ConstantVisitor";
23+
import { ConstantPool } from "./ConstantPool";
24+
25+
export class ConstantPoolFactory extends Factory {
26+
/**
27+
* Generate function map for specified target.
28+
*
29+
* @param AST The AST of the target
30+
*/
31+
extract(
32+
filePath: string,
33+
AST: t.Node,
34+
constantPool?: ConstantPool | undefined
35+
): ConstantPool {
36+
if (!constantPool) {
37+
constantPool = new ConstantPool();
38+
}
39+
const constantVisitor = new ConstantVisitor(
40+
filePath,
41+
this.syntaxForgiving,
42+
constantPool
43+
);
44+
traverse(AST, constantVisitor);
45+
46+
return constantPool;
47+
}
48+
}

libraries/analysis-javascript/lib/constant/ConstantPoolManager.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ export class ConstantPoolManager {
2323
protected _contextConstantPool: ConstantPool;
2424
protected _dynamicConstantPool: ConstantPool;
2525

26-
constructor() {
27-
this._targetConstantPool = new ConstantPool();
28-
this._contextConstantPool = new ConstantPool();
29-
this._dynamicConstantPool = new ConstantPool();
26+
constructor(
27+
targetConstantPool: ConstantPool,
28+
contextConstantPool: ConstantPool,
29+
dynamicConstantPool: ConstantPool
30+
) {
31+
this._targetConstantPool = targetConstantPool;
32+
this._contextConstantPool = contextConstantPool;
33+
this._dynamicConstantPool = dynamicConstantPool;
3034
}
3135

3236
public get targetConstantPool(): ConstantPool {

libraries/analysis-javascript/lib/constant/ConstantVisitor.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@ import { ConstantPool } from "./ConstantPool";
2323
export class ConstantVisitor extends AbstractSyntaxTreeVisitor {
2424
protected _constantPool: ConstantPool;
2525

26-
constructor(filePath: string, constantPool: ConstantPool) {
27-
super(filePath);
26+
get constantPool() {
27+
return this._constantPool;
28+
}
29+
30+
constructor(
31+
filePath: string,
32+
syntaxForgiving: boolean,
33+
constantPool: ConstantPool
34+
) {
35+
super(filePath, syntaxForgiving);
2836
this._constantPool = constantPool;
2937
}
3038

libraries/analysis-javascript/lib/dependency/DependencyFactory.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,24 @@ import * as t from "@babel/types";
2121
import { DependencyFactory as CoreDependencyFactory } from "@syntest/analysis";
2222

2323
import { DependencyVisitor } from "./DependencyVisitor";
24+
import { Factory } from "../Factory";
2425

2526
/**
2627
* Dependency generator for targets.
2728
*
2829
* @author Dimitri Stallenberg
2930
*/
30-
export class DependencyFactory implements CoreDependencyFactory<t.Node> {
31+
export class DependencyFactory
32+
extends Factory
33+
implements CoreDependencyFactory<t.Node>
34+
{
3135
/**
3236
* Generate function map for specified target.
3337
*
3438
* @param AST The AST of the target
3539
*/
3640
extract(filePath: string, AST: t.Node): string[] {
37-
const visitor = new DependencyVisitor(filePath);
41+
const visitor = new DependencyVisitor(filePath, this.syntaxForgiving);
3842

3943
traverse(AST, visitor);
4044

libraries/analysis-javascript/lib/dependency/DependencyVisitor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ export class DependencyVisitor extends AbstractSyntaxTreeVisitor {
2626

2727
private _imports: Set<string>;
2828

29-
constructor(filePath: string) {
30-
super(filePath);
29+
constructor(filePath: string, syntaxForgiving: boolean) {
30+
super(filePath, syntaxForgiving);
3131
DependencyVisitor.LOGGER = getLogger("DependencyVisitor");
3232
this._imports = new Set<string>();
3333
}

0 commit comments

Comments
 (0)