Skip to content

Commit

Permalink
Merge pull request peggyjs#451 from markw65/jsdoc-stack
Browse files Browse the repository at this point in the history
Make stack.js ts clean
  • Loading branch information
hildjj authored Dec 9, 2023
2 parents f2c271f + a873e7d commit 076916c
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Released: TBD

### Minor Changes

- [#451](https://github.com/peggyjs/peggy/pull/451) Make stack.js ts clean
- [#439](https://github.com/peggyjs/peggy/pull/439) Make peg$computePosDetails a little faster
- [#437](https://github.com/peggyjs/peggy/pull/437) Better type checking for visitor
- [#435](https://github.com/peggyjs/peggy/pull/435) Setup tsconfig to detect use of library functions from es6 or later
Expand Down
2 changes: 1 addition & 1 deletion docs/js/benchmark-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/js/test-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/vendor/peggy/peggy.min.js

Large diffs are not rendered by default.

40 changes: 37 additions & 3 deletions lib/compiler/stack.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
// @ts-check
"use strict";

const { SourceNode } = require("source-map-generator");
const GrammarLocation = require("../grammar-location.js");

/**
* @typedef {(string|SourceNode)[]} SourceArray
*/

/** Utility class that helps generating code for C-like languages. */
class Stack {
/**
Expand All @@ -27,7 +32,10 @@ class Stack {
* @type {Record<number,{label:string,location:import("../peg.js").LocationRange}>}
*/
this.labels = {};
/* Stack of in-flight source mappings */
/**
* Stack of in-flight source mappings
* @type {[SourceArray, number, PEG.LocationRange][]}
*/
this.sourceMapStack = [];
}

Expand All @@ -49,6 +57,13 @@ class Stack {
return this.varName + i;
}

/**
*
* @param {PEG.LocationRange} location
* @param {SourceArray} chunks
* @param {string} [name]
* @returns
*/
static sourceNode(location, chunks, name) {
const start = GrammarLocation.offsetStart(location);
return new SourceNode(
Expand Down Expand Up @@ -150,7 +165,7 @@ class Stack {
/**
* Returns name of the variable at index `i`.
*
* @param {number} [i] Index of the variable from top of the stack
* @param {number} i Index of the variable from top of the stack
* @return {string} Generated name
*
* @throws {RangeError} If `i < 0` or more than the stack size
Expand Down Expand Up @@ -258,6 +273,11 @@ class Stack {
return result;
}

/**
*
* @param {SourceArray} parts
* @param {PEG.LocationRange} location
*/
sourceMapPush(parts, location) {
if (this.sourceMapStack.length) {
const top = this.sourceMapStack[this.sourceMapStack.length - 1];
Expand All @@ -281,12 +301,21 @@ class Stack {
]);
}

/**
* @returns {{parts:SourceArray,location:PEG.LocationRange}}
*/
sourceMapPopInternal() {
const elt = this.sourceMapStack.pop();
if (!elt) {
throw new RangeError(
`Rule '${this.ruleName}': Attempting to pop an empty source map stack.\nBytecode: ${this.bytecode}`
);
}
const [
parts,
index,
location,
] = this.sourceMapStack.pop();
] = elt;
const chunks = parts.splice(index).map(
chunk => (chunk instanceof SourceNode
? chunk
Expand All @@ -305,6 +334,10 @@ class Stack {
return { parts, location };
}

/**
* @param {number} [offset]
* @returns {[SourceArray, number, PEG.LocationRange]|undefined}
*/
sourceMapPop(offset) {
const { location } = this.sourceMapPopInternal();
if (this.sourceMapStack.length
Expand All @@ -325,6 +358,7 @@ class Stack {
newLoc,
]);
}
return undefined;
}
}

Expand Down
17 changes: 17 additions & 0 deletions test/unit/compiler/stack.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ describe("utility class Stack", () => {
"Rule 'rule': The variable stack underflow: attempt to use a variable 'v<x>' at an index -3.\nBytecode: 42"
);
});

it("`sourceMapPop`", () => {
expect(() => stack.sourceMapPop()).to.throw(
RangeError,
"Rule 'rule': Attempting to pop an empty source map stack.\nBytecode: 42"
);
});
});

it("`defines` returns an empty string", () => {
Expand Down Expand Up @@ -268,4 +275,14 @@ describe("utility class Stack", () => {
);
});
});

describe("SourceNode handling", () => {
it("sourceNode handles unknown column", () => {
expect(Stack.sourceNode({
source: "",
start: { line:1, column:0, offset:0 },
end: { line:1, column:0, offset:0 },
}, ["foo"], "test").column).to.equal(null);
});
});
});

0 comments on commit 076916c

Please sign in to comment.