Skip to content

Commit

Permalink
Only parse JS code for imports if we are generating es-format JS.
Browse files Browse the repository at this point in the history
  • Loading branch information
hildjj committed Dec 26, 2023
1 parent dd1ee2b commit 4ef31a8
Show file tree
Hide file tree
Showing 16 changed files with 4,338 additions and 916 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
ignorePatterns: [
"docs/",
"lib/parser.js", // Generated
"lib/compiler/passes/js-imports.js", // Generated
"examples/*.js", // Testing examples
"test/vendor/",
"test/cli/fixtures/bad.js", // Intentionally-invalid
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.

2 changes: 0 additions & 2 deletions lib/compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const generateJS = require("./passes/generate-js");
const inferenceMatchResult = require("./passes/inference-match-result");
const removeProxyRules = require("./passes/remove-proxy-rules");
const mergeCharacterClasses = require("./passes/merge-character-classes");
const moveImports = require("./passes/move-imports");
const reportDuplicateLabels = require("./passes/report-duplicate-labels");
const reportDuplicateRules = require("./passes/report-duplicate-rules");
const reportInfiniteRecursion = require("./passes/report-infinite-recursion");
Expand Down Expand Up @@ -62,7 +61,6 @@ const compiler = {
removeProxyRules,
mergeCharacterClasses,
inferenceMatchResult,
moveImports,
],
generate: [
generateBytecode,
Expand Down
25 changes: 21 additions & 4 deletions lib/compiler/passes/generate-js.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const VERSION = require("../../version");
const { stringEscape, regexpClassEscape } = require("../utils");
const { SourceNode } = require("source-map-generator");
const GrammarLocation = require("../../grammar-location");
const { parse: parseImport } = require("./js-imports.js");

/**
* @typedef {import("../../peg")} PEG
Expand Down Expand Up @@ -848,14 +849,30 @@ function generateJS(ast, options) {
function generateToplevel() {
const parts = [];

if (ast.topLevelInitializer) {
if (Array.isArray(ast.topLevelInitializer)) {
for (const tli of ast.topLevelInitializer) {
let topLevel = ast.topLevelInitializer;
if (topLevel) {
if (Array.isArray(topLevel)) {
if (options.format === "es") {
const imps = [];
const codes = [];
for (const tli of topLevel) {
const [imports, code] = parseImport(tli.code);
if (imports.code) {
imps.push(imports);
codes.push(code);
} else {
// Prefer the original
codes.push(tli);
}
}
topLevel = imps.concat(codes);
}
for (const tli of topLevel) {
parts.push(ast2SourceNode(tli));
parts.push("");
}
} else {
parts.push(ast2SourceNode(ast.topLevelInitializer));
parts.push(ast2SourceNode(topLevel));
parts.push("");
}
}
Expand Down
3,905 changes: 3,905 additions & 0 deletions lib/compiler/passes/js-imports.js

Large diffs are not rendered by default.

21 changes: 0 additions & 21 deletions lib/compiler/passes/move-imports.js

This file was deleted.

1,173 changes: 347 additions & 826 deletions lib/parser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"scripts": {
"clean": "rimraf build browser bin/*.map && mkdir browser",
"parser": "node bin/peggy.js -o lib/parser.js --format commonjs src/parser.pegjs",
"parser": "node bin/peggy.js -o lib/parser.js --format commonjs src/parser.pegjs && node bin/peggy.js -o lib/compiler/passes/js-imports.js --format commonjs src/js-imports.peggy src/parser.pegjs",
"examples": "node bin/peggy.js -c docs/js/options.js docs/js/examples.peggy",
"set_version": "node ./tools/set_version",
"lint": "eslint . --ext js,ts,mjs",
Expand Down
48 changes: 48 additions & 0 deletions src/js-imports.peggy
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
JSSource = imports:ImportDeclarations code:BareCodeBlock {
return [imports, {
type: "top_level_initializer",
code: code[0],
codeLocation: code[1],
}];
}

ImportDeclarations
= code:$ImportDeclaration* {
return {
type: "top_level_initializer",
code,
codeLocation: location()
};
}

ImportDeclaration
= __ "import" __ ImportClause __ FromClause __ ";"?
/ __ "import" __ ModuleSpecifier __ ";"?

ImportClause
= ImportedDefaultBinding
/ NameSpaceImport
/ NamedImports
/ ImportedDefaultBinding __ "," __ (NameSpaceImport / NamedImports)

ImportedDefaultBinding = ImportedBinding
NameSpaceImport = "*" __ "as" __ ImportedBinding
NamedImports
= "{" __ "}"
/ "{" __ ImportsList __ ","? __ "}"
FromClause = "from" __ ModuleSpecifier
ImportsList = ImportSpecifier|1.., __ "," __|
ImportSpecifier
= ModuleExportName __ "as" __ ImportedBinding
/ ImportedBinding
ModuleSpecifier = StringLiteral
ImportedBinding
= BindingIdentifier

ModuleExportName
= IdentifierName
/ StringLiteral

BindingIdentifier = id:IdentifierName &{
return reservedWords.indexOf(id[0]) === -1
}
56 changes: 3 additions & 53 deletions src/parser.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,64 +57,14 @@ Grammar
}

TopLevelInitializer
= "{" "{" imports:ImportDeclarations code:BareCodeBlock "}" "}" EOS {
const ret = {
= "{" code:CodeBlock "}" EOS {
return {
type: "top_level_initializer",
code: code[0],
codeLocation: code[1],
imports: false,
location: location()
};
}
if (imports[0]) {
return [
{
type: "top_level_initializer",
code: imports[0],
codeLocation: imports[1],
imports: true,
location: location()
},
ret
];
}
return ret;
}

ImportDeclarations
= imports:$ImportDeclaration* {
return [imports, location()]
}
ImportDeclaration
= __ "import" __ ImportClause __ FromClause __ ";"?
/ __ "import" __ ModuleSpecifier __ ";"?

ImportClause
= ImportedDefaultBinding
/ NameSpaceImport
/ NamedImports
/ ImportedDefaultBinding __ "," __ (NameSpaceImport / NamedImports)

ImportedDefaultBinding = ImportedBinding
NameSpaceImport = "*" __ "as" __ ImportedBinding
NamedImports
= "{" __ "}"
/ "{" __ ImportsList __ ","? __ "}"
FromClause = "from" __ ModuleSpecifier
ImportsList = ImportSpecifier|1.., __ "," __|
ImportSpecifier
= ModuleExportName __ "as" __ ImportedBinding
/ ImportedBinding
ModuleSpecifier = StringLiteral
ImportedBinding
= BindingIdentifier

ModuleExportName
= IdentifierName
/ StringLiteral

BindingIdentifier = id:IdentifierName &{
return reservedWords.indexOf(id[0]) === -1
}

Initializer
= code:CodeBlock EOS {
Expand Down
4 changes: 4 additions & 0 deletions test/cli/fixtures/useFrags/identifier.peggy
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
{{
// Useless TLI with NO import
const G = "global";
}}
id = IdentifierName
2 changes: 1 addition & 1 deletion test/cli/fixtures/useFrags/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"private": "true",
"scripts": {
"build": "../../../../bin/peggy.js identifier.peggy npm:frags/unicode.peggy && ../../../../bin/peggy.js fs.peggy npm:frags/path.peggy"
"build": "../../../../bin/peggy.js --format es identifier.peggy npm:frags/unicode.peggy && ../../../../bin/peggy.js --format es fs.peggy npm:frags/path.peggy"
},
"author": "Joe Hildebrand <joe-github@cursive.net>",
"license": "MIT",
Expand Down
6 changes: 3 additions & 3 deletions test/cli/run.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ Options:
let input1 = path.join(__dirname, "fixtures", "useFrags", "identifier.peggy");
let out = path.join(__dirname, "fixtures", "useFrags", "identifier.js");
await expect(exec({
args: [input1, "npm:frags/unicode.peggy"],
args: ["--format", "es", input1, "npm:frags/unicode.peggy"],
exitCode: 0,
})).resolves.toBe("");

Expand All @@ -865,15 +865,15 @@ Options:
input1 = path.join(__dirname, "fixtures", "useFrags", "fs.peggy");
out = path.join(__dirname, "fixtures", "useFrags", "fs.js");
await expect(exec({
args: [input1, "npm:frags/path.peggy"],
args: ["--format", "es", input1, "npm:frags/path.peggy"],
exitCode: 0,
})).resolves.toBe("");

fs.unlinkSync(out);

out = path.join(__dirname, "..", "..", "path.js");
await expect(exec({
args: ["npm:frags/path.peggy"],
args: ["--format", "es", "npm:frags/path.peggy"],

exitCode: 0,
})).resolves.toBe("");
Expand Down
3 changes: 1 addition & 2 deletions test/unit/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("Peggy grammar parser", () => {
const ruleB = { type: "rule", name: "b", expression: literalEfgh };
const ruleC = { type: "rule", name: "c", expression: literalIjkl };
const ruleStart = { type: "rule", name: "start", expression: literalAbcd };
const topLevelInitializer = { type: "top_level_initializer", code: " top level code ", imports: false };
const topLevelInitializer = { type: "top_level_initializer", code: " top level code " };
const initializer = { type: "initializer", code: " code " };

function oneRuleGrammar(expression) {
Expand Down Expand Up @@ -1136,7 +1136,6 @@ c = @'ijkl'
topLevelInitializer: {
type: "top_level_initializer",
code: "\n const foo = 12;\n",
imports: false,
codeLocation: {
source: undefined,
start: { offset: 3, line: 2, column: 3 },
Expand Down

0 comments on commit 4ef31a8

Please sign in to comment.