Giter Site home page Giter Site logo

parser's People

Contributors

aboudjem avatar alcuadrado avatar aoi-w avatar aoli-al avatar federicobond avatar frangio avatar fubhy avatar fvictorio avatar gnsps avatar janther avatar junderw avatar maxsam4 avatar naddison36 avatar obernardovieira avatar yxliang01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

parser's Issues

Make visibility in constructor optional

Starting from solidity 0.7.0, constructors shouldn't have a constructor.

I think the fix here is just to make the keyword optional after constructors, and to update the node properly.

Nightly compiler not supported in pragma

If the contract contains pragma solidity >=0.8.2-nightly <0.9.0; the parser returns for the pragma node { type: 'PragmaDirective', name: 'solidity', value: '>=0.8.2' }.

I would expect the value to be >=0.8.2-nightly <0.9.0

Version used: 0.11.1 via hardhat

Import `0.13.2` fail

I have react app.Β Everything works well with version 0.9.1, but when I installed 0.13.2 import fails

import parser from '@solidity-parser/parser';
as well as
import * as parser from '@solidity-parser/parser';
const parser require('@solidity-parser/parser');

error:

TypeError: __webpack_require__(...).join is not a function
   ...

on localhost:

node_modules/@solidity-parser/parser/dist/index.cjs.js:25092
  25089 |   if (typeof BROWSER !== "undefined") {
  25090 |     module2.exports = require_Solidity();
  25091 |   } else {
> 25092 |     module2.exports = require("fs").readFileSync(require("path").join(__dirname, "./antlr/Solidity.tokens")).toString();
  25093 |   }
  25094 | });
  25095 | 

Repo: https://github.com/aquiladev/remix-sol2uml

Cannot parse new `using ... global` syntax

Solidity 0.8.13 introduced a new file-level syntax for specifying a global using statement on user-defined types:

using ... for ... global;

Solidity parser currently cannot handle this syntax.

Example contract using this syntax:

type Fixed18 is int256;
using Fixed18Lib for Fixed18 global;

