Skip to content

Commit

Permalink
Merge pull request #1382 from jacqueswww/1363_vyper_ast
Browse files Browse the repository at this point in the history
1363 vyper ast
  • Loading branch information
fubuloubu authored May 10, 2019
2 parents 42891b1 + 000a12e commit 446aab9
Show file tree
Hide file tree
Showing 32 changed files with 767 additions and 151 deletions.
6 changes: 4 additions & 2 deletions bin/vyper
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ format_options_help = """Format to print, one or more of:
bytecode_runtime - Bytecode at runtime
abi - ABI in JSON format
abi_python - ABI in python format
ast - AST in JSON format
source_map - Vyper source map
method_identifiers - Dictionary of method signature to method identifier.
combined_json - All of the above format options combined as single JSON output.
Expand Down Expand Up @@ -105,7 +106,8 @@ if __name__ == '__main__':
else: # Normal output.
translate_map = {
'abi_python': 'abi',
'json': 'abi'
'json': 'abi',
'ast': 'ast_dict'
}
formats = []
orig_args = uniq(args.format.split(','))
Expand Down Expand Up @@ -156,7 +158,7 @@ if __name__ == '__main__':
for out in out_list:
for f in orig_args:
o = out[translate_map.get(f, f)]
if f in ('abi', 'json'):
if f in ('abi', 'json', 'ast'):
print(json.dumps(o))
elif f == 'abi_python':
print(o)
Expand Down
2 changes: 1 addition & 1 deletion tests/examples/market_maker/test_on_chain_market_maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def erc20(get_contract):
)


def test_initial_statet(market_maker):
def test_initial_state(market_maker):
assert market_maker.totalEthQty() == 0
assert market_maker.totalTokenQty() == 0
assert market_maker.invariant() == 0
Expand Down
37 changes: 37 additions & 0 deletions tests/parser/ast_utils/test_ast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from vyper.ast_utils import (
parse_to_ast,
)


def test_ast_equal():
code = """
@public
def test() -> int128:
a: uint256 = 100
return 123
"""

ast1 = parse_to_ast(code)
ast2 = parse_to_ast("\n \n" + code + "\n\n")

assert ast1 == ast2


def test_ast_unequal():
code1 = """
@public
def test() -> int128:
a: uint256 = 100
return 123
"""
code2 = """
@public
def test() -> int128:
a: uint256 = 100
return 121
"""

ast1 = parse_to_ast(code1)
ast2 = parse_to_ast(code2)

assert ast1 != ast2
84 changes: 84 additions & 0 deletions tests/parser/ast_utils/test_ast_dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from vyper import (
compiler,
)
from vyper.ast_utils import (
ast_to_dict,
dict_to_ast,
parse_to_ast,
)


def get_node_ids(ast_struct, ids=None):
if ids is None:
ids = []

for k, v in ast_struct.items():
if isinstance(v, dict):
ids = get_node_ids(v, ids)
elif isinstance(v, list):
for x in v:
ids = get_node_ids(x, ids)
elif k == 'node_id':
ids.append(v)
elif v is None or isinstance(v, (str, int)):
continue
else:
raise Exception('Unknown ast_struct provided.')
return ids


def test_ast_to_dict_node_id():
code = """
@public
def test() -> int128:
a: uint256 = 100
return 123
"""
dict_out = compiler.compile_code(code, ['ast_dict'])
node_ids = get_node_ids(dict_out)

assert len(node_ids) == len(set(node_ids))


def test_basic_ast():
code = """
a: int128
"""
dict_out = compiler.compile_code(code, ['ast_dict'])
assert dict_out['ast_dict']['ast'][0] == {
'annotation': {
'ast_type': 'Name',
'col_offset': 3,
'id': 'int128',
'lineno': 2,
'node_id': 4
},
'ast_type': 'AnnAssign',
'col_offset': 0,
'lineno': 2,
'node_id': 1,
'simple': 1,
'target': {
'ast_type': 'Name',
'col_offset': 0,
'id': 'a',
'lineno': 2,
'node_id': 2
},
'value': None
}


def test_dict_to_ast():
code = """
@public
def test() -> int128:
a: uint256 = 100
return 123
"""

original_ast = parse_to_ast(code)
out_dict = ast_to_dict(original_ast)
new_ast = dict_to_ast(out_dict)

assert new_ast == original_ast
18 changes: 18 additions & 0 deletions tests/parser/ast_utils/test_ast_to_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from vyper.ast_utils import (
ast_to_string,
parse_to_ast,
)


def test_ast_to_string():
code = """
@public
def testme(a: int128) -> int128:
return a
"""
vyper_ast = parse_to_ast(code)
assert ast_to_string(vyper_ast) == (
"Module(body=[FunctionDef(name='testme', args=arguments(args=[arg(arg='a',"
" annotation=Name(id='int128'))], defaults=[]), body=[Return(value=Name(id='a'))],"
" decorator_list=[Name(id='public')], returns=Name(id='int128'))])"
)
5 changes: 0 additions & 5 deletions tests/parser/exceptions/test_invalid_literal_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ def foo():
""",
"""
@public
def foo():
x = convert(-1, uint256)
""",
"""
@public
def foo():
x = convert(-(-(-1)), uint256)
""",
Expand Down
9 changes: 0 additions & 9 deletions tests/parser/exceptions/test_invalid_type_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ def foo(x): pass
b: map((int128, decimal), int128)
""",
"""
b: int128[int128: address]
""",
"""
x: wei(wei)
""",
"""
Expand All @@ -61,18 +58,12 @@ def foo(x): pass
x: int128(wei ** -1)
""",
"""
x: int128(wei >> 3)
""",
"""
x: bytes <= wei
""",
"""
x: string <= 33
""",
"""
x: bytes[1:3]
""",
"""
x: bytes[33.3]
""",
"""
Expand Down
23 changes: 0 additions & 23 deletions tests/parser/exceptions/test_structure_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,6 @@ def foo(): pass
send(0x1234567890123456789012345678901234567890, 5)
""",
"""
x: int128[5]
@public
def foo():
self.x[2:4] = 3
""",
"""
x: int128[5]
@public
def foo():
z = self.x[2:4]
""",
"""
@public
def foo():
x: int128[5]
z = x[2:4]
""",
"""
@public
def foo():
x: int128 = 5
Expand Down Expand Up @@ -147,11 +129,6 @@ def foo() -> int128:
""",
"""
@public
def foo():
x: address = ~self
""",
"""
@public
def foo():
x = concat(b"")
""",
Expand Down
55 changes: 55 additions & 0 deletions tests/parser/exceptions/test_syntax_exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import pytest
from pytest import (
raises,
)

from vyper import (
compiler,
)
from vyper.exceptions import (
SyntaxException,
)

fail_list = [
"""
x: bytes[1:3]
""",
"""
b: int128[int128: address]
""",
"""
x: int128[5]
@public
def foo():
self.x[2:4] = 3
""",
"""
@public
def foo():
x: address = ~self
""",
"""
x: int128[5]
@public
def foo():
z = self.x[2:4]
""",
"""
@public
def foo():
x: int128[5]
z = x[2:4]
""",
"""
x: int128(wei >> 3)
""",
"""
Transfer: event({_&rom: indexed(address)})
""",
]


@pytest.mark.parametrize('bad_code', fail_list)
def test_syntax_exception(bad_code):
with raises(SyntaxException):
compiler.compile_code(bad_code)
14 changes: 7 additions & 7 deletions tests/parser/parser_utils/test_annotate_and_optimize_ast.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import ast
import ast as python_ast

from vyper.parser.parser_utils import (
annotate_and_optimize_ast,
annotate_ast,
)
from vyper.parser.pre_parser import (
pre_parse,
)


class AssertionVisitor(ast.NodeVisitor):
class AssertionVisitor(python_ast.NodeVisitor):
def assert_about_node(self, node):
assert False

Expand All @@ -34,11 +34,11 @@ def foo() -> int128:

def get_contract_info(source_code):
class_types, reformatted_code = pre_parse(source_code)
parsed_ast = ast.parse(reformatted_code)
py_ast = python_ast.parse(reformatted_code)

annotate_and_optimize_ast(parsed_ast, reformatted_code, class_types)
annotate_ast(py_ast, reformatted_code, class_types)

return parsed_ast, reformatted_code
return py_ast, reformatted_code


def test_it_annotates_ast_with_source_code():
Expand Down Expand Up @@ -67,5 +67,5 @@ def test_it_rewrites_unary_subtractions():
function_def = contract_ast.body[2]
return_stmt = function_def.body[0]

assert isinstance(return_stmt.value, ast.Num)
assert isinstance(return_stmt.value, python_ast.Num)
assert return_stmt.value.n == -1
3 changes: 2 additions & 1 deletion tests/parser/syntax/test_no_none.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from vyper.exceptions import (
InvalidLiteralException,
SyntaxException,
)


Expand Down Expand Up @@ -123,7 +124,7 @@ def foo():
for contract in contracts:
assert_compile_failed(
lambda: get_contract_with_gas_estimation(contract),
InvalidLiteralException
SyntaxException
)


Expand Down
3 changes: 0 additions & 3 deletions tests/parser/syntax/utils/test_event_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ def foo(i: int128) -> int128:
Transfer: eve.t({_from: indexed(address)})
""", InvalidTypeException),
"""
Transfer: event({_&rom: indexed(address)})
""",
"""
Transfer: event({_from: i.dexed(address), _to: indexed(address),lue: uint256})
"""
]
Expand Down
Loading

0 comments on commit 446aab9

Please sign in to comment.