Skip to content

Commit 3f5dcac

Browse files
authored
multiline strings should be indented and grouped (#1436)
* multiline strings should be indented and grouped * ignore ANTLR mismatch
1 parent b52ba5c commit 3f5dcac

6 files changed

Lines changed: 128 additions & 14 deletions

File tree

src/slang-nodes/AssignmentExpression.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst';
22
import { isBinaryOperation } from '../slang-utils/is-binary-operation.js';
33
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
44
import { extractVariant } from '../slang-utils/extract-variant.js';
5+
import { isMultilineString } from '../slang-utils/is-multiline-string.js';
56
import { SlangNode } from './SlangNode.js';
67
import { Expression } from './Expression.js';
78
import { TerminalNode } from './TerminalNode.js';
@@ -45,7 +46,8 @@ export class AssignmentExpression extends SlangNode {
4546
printIndentedGroupOrSpacedDocument(
4647
path.call(print, 'rightOperand'),
4748
!(this.rightOperand instanceof TerminalNode) &&
48-
isBinaryOperation(this.rightOperand)
49+
(isBinaryOperation(this.rightOperand) ||
50+
isMultilineString(this.rightOperand))
4951
)
5052
];
5153
}

src/slang-nodes/VariableDeclarationValue.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { NonterminalKind } from '@nomicfoundation/slang/cst';
22
import { extractVariant } from '../slang-utils/extract-variant.js';
3+
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
4+
import { isMultilineString } from '../slang-utils/is-multiline-string.js';
35
import { SlangNode } from './SlangNode.js';
46
import { Expression } from './Expression.js';
7+
import { TerminalNode } from './TerminalNode.js';
58

69
import type * as ast from '@nomicfoundation/slang/ast';
710
import type { AstPath, Doc, ParserOptions } from 'prettier';
@@ -28,6 +31,13 @@ export class VariableDeclarationValue extends SlangNode {
2831
}
2932

3033
print(path: AstPath<VariableDeclarationValue>, print: PrintFunction): Doc {
31-
return [' = ', path.call(print, 'expression')];
34+
return [
35+
' =',
36+
printIndentedGroupOrSpacedDocument(
37+
path.call(print, 'expression'),
38+
!(this.expression instanceof TerminalNode) &&
39+
isMultilineString(this.expression)
40+
)
41+
];
3242
}
3343
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { NonterminalKind } from '@nomicfoundation/slang/cst';
2+
import { createKindCheckFunction } from './create-kind-check-function.js';
3+
4+
import type { StrictAstNode } from '../slang-nodes/types.js';
5+
import type { StringLiterals } from '../slang-nodes/StringLiterals.js';
6+
import type { HexStringLiterals } from '../slang-nodes/HexStringLiterals.js';
7+
import type { UnicodeStringLiterals } from '../slang-nodes/UnicodeStringLiterals.js';
8+
9+
export const isMultilineString = createKindCheckFunction([
10+
NonterminalKind.StringLiterals,
11+
NonterminalKind.HexStringLiterals,
12+
NonterminalKind.UnicodeStringLiterals
13+
]) as (
14+
node: StrictAstNode
15+
) => node is StringLiterals | HexStringLiterals | UnicodeStringLiterals;

