Repository: protofire/solhint
Pull request #272 (2020-11-19 01:11:41)

fix: Added support for the `receive` function in `ordering`
Fixes: #248


Patch:
diff --git a/lib/common/ast-types.js b/lib/common/ast-types.js
index 411f56f..72d2572 100644
--- a/lib/common/ast-types.js
+++ b/lib/common/ast-types.js
@@ -2,6 +2,10 @@ function isFallbackFunction(node) {
   return isFunctionDefinition(node) && node.isFallback
 }
 
+function isReceiveFunction(node) {
+  return isFunctionDefinition(node) && node.isReceiveEther
+}
+
 function isFunctionDefinition(node) {
   return node.type === 'FunctionDefinition'
 }
@@ -16,6 +20,7 @@ function isEnumDefinition(node) {
 
 module.exports = {
   isFallbackFunction,
+  isReceiveFunction,
   isFunctionDefinition,
   isStructDefinition,
   isEnumDefinition
diff --git a/lib/rules/order/ordering.js b/lib/rules/order/ordering.js
index 975fdeb..aa9dd02 100644
--- a/lib/rules/order/ordering.js
+++ b/lib/rules/order/ordering.js
@@ -1,5 +1,5 @@
 const BaseChecker = require('./../base-checker')
-const { isFallbackFunction } = require('../../common/ast-types')
+const { isFallbackFunction, isReceiveFunction } = require('../../common/ast-types')
 
 const ruleId = 'ordering'
 const meta = {
@@ -128,28 +128,32 @@ function contractPartOrder(node) {
     return [30, 'constructor']
   }
 
+  if (isReceiveFunction(node)) {
+    return [40, 'receive function']
+  }
+
   if (isFallbackFunction(node)) {
-    return [40, 'fallback function']
+    return [50, 'fallback function']
   }
 
   if (node.type === 'FunctionDefinition') {
     if (node.visibility === 'external' && !isConst(node)) {
-      return [50, 'external function']
+      return [60, 'external function']
     }
     if (node.visibility === 'external' && isConst(node)) {
-      return [60, 'external const function']
+      return [70, 'external const function']
     }
     if (node.visibility === 'public' && !isConst(node)) {
-      return [70, 'public function']
+      return [80, 'public function']
     }
     if (node.visibility === 'public' && isConst(node)) {
-      return [80, 'public const function']
+      return [90, 'public const function']
     }
     if (node.visibility === 'internal') {
-      return [90, 'internal function']
+      return [100, 'internal function']
     }
     if (node.visibility === 'private') {
-      return [100, 'private function']
+      return [110, 'private function']
     }
     throw new Error('Unknown order for function, please report this issue')
   }


Test patch:
diff --git a/test/rules/order/ordering.js b/test/rules/order/ordering.js
index e8a9552..3b23b5e 100644
--- a/test/rules/order/ordering.js
+++ b/test/rules/order/ordering.js
@@ -85,6 +85,33 @@ describe('Linter - ordering', () => {
     assert.ok(report.messages[0].message.includes('Function order is incorrect'))
   })
 
+  it('should raise incorrect function order error for fallback before receive', () => {
+    const code = contractWith(`
+                fallback() external payable  {}
+                receive() external payable {}
+            `)
+
+    const report = linter.processStr(code, {
+      rules: { ordering: 'error' }
+    })
+
+    assert.equal(report.errorCount, 1)
+    assert.ok(report.messages[0].message.includes('Function order is incorrect'))
+  })
+
+  it('should not raise incorrect function order error', () => {
+    const code = contractWith(`
+                receive() external payable {}
+                fallback() external payable  {}
+            `)
+
+    const report = linter.processStr(code, {
+      rules: { ordering: 'error' }
+    })
+
+    assert.equal(report.errorCount, 0)
+  })
+
   it('should not raise incorrect function order error', () => {
     const code = contractWith(`
                 function A() public {}