8000 support moonbit language · A-23187/vscode-leetcode@f1abc6a · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f1abc6a

Browse files
committed
support moonbit language
1 parent 586b3e4 commit f1abc6a

File tree

5 files changed

+101
-9
lines changed

5 files changed

+101
-9
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
"displayName": "LeetCode",
44
"description": "Solve LeetCode problems in VS Code",
55
"version": "0.18.4",
6-
"author": "LeetCode",
7-
"publisher": "LeetCode",
6+
"author": "A-23187",
7+
"publisher": "A-23187",
88
"license": "MIT",
99
"icon": "resources/LeetCode.png",
1010
"engines": {
1111
"vscode": "^1.57.0"
1212
},
1313
"repository": {
1414
"type": "git",
15-
"url": "https://github.com/LeetCode-OpenSource/vscode-leetcode"
15+
"url": "https://github.com/A-23187/vscode-leetcode"
1616
},
17-
"homepage": "https://github.com/LeetCode-OpenSource/vscode-leetcode/blob/master/README.md",
17+
"homepage": "https://github.com/A-23187/vscode-leetcode/blob/master/README.md",
1818
"categories": [
1919
"Other",
2020
"Snippets"
@@ -310,6 +310,7 @@
310310
"java",
311311
"javascript",
312312
"kotlin",
313+
"moonbit",
313314
"mysql",
314315
"php",
315316
"python",
@@ -523,6 +524,18 @@
523524
},
524525
"minProperties": 1
525526
},
527+
"moonbit": {
528+
"type": "object",
529+
"properties": {
530+
"folder": {
531+
"type": "string"
532+
},
533+
"filename": {
534+
"type": "string"
535+
}
536+
},
537+
"minProperties": 1
538+
},
526539
"mysql": {
527540
"type": "object",
528541
"properties": {
@@ -636,6 +649,10 @@
636649
"default": {
637650
"folder": "",
638651
"filename": "${id}.${kebab-case-name}.${ext}"
652+
},
653+
"moonbit": {
654+
"folder": "moonbit",
655+
"filename": "${id}/${id}.${ext}"
639656
}
640657
}
641658
},

src/leetCodeExecutor.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { executeCommand, executeCommandWithProgress } from "./utils/cpUtils";
1313
import { DialogOptions, openUrl } from "./utils/uiUtils";
1414
import * as wsl from "./utils/wslUtils";
1515
import { toWslPath, useWsl } from "./utils/wslUtils";
16+
import { genMoonbitCodeTemplateAndWrite, isMoonbitFile, moonbitBuild } from "./utils/moonbitUtils";
1617

