Skip to content

Commit

Permalink
Support multi-line text literals (#103)
Browse files Browse the repository at this point in the history
* Bump motoko.rs to 0.0.27

* Add test cases

* Reformat

* 0.6.0

* Bump mo-fmt

* Test corner case

* Deactivate end-of-block semicolon insertion (relied on single-line text literals)

* 0.6.1

* Update unit tests

* Bump mo-fmt

* Run 'npm audit fix'
  • Loading branch information
rvanasa committed Jun 27, 2023
1 parent ea55aab commit 1583060
Show file tree
Hide file tree
Showing 8 changed files with 486 additions and 733 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "prettier-plugin-motoko",
"version": "0.5.3",
"version": "0.6.1",
"description": "A code formatter for the Motoko smart contract language.",
"main": "lib/environments/node.js",
"browser": "lib/environments/web.js",
Expand Down
1,096 changes: 420 additions & 676 deletions packages/mo-fmt/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/mo-fmt/package.json
@@ -1,6 +1,6 @@
{
"name": "mo-fmt",
"version": "0.5.3",
"version": "0.6.1",
"description": "An easy-to-use Motoko formatter command.",
"main": "src/cli.js",
"bin": {
Expand All @@ -21,7 +21,7 @@
"commander": "^9.4.0",
"fast-glob": "^3.2.11",
"prettier": "^2.7",
"prettier-plugin-motoko": "^0.5.3"
"prettier-plugin-motoko": "^0.6.1"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^22.0.2",
Expand Down
1 change: 0 additions & 1 deletion src/options.ts
Expand Up @@ -2,7 +2,6 @@ import { SupportOption } from 'prettier';

const options: Record<string, SupportOption> = {
// replaceComma: {

// },
};

Expand Down
71 changes: 31 additions & 40 deletions src/parsers/motoko-tt-parse/preprocess.ts
@@ -1,8 +1,6 @@
import { ParserOptions } from 'prettier';
import outOfCharacter from 'out-of-character';

const LINE_COMMENT = '//';

export default function preprocess(
code: string,
options: ParserOptions<any>,
Expand All @@ -11,44 +9,37 @@ export default function preprocess(
code = code.replace(/[ \t]+(?=\r?\n)/g, ''); // remove trailing spaces
code = outOfCharacter.replace(code); // remove invisible unicode characters

if (options.semi) {
// Infer semicolons
let nextIndent = 0;
const reversedLines = code.split('\n').reverse();
code = reversedLines
.map((line: string, i: number) => {
const trimmedLine = line.trim();
if (!trimmedLine) {
return line;
}
// if (trimmedLine.startsWith(LINE_COMMENT)) {
// const comment = trimmedLine
// .substring(LINE_COMMENT.length)
// .trim();
// return line;
// }

let indent = 0;
while (indent < line.length && line.charAt(indent) === ' ') {
indent++;
}

const nextTrimmedLine = (reversedLines[i - 1] || '').trim();
// const previousTrimmedLine = (lines[i + 1] || '').trim();

if (
trimmedLine === '}' &&
!/^(else|catch)([^a-zA-Z0-9_]|$)/.test(nextTrimmedLine)
) {
line += ';';
}

nextIndent = indent;
return line;
})
.reverse()
.join('\n');
}
// if (options.semi) {
// // Infer semicolons
// let nextIndent = 0;
// const reversedLines = code.split('\n').reverse();
// code = reversedLines
// .map((line: string, i: number) => {
// const trimmedLine = line.trim();
// if (!trimmedLine) {
// return line;
// }

// let indent = 0;
// while (indent < line.length && line.charAt(indent) === ' ') {
// indent++;
// }

// const nextTrimmedLine = (reversedLines[i - 1] || '').trim();

// if (
// trimmedLine === '}' &&
// !/^(else|catch)([^a-zA-Z0-9_]|$)/.test(nextTrimmedLine)
// ) {
// line += ';';
// }

// nextIndent = indent;
// return line;
// })
// .reverse()
// .join('\n');
// }

return code;
}
39 changes: 29 additions & 10 deletions tests/formatter.test.ts
Expand Up @@ -42,7 +42,7 @@ describe('Motoko formatter', () => {

test('line comments', () => {
expect(format('{//\n}//')).toStrictEqual('{\n //\n} //\n');
expect(format('{\n//\n}\n//')).toStrictEqual('{\n //\n};\n//\n');
expect(format('{\n//\n};\n//')).toStrictEqual('{\n //\n};\n//\n');
expect(format('//a\n//b')).toStrictEqual('//a\n//b\n');
expect(format('//a\n\n\n//b')).toStrictEqual('//a\n\n//b\n');
});
Expand Down Expand Up @@ -304,7 +304,9 @@ describe('Motoko formatter', () => {
});

test('prettier-ignore line comment as first line in block', () => {
expect(format('{\n// prettier-ignore\n 123}')).toStrictEqual('{\n // prettier-ignore\n 123\n};\n');
expect(format('{\n// prettier-ignore\n 123}')).toStrictEqual(
'{\n // prettier-ignore\n 123\n};\n',
);
});

test('unclosed quotes in comments', () => {
Expand All @@ -330,10 +332,10 @@ describe('Motoko formatter', () => {
expect(format('0.\ny')).toStrictEqual('0.\ny;\n');
});

test('automatic semicolons', () => {
expect(format('{\n}\nA\n')).toStrictEqual('{};\nA;\n');
expect(format('{\n// }\n}\nA\n')).toStrictEqual('{\n // }\n};\nA;\n');
});
// test('automatic semicolons', () => {
// expect(format('{\n}\nA\n')).toStrictEqual('{};\nA;\n');
// expect(format('{\n// }\n}\nA\n')).toStrictEqual('{\n // }\n};\nA;\n');
// });

test('conditional parentheses', () => {
expect(format('if a b')).toStrictEqual('if a b\n');
Expand Down Expand Up @@ -375,9 +377,26 @@ describe('Motoko formatter', () => {
});

test('`with` keyword', () => {
expect(format('{a and b with c = d}')).toStrictEqual('{ a and b with c = d }\n');
expect(format('{a and b with\nc = d}')).toStrictEqual('{\n a and b with\n c = d\n};\n');
expect(format('{a and b with \nc = d}')).toStrictEqual('{\n a and b with\n c = d\n};\n');
expect(format('{a and b with\nc = d; e = f;}')).toStrictEqual('{\n a and b with\n c = d;\n e = f;\n};\n');
expect(format('{a and b with c = d}')).toStrictEqual(
'{ a and b with c = d }\n',
);
expect(format('{a and b with\nc = d}')).toStrictEqual(
'{\n a and b with\n c = d\n};\n',
);
expect(format('{a and b with \nc = d}')).toStrictEqual(
'{\n a and b with\n c = d\n};\n',
);
expect(format('{a and b with\nc = d; e = f;}')).toStrictEqual(
'{\n a and b with\n c = d;\n e = f;\n};\n',
);
});

test('multi-line text', () => {
expectFormatted('"A\nB"\n');
expectFormatted('" A\n B"\n');
expectFormatted('"A\n\nB"\n');
expectFormatted('"A\n\n B"\n');
expectFormatted('"\nA\n\n B\n "\n');
expectFormatted('"\n\n{\n}\n\n"\n');
});
});
2 changes: 1 addition & 1 deletion wasm/Cargo.toml
Expand Up @@ -15,7 +15,7 @@ serde = { version = "1.0.143", features = ["derive"] }
serde_json = "1.0.83"
wasm-bindgen = { version = "=0.2.82" }
serde-wasm-bindgen = "=0.4.3"
motoko = "0.0.26"
motoko = "0.0.27"

console_error_panic_hook = { version = "0.1.6", optional = true }

Expand Down

0 comments on commit 1583060

Please sign in to comment.