library Fixed18Lib {
    function add(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {
        return Fixed18.wrap(Fixed18.unwrap(a) + Fixed18.unwrap(b));
    }

    function sub(Fixed18 a, Fixed18 b) internal pure returns (Fixed18) {
        return Fixed18.wrap(Fixed18.unwrap(a) - Fixed18.unwrap(b));
    }
}

Investigate better error handling

There is a "Error Reporting and Recovery" chapter in the ANTLR book. It would be useful to check if there's something there that can be applied in this parser. Right now the tolerant mode works in some cases, like this:

contract Foo {

but not on other like this:

contract Foo {

contract Bar {}

I have no idea what the trade-offs are here, nor the complexity involved in improving this.

Inaccurate location information for VariableDeclaration since 0.13.x

Hey πŸ‘‹

I am using this parser in my vscode extension vscode-visual-developer. I just tried updating von 0.12.x to 0.13.x and found out that the location information for VariableDeclaration AST types is off. It seems to always start at line-start now πŸ€”

Here's a screenshot that visualizes this. My extension highlights state-vars by drawing a golden dotted box around state-vars (and their declaration). Since 0.13.0 it highlights the full line (starting from col:1 to end of the declaration).

This may be a bug in the parser. Would be great if you could investigate.

cheers,
tin

Actual: (complete declaration line highlighted: VariableDeclaration.loc seems to be off.

image

Expected: behavior from 0.12.x. VariableDeclaration.loc returns range for the variable name only.

Question about antlr4 dependency & minimum Node version

(Thanks a million for maintaining this @fvictorio. It's the best.)

In 71f83ca antlr4 is added as a direct dependency.

Was updating some things to 0.9.1 and am getting the installation error below when is Node < 14.

14 is LTS as of late October but just wanted to double-check with you that this is expected.

[2/4] 🚚  Fetching packages...
error [email protected]: The engine "node" is incompatible with this module. Expected version ">=14". Got "12.16.0"
error Found incompatible module.

Unable to parse address[][] in abidecode()

Whilst the Solidity compiler compiles this without errors the parser throws (both with Solhint and Prettier) on the following line:

(IUniswapV2Router02 uniswapV2Router, address[][] memory swapPaths) = abi.decode(strategyData, (IUniswapV2Router02, address[][]));

Context: https://github.com/Rari-Capital/fuse-v1/blob/15b3920fb017b3115b07362d7578d2df65f36582/src/liquidators/BalancerPoolTokenLiquidator.sol#L63

Error (on running Solhint):

/home/zerosnacks/Projects/fuse-v1/node_modules/solhint/lib/index.js:40
      throw e
      ^

Error: Unrecognized expression
    at ASTBuilder.visitExpression (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:36165:11)
    at ExpressionContext.accept (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:34066:22)
    at ASTBuilder.visit (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
    at /home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:36301:19
    at Array.map (<anonymous>)
    at ASTBuilder.visitTupleExpression (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:36297:57)
    at TupleExpressionContext.accept (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:34972:22)
    at ASTBuilder.visit (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
    at ASTBuilder.visitPrimaryExpression (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:36293:17)
    at ASTBuilder.visitExpression (/home/zerosnacks/Projects/fuse-v1/node_modules/@solidity-parser/parser/dist/index.cjs.js:36018:21)

Error Parse with BEP20Token.sol

Hi,
I use solidity-parser to parse file BEP20Token.sol ( from Binance ) but I get an error

My code:

const parser = require("@solidity-parser/parser");
const fs = require("fs");

const input = fs.readFileSync("./BEP20Token.sol").toString();

try {
  const ast = parser.parse(input);
  console.log(ast)
} catch (e) {
  console.log(e);
  if (e instanceof parser.ParserError) {
    console.error(e.errors);
  }
}
TypeError: Cannot read property 'length' of undefined
    at ASTBuilder.visitExpression (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:36002:26)
    at ASTBuilder.visitExpression (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:36064:25)
    at ASTBuilder.visitExpressionStatement (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:35932:24)
    at ExpressionStatementContext.accept (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:33418:22)
    at ASTBuilder.visit (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:17669:19)
    at ASTBuilder.visitSimpleStatement (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:35449:17)
    at SimpleStatementContext.accept (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:33590:22)
    at ASTBuilder.visit (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:17669:19)
    at ASTBuilder.visitStatement (D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:35446:17)
    at D:\apps\test\testParse\node_modules\@solidity-parser\parser\dist\index.cjs.js:35482:51

Thanks

Bug: Expanded fallback function syntax not properly parsed

Fallback functions with the expanded syntax for inputs and output: fallback (bytes calldata input) external [payable] returns (bytes memory output) are not correctly parsed. This syntax is valid per the latest Solidity documentation.

This issue is in reference to a related bug in the prettier-solidity/prettier-plugin-solidity repo (issue 659) where fallback functions with parameters and returnParameters are not correctly formatted.

I believe the issue is that the parser doesn't capture the parameters and returnsParameters when the fallback keyword is identified in parser/ASTBuilder.ts

parser/src/ASTBuilder.ts

Lines 342 to 345 in 1a7bfb8

case 'fallback':
visibility = 'external'
isFallback = true
break

A potential fix is using the parameter and returnParameter parsing logic implemented for the function keyword starting on line 354 of the same file:

parameters = ctx
  .parameterList()
  .parameter()
  .map((x) => this.visit(x))
returnParameters =
  ctxReturnParameters !== undefined
    ? this.visitReturnParameters(ctxReturnParameters)
    : null

Add support for parsing the SPDX-License-Identifier

Solidity 0.6.8 introduces SPDX license identifiers so developers can specify the license the contract uses. Source

I think there are tools that use this library that would benefit if this would be implemented for example solhint.

I would like to provide a PR to implement this, but I'm a little bit out of my depth here.. If one can give me a hint how to implement an additional type with the mentioned formatting, would greatly appreciate it.

Reference to ctx.constructor.name in ASTBuilder breaks webpack production builds

Hi There,

I'm running into an issue where a simple parse on the following contract code results in divergent parsing locally vs. in production (javascript):

// Extremely simple Solidity contract example.
import "File1";

pragma solidity >=0.6.7;

contract Test is Test2 {
	uint z = 0;

	function test() public returns (uint256) {
		other();
		y += 1;
		z += 1;
	}
}

Locally I get an AST element starting with SourceUnit, in production I get an object like so:

[
  {
    "type": "p"
  }
]

Do you have any thoughts on what may be causing this? Is there perhaps an antlr compilation step that occurs as the yarn package is installed?

UPDATE: For more details, see below, but effectively the key problem is this reference: https://github.com/solidity-parser/parser/blob/master/src/ASTBuilder.js#L1458. Classes get renamed during webpack optimisation so references to class names are not supported. This could be fixed by manually adding a type property to each class rather than automatically deriving it from the class name.

Remove semantic checks

There are some semantic checks in the parser, like for example checking if a receive function is payable.

In my opinion, this should be a compiler's responsibility. The parser should err on the permissive side, accepting anything that makes sense syntactically. Otherwise, we should also do things like, for example, emitting warning on deprecated constructions. Plus, this kind of stuff depends on the solidity version, but the parser has been pretty version-independent so far, which is nice.

Migrate to jest

I would like to refactor this project to use jest because a lot of tests here are practically snapshot tests.

ParserError: Could not instrument: ... extraneous input '....' expecting {';', '='}

Hi,

Like @fvictorio asked me to in this issue in the solidity-coverage repo, I opening the same issue here:

First of all thank you for building and maintaining this tool.

I was trying to use the solidity-coverage buidler plugin for the first time, and I encountered this solidity-parser bug and some others which all seem to be related to solc 0.6 syntax, I would assume.

An unexpected error occurred:

ParserError: Could not instrument: gelato_core/gelato_provider_module_examples/gelato_user_proxy_provider/ProviderModuleGelatoUserProxy.sol. (Please verify solc can compile this file without errors.) extraneous input 'isProxyExtcodehashProvided' expecting {';', '='} (17:45)
    at Object.parse (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-antlr/dist/index.js:79:11)
    at Instrumenter.instrument (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-coverage/lib/instrumenter.js:63:30)
    at API.instrument (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-coverage/lib/api.js:91:48)
    at SimpleTaskDefinition.action (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-coverage/plugins/buidler.plugin.js:86:23)
    at processTicksAndRejections (internal/process/task_queues.js:94:5)
    at Environment._runTaskDefinition (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/@nomiclabs/buidler/src/internal/core/runtime-environment.ts:190:14)
    at main (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/@nomiclabs/buidler/src/internal/cli/cli.ts:151:5)

This is the source solidity code referenced in the error log:
FILE: ProviderModuleGelatoUserProxy.sol
LINE 17: mapping(bytes32 => bool) public override isProxyExtcodehashProvided;

And all my contracts compile without errors using npx buidler compile.

Can't seem to load browser friendly parser

If trying to load the browser friendly parser I get an empty object.

const parser = require('@solidity-parser/parser');
console.log(parser) // { ParserError: [Getter], parse: [Getter], tokenize: [Getter], visit: [Getter] }β€ˆ

const parser = require('@solidity-parser/parser/dist/index.iife');
console.log(parser) // {}

add `virtual` and `override` for modifiers

Modifiers also have virtual and override.

Here is the documentation

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.7.0;

contract Base
{
    modifier foo() virtual {_;}
}

contract Inherited is Base
{
    modifier foo() override {_;}
}

In case of multiple inheritance, all direct base contracts must be specified explicitly:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.7.0;

contract Base1
{
    modifier foo() virtual {_;}
}

contract Base2
{
    modifier foo() virtual {_;}
}

contract Inherited is Base1, Base2
{
    modifier foo() override(Base1, Base2) {_;}
}

Handle commas in assembly assignment

This is valid code but it generates a parsing error in the let i, j line:

contract Test {
    function foo() public pure {
        assembly {
            function bar() -> a, b {
                a := 1
                b := 2
            }

            let i, j := bar()
        }
    }
}

Node 14: Warning: Accessing non-existent property 'INVALID_ALT_NUMBER' of module exports inside circular dependency

When using this parser on Node 14, I get this warnings:

pato@pmbp:14% node --trace-warnings node_modules/.bin/buidler test
(node:2572) Warning: Accessing non-existent property 'INVALID_ALT_NUMBER' of module exports inside circular dependency
    at emitCircularRequireWarning (internal/modules/cjs/loader.js:823:11)
    at Object.get (internal/modules/cjs/loader.js:837:5)
    at Object.<anonymous> (/private/tmp/14/node_modules/@solidity-parser/parser/dist/antlr4/RuleContext.js:32:46)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18)
    at Object.<anonymous> (/private/tmp/14/node_modules/@solidity-parser/parser/dist/antlr4/PredictionContext.js:10:19)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18)
(node:2572) Warning: Accessing non-existent property 'INVALID_ALT_NUMBER' of module exports inside circular dependency
    at emitCircularRequireWarning (internal/modules/cjs/loader.js:823:11)
    at Object.get (internal/modules/cjs/loader.js:837:5)
    at Object.<anonymous> (/private/tmp/14/node_modules/@solidity-parser/parser/dist/antlr4/tree/Trees.js:15:49)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18)
    at Object.<anonymous> (/private/tmp/14/node_modules/@solidity-parser/parser/dist/antlr4/RuleContext.js:126:13)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Module.require (internal/modules/cjs/loader.js:1089:19)
    at require (internal/modules/cjs/helpers.js:73:18)

ArrayTypeName.length incorrect type

ArrayTypeName is currently defined with length having type Expression | null

export interface ArrayTypeName extends BaseASTNode {
  type: 'ArrayTypeName'
  baseTypeName: TypeName
  length: Expression | null
}

At runtime, the length for a fixed length array is returning a length of type NumberLiteral. So the type should be

export interface ArrayTypeName extends BaseASTNode {
  type: 'ArrayTypeName'
  baseTypeName: TypeName
  length: NumberLiteral | null
}

Some example fixed length arrays are

bool[2] flags = [true, false];
uint256[2][3] multiDim2x3;
address[3][2] multiDim3x2;

I tried to create a PR for this but I got lost in the required ASTBuilder changes in the visitTypeName function.

Cannot parse SafeMath.sol from openzeppelin

Hello guys. I am using truffle-flattener package with openzeppelin. Which is using this repo for parsing solidity code.

When I run truffle-flattener I got this error

Error: Could not parse /home/mentalrob/projects/bnb-barbut-ci/barbut/node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol for extracting its imports: ParserError: missing ';' at '{' (22:18)
    at getDependencies (/home/mentalrob/.nvm/versions/node/v14.15.0/lib/node_modules/truffle-flattener/index.js:44:11)
    at dependenciesDfs (/home/mentalrob/.nvm/versions/node/v14.15.0/lib/node_modules/truffle-flattener/index.js:64:24)
    at async dependenciesDfs (/home/mentalrob/.nvm/versions/node/v14.15.0/lib/node_modules/truffle-flattener/index.js:73:7)

Here is the SafeMath.sol file that i have

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

I guess unchecked word is causing this issue.
Any ideas to fix this ?
Thanks

Assertion error: primary expression should exist when children length is 1

After upgrading from "0.13.2" to "0.14.2" I receive the following error:

contracts/Perpetual.sol[error] contracts/Perpetual.sol: Error: Assertion error: primary expression should exist when children length is 1
[error]     at ASTBuilder.visitExpression (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:36119:17)
[error]     at ASTBuilder.visitExpression (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:36177:25)
[error]     at ASTBuilder.visitExpression (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:36167:30)
[error]     at ASTBuilder.visitExpressionStatement (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:36040:24)
[error]     at ExpressionStatementContext.accept (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:33516:22)
[error]     at ASTBuilder.visit (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
[error]     at ASTBuilder.visitSimpleStatement (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:35550:17)
[error]     at SimpleStatementContext.accept (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:33688:22)
[error]     at ASTBuilder.visit (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
[error]     at ASTBuilder.visitStatement (/Users/username/project/node_modules/@solidity-parser/parser/dist/index.cjs.js:35547:17)

Tried looking for the error in Perpetual.sol but there's no given line numbers and couldn't find any info on this particular error anywhere.

Unable to detect unnamed overriding

I want to find out function overriding and function modifier overriding in the AST. However, it seems not possible in some situation.

contract A {
  function f(uint a) public virtual {
    return a + 1;
  }
}

contract B is A {
  function f(uint a) public override { // cannot detect
    return a + 2;
  }
}

The override array of the FunctionDefinition node of B.f is empty, which means I cannot know whether a function is overriding another function in the parent contract. However, the code below works:

contract A {
  function f(uint a) public virtual {
    return a + 1;
  }
}

contract B is A {
  function f(uint a) public override(A) { // can detect
    return a + 2;
  }
}

When the name is explicitly given in override(...), the override array contains one element. How can I detect unnamed overriding? The same situation happens on function modifier overriding:

contract A {
  modifier m() virtual { _; }
}

contract B is A {
  modifier m() override { _; } // cannot detect
}

Support multiline hex literals.

This was merged in ethereum/solidity#7524 1 year ago.

Given the case:

string memory a = 'abc' 'def'
   'ghi'     'jkl';

string memory b = 'abcdefghijkl';

bytes memory c = hex'dead' hex'beef'
     hex'deadbe' hex'ef';

bytes memory d = hex'deadbeefdeadbeef';

a == b and c == d in this case. line breaks and spaces can be in between each section.

It makes code readability much easier.

We use prettier, so doing this breaks formatting for us.

VariableDeclaration type missing isImmutable

The VariableDeclaration type is missing the isImmutable boolean value which is available at runtime

export interface VariableDeclaration extends BaseASTNode {
  type: 'VariableDeclaration'
  isIndexed: boolean
  isStateVar: boolean
  typeName: TypeName | null
  name: string | null
  identifier: Identifier | null
  isDeclaredConst?: boolean
  storageLocation: string | null
  expression: Expression | null
  visibility?: 'public' | 'private' | 'internal' | 'default'
}```

Some interfaces are incorrectly typed in `ast-types.d.ts`

Thank you for implementing the parser - it's very useful.

I'd like to point out some typing problems in dist/ast-types.d.ts.

The type of BaseASTNode.loc is wrong

export interface BaseASTNode {
    type: ASTNodeTypeString;
    range?: [number, number];
    loc?: Location;
}

I guess the definition of Location is missing? The Location here is an interface in the typescript standard library and has nothing to do with line of code.

The type of ASTNodeTypeString is unsound

export declare type ASTNodeTypeString = 'SourceUnit' | 'PragmaDirective' | 'PragmaName' | 'PragmaValue' | 'ImportDirective' | 'ContractDefinition' | 'InheritanceSpecifier' | 'StateVariableDeclaration' | 'UsingForDeclaration' | 'StructDefinition' | 'ModifierDefinition' | 'ModifierInvocation' | 'FunctionDefinition' | 'EventDefinition' | 'EnumValue' | 'EnumDefinition' | 'VariableDeclaration' | 'UserDefinedTypeName' | 'Mapping' | 'ArrayTypeName' | 'FunctionTypeName' | 'StorageLocation' | 'StateMutability' | 'Block' | 'ExpressionStatement' | 'IfStatement' | 'WhileStatement' | 'ForStatement' | 'InlineAssemblyStatement' | 'DoWhileStatement' | 'ContinueStatement' | 'Break' | 'Continue' | 'BreakStatement' | 'ReturnStatement' | 'EmitStatement' | 'ThrowStatement' | 'VariableDeclarationStatement' | 'IdentifierList' | 'ElementaryTypeName' | 'FunctionCall' | 'AssemblyBlock' | 'AssemblyItem' | 'AssemblyCall' | 'AssemblyLocalDefinition' | 'AssemblyAssignment' | 'AssemblyStackAssignment' | 'LabelDefinition' | 'AssemblySwitch' | 'AssemblyCase' | 'AssemblyFunctionDefinition' | 'AssemblyFunctionReturns' | 'AssemblyFor' | 'AssemblyIf' | 'AssemblyLiteral' | 'SubAssembly' | 'TupleExpression' | 'TypeNameExpression' | 'NameValueExpression' | 'BooleanLiteral' | 'NumberLiteral' | 'Identifier' | 'BinaryOperation' | 'UnaryOperation' | 'NewExpression' | 'Conditional' | 'StringLiteral' | 'HexLiteral' | 'HexNumber' | 'DecimalNumber' | 'MemberAccess' | 'IndexAccess' | 'IndexRangeAccess' | 'NameValueList' | 'UncheckedStatement';

Some node types are missing in this declaration, e.g. 'TryStatement' and 'FileLevelConstant'.

Interfaces of some AST node types derived from BaseASTNode are not given

export interface SourceUnit extends BaseASTNode {
    type: 'SourceUnit';
    children: ASTNode[];
}

The interface like this is very useful, but some are missing, e.g. PragmaName, PragmaValue, StorageLocation, StateMutability, and IdentifierList.

Add support for unicode literals

Since v0.7.0, Solidity has a new syntax for unicode literals (see documents):

string memory a = unicode"Hello πŸ˜ƒ";

However, this is not currently supported by the parser.

For the following Javascript code:

const parser = require('@solidity-parser/parser');
const code = `
  contract test {
    function f() {
      string memory a = unicode"Hello πŸ˜ƒ";
    }
  }
`;
parser.parse(code);

An error will be thrown:

/.../node_modules/@solidity-parser/parser/src/index.ts:72
    throw new ParserError({ errors: listener.getErrors() })
          ^
Error: extraneous input '"Hello πŸ˜ƒ"' expecting ';' (4:31)
    at Object.parse (/.../node_modules/@solidity-parser/parser/src/index.ts:72:11)

Always expose information about the underlying node

Nodes like FunctionDefinition have properties like visibility and stateMutability that are plain strings, but that don't have information about the original text. This makes it harder to implement things like the visibility-modifier-order rule in Solhint because you have no way of knowing the position in the original text where that value comes from. A slightly better idea is that a FunctionDefinition node has something like a visibilityNode (maybe?) which has that node. If visibility is default, visibilityNode is null. This is a solution that doesn't imply a breaking change. An alternative with a breaking change is to make visibility be a node, and consumers need to interpret a null value as a default.

Unbalanced parenthesis cause unclear error message

contract C {
  function f() {
    require(balanceOf();
  }
}

results in

[error] contracts/A.sol: TypeError: Cannot read property 'length' of undefined
[error]     at ASTBuilder.visitExpression (/node_modules/@solidity-parser/parser/dist/index.cjs.js:36002:26)
[error]     at ASTBuilder.visitExpressionStatement (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35932:24)
[error]     at ExpressionStatementContext.accept (/node_modules/@solidity-parser/parser/dist/index.cjs.js:33418:22)
[error]     at ASTBuilder.visit (/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
[error]     at ASTBuilder.visitSimpleStatement (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35449:17)
[error]     at SimpleStatementContext.accept (/node_modules/@solidity-parser/parser/dist/index.cjs.js:33590:22)
[error]     at ASTBuilder.visit (/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
[error]     at ASTBuilder.visitStatement (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35446:17)
[error]     at /node_modules/@solidity-parser/parser/dist/index.cjs.js:35482:51
[error]     at Array.map (<anonymous>)

I think there should be a nicer message saying what failed, if possible?

(Originally opened at prettier-solidity/prettier-plugin-solidity#586. Prettier uses the version 0.13.2 of the parser.)

Handle `payable` when used as a function

When payable is used as a function (to cast an address to a payable address), the parser doesn't return a proper node:

{
    type: 'FunctionCall',
    expression: { type: 'TerminalNodeImpl' },
    arguments: [ ... ],
    names: []
  }

Notice that expression should be { type: 'Identifier', name: 'payable' }

Error: Could not instrument: ..... Unrecognized expression

@fvictorio and @cgewecke thanks for the update in issue #9 .

However, now I get a new Parser Error, I assume one of the following things could be the issue with my expressions in the contract (that compiles fine):

  • pragma experimental ABIEncoderV2 in order to accept solidity structs and nested structs as function params and to emit them in events. (btw the EncoderV2 is not considered experimental any more since 0.6)

  • I am using solidity try/catch expressions

An unexpected error occurred:

Error: Could not instrument: gelato_core/GelatoCore.sol. (Please verify solc can compile this file without errors.) Unrecognized expression
    at ASTBuilder.Expression (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:758:11)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.Expression (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:700:30)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.TryStatement (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:483:24)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.Statement (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:557:17)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.<anonymous> (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1292:19)
    at Array.map (<anonymous>)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1291:16)
    at ASTBuilder.Block (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:517:24)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.FunctionDefinition (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:143:20)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.ContractPart (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:127:17)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
    at ASTBuilder.<anonymous> (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1292:19)
    at Array.map (<anonymous>)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1291:16)
    at ASTBuilder.ContractDefinition (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:113:22)
    at ASTBuilder.visit (/Users/luis/Desktop/gelato-gnosis-safe/node_modules/solidity-parser-diligence/dist/ASTBuilder.js:1304:38)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Can't handle stray commas in parameter list

contract C {
  function f(uint256 a,) external view {}
}

results in

$ prettier --write "contracts/**/*.sol"
contracts/a.sol
[error] contracts/a.sol: Error: Assertion error: unhandled type name case
[error]     at ASTBuilder.visitTypeName (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35664:11)
[error]     at ASTBuilder.visitParameter (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35499:22)
[error]     at ParameterContext.accept (/node_modules/@solidity-parser/parser/dist/index.cjs.js:32870:22)
[error]     at ASTBuilder.visit (/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
[error]     at /node_modules/@solidity-parser/parser/dist/index.cjs.js:35552:70
[error]     at Array.map (<anonymous>)
[error]     at ASTBuilder.visitFunctionDefinition (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35552:54)
[error]     at FunctionDefinitionContext.accept (/node_modules/@solidity-parser/parser/dist/index.cjs.js:32561:22)
[error]     at ASTBuilder.visit (/node_modules/@solidity-parser/parser/dist/index.cjs.js:17669:19)
[error]     at ASTBuilder.visitContractPart (/node_modules/@solidity-parser/parser/dist/index.cjs.js:35334:17)

The same happens with return parameters:

contract C {
    function f(uint256) external view returns (uint256,) {}
}

I think there should be a nicer message saying what failed, if possible?

(Originally opened at prettier-solidity/prettier-plugin-solidity#585. Prettier uses the version 0.13.2 of the parser.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.