tests/config/run-format-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ const antlrMismatchTests = new Map(
8585
// ANTLR doesn't support UntypedTupleMember with a storage location, which
8686
// is valid Slang, but not in Solidity.
8787
"AllSolidityFeaturesV0.4.26/AllSolidityFeatures.sol",
88+
// TODO: Review why this test doesn't match.
89+
"MultipartStrings/MultipartStrings.sol",
8890
].map((fixture) => {
8991
const [file, compareBytecode = () => true] = Array.isArray(fixture)
9092
? fixture
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
contract MultipartStrings {
2-
bytes b1 = hex'beef';
3-
bytes b2 = hex"beef";
4-
bytes b3 = hex"beef" hex"c0ffee";
5-
bytes b4 = hex"beeeeeeeeeeeeeeeeeeeeeef" hex"c0000000000ffeeeeeeeeeeeeeeeeeee";
2+
bytes h1 = hex'beef';
3+
bytes h2 = hex"beef";
4+
bytes h3 = hex"beef" hex"c0ffee";
5+
bytes h4 = hex"beeeeeeeeeeeeeeeeeeeeeef" hex"c0000000000ffeeeeeeeeeeeeeeeeeee";
66

77
string s1 = "foo";
88
string s2 = "foo" "bar";
99
string s3 = "foofoofoofooofoofoofofoooofofoo" "barbarbrabrbarbarbabrabrbabr";
10+
11+
string u1 = unicode'hello 🦄';
12+
string u2 = unicode'hello 🦄' unicode' world 🦄';
13+
string u3 = unicode'hellohellohellohellohellohello 🦄' unicode' worldworldworldworldworldworld 🦄';
14+
15+
function multilineString() public pure {
16+
bytes hex1 = hex'DeadBeef00' hex'DeadBeef01' hex'DeadBeef02' hex'DeadBeef03' hex'DeadBeef04' hex'DeadBeef05';
17+
hex1 = hex'DeadBeef0a' hex'DeadBeef0b' hex'DeadBeef0c' hex'DeadBeef0d' hex'DeadBeef0e' hex'DeadBeef0f';
18+
19+
string str = 'DeadBeef00' 'DeadBeef01' 'DeadBeef02' 'DeadBeef03' 'DeadBeef04' 'DeadBeef05';
20+
str = 'DeadBeef0a' 'DeadBeef0b' 'DeadBeef0c' 'DeadBeef0d' 'DeadBeef0e' 'DeadBeef0f';
21+
22+
string uni = unicode'DeadBeef00🦄' unicode'DeadBeef01🦄' unicode'DeadBeef02🦄' unicode'DeadBeef03🦄' unicode'DeadBeef04🦄' unicode'DeadBeef05🦄';
23+
uni = unicode'DeadBeef0a🦄' unicode'DeadBeef0b🦄' unicode'DeadBeef0c🦄' unicode'DeadBeef0d🦄' unicode'DeadBeef0e🦄' unicode'DeadBeef0f🦄';
24+
}
1025
}

tests/format/MultipartStrings/__snapshots__/format.test.js.snap

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,39 @@ printWidth: 80
77
| printWidth
88
=====================================input======================================
99
contract MultipartStrings {
10-
bytes b1 = hex'beef';
11-
bytes b2 = hex"beef";
12-
bytes b3 = hex"beef" hex"c0ffee";
13-
bytes b4 = hex"beeeeeeeeeeeeeeeeeeeeeef" hex"c0000000000ffeeeeeeeeeeeeeeeeeee";
10+
bytes h1 = hex'beef';
11+
bytes h2 = hex"beef";
12+
bytes h3 = hex"beef" hex"c0ffee";
13+
bytes h4 = hex"beeeeeeeeeeeeeeeeeeeeeef" hex"c0000000000ffeeeeeeeeeeeeeeeeeee";
1414
1515
string s1 = "foo";
1616
string s2 = "foo" "bar";
1717
string s3 = "foofoofoofooofoofoofofoooofofoo" "barbarbrabrbarbarbabrabrbabr";
18+
19+
string u1 = unicode'hello 🦄';
20+
string u2 = unicode'hello 🦄' unicode' world 🦄';
21+
string u3 = unicode'hellohellohellohellohellohello 🦄' unicode' worldworldworldworldworldworld 🦄';
22+
23+
function multilineString() public pure {
24+
bytes hex1 = hex'DeadBeef00' hex'DeadBeef01' hex'DeadBeef02' hex'DeadBeef03' hex'DeadBeef04' hex'DeadBeef05';
25+
hex1 = hex'DeadBeef0a' hex'DeadBeef0b' hex'DeadBeef0c' hex'DeadBeef0d' hex'DeadBeef0e' hex'DeadBeef0f';
26+
27+
string str = 'DeadBeef00' 'DeadBeef01' 'DeadBeef02' 'DeadBeef03' 'DeadBeef04' 'DeadBeef05';
28+
str = 'DeadBeef0a' 'DeadBeef0b' 'DeadBeef0c' 'DeadBeef0d' 'DeadBeef0e' 'DeadBeef0f';
29+
30+
string uni = unicode'DeadBeef00🦄' unicode'DeadBeef01🦄' unicode'DeadBeef02🦄' unicode'DeadBeef03🦄' unicode'DeadBeef04🦄' unicode'DeadBeef05🦄';
31+
uni = unicode'DeadBeef0a🦄' unicode'DeadBeef0b🦄' unicode'DeadBeef0c🦄' unicode'DeadBeef0d🦄' unicode'DeadBeef0e🦄' unicode'DeadBeef0f🦄';
32+
}
1833
}
1934
2035
=====================================output=====================================
2136
contract MultipartStrings {
22-
bytes b1 = hex"beef";
23-
bytes b2 = hex"beef";
24-
bytes b3 =
37+
bytes h1 = hex"beef";
38+
bytes h2 = hex"beef";
39+
bytes h3 =
2540
hex"beef"
2641
hex"c0ffee";
27-
bytes b4 =
42+
bytes h4 =
2843
hex"beeeeeeeeeeeeeeeeeeeeeef"
2944
hex"c0000000000ffeeeeeeeeeeeeeeeeeee";
3045
@@ -35,6 +50,61 @@ contract MultipartStrings {
3550
string s3 =
3651
"foofoofoofooofoofoofofoooofofoo"
3752
"barbarbrabrbarbarbabrabrbabr";
53+
54+
string u1 = unicode"hello 🦄";
55+
string u2 =
56+
unicode"hello 🦄"
57+
unicode" world 🦄";
58+
string u3 =
59+
unicode"hellohellohellohellohellohello 🦄"
60+
unicode" worldworldworldworldworldworld 🦄";
61+
62+
function multilineString() public pure {
63+
bytes hex1 =
64+
hex"DeadBeef00"
65+
hex"DeadBeef01"
66+
hex"DeadBeef02"
67+
hex"DeadBeef03"
68+
hex"DeadBeef04"
69+
hex"DeadBeef05";
70+
hex1 =
71+
hex"DeadBeef0a"
72+
hex"DeadBeef0b"
73+
hex"DeadBeef0c"
74+
hex"DeadBeef0d"
75+
hex"DeadBeef0e"
76+
hex"DeadBeef0f";
77+
78+
string str =
79+
"DeadBeef00"
80+
"DeadBeef01"
81+
"DeadBeef02"
82+
"DeadBeef03"
83+
"DeadBeef04"
84+
"DeadBeef05";
85+
str =
86+
"DeadBeef0a"
87+
"DeadBeef0b"
88+
"DeadBeef0c"
89+
"DeadBeef0d"
90+
"DeadBeef0e"
91+
"DeadBeef0f";
92+
93+
string uni =
94+
unicode"DeadBeef00🦄"
95+
unicode"DeadBeef01🦄"
96+
unicode"DeadBeef02🦄"
97+
unicode"DeadBeef03🦄"
98+
unicode"DeadBeef04🦄"
99+
unicode"DeadBeef05🦄";
100+
uni =
101+
unicode"DeadBeef0a🦄"
102+
unicode"DeadBeef0b🦄"
103+
unicode"DeadBeef0c🦄"
104+
unicode"DeadBeef0d🦄"
105+
unicode"DeadBeef0e🦄"
106+
unicode"DeadBeef0f🦄";
107+
}
38108
}
39109
40110
================================================================================

0 commit comments

Comments
 (0)