Consensys / python-solidity-parser

An experimental Solidity parser for Python built on top of a robust ANTLR4 grammar 📚
https://pypi.org/project/solidity-parser/
142 stars 37 forks source link

Feature Request: Get object's raw source #21

Open lpinilla opened 2 years ago

lpinilla commented 2 years ago

Hi,

How are you? Thanks of all, thanks for doing the port of the tool, I was thinking of doing it myself and I found someone else did it :smile:

I was wondering if there was a way to get the raw source of an objects, let's say a contract or function.

I was thinking in something like:

sourceUnitObject = parser.objectify(sourceUnit)
raw_text = sourceUnitObject.contracts['MyContract'].raw
print(raw_text)
>>'contract MyContract { ..'

Thanks!

seyyedaliayati commented 1 year ago

This is indeed a very useful feature. I started working on it.

seyyedaliayati commented 1 year ago

This is indeed a very useful feature. I started working on it.

Here is my solution:

  1. Set loc=True in parse function.
  2. Use the following helper function:

    def get_content_between_positions(file_path, positions):
    start_line = positions['start']['line']
    start_column = positions['start']['column']
    end_line = positions['end']['line']
    end_column = positions['end']['column']
    
    with open(file_path, 'r') as file:
        lines = file.readlines()
    
    content = ''
    for line_number, line in enumerate(lines, 1):
        if start_line <= line_number <= end_line:
            if line_number == start_line:
                content += line[start_column:]
            elif line_number == end_line:
                content += line[:end_column+1]
            else:
                content += line
    
    return content
  3. use ._node.loc. to access the location dictionary.
    
    from solidity_parser import parser, objectify, visit
    source_unit = parser.parse_file(sample_test_file, loc=True)
    source_unit_obj = objectify(source_unit)

contracts = source_unit_obj.contracts

for contract in contracts.values(): print(get_content_between_positions(sample_test_file, contract.functions['']._node.loc))



The output will be the context of the function! Enjoy it :)