@exercode/problem-utils 4.3.3 → 4.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/checkAllProblems.cjs +1 -1
- package/dist/cli/checkAllProblems.cjs.map +1 -1
- package/dist/cli/checkAllProblems.js +1 -1
- package/dist/cli/checkAllProblems.js.map +1 -1
- package/dist/cli/exercodeProblem.cjs +1 -1
- package/dist/cli/exercodeProblem.cjs.map +1 -1
- package/dist/cli/exercodeProblem.js +1 -1
- package/dist/cli/exercodeProblem.js.map +1 -1
- package/dist/helpers/checkProblemDirIsolation.cjs.map +1 -1
- package/dist/helpers/checkProblemDirIsolation.js.map +1 -1
- package/dist/helpers/compareExpectedOutputFiles.cjs.map +1 -1
- package/dist/helpers/compareExpectedOutputFiles.js.map +1 -1
- package/dist/helpers/findModelAnswerDirs.cjs.map +1 -1
- package/dist/helpers/findModelAnswerDirs.js.map +1 -1
- package/dist/helpers/javaJudge.cjs +1 -1
- package/dist/helpers/javaJudge.cjs.map +1 -1
- package/dist/helpers/javaJudge.js +1 -1
- package/dist/helpers/javaJudge.js.map +1 -1
- package/dist/helpers/judgeByStaticAnalysis.cjs.map +1 -1
- package/dist/helpers/judgeByStaticAnalysis.js.map +1 -1
- package/dist/helpers/parseCsv.cjs +2 -2
- package/dist/helpers/parseCsv.cjs.map +1 -1
- package/dist/helpers/parseCsv.js +2 -2
- package/dist/helpers/parseCsv.js.map +1 -1
- package/dist/helpers/readOutputFiles.cjs.map +1 -1
- package/dist/helpers/readOutputFiles.js.map +1 -1
- package/dist/helpers/removeCommentsInSourceCode.cjs +4 -4
- package/dist/helpers/removeCommentsInSourceCode.cjs.map +1 -1
- package/dist/helpers/removeCommentsInSourceCode.js +4 -4
- package/dist/helpers/removeCommentsInSourceCode.js.map +1 -1
- package/dist/helpers/resolveCwds.cjs +1 -1
- package/dist/helpers/resolveCwds.cjs.map +1 -1
- package/dist/helpers/resolveCwds.js +1 -1
- package/dist/helpers/resolveCwds.js.map +1 -1
- package/dist/helpers/runCommandInTemporaryPackageManagerProject.cjs.map +1 -1
- package/dist/helpers/runCommandInTemporaryPackageManagerProject.js.map +1 -1
- package/dist/helpers/runHarnessProcess.cjs +1 -1
- package/dist/helpers/runHarnessProcess.cjs.map +1 -1
- package/dist/helpers/runHarnessProcess.js +1 -1
- package/dist/helpers/runHarnessProcess.js.map +1 -1
- package/dist/helpers/sourceCodeGrammars.cjs.map +1 -1
- package/dist/helpers/sourceCodeGrammars.js.map +1 -1
- package/dist/helpers/spawnWithLimits.cjs +1 -1
- package/dist/helpers/spawnWithLimits.cjs.map +1 -1
- package/dist/helpers/spawnWithLimits.js +1 -1
- package/dist/helpers/spawnWithLimits.js.map +1 -1
- package/dist/helpers/startHttpServer.cjs +1 -1
- package/dist/helpers/startHttpServer.cjs.map +1 -1
- package/dist/helpers/startHttpServer.js +1 -1
- package/dist/helpers/startHttpServer.js.map +1 -1
- package/dist/learningMaterial/validateContest.cjs.map +1 -1
- package/dist/learningMaterial/validateContest.js.map +1 -1
- package/dist/learningMaterial/validateCourse.cjs +1 -1
- package/dist/learningMaterial/validateCourse.cjs.map +1 -1
- package/dist/learningMaterial/validateCourse.js +1 -1
- package/dist/learningMaterial/validateCourse.js.map +1 -1
- package/dist/learningMaterial/validateMaterial.cjs.map +1 -1
- package/dist/learningMaterial/validateMaterial.js.map +1 -1
- package/dist/learningMaterial/validateProblem.cjs +1 -1
- package/dist/learningMaterial/validateProblem.cjs.map +1 -1
- package/dist/learningMaterial/validateProblem.js +1 -1
- package/dist/learningMaterial/validateProblem.js.map +1 -1
- package/dist/presets/command.cjs +1 -1
- package/dist/presets/command.cjs.map +1 -1
- package/dist/presets/command.js +1 -1
- package/dist/presets/command.js.map +1 -1
- package/dist/presets/evaluation.cjs +1 -1
- package/dist/presets/evaluation.cjs.map +1 -1
- package/dist/presets/evaluation.js +1 -1
- package/dist/presets/evaluation.js.map +1 -1
- package/dist/presets/guiCommand.cjs +1 -1
- package/dist/presets/guiCommand.cjs.map +1 -1
- package/dist/presets/guiCommand.js +1 -1
- package/dist/presets/guiCommand.js.map +1 -1
- package/dist/presets/springBoot.cjs.map +1 -1
- package/dist/presets/springBoot.js.map +1 -1
- package/dist/presets/stdio.cjs.map +1 -1
- package/dist/presets/stdio.js.map +1 -1
- package/dist/presets/tomcat.cjs.map +1 -1
- package/dist/presets/tomcat.js.map +1 -1
- package/package.json +26 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"javaJudge.cjs","names":["fs","path","z","require_runtime","node_fs","node_path","zod","MAX_OUTPUT_LENGTH","resolveJavaRelativePath","sourceCode","sourcePath","packageMatch","fallbackRelativePath","listSubmissionFiles","filePaths","collectSubmissionFiles","rootDir","currentDir","relativeDir","entries","entry","entryRelativePath","readOutputFiles","filePath","parsed","values","outputFileSchema","result","value","truncateOutput"],"sources":["../../src/helpers/javaJudge.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\ntype OutputFile = NonNullable<TestCaseResult['outputFiles']>[number];\nexport const MAX_OUTPUT_LENGTH = 50_000;\n\nexport async function resolveJavaRelativePath(sourcePath: string, fallbackRelativePath: string): Promise<string> {\n const sourceCode = await fs.promises.readFile(sourcePath, 'utf8');\n const packageMatch = /^\\s*package\\s+([a-zA-Z0-9_.]+)\\s*;/m.exec(sourceCode);\n if (!packageMatch?.[1]) {\n return fallbackRelativePath;\n }\n\n return path.join(packageMatch[1].replaceAll('.', '/'), path.basename(fallbackRelativePath));\n}\n\nexport async function listSubmissionFiles(rootDir: string): Promise<string[]> {\n const filePaths: string[] = [];\n await collectSubmissionFiles(rootDir, '', filePaths);\n return filePaths.toSorted();\n}\n\nasync function collectSubmissionFiles(rootDir: string, relativeDir: string, filePaths: string[]): Promise<void> {\n const currentDir = relativeDir ? path.join(rootDir, relativeDir) : rootDir;\n const entries = await fs.promises.readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const entryRelativePath = relativeDir ? path.join(relativeDir, entry.name) : entry.name;\n if (entry.isDirectory()) {\n await collectSubmissionFiles(rootDir, entryRelativePath, filePaths);\n continue;\n }\n if (entry.isFile()) {\n filePaths.push(entryRelativePath);\n }\n }\n}\n\nexport function readOutputFiles(filePath: string): OutputFile[] | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n\n // Malformed evaluator JSON remains a harness error (JUDGE_NOT_AVAILABLE), not missing screenshots.\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n const values = z.array(z.unknown()).safeParse(parsed);\n if (!values.success) return undefined;\n const outputFileSchema = z.object({\n path: z.string(),\n data: z.string(),\n encoding: z.literal('base64').optional(),\n });\n return values.data.flatMap((value) => {\n const result = outputFileSchema.safeParse(value);\n return result.success ? [result.data] : [];\n });\n}\n\nexport function truncateOutput(value: string): string {\n return value.slice(0, MAX_OUTPUT_LENGTH);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"javaJudge.cjs","names":["fs","path","z","require_runtime","node_fs","node_path","zod","MAX_OUTPUT_LENGTH","resolveJavaRelativePath","sourceCode","sourcePath","packageMatch","fallbackRelativePath","listSubmissionFiles","filePaths","collectSubmissionFiles","rootDir","currentDir","relativeDir","entries","entry","entryRelativePath","readOutputFiles","filePath","parsed","values","outputFileSchema","result","value","truncateOutput"],"sources":["../../src/helpers/javaJudge.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { z } from 'zod';\n\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\ntype OutputFile = NonNullable<TestCaseResult['outputFiles']>[number];\nexport const MAX_OUTPUT_LENGTH = 50_000;\n\nexport async function resolveJavaRelativePath(sourcePath: string, fallbackRelativePath: string): Promise<string> {\n const sourceCode = await fs.promises.readFile(sourcePath, 'utf8');\n const packageMatch = /^\\s*package\\s+([a-zA-Z0-9_.]+)\\s*;/m.exec(sourceCode);\n if (!packageMatch?.[1]) {\n return fallbackRelativePath;\n }\n\n return path.join(packageMatch[1].replaceAll('.', '/'), path.basename(fallbackRelativePath));\n}\n\nexport async function listSubmissionFiles(rootDir: string): Promise<string[]> {\n const filePaths: string[] = [];\n await collectSubmissionFiles(rootDir, '', filePaths);\n return filePaths.toSorted();\n}\n\nasync function collectSubmissionFiles(rootDir: string, relativeDir: string, filePaths: string[]): Promise<void> {\n const currentDir = relativeDir ? path.join(rootDir, relativeDir) : rootDir;\n const entries = await fs.promises.readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const entryRelativePath = relativeDir ? path.join(relativeDir, entry.name) : entry.name;\n if (entry.isDirectory()) {\n await collectSubmissionFiles(rootDir, entryRelativePath, filePaths);\n continue;\n }\n if (entry.isFile()) {\n filePaths.push(entryRelativePath);\n }\n }\n}\n\nexport function readOutputFiles(filePath: string): OutputFile[] | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n\n // Malformed evaluator JSON remains a harness error (JUDGE_NOT_AVAILABLE), not missing screenshots.\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n const values = z.array(z.unknown()).safeParse(parsed);\n if (!values.success) return undefined;\n const outputFileSchema = z.object({\n path: z.string(),\n data: z.string(),\n encoding: z.literal('base64').optional(),\n });\n return values.data.flatMap((value) => {\n const result = outputFileSchema.safeParse(value);\n return result.success ? [result.data] : [];\n });\n}\n\nexport function truncateOutput(value: string): string {\n return value.slice(0, MAX_OUTPUT_LENGTH);\n}\n"],"mappings":"6KAQA,MAAaO,EAAoB,IAEjC,eAAsBC,EAAwB,EAAoB,EAA+C,CAC/G,IAAMC,EAAa,MAAMT,EAAAA,QAAG,SAAS,SAASU,EAAY,MAAM,EAC1DC,EAAe,sCAAsC,KAAKF,CAAU,EAK1E,OAJKE,IAAe,GAIbV,EAAAA,QAAK,KAAKU,EAAa,EAAE,CAAC,WAAW,IAAK,GAAG,EAAGV,EAAAA,QAAK,SAASW,CAAoB,CAAC,EAHjFA,CAIX,CAEA,eAAsBC,EAAoB,EAAoC,CAC5E,IAAMC,EAAsB,CAAC,EAE7B,OADA,MAAMC,EAAuBC,EAAS,GAAIF,CAAS,EAC5CA,EAAU,SAAS,CAC5B,CAEA,eAAeC,EAAuB,EAAiB,EAAqB,EAAoC,CAC9G,IAAME,EAAaC,EAAcjB,EAAAA,QAAK,KAAKe,EAASE,CAAW,EAAIF,EAC7DG,EAAU,MAAMnB,EAAAA,QAAG,SAAS,QAAQiB,EAAY,CAAE,cAAe,EAAK,CAAC,EAC7E,IAAK,IAAMG,KAASD,EAAS,CAC3B,IAAME,EAAoBH,EAAcjB,EAAAA,QAAK,KAAKiB,EAAaE,EAAM,IAAI,EAAIA,EAAM,KAC/EA,EAAM,YAAY,EACpB,MAAML,EAAuBC,EAASK,EAAmBP,CAAS,EAGhEM,EAAM,OAAO,GACfN,EAAU,KAAKO,CAAiB,CAEpC,CACF,CAEA,SAAgBC,EAAgB,EAA4C,CAC1E,GAAI,CAACtB,EAAAA,QAAG,WAAWuB,CAAQ,EACzB,OAIF,IAAMC,EAAkB,KAAK,MAAMxB,EAAAA,QAAG,aAAauB,EAAU,MAAM,CAAC,EAC9DE,EAASvB,EAAAA,EAAE,MAAMA,EAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAUsB,CAAM,EACpD,GAAI,CAACC,EAAO,QAAS,OACrB,IAAMC,EAAmBxB,EAAAA,EAAE,OAAO,CAChC,KAAMA,EAAAA,EAAE,OAAO,EACf,KAAMA,EAAAA,EAAE,OAAO,EACf,SAAUA,EAAAA,EAAE,QAAQ,QAAQ,CAAC,CAAC,SAAS,CACzC,CAAC,EACD,OAAOuB,EAAO,KAAK,QAAS,GAAU,CACpC,IAAME,EAASD,EAAiB,UAAUE,CAAK,EAC/C,OAAOD,EAAO,QAAU,CAACA,EAAO,IAAI,EAAI,CAAC,CAC3C,CAAC,CACH,CAEA,SAAgBE,EAAe,EAAuB,CACpD,OAAOD,EAAM,MAAM,EAAGrB,CAAiB,CACzC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"node:fs";import t from"node:path";import{z as n}from"zod";const r=5e4;async function i(n,r){let i=await e.promises.readFile(n,`utf8`),a=/^\s*package\s+([a-zA-Z0-9_.]+)\s*;/m.exec(i);return a?.[1]?t.join(a[1].replaceAll(`.`,`/`),t.basename(r)):r}async function a(e){let t=[];return await o(e,``,t),t.toSorted()}async function o(n,r,i){let a=r?t.join(n,r):n,s=await e.promises.readdir(a,{withFileTypes:!0});for(let e of s){let a=r?t.join(r,e.name):e.name;
|
|
1
|
+
import e from"node:fs";import t from"node:path";import{z as n}from"zod";const r=5e4;async function i(n,r){let i=await e.promises.readFile(n,`utf8`),a=/^\s*package\s+([a-zA-Z0-9_.]+)\s*;/m.exec(i);return a?.[1]?t.join(a[1].replaceAll(`.`,`/`),t.basename(r)):r}async function a(e){let t=[];return await o(e,``,t),t.toSorted()}async function o(n,r,i){let a=r?t.join(n,r):n,s=await e.promises.readdir(a,{withFileTypes:!0});for(let e of s){let a=r?t.join(r,e.name):e.name;e.isDirectory()?await o(n,a,i):e.isFile()&&i.push(a)}}function s(t){if(!e.existsSync(t))return;let r=JSON.parse(e.readFileSync(t,`utf8`)),i=n.array(n.unknown()).safeParse(r);if(!i.success)return;let a=n.object({path:n.string(),data:n.string(),encoding:n.literal(`base64`).optional()});return i.data.flatMap(e=>{let t=a.safeParse(e);return t.success?[t.data]:[]})}function c(e){return e.slice(0,r)}export{r as MAX_OUTPUT_LENGTH,a as listSubmissionFiles,s as readOutputFiles,i as resolveJavaRelativePath,c as truncateOutput};
|
|
2
2
|
//# sourceMappingURL=javaJudge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"javaJudge.js","names":["fs","path","MAX_OUTPUT_LENGTH","resolveJavaRelativePath","sourceCode","sourcePath","packageMatch","fallbackRelativePath","listSubmissionFiles","filePaths","collectSubmissionFiles","rootDir","currentDir","relativeDir","entries","entry","entryRelativePath","readOutputFiles","filePath","parsed","values","z","outputFileSchema","result","value","truncateOutput"],"sources":["../../src/helpers/javaJudge.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\ntype OutputFile = NonNullable<TestCaseResult['outputFiles']>[number];\nexport const MAX_OUTPUT_LENGTH = 50_000;\n\nexport async function resolveJavaRelativePath(sourcePath: string, fallbackRelativePath: string): Promise<string> {\n const sourceCode = await fs.promises.readFile(sourcePath, 'utf8');\n const packageMatch = /^\\s*package\\s+([a-zA-Z0-9_.]+)\\s*;/m.exec(sourceCode);\n if (!packageMatch?.[1]) {\n return fallbackRelativePath;\n }\n\n return path.join(packageMatch[1].replaceAll('.', '/'), path.basename(fallbackRelativePath));\n}\n\nexport async function listSubmissionFiles(rootDir: string): Promise<string[]> {\n const filePaths: string[] = [];\n await collectSubmissionFiles(rootDir, '', filePaths);\n return filePaths.toSorted();\n}\n\nasync function collectSubmissionFiles(rootDir: string, relativeDir: string, filePaths: string[]): Promise<void> {\n const currentDir = relativeDir ? path.join(rootDir, relativeDir) : rootDir;\n const entries = await fs.promises.readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const entryRelativePath = relativeDir ? path.join(relativeDir, entry.name) : entry.name;\n if (entry.isDirectory()) {\n await collectSubmissionFiles(rootDir, entryRelativePath, filePaths);\n continue;\n }\n if (entry.isFile()) {\n filePaths.push(entryRelativePath);\n }\n }\n}\n\nexport function readOutputFiles(filePath: string): OutputFile[] | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n\n // Malformed evaluator JSON remains a harness error (JUDGE_NOT_AVAILABLE), not missing screenshots.\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n const values = z.array(z.unknown()).safeParse(parsed);\n if (!values.success) return undefined;\n const outputFileSchema = z.object({\n path: z.string(),\n data: z.string(),\n encoding: z.literal('base64').optional(),\n });\n return values.data.flatMap((value) => {\n const result = outputFileSchema.safeParse(value);\n return result.success ? [result.data] : [];\n });\n}\n\nexport function truncateOutput(value: string): string {\n return value.slice(0, MAX_OUTPUT_LENGTH);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"javaJudge.js","names":["fs","path","MAX_OUTPUT_LENGTH","resolveJavaRelativePath","sourceCode","sourcePath","packageMatch","fallbackRelativePath","listSubmissionFiles","filePaths","collectSubmissionFiles","rootDir","currentDir","relativeDir","entries","entry","entryRelativePath","readOutputFiles","filePath","parsed","values","z","outputFileSchema","result","value","truncateOutput"],"sources":["../../src/helpers/javaJudge.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { z } from 'zod';\n\nimport type { TestCaseResult } from '../types/testCaseResult.js';\n\ntype OutputFile = NonNullable<TestCaseResult['outputFiles']>[number];\nexport const MAX_OUTPUT_LENGTH = 50_000;\n\nexport async function resolveJavaRelativePath(sourcePath: string, fallbackRelativePath: string): Promise<string> {\n const sourceCode = await fs.promises.readFile(sourcePath, 'utf8');\n const packageMatch = /^\\s*package\\s+([a-zA-Z0-9_.]+)\\s*;/m.exec(sourceCode);\n if (!packageMatch?.[1]) {\n return fallbackRelativePath;\n }\n\n return path.join(packageMatch[1].replaceAll('.', '/'), path.basename(fallbackRelativePath));\n}\n\nexport async function listSubmissionFiles(rootDir: string): Promise<string[]> {\n const filePaths: string[] = [];\n await collectSubmissionFiles(rootDir, '', filePaths);\n return filePaths.toSorted();\n}\n\nasync function collectSubmissionFiles(rootDir: string, relativeDir: string, filePaths: string[]): Promise<void> {\n const currentDir = relativeDir ? path.join(rootDir, relativeDir) : rootDir;\n const entries = await fs.promises.readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const entryRelativePath = relativeDir ? path.join(relativeDir, entry.name) : entry.name;\n if (entry.isDirectory()) {\n await collectSubmissionFiles(rootDir, entryRelativePath, filePaths);\n continue;\n }\n if (entry.isFile()) {\n filePaths.push(entryRelativePath);\n }\n }\n}\n\nexport function readOutputFiles(filePath: string): OutputFile[] | undefined {\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n\n // Malformed evaluator JSON remains a harness error (JUDGE_NOT_AVAILABLE), not missing screenshots.\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n const values = z.array(z.unknown()).safeParse(parsed);\n if (!values.success) return undefined;\n const outputFileSchema = z.object({\n path: z.string(),\n data: z.string(),\n encoding: z.literal('base64').optional(),\n });\n return values.data.flatMap((value) => {\n const result = outputFileSchema.safeParse(value);\n return result.success ? [result.data] : [];\n });\n}\n\nexport function truncateOutput(value: string): string {\n return value.slice(0, MAX_OUTPUT_LENGTH);\n}\n"],"mappings":"wEAQA,MAAaE,EAAoB,IAEjC,eAAsBC,EAAwB,EAAoB,EAA+C,CAC/G,IAAMC,EAAa,MAAMJ,EAAG,SAAS,SAASK,EAAY,MAAM,EAC1DC,EAAe,sCAAsC,KAAKF,CAAU,EAK1E,OAJKE,IAAe,GAIbL,EAAK,KAAKK,EAAa,EAAE,CAAC,WAAW,IAAK,GAAG,EAAGL,EAAK,SAASM,CAAoB,CAAC,EAHjFA,CAIX,CAEA,eAAsBC,EAAoB,EAAoC,CAC5E,IAAMC,EAAsB,CAAC,EAE7B,OADA,MAAMC,EAAuBC,EAAS,GAAIF,CAAS,EAC5CA,EAAU,SAAS,CAC5B,CAEA,eAAeC,EAAuB,EAAiB,EAAqB,EAAoC,CAC9G,IAAME,EAAaC,EAAcZ,EAAK,KAAKU,EAASE,CAAW,EAAIF,EAC7DG,EAAU,MAAMd,EAAG,SAAS,QAAQY,EAAY,CAAE,cAAe,EAAK,CAAC,EAC7E,IAAK,IAAMG,KAASD,EAAS,CAC3B,IAAME,EAAoBH,EAAcZ,EAAK,KAAKY,EAAaE,EAAM,IAAI,EAAIA,EAAM,KAC/EA,EAAM,YAAY,EACpB,MAAML,EAAuBC,EAASK,EAAmBP,CAAS,EAGhEM,EAAM,OAAO,GACfN,EAAU,KAAKO,CAAiB,CAEpC,CACF,CAEA,SAAgBC,EAAgB,EAA4C,CAC1E,GAAI,CAACjB,EAAG,WAAWkB,CAAQ,EACzB,OAIF,IAAMC,EAAkB,KAAK,MAAMnB,EAAG,aAAakB,EAAU,MAAM,CAAC,EAC9DE,EAASC,EAAE,MAAMA,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAUF,CAAM,EACpD,GAAI,CAACC,EAAO,QAAS,OACrB,IAAME,EAAmBD,EAAE,OAAO,CAChC,KAAMA,EAAE,OAAO,EACf,KAAMA,EAAE,OAAO,EACf,SAAUA,EAAE,QAAQ,QAAQ,CAAC,CAAC,SAAS,CACzC,CAAC,EACD,OAAOD,EAAO,KAAK,QAAS,GAAU,CACpC,IAAMG,EAASD,EAAiB,UAAUE,CAAK,EAC/C,OAAOD,EAAO,QAAU,CAACA,EAAO,IAAI,EAAI,CAAC,CAC3C,CAAC,CACH,CAEA,SAAgBE,EAAe,EAAuB,CACpD,OAAOD,EAAM,MAAM,EAAGtB,CAAiB,CACzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judgeByStaticAnalysis.cjs","names":["fs","path","findLanguageDefinitionByPath","removeCommentsInSourceCode","DecisionCode","normalizeCodeRule","require_runtime","require_removeCommentsInSourceCode","require_problem","require_findLanguageDefinitionByPath","require_decisionCode","node_fs","node_path","judgeByStaticAnalysis","needsSourceCode","problemMarkdownFrontMatterLike","filePathSet","sourceCodeWithoutCommentFiles","dirent","cwd","relativePath","languageDefinition","text","missingFilePaths","p","violations","rule","re","pattern","matches","file","match","message","formatForbiddenRuleViolation","missingRequiredLabels","f","label","locations","violation","path"],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport { normalizeCodeRule } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\
|
|
1
|
+
{"version":3,"file":"judgeByStaticAnalysis.cjs","names":["fs","path","findLanguageDefinitionByPath","removeCommentsInSourceCode","DecisionCode","normalizeCodeRule","require_runtime","require_removeCommentsInSourceCode","require_problem","require_findLanguageDefinitionByPath","require_decisionCode","node_fs","node_path","judgeByStaticAnalysis","needsSourceCode","problemMarkdownFrontMatterLike","filePathSet","sourceCodeWithoutCommentFiles","dirent","cwd","relativePath","languageDefinition","text","missingFilePaths","p","violations","rule","re","pattern","matches","file","match","message","formatForbiddenRuleViolation","missingRequiredLabels","f","label","locations","violation","path"],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport { normalizeCodeRule } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\nimport { findLanguageDefinitionByPath } from './findLanguageDefinitionByPath.js';\nimport { removeCommentsInSourceCode } from './removeCommentsInSourceCode.js';\n\ninterface ForbiddenRuleViolation {\n /** Learner-facing description of the rule; the raw pattern when the problem declares no message. */\n label: string;\n matches: { path: string; match: string }[];\n}\n\nexport async function judgeByStaticAnalysis(\n cwd: string,\n problemMarkdownFrontMatterLike: Pick<\n ProblemMarkdownFrontMatter,\n 'forbiddenRegExpsInCode' | 'forbiddenTextsInCode' | 'requiredRegExpsInCode' | 'requiredSubmissionFilePaths'\n >\n): Promise<Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown'> | undefined> {\n const needsSourceCode =\n !!problemMarkdownFrontMatterLike.forbiddenRegExpsInCode?.length ||\n !!problemMarkdownFrontMatterLike.forbiddenTextsInCode?.length ||\n !!problemMarkdownFrontMatterLike.requiredRegExpsInCode?.length;\n if (!needsSourceCode && !problemMarkdownFrontMatterLike.requiredSubmissionFilePaths?.length) return;\n\n const filePathSet = new Set<string>();\n const sourceCodeWithoutCommentFiles: { path: string; data: string }[] = [];\n\n for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true, recursive: true })) {\n if (!dirent.isFile()) continue;\n\n const relativePath = path.relative(cwd, path.join(dirent.parentPath, dirent.name));\n filePathSet.add(relativePath);\n\n if (!needsSourceCode) continue;\n const languageDefinition = findLanguageDefinitionByPath(dirent.name);\n if (!languageDefinition) continue;\n\n const text = await fs.promises.readFile(path.join(dirent.parentPath, dirent.name), 'utf8');\n const isBinary = text.includes('\\uFFFD');\n if (isBinary) continue;\n\n sourceCodeWithoutCommentFiles.push({\n path: relativePath,\n data: languageDefinition.grammer ? removeCommentsInSourceCode(languageDefinition.grammer, text) : text,\n });\n }\n\n if (problemMarkdownFrontMatterLike.requiredSubmissionFilePaths) {\n const missingFilePaths = problemMarkdownFrontMatterLike.requiredSubmissionFilePaths\n .filter((p) => !filePathSet.has(p))\n .toSorted();\n\n if (missingFilePaths.length > 0) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n feedbackMarkdown: `ファイルが不足しています。\n次のファイルを追加してから再度提出してください。\n\n${missingFilePaths.map((p) => `- \\`${p}\\``).join('\\n')}\n`,\n };\n }\n }\n\n const violations: ForbiddenRuleViolation[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.forbiddenRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern, 'g');\n const matches = sourceCodeWithoutCommentFiles.flatMap((file) =>\n [...file.data.matchAll(re)].map((match) => ({ path: file.path, match: match[0] }))\n );\n if (matches.length > 0) violations.push({ label: message ?? `禁止パターン \\`${re.toString()}\\``, matches });\n }\n for (const rule of problemMarkdownFrontMatterLike.forbiddenTextsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const matches = sourceCodeWithoutCommentFiles\n .filter((file) => file.data.includes(pattern))\n .map((file) => ({ path: file.path, match: pattern }));\n if (matches.length > 0) violations.push({ label: message ?? `禁止文字列 \\`${pattern}\\``, matches });\n }\n\n if (violations.length > 0) {\n return {\n decisionCode: DecisionCode.FORBIDDEN_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に禁止された文字列が含まれています。\nソースコードを修正してから再度提出してください。\n\n${violations.map(formatForbiddenRuleViolation).join('\\n')}\n`,\n };\n }\n\n const missingRequiredLabels: string[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.requiredRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern);\n const isFound = sourceCodeWithoutCommentFiles.some((f) => re.test(f.data));\n if (!isFound) missingRequiredLabels.push(message ?? `\\`${re.toString()}\\``);\n }\n\n if (missingRequiredLabels.length > 0) {\n return {\n decisionCode: DecisionCode.REQUIRED_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に必要な文字列が含まれていません。\nソースコードを修正してから再度提出してください。\n\n${missingRequiredLabels.map((label) => `- ${label}`).join('\\n')}\n`,\n };\n }\n\n return;\n}\n\nfunction formatForbiddenRuleViolation(violation: ForbiddenRuleViolation): string {\n const locations = [...new Set(violation.matches.map(({ path, match }) => ` - \\`${path}\\`: \\`${match}\\``))];\n return `- ${violation.label}\\n${locations.join('\\n')}`;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judgeByStaticAnalysis.js","names":["fs","path","judgeByStaticAnalysis","needsSourceCode","problemMarkdownFrontMatterLike","filePathSet","sourceCodeWithoutCommentFiles","dirent","cwd","relativePath","languageDefinition","findLanguageDefinitionByPath","text","removeCommentsInSourceCode","missingFilePaths","p","DecisionCode","violations","rule","normalizeCodeRule","re","pattern","matches","file","match","message","formatForbiddenRuleViolation","missingRequiredLabels","f","label","locations","violation"],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport { normalizeCodeRule } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\
|
|
1
|
+
{"version":3,"file":"judgeByStaticAnalysis.js","names":["fs","path","judgeByStaticAnalysis","needsSourceCode","problemMarkdownFrontMatterLike","filePathSet","sourceCodeWithoutCommentFiles","dirent","cwd","relativePath","languageDefinition","findLanguageDefinitionByPath","text","removeCommentsInSourceCode","missingFilePaths","p","DecisionCode","violations","rule","normalizeCodeRule","re","pattern","matches","file","match","message","formatForbiddenRuleViolation","missingRequiredLabels","f","label","locations","violation"],"sources":["../../src/helpers/judgeByStaticAnalysis.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { DecisionCode } from '../types/decisionCode.js';\nimport type { ProblemMarkdownFrontMatter } from '../types/problem.js';\nimport { normalizeCodeRule } from '../types/problem.js';\nimport type { TestCaseResult } from '../types/testCaseResult.js';\nimport { findLanguageDefinitionByPath } from './findLanguageDefinitionByPath.js';\nimport { removeCommentsInSourceCode } from './removeCommentsInSourceCode.js';\n\ninterface ForbiddenRuleViolation {\n /** Learner-facing description of the rule; the raw pattern when the problem declares no message. */\n label: string;\n matches: { path: string; match: string }[];\n}\n\nexport async function judgeByStaticAnalysis(\n cwd: string,\n problemMarkdownFrontMatterLike: Pick<\n ProblemMarkdownFrontMatter,\n 'forbiddenRegExpsInCode' | 'forbiddenTextsInCode' | 'requiredRegExpsInCode' | 'requiredSubmissionFilePaths'\n >\n): Promise<Pick<TestCaseResult, 'decisionCode' | 'feedbackMarkdown'> | undefined> {\n const needsSourceCode =\n !!problemMarkdownFrontMatterLike.forbiddenRegExpsInCode?.length ||\n !!problemMarkdownFrontMatterLike.forbiddenTextsInCode?.length ||\n !!problemMarkdownFrontMatterLike.requiredRegExpsInCode?.length;\n if (!needsSourceCode && !problemMarkdownFrontMatterLike.requiredSubmissionFilePaths?.length) return;\n\n const filePathSet = new Set<string>();\n const sourceCodeWithoutCommentFiles: { path: string; data: string }[] = [];\n\n for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true, recursive: true })) {\n if (!dirent.isFile()) continue;\n\n const relativePath = path.relative(cwd, path.join(dirent.parentPath, dirent.name));\n filePathSet.add(relativePath);\n\n if (!needsSourceCode) continue;\n const languageDefinition = findLanguageDefinitionByPath(dirent.name);\n if (!languageDefinition) continue;\n\n const text = await fs.promises.readFile(path.join(dirent.parentPath, dirent.name), 'utf8');\n const isBinary = text.includes('\\uFFFD');\n if (isBinary) continue;\n\n sourceCodeWithoutCommentFiles.push({\n path: relativePath,\n data: languageDefinition.grammer ? removeCommentsInSourceCode(languageDefinition.grammer, text) : text,\n });\n }\n\n if (problemMarkdownFrontMatterLike.requiredSubmissionFilePaths) {\n const missingFilePaths = problemMarkdownFrontMatterLike.requiredSubmissionFilePaths\n .filter((p) => !filePathSet.has(p))\n .toSorted();\n\n if (missingFilePaths.length > 0) {\n return {\n decisionCode: DecisionCode.MISSING_REQUIRED_SUBMISSION_FILE_ERROR,\n feedbackMarkdown: `ファイルが不足しています。\n次のファイルを追加してから再度提出してください。\n\n${missingFilePaths.map((p) => `- \\`${p}\\``).join('\\n')}\n`,\n };\n }\n }\n\n const violations: ForbiddenRuleViolation[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.forbiddenRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern, 'g');\n const matches = sourceCodeWithoutCommentFiles.flatMap((file) =>\n [...file.data.matchAll(re)].map((match) => ({ path: file.path, match: match[0] }))\n );\n if (matches.length > 0) violations.push({ label: message ?? `禁止パターン \\`${re.toString()}\\``, matches });\n }\n for (const rule of problemMarkdownFrontMatterLike.forbiddenTextsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const matches = sourceCodeWithoutCommentFiles\n .filter((file) => file.data.includes(pattern))\n .map((file) => ({ path: file.path, match: pattern }));\n if (matches.length > 0) violations.push({ label: message ?? `禁止文字列 \\`${pattern}\\``, matches });\n }\n\n if (violations.length > 0) {\n return {\n decisionCode: DecisionCode.FORBIDDEN_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に禁止された文字列が含まれています。\nソースコードを修正してから再度提出してください。\n\n${violations.map(formatForbiddenRuleViolation).join('\\n')}\n`,\n };\n }\n\n const missingRequiredLabels: string[] = [];\n\n for (const rule of problemMarkdownFrontMatterLike.requiredRegExpsInCode ?? []) {\n const { pattern, message } = normalizeCodeRule(rule);\n const re = new RegExp(pattern);\n const isFound = sourceCodeWithoutCommentFiles.some((f) => re.test(f.data));\n if (!isFound) missingRequiredLabels.push(message ?? `\\`${re.toString()}\\``);\n }\n\n if (missingRequiredLabels.length > 0) {\n return {\n decisionCode: DecisionCode.REQUIRED_PATTERNS_IN_CODE_ERROR,\n feedbackMarkdown: `ソースコード中に必要な文字列が含まれていません。\nソースコードを修正してから再度提出してください。\n\n${missingRequiredLabels.map((label) => `- ${label}`).join('\\n')}\n`,\n };\n }\n\n return;\n}\n\nfunction formatForbiddenRuleViolation(violation: ForbiddenRuleViolation): string {\n const locations = [...new Set(violation.matches.map(({ path, match }) => ` - \\`${path}\\`: \\`${match}\\``))];\n return `- ${violation.label}\\n${locations.join('\\n')}`;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";var e=class extends Error{reason;lineNumber;constructor(e,t){super(`${e.replaceAll(`_`,` `)} on line ${t}`),this.name=`CsvParseError`,this.reason=e,this.lineNumber=t}};function t(e){return n(e).map(e=>e.cells)}function n(t){let n=[],r=[],i=``,a=`start`,o=!1,s=1,c=1,l=0,u=t.startsWith(``)?t.slice(1):t,d=()=>{r.push(i),i=``,a=`start`};for(;l<u.length;){let t=u[l];if(a===`quoted`){if(t===`"`){if(u[l+1]===`"`){i+=`"`,l+=2;continue}a=`closed`}else(t===`
|
|
2
2
|
`||t===`\r`&&u[l+1]!==`
|
|
3
|
-
`)&&s++,i+=t;l
|
|
3
|
+
`)&&s++,i+=t;l++}else{if(o=!0,t===`,`||t===`
|
|
4
4
|
`||t===`\r`)d(),t!==`,`&&(n.push({cells:r,lineNumber:c}),r=[],o=!1,t===`\r`&&u[l+1]===`
|
|
5
|
-
`&&l++,s++,c=s);else if(t===`"`){if(a!==`start`)throw new e(`unexpected_quote`,s);a=`quoted`}else if(a===`closed`)throw new e(`text_after_quoted_field`,s);else a=`unquoted`,i+=t;l++}if(a===`quoted`)throw new e(`unterminated_quote`,c);return o&&(d(),n.push({cells:r,lineNumber:c})),n}exports.CsvParseError=e,exports.parseCsv=t,exports.parseCsvRecords=n;
|
|
5
|
+
`&&l++,s++,c=s);else if(t===`"`){if(a!==`start`)throw new e(`unexpected_quote`,s);a=`quoted`}else if(a===`closed`)throw new e(`text_after_quoted_field`,s);else a=`unquoted`,i+=t;l++}}if(a===`quoted`)throw new e(`unterminated_quote`,c);return o&&(d(),n.push({cells:r,lineNumber:c})),n}exports.CsvParseError=e,exports.parseCsv=t,exports.parseCsvRecords=n;
|
|
6
6
|
//# sourceMappingURL=parseCsv.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseCsv.cjs","names":["CsvParseError","reason","lineNumber","parseCsv","parseCsvRecords","text","record","records","cells","field","fieldState","hasField","recordLineNumber","index","content","endField","char"],"sources":["../../src/helpers/parseCsv.ts"],"sourcesContent":["export type CsvParseErrorReason = 'unterminated_quote' | 'unexpected_quote' | 'text_after_quoted_field';\n\nexport class CsvParseError extends Error {\n readonly reason: CsvParseErrorReason;\n /** 1-based physical line where the error was detected (the record's start line for an unterminated quote). */\n readonly lineNumber: number;\n\n constructor(reason: CsvParseErrorReason, lineNumber: number) {\n super(`${reason.replaceAll('_', ' ')} on line ${lineNumber}`);\n this.name = 'CsvParseError';\n this.reason = reason;\n this.lineNumber = lineNumber;\n }\n}\n\nexport interface CsvRecord {\n cells: string[];\n /** 1-based physical line on which the record starts (quoted fields may span several lines). */\n lineNumber: number;\n}\n\n/**\n * Parse RFC 4180 style CSV text (double-quoted fields, `\"\"` escapes, LF, CRLF, or CR line ends) into rows.\n * A trailing line end does not produce an extra row.\n *\n * @throws {CsvParseError} when a quoted field is not closed, or a quote appears anywhere but around a whole field.\n */\nexport function parseCsv(text: string): string[][] {\n return parseCsvRecords(text).map((record) => record.cells);\n}\n\n/** Like {@link parseCsv}, but also reports the physical line each record starts on. */\nexport function parseCsvRecords(text: string): CsvRecord[] {\n const records: CsvRecord[] = [];\n let cells: string[] = [];\n let field = '';\n let fieldState: 'start' | 'unquoted' | 'quoted' | 'closed' = 'start';\n let hasField = false;\n let lineNumber = 1;\n let recordLineNumber = 1;\n let index = 0;\n const content = text.startsWith('\\uFEFF') ? text.slice(1) : text;\n\n const endField = (): void => {\n cells.push(field);\n field = '';\n fieldState = 'start';\n };\n\n while (index < content.length) {\n const char = content[index] as string;\n if (fieldState === 'quoted') {\n if (char === '\"') {\n if (content[index + 1] === '\"') {\n field += '\"';\n index += 2;\n continue;\n }\n fieldState = 'closed';\n } else {\n if (char === '\\n' || (char === '\\r' && content[index + 1] !== '\\n')) lineNumber++;\n field += char;\n }\n index++;\n continue;\n }\n\n hasField = true;\n if (char === ',' || char === '\\n' || char === '\\r') {\n endField();\n if (char !== ',') {\n records.push({ cells, lineNumber: recordLineNumber });\n cells = [];\n hasField = false;\n if (char === '\\r' && content[index + 1] === '\\n') index++;\n lineNumber++;\n recordLineNumber = lineNumber;\n }\n } else if (char === '\"') {\n if (fieldState !== 'start') throw new CsvParseError('unexpected_quote', lineNumber);\n fieldState = 'quoted';\n } else if (fieldState === 'closed') {\n throw new CsvParseError('text_after_quoted_field', lineNumber);\n } else {\n fieldState = 'unquoted';\n field += char;\n }\n index++;\n }\n\n if (fieldState === 'quoted') throw new CsvParseError('unterminated_quote', recordLineNumber);\n if (hasField) {\n endField();\n records.push({ cells, lineNumber: recordLineNumber });\n }\n return records;\n}\n"],"mappings":"aAEA,IAAaA,EAAb,cAAmC,KAAM,CACvC,OAEA,WAEA,YAAY,EAA6B,EAAoB,CAC3D,MAAM,GAAGC,EAAO,WAAW,IAAK,GAAG,EAAE,WAAWC,GAAY,EAC5D,KAAK,KAAO,gBACZ,KAAK,OAASD,EACd,KAAK,WAAaC,CACpB,CACF,EAcA,SAAgBC,EAAS,EAA0B,CACjD,OAAOC,EAAgBC,CAAI,CAAC,CAAC,IAAK,GAAWC,EAAO,KAAK,CAC3D,CAGA,SAAgBF,EAAgB,EAA2B,CACzD,IAAMG,EAAuB,CAAC,EAC1BC,EAAkB,CAAC,EACnBC,EAAQ,GACRC,EAAyD,QACzDC,EAAW,GACXT,EAAa,EACbU,EAAmB,EACnBC,EAAQ,EACNC,EAAUT,EAAK,WAAW,GAAQ,EAAIA,EAAK,MAAM,CAAC,EAAIA,EAEtDU,MAAuB,CAC3BP,EAAM,KAAKC,CAAK,EAChB,EAAQ,GACR,EAAa,OACf,EAEA,KAAOI,EAAQC,EAAQ,QAAQ,CAC7B,IAAME,EAAOF,EAAQD,GACrB,GAAIH,IAAe,SAAU,CAC3B,GAAIM,IAAS,IAAK,CAChB,GAAIF,EAAQD,EAAQ,KAAO,IAAK,CAC9B,GAAS,IACT,GAAS,EACT,QACF,CACA,EAAa,QACf,MACMG,IAAS;GAASA,IAAS,MAAQF,EAAQD,EAAQ,KAAO;IAAO,IACrE,GAASG,EAEX,
|
|
1
|
+
{"version":3,"file":"parseCsv.cjs","names":["CsvParseError","reason","lineNumber","parseCsv","parseCsvRecords","text","record","records","cells","field","fieldState","hasField","recordLineNumber","index","content","endField","char"],"sources":["../../src/helpers/parseCsv.ts"],"sourcesContent":["export type CsvParseErrorReason = 'unterminated_quote' | 'unexpected_quote' | 'text_after_quoted_field';\n\nexport class CsvParseError extends Error {\n readonly reason: CsvParseErrorReason;\n /** 1-based physical line where the error was detected (the record's start line for an unterminated quote). */\n readonly lineNumber: number;\n\n constructor(reason: CsvParseErrorReason, lineNumber: number) {\n super(`${reason.replaceAll('_', ' ')} on line ${lineNumber}`);\n this.name = 'CsvParseError';\n this.reason = reason;\n this.lineNumber = lineNumber;\n }\n}\n\nexport interface CsvRecord {\n cells: string[];\n /** 1-based physical line on which the record starts (quoted fields may span several lines). */\n lineNumber: number;\n}\n\n/**\n * Parse RFC 4180 style CSV text (double-quoted fields, `\"\"` escapes, LF, CRLF, or CR line ends) into rows.\n * A trailing line end does not produce an extra row.\n *\n * @throws {CsvParseError} when a quoted field is not closed, or a quote appears anywhere but around a whole field.\n */\nexport function parseCsv(text: string): string[][] {\n return parseCsvRecords(text).map((record) => record.cells);\n}\n\n/** Like {@link parseCsv}, but also reports the physical line each record starts on. */\nexport function parseCsvRecords(text: string): CsvRecord[] {\n const records: CsvRecord[] = [];\n let cells: string[] = [];\n let field = '';\n let fieldState: 'start' | 'unquoted' | 'quoted' | 'closed' = 'start';\n let hasField = false;\n let lineNumber = 1;\n let recordLineNumber = 1;\n let index = 0;\n const content = text.startsWith('\\uFEFF') ? text.slice(1) : text;\n\n const endField = (): void => {\n cells.push(field);\n field = '';\n fieldState = 'start';\n };\n\n while (index < content.length) {\n const char = content[index] as string;\n if (fieldState === 'quoted') {\n if (char === '\"') {\n if (content[index + 1] === '\"') {\n field += '\"';\n index += 2;\n continue;\n }\n fieldState = 'closed';\n } else {\n if (char === '\\n' || (char === '\\r' && content[index + 1] !== '\\n')) lineNumber++;\n field += char;\n }\n index++;\n continue;\n }\n\n hasField = true;\n if (char === ',' || char === '\\n' || char === '\\r') {\n endField();\n if (char !== ',') {\n records.push({ cells, lineNumber: recordLineNumber });\n cells = [];\n hasField = false;\n if (char === '\\r' && content[index + 1] === '\\n') index++;\n lineNumber++;\n recordLineNumber = lineNumber;\n }\n } else if (char === '\"') {\n if (fieldState !== 'start') throw new CsvParseError('unexpected_quote', lineNumber);\n fieldState = 'quoted';\n } else if (fieldState === 'closed') {\n throw new CsvParseError('text_after_quoted_field', lineNumber);\n } else {\n fieldState = 'unquoted';\n field += char;\n }\n index++;\n }\n\n if (fieldState === 'quoted') throw new CsvParseError('unterminated_quote', recordLineNumber);\n if (hasField) {\n endField();\n records.push({ cells, lineNumber: recordLineNumber });\n }\n return records;\n}\n"],"mappings":"aAEA,IAAaA,EAAb,cAAmC,KAAM,CACvC,OAEA,WAEA,YAAY,EAA6B,EAAoB,CAC3D,MAAM,GAAGC,EAAO,WAAW,IAAK,GAAG,EAAE,WAAWC,GAAY,EAC5D,KAAK,KAAO,gBACZ,KAAK,OAASD,EACd,KAAK,WAAaC,CACpB,CACF,EAcA,SAAgBC,EAAS,EAA0B,CACjD,OAAOC,EAAgBC,CAAI,CAAC,CAAC,IAAK,GAAWC,EAAO,KAAK,CAC3D,CAGA,SAAgBF,EAAgB,EAA2B,CACzD,IAAMG,EAAuB,CAAC,EAC1BC,EAAkB,CAAC,EACnBC,EAAQ,GACRC,EAAyD,QACzDC,EAAW,GACXT,EAAa,EACbU,EAAmB,EACnBC,EAAQ,EACNC,EAAUT,EAAK,WAAW,GAAQ,EAAIA,EAAK,MAAM,CAAC,EAAIA,EAEtDU,MAAuB,CAC3BP,EAAM,KAAKC,CAAK,EAChB,EAAQ,GACR,EAAa,OACf,EAEA,KAAOI,EAAQC,EAAQ,QAAQ,CAC7B,IAAME,EAAOF,EAAQD,GACrB,GAAIH,IAAe,SAAU,CAC3B,GAAIM,IAAS,IAAK,CAChB,GAAIF,EAAQD,EAAQ,KAAO,IAAK,CAC9B,GAAS,IACT,GAAS,EACT,QACF,CACA,EAAa,QACf,MACMG,IAAS;GAASA,IAAS,MAAQF,EAAQD,EAAQ,KAAO;IAAO,IACrE,GAASG,EAEX,GAEF,KAEA,CACA,GADA,EAAW,GACPA,IAAS,KAAOA,IAAS;GAAQA,IAAS,KAC5CD,EAAS,EACLC,IAAS,MACXT,EAAQ,KAAK,CAAE,QAAO,WAAYK,CAAiB,CAAC,EACpD,EAAQ,CAAC,EACT,EAAW,GACPI,IAAS,MAAQF,EAAQD,EAAQ,KAAO;GAAM,IAClD,IACA,EAAmBX,QAEhB,GAAIc,IAAS,IAAK,CACvB,GAAIN,IAAe,QAAS,MAAM,IAAIV,EAAc,mBAAoBE,CAAU,EAClF,EAAa,QACf,MAAO,GAAIQ,IAAe,SACxB,MAAM,IAAIV,EAAc,0BAA2BE,CAAU,MAE7D,GAAa,WACb,GAASc,EAEX,GApBW,CAqBb,CAEA,GAAIN,IAAe,SAAU,MAAM,IAAIV,EAAc,qBAAsBY,CAAgB,EAK3F,OAJID,IACFI,EAAS,EACTR,EAAQ,KAAK,CAAE,QAAO,WAAYK,CAAiB,CAAC,GAE/CL,CACT"}
|
package/dist/helpers/parseCsv.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var e=class extends Error{reason;lineNumber;constructor(e,t){super(`${e.replaceAll(`_`,` `)} on line ${t}`),this.name=`CsvParseError`,this.reason=e,this.lineNumber=t}};function t(e){return n(e).map(e=>e.cells)}function n(t){let n=[],r=[],i=``,a=`start`,o=!1,s=1,c=1,l=0,u=t.startsWith(``)?t.slice(1):t,d=()=>{r.push(i),i=``,a=`start`};for(;l<u.length;){let t=u[l];if(a===`quoted`){if(t===`"`){if(u[l+1]===`"`){i+=`"`,l+=2;continue}a=`closed`}else(t===`
|
|
2
2
|
`||t===`\r`&&u[l+1]!==`
|
|
3
|
-
`)&&s++,i+=t;l
|
|
3
|
+
`)&&s++,i+=t;l++}else{if(o=!0,t===`,`||t===`
|
|
4
4
|
`||t===`\r`)d(),t!==`,`&&(n.push({cells:r,lineNumber:c}),r=[],o=!1,t===`\r`&&u[l+1]===`
|
|
5
|
-
`&&l++,s++,c=s);else if(t===`"`){if(a!==`start`)throw new e(`unexpected_quote`,s);a=`quoted`}else if(a===`closed`)throw new e(`text_after_quoted_field`,s);else a=`unquoted`,i+=t;l++}if(a===`quoted`)throw new e(`unterminated_quote`,c);return o&&(d(),n.push({cells:r,lineNumber:c})),n}export{e as CsvParseError,t as parseCsv,n as parseCsvRecords};
|
|
5
|
+
`&&l++,s++,c=s);else if(t===`"`){if(a!==`start`)throw new e(`unexpected_quote`,s);a=`quoted`}else if(a===`closed`)throw new e(`text_after_quoted_field`,s);else a=`unquoted`,i+=t;l++}}if(a===`quoted`)throw new e(`unterminated_quote`,c);return o&&(d(),n.push({cells:r,lineNumber:c})),n}export{e as CsvParseError,t as parseCsv,n as parseCsvRecords};
|
|
6
6
|
//# sourceMappingURL=parseCsv.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseCsv.js","names":["CsvParseError","reason","lineNumber","parseCsv","parseCsvRecords","text","record","records","cells","field","fieldState","hasField","recordLineNumber","index","content","endField","char"],"sources":["../../src/helpers/parseCsv.ts"],"sourcesContent":["export type CsvParseErrorReason = 'unterminated_quote' | 'unexpected_quote' | 'text_after_quoted_field';\n\nexport class CsvParseError extends Error {\n readonly reason: CsvParseErrorReason;\n /** 1-based physical line where the error was detected (the record's start line for an unterminated quote). */\n readonly lineNumber: number;\n\n constructor(reason: CsvParseErrorReason, lineNumber: number) {\n super(`${reason.replaceAll('_', ' ')} on line ${lineNumber}`);\n this.name = 'CsvParseError';\n this.reason = reason;\n this.lineNumber = lineNumber;\n }\n}\n\nexport interface CsvRecord {\n cells: string[];\n /** 1-based physical line on which the record starts (quoted fields may span several lines). */\n lineNumber: number;\n}\n\n/**\n * Parse RFC 4180 style CSV text (double-quoted fields, `\"\"` escapes, LF, CRLF, or CR line ends) into rows.\n * A trailing line end does not produce an extra row.\n *\n * @throws {CsvParseError} when a quoted field is not closed, or a quote appears anywhere but around a whole field.\n */\nexport function parseCsv(text: string): string[][] {\n return parseCsvRecords(text).map((record) => record.cells);\n}\n\n/** Like {@link parseCsv}, but also reports the physical line each record starts on. */\nexport function parseCsvRecords(text: string): CsvRecord[] {\n const records: CsvRecord[] = [];\n let cells: string[] = [];\n let field = '';\n let fieldState: 'start' | 'unquoted' | 'quoted' | 'closed' = 'start';\n let hasField = false;\n let lineNumber = 1;\n let recordLineNumber = 1;\n let index = 0;\n const content = text.startsWith('\\uFEFF') ? text.slice(1) : text;\n\n const endField = (): void => {\n cells.push(field);\n field = '';\n fieldState = 'start';\n };\n\n while (index < content.length) {\n const char = content[index] as string;\n if (fieldState === 'quoted') {\n if (char === '\"') {\n if (content[index + 1] === '\"') {\n field += '\"';\n index += 2;\n continue;\n }\n fieldState = 'closed';\n } else {\n if (char === '\\n' || (char === '\\r' && content[index + 1] !== '\\n')) lineNumber++;\n field += char;\n }\n index++;\n continue;\n }\n\n hasField = true;\n if (char === ',' || char === '\\n' || char === '\\r') {\n endField();\n if (char !== ',') {\n records.push({ cells, lineNumber: recordLineNumber });\n cells = [];\n hasField = false;\n if (char === '\\r' && content[index + 1] === '\\n') index++;\n lineNumber++;\n recordLineNumber = lineNumber;\n }\n } else if (char === '\"') {\n if (fieldState !== 'start') throw new CsvParseError('unexpected_quote', lineNumber);\n fieldState = 'quoted';\n } else if (fieldState === 'closed') {\n throw new CsvParseError('text_after_quoted_field', lineNumber);\n } else {\n fieldState = 'unquoted';\n field += char;\n }\n index++;\n }\n\n if (fieldState === 'quoted') throw new CsvParseError('unterminated_quote', recordLineNumber);\n if (hasField) {\n endField();\n records.push({ cells, lineNumber: recordLineNumber });\n }\n return records;\n}\n"],"mappings":"AAEA,IAAaA,EAAb,cAAmC,KAAM,CACvC,OAEA,WAEA,YAAY,EAA6B,EAAoB,CAC3D,MAAM,GAAGC,EAAO,WAAW,IAAK,GAAG,EAAE,WAAWC,GAAY,EAC5D,KAAK,KAAO,gBACZ,KAAK,OAASD,EACd,KAAK,WAAaC,CACpB,CACF,EAcA,SAAgBC,EAAS,EAA0B,CACjD,OAAOC,EAAgBC,CAAI,CAAC,CAAC,IAAK,GAAWC,EAAO,KAAK,CAC3D,CAGA,SAAgBF,EAAgB,EAA2B,CACzD,IAAMG,EAAuB,CAAC,EAC1BC,EAAkB,CAAC,EACnBC,EAAQ,GACRC,EAAyD,QACzDC,EAAW,GACXT,EAAa,EACbU,EAAmB,EACnBC,EAAQ,EACNC,EAAUT,EAAK,WAAW,GAAQ,EAAIA,EAAK,MAAM,CAAC,EAAIA,EAEtDU,MAAuB,CAC3BP,EAAM,KAAKC,CAAK,EAChB,EAAQ,GACR,EAAa,OACf,EAEA,KAAOI,EAAQC,EAAQ,QAAQ,CAC7B,IAAME,EAAOF,EAAQD,GACrB,GAAIH,IAAe,SAAU,CAC3B,GAAIM,IAAS,IAAK,CAChB,GAAIF,EAAQD,EAAQ,KAAO,IAAK,CAC9B,GAAS,IACT,GAAS,EACT,QACF,CACA,EAAa,QACf,MACMG,IAAS;GAASA,IAAS,MAAQF,EAAQD,EAAQ,KAAO;IAAO,IACrE,GAASG,EAEX,
|
|
1
|
+
{"version":3,"file":"parseCsv.js","names":["CsvParseError","reason","lineNumber","parseCsv","parseCsvRecords","text","record","records","cells","field","fieldState","hasField","recordLineNumber","index","content","endField","char"],"sources":["../../src/helpers/parseCsv.ts"],"sourcesContent":["export type CsvParseErrorReason = 'unterminated_quote' | 'unexpected_quote' | 'text_after_quoted_field';\n\nexport class CsvParseError extends Error {\n readonly reason: CsvParseErrorReason;\n /** 1-based physical line where the error was detected (the record's start line for an unterminated quote). */\n readonly lineNumber: number;\n\n constructor(reason: CsvParseErrorReason, lineNumber: number) {\n super(`${reason.replaceAll('_', ' ')} on line ${lineNumber}`);\n this.name = 'CsvParseError';\n this.reason = reason;\n this.lineNumber = lineNumber;\n }\n}\n\nexport interface CsvRecord {\n cells: string[];\n /** 1-based physical line on which the record starts (quoted fields may span several lines). */\n lineNumber: number;\n}\n\n/**\n * Parse RFC 4180 style CSV text (double-quoted fields, `\"\"` escapes, LF, CRLF, or CR line ends) into rows.\n * A trailing line end does not produce an extra row.\n *\n * @throws {CsvParseError} when a quoted field is not closed, or a quote appears anywhere but around a whole field.\n */\nexport function parseCsv(text: string): string[][] {\n return parseCsvRecords(text).map((record) => record.cells);\n}\n\n/** Like {@link parseCsv}, but also reports the physical line each record starts on. */\nexport function parseCsvRecords(text: string): CsvRecord[] {\n const records: CsvRecord[] = [];\n let cells: string[] = [];\n let field = '';\n let fieldState: 'start' | 'unquoted' | 'quoted' | 'closed' = 'start';\n let hasField = false;\n let lineNumber = 1;\n let recordLineNumber = 1;\n let index = 0;\n const content = text.startsWith('\\uFEFF') ? text.slice(1) : text;\n\n const endField = (): void => {\n cells.push(field);\n field = '';\n fieldState = 'start';\n };\n\n while (index < content.length) {\n const char = content[index] as string;\n if (fieldState === 'quoted') {\n if (char === '\"') {\n if (content[index + 1] === '\"') {\n field += '\"';\n index += 2;\n continue;\n }\n fieldState = 'closed';\n } else {\n if (char === '\\n' || (char === '\\r' && content[index + 1] !== '\\n')) lineNumber++;\n field += char;\n }\n index++;\n continue;\n }\n\n hasField = true;\n if (char === ',' || char === '\\n' || char === '\\r') {\n endField();\n if (char !== ',') {\n records.push({ cells, lineNumber: recordLineNumber });\n cells = [];\n hasField = false;\n if (char === '\\r' && content[index + 1] === '\\n') index++;\n lineNumber++;\n recordLineNumber = lineNumber;\n }\n } else if (char === '\"') {\n if (fieldState !== 'start') throw new CsvParseError('unexpected_quote', lineNumber);\n fieldState = 'quoted';\n } else if (fieldState === 'closed') {\n throw new CsvParseError('text_after_quoted_field', lineNumber);\n } else {\n fieldState = 'unquoted';\n field += char;\n }\n index++;\n }\n\n if (fieldState === 'quoted') throw new CsvParseError('unterminated_quote', recordLineNumber);\n if (hasField) {\n endField();\n records.push({ cells, lineNumber: recordLineNumber });\n }\n return records;\n}\n"],"mappings":"AAEA,IAAaA,EAAb,cAAmC,KAAM,CACvC,OAEA,WAEA,YAAY,EAA6B,EAAoB,CAC3D,MAAM,GAAGC,EAAO,WAAW,IAAK,GAAG,EAAE,WAAWC,GAAY,EAC5D,KAAK,KAAO,gBACZ,KAAK,OAASD,EACd,KAAK,WAAaC,CACpB,CACF,EAcA,SAAgBC,EAAS,EAA0B,CACjD,OAAOC,EAAgBC,CAAI,CAAC,CAAC,IAAK,GAAWC,EAAO,KAAK,CAC3D,CAGA,SAAgBF,EAAgB,EAA2B,CACzD,IAAMG,EAAuB,CAAC,EAC1BC,EAAkB,CAAC,EACnBC,EAAQ,GACRC,EAAyD,QACzDC,EAAW,GACXT,EAAa,EACbU,EAAmB,EACnBC,EAAQ,EACNC,EAAUT,EAAK,WAAW,GAAQ,EAAIA,EAAK,MAAM,CAAC,EAAIA,EAEtDU,MAAuB,CAC3BP,EAAM,KAAKC,CAAK,EAChB,EAAQ,GACR,EAAa,OACf,EAEA,KAAOI,EAAQC,EAAQ,QAAQ,CAC7B,IAAME,EAAOF,EAAQD,GACrB,GAAIH,IAAe,SAAU,CAC3B,GAAIM,IAAS,IAAK,CAChB,GAAIF,EAAQD,EAAQ,KAAO,IAAK,CAC9B,GAAS,IACT,GAAS,EACT,QACF,CACA,EAAa,QACf,MACMG,IAAS;GAASA,IAAS,MAAQF,EAAQD,EAAQ,KAAO;IAAO,IACrE,GAASG,EAEX,GAEF,KAEA,CACA,GADA,EAAW,GACPA,IAAS,KAAOA,IAAS;GAAQA,IAAS,KAC5CD,EAAS,EACLC,IAAS,MACXT,EAAQ,KAAK,CAAE,QAAO,WAAYK,CAAiB,CAAC,EACpD,EAAQ,CAAC,EACT,EAAW,GACPI,IAAS,MAAQF,EAAQD,EAAQ,KAAO;GAAM,IAClD,IACA,EAAmBX,QAEhB,GAAIc,IAAS,IAAK,CACvB,GAAIN,IAAe,QAAS,MAAM,IAAIV,EAAc,mBAAoBE,CAAU,EAClF,EAAa,QACf,MAAO,GAAIQ,IAAe,SACxB,MAAM,IAAIV,EAAc,0BAA2BE,CAAU,MAE7D,GAAa,WACb,GAASc,EAEX,GApBW,CAqBb,CAEA,GAAIN,IAAe,SAAU,MAAM,IAAIV,EAAc,qBAAsBY,CAAgB,EAK3F,OAJID,IACFI,EAAS,EACTR,EAAQ,KAAK,CAAE,QAAO,WAAYK,CAAiB,CAAC,GAE/CL,CACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readOutputFiles.cjs","names":["fs","path","encodeFileForTestCaseResult","require_runtime","require_printTestCaseResult","node_fs","node_path","readOutputFiles","outputFiles","filePath","outputFilePaths","buffer","cwd"],"sources":["../../src/helpers/readOutputFiles.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { TestCaseResult } from '../types/testCaseResult.js';\
|
|
1
|
+
{"version":3,"file":"readOutputFiles.cjs","names":["fs","path","encodeFileForTestCaseResult","require_runtime","require_printTestCaseResult","node_fs","node_path","readOutputFiles","outputFiles","filePath","outputFilePaths","buffer","cwd"],"sources":["../../src/helpers/readOutputFiles.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { TestCaseResult } from '../types/testCaseResult.js';\nimport { encodeFileForTestCaseResult } from './printTestCaseResult.js';\n\nexport async function readOutputFiles(\n cwd: string,\n outputFilePaths: readonly string[]\n): Promise<NonNullable<TestCaseResult['outputFiles']>> {\n const outputFiles: NonNullable<TestCaseResult['outputFiles']> = [];\n for (const filePath of outputFilePaths) {\n try {\n // Read as-is on purpose: the submission runs as the same OS user as this harness, so a symlink\n // only reaches what it can already read, and a planted FIFO only stalls its own run, which the\n // judge server's request timeout ends.\n const buffer = await fs.promises.readFile(path.join(cwd, filePath));\n outputFiles.push(encodeFileForTestCaseResult(filePath, buffer));\n } catch {\n // file not found\n }\n }\n return outputFiles;\n}\n"],"mappings":"+LAMA,eAAsBO,EACpB,EACA,EACqD,CACrD,IAAMC,EAA0D,CAAC,EACjE,IAAK,IAAMC,KAAYC,EACrB,GAAI,CAIF,IAAMC,EAAS,MAAMX,EAAAA,QAAG,SAAS,SAASC,EAAAA,QAAK,KAAKW,EAAKH,CAAQ,CAAC,EAClED,EAAY,KAAKN,EAAAA,4BAA4BO,EAAUE,CAAM,CAAC,CAChE,MAAQ,CAER,CAEF,OAAOH,CACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readOutputFiles.js","names":["fs","path","readOutputFiles","outputFiles","filePath","outputFilePaths","buffer","cwd","encodeFileForTestCaseResult"],"sources":["../../src/helpers/readOutputFiles.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { TestCaseResult } from '../types/testCaseResult.js';\
|
|
1
|
+
{"version":3,"file":"readOutputFiles.js","names":["fs","path","readOutputFiles","outputFiles","filePath","outputFilePaths","buffer","cwd","encodeFileForTestCaseResult"],"sources":["../../src/helpers/readOutputFiles.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { TestCaseResult } from '../types/testCaseResult.js';\nimport { encodeFileForTestCaseResult } from './printTestCaseResult.js';\n\nexport async function readOutputFiles(\n cwd: string,\n outputFilePaths: readonly string[]\n): Promise<NonNullable<TestCaseResult['outputFiles']>> {\n const outputFiles: NonNullable<TestCaseResult['outputFiles']> = [];\n for (const filePath of outputFilePaths) {\n try {\n // Read as-is on purpose: the submission runs as the same OS user as this harness, so a symlink\n // only reaches what it can already read, and a planted FIFO only stalls its own run, which the\n // judge server's request timeout ends.\n const buffer = await fs.promises.readFile(path.join(cwd, filePath));\n outputFiles.push(encodeFileForTestCaseResult(filePath, buffer));\n } catch {\n // file not found\n }\n }\n return outputFiles;\n}\n"],"mappings":"uHAMA,eAAsBE,EACpB,EACA,EACqD,CACrD,IAAMC,EAA0D,CAAC,EACjE,IAAK,IAAMC,KAAYC,EACrB,GAAI,CAIF,IAAMC,EAAS,MAAMN,EAAG,SAAS,SAASC,EAAK,KAAKM,EAAKH,CAAQ,CAAC,EAClED,EAAY,KAAKK,EAA4BJ,EAAUE,CAAM,CAAC,CAChE,MAAQ,CAER,CAEF,OAAOH,CACT"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";function e(e,t){return n(e,t,{removeStrings:!1})}function t(e,t){return n(e,t,{removeStrings:!0})}function n(e,t,n,a=r(e)){if(!e.comments?.length&&(!n.removeStrings||!e.strings?.length))return t;let s=[],c=0;for(;c<t.length;){let r;for(let e of a){let a=e.openRegExp;a.lastIndex=c;let o=a.exec(t);o&&i(o,e,r,n)&&(r={grammar:e,match:o})}if(r){let i=r.match.index;if(!r.grammar.isComment&&n.removeStrings&&(i=d(t,r.match.index)),s.push(t.slice(c,i)),r.grammar.isComment){let e=r.grammar.closeRegExp;e.lastIndex=r.match.index+r.match[0].length;let n=e.exec(t);c=n?n.index+n[0].length:t.length}else{c=o(t,r.match.index,r.grammar);let i=t.slice(r.match.index,c);n.removeStrings?s.push(p(e,a,r.grammar,t,r.match.index,i)):s.push(i)}}else s.push(t.slice(c)),c=t.length}return s.join(``)}function r(e){return[...e.comments?.map(e=>({closeRegExp:a(e.close??/(?=\n)/g),isComment:!0,openRegExp:a(e.open)}))??[],...e.strings?.map(e=>({closeRegExp:a(e.close),isComment:!1,openRegExp:a(e.open),templateSyntax:e.templateSyntax}))??[]]}function i(e,t,n,r){return!n||e.index<n.match.index?!0:e.index>n.match.index?!1:r.removeStrings&&n.grammar.isComment&&!t.isComment}function a(e){return new RegExp(e,e.flags.includes(`g`)?e.flags:`${e.flags}g`)}function o(e,t,n){if(n.templateSyntax===`kotlin`)return s(e,t);if(e[t]==="`")return c(e,t);if(_(e,t))return l(e,t);let r=n.closeRegExp;r.lastIndex=t+1;let i=r.exec(e);return i?i.index+i[0].length:e.length}function s(e,t){let n=u(e,t),r=n.length===3,i=t+n.length;for(;i<e.length;){if(e.startsWith(n,i))return i+n.length
|
|
2
|
-
`)}function h(e){return e!==void 0&&/[\p{L}_]/u.test(e)}function g(e){return e!==void 0&&/[\p{L}\p{N}_]/u.test(e)}function _(e,t){return f(e,t)?.toLowerCase().includes(`f`)??!1}function v(e,t,r){let i=[],a=1;for(;a<r.length-1;)
|
|
3
|
-
`)}function y(e,t,r){let i=u(r,0).length,a=[],o=i;for(;o<r.length-i;)
|
|
4
|
-
`)}function b(e,t,n,r){let i=1,a=t;for(;a<e.length;){let o=e[a];if(o===`"`&&r.supportsKotlinStrings)
|
|
1
|
+
"use strict";function e(e,t){return n(e,t,{removeStrings:!1})}function t(e,t){return n(e,t,{removeStrings:!0})}function n(e,t,n,a=r(e)){if(!e.comments?.length&&(!n.removeStrings||!e.strings?.length))return t;let s=[],c=0;for(;c<t.length;){let r;for(let e of a){let a=e.openRegExp;a.lastIndex=c;let o=a.exec(t);o&&i(o,e,r,n)&&(r={grammar:e,match:o})}if(r){let i=r.match.index;if(!r.grammar.isComment&&n.removeStrings&&(i=d(t,r.match.index)),s.push(t.slice(c,i)),r.grammar.isComment){let e=r.grammar.closeRegExp;e.lastIndex=r.match.index+r.match[0].length;let n=e.exec(t);c=n?n.index+n[0].length:t.length}else{c=o(t,r.match.index,r.grammar);let i=t.slice(r.match.index,c);n.removeStrings?s.push(p(e,a,r.grammar,t,r.match.index,i)):s.push(i)}}else s.push(t.slice(c)),c=t.length}return s.join(``)}function r(e){return[...e.comments?.map(e=>({closeRegExp:a(e.close??/(?=\n)/g),isComment:!0,openRegExp:a(e.open)}))??[],...e.strings?.map(e=>({closeRegExp:a(e.close),isComment:!1,openRegExp:a(e.open),templateSyntax:e.templateSyntax}))??[]]}function i(e,t,n,r){return!n||e.index<n.match.index?!0:e.index>n.match.index?!1:r.removeStrings&&n.grammar.isComment&&!t.isComment}function a(e){return new RegExp(e,e.flags.includes(`g`)?e.flags:`${e.flags}g`)}function o(e,t,n){if(n.templateSyntax===`kotlin`)return s(e,t);if(e[t]==="`")return c(e,t);if(_(e,t))return l(e,t);let r=n.closeRegExp;r.lastIndex=t+1;let i=r.exec(e);return i?i.index+i[0].length:e.length}function s(e,t){let n=u(e,t),r=n.length===3,i=t+n.length;for(;i<e.length;){if(e.startsWith(n,i))return i+n.length;!r&&e[i]===`\\`?i+=2:e[i]===`$`&&e[i+1]===`{`?i=b(e,i+2,`}`,{slashStartsComments:!0,slashStartsRegExp:!1,supportsKotlinStrings:!0}).endIndex+1:i+=1}return e.length}function c(e,t){let n=t+1;for(;n<e.length;)if(e[n]===`\\`)n+=2;else{if(e[n]==="`")return n+1;e[n]===`$`&&e[n+1]===`{`?n=b(e,n+2,`}`,{slashStartsRegExp:!0}).endIndex+1:n+=1}return e.length}function l(e,t){let n=u(e,t),r=t+n.length;for(;r<e.length;){if(e.startsWith(n,r))return r+n.length;e[r]===`{`&&e[r+1]===`{`?r+=2:e[r]===`{`?r=b(e,r+1,`}`,{slashStartsRegExp:!1}).endIndex+1:r+=e[r]===`\\`?2:1}return e.length}function u(e,t){let n=e.slice(t,t+3);return n===`'''`||n===`"""`?n:e[t]??``}function d(e,t){let n=f(e,t);return n?t-n.length:t}function f(e,t){if(e[t]!==`"`&&e[t]!==`'`)return;let n=t-1;for(;n>=0&&/[A-Za-z]/.test(e[n]??``);)--n;let r=e.slice(n+1,t);if(r&&/^[bfru]+$/i.test(r)&&!(n>=0&&/[\dA-Za-z_]/.test(e[n]??``)))return r}function p(e,t,n,r,i,a){return n.templateSyntax===`kotlin`?m(e,t,a):a.startsWith("`")?v(e,t,a):_(r,i)?y(e,t,a):``}function m(e,t,r){let i=u(r,0).length,a=i===3,o=[],s=i;for(;s<r.length-i;)if(!a&&r[s]===`\\`)s+=2;else if(r[s]!==`$`)s+=1;else if(r[s+1]===`{`){let i=b(r,s+2,`}`,{slashStartsComments:!0,slashStartsRegExp:!1,supportsKotlinStrings:!0});o.push(n(e,i.content,{removeStrings:!0},t)),s=i.endIndex+1}else if(h(r[s+1])){let e=s+2;for(;g(r[e]);)e+=1;o.push(r.slice(s+1,e)),s=e}else s+=1;return o.join(`
|
|
2
|
+
`)}function h(e){return e!==void 0&&/[\p{L}_]/u.test(e)}function g(e){return e!==void 0&&/[\p{L}\p{N}_]/u.test(e)}function _(e,t){return f(e,t)?.toLowerCase().includes(`f`)??!1}function v(e,t,r){let i=[],a=1;for(;a<r.length-1;)if(r[a]===`\\`)a+=2;else if(r[a]===`$`&&r[a+1]===`{`){let o=b(r,a+2,`}`,{slashStartsRegExp:!0});i.push(n(e,o.content,{removeStrings:!0},t)),a=o.endIndex+1}else a+=1;return i.join(`
|
|
3
|
+
`)}function y(e,t,r){let i=u(r,0).length,a=[],o=i;for(;o<r.length-i;)if(r[o]===`{`&&r[o+1]===`{`)o+=2;else if(r[o]===`{`){let i=b(r,o+1,`}`,{slashStartsRegExp:!1});a.push(n(e,i.content,{removeStrings:!0},t)),o=i.endIndex+1}else o+=r[o]===`\\`?2:1;return a.join(`
|
|
4
|
+
`)}function b(e,t,n,r){let i=1,a=t;for(;a<e.length;){let o=e[a];if(o===`"`&&r.supportsKotlinStrings)a=s(e,a);else if(o===`"`||o===`'`||o==="`")a=x(e,a);else if((r.slashStartsComments||r.slashStartsRegExp)&&e[a]===`/`&&e[a+1]===`/`)a=C(e,a);else if((r.slashStartsComments||r.slashStartsRegExp)&&e[a]===`/`&&e[a+1]===`*`)a=w(e,a);else if(r.slashStartsRegExp&&o===`/`)a=S(e,a);else{if(o===`{`&&(i+=1),o===n&&(--i,i===0))return{content:e.slice(t,a),endIndex:a};a+=1}}return{content:e.slice(t),endIndex:e.length}}function x(e,t){let n=u(e,t),r=t+n.length;for(;r<e.length;)if(e[r]===`\\`)r+=2;else{if(e.startsWith(n,r))return r+n.length;r+=1}return r}function S(e,t){let n=t+1,r=!1;for(;n<e.length;)if(e[n]===`\\`)n+=2;else{if(e[n]===`[`&&(r=!0),e[n]===`]`&&(r=!1),e[n]===`/`&&!r){for(n+=1;/[A-Za-z]/.test(e[n]??``);)n+=1;return n}if(e[n]===`
|
|
5
5
|
`)return t+1;n+=1}return t+1}function C(e,t){let n=e.indexOf(`
|
|
6
6
|
`,t+2);return n===-1?e.length:n}function w(e,t){let n=e.indexOf(`*/`,t+2);return n===-1?e.length:n+2}exports.removeCommentsAndStringsInSourceCode=t,exports.removeCommentsInSourceCode=e;
|
|
7
7
|
//# sourceMappingURL=removeCommentsInSourceCode.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeCommentsInSourceCode.cjs","names":["removeCommentsInSourceCode","removeCommentsAndMaybeStringsInSourceCode","grammar","sourceCode","removeCommentsAndStringsInSourceCode","compileCommentOrStringGrammars","options","newSourceCodeSlices","lastIndex","first","commentOrStringGrammer","commentOrStringGrammars","startRegExp","match","shouldPreferMatch","stringPrefixStartIndex","getPythonStringPrefixStartIndex","closeRegExp","findStringEndIndex","stringLiteral","preserveStringInterpolationExpressions","makeGlobalRegExp","v","regExp","findKotlinStringEndIndex","stringStartIndex","findJavaScriptTemplateEndIndex","hasPythonFStringPrefix","findPythonFStringEndIndex","quote","getStringQuote","isRawString","index","readBalancedExpression","threeCharacterQuote","prefix","getPythonStringPrefix","stringGrammar","preserveKotlinStringTemplateExpressions","preserveJavaScriptTemplateExpressions","preservePythonFStringExpressions","quoteLength","expressions","expression","isKotlinIdentifierStart","endIndex","isKotlinIdentifierPart","character","depth","startIndex","char","skipQuotedSpan","skipJavaScriptSingleLineComment","skipJavaScriptBlockComment","skipJavaScriptRegExpLiteral","closeChar","inCharacterClass","newLineIndex"],"sources":["../../src/helpers/removeCommentsInSourceCode.ts"],"sourcesContent":["import type { LanguageDefinition } from '../types/language.js';\n\nexport type SourceCodeGrammar = NonNullable<LanguageDefinition['grammer']>;\n\n/** Removes comments from source code according to the provided language grammar. */\nexport function removeCommentsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: false });\n}\n\n/** Removes comments and string literal contents while preserving executable interpolation expressions. */\nexport function removeCommentsAndStringsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: true });\n}\n\ninterface CommentOrStringGrammar {\n closeRegExp: RegExp;\n isComment: boolean;\n openRegExp: RegExp;\n templateSyntax?: 'kotlin';\n}\n\ninterface BalancedExpressionOptions {\n slashStartsComments?: boolean;\n slashStartsRegExp: boolean;\n supportsKotlinStrings?: boolean;\n}\n\nfunction removeCommentsAndMaybeStringsInSourceCode(\n grammar: SourceCodeGrammar,\n sourceCode: string,\n options: { removeStrings: boolean },\n commentOrStringGrammars = compileCommentOrStringGrammars(grammar)\n): string {\n if (!grammar.comments?.length && (!options.removeStrings || !grammar.strings?.length)) return sourceCode;\n\n const newSourceCodeSlices: string[] = [];\n\n let lastIndex = 0;\n\n while (lastIndex < sourceCode.length) {\n let first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined;\n\n for (const commentOrStringGrammer of commentOrStringGrammars) {\n const startRegExp = commentOrStringGrammer.openRegExp;\n startRegExp.lastIndex = lastIndex;\n\n const match = startRegExp.exec(sourceCode);\n\n if (match && shouldPreferMatch(match, commentOrStringGrammer, first, options)) {\n first = { grammar: commentOrStringGrammer, match };\n }\n }\n\n if (first) {\n let stringPrefixStartIndex = first.match.index;\n if (!first.grammar.isComment && options.removeStrings) {\n stringPrefixStartIndex = getPythonStringPrefixStartIndex(sourceCode, first.match.index);\n }\n newSourceCodeSlices.push(sourceCode.slice(lastIndex, stringPrefixStartIndex));\n\n if (!first.grammar.isComment) {\n lastIndex = findStringEndIndex(sourceCode, first.match.index, first.grammar);\n const stringLiteral = sourceCode.slice(first.match.index, lastIndex);\n if (options.removeStrings) {\n newSourceCodeSlices.push(\n preserveStringInterpolationExpressions(\n grammar,\n commentOrStringGrammars,\n first.grammar,\n sourceCode,\n first.match.index,\n stringLiteral\n )\n );\n } else {\n newSourceCodeSlices.push(stringLiteral);\n }\n } else {\n const closeRegExp = first.grammar.closeRegExp;\n closeRegExp.lastIndex = first.match.index + first.match[0].length;\n\n const match = closeRegExp.exec(sourceCode);\n\n lastIndex = match ? match.index + match[0].length : sourceCode.length;\n }\n } else {\n newSourceCodeSlices.push(sourceCode.slice(lastIndex));\n lastIndex = sourceCode.length;\n }\n }\n\n return newSourceCodeSlices.join('');\n}\n\nfunction compileCommentOrStringGrammars(grammar: SourceCodeGrammar): readonly CommentOrStringGrammar[] {\n return [\n ...(grammar.comments?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close ?? /(?=\\n)/g),\n isComment: true,\n openRegExp: makeGlobalRegExp(v.open),\n })) ?? []),\n ...(grammar.strings?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close),\n isComment: false,\n openRegExp: makeGlobalRegExp(v.open),\n templateSyntax: v.templateSyntax,\n })) ?? []),\n ] satisfies CommentOrStringGrammar[];\n}\n\nfunction shouldPreferMatch(\n match: RegExpExecArray,\n grammar: CommentOrStringGrammar,\n first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined,\n options: { removeStrings: boolean }\n): boolean {\n if (!first) return true;\n if (match.index < first.match.index) return true;\n if (match.index > first.match.index) return false;\n return options.removeStrings && first.grammar.isComment && !grammar.isComment;\n}\n\nfunction makeGlobalRegExp(regExp: RegExp): RegExp {\n return new RegExp(regExp, regExp.flags.includes('g') ? regExp.flags : `${regExp.flags}g`);\n}\n\nfunction findStringEndIndex(sourceCode: string, stringStartIndex: number, grammar: CommentOrStringGrammar): number {\n if (grammar.templateSyntax === 'kotlin') return findKotlinStringEndIndex(sourceCode, stringStartIndex);\n if (sourceCode[stringStartIndex] === '`') return findJavaScriptTemplateEndIndex(sourceCode, stringStartIndex);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return findPythonFStringEndIndex(sourceCode, stringStartIndex);\n\n const closeRegExp = grammar.closeRegExp;\n closeRegExp.lastIndex = stringStartIndex + 1;\n const match = closeRegExp.exec(sourceCode);\n return match ? match.index + match[0].length : sourceCode.length;\n}\n\nfunction findKotlinStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n const isRawString = quote.length === 3;\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (!isRawString && sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index =\n readBalancedExpression(sourceCode, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findJavaScriptTemplateEndIndex(sourceCode: string, stringStartIndex: number): number {\n let index = stringStartIndex + 1;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '`') return index + 1;\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index = readBalancedExpression(sourceCode, index + 2, '}', { slashStartsRegExp: true }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findPythonFStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (sourceCode[index] === '{' && sourceCode[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '{') {\n index = readBalancedExpression(sourceCode, index + 1, '}', { slashStartsRegExp: false }).endIndex + 1;\n continue;\n }\n index += sourceCode[index] === '\\\\' ? 2 : 1;\n }\n\n return sourceCode.length;\n}\n\nfunction getStringQuote(sourceCode: string, stringStartIndex: number): string {\n const threeCharacterQuote = sourceCode.slice(stringStartIndex, stringStartIndex + 3);\n if (threeCharacterQuote === \"'''\" || threeCharacterQuote === '\"\"\"') return threeCharacterQuote;\n return sourceCode[stringStartIndex] ?? '';\n}\n\nfunction getPythonStringPrefixStartIndex(sourceCode: string, stringStartIndex: number): number {\n const prefix = getPythonStringPrefix(sourceCode, stringStartIndex);\n return prefix ? stringStartIndex - prefix.length : stringStartIndex;\n}\n\nfunction getPythonStringPrefix(sourceCode: string, stringStartIndex: number): string | undefined {\n if (sourceCode[stringStartIndex] !== '\"' && sourceCode[stringStartIndex] !== \"'\") return undefined;\n let index = stringStartIndex - 1;\n while (index >= 0 && /[A-Za-z]/.test(sourceCode[index] ?? '')) index -= 1;\n\n const prefix = sourceCode.slice(index + 1, stringStartIndex);\n if (!prefix || !/^[bfru]+$/i.test(prefix)) return undefined;\n if (index >= 0 && /[\\dA-Za-z_]/.test(sourceCode[index] ?? '')) return undefined;\n\n return prefix;\n}\n\nfunction preserveStringInterpolationExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringGrammar: CommentOrStringGrammar,\n sourceCode: string,\n stringStartIndex: number,\n stringLiteral: string\n): string {\n if (stringGrammar.templateSyntax === 'kotlin')\n return preserveKotlinStringTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (stringLiteral.startsWith('`'))\n return preserveJavaScriptTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return preservePythonFStringExpressions(grammar, commentOrStringGrammars, stringLiteral);\n return '';\n}\n\nfunction preserveKotlinStringTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const isRawString = quoteLength === 3;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (!isRawString && stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] !== '$') {\n index += 1;\n continue;\n }\n if (stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n if (isKotlinIdentifierStart(stringLiteral[index + 1])) {\n let endIndex = index + 2;\n while (isKotlinIdentifierPart(stringLiteral[endIndex])) endIndex += 1;\n expressions.push(stringLiteral.slice(index + 1, endIndex));\n index = endIndex;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction isKotlinIdentifierStart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}_]/u.test(character);\n}\n\nfunction isKotlinIdentifierPart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}\\p{N}_]/u.test(character);\n}\n\nfunction hasPythonFStringPrefix(sourceCode: string, stringStartIndex: number): boolean {\n return getPythonStringPrefix(sourceCode, stringStartIndex)?.toLowerCase().includes('f') ?? false;\n}\n\nfunction preserveJavaScriptTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const expressions: string[] = [];\n let index = 1;\n\n while (index < stringLiteral.length - 1) {\n if (stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '$' && stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', { slashStartsRegExp: true });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction preservePythonFStringExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (stringLiteral[index] === '{' && stringLiteral[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 1, '}', { slashStartsRegExp: false });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += stringLiteral[index] === '\\\\' ? 2 : 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction readBalancedExpression(\n sourceCode: string,\n startIndex: number,\n closeChar: string,\n options: BalancedExpressionOptions\n): { content: string; endIndex: number } {\n let depth = 1;\n let index = startIndex;\n\n while (index < sourceCode.length) {\n const char = sourceCode[index];\n if (char === '\"' && options.supportsKotlinStrings) {\n index = findKotlinStringEndIndex(sourceCode, index);\n continue;\n }\n if (char === '\"' || char === \"'\" || char === '`') {\n index = skipQuotedSpan(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '/'\n ) {\n index = skipJavaScriptSingleLineComment(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '*'\n ) {\n index = skipJavaScriptBlockComment(sourceCode, index);\n continue;\n }\n if (options.slashStartsRegExp && char === '/') {\n index = skipJavaScriptRegExpLiteral(sourceCode, index);\n continue;\n }\n if (char === '{') depth += 1;\n if (char === closeChar) {\n depth -= 1;\n if (depth === 0) return { content: sourceCode.slice(startIndex, index), endIndex: index };\n }\n index += 1;\n }\n\n return { content: sourceCode.slice(startIndex), endIndex: sourceCode.length };\n}\n\nfunction skipQuotedSpan(sourceCode: string, startIndex: number): number {\n const quote = getStringQuote(sourceCode, startIndex);\n let index = startIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n index += 1;\n }\n\n return index;\n}\n\nfunction skipJavaScriptRegExpLiteral(sourceCode: string, startIndex: number): number {\n let index = startIndex + 1;\n let inCharacterClass = false;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '[') inCharacterClass = true;\n if (sourceCode[index] === ']') inCharacterClass = false;\n if (sourceCode[index] === '/' && !inCharacterClass) {\n index += 1;\n while (/[A-Za-z]/.test(sourceCode[index] ?? '')) index += 1;\n return index;\n }\n if (sourceCode[index] === '\\n') return startIndex + 1;\n index += 1;\n }\n\n return startIndex + 1;\n}\n\nfunction skipJavaScriptSingleLineComment(sourceCode: string, startIndex: number): number {\n const newLineIndex = sourceCode.indexOf('\\n', startIndex + 2);\n return newLineIndex === -1 ? sourceCode.length : newLineIndex;\n}\n\nfunction skipJavaScriptBlockComment(sourceCode: string, startIndex: number): number {\n const endIndex = sourceCode.indexOf('*/', startIndex + 2);\n return endIndex === -1 ? sourceCode.length : endIndex + 2;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"removeCommentsInSourceCode.cjs","names":["removeCommentsInSourceCode","removeCommentsAndMaybeStringsInSourceCode","grammar","sourceCode","removeCommentsAndStringsInSourceCode","compileCommentOrStringGrammars","options","newSourceCodeSlices","lastIndex","first","commentOrStringGrammer","commentOrStringGrammars","startRegExp","match","shouldPreferMatch","stringPrefixStartIndex","getPythonStringPrefixStartIndex","closeRegExp","findStringEndIndex","stringLiteral","preserveStringInterpolationExpressions","makeGlobalRegExp","v","regExp","findKotlinStringEndIndex","stringStartIndex","findJavaScriptTemplateEndIndex","hasPythonFStringPrefix","findPythonFStringEndIndex","quote","getStringQuote","isRawString","index","readBalancedExpression","threeCharacterQuote","prefix","getPythonStringPrefix","stringGrammar","preserveKotlinStringTemplateExpressions","preserveJavaScriptTemplateExpressions","preservePythonFStringExpressions","quoteLength","expressions","expression","isKotlinIdentifierStart","endIndex","isKotlinIdentifierPart","character","depth","startIndex","char","skipQuotedSpan","skipJavaScriptSingleLineComment","skipJavaScriptBlockComment","skipJavaScriptRegExpLiteral","closeChar","inCharacterClass","newLineIndex"],"sources":["../../src/helpers/removeCommentsInSourceCode.ts"],"sourcesContent":["import type { LanguageDefinition } from '../types/language.js';\n\nexport type SourceCodeGrammar = NonNullable<LanguageDefinition['grammer']>;\n\n/** Removes comments from source code according to the provided language grammar. */\nexport function removeCommentsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: false });\n}\n\n/** Removes comments and string literal contents while preserving executable interpolation expressions. */\nexport function removeCommentsAndStringsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: true });\n}\n\ninterface CommentOrStringGrammar {\n closeRegExp: RegExp;\n isComment: boolean;\n openRegExp: RegExp;\n templateSyntax?: 'kotlin';\n}\n\ninterface BalancedExpressionOptions {\n slashStartsComments?: boolean;\n slashStartsRegExp: boolean;\n supportsKotlinStrings?: boolean;\n}\n\nfunction removeCommentsAndMaybeStringsInSourceCode(\n grammar: SourceCodeGrammar,\n sourceCode: string,\n options: { removeStrings: boolean },\n commentOrStringGrammars = compileCommentOrStringGrammars(grammar)\n): string {\n if (!grammar.comments?.length && (!options.removeStrings || !grammar.strings?.length)) return sourceCode;\n\n const newSourceCodeSlices: string[] = [];\n\n let lastIndex = 0;\n\n while (lastIndex < sourceCode.length) {\n let first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined;\n\n for (const commentOrStringGrammer of commentOrStringGrammars) {\n const startRegExp = commentOrStringGrammer.openRegExp;\n startRegExp.lastIndex = lastIndex;\n\n const match = startRegExp.exec(sourceCode);\n\n if (match && shouldPreferMatch(match, commentOrStringGrammer, first, options)) {\n first = { grammar: commentOrStringGrammer, match };\n }\n }\n\n if (first) {\n let stringPrefixStartIndex = first.match.index;\n if (!first.grammar.isComment && options.removeStrings) {\n stringPrefixStartIndex = getPythonStringPrefixStartIndex(sourceCode, first.match.index);\n }\n newSourceCodeSlices.push(sourceCode.slice(lastIndex, stringPrefixStartIndex));\n\n if (!first.grammar.isComment) {\n lastIndex = findStringEndIndex(sourceCode, first.match.index, first.grammar);\n const stringLiteral = sourceCode.slice(first.match.index, lastIndex);\n if (options.removeStrings) {\n newSourceCodeSlices.push(\n preserveStringInterpolationExpressions(\n grammar,\n commentOrStringGrammars,\n first.grammar,\n sourceCode,\n first.match.index,\n stringLiteral\n )\n );\n } else {\n newSourceCodeSlices.push(stringLiteral);\n }\n } else {\n const closeRegExp = first.grammar.closeRegExp;\n closeRegExp.lastIndex = first.match.index + first.match[0].length;\n\n const match = closeRegExp.exec(sourceCode);\n\n lastIndex = match ? match.index + match[0].length : sourceCode.length;\n }\n } else {\n newSourceCodeSlices.push(sourceCode.slice(lastIndex));\n lastIndex = sourceCode.length;\n }\n }\n\n return newSourceCodeSlices.join('');\n}\n\nfunction compileCommentOrStringGrammars(grammar: SourceCodeGrammar): readonly CommentOrStringGrammar[] {\n return [\n ...(grammar.comments?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close ?? /(?=\\n)/g),\n isComment: true,\n openRegExp: makeGlobalRegExp(v.open),\n })) ?? []),\n ...(grammar.strings?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close),\n isComment: false,\n openRegExp: makeGlobalRegExp(v.open),\n templateSyntax: v.templateSyntax,\n })) ?? []),\n ] satisfies CommentOrStringGrammar[];\n}\n\nfunction shouldPreferMatch(\n match: RegExpExecArray,\n grammar: CommentOrStringGrammar,\n first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined,\n options: { removeStrings: boolean }\n): boolean {\n if (!first) return true;\n if (match.index < first.match.index) return true;\n if (match.index > first.match.index) return false;\n return options.removeStrings && first.grammar.isComment && !grammar.isComment;\n}\n\nfunction makeGlobalRegExp(regExp: RegExp): RegExp {\n return new RegExp(regExp, regExp.flags.includes('g') ? regExp.flags : `${regExp.flags}g`);\n}\n\nfunction findStringEndIndex(sourceCode: string, stringStartIndex: number, grammar: CommentOrStringGrammar): number {\n if (grammar.templateSyntax === 'kotlin') return findKotlinStringEndIndex(sourceCode, stringStartIndex);\n if (sourceCode[stringStartIndex] === '`') return findJavaScriptTemplateEndIndex(sourceCode, stringStartIndex);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return findPythonFStringEndIndex(sourceCode, stringStartIndex);\n\n const closeRegExp = grammar.closeRegExp;\n closeRegExp.lastIndex = stringStartIndex + 1;\n const match = closeRegExp.exec(sourceCode);\n return match ? match.index + match[0].length : sourceCode.length;\n}\n\nfunction findKotlinStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n const isRawString = quote.length === 3;\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (!isRawString && sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index =\n readBalancedExpression(sourceCode, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findJavaScriptTemplateEndIndex(sourceCode: string, stringStartIndex: number): number {\n let index = stringStartIndex + 1;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '`') return index + 1;\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index = readBalancedExpression(sourceCode, index + 2, '}', { slashStartsRegExp: true }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findPythonFStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (sourceCode[index] === '{' && sourceCode[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '{') {\n index = readBalancedExpression(sourceCode, index + 1, '}', { slashStartsRegExp: false }).endIndex + 1;\n continue;\n }\n index += sourceCode[index] === '\\\\' ? 2 : 1;\n }\n\n return sourceCode.length;\n}\n\nfunction getStringQuote(sourceCode: string, stringStartIndex: number): string {\n const threeCharacterQuote = sourceCode.slice(stringStartIndex, stringStartIndex + 3);\n if (threeCharacterQuote === \"'''\" || threeCharacterQuote === '\"\"\"') return threeCharacterQuote;\n return sourceCode[stringStartIndex] ?? '';\n}\n\nfunction getPythonStringPrefixStartIndex(sourceCode: string, stringStartIndex: number): number {\n const prefix = getPythonStringPrefix(sourceCode, stringStartIndex);\n return prefix ? stringStartIndex - prefix.length : stringStartIndex;\n}\n\nfunction getPythonStringPrefix(sourceCode: string, stringStartIndex: number): string | undefined {\n if (sourceCode[stringStartIndex] !== '\"' && sourceCode[stringStartIndex] !== \"'\") return undefined;\n let index = stringStartIndex - 1;\n while (index >= 0 && /[A-Za-z]/.test(sourceCode[index] ?? '')) index -= 1;\n\n const prefix = sourceCode.slice(index + 1, stringStartIndex);\n if (!prefix || !/^[bfru]+$/i.test(prefix)) return undefined;\n if (index >= 0 && /[\\dA-Za-z_]/.test(sourceCode[index] ?? '')) return undefined;\n\n return prefix;\n}\n\nfunction preserveStringInterpolationExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringGrammar: CommentOrStringGrammar,\n sourceCode: string,\n stringStartIndex: number,\n stringLiteral: string\n): string {\n if (stringGrammar.templateSyntax === 'kotlin')\n return preserveKotlinStringTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (stringLiteral.startsWith('`'))\n return preserveJavaScriptTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return preservePythonFStringExpressions(grammar, commentOrStringGrammars, stringLiteral);\n return '';\n}\n\nfunction preserveKotlinStringTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const isRawString = quoteLength === 3;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (!isRawString && stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] !== '$') {\n index += 1;\n continue;\n }\n if (stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n if (isKotlinIdentifierStart(stringLiteral[index + 1])) {\n let endIndex = index + 2;\n while (isKotlinIdentifierPart(stringLiteral[endIndex])) endIndex += 1;\n expressions.push(stringLiteral.slice(index + 1, endIndex));\n index = endIndex;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction isKotlinIdentifierStart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}_]/u.test(character);\n}\n\nfunction isKotlinIdentifierPart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}\\p{N}_]/u.test(character);\n}\n\nfunction hasPythonFStringPrefix(sourceCode: string, stringStartIndex: number): boolean {\n return getPythonStringPrefix(sourceCode, stringStartIndex)?.toLowerCase().includes('f') ?? false;\n}\n\nfunction preserveJavaScriptTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const expressions: string[] = [];\n let index = 1;\n\n while (index < stringLiteral.length - 1) {\n if (stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '$' && stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', { slashStartsRegExp: true });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction preservePythonFStringExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (stringLiteral[index] === '{' && stringLiteral[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 1, '}', { slashStartsRegExp: false });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += stringLiteral[index] === '\\\\' ? 2 : 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction readBalancedExpression(\n sourceCode: string,\n startIndex: number,\n closeChar: string,\n options: BalancedExpressionOptions\n): { content: string; endIndex: number } {\n let depth = 1;\n let index = startIndex;\n\n while (index < sourceCode.length) {\n const char = sourceCode[index];\n if (char === '\"' && options.supportsKotlinStrings) {\n index = findKotlinStringEndIndex(sourceCode, index);\n continue;\n }\n if (char === '\"' || char === \"'\" || char === '`') {\n index = skipQuotedSpan(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '/'\n ) {\n index = skipJavaScriptSingleLineComment(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '*'\n ) {\n index = skipJavaScriptBlockComment(sourceCode, index);\n continue;\n }\n if (options.slashStartsRegExp && char === '/') {\n index = skipJavaScriptRegExpLiteral(sourceCode, index);\n continue;\n }\n if (char === '{') depth += 1;\n if (char === closeChar) {\n depth -= 1;\n if (depth === 0) return { content: sourceCode.slice(startIndex, index), endIndex: index };\n }\n index += 1;\n }\n\n return { content: sourceCode.slice(startIndex), endIndex: sourceCode.length };\n}\n\nfunction skipQuotedSpan(sourceCode: string, startIndex: number): number {\n const quote = getStringQuote(sourceCode, startIndex);\n let index = startIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n index += 1;\n }\n\n return index;\n}\n\nfunction skipJavaScriptRegExpLiteral(sourceCode: string, startIndex: number): number {\n let index = startIndex + 1;\n let inCharacterClass = false;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '[') inCharacterClass = true;\n if (sourceCode[index] === ']') inCharacterClass = false;\n if (sourceCode[index] === '/' && !inCharacterClass) {\n index += 1;\n while (/[A-Za-z]/.test(sourceCode[index] ?? '')) index += 1;\n return index;\n }\n if (sourceCode[index] === '\\n') return startIndex + 1;\n index += 1;\n }\n\n return startIndex + 1;\n}\n\nfunction skipJavaScriptSingleLineComment(sourceCode: string, startIndex: number): number {\n const newLineIndex = sourceCode.indexOf('\\n', startIndex + 2);\n return newLineIndex === -1 ? sourceCode.length : newLineIndex;\n}\n\nfunction skipJavaScriptBlockComment(sourceCode: string, startIndex: number): number {\n const endIndex = sourceCode.indexOf('*/', startIndex + 2);\n return endIndex === -1 ? sourceCode.length : endIndex + 2;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
function e(e,t){return n(e,t,{removeStrings:!1})}function t(e,t){return n(e,t,{removeStrings:!0})}function n(e,t,n,a=r(e)){if(!e.comments?.length&&(!n.removeStrings||!e.strings?.length))return t;let s=[],c=0;for(;c<t.length;){let r;for(let e of a){let a=e.openRegExp;a.lastIndex=c;let o=a.exec(t);o&&i(o,e,r,n)&&(r={grammar:e,match:o})}if(r){let i=r.match.index;if(!r.grammar.isComment&&n.removeStrings&&(i=d(t,r.match.index)),s.push(t.slice(c,i)),r.grammar.isComment){let e=r.grammar.closeRegExp;e.lastIndex=r.match.index+r.match[0].length;let n=e.exec(t);c=n?n.index+n[0].length:t.length}else{c=o(t,r.match.index,r.grammar);let i=t.slice(r.match.index,c);n.removeStrings?s.push(p(e,a,r.grammar,t,r.match.index,i)):s.push(i)}}else s.push(t.slice(c)),c=t.length}return s.join(``)}function r(e){return[...e.comments?.map(e=>({closeRegExp:a(e.close??/(?=\n)/g),isComment:!0,openRegExp:a(e.open)}))??[],...e.strings?.map(e=>({closeRegExp:a(e.close),isComment:!1,openRegExp:a(e.open),templateSyntax:e.templateSyntax}))??[]]}function i(e,t,n,r){return!n||e.index<n.match.index?!0:e.index>n.match.index?!1:r.removeStrings&&n.grammar.isComment&&!t.isComment}function a(e){return new RegExp(e,e.flags.includes(`g`)?e.flags:`${e.flags}g`)}function o(e,t,n){if(n.templateSyntax===`kotlin`)return s(e,t);if(e[t]==="`")return c(e,t);if(_(e,t))return l(e,t);let r=n.closeRegExp;r.lastIndex=t+1;let i=r.exec(e);return i?i.index+i[0].length:e.length}function s(e,t){let n=u(e,t),r=n.length===3,i=t+n.length;for(;i<e.length;){if(e.startsWith(n,i))return i+n.length
|
|
2
|
-
`)}function h(e){return e!==void 0&&/[\p{L}_]/u.test(e)}function g(e){return e!==void 0&&/[\p{L}\p{N}_]/u.test(e)}function _(e,t){return f(e,t)?.toLowerCase().includes(`f`)??!1}function v(e,t,r){let i=[],a=1;for(;a<r.length-1;)
|
|
3
|
-
`)}function y(e,t,r){let i=u(r,0).length,a=[],o=i;for(;o<r.length-i;)
|
|
4
|
-
`)}function b(e,t,n,r){let i=1,a=t;for(;a<e.length;){let o=e[a];if(o===`"`&&r.supportsKotlinStrings)
|
|
1
|
+
function e(e,t){return n(e,t,{removeStrings:!1})}function t(e,t){return n(e,t,{removeStrings:!0})}function n(e,t,n,a=r(e)){if(!e.comments?.length&&(!n.removeStrings||!e.strings?.length))return t;let s=[],c=0;for(;c<t.length;){let r;for(let e of a){let a=e.openRegExp;a.lastIndex=c;let o=a.exec(t);o&&i(o,e,r,n)&&(r={grammar:e,match:o})}if(r){let i=r.match.index;if(!r.grammar.isComment&&n.removeStrings&&(i=d(t,r.match.index)),s.push(t.slice(c,i)),r.grammar.isComment){let e=r.grammar.closeRegExp;e.lastIndex=r.match.index+r.match[0].length;let n=e.exec(t);c=n?n.index+n[0].length:t.length}else{c=o(t,r.match.index,r.grammar);let i=t.slice(r.match.index,c);n.removeStrings?s.push(p(e,a,r.grammar,t,r.match.index,i)):s.push(i)}}else s.push(t.slice(c)),c=t.length}return s.join(``)}function r(e){return[...e.comments?.map(e=>({closeRegExp:a(e.close??/(?=\n)/g),isComment:!0,openRegExp:a(e.open)}))??[],...e.strings?.map(e=>({closeRegExp:a(e.close),isComment:!1,openRegExp:a(e.open),templateSyntax:e.templateSyntax}))??[]]}function i(e,t,n,r){return!n||e.index<n.match.index?!0:e.index>n.match.index?!1:r.removeStrings&&n.grammar.isComment&&!t.isComment}function a(e){return new RegExp(e,e.flags.includes(`g`)?e.flags:`${e.flags}g`)}function o(e,t,n){if(n.templateSyntax===`kotlin`)return s(e,t);if(e[t]==="`")return c(e,t);if(_(e,t))return l(e,t);let r=n.closeRegExp;r.lastIndex=t+1;let i=r.exec(e);return i?i.index+i[0].length:e.length}function s(e,t){let n=u(e,t),r=n.length===3,i=t+n.length;for(;i<e.length;){if(e.startsWith(n,i))return i+n.length;!r&&e[i]===`\\`?i+=2:e[i]===`$`&&e[i+1]===`{`?i=b(e,i+2,`}`,{slashStartsComments:!0,slashStartsRegExp:!1,supportsKotlinStrings:!0}).endIndex+1:i+=1}return e.length}function c(e,t){let n=t+1;for(;n<e.length;)if(e[n]===`\\`)n+=2;else{if(e[n]==="`")return n+1;e[n]===`$`&&e[n+1]===`{`?n=b(e,n+2,`}`,{slashStartsRegExp:!0}).endIndex+1:n+=1}return e.length}function l(e,t){let n=u(e,t),r=t+n.length;for(;r<e.length;){if(e.startsWith(n,r))return r+n.length;e[r]===`{`&&e[r+1]===`{`?r+=2:e[r]===`{`?r=b(e,r+1,`}`,{slashStartsRegExp:!1}).endIndex+1:r+=e[r]===`\\`?2:1}return e.length}function u(e,t){let n=e.slice(t,t+3);return n===`'''`||n===`"""`?n:e[t]??``}function d(e,t){let n=f(e,t);return n?t-n.length:t}function f(e,t){if(e[t]!==`"`&&e[t]!==`'`)return;let n=t-1;for(;n>=0&&/[A-Za-z]/.test(e[n]??``);)--n;let r=e.slice(n+1,t);if(r&&/^[bfru]+$/i.test(r)&&!(n>=0&&/[\dA-Za-z_]/.test(e[n]??``)))return r}function p(e,t,n,r,i,a){return n.templateSyntax===`kotlin`?m(e,t,a):a.startsWith("`")?v(e,t,a):_(r,i)?y(e,t,a):``}function m(e,t,r){let i=u(r,0).length,a=i===3,o=[],s=i;for(;s<r.length-i;)if(!a&&r[s]===`\\`)s+=2;else if(r[s]!==`$`)s+=1;else if(r[s+1]===`{`){let i=b(r,s+2,`}`,{slashStartsComments:!0,slashStartsRegExp:!1,supportsKotlinStrings:!0});o.push(n(e,i.content,{removeStrings:!0},t)),s=i.endIndex+1}else if(h(r[s+1])){let e=s+2;for(;g(r[e]);)e+=1;o.push(r.slice(s+1,e)),s=e}else s+=1;return o.join(`
|
|
2
|
+
`)}function h(e){return e!==void 0&&/[\p{L}_]/u.test(e)}function g(e){return e!==void 0&&/[\p{L}\p{N}_]/u.test(e)}function _(e,t){return f(e,t)?.toLowerCase().includes(`f`)??!1}function v(e,t,r){let i=[],a=1;for(;a<r.length-1;)if(r[a]===`\\`)a+=2;else if(r[a]===`$`&&r[a+1]===`{`){let o=b(r,a+2,`}`,{slashStartsRegExp:!0});i.push(n(e,o.content,{removeStrings:!0},t)),a=o.endIndex+1}else a+=1;return i.join(`
|
|
3
|
+
`)}function y(e,t,r){let i=u(r,0).length,a=[],o=i;for(;o<r.length-i;)if(r[o]===`{`&&r[o+1]===`{`)o+=2;else if(r[o]===`{`){let i=b(r,o+1,`}`,{slashStartsRegExp:!1});a.push(n(e,i.content,{removeStrings:!0},t)),o=i.endIndex+1}else o+=r[o]===`\\`?2:1;return a.join(`
|
|
4
|
+
`)}function b(e,t,n,r){let i=1,a=t;for(;a<e.length;){let o=e[a];if(o===`"`&&r.supportsKotlinStrings)a=s(e,a);else if(o===`"`||o===`'`||o==="`")a=x(e,a);else if((r.slashStartsComments||r.slashStartsRegExp)&&e[a]===`/`&&e[a+1]===`/`)a=C(e,a);else if((r.slashStartsComments||r.slashStartsRegExp)&&e[a]===`/`&&e[a+1]===`*`)a=w(e,a);else if(r.slashStartsRegExp&&o===`/`)a=S(e,a);else{if(o===`{`&&(i+=1),o===n&&(--i,i===0))return{content:e.slice(t,a),endIndex:a};a+=1}}return{content:e.slice(t),endIndex:e.length}}function x(e,t){let n=u(e,t),r=t+n.length;for(;r<e.length;)if(e[r]===`\\`)r+=2;else{if(e.startsWith(n,r))return r+n.length;r+=1}return r}function S(e,t){let n=t+1,r=!1;for(;n<e.length;)if(e[n]===`\\`)n+=2;else{if(e[n]===`[`&&(r=!0),e[n]===`]`&&(r=!1),e[n]===`/`&&!r){for(n+=1;/[A-Za-z]/.test(e[n]??``);)n+=1;return n}if(e[n]===`
|
|
5
5
|
`)return t+1;n+=1}return t+1}function C(e,t){let n=e.indexOf(`
|
|
6
6
|
`,t+2);return n===-1?e.length:n}function w(e,t){let n=e.indexOf(`*/`,t+2);return n===-1?e.length:n+2}export{t as removeCommentsAndStringsInSourceCode,e as removeCommentsInSourceCode};
|
|
7
7
|
//# sourceMappingURL=removeCommentsInSourceCode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeCommentsInSourceCode.js","names":["removeCommentsInSourceCode","removeCommentsAndMaybeStringsInSourceCode","grammar","sourceCode","removeCommentsAndStringsInSourceCode","compileCommentOrStringGrammars","options","newSourceCodeSlices","lastIndex","first","commentOrStringGrammer","commentOrStringGrammars","startRegExp","match","shouldPreferMatch","stringPrefixStartIndex","getPythonStringPrefixStartIndex","closeRegExp","findStringEndIndex","stringLiteral","preserveStringInterpolationExpressions","makeGlobalRegExp","v","regExp","findKotlinStringEndIndex","stringStartIndex","findJavaScriptTemplateEndIndex","hasPythonFStringPrefix","findPythonFStringEndIndex","quote","getStringQuote","isRawString","index","readBalancedExpression","threeCharacterQuote","prefix","getPythonStringPrefix","stringGrammar","preserveKotlinStringTemplateExpressions","preserveJavaScriptTemplateExpressions","preservePythonFStringExpressions","quoteLength","expressions","expression","isKotlinIdentifierStart","endIndex","isKotlinIdentifierPart","character","depth","startIndex","char","skipQuotedSpan","skipJavaScriptSingleLineComment","skipJavaScriptBlockComment","skipJavaScriptRegExpLiteral","closeChar","inCharacterClass","newLineIndex"],"sources":["../../src/helpers/removeCommentsInSourceCode.ts"],"sourcesContent":["import type { LanguageDefinition } from '../types/language.js';\n\nexport type SourceCodeGrammar = NonNullable<LanguageDefinition['grammer']>;\n\n/** Removes comments from source code according to the provided language grammar. */\nexport function removeCommentsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: false });\n}\n\n/** Removes comments and string literal contents while preserving executable interpolation expressions. */\nexport function removeCommentsAndStringsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: true });\n}\n\ninterface CommentOrStringGrammar {\n closeRegExp: RegExp;\n isComment: boolean;\n openRegExp: RegExp;\n templateSyntax?: 'kotlin';\n}\n\ninterface BalancedExpressionOptions {\n slashStartsComments?: boolean;\n slashStartsRegExp: boolean;\n supportsKotlinStrings?: boolean;\n}\n\nfunction removeCommentsAndMaybeStringsInSourceCode(\n grammar: SourceCodeGrammar,\n sourceCode: string,\n options: { removeStrings: boolean },\n commentOrStringGrammars = compileCommentOrStringGrammars(grammar)\n): string {\n if (!grammar.comments?.length && (!options.removeStrings || !grammar.strings?.length)) return sourceCode;\n\n const newSourceCodeSlices: string[] = [];\n\n let lastIndex = 0;\n\n while (lastIndex < sourceCode.length) {\n let first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined;\n\n for (const commentOrStringGrammer of commentOrStringGrammars) {\n const startRegExp = commentOrStringGrammer.openRegExp;\n startRegExp.lastIndex = lastIndex;\n\n const match = startRegExp.exec(sourceCode);\n\n if (match && shouldPreferMatch(match, commentOrStringGrammer, first, options)) {\n first = { grammar: commentOrStringGrammer, match };\n }\n }\n\n if (first) {\n let stringPrefixStartIndex = first.match.index;\n if (!first.grammar.isComment && options.removeStrings) {\n stringPrefixStartIndex = getPythonStringPrefixStartIndex(sourceCode, first.match.index);\n }\n newSourceCodeSlices.push(sourceCode.slice(lastIndex, stringPrefixStartIndex));\n\n if (!first.grammar.isComment) {\n lastIndex = findStringEndIndex(sourceCode, first.match.index, first.grammar);\n const stringLiteral = sourceCode.slice(first.match.index, lastIndex);\n if (options.removeStrings) {\n newSourceCodeSlices.push(\n preserveStringInterpolationExpressions(\n grammar,\n commentOrStringGrammars,\n first.grammar,\n sourceCode,\n first.match.index,\n stringLiteral\n )\n );\n } else {\n newSourceCodeSlices.push(stringLiteral);\n }\n } else {\n const closeRegExp = first.grammar.closeRegExp;\n closeRegExp.lastIndex = first.match.index + first.match[0].length;\n\n const match = closeRegExp.exec(sourceCode);\n\n lastIndex = match ? match.index + match[0].length : sourceCode.length;\n }\n } else {\n newSourceCodeSlices.push(sourceCode.slice(lastIndex));\n lastIndex = sourceCode.length;\n }\n }\n\n return newSourceCodeSlices.join('');\n}\n\nfunction compileCommentOrStringGrammars(grammar: SourceCodeGrammar): readonly CommentOrStringGrammar[] {\n return [\n ...(grammar.comments?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close ?? /(?=\\n)/g),\n isComment: true,\n openRegExp: makeGlobalRegExp(v.open),\n })) ?? []),\n ...(grammar.strings?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close),\n isComment: false,\n openRegExp: makeGlobalRegExp(v.open),\n templateSyntax: v.templateSyntax,\n })) ?? []),\n ] satisfies CommentOrStringGrammar[];\n}\n\nfunction shouldPreferMatch(\n match: RegExpExecArray,\n grammar: CommentOrStringGrammar,\n first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined,\n options: { removeStrings: boolean }\n): boolean {\n if (!first) return true;\n if (match.index < first.match.index) return true;\n if (match.index > first.match.index) return false;\n return options.removeStrings && first.grammar.isComment && !grammar.isComment;\n}\n\nfunction makeGlobalRegExp(regExp: RegExp): RegExp {\n return new RegExp(regExp, regExp.flags.includes('g') ? regExp.flags : `${regExp.flags}g`);\n}\n\nfunction findStringEndIndex(sourceCode: string, stringStartIndex: number, grammar: CommentOrStringGrammar): number {\n if (grammar.templateSyntax === 'kotlin') return findKotlinStringEndIndex(sourceCode, stringStartIndex);\n if (sourceCode[stringStartIndex] === '`') return findJavaScriptTemplateEndIndex(sourceCode, stringStartIndex);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return findPythonFStringEndIndex(sourceCode, stringStartIndex);\n\n const closeRegExp = grammar.closeRegExp;\n closeRegExp.lastIndex = stringStartIndex + 1;\n const match = closeRegExp.exec(sourceCode);\n return match ? match.index + match[0].length : sourceCode.length;\n}\n\nfunction findKotlinStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n const isRawString = quote.length === 3;\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (!isRawString && sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index =\n readBalancedExpression(sourceCode, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findJavaScriptTemplateEndIndex(sourceCode: string, stringStartIndex: number): number {\n let index = stringStartIndex + 1;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '`') return index + 1;\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index = readBalancedExpression(sourceCode, index + 2, '}', { slashStartsRegExp: true }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findPythonFStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (sourceCode[index] === '{' && sourceCode[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '{') {\n index = readBalancedExpression(sourceCode, index + 1, '}', { slashStartsRegExp: false }).endIndex + 1;\n continue;\n }\n index += sourceCode[index] === '\\\\' ? 2 : 1;\n }\n\n return sourceCode.length;\n}\n\nfunction getStringQuote(sourceCode: string, stringStartIndex: number): string {\n const threeCharacterQuote = sourceCode.slice(stringStartIndex, stringStartIndex + 3);\n if (threeCharacterQuote === \"'''\" || threeCharacterQuote === '\"\"\"') return threeCharacterQuote;\n return sourceCode[stringStartIndex] ?? '';\n}\n\nfunction getPythonStringPrefixStartIndex(sourceCode: string, stringStartIndex: number): number {\n const prefix = getPythonStringPrefix(sourceCode, stringStartIndex);\n return prefix ? stringStartIndex - prefix.length : stringStartIndex;\n}\n\nfunction getPythonStringPrefix(sourceCode: string, stringStartIndex: number): string | undefined {\n if (sourceCode[stringStartIndex] !== '\"' && sourceCode[stringStartIndex] !== \"'\") return undefined;\n let index = stringStartIndex - 1;\n while (index >= 0 && /[A-Za-z]/.test(sourceCode[index] ?? '')) index -= 1;\n\n const prefix = sourceCode.slice(index + 1, stringStartIndex);\n if (!prefix || !/^[bfru]+$/i.test(prefix)) return undefined;\n if (index >= 0 && /[\\dA-Za-z_]/.test(sourceCode[index] ?? '')) return undefined;\n\n return prefix;\n}\n\nfunction preserveStringInterpolationExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringGrammar: CommentOrStringGrammar,\n sourceCode: string,\n stringStartIndex: number,\n stringLiteral: string\n): string {\n if (stringGrammar.templateSyntax === 'kotlin')\n return preserveKotlinStringTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (stringLiteral.startsWith('`'))\n return preserveJavaScriptTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return preservePythonFStringExpressions(grammar, commentOrStringGrammars, stringLiteral);\n return '';\n}\n\nfunction preserveKotlinStringTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const isRawString = quoteLength === 3;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (!isRawString && stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] !== '$') {\n index += 1;\n continue;\n }\n if (stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n if (isKotlinIdentifierStart(stringLiteral[index + 1])) {\n let endIndex = index + 2;\n while (isKotlinIdentifierPart(stringLiteral[endIndex])) endIndex += 1;\n expressions.push(stringLiteral.slice(index + 1, endIndex));\n index = endIndex;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction isKotlinIdentifierStart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}_]/u.test(character);\n}\n\nfunction isKotlinIdentifierPart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}\\p{N}_]/u.test(character);\n}\n\nfunction hasPythonFStringPrefix(sourceCode: string, stringStartIndex: number): boolean {\n return getPythonStringPrefix(sourceCode, stringStartIndex)?.toLowerCase().includes('f') ?? false;\n}\n\nfunction preserveJavaScriptTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const expressions: string[] = [];\n let index = 1;\n\n while (index < stringLiteral.length - 1) {\n if (stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '$' && stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', { slashStartsRegExp: true });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction preservePythonFStringExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (stringLiteral[index] === '{' && stringLiteral[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 1, '}', { slashStartsRegExp: false });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += stringLiteral[index] === '\\\\' ? 2 : 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction readBalancedExpression(\n sourceCode: string,\n startIndex: number,\n closeChar: string,\n options: BalancedExpressionOptions\n): { content: string; endIndex: number } {\n let depth = 1;\n let index = startIndex;\n\n while (index < sourceCode.length) {\n const char = sourceCode[index];\n if (char === '\"' && options.supportsKotlinStrings) {\n index = findKotlinStringEndIndex(sourceCode, index);\n continue;\n }\n if (char === '\"' || char === \"'\" || char === '`') {\n index = skipQuotedSpan(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '/'\n ) {\n index = skipJavaScriptSingleLineComment(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '*'\n ) {\n index = skipJavaScriptBlockComment(sourceCode, index);\n continue;\n }\n if (options.slashStartsRegExp && char === '/') {\n index = skipJavaScriptRegExpLiteral(sourceCode, index);\n continue;\n }\n if (char === '{') depth += 1;\n if (char === closeChar) {\n depth -= 1;\n if (depth === 0) return { content: sourceCode.slice(startIndex, index), endIndex: index };\n }\n index += 1;\n }\n\n return { content: sourceCode.slice(startIndex), endIndex: sourceCode.length };\n}\n\nfunction skipQuotedSpan(sourceCode: string, startIndex: number): number {\n const quote = getStringQuote(sourceCode, startIndex);\n let index = startIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n index += 1;\n }\n\n return index;\n}\n\nfunction skipJavaScriptRegExpLiteral(sourceCode: string, startIndex: number): number {\n let index = startIndex + 1;\n let inCharacterClass = false;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '[') inCharacterClass = true;\n if (sourceCode[index] === ']') inCharacterClass = false;\n if (sourceCode[index] === '/' && !inCharacterClass) {\n index += 1;\n while (/[A-Za-z]/.test(sourceCode[index] ?? '')) index += 1;\n return index;\n }\n if (sourceCode[index] === '\\n') return startIndex + 1;\n index += 1;\n }\n\n return startIndex + 1;\n}\n\nfunction skipJavaScriptSingleLineComment(sourceCode: string, startIndex: number): number {\n const newLineIndex = sourceCode.indexOf('\\n', startIndex + 2);\n return newLineIndex === -1 ? sourceCode.length : newLineIndex;\n}\n\nfunction skipJavaScriptBlockComment(sourceCode: string, startIndex: number): number {\n const endIndex = sourceCode.indexOf('*/', startIndex + 2);\n return endIndex === -1 ? sourceCode.length : endIndex + 2;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"removeCommentsInSourceCode.js","names":["removeCommentsInSourceCode","removeCommentsAndMaybeStringsInSourceCode","grammar","sourceCode","removeCommentsAndStringsInSourceCode","compileCommentOrStringGrammars","options","newSourceCodeSlices","lastIndex","first","commentOrStringGrammer","commentOrStringGrammars","startRegExp","match","shouldPreferMatch","stringPrefixStartIndex","getPythonStringPrefixStartIndex","closeRegExp","findStringEndIndex","stringLiteral","preserveStringInterpolationExpressions","makeGlobalRegExp","v","regExp","findKotlinStringEndIndex","stringStartIndex","findJavaScriptTemplateEndIndex","hasPythonFStringPrefix","findPythonFStringEndIndex","quote","getStringQuote","isRawString","index","readBalancedExpression","threeCharacterQuote","prefix","getPythonStringPrefix","stringGrammar","preserveKotlinStringTemplateExpressions","preserveJavaScriptTemplateExpressions","preservePythonFStringExpressions","quoteLength","expressions","expression","isKotlinIdentifierStart","endIndex","isKotlinIdentifierPart","character","depth","startIndex","char","skipQuotedSpan","skipJavaScriptSingleLineComment","skipJavaScriptBlockComment","skipJavaScriptRegExpLiteral","closeChar","inCharacterClass","newLineIndex"],"sources":["../../src/helpers/removeCommentsInSourceCode.ts"],"sourcesContent":["import type { LanguageDefinition } from '../types/language.js';\n\nexport type SourceCodeGrammar = NonNullable<LanguageDefinition['grammer']>;\n\n/** Removes comments from source code according to the provided language grammar. */\nexport function removeCommentsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: false });\n}\n\n/** Removes comments and string literal contents while preserving executable interpolation expressions. */\nexport function removeCommentsAndStringsInSourceCode(grammar: SourceCodeGrammar, sourceCode: string): string {\n return removeCommentsAndMaybeStringsInSourceCode(grammar, sourceCode, { removeStrings: true });\n}\n\ninterface CommentOrStringGrammar {\n closeRegExp: RegExp;\n isComment: boolean;\n openRegExp: RegExp;\n templateSyntax?: 'kotlin';\n}\n\ninterface BalancedExpressionOptions {\n slashStartsComments?: boolean;\n slashStartsRegExp: boolean;\n supportsKotlinStrings?: boolean;\n}\n\nfunction removeCommentsAndMaybeStringsInSourceCode(\n grammar: SourceCodeGrammar,\n sourceCode: string,\n options: { removeStrings: boolean },\n commentOrStringGrammars = compileCommentOrStringGrammars(grammar)\n): string {\n if (!grammar.comments?.length && (!options.removeStrings || !grammar.strings?.length)) return sourceCode;\n\n const newSourceCodeSlices: string[] = [];\n\n let lastIndex = 0;\n\n while (lastIndex < sourceCode.length) {\n let first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined;\n\n for (const commentOrStringGrammer of commentOrStringGrammars) {\n const startRegExp = commentOrStringGrammer.openRegExp;\n startRegExp.lastIndex = lastIndex;\n\n const match = startRegExp.exec(sourceCode);\n\n if (match && shouldPreferMatch(match, commentOrStringGrammer, first, options)) {\n first = { grammar: commentOrStringGrammer, match };\n }\n }\n\n if (first) {\n let stringPrefixStartIndex = first.match.index;\n if (!first.grammar.isComment && options.removeStrings) {\n stringPrefixStartIndex = getPythonStringPrefixStartIndex(sourceCode, first.match.index);\n }\n newSourceCodeSlices.push(sourceCode.slice(lastIndex, stringPrefixStartIndex));\n\n if (!first.grammar.isComment) {\n lastIndex = findStringEndIndex(sourceCode, first.match.index, first.grammar);\n const stringLiteral = sourceCode.slice(first.match.index, lastIndex);\n if (options.removeStrings) {\n newSourceCodeSlices.push(\n preserveStringInterpolationExpressions(\n grammar,\n commentOrStringGrammars,\n first.grammar,\n sourceCode,\n first.match.index,\n stringLiteral\n )\n );\n } else {\n newSourceCodeSlices.push(stringLiteral);\n }\n } else {\n const closeRegExp = first.grammar.closeRegExp;\n closeRegExp.lastIndex = first.match.index + first.match[0].length;\n\n const match = closeRegExp.exec(sourceCode);\n\n lastIndex = match ? match.index + match[0].length : sourceCode.length;\n }\n } else {\n newSourceCodeSlices.push(sourceCode.slice(lastIndex));\n lastIndex = sourceCode.length;\n }\n }\n\n return newSourceCodeSlices.join('');\n}\n\nfunction compileCommentOrStringGrammars(grammar: SourceCodeGrammar): readonly CommentOrStringGrammar[] {\n return [\n ...(grammar.comments?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close ?? /(?=\\n)/g),\n isComment: true,\n openRegExp: makeGlobalRegExp(v.open),\n })) ?? []),\n ...(grammar.strings?.map((v) => ({\n closeRegExp: makeGlobalRegExp(v.close),\n isComment: false,\n openRegExp: makeGlobalRegExp(v.open),\n templateSyntax: v.templateSyntax,\n })) ?? []),\n ] satisfies CommentOrStringGrammar[];\n}\n\nfunction shouldPreferMatch(\n match: RegExpExecArray,\n grammar: CommentOrStringGrammar,\n first: { grammar: CommentOrStringGrammar; match: RegExpExecArray } | undefined,\n options: { removeStrings: boolean }\n): boolean {\n if (!first) return true;\n if (match.index < first.match.index) return true;\n if (match.index > first.match.index) return false;\n return options.removeStrings && first.grammar.isComment && !grammar.isComment;\n}\n\nfunction makeGlobalRegExp(regExp: RegExp): RegExp {\n return new RegExp(regExp, regExp.flags.includes('g') ? regExp.flags : `${regExp.flags}g`);\n}\n\nfunction findStringEndIndex(sourceCode: string, stringStartIndex: number, grammar: CommentOrStringGrammar): number {\n if (grammar.templateSyntax === 'kotlin') return findKotlinStringEndIndex(sourceCode, stringStartIndex);\n if (sourceCode[stringStartIndex] === '`') return findJavaScriptTemplateEndIndex(sourceCode, stringStartIndex);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return findPythonFStringEndIndex(sourceCode, stringStartIndex);\n\n const closeRegExp = grammar.closeRegExp;\n closeRegExp.lastIndex = stringStartIndex + 1;\n const match = closeRegExp.exec(sourceCode);\n return match ? match.index + match[0].length : sourceCode.length;\n}\n\nfunction findKotlinStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n const isRawString = quote.length === 3;\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (!isRawString && sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index =\n readBalancedExpression(sourceCode, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findJavaScriptTemplateEndIndex(sourceCode: string, stringStartIndex: number): number {\n let index = stringStartIndex + 1;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '`') return index + 1;\n if (sourceCode[index] === '$' && sourceCode[index + 1] === '{') {\n index = readBalancedExpression(sourceCode, index + 2, '}', { slashStartsRegExp: true }).endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return sourceCode.length;\n}\n\nfunction findPythonFStringEndIndex(sourceCode: string, stringStartIndex: number): number {\n const quote = getStringQuote(sourceCode, stringStartIndex);\n let index = stringStartIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n if (sourceCode[index] === '{' && sourceCode[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '{') {\n index = readBalancedExpression(sourceCode, index + 1, '}', { slashStartsRegExp: false }).endIndex + 1;\n continue;\n }\n index += sourceCode[index] === '\\\\' ? 2 : 1;\n }\n\n return sourceCode.length;\n}\n\nfunction getStringQuote(sourceCode: string, stringStartIndex: number): string {\n const threeCharacterQuote = sourceCode.slice(stringStartIndex, stringStartIndex + 3);\n if (threeCharacterQuote === \"'''\" || threeCharacterQuote === '\"\"\"') return threeCharacterQuote;\n return sourceCode[stringStartIndex] ?? '';\n}\n\nfunction getPythonStringPrefixStartIndex(sourceCode: string, stringStartIndex: number): number {\n const prefix = getPythonStringPrefix(sourceCode, stringStartIndex);\n return prefix ? stringStartIndex - prefix.length : stringStartIndex;\n}\n\nfunction getPythonStringPrefix(sourceCode: string, stringStartIndex: number): string | undefined {\n if (sourceCode[stringStartIndex] !== '\"' && sourceCode[stringStartIndex] !== \"'\") return undefined;\n let index = stringStartIndex - 1;\n while (index >= 0 && /[A-Za-z]/.test(sourceCode[index] ?? '')) index -= 1;\n\n const prefix = sourceCode.slice(index + 1, stringStartIndex);\n if (!prefix || !/^[bfru]+$/i.test(prefix)) return undefined;\n if (index >= 0 && /[\\dA-Za-z_]/.test(sourceCode[index] ?? '')) return undefined;\n\n return prefix;\n}\n\nfunction preserveStringInterpolationExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringGrammar: CommentOrStringGrammar,\n sourceCode: string,\n stringStartIndex: number,\n stringLiteral: string\n): string {\n if (stringGrammar.templateSyntax === 'kotlin')\n return preserveKotlinStringTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (stringLiteral.startsWith('`'))\n return preserveJavaScriptTemplateExpressions(grammar, commentOrStringGrammars, stringLiteral);\n if (hasPythonFStringPrefix(sourceCode, stringStartIndex))\n return preservePythonFStringExpressions(grammar, commentOrStringGrammars, stringLiteral);\n return '';\n}\n\nfunction preserveKotlinStringTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const isRawString = quoteLength === 3;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (!isRawString && stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] !== '$') {\n index += 1;\n continue;\n }\n if (stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', {\n slashStartsComments: true,\n slashStartsRegExp: false,\n supportsKotlinStrings: true,\n });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n if (isKotlinIdentifierStart(stringLiteral[index + 1])) {\n let endIndex = index + 2;\n while (isKotlinIdentifierPart(stringLiteral[endIndex])) endIndex += 1;\n expressions.push(stringLiteral.slice(index + 1, endIndex));\n index = endIndex;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction isKotlinIdentifierStart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}_]/u.test(character);\n}\n\nfunction isKotlinIdentifierPart(character: string | undefined): boolean {\n return character !== undefined && /[\\p{L}\\p{N}_]/u.test(character);\n}\n\nfunction hasPythonFStringPrefix(sourceCode: string, stringStartIndex: number): boolean {\n return getPythonStringPrefix(sourceCode, stringStartIndex)?.toLowerCase().includes('f') ?? false;\n}\n\nfunction preserveJavaScriptTemplateExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const expressions: string[] = [];\n let index = 1;\n\n while (index < stringLiteral.length - 1) {\n if (stringLiteral[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '$' && stringLiteral[index + 1] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 2, '}', { slashStartsRegExp: true });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction preservePythonFStringExpressions(\n grammar: SourceCodeGrammar,\n commentOrStringGrammars: readonly CommentOrStringGrammar[],\n stringLiteral: string\n): string {\n const quoteLength = getStringQuote(stringLiteral, 0).length;\n const expressions: string[] = [];\n let index = quoteLength;\n\n while (index < stringLiteral.length - quoteLength) {\n if (stringLiteral[index] === '{' && stringLiteral[index + 1] === '{') {\n index += 2;\n continue;\n }\n if (stringLiteral[index] === '{') {\n const expression = readBalancedExpression(stringLiteral, index + 1, '}', { slashStartsRegExp: false });\n expressions.push(\n removeCommentsAndMaybeStringsInSourceCode(\n grammar,\n expression.content,\n { removeStrings: true },\n commentOrStringGrammars\n )\n );\n index = expression.endIndex + 1;\n continue;\n }\n index += stringLiteral[index] === '\\\\' ? 2 : 1;\n }\n\n return expressions.join('\\n');\n}\n\nfunction readBalancedExpression(\n sourceCode: string,\n startIndex: number,\n closeChar: string,\n options: BalancedExpressionOptions\n): { content: string; endIndex: number } {\n let depth = 1;\n let index = startIndex;\n\n while (index < sourceCode.length) {\n const char = sourceCode[index];\n if (char === '\"' && options.supportsKotlinStrings) {\n index = findKotlinStringEndIndex(sourceCode, index);\n continue;\n }\n if (char === '\"' || char === \"'\" || char === '`') {\n index = skipQuotedSpan(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '/'\n ) {\n index = skipJavaScriptSingleLineComment(sourceCode, index);\n continue;\n }\n if (\n (options.slashStartsComments || options.slashStartsRegExp) &&\n sourceCode[index] === '/' &&\n sourceCode[index + 1] === '*'\n ) {\n index = skipJavaScriptBlockComment(sourceCode, index);\n continue;\n }\n if (options.slashStartsRegExp && char === '/') {\n index = skipJavaScriptRegExpLiteral(sourceCode, index);\n continue;\n }\n if (char === '{') depth += 1;\n if (char === closeChar) {\n depth -= 1;\n if (depth === 0) return { content: sourceCode.slice(startIndex, index), endIndex: index };\n }\n index += 1;\n }\n\n return { content: sourceCode.slice(startIndex), endIndex: sourceCode.length };\n}\n\nfunction skipQuotedSpan(sourceCode: string, startIndex: number): number {\n const quote = getStringQuote(sourceCode, startIndex);\n let index = startIndex + quote.length;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode.startsWith(quote, index)) return index + quote.length;\n index += 1;\n }\n\n return index;\n}\n\nfunction skipJavaScriptRegExpLiteral(sourceCode: string, startIndex: number): number {\n let index = startIndex + 1;\n let inCharacterClass = false;\n\n while (index < sourceCode.length) {\n if (sourceCode[index] === '\\\\') {\n index += 2;\n continue;\n }\n if (sourceCode[index] === '[') inCharacterClass = true;\n if (sourceCode[index] === ']') inCharacterClass = false;\n if (sourceCode[index] === '/' && !inCharacterClass) {\n index += 1;\n while (/[A-Za-z]/.test(sourceCode[index] ?? '')) index += 1;\n return index;\n }\n if (sourceCode[index] === '\\n') return startIndex + 1;\n index += 1;\n }\n\n return startIndex + 1;\n}\n\nfunction skipJavaScriptSingleLineComment(sourceCode: string, startIndex: number): number {\n const newLineIndex = sourceCode.indexOf('\\n', startIndex + 2);\n return newLineIndex === -1 ? sourceCode.length : newLineIndex;\n}\n\nfunction skipJavaScriptBlockComment(sourceCode: string, startIndex: number): number {\n const endIndex = sourceCode.indexOf('*/', startIndex + 2);\n return endIndex === -1 ? sourceCode.length : endIndex + 2;\n}\n"],"mappings":"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"}
|