diff --git a/src/parser.js b/src/parser.js index 60291a126..850506adf 100644 --- a/src/parser.js +++ b/src/parser.js @@ -176,6 +176,10 @@ function parse(text, _parsers, options = _parsers) { '&' ]); break; + case '==': + case '!=': + ctx.left = tryHug(ctx.left, ['==', '!=']); + break; case '||': ctx.left = tryHug(ctx.left, ['&&']); ctx.right = tryHug(ctx.right, ['&&']); diff --git a/src/slang-nodes/EqualityExpression.ts b/src/slang-nodes/EqualityExpression.ts index 3faed90bf..2ffe97065 100644 --- a/src/slang-nodes/EqualityExpression.ts +++ b/src/slang-nodes/EqualityExpression.ts @@ -1,5 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printComparisonOperation } from '../slang-printers/print-comparison-operation.js'; +import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { Expression } from './Expression.js'; @@ -8,6 +9,8 @@ import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; import type { PrintFunction, SlangNode } from '../types.d.ts'; +const tryToHug = createHugFunction(['==', '!=']); + export class EqualityExpression implements SlangNode { readonly kind = NonterminalKind.EqualityExpression; @@ -32,6 +35,8 @@ export class EqualityExpression implements SlangNode { this.comments = metadata.comments; this.loc = metadata.loc; + + this.leftOperand = tryToHug(this.leftOperand); } print( diff --git a/tests/format/BinaryOperationHierarchy/__snapshots__/format.test.js.snap b/tests/format/BinaryOperationHierarchy/__snapshots__/format.test.js.snap index 67b184d15..f90d816e1 100644 --- a/tests/format/BinaryOperationHierarchy/__snapshots__/format.test.js.snap +++ b/tests/format/BinaryOperationHierarchy/__snapshots__/format.test.js.snap @@ -1029,10 +1029,10 @@ contract Group { veryVeryVeryLongUint256A == veryVeryVeryLongUint256B ^ veryVeryVeryLongUint256C; resultBoolean = - veryVeryVeryLongUint256A == veryVeryVeryLongUint256B == + (veryVeryVeryLongUint256A == veryVeryVeryLongUint256B) == veryVeryVeryLongBooleanC; resultBoolean = - veryVeryVeryLongUint256A == veryVeryVeryLongUint256B != + (veryVeryVeryLongUint256A == veryVeryVeryLongUint256B) != veryVeryVeryLongBooleanC; resultBoolean = veryVeryVeryLongBooleanA == @@ -1083,10 +1083,10 @@ contract Group { veryVeryVeryLongUint256A != veryVeryVeryLongUint256B ^ veryVeryVeryLongUint256C; resultBoolean = - veryVeryVeryLongUint256A != veryVeryVeryLongUint256B == + (veryVeryVeryLongUint256A != veryVeryVeryLongUint256B) == veryVeryVeryLongBooleanC; resultBoolean = - veryVeryVeryLongUint256A != veryVeryVeryLongUint256B != + (veryVeryVeryLongUint256A != veryVeryVeryLongUint256B) != veryVeryVeryLongBooleanC; resultBoolean = veryVeryVeryLongBooleanA != @@ -2515,12 +2515,12 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256B ^ veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A == - veryVeryVeryExtremelyExtremelyLongUint256B == + (veryVeryVeryExtremelyExtremelyLongUint256A == + veryVeryVeryExtremelyExtremelyLongUint256B) == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A == - veryVeryVeryExtremelyExtremelyLongUint256B != + (veryVeryVeryExtremelyExtremelyLongUint256A == + veryVeryVeryExtremelyExtremelyLongUint256B) != veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA == @@ -2586,12 +2586,12 @@ contract Indent { veryVeryVeryExtremelyExtremelyLongUint256B ^ veryVeryVeryExtremelyExtremelyLongUint256C; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A != - veryVeryVeryExtremelyExtremelyLongUint256B == + (veryVeryVeryExtremelyExtremelyLongUint256A != + veryVeryVeryExtremelyExtremelyLongUint256B) == veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = - veryVeryVeryExtremelyExtremelyLongUint256A != - veryVeryVeryExtremelyExtremelyLongUint256B != + (veryVeryVeryExtremelyExtremelyLongUint256A != + veryVeryVeryExtremelyExtremelyLongUint256B) != veryVeryVeryExtremelyExtremelyLongBooleanC; resultBoolean = veryVeryVeryExtremelyExtremelyLongBooleanA != diff --git a/tests/format/Parentheses/EqualParentheses.sol b/tests/format/Parentheses/EqualParentheses.sol new file mode 100644 index 000000000..73cc4d7cb --- /dev/null +++ b/tests/format/Parentheses/EqualParentheses.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract EqualParentheses { + function notEqualAdd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b + c; + } + + function notEqualSub(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b - c; + } + + function notEqualMul(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b * c; + } + + function notEqualDiv(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b / c; + } + + function notEqualMod(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b % c; + } + + function notEqualExp(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b ** c; + } + + function notEqualShiftL(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b << c; + } + + function notEqualShiftR(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b >> c; + } + + function notEqualBitAnd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b & c; + } + + function notEqualBitOr(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b | c; + } + + function notEqualBitXor(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b ^ c; + } + + function notEqualEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a == b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a == b != c; + } +} \ No newline at end of file diff --git a/tests/format/Parentheses/LogicNoParentheses.sol b/tests/format/Parentheses/LogicNoParentheses.sol index 2345f549f..c2414f4bf 100644 --- a/tests/format/Parentheses/LogicNoParentheses.sol +++ b/tests/format/Parentheses/LogicNoParentheses.sol @@ -17,4 +17,20 @@ contract LogicNoParentheses { function andAnd(bool a, bool b, bool c) public pure returns (bool) { return a && b && c; } + + function equalEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b == c; + } + + function equalNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b != c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b != c; + } } diff --git a/tests/format/Parentheses/NotEqualParentheses.sol b/tests/format/Parentheses/NotEqualParentheses.sol new file mode 100644 index 000000000..16a88bdae --- /dev/null +++ b/tests/format/Parentheses/NotEqualParentheses.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract NotEqualParentheses { + function notEqualAdd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b + c; + } + + function notEqualSub(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b - c; + } + + function notEqualMul(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b * c; + } + + function notEqualDiv(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b / c; + } + + function notEqualMod(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b % c; + } + + function notEqualExp(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b ** c; + } + + function notEqualShiftL(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b << c; + } + + function notEqualShiftR(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b >> c; + } + + function notEqualBitAnd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b & c; + } + + function notEqualBitOr(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b | c; + } + + function notEqualBitXor(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b ^ c; + } + + function notEqualEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a != b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a != b != c; + } +} \ No newline at end of file diff --git a/tests/format/Parentheses/__snapshots__/format.test.js.snap b/tests/format/Parentheses/__snapshots__/format.test.js.snap index 815377d40..8f00ac708 100644 --- a/tests/format/Parentheses/__snapshots__/format.test.js.snap +++ b/tests/format/Parentheses/__snapshots__/format.test.js.snap @@ -980,6 +980,229 @@ contract DivNoParentheses { ================================================================================ `; +exports[`EqualParentheses.sol format 1`] = ` +====================================options===================================== +parsers: ["slang"] +printWidth: 80 + | printWidth +=====================================input====================================== +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract EqualParentheses { + function notEqualAdd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b + c; + } + + function notEqualSub(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b - c; + } + + function notEqualMul(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b * c; + } + + function notEqualDiv(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b / c; + } + + function notEqualMod(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b % c; + } + + function notEqualExp(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b ** c; + } + + function notEqualShiftL(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b << c; + } + + function notEqualShiftR(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b >> c; + } + + function notEqualBitAnd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b & c; + } + + function notEqualBitOr(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b | c; + } + + function notEqualBitXor(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a == b ^ c; + } + + function notEqualEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a == b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a == b != c; + } +} +=====================================output===================================== +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract EqualParentheses { + function notEqualAdd( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b + c; + } + + function notEqualSub( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b - c; + } + + function notEqualMul( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b * c; + } + + function notEqualDiv( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b / c; + } + + function notEqualMod( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b % c; + } + + function notEqualExp( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b ** c; + } + + function notEqualShiftL( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b << c; + } + + function notEqualShiftR( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b >> c; + } + + function notEqualBitAnd( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b & c; + } + + function notEqualBitOr( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b | c; + } + + function notEqualBitXor( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a == b ^ c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a == b) == c; + } + + function notEqualNotEqual( + bool a, + bool b, + bool c + ) public pure returns (bool) { + return (a == b) != c; + } +} + +================================================================================ +`; + exports[`ExpNoParentheses.sol format 1`] = ` ====================================options===================================== parsers: ["slang"] @@ -1201,6 +1424,22 @@ contract LogicNoParentheses { function andAnd(bool a, bool b, bool c) public pure returns (bool) { return a && b && c; } + + function equalEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b == c; + } + + function equalNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a == b != c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return a != b != c; + } } =====================================output===================================== @@ -1223,6 +1462,26 @@ contract LogicNoParentheses { function andAnd(bool a, bool b, bool c) public pure returns (bool) { return a && b && c; } + + function equalEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a == b) == c; + } + + function equalNotEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a == b) != c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a != b) == c; + } + + function notEqualNotEqual( + bool a, + bool b, + bool c + ) public pure returns (bool) { + return (a != b) != c; + } } ================================================================================ @@ -1620,6 +1879,229 @@ contract MulNoParentheses { ================================================================================ `; +exports[`NotEqualParentheses.sol format 1`] = ` +====================================options===================================== +parsers: ["slang"] +printWidth: 80 + | printWidth +=====================================input====================================== +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract NotEqualParentheses { + function notEqualAdd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b + c; + } + + function notEqualSub(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b - c; + } + + function notEqualMul(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b * c; + } + + function notEqualDiv(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b / c; + } + + function notEqualMod(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b % c; + } + + function notEqualExp(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b ** c; + } + + function notEqualShiftL(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b << c; + } + + function notEqualShiftR(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b >> c; + } + + function notEqualBitAnd(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b & c; + } + + function notEqualBitOr(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b | c; + } + + function notEqualBitXor(uint256 a, uint256 b, uint256 c) + public + pure + returns (bool) + { + return a != b ^ c; + } + + function notEqualEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a != b == c; + } + + function notEqualNotEqual(bool a, bool b, bool c) + public + pure + returns (bool) + { + return a != b != c; + } +} +=====================================output===================================== +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +contract NotEqualParentheses { + function notEqualAdd( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b + c; + } + + function notEqualSub( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b - c; + } + + function notEqualMul( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b * c; + } + + function notEqualDiv( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b / c; + } + + function notEqualMod( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b % c; + } + + function notEqualExp( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b ** c; + } + + function notEqualShiftL( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b << c; + } + + function notEqualShiftR( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b >> c; + } + + function notEqualBitAnd( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b & c; + } + + function notEqualBitOr( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b | c; + } + + function notEqualBitXor( + uint256 a, + uint256 b, + uint256 c + ) public pure returns (bool) { + return a != b ^ c; + } + + function notEqualEqual(bool a, bool b, bool c) public pure returns (bool) { + return (a != b) == c; + } + + function notEqualNotEqual( + bool a, + bool b, + bool c + ) public pure returns (bool) { + return (a != b) != c; + } +} + +================================================================================ +`; + exports[`ShiftLNoParentheses.sol format 1`] = ` ====================================options===================================== parsers: ["slang"]