Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/chevrotain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"build:transpile": "node \"../../node_modules/esbuild/bin/esbuild\" --format=cjs --target=es2022 --bundle --log-level=error --outfile=dist/cjs/lib/index.js lib/index.ts"
},
"dependencies": {
"chevrotain": "^11.0.3"
"chevrotain": "^12.0.0"
},
"devDependencies": {
"esbuild": "^0.27.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/core/lib/lexer-builder/LexerBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class LexerBuilder<NAMES extends string = string> {

public addAfter<Name extends string>(
after: NamedToken<NAMES>,
...token: CheckOverlap<Name, NAMES, never, NamedToken<Name>[]>
...token: CheckOverlap<Name, NAMES, NamedToken<Name>[]>
): LexerBuilder<NAMES | Name> {
const index = this.tokens.indexOf(after);
if (index === -1) {
Expand Down
129 changes: 129 additions & 0 deletions packages/core/test/AstCoreFactory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { describe, it } from 'vitest';
import { AstCoreFactory } from '../lib/AstCoreFactory.js';

describe('astCoreFactory', () => {
describe('source location management', () => {
it('gen() creates autoGenerate location', ({ expect }) => {
const factory = new AstCoreFactory();
const loc = factory.gen();
expect(loc.sourceLocationType).toBe('autoGenerate');
});

it('sourceLocation creates source location when tracking enabled', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const loc = factory.sourceLocationSource(10, 20);
expect(factory.isSourceLocationSource(loc)).toBe(true);
expect(loc).toMatchObject({ start: 10, end: 20 });
});

it('sourceLocationStringReplace creates stringReplace location', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const loc = factory.sourceLocationStringReplace('new content', 5, 15);
expect(factory.isSourceLocationStringReplace(loc)).toBe(true);
if (factory.isSourceLocationStringReplace(loc)) {
expect(loc.newSource).toBe('new content');
expect(loc.start).toBe(5);
expect(loc.end).toBe(15);
}
});

it('sourceLocationStringReplace returns gen() when tracking disabled', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: false });
const loc = factory.sourceLocationStringReplace('new content', 5, 15);
expect(factory.isSourceLocationNodeAutoGenerate(loc)).toBe(true);
});

it('sourceLocationNodeReplace with number arguments', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const loc = factory.sourceLocationNodeReplace(0, 10);
expect(factory.isSourceLocationNodeReplace(loc)).toBe(true);
expect(loc.start).toBe(0);
expect(loc.end).toBe(10);
});

it('sourceLocationNodeReplace with SourceLocationSource argument', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const sourceLoc = factory.sourceLocationSource(5, 25);
if (factory.isSourceLocationSource(sourceLoc)) {
const loc = factory.sourceLocationNodeReplace(sourceLoc);
expect(factory.isSourceLocationNodeReplace(loc)).toBe(true);
}
});

it('sourceLocationNodeReplaceUnsafe handles SourceLocationSource', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const sourceLoc = factory.sourceLocationSource(0, 10);
if (factory.isSourceLocationSource(sourceLoc)) {
const loc = factory.sourceLocationNodeReplaceUnsafe(sourceLoc);
expect(factory.isSourceLocationNodeReplace(loc)).toBe(true);
}
});

it('sourceLocationNodeReplaceUnsafe throws for unsupported types', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const genLoc = factory.gen();
expect(() => factory.sourceLocationNodeReplaceUnsafe(genLoc))
.toThrowError('Cannot convert SourceLocation');
});

it('sourceLocationInlinedSource creates inlined source location', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const innerLoc = factory.sourceLocationSource(0, 10);
// SourceLocationInlinedSource(newSource, subLoc, start, end, startOnNew?, endOnNew?)
const loc = factory.sourceLocationInlinedSource('inline source', innerLoc, 5, 15);
expect(factory.isSourceLocationInlinedSource(loc)).toBe(true);
});

it('sourceLocationNoMaterialize creates noMaterialize location', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });
const loc = factory.sourceLocationNoMaterialize();
expect(factory.isSourceLocationNoMaterialize(loc)).toBe(true);
});
});

describe('type checking', () => {
it('isLocalized checks for loc property', ({ expect }) => {
const factory = new AstCoreFactory();
expect(factory.isLocalized({ loc: factory.gen() })).toBe(true);
expect(factory.isLocalized({})).toBe(false);
expect(factory.isLocalized({ loc: 'not a location' })).toBe(false);
});

it('isOfType checks type property', ({ expect }) => {
const factory = new AstCoreFactory();
expect(factory.isOfType({ type: 'test' }, 'test')).toBe(true);
expect(factory.isOfType({ type: 'other' }, 'test')).toBe(false);
expect(factory.isOfType({}, 'test')).toBe(false);
});

it('isOfSubType checks type and subType properties', ({ expect }) => {
const factory = new AstCoreFactory();
expect(factory.isOfSubType({ type: 'a', subType: 'b' }, 'a', 'b')).toBe(true);
expect(factory.isOfSubType({ type: 'a', subType: 'c' }, 'a', 'b')).toBe(false);
expect(factory.isOfSubType({ type: 'x', subType: 'b' }, 'a', 'b')).toBe(false);
});
});

describe('location types', () => {
it('identifies all location types correctly', ({ expect }) => {
const factory = new AstCoreFactory({ tracksSourceLocation: true });

const genLoc = factory.gen();
expect(factory.isSourceLocationNodeAutoGenerate(genLoc)).toBe(true);
expect(factory.isSourceLocationSource(genLoc)).toBe(false);

const sourceLoc = factory.sourceLocationSource(0, 10);
expect(factory.isSourceLocationSource(sourceLoc)).toBe(true);
expect(factory.isSourceLocationNodeAutoGenerate(sourceLoc)).toBe(false);

const noMatLoc = factory.sourceLocationNoMaterialize();
expect(factory.isSourceLocationNoMaterialize(noMatLoc)).toBe(true);

const strReplaceLoc = factory.sourceLocationStringReplace('x', 0, 1);
expect(factory.isSourceLocationStringReplace(strReplaceLoc)).toBe(true);

const nodeReplaceLoc = factory.sourceLocationNodeReplace(0, 5);
expect(factory.isSourceLocationNodeReplace(nodeReplaceLoc)).toBe(true);
});
});
});
Loading
Loading