From b5f3998d10e6460f004e06b529226f3d2eb8964a Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Mon, 22 Dec 2025 15:22:09 +0100 Subject: [PATCH 1/6] poc mops fix --- cli/cli.ts | 8 ++ cli/commands/fix.ts | 246 +++++++++++++++++++++++++++++++++++++++++ cli/package-lock.json | 123 +++++++++++++++++++++ cli/package.json | 1 + cli/tests/fix.test.ts | 110 ++++++++++++++++++ cli/tests/fix/m0236.mo | 12 ++ 6 files changed, 500 insertions(+) create mode 100644 cli/commands/fix.ts create mode 100644 cli/tests/fix.test.ts create mode 100644 cli/tests/fix/m0236.mo diff --git a/cli/cli.ts b/cli/cli.ts index 490e8779..5e8e2230 100755 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -13,6 +13,7 @@ import { bump } from "./commands/bump.js"; import { checkCandid } from "./commands/check-candid.js"; import { docsCoverage } from "./commands/docs-coverage.js"; import { docs } from "./commands/docs.js"; +import { fix } from "./commands/fix.js"; import { format } from "./commands/format.js"; import { init } from "./commands/init.js"; import { installAll } from "./commands/install/install-all.js"; @@ -509,6 +510,13 @@ maintainerCommand program.addCommand(maintainerCommand); +// fix +program + .command("fix ") + .description("Automatically fix code issues in a file") + .option("--dry-run", "Show what would be fixed without modifying files") + .action(fix); + // bump program .command("bump [major|minor|patch]") diff --git a/cli/commands/fix.ts b/cli/commands/fix.ts new file mode 100644 index 00000000..d30d75d9 --- /dev/null +++ b/cli/commands/fix.ts @@ -0,0 +1,246 @@ +import mo from "motoko"; +import fs from "node:fs"; +import { promisify } from "node:util"; + +// @ts-ignore +import base from "motoko/packages/latest/base.json"; +mo.loadPackage(base); + +// Enable M0236 warning +mo.setExtraFlags(["-W", "M0236"]); + +const readFile = promisify(fs.readFile); +const writeFile = promisify(fs.writeFile); + +interface Diagnostic { + source: string; + message: string; + range: { + start: { line: number; character: number }; + end: { line: number; character: number }; + }; + code?: string; + severity: number; +} + +interface Fix { + range: { + start: { line: number; character: number }; + end: { line: number; character: number }; + }; + newText: string; + message: string; +} + +export const fix = async (file: string, options: { dryRun?: boolean }) => { + console.log(`Checking for fixes in ${file}...`); + + try { + const content = await readFile(file, "utf8"); + mo.write(file, content); + + const diagnostics = mo.check(file) as any as Diagnostic[]; + + if (!diagnostics || diagnostics.length === 0) { + console.log("No fixes needed."); + return; + } + + const fixes: Fix[] = []; + + for (const diag of diagnostics) { + // Fix M0236: Dot notation suggestion + if (diag.code === "M0236") { + const match = diag.message.match( + /You can use the dot notation `(.+)\.(.+)\(\.\.\.\)` here/, + ); + if (match) { + const suggestedMethod = match[2]; + + const originalText = extractText(content, diag.range); + const parsed = parseCall(originalText); + + if (parsed && parsed.args.length > 0) { + const receiver = parsed.args[0]; + const restArgs = parsed.args.slice(1).join(", "); + const newText = `${receiver}.${suggestedMethod}(${restArgs})`; + + fixes.push({ + range: diag.range, + newText: newText, + message: diag.message, + }); + } + } + } + } + + if (fixes.length > 0) { + console.log(`Found ${fixes.length} fix(es)`); + + if (options.dryRun) { + for (const f of fixes) { + console.log( + ` Would replace '${extractText(content, f.range)}' at ${f.range.start.line + 1}:${f.range.start.character + 1} with: '${f.newText}'`, + ); + } + } else { + const fixedContent = applyFixes(content, fixes); + await writeFile(file, fixedContent); + console.log(`Applied ${fixes.length} fix(es).`); + } + } else { + console.log("No fixes applied."); + } + } catch (err) { + console.error(`Error processing ${file}:`, err); + throw err; + } +}; + +function extractText( + content: string, + range: { + start: { line: number; character: number }; + end: { line: number; character: number }; + }, +): string { + const lines = content.split("\n"); + const startLineNr = range.start.line; + const endLineNr = range.end.line; + const startChar = range.start.character; + const endChar = range.end.character; + const startLine = lines[startLineNr]; + if (startLine === undefined) { + throw new Error(`Start line not found: ${startLineNr}`); + } + + const endLine = lines[endLineNr]; + if (endLine === undefined) { + throw new Error(`End line not found: ${endLineNr}`); + } + + if (startLineNr === endLineNr) { + return startLine.substring(startChar, endChar); + } + + let text = startLine.substring(startChar); + for (let i = startLineNr + 1; i < endLineNr; i++) { + text += "\n" + lines[i]; + } + text += "\n" + endLine.substring(0, endChar); + return text; +} + +function parseCall(code: string): { func: string; args: string[] } | null { + // Matches Func(args) or Module.Func(args) + const match = code.match(/^([\w.]+)\s*\(([\s\S]*)\)$/); + if (!match) { + return null; + } + + const func = match[1] || ""; + const argsStr = match[2] || ""; + + const args: string[] = []; + let current = ""; + let depth = 0; + + for (let i = 0; i < argsStr.length; i++) { + const char = argsStr[i]; + if (char === "(" || char === "[" || char === "{") { + depth++; + } + if (char === ")" || char === "]" || char === "}") { + depth--; + } + + if (char === "," && depth === 0) { + args.push(current.trim()); + current = ""; + } else { + current += char; + } + } + if (current.trim()) { + args.push(current.trim()); + } + + // Handle empty args case "()" + if (args.length === 1 && args[0] === "") { + return { func, args: [] }; + } + + return { func, args }; +} + +function applyFixes(content: string, fixes: Fix[]): string { + // Sort fixes in reverse order to avoid invalidating ranges + const sortedFixes = [...fixes].sort((a, b) => { + if (a.range.start.line !== b.range.start.line) { + return b.range.start.line - a.range.start.line; + } + return b.range.start.character - a.range.start.character; + }); + + let lines = content.split("\n"); + + for (const fix of sortedFixes) { + const startLine = fix.range.start.line; + const endLine = fix.range.end.line; + const startChar = fix.range.start.character; + const endChar = fix.range.end.character; + + if (startLine === endLine) { + const line = lines[startLine]; + if (line === undefined) { + throw new Error(`Line ${startLine} not found`); + } + lines[startLine] = + line.slice(0, startChar) + fix.newText + line.slice(endChar); + } else { + throw new Error("Multi-line replacement not supported"); + } + } + + // Alternative: work on full string + // Re-join lines for simplicity if we didn't modify in place above + // But wait, the loop above modifies 'lines' array. + // The 'else' block was empty. + + // Let's rewrite applyFixes to work on the full string for safety with multiline + return applyFixesString(content, sortedFixes); +} + +function applyFixesString(content: string, fixes: Fix[]): string { + // Sort fixes in reverse order + const sortedFixes = [...fixes].sort((a, b) => { + if (a.range.start.line !== b.range.start.line) { + return b.range.start.line - a.range.start.line; + } + return b.range.start.character - a.range.start.character; + }); + + // We need to map (line, char) to absolute index + const lines = content.split("\n"); + const lineOffsets: number[] = []; + let currentOffset = 0; + for (const line of lines) { + lineOffsets.push(currentOffset); + currentOffset += line.length + 1; // +1 for \n + } + + let result = content; + + for (const fix of sortedFixes) { + const startOffset = + lineOffsets[fix.range.start.line]! + fix.range.start.character; + const endOffset = + lineOffsets[fix.range.end.line]! + fix.range.end.character; + + result = + result.slice(0, startOffset) + fix.newText + result.slice(endOffset); + } + + return result; +} diff --git a/cli/package-lock.json b/cli/package-lock.json index 0e3597d8..a0e2ead0 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -37,6 +37,7 @@ "mdast-util-from-markdown": "2.0.2", "mdast-util-to-markdown": "2.1.2", "minimatch": "10.0.1", + "motoko": "3.16.0", "ncp": "2.0.0", "node-fetch": "3.3.2", "octokit": "3.1.2", @@ -4929,6 +4930,57 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "license": "MIT", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/cross-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/cross-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/cross-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -10576,6 +10628,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/motoko": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/motoko/-/motoko-3.16.0.tgz", + "integrity": "sha512-6LQiRYp5LsakznOewQKqppF76pn818ynhhU1cy9emCu7e8VMI1OroCDD0Ya8j7TSug1Q7DsrkfrGi2jbgxaJDw==", + "license": "Apache-2.0", + "dependencies": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "parse-github-url": "1.0.3", + "sanitize-filename": "1.6.3" + } + }, + "node_modules/motoko/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/motoko/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -11237,6 +11324,18 @@ "node": ">=6" } }, + "node_modules/parse-github-url": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.3.tgz", + "integrity": "sha512-tfalY5/4SqGaV/GIGzWyHnFjlpTPTNpENR9Ea2lLldSJ8EWXMsvacWucqY3m3I4YPtas15IxTLQVQ5NSYXPrww==", + "license": "MIT", + "bin": { + "parse-github-url": "cli.js" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -12195,6 +12294,15 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -13101,6 +13209,15 @@ "node": ">=18" } }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, "node_modules/ts-jest": { "version": "29.4.5", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.5.tgz", @@ -13587,6 +13704,12 @@ "punycode": "^2.1.0" } }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "license": "(WTFPL OR MIT)" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/cli/package.json b/cli/package.json index 7d128add..28f87bcf 100644 --- a/cli/package.json +++ b/cli/package.json @@ -78,6 +78,7 @@ "mdast-util-from-markdown": "2.0.2", "mdast-util-to-markdown": "2.1.2", "minimatch": "10.0.1", + "motoko": "3.16.0", "ncp": "2.0.0", "node-fetch": "3.3.2", "octokit": "3.1.2", diff --git a/cli/tests/fix.test.ts b/cli/tests/fix.test.ts new file mode 100644 index 00000000..a261016b --- /dev/null +++ b/cli/tests/fix.test.ts @@ -0,0 +1,110 @@ +import { describe, expect, test, beforeAll } from "@jest/globals"; +import { execa } from "execa"; +import { execSync } from "child_process"; +import fs from "fs"; +import path from "path"; +import { promisify } from "util"; + +const readFile = promisify(fs.readFile); +const writeFile = promisify(fs.writeFile); +const rm = promisify(fs.rm); + +interface CliOptions { + cwd?: string; +} + +const cli = async (args: string[], { cwd }: CliOptions = {}) => { + return await execa("npm", ["run", "mops", "--", ...args], { + env: { MOPS_CWD: cwd }, + stdio: "pipe", + reject: false, + }); +}; + +const MO_VERSION = "1.0.0"; +const SRC_FILE = path.join(import.meta.dirname, "fix/m0236.mo"); + +describe("mops fix", () => { + beforeAll(async () => { + // Ensure toolchain is initialized and moc is installed + const initResult = await cli(["toolchain", "init"]); + if ( + initResult.exitCode !== 0 && + !initResult.stdout.includes("already initialized") + ) { + throw new Error(`toolchain init failed: ${initResult.stderr}`); + } + + const useResult = await cli(["toolchain", "use", "moc", MO_VERSION]); + if (useResult.exitCode !== 0) { + throw new Error(`toolchain use failed: ${useResult.stderr}`); + } + }, 120000); + + test("fixes M0236 warning", async () => { + // Create a temporary file by adding .tmp to the source file name + const tmpFile = `${SRC_FILE}.tmp`; + + // Copy the original source file to temp location + const originalContent = await readFile(SRC_FILE, "utf8"); + await writeFile(tmpFile, originalContent); + + // Get moc path via toolchain + const mocBinResult = await cli(["toolchain", "bin", "moc"]); + // Extract just the path, removing npm output prefix + const lines = mocBinResult.stdout.split("\n"); + const mocPath = lines[lines.length - 1]!.trim(); + + if (!mocPath || !fs.existsSync(mocPath)) { + throw new Error( + `moc binary not found at ${mocPath}. Toolchain setup may have failed.`, + ); + } + + // Check initial state - should have M0236 warning + let hasWarning = false; + const tmpDir = path.dirname(SRC_FILE); + try { + const checkResult = execSync( + `"${mocPath}" --check "${tmpFile}" -W M0236 2>&1`, + { encoding: "utf8", cwd: tmpDir }, + ); + hasWarning = checkResult.includes("M0236"); + } catch (e: any) { + // If execSync throws, check stderr/stdout + const output = (e.stdout || e.stderr || e.message || "").toString(); + hasWarning = output.includes("M0236"); + } + expect(hasWarning).toBe(true); + + // Run mops fix on the temp file + const fixResult = await cli(["fix", tmpFile]); + expect(fixResult.exitCode).toBe(0); + + // Verify file content changed + const content = await readFile(tmpFile, "utf8"); + expect(content).toContain("peopleMap.size()"); + expect(content).not.toContain("Map.size(peopleMap)"); + + // Verify compilation after fix - should not have M0236 warning + try { + const postCheckResult = execSync( + `"${mocPath}" --check "${tmpFile}" -W M0236 2>&1`, + { encoding: "utf8", cwd: tmpDir }, + ); + expect(postCheckResult).not.toContain("M0236"); + // Should compile without errors + expect(postCheckResult).not.toMatch(/error/i); + } catch (e: any) { + const output = e.stdout || e.stderr || e.message || ""; + expect(output).not.toContain("M0236"); + // If there are errors, they should not be related to our fix + if (output.toLowerCase().includes("error")) { + throw new Error(`Compilation failed after fix: ${output}`); + } + } finally { + // Clean up temporary file + await rm(tmpFile, { force: true }); + } + }, 60000); +}); diff --git a/cli/tests/fix/m0236.mo b/cli/tests/fix/m0236.mo new file mode 100644 index 00000000..d58ca37f --- /dev/null +++ b/cli/tests/fix/m0236.mo @@ -0,0 +1,12 @@ +module Map { + public type Map = { map : [(K, [var V])] }; + public func empty() : Map = { map = [] }; + public func size(self : Map) : Nat { self.map.size() }; +}; + +module M { + public func main() { + let peopleMap = Map.empty(); + ignore Map.size(peopleMap); + }; +}; From cee4619774dfee9b360045bfd991b54167949e6e Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Mon, 22 Dec 2025 17:02:36 +0100 Subject: [PATCH 2/6] support more warns --- cli/commands/fix.ts | 101 +++++++++++++++++----------- cli/tests/fix.test.ts | 145 +++++++++++++++++++++++------------------ cli/tests/fix/m0223.mo | 8 +++ cli/tests/fix/m0235.mo | 13 ++++ cli/tests/fix/m0237.mo | 34 ++++++++++ 5 files changed, 201 insertions(+), 100 deletions(-) create mode 100644 cli/tests/fix/m0223.mo create mode 100644 cli/tests/fix/m0235.mo create mode 100644 cli/tests/fix/m0237.mo diff --git a/cli/commands/fix.ts b/cli/commands/fix.ts index d30d75d9..bbe0f52d 100644 --- a/cli/commands/fix.ts +++ b/cli/commands/fix.ts @@ -6,8 +6,8 @@ import { promisify } from "node:util"; import base from "motoko/packages/latest/base.json"; mo.loadPackage(base); -// Enable M0236 warning -mo.setExtraFlags(["-W", "M0236"]); +// Enable all warning codes we can fix +mo.setExtraFlags(["-W", "M0223,M0235,M0236,M0237"]); const readFile = promisify(fs.readFile); const writeFile = promisify(fs.writeFile); @@ -49,6 +49,25 @@ export const fix = async (file: string, options: { dryRun?: boolean }) => { const fixes: Fix[] = []; for (const diag of diagnostics) { + // Fix M0223: Redundant type instantiation + // Remove type arguments like from inferred(1) -> inferred(1) + // The range always covers the whole type instantiation, so we can just remove it + if (diag.code === "M0223") { + fixes.push({ + range: diag.range, + newText: "", // Remove the type instantiation entirely + message: diag.message, + }); + } + + // Fix M0235: Deprecation warning + // Note: Deprecation warnings can't be automatically fixed, but we skip them + // as they require manual code changes. The test may need adjustment. + if (diag.code === "M0235") { + // Skip - deprecation warnings require manual intervention + continue; + } + // Fix M0236: Dot notation suggestion if (diag.code === "M0236") { const match = diag.message.match( @@ -73,6 +92,48 @@ export const fix = async (file: string, options: { dryRun?: boolean }) => { } } } + + // Fix M0237: Redundant explicit implicit arguments + // Remove explicit implicit arguments like Nat.compare from get(Nat.compare, 1) -> get(1) + // The range covers the argument, and we optionally remove whitespace + comma after it + if (diag.code === "M0237") { + const lines = content.split("\n"); + const lineIdx = diag.range.end.line; + const line = lines[lineIdx]; + + if (line) { + const restOfLine = line.substring(diag.range.end.character); + const nextLine = lines[lineIdx + 1]; + const textToCheck = + nextLine !== undefined ? restOfLine + "\n" + nextLine : restOfLine; + + const match = textToCheck.match(/^\s*,\s*/); + + if (match) { + const fullMatch = match[0]; + + let endLine = lineIdx; + let endChar = diag.range.end.character; + + const nlIndex = fullMatch.lastIndexOf("\n"); + if (nlIndex !== -1) { + endLine++; + endChar = fullMatch.length - (nlIndex + 1); + } else { + endChar += fullMatch.length; + } + + fixes.push({ + range: { + start: diag.range.start, + end: { line: endLine, character: endChar }, + }, + newText: "", + message: diag.message, + }); + } + } + } } if (fixes.length > 0) { @@ -175,41 +236,7 @@ function parseCall(code: string): { func: string; args: string[] } | null { } function applyFixes(content: string, fixes: Fix[]): string { - // Sort fixes in reverse order to avoid invalidating ranges - const sortedFixes = [...fixes].sort((a, b) => { - if (a.range.start.line !== b.range.start.line) { - return b.range.start.line - a.range.start.line; - } - return b.range.start.character - a.range.start.character; - }); - - let lines = content.split("\n"); - - for (const fix of sortedFixes) { - const startLine = fix.range.start.line; - const endLine = fix.range.end.line; - const startChar = fix.range.start.character; - const endChar = fix.range.end.character; - - if (startLine === endLine) { - const line = lines[startLine]; - if (line === undefined) { - throw new Error(`Line ${startLine} not found`); - } - lines[startLine] = - line.slice(0, startChar) + fix.newText + line.slice(endChar); - } else { - throw new Error("Multi-line replacement not supported"); - } - } - - // Alternative: work on full string - // Re-join lines for simplicity if we didn't modify in place above - // But wait, the loop above modifies 'lines' array. - // The 'else' block was empty. - - // Let's rewrite applyFixes to work on the full string for safety with multiline - return applyFixesString(content, sortedFixes); + return applyFixesString(content, fixes); } function applyFixesString(content: string, fixes: Fix[]): string { diff --git a/cli/tests/fix.test.ts b/cli/tests/fix.test.ts index a261016b..0ba88d49 100644 --- a/cli/tests/fix.test.ts +++ b/cli/tests/fix.test.ts @@ -22,9 +22,65 @@ const cli = async (args: string[], { cwd }: CliOptions = {}) => { }; const MO_VERSION = "1.0.0"; -const SRC_FILE = path.join(import.meta.dirname, "fix/m0236.mo"); +// Enable all warning codes we test +const WARNING_FLAGS = "-W M0223,M0235,M0236,M0237"; + +/** + * Creates a temporary file from a source file and ensures cleanup + */ +async function withTmpFile( + sourceFile: string, + callback: (tmpFile: string) => Promise, +): Promise { + const tmpFile = `${sourceFile}.tmp`; + try { + // Copy the original source file to temp location + const originalContent = await readFile(sourceFile, "utf8"); + await writeFile(tmpFile, originalContent); + return await callback(tmpFile); + } finally { + // Clean up temporary file + await rm(tmpFile, { force: true }); + } +} + +/** + * Gets the moc binary path from toolchain + */ +async function getMocPath(): Promise { + const mocBinResult = await cli(["toolchain", "bin", "moc"]); + // Extract just the path, removing npm output prefix + const lines = mocBinResult.stdout.split("\n"); + const mocPath = lines[lines.length - 1]!.trim(); + + if (!mocPath || !fs.existsSync(mocPath)) { + throw new Error( + `moc binary not found at ${mocPath}. Toolchain setup may have failed.`, + ); + } + return mocPath; +} + +function getWarnings(filePath: string, mocPath: string, cwd: string): string[] { + const output = execSync( + `"${mocPath}" --check "${filePath}" ${WARNING_FLAGS} 2>&1`, + { encoding: "utf8", cwd }, + ); + + const warnings: string[] = []; + + const warningRegex = /warning \[(M\d+)\]/gi; + let match; + while ((match = warningRegex.exec(output)) !== null) { + warnings.push(match[1]!); + } + + return warnings; +} describe("mops fix", () => { + let mocPath: string; + beforeAll(async () => { // Ensure toolchain is initialized and moc is installed const initResult = await cli(["toolchain", "init"]); @@ -39,72 +95,35 @@ describe("mops fix", () => { if (useResult.exitCode !== 0) { throw new Error(`toolchain use failed: ${useResult.stderr}`); } + + mocPath = await getMocPath(); }, 120000); - test("fixes M0236 warning", async () => { - // Create a temporary file by adding .tmp to the source file name - const tmpFile = `${SRC_FILE}.tmp`; + const testCases = [ + { code: "M0223", file: "m0223.mo" }, + { code: "M0235", file: "m0235.mo" }, + { code: "M0236", file: "m0236.mo" }, + { code: "M0237", file: "m0237.mo" }, + ]; - // Copy the original source file to temp location - const originalContent = await readFile(SRC_FILE, "utf8"); - await writeFile(tmpFile, originalContent); + for (const { code, file } of testCases) { + test(`fixes ${code} warning`, async () => { + const srcFile = path.join(import.meta.dirname, "fix", file); + const tmpDir = path.dirname(srcFile); - // Get moc path via toolchain - const mocBinResult = await cli(["toolchain", "bin", "moc"]); - // Extract just the path, removing npm output prefix - const lines = mocBinResult.stdout.split("\n"); - const mocPath = lines[lines.length - 1]!.trim(); + await withTmpFile(srcFile, async (tmpFile) => { + // Check initial state - should have the warning + const beforeWarnings = getWarnings(tmpFile, mocPath, tmpDir); + expect(beforeWarnings).toContain(code); - if (!mocPath || !fs.existsSync(mocPath)) { - throw new Error( - `moc binary not found at ${mocPath}. Toolchain setup may have failed.`, - ); - } + // Run mops fix on the temp file + const fixResult = await cli(["fix", tmpFile]); + expect(fixResult.exitCode).toBe(0); - // Check initial state - should have M0236 warning - let hasWarning = false; - const tmpDir = path.dirname(SRC_FILE); - try { - const checkResult = execSync( - `"${mocPath}" --check "${tmpFile}" -W M0236 2>&1`, - { encoding: "utf8", cwd: tmpDir }, - ); - hasWarning = checkResult.includes("M0236"); - } catch (e: any) { - // If execSync throws, check stderr/stdout - const output = (e.stdout || e.stderr || e.message || "").toString(); - hasWarning = output.includes("M0236"); - } - expect(hasWarning).toBe(true); - - // Run mops fix on the temp file - const fixResult = await cli(["fix", tmpFile]); - expect(fixResult.exitCode).toBe(0); - - // Verify file content changed - const content = await readFile(tmpFile, "utf8"); - expect(content).toContain("peopleMap.size()"); - expect(content).not.toContain("Map.size(peopleMap)"); - - // Verify compilation after fix - should not have M0236 warning - try { - const postCheckResult = execSync( - `"${mocPath}" --check "${tmpFile}" -W M0236 2>&1`, - { encoding: "utf8", cwd: tmpDir }, - ); - expect(postCheckResult).not.toContain("M0236"); - // Should compile without errors - expect(postCheckResult).not.toMatch(/error/i); - } catch (e: any) { - const output = e.stdout || e.stderr || e.message || ""; - expect(output).not.toContain("M0236"); - // If there are errors, they should not be related to our fix - if (output.toLowerCase().includes("error")) { - throw new Error(`Compilation failed after fix: ${output}`); - } - } finally { - // Clean up temporary file - await rm(tmpFile, { force: true }); - } - }, 60000); + // Verify compilation after fix - should not have warnings or errors + const afterWarnings = getWarnings(tmpFile, mocPath, tmpDir); + expect(afterWarnings).toHaveLength(0); + }); + }, 60000); + } }); diff --git a/cli/tests/fix/m0223.mo b/cli/tests/fix/m0223.mo new file mode 100644 index 00000000..45ba8212 --- /dev/null +++ b/cli/tests/fix/m0223.mo @@ -0,0 +1,8 @@ +module M { + public func inferred(x : T) : T = x; + + public func main() { + let n1 = inferred(1); // Redundant type instantiation + ignore n1; + }; +}; diff --git a/cli/tests/fix/m0235.mo b/cli/tests/fix/m0235.mo new file mode 100644 index 00000000..e0fd4073 --- /dev/null +++ b/cli/tests/fix/m0235.mo @@ -0,0 +1,13 @@ +module A { + /// @deprecated M0235 + public let foo = 5; + /// @deprecated M0235 + public func f(x : Nat) : Nat { x }; +}; + +module M { + public func main() { + ignore A.foo; // Deprecated field + ignore A.f(5); // Deprecated function + }; +}; diff --git a/cli/tests/fix/m0237.mo b/cli/tests/fix/m0237.mo new file mode 100644 index 00000000..5a8a9245 --- /dev/null +++ b/cli/tests/fix/m0237.mo @@ -0,0 +1,34 @@ +type Order = { + #less; + #equal; + #greater; +}; + +module Nat { + public func compare(_ : Nat, _ : Nat) : Order { #equal }; +}; + +module Map { + public type Map = { map : [(K, [var V])] }; + public func empty() : Map = { map = [] }; + + public func get( + self : Map, + compare : (implicit : (K, K) -> Order), + n : K, + ) : ?V { + ignore (self, compare, n); + null; + }; +}; + +module M { + public func main() { + let peopleMap = Map.empty(); + ignore peopleMap.get(Nat.compare, 1); // Redundant explicit argument + ignore peopleMap.get( + Nat.compare, + 1, + ); // Redundant explicit argument + }; +}; From 1f81b1996de925d5465db1d9152f9b239e6ea2d7 Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Mon, 22 Dec 2025 17:04:35 +0100 Subject: [PATCH 3/6] mops lock --- mops.lock | 141 +++++++++++++++++++++++++++++++++--------------------- mops.toml | 6 +-- 2 files changed, 90 insertions(+), 57 deletions(-) diff --git a/mops.lock b/mops.lock index 1294c685..b6f090e1 100644 --- a/mops.lock +++ b/mops.lock @@ -1,6 +1,37 @@ { - "version": 2, - "mopsTomlDepsHash": "722dc0bee276245351407defa34eb1cd2f96334559d4736d892f8871144cfeb1", + "version": 3, + "mopsTomlDepsHash": "d15fe96a0e23a36c49c0b38013457ad48ae622b71540da042a64dc2c32e89210", + "deps": { + "base": "0.14.14", + "time-consts": "1.0.1", + "map": "9.0.1", + "ic": "3.2.0", + "backup": "3.0.0", + "linked-list": "0.1.0", + "http-types": "1.0.1", + "motoko-datetime": "https://github.com/ByronBecker/motoko-datetime#v0.1.1@bda6139ec56d36731326727ae28510f1e1843f27", + "memory-region": "0.1.1", + "stableheapbtreemap": "1.3.0", + "matchers": "https://github.com/kritzcreek/motoko-matchers#v1.3.0", + "fuzz": "1.0.0", + "sha2": "0.1.0", + "vector": "0.4.0", + "datetime": "1.0.0", + "core": "2.0.0", + "xtended-text": "2.0.0", + "xtended-numbers": "2.0.0", + "buffer": "0.0.1", + "principal-ext": "0.1.0", + "telegram-bot": "0.1.1", + "serde": "3.3.2", + "itertools": "0.2.2", + "candid": "2.0.0", + "cbor": "4.0.0", + "byte-utils": "0.1.1", + "base@0.7.3": "0.7.3", + "test": "2.1.1", + "bench": "1.0.0" + }, "hashes": { "base@0.14.14": { "base@0.14.14/NOTICE": "3960a8d25fa5fc909325817b08b36c1146970930ca15b6352f8ea6db803cab47", @@ -408,58 +439,60 @@ "datetime@1.0.0/iana/timezones/Universal.mo": "b14af8ce8270b2e1a8c90e6165041fa0eb5434da01c468c8dacadc76fb9628f7", "datetime@1.0.0/iana/timezones/US.mo": "e46acc3bfbcdb0c25efa8f24e62626918cb0a00a56302dc458110628dfb2fb9d" }, - "core@0.6.0": { - "core@0.6.0/src/Array.mo": "a22df6109b7ab80bbe1a528d6e2b3d49e90c792cbc47d2cfadb5b9d5bccfd99e", - "core@0.6.0/NOTICE": "d62ca4ef9e2c9df064115c339013593cf0769e2b9dc78fa4b3211222541c7f83", - "core@0.6.0/README.md": "ef1e6c05db36d238f144b0cfa82cb1e6a68c94a5895619d32c55f7a190d25cff", - "core@0.6.0/LICENSE": "840e3d57a38a8061f55d04470fbd58b9345326fa04ea10ee42add5c6e3b2aa08", - "core@0.6.0/mops.toml": "be66822dab4ef108b780c82b27c3635625b25e2c5753d89ab707c9db13fcf674", - "core@0.6.0/src/Bool.mo": "a13590c559c53109e79ffff7de0506e59f1f93754ef2d0efa1df9baaf1751e95", - "core@0.6.0/src/Blob.mo": "58fe96119602151a6816db9817bfd3062526e15fac49c2a259fd2a5061266775", - "core@0.6.0/src/Float.mo": "20beea2c0d9039593cc28c638e289f42b3f5a9405b9a43c1fc76571cbb0e6f5d", - "core@0.6.0/src/Error.mo": "fb53abc8de032fa421e327a7fb4880345b7b8e91bbb84d9183d2172b7a9ec773", - "core@0.6.0/src/Func.mo": "c00d06b15e3376821020ceaaffae2a70bf206c672e746459ba1079adc6d1a619", - "core@0.6.0/src/CertifiedData.mo": "5af3182d77ab7aab2384d1f663a8cd992bbd6652aacff29c443314cf2186328f", - "core@0.6.0/src/Cycles.mo": "9d36e2196cb36430072b5b10c95f0b068e8e73db9362ac01f44459275d4d991d", - "core@0.6.0/src/Char.mo": "0d1146320d21048cd49663c9838b1a6ce7ec1add1ad256b51a1eac4bbe3f6be8", - "core@0.6.0/src/Debug.mo": "5c9398296ea0a913e2f356a3e169bb56df817248036aaa5c97507d29915143cf", - "core@0.6.0/src/Int.mo": "e3d48615e950a72dc5f0f052a47c3a66b6a86c8d1d2b25127f25852bd1595daa", - "core@0.6.0/src/Int32.mo": "6fb63738e2482ee6b361745a7c0b03f684cdfcfa578e1bae53a9e0df527f1f72", - "core@0.6.0/src/Int16.mo": "5102cbb40ff1ecdc005bdc96ded6ef3619aa840526d2b243c0463dbb758aa4a8", - "core@0.6.0/src/Iter.mo": "6098e63365cabe82046fd0100f53b029cc2693a438d0a7aafc7e930c8bb986b2", - "core@0.6.0/src/Int8.mo": "186de373b7857c3d6a6a3814285959e291088e8ae17de4a1bf2bd5e15490d511", - "core@0.6.0/src/InternetComputer.mo": "20383755c98801e560c17f9aefd9b4eb00463ee598125de1b39f6ae6fc8c60c9", - "core@0.6.0/src/Int64.mo": "05d49bb8a25ef1f49e8a164fd5a63cc03fd56c1bbb91f1b6d5096ba9bd9eb23a", - "core@0.6.0/src/Map.mo": "7380681b761ce0f8e9ae731b87fc378f1d2beb4bf1d47db742321f63f0d2559a", - "core@0.6.0/src/List.mo": "42017a2858014d34f95ae3949ca8db04b06e3ecb522cbc893be8fbf0a55fbe3f", - "core@0.6.0/src/Order.mo": "ebc93dd27cee7befd6e41794fb220f079dfb017145a76d77a225b2fcb3bbfd9e", - "core@0.6.0/src/Nat8.mo": "02c42e668f0fd95df5f864b4bbede58565a0a0395c6a04f6cb357f83090d245d", - "core@0.6.0/src/Nat16.mo": "0f83fbbbd2c4b0c71e9465e67273464faf32f126e59f3417476d536ee7e2ebbc", - "core@0.6.0/src/Nat64.mo": "9d8454be0bf9b234f5a5d308a1afdc02bc770a9d0d587bc23f8fba392a21ead9", - "core@0.6.0/src/Option.mo": "14e4f9d3332f778e0afa922e68852bf8fefcb885f1455770333867d120d64230", - "core@0.6.0/src/Nat.mo": "53fcb2ccbd3cbed4e2be7458a4548a55c317cac2a96ee97a9427d4518b9bc188", - "core@0.6.0/src/Nat32.mo": "e35fccf57b5a5aca880860481388c8d679b2289710a43d9acd5f77ed19984614", - "core@0.6.0/src/Principal.mo": "28d5b9f7c5296cd524b8878e46c390cd75e2839c3de72e7a61ecef5de424e296", - "core@0.6.0/src/Result.mo": "a3eed6fe0156ac5a10418c13397fab7bcbc803a95cfc12fdb4de159e97f5cc94", - "core@0.6.0/src/Region.mo": "c853ca2803d26f650e8e0cc0ba1b219664e7e0fdcea2a747f146f035dc5659dd", - "core@0.6.0/src/Random.mo": "7862375427f25ead3e87fb0443912cc2ff87987de105b8c82147988ade4a2654", - "core@0.6.0/src/Runtime.mo": "5ac1290bec77ab04ae51df5fdc56ab4c6850823ffcd18e4140dfcc1b5a66cce3", - "core@0.6.0/src/Queue.mo": "da65b9f1df3caaf23770dd35caa1400200f2f0b7cd4da0b15d3718dbef19c192", - "core@0.6.0/src/Stack.mo": "95d40067ad729faaf794fbe2e59e4566002dcce159e77d1c67d4a5d0a2281359", - "core@0.6.0/src/Text.mo": "9a941988aa79ef42008f52fbbb7ee43c24a2ea084265f1102d5cf658ac2d47e0", - "core@0.6.0/src/Set.mo": "db592ed58c0a333fd50303cf71fb47adf2e0660e0b53364c49a2aef536380db3", - "core@0.6.0/src/Timer.mo": "dee7c31d1d4fd29794da552a133bcb90fbd29e3ec004407d1d6a16f430ac8151", - "core@0.6.0/src/Types.mo": "05d93ce3e643d08bb76d7ea5d7b597e3d3de65b7b4fce59f06ed281fd3c8c046", - "core@0.6.0/src/Tuples.mo": "632c1d344d561df66c7092b13c9009e41f5c73d068f1ae13001ac55353c66376", - "core@0.6.0/src/Time.mo": "e08d502d5eb3ca0ab7b4cce7322404faf1c72bc2bed7d2ded5a46d6afd80fd39", - "core@0.6.0/src/internal/BTreeHelper.mo": "20a475baf18f924ee0297fc234469fa0985cdaa31c85ce002b5a921383b0534d", - "core@0.6.0/src/pure/List.mo": "e4a873f01cd5f923a43b7a4f86924f9348b9102a1b9e6831bfbd7032aa22a244", - "core@0.6.0/src/internal/PRNG.mo": "8a93e87baa2b12f613c82394a4a05b425e44a695bbace4ca36f9a1f78be26442", - "core@0.6.0/src/VarArray.mo": "5cb4a5bcf4a135878e44230a3afd91cfd3e95b2e44092c8ab31a6ee377e151f6", - "core@0.6.0/src/pure/Queue.mo": "f43869d27e7392074297afd7d271a282c461ee1eb69105b269751ca22070ccce", - "core@0.6.0/src/pure/Map.mo": "33f63f1878f0474c6669363dde9ff6808ac992fa6353a7051b9a0c0cc7ee8f6c", - "core@0.6.0/src/pure/Set.mo": "57c3ba2b50af6f22d4bc62758520a08cdedfafe3980faece4878d8b59e9a746e", - "core@0.6.0/src/pure/RealTimeQueue.mo": "6e1f9a60d862f0bd214c205f70c98313ebc741f63ab62d3292c0d92d871c100f" + "core@2.0.0": { + "core@2.0.0/README.md": "d99a4e5563682e4ad38ad06d09c1395f9b6bbd1ce789660586a2e95c0347831c", + "core@2.0.0/LICENSE": "840e3d57a38a8061f55d04470fbd58b9345326fa04ea10ee42add5c6e3b2aa08", + "core@2.0.0/src/Blob.mo": "3f8846e1f7ad960ceb9c2473aec74ce3a20cc5731fcd197d95a2713afbec6ff9", + "core@2.0.0/mops.toml": "5ddc95fe515376948efe1be5b926784191c6c0e47427267c77cb425b4a5d3c29", + "core@2.0.0/NOTICE": "d62ca4ef9e2c9df064115c339013593cf0769e2b9dc78fa4b3211222541c7f83", + "core@2.0.0/src/Bool.mo": "3b606a6631f28c774e3055bc860201e56260fd32fdc5e8dc00d901506be95db5", + "core@2.0.0/src/Array.mo": "39fd012385c99f2a8a571da48c66daee3b4b83fcfbe8aeb4e23d98d65817e5ff", + "core@2.0.0/src/Cycles.mo": "9f5c1fceea47f05c43f22a1c25e8753fb7e552e36106d27bceef24b1310f4cbc", + "core@2.0.0/src/Float.mo": "d03ee038bd8b4b61f45ae27664ffe42287b7278b7f1ccc91d3774daa5d656933", + "core@2.0.0/src/CertifiedData.mo": "5af3182d77ab7aab2384d1f663a8cd992bbd6652aacff29c443314cf2186328f", + "core@2.0.0/src/Error.mo": "cf17271aa066577a4621ee2c207923f10947f5e2fdb99fcfe779a84979a8feaf", + "core@2.0.0/src/Char.mo": "a8d00178eb4b776fb6857f2521799f1103f43b8b201f4e94d540c6c47e1e716c", + "core@2.0.0/src/Debug.mo": "428a4e0af02fe57cad6834e952f036ef825cb76892c3ddd6ad808c048b1b3357", + "core@2.0.0/src/Int.mo": "e07ffc73de0accc26c356be4a208769c74b36e7e394a900dc47128ba894ed988", + "core@2.0.0/src/Func.mo": "535991ccca8d551d48129a0b7df03ea7bd6ebf3d74b1b572259d10ce709d7d46", + "core@2.0.0/src/Int16.mo": "f6d2721e3af1e70dfd196784a4af27dbf0c543f68569d04631c466e07a728ab1", + "core@2.0.0/src/Int32.mo": "eea42ea954fa1b7c7d8e86d4841c373c66e2a61fcc9fde7a87be0de33bb75d7f", + "core@2.0.0/src/Int64.mo": "9754e7ce183006903a0114bf31400c97bc271a217301864da121eca24fe425b4", + "core@2.0.0/src/List.mo": "263c61ad591bc94f5adfc27517122ce060b9f50425b52e4e01c2d0ed1ced029d", + "core@2.0.0/src/Iter.mo": "7d49f85312f607f1fc6b99c89e51a72ae4605a6638ea8252532210cfabeb2ecf", + "core@2.0.0/src/Int8.mo": "f4c3cc0d72d99d563e1c7ff0f6cdaf65aa5ad8d2ef2f5058d8285ca234deea72", + "core@2.0.0/src/InternetComputer.mo": "20383755c98801e560c17f9aefd9b4eb00463ee598125de1b39f6ae6fc8c60c9", + "core@2.0.0/src/Nat32.mo": "aceb48ea93a7dcd270e8555aa8177e9b9772d045c55716f109ce02d70c439683", + "core@2.0.0/src/Nat8.mo": "f40b216516ac4e1bf877f78bfc38928cf252622df8d6ecfef5700493018ea624", + "core@2.0.0/src/Option.mo": "aeec94cd6954e7b8b5463a5b15abddfb56c5322cb9b9e7ac782092d5c33a8b38", + "core@2.0.0/src/Nat64.mo": "c5ce5d691c2c04c1d920f567084a5465284adc5fb4961d400fb7f4c569b1b1af", + "core@2.0.0/src/Order.mo": "6c21e905e1e8c2b40cd50438218230c207d0bbec0d2514779edd76f9f84a812c", + "core@2.0.0/src/Map.mo": "71c1dd738868479cc9770470706f6f222ac9d7b4a2743f59b33b16b31fd98ac7", + "core@2.0.0/src/Nat.mo": "a1382b7b1b9baf7e7dd88767e50d19debcaa4235e753db7892c30b6f933585a7", + "core@2.0.0/src/Nat16.mo": "15f78bbecb38eb562c8b55d2a8568ffa28c498ff066988fc55107fc2b0e7953c", + "core@2.0.0/src/Runtime.mo": "5ac1290bec77ab04ae51df5fdc56ab4c6850823ffcd18e4140dfcc1b5a66cce3", + "core@2.0.0/src/Random.mo": "f5d48c30297b579a068af8cd8c6f4f986605e492b1b65424329a5171d1480e97", + "core@2.0.0/src/Queue.mo": "807ae8b4bdcaef6e37c57b65a93a04c0c5ed72f77e315e9916f5a25f62ce424f", + "core@2.0.0/src/Region.mo": "ef1726393401a7cafaebabde303debc31c1ef2f3b12bbfeca3850d1852148a95", + "core@2.0.0/src/PriorityQueue.mo": "a0ac43f32856c2902608062faefb35024879df5d87ecbe2b499195978f1fd00e", + "core@2.0.0/src/Set.mo": "d64fed0989da152d0a4baa81719bef548ad3f461367d5d434d14e98cb18281f0", + "core@2.0.0/src/Principal.mo": "f974da926ed30bdd69ef0505036e9fa183846b933be83f2135b81bcc2af08891", + "core@2.0.0/src/Result.mo": "0932722ab0187524c3c11539ccf2a1b9453438a9f3a042dde94e45d9c56a32c5", + "core@2.0.0/src/Time.mo": "e08d502d5eb3ca0ab7b4cce7322404faf1c72bc2bed7d2ded5a46d6afd80fd39", + "core@2.0.0/src/Stack.mo": "f70b2b978f37ebba351a5a5eb1b163a7ee9c2e579861ea1a14072b0bb57f1869", + "core@2.0.0/src/Timer.mo": "dee7c31d1d4fd29794da552a133bcb90fbd29e3ec004407d1d6a16f430ac8151", + "core@2.0.0/src/Text.mo": "d25b81756249cf768725b544da9ea3efe8262a3851fe8fa9ef0ccb97f699694c", + "core@2.0.0/src/VarArray.mo": "e91eb94403b89f5830afa9a8147e2a68eee8c5f672a8c4cdfd177aace8b3e02f", + "core@2.0.0/src/Types.mo": "00dc0132996b3bb3eaf5cc4413be78ca860137ef26f5b472b0e7b3ef68f6652f", + "core@2.0.0/src/WeakReference.mo": "06e58a6d67bf67c4b31ff871416d0cf6d6e34bfb409ce73d83372ef6b74de3cf", + "core@2.0.0/src/Tuples.mo": "2151dffc272c7d9ad6ff927432528d3893f220d414fbad237b9c6827006e5490", + "core@2.0.0/src/pure/List.mo": "b4fb45cf75410461fb1501a316d2384d1be63fee1fccf11ed1d29677e5e2393c", + "core@2.0.0/src/pure/Map.mo": "e9868fc4dd5e8e6272382e33241c59f8664e3de2e618cbf62fa8b20beabecfab", + "core@2.0.0/src/internal/BTreeHelper.mo": "20a475baf18f924ee0297fc234469fa0985cdaa31c85ce002b5a921383b0534d", + "core@2.0.0/src/internal/PRNG.mo": "8a93e87baa2b12f613c82394a4a05b425e44a695bbace4ca36f9a1f78be26442", + "core@2.0.0/src/pure/RealTimeQueue.mo": "ad0866b7bad9da97875e5e8d2f37e44909ac05899b244f844ffece6135559648", + "core@2.0.0/src/pure/Queue.mo": "21cfed3bb4aa4bf8265adcaaea4e0f4b7f34c3ee81abbb9e6b889efd4626a8b8", + "core@2.0.0/src/pure/Set.mo": "f0155b1d548cbc8889fcff75ef52f0cab7998b034621e4faac8d3b79d7bbac07" }, "xtended-text@2.0.0": { "xtended-text@2.0.0/src/CharX.mo": "2e4cfb328a39f88a3f6dda765582139c75cb7783159f1e3ee457fb9df107f9b5", diff --git a/mops.toml b/mops.toml index b9f5c1cb..c80ef279 100644 --- a/mops.toml +++ b/mops.toml @@ -10,6 +10,7 @@ http-types = "1.0.1" datetime = "1.0.0" principal-ext = "0.1.0" telegram-bot = "0.1.1" +core = "2.0.0" [dev-dependencies] test = "2.1.1" @@ -17,6 +18,5 @@ fuzz = "1.0.0" bench = "1.0.0" [toolchain] -moc = "0.14.14" -wasmtime = "34.0.1" -# pocket-ic = "9.0.3" \ No newline at end of file +moc = "1.0.0" +wasmtime = "34.0.1" \ No newline at end of file From 440958c93f0847fb6dd41e7b0c6a6db53408ba33 Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Mon, 22 Dec 2025 17:12:47 +0100 Subject: [PATCH 4/6] mops toml --- mops.lock | 110 +++++++++++++++++++++++++++--------------------------- mops.toml | 4 +- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/mops.lock b/mops.lock index b6f090e1..8cd87e38 100644 --- a/mops.lock +++ b/mops.lock @@ -1,6 +1,6 @@ { "version": 3, - "mopsTomlDepsHash": "d15fe96a0e23a36c49c0b38013457ad48ae622b71540da042a64dc2c32e89210", + "mopsTomlDepsHash": "722dc0bee276245351407defa34eb1cd2f96334559d4736d892f8871144cfeb1", "deps": { "base": "0.14.14", "time-consts": "1.0.1", @@ -17,7 +17,7 @@ "sha2": "0.1.0", "vector": "0.4.0", "datetime": "1.0.0", - "core": "2.0.0", + "core": "0.6.0", "xtended-text": "2.0.0", "xtended-numbers": "2.0.0", "buffer": "0.0.1", @@ -439,60 +439,58 @@ "datetime@1.0.0/iana/timezones/Universal.mo": "b14af8ce8270b2e1a8c90e6165041fa0eb5434da01c468c8dacadc76fb9628f7", "datetime@1.0.0/iana/timezones/US.mo": "e46acc3bfbcdb0c25efa8f24e62626918cb0a00a56302dc458110628dfb2fb9d" }, - "core@2.0.0": { - "core@2.0.0/README.md": "d99a4e5563682e4ad38ad06d09c1395f9b6bbd1ce789660586a2e95c0347831c", - "core@2.0.0/LICENSE": "840e3d57a38a8061f55d04470fbd58b9345326fa04ea10ee42add5c6e3b2aa08", - "core@2.0.0/src/Blob.mo": "3f8846e1f7ad960ceb9c2473aec74ce3a20cc5731fcd197d95a2713afbec6ff9", - "core@2.0.0/mops.toml": "5ddc95fe515376948efe1be5b926784191c6c0e47427267c77cb425b4a5d3c29", - "core@2.0.0/NOTICE": "d62ca4ef9e2c9df064115c339013593cf0769e2b9dc78fa4b3211222541c7f83", - "core@2.0.0/src/Bool.mo": "3b606a6631f28c774e3055bc860201e56260fd32fdc5e8dc00d901506be95db5", - "core@2.0.0/src/Array.mo": "39fd012385c99f2a8a571da48c66daee3b4b83fcfbe8aeb4e23d98d65817e5ff", - "core@2.0.0/src/Cycles.mo": "9f5c1fceea47f05c43f22a1c25e8753fb7e552e36106d27bceef24b1310f4cbc", - "core@2.0.0/src/Float.mo": "d03ee038bd8b4b61f45ae27664ffe42287b7278b7f1ccc91d3774daa5d656933", - "core@2.0.0/src/CertifiedData.mo": "5af3182d77ab7aab2384d1f663a8cd992bbd6652aacff29c443314cf2186328f", - "core@2.0.0/src/Error.mo": "cf17271aa066577a4621ee2c207923f10947f5e2fdb99fcfe779a84979a8feaf", - "core@2.0.0/src/Char.mo": "a8d00178eb4b776fb6857f2521799f1103f43b8b201f4e94d540c6c47e1e716c", - "core@2.0.0/src/Debug.mo": "428a4e0af02fe57cad6834e952f036ef825cb76892c3ddd6ad808c048b1b3357", - "core@2.0.0/src/Int.mo": "e07ffc73de0accc26c356be4a208769c74b36e7e394a900dc47128ba894ed988", - "core@2.0.0/src/Func.mo": "535991ccca8d551d48129a0b7df03ea7bd6ebf3d74b1b572259d10ce709d7d46", - "core@2.0.0/src/Int16.mo": "f6d2721e3af1e70dfd196784a4af27dbf0c543f68569d04631c466e07a728ab1", - "core@2.0.0/src/Int32.mo": "eea42ea954fa1b7c7d8e86d4841c373c66e2a61fcc9fde7a87be0de33bb75d7f", - "core@2.0.0/src/Int64.mo": "9754e7ce183006903a0114bf31400c97bc271a217301864da121eca24fe425b4", - "core@2.0.0/src/List.mo": "263c61ad591bc94f5adfc27517122ce060b9f50425b52e4e01c2d0ed1ced029d", - "core@2.0.0/src/Iter.mo": "7d49f85312f607f1fc6b99c89e51a72ae4605a6638ea8252532210cfabeb2ecf", - "core@2.0.0/src/Int8.mo": "f4c3cc0d72d99d563e1c7ff0f6cdaf65aa5ad8d2ef2f5058d8285ca234deea72", - "core@2.0.0/src/InternetComputer.mo": "20383755c98801e560c17f9aefd9b4eb00463ee598125de1b39f6ae6fc8c60c9", - "core@2.0.0/src/Nat32.mo": "aceb48ea93a7dcd270e8555aa8177e9b9772d045c55716f109ce02d70c439683", - "core@2.0.0/src/Nat8.mo": "f40b216516ac4e1bf877f78bfc38928cf252622df8d6ecfef5700493018ea624", - "core@2.0.0/src/Option.mo": "aeec94cd6954e7b8b5463a5b15abddfb56c5322cb9b9e7ac782092d5c33a8b38", - "core@2.0.0/src/Nat64.mo": "c5ce5d691c2c04c1d920f567084a5465284adc5fb4961d400fb7f4c569b1b1af", - "core@2.0.0/src/Order.mo": "6c21e905e1e8c2b40cd50438218230c207d0bbec0d2514779edd76f9f84a812c", - "core@2.0.0/src/Map.mo": "71c1dd738868479cc9770470706f6f222ac9d7b4a2743f59b33b16b31fd98ac7", - "core@2.0.0/src/Nat.mo": "a1382b7b1b9baf7e7dd88767e50d19debcaa4235e753db7892c30b6f933585a7", - "core@2.0.0/src/Nat16.mo": "15f78bbecb38eb562c8b55d2a8568ffa28c498ff066988fc55107fc2b0e7953c", - "core@2.0.0/src/Runtime.mo": "5ac1290bec77ab04ae51df5fdc56ab4c6850823ffcd18e4140dfcc1b5a66cce3", - "core@2.0.0/src/Random.mo": "f5d48c30297b579a068af8cd8c6f4f986605e492b1b65424329a5171d1480e97", - "core@2.0.0/src/Queue.mo": "807ae8b4bdcaef6e37c57b65a93a04c0c5ed72f77e315e9916f5a25f62ce424f", - "core@2.0.0/src/Region.mo": "ef1726393401a7cafaebabde303debc31c1ef2f3b12bbfeca3850d1852148a95", - "core@2.0.0/src/PriorityQueue.mo": "a0ac43f32856c2902608062faefb35024879df5d87ecbe2b499195978f1fd00e", - "core@2.0.0/src/Set.mo": "d64fed0989da152d0a4baa81719bef548ad3f461367d5d434d14e98cb18281f0", - "core@2.0.0/src/Principal.mo": "f974da926ed30bdd69ef0505036e9fa183846b933be83f2135b81bcc2af08891", - "core@2.0.0/src/Result.mo": "0932722ab0187524c3c11539ccf2a1b9453438a9f3a042dde94e45d9c56a32c5", - "core@2.0.0/src/Time.mo": "e08d502d5eb3ca0ab7b4cce7322404faf1c72bc2bed7d2ded5a46d6afd80fd39", - "core@2.0.0/src/Stack.mo": "f70b2b978f37ebba351a5a5eb1b163a7ee9c2e579861ea1a14072b0bb57f1869", - "core@2.0.0/src/Timer.mo": "dee7c31d1d4fd29794da552a133bcb90fbd29e3ec004407d1d6a16f430ac8151", - "core@2.0.0/src/Text.mo": "d25b81756249cf768725b544da9ea3efe8262a3851fe8fa9ef0ccb97f699694c", - "core@2.0.0/src/VarArray.mo": "e91eb94403b89f5830afa9a8147e2a68eee8c5f672a8c4cdfd177aace8b3e02f", - "core@2.0.0/src/Types.mo": "00dc0132996b3bb3eaf5cc4413be78ca860137ef26f5b472b0e7b3ef68f6652f", - "core@2.0.0/src/WeakReference.mo": "06e58a6d67bf67c4b31ff871416d0cf6d6e34bfb409ce73d83372ef6b74de3cf", - "core@2.0.0/src/Tuples.mo": "2151dffc272c7d9ad6ff927432528d3893f220d414fbad237b9c6827006e5490", - "core@2.0.0/src/pure/List.mo": "b4fb45cf75410461fb1501a316d2384d1be63fee1fccf11ed1d29677e5e2393c", - "core@2.0.0/src/pure/Map.mo": "e9868fc4dd5e8e6272382e33241c59f8664e3de2e618cbf62fa8b20beabecfab", - "core@2.0.0/src/internal/BTreeHelper.mo": "20a475baf18f924ee0297fc234469fa0985cdaa31c85ce002b5a921383b0534d", - "core@2.0.0/src/internal/PRNG.mo": "8a93e87baa2b12f613c82394a4a05b425e44a695bbace4ca36f9a1f78be26442", - "core@2.0.0/src/pure/RealTimeQueue.mo": "ad0866b7bad9da97875e5e8d2f37e44909ac05899b244f844ffece6135559648", - "core@2.0.0/src/pure/Queue.mo": "21cfed3bb4aa4bf8265adcaaea4e0f4b7f34c3ee81abbb9e6b889efd4626a8b8", - "core@2.0.0/src/pure/Set.mo": "f0155b1d548cbc8889fcff75ef52f0cab7998b034621e4faac8d3b79d7bbac07" + "core@0.6.0": { + "core@0.6.0/src/Array.mo": "a22df6109b7ab80bbe1a528d6e2b3d49e90c792cbc47d2cfadb5b9d5bccfd99e", + "core@0.6.0/NOTICE": "d62ca4ef9e2c9df064115c339013593cf0769e2b9dc78fa4b3211222541c7f83", + "core@0.6.0/README.md": "ef1e6c05db36d238f144b0cfa82cb1e6a68c94a5895619d32c55f7a190d25cff", + "core@0.6.0/LICENSE": "840e3d57a38a8061f55d04470fbd58b9345326fa04ea10ee42add5c6e3b2aa08", + "core@0.6.0/mops.toml": "be66822dab4ef108b780c82b27c3635625b25e2c5753d89ab707c9db13fcf674", + "core@0.6.0/src/Bool.mo": "a13590c559c53109e79ffff7de0506e59f1f93754ef2d0efa1df9baaf1751e95", + "core@0.6.0/src/Blob.mo": "58fe96119602151a6816db9817bfd3062526e15fac49c2a259fd2a5061266775", + "core@0.6.0/src/Float.mo": "20beea2c0d9039593cc28c638e289f42b3f5a9405b9a43c1fc76571cbb0e6f5d", + "core@0.6.0/src/Error.mo": "fb53abc8de032fa421e327a7fb4880345b7b8e91bbb84d9183d2172b7a9ec773", + "core@0.6.0/src/Func.mo": "c00d06b15e3376821020ceaaffae2a70bf206c672e746459ba1079adc6d1a619", + "core@0.6.0/src/CertifiedData.mo": "5af3182d77ab7aab2384d1f663a8cd992bbd6652aacff29c443314cf2186328f", + "core@0.6.0/src/Cycles.mo": "9d36e2196cb36430072b5b10c95f0b068e8e73db9362ac01f44459275d4d991d", + "core@0.6.0/src/Char.mo": "0d1146320d21048cd49663c9838b1a6ce7ec1add1ad256b51a1eac4bbe3f6be8", + "core@0.6.0/src/Debug.mo": "5c9398296ea0a913e2f356a3e169bb56df817248036aaa5c97507d29915143cf", + "core@0.6.0/src/Int.mo": "e3d48615e950a72dc5f0f052a47c3a66b6a86c8d1d2b25127f25852bd1595daa", + "core@0.6.0/src/Int32.mo": "6fb63738e2482ee6b361745a7c0b03f684cdfcfa578e1bae53a9e0df527f1f72", + "core@0.6.0/src/Int16.mo": "5102cbb40ff1ecdc005bdc96ded6ef3619aa840526d2b243c0463dbb758aa4a8", + "core@0.6.0/src/Iter.mo": "6098e63365cabe82046fd0100f53b029cc2693a438d0a7aafc7e930c8bb986b2", + "core@0.6.0/src/Int8.mo": "186de373b7857c3d6a6a3814285959e291088e8ae17de4a1bf2bd5e15490d511", + "core@0.6.0/src/InternetComputer.mo": "20383755c98801e560c17f9aefd9b4eb00463ee598125de1b39f6ae6fc8c60c9", + "core@0.6.0/src/Int64.mo": "05d49bb8a25ef1f49e8a164fd5a63cc03fd56c1bbb91f1b6d5096ba9bd9eb23a", + "core@0.6.0/src/Map.mo": "7380681b761ce0f8e9ae731b87fc378f1d2beb4bf1d47db742321f63f0d2559a", + "core@0.6.0/src/List.mo": "42017a2858014d34f95ae3949ca8db04b06e3ecb522cbc893be8fbf0a55fbe3f", + "core@0.6.0/src/Order.mo": "ebc93dd27cee7befd6e41794fb220f079dfb017145a76d77a225b2fcb3bbfd9e", + "core@0.6.0/src/Nat8.mo": "02c42e668f0fd95df5f864b4bbede58565a0a0395c6a04f6cb357f83090d245d", + "core@0.6.0/src/Nat16.mo": "0f83fbbbd2c4b0c71e9465e67273464faf32f126e59f3417476d536ee7e2ebbc", + "core@0.6.0/src/Nat64.mo": "9d8454be0bf9b234f5a5d308a1afdc02bc770a9d0d587bc23f8fba392a21ead9", + "core@0.6.0/src/Option.mo": "14e4f9d3332f778e0afa922e68852bf8fefcb885f1455770333867d120d64230", + "core@0.6.0/src/Nat.mo": "53fcb2ccbd3cbed4e2be7458a4548a55c317cac2a96ee97a9427d4518b9bc188", + "core@0.6.0/src/Nat32.mo": "e35fccf57b5a5aca880860481388c8d679b2289710a43d9acd5f77ed19984614", + "core@0.6.0/src/Principal.mo": "28d5b9f7c5296cd524b8878e46c390cd75e2839c3de72e7a61ecef5de424e296", + "core@0.6.0/src/Result.mo": "a3eed6fe0156ac5a10418c13397fab7bcbc803a95cfc12fdb4de159e97f5cc94", + "core@0.6.0/src/Region.mo": "c853ca2803d26f650e8e0cc0ba1b219664e7e0fdcea2a747f146f035dc5659dd", + "core@0.6.0/src/Random.mo": "7862375427f25ead3e87fb0443912cc2ff87987de105b8c82147988ade4a2654", + "core@0.6.0/src/Runtime.mo": "5ac1290bec77ab04ae51df5fdc56ab4c6850823ffcd18e4140dfcc1b5a66cce3", + "core@0.6.0/src/Queue.mo": "da65b9f1df3caaf23770dd35caa1400200f2f0b7cd4da0b15d3718dbef19c192", + "core@0.6.0/src/Stack.mo": "95d40067ad729faaf794fbe2e59e4566002dcce159e77d1c67d4a5d0a2281359", + "core@0.6.0/src/Text.mo": "9a941988aa79ef42008f52fbbb7ee43c24a2ea084265f1102d5cf658ac2d47e0", + "core@0.6.0/src/Set.mo": "db592ed58c0a333fd50303cf71fb47adf2e0660e0b53364c49a2aef536380db3", + "core@0.6.0/src/Timer.mo": "dee7c31d1d4fd29794da552a133bcb90fbd29e3ec004407d1d6a16f430ac8151", + "core@0.6.0/src/Types.mo": "05d93ce3e643d08bb76d7ea5d7b597e3d3de65b7b4fce59f06ed281fd3c8c046", + "core@0.6.0/src/Tuples.mo": "632c1d344d561df66c7092b13c9009e41f5c73d068f1ae13001ac55353c66376", + "core@0.6.0/src/Time.mo": "e08d502d5eb3ca0ab7b4cce7322404faf1c72bc2bed7d2ded5a46d6afd80fd39", + "core@0.6.0/src/internal/BTreeHelper.mo": "20a475baf18f924ee0297fc234469fa0985cdaa31c85ce002b5a921383b0534d", + "core@0.6.0/src/pure/List.mo": "e4a873f01cd5f923a43b7a4f86924f9348b9102a1b9e6831bfbd7032aa22a244", + "core@0.6.0/src/internal/PRNG.mo": "8a93e87baa2b12f613c82394a4a05b425e44a695bbace4ca36f9a1f78be26442", + "core@0.6.0/src/VarArray.mo": "5cb4a5bcf4a135878e44230a3afd91cfd3e95b2e44092c8ab31a6ee377e151f6", + "core@0.6.0/src/pure/Queue.mo": "f43869d27e7392074297afd7d271a282c461ee1eb69105b269751ca22070ccce", + "core@0.6.0/src/pure/Map.mo": "33f63f1878f0474c6669363dde9ff6808ac992fa6353a7051b9a0c0cc7ee8f6c", + "core@0.6.0/src/pure/Set.mo": "57c3ba2b50af6f22d4bc62758520a08cdedfafe3980faece4878d8b59e9a746e", + "core@0.6.0/src/pure/RealTimeQueue.mo": "6e1f9a60d862f0bd214c205f70c98313ebc741f63ab62d3292c0d92d871c100f" }, "xtended-text@2.0.0": { "xtended-text@2.0.0/src/CharX.mo": "2e4cfb328a39f88a3f6dda765582139c75cb7783159f1e3ee457fb9df107f9b5", diff --git a/mops.toml b/mops.toml index c80ef279..e12ac8ee 100644 --- a/mops.toml +++ b/mops.toml @@ -10,7 +10,6 @@ http-types = "1.0.1" datetime = "1.0.0" principal-ext = "0.1.0" telegram-bot = "0.1.1" -core = "2.0.0" [dev-dependencies] test = "2.1.1" @@ -19,4 +18,5 @@ bench = "1.0.0" [toolchain] moc = "1.0.0" -wasmtime = "34.0.1" \ No newline at end of file +wasmtime = "34.0.1" +# pocket-ic = "9.0.3" From b5f89d72e3d6a60b8e6184f5808c1b7b1ae76d4f Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Mon, 22 Dec 2025 17:13:39 +0100 Subject: [PATCH 5/6] drop M0235 --- cli/commands/fix.ts | 10 +--------- cli/tests/fix.test.ts | 3 +-- cli/tests/fix/m0235.mo | 13 ------------- 3 files changed, 2 insertions(+), 24 deletions(-) delete mode 100644 cli/tests/fix/m0235.mo diff --git a/cli/commands/fix.ts b/cli/commands/fix.ts index bbe0f52d..f3a6026e 100644 --- a/cli/commands/fix.ts +++ b/cli/commands/fix.ts @@ -7,7 +7,7 @@ import base from "motoko/packages/latest/base.json"; mo.loadPackage(base); // Enable all warning codes we can fix -mo.setExtraFlags(["-W", "M0223,M0235,M0236,M0237"]); +mo.setExtraFlags(["-W", "M0223,M0236,M0237"]); const readFile = promisify(fs.readFile); const writeFile = promisify(fs.writeFile); @@ -60,14 +60,6 @@ export const fix = async (file: string, options: { dryRun?: boolean }) => { }); } - // Fix M0235: Deprecation warning - // Note: Deprecation warnings can't be automatically fixed, but we skip them - // as they require manual code changes. The test may need adjustment. - if (diag.code === "M0235") { - // Skip - deprecation warnings require manual intervention - continue; - } - // Fix M0236: Dot notation suggestion if (diag.code === "M0236") { const match = diag.message.match( diff --git a/cli/tests/fix.test.ts b/cli/tests/fix.test.ts index 0ba88d49..682f9308 100644 --- a/cli/tests/fix.test.ts +++ b/cli/tests/fix.test.ts @@ -23,7 +23,7 @@ const cli = async (args: string[], { cwd }: CliOptions = {}) => { const MO_VERSION = "1.0.0"; // Enable all warning codes we test -const WARNING_FLAGS = "-W M0223,M0235,M0236,M0237"; +const WARNING_FLAGS = "-W M0223,M0236,M0237"; /** * Creates a temporary file from a source file and ensures cleanup @@ -101,7 +101,6 @@ describe("mops fix", () => { const testCases = [ { code: "M0223", file: "m0223.mo" }, - { code: "M0235", file: "m0235.mo" }, { code: "M0236", file: "m0236.mo" }, { code: "M0237", file: "m0237.mo" }, ]; diff --git a/cli/tests/fix/m0235.mo b/cli/tests/fix/m0235.mo deleted file mode 100644 index e0fd4073..00000000 --- a/cli/tests/fix/m0235.mo +++ /dev/null @@ -1,13 +0,0 @@ -module A { - /// @deprecated M0235 - public let foo = 5; - /// @deprecated M0235 - public func f(x : Nat) : Nat { x }; -}; - -module M { - public func main() { - ignore A.foo; // Deprecated field - ignore A.f(5); // Deprecated function - }; -}; From 303eef3175ab299ba3dd15519e19bb53a59a75dd Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Mon, 22 Dec 2025 17:41:14 +0100 Subject: [PATCH 6/6] set flags via argument --- cli/cli.ts | 5 ++++- cli/commands/fix.ts | 16 ++++++++-------- cli/tests/fix.test.ts | 4 ++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cli/cli.ts b/cli/cli.ts index 5e8e2230..a7bf8cd2 100755 --- a/cli/cli.ts +++ b/cli/cli.ts @@ -515,7 +515,10 @@ program .command("fix ") .description("Automatically fix code issues in a file") .option("--dry-run", "Show what would be fixed without modifying files") - .action(fix); + .allowExcessArguments(true) + .action(async (file, options) => { + await fix(file, { ...options, extraArgs: program.args }); + }); // bump program diff --git a/cli/commands/fix.ts b/cli/commands/fix.ts index f3a6026e..ea080896 100644 --- a/cli/commands/fix.ts +++ b/cli/commands/fix.ts @@ -2,13 +2,6 @@ import mo from "motoko"; import fs from "node:fs"; import { promisify } from "node:util"; -// @ts-ignore -import base from "motoko/packages/latest/base.json"; -mo.loadPackage(base); - -// Enable all warning codes we can fix -mo.setExtraFlags(["-W", "M0223,M0236,M0237"]); - const readFile = promisify(fs.readFile); const writeFile = promisify(fs.writeFile); @@ -32,13 +25,20 @@ interface Fix { message: string; } -export const fix = async (file: string, options: { dryRun?: boolean }) => { +export const fix = async ( + file: string, + options: { dryRun?: boolean; extraArgs?: string[] } = {}, +) => { console.log(`Checking for fixes in ${file}...`); try { const content = await readFile(file, "utf8"); mo.write(file, content); + if (options.extraArgs && options.extraArgs.length > 0) { + mo.setExtraFlags(options.extraArgs); + } + const diagnostics = mo.check(file) as any as Diagnostic[]; if (!diagnostics || diagnostics.length === 0) { diff --git a/cli/tests/fix.test.ts b/cli/tests/fix.test.ts index 682f9308..ce3ac949 100644 --- a/cli/tests/fix.test.ts +++ b/cli/tests/fix.test.ts @@ -23,7 +23,7 @@ const cli = async (args: string[], { cwd }: CliOptions = {}) => { const MO_VERSION = "1.0.0"; // Enable all warning codes we test -const WARNING_FLAGS = "-W M0223,M0236,M0237"; +const WARNING_FLAGS = "-W=M0223,M0236,M0237"; /** * Creates a temporary file from a source file and ensures cleanup @@ -116,7 +116,7 @@ describe("mops fix", () => { expect(beforeWarnings).toContain(code); // Run mops fix on the temp file - const fixResult = await cli(["fix", tmpFile]); + const fixResult = await cli(["fix", tmpFile, "--", WARNING_FLAGS]); expect(fixResult.exitCode).toBe(0); // Verify compilation after fix - should not have warnings or errors