1718
class LeetCodeExecutor implements Disposable {
1819
private leetCodeRootPath: string;
@@ -102,7 +103,7 @@ class LeetCodeExecutor implements Disposable {
102103

103104
public async showProblem(problemNode: IProblem, language: string, filePath: string, showDescriptionInComment: boolean = false, needTranslation: boolean): Promise<void> {
104105
const templateType: string = showDescriptionInComment ? "-cx" : "-c";
105-
const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", problemNode.id, templateType, "-l", language];
106+
const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", problemNode.id, templateType, "-l", language === "moonbit" ? "javascript" : language];
106107

107108
if (!needTranslation) {
108109
cmd.push("-T"); // use -T to force English version
@@ -111,6 +112,9 @@ class LeetCodeExecutor implements Disposable {
111112
if (!await fse.pathExists(filePath)) {
112113
await fse.createFile(filePath);
113114
const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", this.nodeExecutable, cmd);
115+
if (isMoonbitFile(filePath, language)) {
116+
return await genMoonbitCodeTemplateAndWrite(codeTemplate, filePath);
117+
}
114118
await fse.writeFile(filePath, codeTemplate);
115119
}
116120
}
@@ -163,6 +167,9 @@ class LeetCodeExecutor implements Disposable {
163167
}
164168

165169
public async submitSolution(filePath: string): Promise<string> {
170+
if (isMoonbitFile(filePath, null)) {
171+
filePath = await moonbitBuild(filePath);
172+
}
166173
try {
167174
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
168175
} catch (error) {
@@ -174,6 +181,9 @@ class LeetCodeExecutor implements Disposable {
174181
}
175182

176183
public async testSolution(filePath: string, testString?: string): Promise<string> {
184+
if (isMoonbitFile(filePath, null)) {
185+
filePath = await moonbitBuild(filePath);
186+
}
177187
if (testString) {
178188
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
179189
}

src/shared.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const languages: string[] = [
2828
"java",
2929
"javascript",
3030
"kotlin",
31+
"moonbit",
3132
"mysql",
3233
"php",
3334
"python",
@@ -48,6 +49,7 @@ export const langExt: Map<string, string> = new Map([
4849
["java", "java"],
4950
["javascript", "js"],
5051
["kotlin", "kt"],
52+
["moonbit", "mbt"],
5153
["mysql", "sql"],
5254
["php", "php"],
5355
["python", "py"],
@@ -133,7 +135,7 @@ export const urls = {
133135
graphql: "https://leetcode.com/graphql",
134136
userGraphql: "https://leetcode.com/graphql",
135137
login: "https://leetcode.com/accounts/login/",
136-
authLoginUrl: `https://leetcode.com/authorize-login/${protocol}/?path=leetcode.vscode-leetcode`,
138+
authLoginUrl: `https://leetcode.com/authorize-login/${protocol}/?path=A-23187.vscode-leetcode`,
137139
};
138140

139141
export const urlsCn = {
@@ -142,7 +144,7 @@ export const urlsCn = {
142144
graphql: "https://leetcode.cn/graphql",
143145
userGraphql: "https://leetcode.cn/graphql/",
144146
login: "https://leetcode.cn/accounts/login/",
145-
authLoginUrl: `https://leetcode.cn/authorize-login/${protocol}/?path=leetcode.vscode-leetcode`,
147+
authLoginUrl: `https://leetcode.cn/authorize-login/${protocol}/?path=A-23187.vscode-leetcode`,
146148
};
147149

148150
export const getUrl = (key: string) => {

src/utils/moonbitUtils.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import * as fse from "fs-extra";
2+
import * as path from "path";
3+
import { WorkspaceConfiguration } from "vscode";
4+
import { executeCommand } from "./cpUtils";
5+
import { getNodeIdFromFile } from "./problemUtils";
6+
import { getWorkspaceConfiguration, getWorkspaceFolder } from "./settingUtils";
7+
import { langExt } from "../shared";
8+
9+
export function getMoonbitFolder(): string {
10+
const leetCodeConfig: WorkspaceConfiguration = getWorkspaceConfiguration();
11+
return path.join(getWorkspaceFolder(),
12+
leetCodeConfig.get<string>("filePath.moonbit.folder", leetCodeConfig.get<string>("filePath.default.folder", "")));
13+
}
14+
15+
export function getMoonbitExt(): string {
16+
return langExt.get("moonbit") || ".mbt";
17+
}
18+
19+
export function isMoonbitFile(filePath: string, language: string | null): boolean {
20+
return filePath.startsWith(getMoonbitFolder()) && filePath.endsWith(`.${getMoonbitExt()}`)
21+
&& (language == null || language === "moonbit");
22+
}
23+
24+
export async function writeMoonbitModuleJson(): Promise<void> {
25+
const modJsonPath: string = path.join(getMoonbitFolder(), "moon.mod.json");
26+
if (await fse.pathExists(modJsonPath)) {
27+
return;
28+
}
29+
await fse.createFile(modJsonPath);
30+
await fse.writeFile(modJsonPath, `{"name":"moonbit-leetcode","source":"."}`);
31+
}
32+
33+
export async function genMoonbitCodeTemplateAndWrite(jsCodeTemplate: string, moonbitFilePath: string): Promise<void> {
34+
const functionReg: RegExp = /^\s*var\s+([^\s]+)\s*=\s*function\s*\((.*)\)/;
35+
let functionName: string = "functionName";
36+
let functionParam: string = "";
37+
const lines: string[] = [];
38+
for (const line of jsCodeTemplate.split("\n")) {
39+
const match: RegExpMatchArray | null = line.match(functionReg);
40+
if (match && match.length === 3) {
41+
functionName = match[1];
42+
functionParam = match[2];
43+
}
44+
if (line && line.indexOf("@lc code=end") < 0) {
45+
lines.push(`// ${line}`);
46+
}
47+
}
48+
// TODO support functionParam with type and return type
49+
lines.push(`pub fn ${functionName}(${functionParam}) -> Unit {\n}\n// @lc code=end\n`);
50+
await writeMoonbitModuleJson();
51+
await fse.writeFile(moonbitFilePath, lines.join("\n"));
52+
await fse.writeFile(path.join(path.dirname(moonbitFilePath), "moon.pkg.json"),
53+
`{"is-main":false,"link":{"js":{"exports":["${functionName}"],"format":"iife"}}}`);
54+
}
55+
56+
export async function moonbitBuild(moonbitFilePath: string): Promise<string> {
57+
const moonbitFolder: string = getMoonbitFolder();
58+
const moonbitExt: string = getMoonbitExt();
59+
await executeCommand("moon", ["build", "--release", "--target", "js", "--directory", moonbitFolder, "--verbose"]);
60+
const jsFilePath: string = path.join(moonbitFolder, "target", "js", "release", "build", `${moonbitFilePath.substring(moonbitFolder.length, moonbitFilePath.length - moonbitExt.length)}js`);
61+
await fse.appendFile(jsFilePath, `// @lc app=leetcode.cn id=${await getNodeIdFromFile(moonbitFilePath)} lang=javascript`);
62+
return jsFilePath;
63+
}

0 commit comments

Comments
 (0)
0