Пример
esprima 4.0.1: parse ECMAScript code and extract AST with tokens, comments, and location info
Проверенный пример — npm esprima 4.0.1: parse ECMAScript code and extract AST with tokens, comments, and location info. Контракт выполнен на node 22 · linux…
sha256:c8bceaf2698705f4837a0141fa98b53852a271866de01a6b2e81d63f7dcf75e5
Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла.
Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди.
MIT-0
Свидетельства выполнения
Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.
- Основа свидетельства
- Подписанный контракт пройден
- Квитанции проверки
- 2
- Ключи подписи, собравшие его
- 1
Заявленная среда
linux 24 · ubuntu · glibc 2.39 x64 npm
Среды запусков проверки
| Окружение | Контракт | Этапы | Запуск |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-08-23 |
| node 22 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22@sha256:8a34c4ab3ea2… |
2026-09-07 |
Кейс
HOW- Цель
- parse ECMAScript code and extract AST with tokens, comments, and location info
- Пакеты
- Символы
-
- esprima.parseModule
- esprima.parseScript
- esprima.tokenize
- Создан
- 2026-08-23T15:39:36Z
Контракт
- esprima.parseScript parses ECMAScript code into an Abstract Syntax Tree (AST) with Program root and script sourceType
- esprima.parseScript with loc and range options attaches line/column location coordinates and index range spans to AST nodes
- esprima.parseScript with tokens and comment options collects lexical tokens and comments on the returned AST
- esprima.parseModule parses ECMAScript modules with top-level import and export declarations
- esprima.tokenize breaks source code into a sequence of lexical tokens with token types and values
- esprima.parseScript throws a SyntaxError on invalid JavaScript syntax
Файлы
- PROMPT.md
- csx.json
- package-lock.json
- package.json
- spec.json
- src/index.js
- test/contract.mjs
Исходный код
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: parse ECMAScript code and extract AST with tokens, comments, and location info
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/esprima@4.0.1
Demonstrate these symbols/APIs:
- esprima.parseModule
- esprima.parseScript
- esprima.tokenize
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:796626a9a00caad97e313ce6eb3c12bd554328a6a4c4ea60a65140714f5ad027","contract":["esprima.parseScript parses ECMAScript code into an Abstract Syntax Tree (AST) with Program root and script sourceType","esprima.parseScript with loc and range options attaches line/column location coordinates and index range spans to AST nodes","esprima.parseScript with tokens and comment options collects lexical tokens and comments on the returned AST","esprima.parseModule parses ECMAScript modules with top-level import and export declarations","esprima.tokenize breaks source code into a sequence of lexical tokens with token types and values","esprima.parseScript throws a SyntaxError on invalid JavaScript syntax"],"goal":"parse ECMAScript code and extract AST with tokens, comments, and location info","kind":"HOW","packages":["pkg:npm/esprima@4.0.1"],"schemaVersion":1,"symbols":["esprima.parseModule","esprima.parseScript","esprima.tokenize"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/esprima@4.0.1"],"schemaVersion":1,"subject":"pkg:npm/esprima@4.0.1","symbols":["esprima.parseModule","esprima.parseScript","esprima.tokenize"],"verifierAdapter":"node-typescript@1"}
{
"name": "sample-esprima-parse",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-esprima-parse",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"esprima": "4.0.1"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
}
}
}
{
"name": "sample-esprima-parse",
"version": "1.0.0",
"private": true,
"description": "Clean-room code sample for esprima AST parsing, tokenization, and comment extraction",
"main": "src/index.js",
"license": "MIT-0",
"dependencies": {
"esprima": "4.0.1"
}
}
{
"schemaVersion": 1,
"goal": "parse ECMAScript code and extract AST with tokens, comments, and location info",
"kind": "HOW",
"packages": [
"pkg:npm/esprima@4.0.1"
],
"symbols": [
"esprima.parseModule",
"esprima.parseScript",
"esprima.tokenize"
]
}
const esprima = require('esprima');
/**
* Parse standard ECMAScript code as a script.
*
* @param {string} code - Source code string to parse.
* @param {object} [options={}] - Parser options (loc, range, tokens, comment, tolerant).
* @returns {object} Program AST root node.
*/
function parseScriptCode(code, options = {}) {
return esprima.parseScript(code, options);
}
/**
* Parse ECMAScript module code (supporting import/export declarations).
*
* @param {string} code - Source code string to parse.
* @param {object} [options={}] - Parser options (loc, range, tokens, comment, tolerant).
* @returns {object} Program AST root node with sourceType 'module'.
*/
function parseModuleCode(code, options = {}) {
return esprima.parseModule(code, options);
}
/**
* Tokenize ECMAScript source code into lexical tokens.
*
* @param {string} code - Source code string to tokenize.
* @param {object} [options={}] - Tokenizer options (loc, range, comment).
* @returns {Array<object>} Array of token objects.
*/
function tokenizeCode(code, options = {}) {
return esprima.tokenize(code, options);
}
module.exports = {
esprima,
parseScriptCode,
parseModuleCode,
tokenizeCode
};
import assert from 'node:assert/strict';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const {
esprima,
parseScriptCode,
parseModuleCode,
tokenizeCode
} = require('../src/index.js');
async function runTests() {
// 1. esprima.parseScript parses ECMAScript code into an Abstract Syntax Tree (AST) with Program root and script sourceType
const simpleCode = 'const answer = 42;';
const scriptAst = parseScriptCode(simpleCode);
assert.equal(typeof esprima.parseScript, 'function', 'esprima.parseScript must be a function');
assert.equal(scriptAst.type, 'Program', 'Root node type must be Program');
assert.equal(scriptAst.sourceType, 'script', 'sourceType must be script');
assert.equal(scriptAst.body.length, 1, 'Body should contain 1 statement');
assert.equal(scriptAst.body[0].type, 'VariableDeclaration', 'First statement is VariableDeclaration');
assert.equal(scriptAst.body[0].kind, 'const', 'Declaration kind is const');
assert.equal(scriptAst.body[0].declarations[0].id.name, 'answer', 'Identifier name is answer');
assert.equal(scriptAst.body[0].declarations[0].init.value, 42, 'Literal value is 42');
// 2. esprima.parseScript with loc and range options attaches line/column location coordinates and index range spans to AST nodes
const locCode = 'let total = 100;\ntotal += 5;';
const locAst = parseScriptCode(locCode, { loc: true, range: true });
assert.ok(locAst.loc, 'Program should have loc property');
assert.equal(locAst.loc.start.line, 1, 'Start line should be 1');
assert.equal(locAst.loc.start.column, 0, 'Start column should be 0');
assert.equal(locAst.loc.end.line, 2, 'End line should be 2');
assert.ok(Array.isArray(locAst.range), 'Program range should be an array');
assert.equal(locAst.range[0], 0, 'Range start index is 0');
assert.equal(locAst.range[1], locCode.length, 'Range end index matches code length');
const firstStmt = locAst.body[0];
assert.equal(firstStmt.loc.start.line, 1, 'First statement start line is 1');
assert.equal(firstStmt.range[0], 0, 'First statement range start is 0');
const secondStmt = locAst.body[1];
assert.equal(secondStmt.loc.start.line, 2, 'Second statement start line is 2');
// 3. esprima.parseScript with tokens and comment options collects lexical tokens and comments on the returned AST
const commentedCode = '// Leading comment\nconst name = "Alice"; /* Block comment */';
const richAst = parseScriptCode(commentedCode, { tokens: true, comment: true, loc: true });
assert.ok(Array.isArray(richAst.tokens), 'AST must contain tokens array');
assert.ok(richAst.tokens.length > 0, 'Tokens array must not be empty');
assert.equal(richAst.tokens[0].type, 'Keyword', 'First token type is Keyword');
assert.equal(richAst.tokens[0].value, 'const', 'First token value is const');
assert.equal(richAst.tokens[1].type, 'Identifier', 'Second token type is Identifier');
assert.equal(richAst.tokens[1].value, 'name', 'Second token value is name');
assert.ok(Array.isArray(richAst.comments), 'AST must contain comments array');
assert.equal(richAst.comments.length, 2, 'Should have captured 2 comments');
assert.equal(richAst.comments[0].type, 'Line', 'First comment type is Line');
assert.equal(richAst.comments[0].value.trim(), 'Leading comment', 'First comment text matches');
assert.equal(richAst.comments[1].type, 'Block', 'Second comment type is Block');
assert.equal(richAst.comments[1].value.trim(), 'Block comment', 'Second comment text matches');
// 4. esprima.parseModule parses ECMAScript modules with top-level import and export declarations
const moduleCode = 'import { calculateSum } from "./math.js";\nexport const result = calculateSum(1, 2);';
assert.equal(typeof esprima.parseModule, 'function', 'esprima.parseModule must be a function');
const moduleAst = parseModuleCode(moduleCode);
assert.equal(moduleAst.type, 'Program', 'Module AST root must be Program');
assert.equal(moduleAst.sourceType, 'module', 'sourceType must be module');
assert.equal(moduleAst.body.length, 2, 'Module has 2 top-level declarations');
assert.equal(moduleAst.body[0].type, 'ImportDeclaration', 'First statement is ImportDeclaration');
assert.equal(moduleAst.body[0].source.value, './math.js', 'Import specifier matches');
assert.equal(moduleAst.body[1].type, 'ExportNamedDeclaration', 'Second statement is ExportNamedDeclaration');
// 5. esprima.tokenize breaks source code into a sequence of lexical tokens with token types and values
const tokenCode = 'function add(x, y) { return x + y; }';
assert.equal(typeof esprima.tokenize, 'function', 'esprima.tokenize must be a function');
const tokens = tokenizeCode(tokenCode, { range: true });
assert.ok(Array.isArray(tokens), 'tokenize must return an array');
assert.ok(tokens.length >= 10, 'Expected multiple tokens');
assert.equal(tokens[0].type, 'Keyword', 'Token 0 type is Keyword');
assert.equal(tokens[0].value, 'function', 'Token 0 value is function');
assert.equal(tokens[1].type, 'Identifier', 'Token 1 type is Identifier');
assert.equal(tokens[1].value, 'add', 'Token 1 value is add');
assert.equal(tokens[2].type, 'Punctuator', 'Token 2 type is Punctuator');
assert.equal(tokens[2].value, '(', 'Token 2 value is (');
assert.ok(Array.isArray(tokens[0].range), 'Token range should be present');
// 6. esprima.parseScript throws a SyntaxError on invalid JavaScript syntax
const invalidCode = 'const = 123;';
assert.throws(
() => {
parseScriptCode(invalidCode);
},
(err) => {
assert.ok(err instanceof Error, 'Error should be instance of Error');
assert.ok(err.name === 'Error' || err.name === 'SyntaxError', 'Error name should be Error or SyntaxError');
assert.ok(err.message.includes('Unexpected') || err.lineNumber !== undefined, 'Error message/location present');
return true;
},
'parseScript on invalid syntax must throw an error'
);
console.log('All contract assertions for esprima passed successfully.');
}
runTests().catch((err) => {
console.error('Contract test failed:', err);
process.exit(1);
});
Исходный сидер
аноним