Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
import AssignmentNode from "./ast/AssignmentNode";
import { GroupingExpr, LiteralExpr, LookupExpr } from "./ast/expressions";
import ScadFile from "./ast/ScadFile";
import { BlockStmt } from "./ast/statements";
import ASTPinpointer, { BinAfter, BinBefore } from "./ASTPinpointer";
import CodeFile from "./CodeFile";
import CodeLocation from "./CodeLocation";
import ErrorCollector from "./ErrorCollector";
import Lexer from "./Lexer";
import ParsingHelper from "./ParsingHelper";
import ASTScopePopulator from "./semantic/ASTScopePopulator";
import Scope from "./semantic/Scope";
describe("ASTPinpointer", () => {
it("the internal binsearch dispatch works with simple tokens", () => {
const f = new CodeFile("<test>", "a=5;b=a;");
const ec = new ErrorCollector();
const lexer = new Lexer(f, ec);
const tokens = lexer.scan();
ec.throwIfAny();
class TstClass extends ASTPinpointer {
testFunc1() {
return this.processAssembledNode(
[tokens[1], tokens[2]],
new ScadFile([], { eot: tokens[tokens.length - 1] })
);
}
}
const p = new TstClass(new CodeLocation(f, 0));
expect(p.testFunc1()).toEqual(BinBefore);
p.pinpointLocation = new CodeLocation(f, 200);
expect(p.testFunc1()).toEqual(BinAfter);
p.pinpointLocation = new CodeLocation(f, 4);
expect(p.testFunc1()).toEqual(BinAfter);
});
it("the internal binsearch dispatch works with function trees", () => {
const f = new CodeFile("<test>", "a=5;b=a;");
const ec = new ErrorCollector();
const lexer = new Lexer(f, ec);
const tokens = lexer.scan();
ec.throwIfAny();
class TstClass extends ASTPinpointer {
testFunc1() {
return this.processAssembledNode(
[
() =>
this.processAssembledNode(
[
tokens[0],
tokens[1],
() =>
this.processAssembledNode(
[tokens[2]],
new (LiteralExpr as any)()
),
tokens[3],
],
new (AssignmentNode as any)()
),
() =>
this.processAssembledNode(
[
tokens[4],
tokens[5],
() =>
this.processAssembledNode(
[tokens[6]],
new (LiteralExpr as any)()
),
tokens[7],
],
new (AssignmentNode as any)()
),
],
new (ScadFile as any)()
);
}
}
const p = new TstClass(new CodeLocation(f, 0));
expect(p.testFunc1()).toBeInstanceOf(AssignmentNode);
p.pinpointLocation = new CodeLocation(f, 200);
expect(p.testFunc1()).toEqual(BinAfter);
p.pinpointLocation = new CodeLocation(f, 1);
expect(p.testFunc1()).toBeInstanceOf(AssignmentNode);
p.pinpointLocation = new CodeLocation(f, 2);
expect(p.testFunc1()).toBeInstanceOf(LiteralExpr);
p.pinpointLocation = new CodeLocation(f, 3);
expect(p.testFunc1()).toBeInstanceOf(AssignmentNode);
});
it("pinpoints nodes in a simple assignment expression", () => {
const f = new CodeFile("<test>", "a=5;b=a;");
// 12345678
const [ast, ec] = ParsingHelper.parseFile(f);
ec.throwIfAny();
if(!ast) {
throw new Error("ast is null");
}
const ap = new ASTPinpointer(new CodeLocation(f, 1));
let theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(AssignmentNode);
ap.pinpointLocation = new CodeLocation(f, 2);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(LiteralExpr);
ap.pinpointLocation = new CodeLocation(f, 3);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(AssignmentNode);
ap.pinpointLocation = new CodeLocation(f, 4);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(AssignmentNode);
ap.pinpointLocation = new CodeLocation(f, 5);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(AssignmentNode);
ap.pinpointLocation = new CodeLocation(f, 6);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(LookupExpr);
ap.pinpointLocation = new CodeLocation(f, 7);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(AssignmentNode);
});
it("populates bottomUpHierarchy", () => {
const f = new CodeFile("<test>", "x=(10);");
const [ast, ec] = ParsingHelper.parseFile(f);
ec.throwIfAny();
if(!ast) {
throw new Error("ast is null");
}
const ap = new ASTPinpointer(new CodeLocation(f, 4));
let theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(LiteralExpr);
expect(ap.bottomUpHierarchy[0]).toBeInstanceOf(LiteralExpr);
expect(ap.bottomUpHierarchy[1]).toBeInstanceOf(GroupingExpr);
expect(ap.bottomUpHierarchy[2]).toBeInstanceOf(AssignmentNode);
expect(ap.bottomUpHierarchy[3]).toBeInstanceOf(ScadFile);
});
it("does not throw when pinpointing in a code file with a module instantation", () => {
const f = new CodeFile("<test>", "cube([10, 10, 10]);");
const [ast, ec] = ParsingHelper.parseFile(f);
ec.throwIfAny();
if(!ast) {
throw new Error("ast is null");
}
const ap = new ASTPinpointer(new CodeLocation(f, 4));
let theNode = ap.doPinpoint(ast);
});
it("does not throw when pinpointing a module delcaration in a scope populated ast, pinpoints the correct ast nodes", async () => {
const f = await CodeFile.load("./src/testdata/pinpointer_block_test.scad");
const [ast, ec] = ParsingHelper.parseFile(f);
const lexer = new Lexer(f, ec);
const tokens = lexer.scan();
ec.throwIfAny();
if(!ast) {
throw new Error("ast is null");
}
const populator = new ASTScopePopulator(new Scope());
const astWithScopes = ast.accept(populator);
const ap = new ASTPinpointer(new CodeLocation(f, 32));
let theNode; //= ap.doPinpoint(astWithScopes);
ap.pinpointLocation = new CodeLocation(f, 58);
theNode = ap.doPinpoint(ast);
expect(theNode).toBeInstanceOf(BlockStmt);
});
});
fc9b20a43This file is pinned to the selected release. Download the original to open it in your design tool.