Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/binary-operator-printers/assignment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { doc } from 'prettier';
import { printAssignmentRightSide } from '../common/printer-helpers.js';

const { group, line, indent } = doc.builders;

Expand All @@ -19,10 +20,7 @@ export const assignment = {
].includes(op),
print: (node, path, print) => [
path.call(print, 'left'),
' ',
node.operator,
node.right.type === 'BinaryOperation'
? group(indent([line, path.call(print, 'right')]))
: [' ', path.call(print, 'right')]
` ${node.operator}`,
printAssignmentRightSide(path.call(print, 'right'), node.right)
]
};
11 changes: 11 additions & 0 deletions src/common/printer-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,14 @@ export const printSeparatedList = (
lastSeparator,
grouped
});

export const printAssignmentRightSide = (document, value) =>
[
'TupleExpression',
'FunctionCall',
'IndexAccess',
'NameValueExpression',
'MemberAccess'
].includes(value.type)
? [' ', document]
: group(indent([line, document]));
6 changes: 1 addition & 5 deletions src/nodes/Conditional.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ const experimentalTernaries = (node, path, print, options) => {
})
];

const document = group([conditionAndTrueExpressionGroup, falseExpressionDoc]);

return parent.type === 'VariableDeclarationStatement'
? indent([softline, document])
: document;
return group([conditionAndTrueExpressionGroup, falseExpressionDoc]);
};

const traditionalTernaries = (path, print) =>
Expand Down
9 changes: 7 additions & 2 deletions src/nodes/FileLevelConstant.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { printAssignmentRightSide } from '../common/printer-helpers.js';

export const FileLevelConstant = {
print: ({ node, path, print }) => [
path.call(print, 'typeName'),
' constant ',
node.name,
' = ',
path.call(print, 'initialValue'),
' =',
printAssignmentRightSide(
path.call(print, 'initialValue'),
node.initialValue
),
';'
]
};
16 changes: 8 additions & 8 deletions src/nodes/StateVariableDeclaration.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { doc } from 'prettier';

const { group, indent, line } = doc.builders;
import { printAssignmentRightSide } from '../common/printer-helpers.js';

const initialValue = (node, path, print) => {
if (!node.initialValue) {
return '';
}

if (node.initialValue.type === 'TupleExpression') {
return [' = ', path.call(print, 'initialValue')];
}

return group([' =', indent([line, path.call(print, 'initialValue')])]);
return [
' =',
printAssignmentRightSide(
path.call(print, 'initialValue'),
node.initialValue
)
];
};

