{"version":3,"file":"language.cjs","names":["writeFileWithoutFollowingSymlinks","path","fs","removeCommentsInSourceCode"],"sources":["../../src/types/language.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { removeCommentsInSourceCode } from '../helpers/removeCommentsInSourceCode.js';\nimport { writeFileWithoutFollowingSymlinks } from '../helpers/safeFs.js';\n\nexport interface LanguageDefinition {\n  /** File extensions to judge with this config. */\n  fileExtensions: readonly string[];\n\n  /** Function executed before the build. */\n  prebuild?(cwd: string): Promise<void>;\n\n  /** Returns the command to build a user program. */\n  buildCommand?(filePath: string): [string, ...string[]];\n\n  /** Returns the command to run a user program. */\n  command(filePath: string): [string, ...string[]];\n\n  /** Grammer definition for static analysis. */\n  grammer?: {\n    strings?: readonly { open: RegExp; close: RegExp; templateSyntax?: 'kotlin' }[];\n    comments?: readonly { open: RegExp; close?: RegExp }[];\n  };\n}\n\nconst cLikeGrammer = {\n  strings: [\n    { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n    { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n  ],\n  comments: [{ open: /\\n?[ \\t]*\\/\\*/, close: /\\*\\// }, { open: /\\n?[ \\t]*\\/\\// }],\n} as const satisfies LanguageDefinition['grammer'];\n\nconst javaScriptLikeGrammer = {\n  strings: [\n    { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n    { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n    { open: /`/, close: /(?<!\\\\)(?:\\\\{2})*`/ },\n  ],\n  comments: [{ open: /\\n?[ \\t]*\\/\\*/, close: /\\*\\// }, { open: /\\n?[ \\t]*\\/\\// }],\n} as const satisfies LanguageDefinition['grammer'];\n\nexport const languageIdToDefinition: Readonly<Record<string, Readonly<LanguageDefinition>>> = {\n  c: {\n    fileExtensions: ['.c'],\n    buildCommand: (filePath) => ['gcc', '--std=c17', '-O2', filePath, '-o', 'main'],\n    command: () => ['./main'],\n    grammer: cLikeGrammer,\n  },\n\n  cpp: {\n    fileExtensions: ['.cpp'],\n    buildCommand: (filePath) => ['g++', '--std=c++20', '-O2', filePath, '-o', 'main'],\n    command: () => ['./main'],\n    grammer: cLikeGrammer,\n  },\n\n  csharp: {\n    fileExtensions: ['.cs'],\n    prebuild: async (cwd) => {\n      // No-follow write: the submission owns `cwd` and could point `Main.csproj` at a file only the\n      // trusted harness user can write.\n      await writeFileWithoutFollowingSymlinks(\n        path.join(cwd, 'Main.csproj'),\n        `<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\n    <AssemblyName>Main</AssemblyName>\n  </PropertyGroup>\n</Project>`\n      );\n    },\n    buildCommand: () => ['dotnet', 'build', 'Main.csproj', '--configuration', 'Release', '--verbosity', 'quiet'],\n    command: () => ['dotnet', 'bin/Release/net8.0/Main.dll'],\n    grammer: cLikeGrammer,\n  },\n\n  css: {\n    fileExtensions: ['.css'],\n    command: () => ['echo', ''],\n    grammer: {\n      strings: [\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [{ open: /\\n?[ \\t]*\\/\\*/, close: /\\*\\// }],\n    },\n  },\n\n  dart: {\n    fileExtensions: ['.dart'],\n    buildCommand: (filePath) => ['dart', 'compile', 'exe', filePath, '-o', 'main'],\n    command: () => ['./main'],\n    grammer: cLikeGrammer,\n  },\n\n  java: {\n    fileExtensions: ['.java'],\n    prebuild: async (cwd) => {\n      const publicClassRegex = /\\bpublic\\s+class\\s+(\\w+)\\b/;\n      for (const dirent of await fs.promises.readdir(cwd, { withFileTypes: true })) {\n        if (!dirent.isFile() || !dirent.name.endsWith('.java')) continue;\n        const data = await fs.promises.readFile(path.join(cwd, dirent.name), 'utf8');\n        const [, className] = publicClassRegex.exec(removeCommentsInSourceCode(cLikeGrammer, data)) ?? [];\n        if (className) await fs.promises.rename(path.join(cwd, dirent.name), path.join(cwd, `${className}.java`));\n      }\n    },\n    buildCommand: (fileName) => ['javac', fileName],\n    // For example, Problem 7-3 in WillBooster's Java lecture uses at least 256MB.\n    command: (fileName) => ['java', '-Xmx1024m', fileName.replace(/\\.java$/, '')],\n    grammer: cLikeGrammer,\n  },\n\n  kotlin: {\n    fileExtensions: ['.kt'],\n    buildCommand: (filePath) => ['kotlinc', filePath, '-include-runtime', '-d', 'main.jar'],\n    command: () => ['java', '-Xmx1024m', '-jar', 'main.jar'],\n    grammer: {\n      strings: [\n        { open: /\"\"\"/, close: /\"\"\"/, templateSyntax: 'kotlin' },\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/, templateSyntax: 'kotlin' },\n      ],\n      comments: cLikeGrammer.comments,\n    },\n  },\n\n  javascript: {\n    fileExtensions: ['.js', '.cjs', '.mjs'],\n    command: (fileName) => ['bun', fileName],\n    grammer: javaScriptLikeGrammer,\n  },\n\n  jsp: {\n    fileExtensions: ['.jsp'],\n    command: () => ['echo', ''],\n    grammer: {\n      strings: [\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [\n        { open: /\\n?[ \\t]*<!--/, close: /-->/ },\n        { open: /\\n?[ \\t]*<%--/, close: /--%>/ },\n        { open: /\\n?[ \\t]*\\/\\*/, close: /\\*\\// },\n        { open: /\\n?[ \\t]*\\/\\// },\n      ],\n    },\n  },\n\n  haskell: {\n    fileExtensions: ['.hs'],\n    buildCommand: (filePath) => ['ghc', '-o', 'main', filePath],\n    command: () => ['./main'],\n    grammer: {\n      strings: [\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [{ open: /\\n?[ \\t]*\\{-/, close: /-\\}/ }, { open: /\\n?[ \\t]*--/ }],\n    },\n  },\n\n  html: {\n    fileExtensions: ['.html'],\n    command: () => ['echo', ''],\n    grammer: {\n      strings: [\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [{ open: /\\n?[ \\t]*<!--/, close: /-->/ }],\n    },\n  },\n\n  php: {\n    fileExtensions: ['.php'],\n    command: (fileName) => ['php', fileName],\n    grammer: {\n      strings: [\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [{ open: /\\n?[ \\t]*\\/\\*/, close: /\\*\\// }, { open: /\\n?[ \\t]*\\/\\// }, { open: /\\n?[ \\t]*#/ }],\n    },\n  },\n\n  python: {\n    fileExtensions: ['.py'],\n    command: (fileName) => ['python3', fileName],\n    grammer: {\n      strings: [\n        { open: /'''/, close: /(?<!\\\\)(?:\\\\{2})*'''/ },\n        { open: /\"\"\"/, close: /(?<!\\\\)(?:\\\\{2})*\"\"\"/ },\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [\n        { open: /\\n?[ \\t]*'''/, close: /'''/ },\n        { open: /\\n?[ \\t]*\"\"\"/, close: /\"\"\"/ },\n        { open: /\\n?[ \\t]*#/ },\n      ],\n    },\n  },\n\n  ruby: {\n    fileExtensions: ['.rb'],\n    buildCommand: (fileName) => ['ruby', '-c', fileName],\n    command: (fileName) => ['ruby', '--jit', fileName],\n    grammer: {\n      strings: [\n        { open: /'/, close: /(?<!\\\\)(?:\\\\{2})*'/ },\n        { open: /\"/, close: /(?<!\\\\)(?:\\\\{2})*\"/ },\n      ],\n      comments: [{ open: /\\n?[ \\t]*=begin/, close: /=end/ }, { open: /\\n?[ \\t]*#/ }],\n    },\n  },\n\n  rust: {\n    fileExtensions: ['.rs'],\n    buildCommand: (filePath) => ['rustc', filePath, '-o', 'main'],\n    command: () => ['./main'],\n    grammer: cLikeGrammer,\n  },\n\n  zig: {\n    fileExtensions: ['.zig'],\n    buildCommand: (filePath) => ['zig', 'build-exe', filePath],\n    command: (filePath) => ['./' + filePath.replace(/\\.zig$/, '')],\n    grammer: cLikeGrammer,\n  },\n\n  typescript: {\n    fileExtensions: ['.ts', '.cts', '.mts'],\n    command: (fileName) => ['bun', fileName],\n    grammer: javaScriptLikeGrammer,\n  },\n\n  text: {\n    fileExtensions: ['.txt'],\n    command: (fileName) => ['cat', fileName],\n  },\n} as const;\n"],"mappings":"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"}