Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1363 vyper ast #1382

Merged
merged 26 commits into from
May 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a9189eb
Add basic Vyper AST layout.
jacqueswww Apr 3, 2019
6ed5805
Fix ast.Name statement to use kwargs instead.
jacqueswww Apr 3, 2019
f356eca
Use python_ast for annotate and optimise tests.
jacqueswww Apr 4, 2019
86bea46
Fix typo in test name.
jacqueswww Apr 4, 2019
a376909
Replace ast.dump.
jacqueswww Apr 4, 2019
7613bc7
Move test cases to use SyntaxException.
jacqueswww Apr 4, 2019
1cc1af1
Finalise the AST layout.
jacqueswww Apr 4, 2019
6239d29
Improve SyntaxException message.
jacqueswww Apr 4, 2019
cce3f06
Add simple -f ast_json output.
jacqueswww Apr 4, 2019
95f7023
Add SyntaxException.
jacqueswww Apr 4, 2019
b36506c
Rename ast to python_ast to be explicit.
jacqueswww Apr 4, 2019
b60576c
Remove ast.dump exceptions.
jacqueswww Apr 4, 2019
e504fe3
Replace import ast with vyper ast instead.
jacqueswww Apr 4, 2019
0cda1ac
Add ast_to_string and to_python_ast.
jacqueswww Apr 4, 2019
7bbcfda
Add ast_utils tests.
jacqueswww Apr 4, 2019
468ad9a
Add basic AST json output.
jacqueswww Apr 4, 2019
131a2ac
Add iterable_cast.
jacqueswww Apr 15, 2019
a0584f2
Add exception to get_node_ids.
jacqueswww Apr 15, 2019
6426c9a
Fix slots, get_slots and only_empty_fields.
jacqueswww Apr 15, 2019
bc0766b
Use iterable_cast for ast_utils.py
jacqueswww Apr 15, 2019
8d2f75f
Merge branch 'master' into 1363_vyper_ast
jacqueswww Apr 15, 2019
9c33553
Add typing.
jacqueswww Apr 15, 2019
be7e2b3
Merge branch 'master' into 1363_vyper_ast
jacqueswww May 9, 2019
468e499
Merge branch 'master' into 1363_vyper_ast
jacqueswww May 9, 2019
ffff148
Merge branch 'master' into 1363_vyper_ast
jacqueswww May 9, 2019
000a12e
Lint fix.
jacqueswww May 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
jacqueswww marked this conversation as resolved.
Show resolved Hide resolved
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