export const StateVariableDeclaration = {
Expand Down
22 changes: 18 additions & 4 deletions src/nodes/VariableDeclarationStatement.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import { doc } from 'prettier';
import { printSeparatedList } from '../common/printer-helpers.js';
import {
printAssignmentRightSide,
printSeparatedList
} from '../common/printer-helpers.js';

const { group, indentIfBreak } = doc.builders;
const { group, indentIfBreak, line } = doc.builders;

const embraceVariables = (document, embrace) =>
embrace ? ['(', printSeparatedList(document), ')'] : document;

const initialValue = (node, path, print) =>
node.initialValue ? [' = ', path.call(print, 'initialValue')] : '';
const initialValue = (node, path, print) => {
if (!node.initialValue) {
return '';
}

return [
' =',
printAssignmentRightSide(
path.call(print, 'initialValue'),
node.initialValue
)
];
};

export const VariableDeclarationStatement = {
print: ({ node, path, print }) => {
Expand Down
11 changes: 3 additions & 8 deletions src/slang-nodes/AssignmentExpression.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { isBinaryOperation } from '../slang-utils/is-binary-operation.js';
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
import { extractVariant } from '../slang-utils/extract-variant.js';
import { isMultilineString } from '../slang-utils/is-multiline-string.js';
import { printAssignmentRightSide } from '../slang-printers/print-assignment-right-side.js';
import { SlangNode } from './SlangNode.js';
import { Expression } from './Expression.js';
import { TerminalNode } from './TerminalNode.js';

import type * as ast from '@nomicfoundation/slang/ast';
import type { AstPath, Doc, ParserOptions } from 'prettier';
Expand Down Expand Up @@ -43,11 +40,9 @@ export class AssignmentExpression extends SlangNode {
return [
path.call(print, 'leftOperand'),
` ${this.operator}`,
printIndentedGroupOrSpacedDocument(
printAssignmentRightSide(
path.call(print, 'rightOperand'),
!(this.rightOperand instanceof TerminalNode) &&
(isBinaryOperation(this.rightOperand) ||
isMultilineString(this.rightOperand))
this.rightOperand
)
];
}
Expand Down
8 changes: 2 additions & 6 deletions src/slang-nodes/ConditionalExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { AstPath, Doc, ParserOptions } from 'prettier';
import type { CollectedMetadata, PrintFunction } from '../types.d.ts';
import type { AstNode, StrictAstNode } from './types.d.ts';

const { group, hardline, ifBreak, indent, line, softline } = doc.builders;
const { group, hardline, ifBreak, indent, line } = doc.builders;

function experimentalTernaries(
node: ConditionalExpression,
Expand Down Expand Up @@ -73,11 +73,7 @@ function experimentalTernaries(
)
];

const document = group([conditionAndTrueExpressionGroup, falseExpressionDoc]);

return parent.kind === NonterminalKind.VariableDeclarationValue
? group(indent([softline, document]))
: document;
return group([conditionAndTrueExpressionGroup, falseExpressionDoc]);
}

function traditionalTernaries(
Expand Down
5 changes: 3 additions & 2 deletions src/slang-nodes/ConstantDefinition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { extractVariant } from '../slang-utils/extract-variant.js';
import { printAssignmentRightSide } from '../slang-printers/print-assignment-right-side.js';
import { SlangNode } from './SlangNode.js';
import { TypeName } from './TypeName.js';
import { TerminalNode } from './TerminalNode.js';
Expand Down Expand Up @@ -40,8 +41,8 @@ export class ConstantDefinition extends SlangNode {
path.call(print, 'typeName'),
' constant ',
path.call(print, 'name'),
' = ',
path.call(print, 'value'),
' =',
printAssignmentRightSide(path.call(print, 'value'), this.value),
';'
];
}
Expand Down
14 changes: 4 additions & 10 deletions src/slang-nodes/MemberAccessExpression.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { doc } from 'prettier';
import { isLabel } from '../slang-utils/is-label.js';
import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js';
import { extractVariant } from '../slang-utils/extract-variant.js';
import { isChainableExpression } from '../slang-utils/is-chainable-expression.js';
import { SlangNode } from './SlangNode.js';
import { Expression } from './Expression.js';
import { TerminalNode } from './TerminalNode.js';

import type * as ast from '@nomicfoundation/slang/ast';
import type { AstPath, Doc, ParserOptions } from 'prettier';
import type { CollectedMetadata, PrintFunction } from '../types.d.ts';
import type { AstNode, StrictAstNode } from './types.d.ts';
import type { AstNode } from './types.d.ts';

const { group, indent, label, softline } = doc.builders;

const isChainableExpression = createKindCheckFunction([
NonterminalKind.FunctionCallExpression,
NonterminalKind.IndexAccessExpression,
NonterminalKind.MemberAccessExpression
]);

function isEndOfChain(
node: MemberAccessExpression,
path: AstPath<StrictAstNode>
path: AstPath<Expression['variant']>
): boolean {
for (
let i = 1, current: StrictAstNode = node, parent = path.getNode(i);
let i = 1, current: Expression['variant'] = node, parent = path.getNode(i);
parent && isChainableExpression(parent);
i++, current = parent, parent = path.getNode(i)
) {
Expand Down
7 changes: 2 additions & 5 deletions src/slang-nodes/StateVariableDefinitionValue.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
import { printAssignmentRightSide } from '../slang-printers/print-assignment-right-side.js';
import { extractVariant } from '../slang-utils/extract-variant.js';
import { SlangNode } from './SlangNode.js';
import { Expression } from './Expression.js';
Expand Down Expand Up @@ -32,10 +32,7 @@ export class StateVariableDefinitionValue extends SlangNode {
): Doc {
return [
' =',
printIndentedGroupOrSpacedDocument(
path.call(print, 'value'),
this.value.kind !== NonterminalKind.ArrayExpression
)
printAssignmentRightSide(path.call(print, 'value'), this.value)
];
}
}
10 changes: 2 additions & 8 deletions src/slang-nodes/VariableDeclarationValue.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { printAssignmentRightSide } from '../slang-printers/print-assignment-right-side.js';
import { extractVariant } from '../slang-utils/extract-variant.js';
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
import { isMultilineString } from '../slang-utils/is-multiline-string.js';
import { SlangNode } from './SlangNode.js';
import { Expression } from './Expression.js';
import { TerminalNode } from './TerminalNode.js';

import type * as ast from '@nomicfoundation/slang/ast';
import type { AstPath, Doc, ParserOptions } from 'prettier';
Expand Down Expand Up @@ -33,11 +31,7 @@ export class VariableDeclarationValue extends SlangNode {
print(path: AstPath<VariableDeclarationValue>, print: PrintFunction): Doc {
return [
' =',
printIndentedGroupOrSpacedDocument(
path.call(print, 'expression'),
!(this.expression instanceof TerminalNode) &&
isMultilineString(this.expression)
)
printAssignmentRightSide(path.call(print, 'expression'), this.expression)
];
}
}
17 changes: 17 additions & 0 deletions src/slang-printers/print-assignment-right-side.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { isChainableExpression } from '../slang-utils/is-chainable-expression.js';
import { printIndentedGroupOrSpacedDocument } from './print-indented-group-or-spaced-document.js';

import type { Doc, doc } from 'prettier';
import type { Expression } from '../slang-nodes/Expression.js';

export function printAssignmentRightSide(
document: Doc,
value: Expression['variant']
): doc.builders.Group | [' ', Doc] {
return printIndentedGroupOrSpacedDocument(
document,
value.kind !== NonterminalKind.ArrayExpression &&
!isChainableExpression(value)
);
}
10 changes: 10 additions & 0 deletions src/slang-utils/is-chainable-expression.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { NonterminalKind } from '@nomicfoundation/slang/cst';
import { createKindCheckFunction } from './create-kind-check-function.js';

import type { Expression } from '../slang-nodes/Expression.js';

export const isChainableExpression = createKindCheckFunction([
NonterminalKind.FunctionCallExpression,
NonterminalKind.IndexAccessExpression,
NonterminalKind.MemberAccessExpression
]) as (node: Expression['variant']) => boolean;
15 changes: 0 additions & 15 deletions src/slang-utils/is-multiline-string.ts

This file was deleted.

2 changes: 0 additions & 2 deletions tests/config/run-format-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ const antlrMismatchTests = new Map(
// ANTLR doesn't support UntypedTupleMember with a storage location, which
// is valid Slang, but not in Solidity.
"AllSolidityFeaturesV0.4.26/AllSolidityFeatures.sol",
// TODO: Review why this test doesn't match.
"MultipartStrings/MultipartStrings.sol",
].map((fixture) => {
const [file, compareBytecode = () => true] = Array.isArray(fixture)
? fixture
Expand Down
36 changes: 20 additions & 16 deletions tests/format/BinaryOperators/__snapshots__/format.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,11 @@ contract ComparisonOperators {
a = veryVeryVeryVeryVeryLongVariableCalledA;
veryVeryVeryVeryVeryLongVariableCalledB
>= veryVeryVeryVeryVeryLongVariableCalledA;
a += veryVeryVeryVeryVeryLongVariableCalledA
|| veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
a +=
veryVeryVeryVeryVeryLongVariableCalledA
|| veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
) {}
a(
veryVeryVeryVeryVeryLongVariableCalledA
Expand Down Expand Up @@ -635,10 +636,11 @@ contract LogicalOperators {
for (
a = veryVeryVeryVeryVeryLongVariableCalledA;
a <= veryVeryVeryVeryVeryLongVariableCalledA;
a += veryVeryVeryVeryVeryLongVariableCalledA
|| veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
a +=
veryVeryVeryVeryVeryLongVariableCalledA
|| veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
) {}
a(
veryVeryVeryVeryVeryLongVariableCalledA
Expand Down Expand Up @@ -1163,10 +1165,11 @@ contract ComparisonOperators {
a = veryVeryVeryVeryVeryLongVariableCalledA;
veryVeryVeryVeryVeryLongVariableCalledB >=
veryVeryVeryVeryVeryLongVariableCalledA;
a += veryVeryVeryVeryVeryLongVariableCalledA ||
veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
a +=
veryVeryVeryVeryVeryLongVariableCalledA ||
veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
) {}
a(
veryVeryVeryVeryVeryLongVariableCalledA ==
Expand Down Expand Up @@ -1316,10 +1319,11 @@ contract LogicalOperators {
for (
a = veryVeryVeryVeryVeryLongVariableCalledA;
a <= veryVeryVeryVeryVeryLongVariableCalledA;
a += veryVeryVeryVeryVeryLongVariableCalledA ||
veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
a +=
veryVeryVeryVeryVeryLongVariableCalledA ||
veryVeryVeryVeryVeryLongVariableCalledB
? 1
: 2
) {}
a(
veryVeryVeryVeryVeryLongVariableCalledA ||
Expand Down
5 changes: 2 additions & 3 deletions tests/format/Conditional/__snapshots__/format.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ pragma solidity ^0.4.24;

contract Conditional {
function foo() {
address contextAddress = longAddress_ == address(0)
? msg.sender
: currentContextAddress_;
address contextAddress =
longAddress_ == address(0) ? msg.sender : currentContextAddress_;
asset == ETH
? require(
address(uint160(msg.sender)).send(quantity),
Expand Down
Loading