Shift Parser
shift-parser is an ECMAScript parser that generates an Abstract Syntax Tree (AST) conforming to the Shift format. Currently at version 8.0.0, the library provides distinct functions for parsing ECMAScript scripts and modules, offering capabilities for static analysis and code transformation. Although its README suggests support for ECMA-262, version 6 (ES2015), the underlying Shift AST Specification, which `shift-parser` implements, states support for ECMAScript 2019. This indicates the parser likely handles features up to ES2019. The package is generally stable, with major versions released periodically rather than on a strict cadence. A key differentiator is its adherence to the machine-readable Shift AST format, which promotes consistency across various JavaScript tooling. It also offers an extended interface for capturing detailed location and comment information using `WeakMap`.
Common errors
-
SyntaxError: Unexpected token 'import'
cause Attempting to parse an ECMAScript module using the `parseScript` function.fixUse `import { parseModule } from 'shift-parser';` or `import { parseModuleWithLocation } from 'shift-parser';` for code containing `import`/`export` statements. -
SyntaxError: Invalid or unexpected token
cause The input string provided to the parser contains invalid ECMAScript syntax.fixReview the input JavaScript code for syntax errors. `shift-parser` performs strict parsing and will throw an error on malformed code. -
TypeError: Cannot read properties of undefined (reading 'get') or 'locations' is undefined
cause Attempting to access `locations.get()` or the `locations` object itself when using `parseScript` or `parseModule` (which do not return location data) instead of their `WithLocation` counterparts, or in an environment without `WeakMap`.fixTo retrieve location and comment information, ensure you are using `parseScriptWithLocation` or `parseModuleWithLocation`. Verify `WeakMap` support in your runtime environment if this error persists.
Warnings
- gotcha The package's README currently states support for ECMA-262 version 6 (ES2015). However, the Shift AST Specification, which shift-parser implements, explicitly supports ECMAScript 2019. Users should be aware that the parser likely handles features up to ES2019 despite the outdated documentation.
- gotcha Incorrectly using `parseScript` for code that contains module-specific syntax (like `import` or `export` declarations) will result in a `SyntaxError`. Conversely, `parseModule` may enforce strict mode or other module-specific behaviors.
- gotcha The `parseScriptWithLocation` and `parseModuleWithLocation` functions return location data via a `WeakMap`. While modern environments generally support `WeakMap`, older or highly constrained environments might not, leading to unexpected behavior if location data is relied upon.
Install
-
npm install shift-parser -
yarn add shift-parser -
pnpm add shift-parser
Imports
- parse
import { parse } from 'shift-parser';import parse from 'shift-parser';
- parseScript, parseModule
const { parseScript, parseModule } = require('shift-parser');import { parseScript, parseModule } from 'shift-parser'; - parseScriptWithLocation, parseModuleWithLocation
const { parseScriptWithLocation } = require('shift-parser'); // CJS style, less common in new projectsimport { parseScriptWithLocation, parseModuleWithLocation } from 'shift-parser';
Quickstart
import { parseModuleWithLocation } from 'shift-parser';
const code = `
// This is a comment
import { add } from './math.js';
function calculate(a, b) {
const result = add(a, b);
return result; // Another comment
}
console.log(calculate(5, 3));
`;
try {
const { tree, locations, comments } = parseModuleWithLocation(code);
console.log('Parsed AST root type:', tree.type);
console.log('Number of top-level statements:', tree.statements.length);
// Accessing a specific node and its location
const functionDeclaration = tree.statements[2]; // Assuming 'function calculate' is the third statement
if (functionDeclaration && locations.has(functionDeclaration)) {
const loc = locations.get(functionDeclaration);
console.log(`'calculate' function starts at line ${loc.start.line}, column ${loc.start.column}`);
}
// Logging comments
console.log('Found comments:', comments.map(c => c.text));
} catch (e) {
if (e instanceof SyntaxError) {
console.error('Parsing failed:', e.message);
} else {
console.error('An unexpected error occurred:', e);
}
}