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

CU-86dt50abt - Error when compiling using union type notation with | (bitwise or) in Event argument type #1233

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions boa3/builtin/contract/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
'to_script_hash',
]

from typing import Any, Union
from typing import Any

from boa3.builtin.compile_time import CreateNewEvent
from boa3.builtin.contract.Nep17Contract import Nep17Contract
from boa3.builtin.type import ECPoint, UInt160, Event

Nep11TransferEvent: Event = CreateNewEvent(
[
('from', Union[UInt160, None]),
('to', Union[UInt160, None]),
('from', UInt160 | None),
('to', UInt160 | None),
('amount', int),
('tokenId', Union[str, bytes])
('tokenId', str | bytes)
],
'Transfer'
)
Expand Down Expand Up @@ -49,8 +49,8 @@

Nep17TransferEvent: Event = CreateNewEvent(
[
('from', Union[UInt160, None]),
('to', Union[UInt160, None]),
('from', UInt160 | None),
('to', UInt160 | None),
('amount', int)
],
'Transfer'
Expand Down
40 changes: 29 additions & 11 deletions boa3/internal/analyser/moduleanalyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,25 @@ def get_values_type(self, value: ast.AST) -> Iterable[IType | None]:

return types

def visit_BinOp(self, bin_op: ast.BinOp) -> IType | None:
left = self.visit(bin_op.left)
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(left, str):
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
left = self.get_symbol(left)
elif isinstance(bin_op.left, ast.Constant) and left is None:
left = self.get_type(left)

right = self.visit(bin_op.right)
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(right, str):
right = self.get_symbol(right)
elif isinstance(bin_op.right, ast.Constant) and right is None:
right = self.get_type(right)

# only validate type1 | type2, other binary operations are evaluated on TypeAnalyser
if isinstance(bin_op.op, ast.BitOr) and isinstance(left, IType) and isinstance(right, IType):
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
return left.union_type(right)

return self.generic_visit(bin_op)

def visit_Call(self, call: ast.Call) -> IType | None:
"""
Visitor of a function call node
Expand Down Expand Up @@ -1319,25 +1338,24 @@ def create_new_event(self, create_call: ast.Call) -> Event:
)
elif len(event_args) > 0:
args_type = self.get_type(event_args[0])
expected_type = Builtin.NewEvent.arguments_type
if not Type.list.is_type_of(args_type):
self._log_error(
CompilerError.MismatchedTypes(line=event_args[0].lineno,
col=event_args[0].col_offset,
expected_type_id=Type.list.identifier,
expected_type_id=expected_type.identifier,
actual_type_id=args_type.identifier)
)
else:
expected_type = expected_type.value_type
for value in event_args[0].elts:
if not isinstance(value, ast.Tuple):
CompilerError.MismatchedTypes(line=value.lineno,
col=value.col_offset,
expected_type_id=Type.tuple.identifier,
actual_type_id=self.get_type(value).identifier)
elif len(value.elts) < 2:
if not isinstance(value, ast.Tuple) or len(value.elts) < 2:
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
actual_type = self.get_type(value)
self._log_error(
CompilerError.UnfilledArgument(line=value.lineno,
col=value.col_offset,
param=list(Builtin.NewEvent.args)[0])
CompilerError.MismatchedTypes(line=value.lineno,
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
col=value.col_offset,
expected_type_id=expected_type.identifier,
actual_type_id=actual_type.identifier)
)
else:
event_arg_name, event_arg_type = value.elts
Expand Down Expand Up @@ -1365,7 +1383,7 @@ def create_new_event(self, create_call: ast.Call) -> Event:
self._log_error(
CompilerError.MismatchedTypes(line=value.lineno,
col=value.col_offset,
expected_type_id=Type.tuple.identifier,
expected_type_id=expected_type.identifier,
actual_type_id=self.get_type(value).identifier)
)
else:
Expand Down
10 changes: 9 additions & 1 deletion boa3/internal/model/builtin/method/createeventmethod.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from boa3.internal.model.builtin.method.builtinmethod import IBuiltinMethod
from boa3.internal.model.expression import IExpression
from boa3.internal.model.type.collection.sequence.mutable.listtype import ListType
from boa3.internal.model.type.itype import IType
from boa3.internal.model.variable import Variable
from boa3.internal.neo.vm.type.AbiType import AbiType
Expand All @@ -11,15 +12,22 @@ class CreateEventMethod(IBuiltinMethod):
def __init__(self):
import ast
from boa3.internal.model.type.type import Type
from boa3.internal.model.type.typeutils import TypeUtils
identifier = 'CreateNewEvent'
args = {
'arguments': Variable(Type.list.build(Type.tuple)),
'arguments': Variable(Type.list.build(
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
Type.tuple.build_collection((Type.str, TypeUtils.type))
)),
'event_name': Variable(Type.str)
}
event_name_default = ast.parse("'{0}'".format(Type.str.default_value)
).body[0].value
super().__init__(identifier, args, defaults=[event_name_default], return_type=EventType)

@property
def arguments_type(self) -> ListType:
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
return self.args['arguments'].type

def validate_parameters(self, *params: IExpression) -> bool:
return len(params) == len(self.args)

Expand Down
6 changes: 3 additions & 3 deletions boa3_test/examples/auxiliary_contracts/update_contract.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Union
from typing import Any

from boa3.builtin.compile_time import CreateNewEvent, NeoMetadata, public
from boa3.builtin.interop import storage, runtime
Expand Down Expand Up @@ -42,8 +42,8 @@ def manifest_metadata() -> NeoMetadata:

on_transfer = CreateNewEvent(
[
('from_addr', Union[UInt160, None]),
('to_addr', Union[UInt160, None]),
('from_addr', UInt160 | None),
('to_addr', UInt160 | None),
('amount', int)
],
'Transfer'
Expand Down
6 changes: 3 additions & 3 deletions boa3_test/examples/nep11_non_divisible.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

from boa3.builtin.compile_time import CreateNewEvent, NeoMetadata, public
from boa3.builtin.contract import abort
from boa3.builtin.interop import storage
luc10921 marked this conversation as resolved.
Show resolved Hide resolved
from boa3.builtin.interop.blockchain import get_contract
from boa3.builtin.interop.contract import CallFlags, call_contract, destroy_contract, get_call_flags, update_contract
from boa3.builtin.interop.iterator import Iterator
from boa3.builtin.interop.json import json_deserialize
from boa3.builtin.interop.runtime import check_witness, get_network, script_container
from boa3.builtin.interop.stdlib import deserialize, serialize
from boa3.builtin.interop import storage
from boa3.builtin.interop.storage.findoptions import FindOptions
from boa3.builtin.type import UInt160, helper as type_helper

Expand Down Expand Up @@ -80,8 +80,8 @@ def gm_manifest() -> NeoMetadata:
on_transfer = CreateNewEvent(
# trigger when tokens are transferred, including zero value transfers.
[
('from_addr', Union[UInt160, None]),
('to_addr', Union[UInt160, None]),
('from_addr', UInt160 | None),
('to_addr', UInt160 | None),
('amount', int),
('tokenId', bytes)
],
Expand Down
6 changes: 3 additions & 3 deletions boa3_test/examples/update_contract.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Union
from typing import Any

from boa3.builtin.compile_time import CreateNewEvent, NeoMetadata, public
from boa3.builtin.interop import storage, runtime
Expand Down Expand Up @@ -46,8 +46,8 @@ def manifest_metadata() -> NeoMetadata:

on_transfer = CreateNewEvent(
[
('from_addr', Union[UInt160, None]),
('to_addr', Union[UInt160, None]),
('from_addr', UInt160 | None),
('to_addr', UInt160 | None),
('amount', int)
],
'Transfer'
Expand Down
6 changes: 2 additions & 4 deletions boa3_test/test_sc/event_test/EventNep17TransferBuilt.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from typing import Union

from boa3.builtin.compile_time import public, CreateNewEvent
from boa3.builtin.type import UInt160

transfer = CreateNewEvent(
[
('from', Union[UInt160, None]),
('to', Union[UInt160, None]),
('from', UInt160 | None),
('to', UInt160 | None),
('amount', int)
],
'Transfer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
[
('optional', Optional[str]),
('union', Union[int, None]),
('union2', bool | None)
],
'event'
)


@public
def main():
event('foo', 1)
event('foo', 1, True)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, Union
from typing import Any, Dict

from boa3.builtin.compile_time import CreateNewEvent, NeoMetadata, public
from boa3.builtin.interop.iterator import Iterator
Expand All @@ -7,8 +7,8 @@
on_transfer = CreateNewEvent(
# trigger when tokens are transferred, including zero value transfers.
[
('from_addr', Union[UInt160, None]),
('to_addr', Union[UInt160, None]),
('from_addr', UInt160 | None),
('to_addr', UInt160 | None),
('amount', int),
('tokenId', bytes)
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, Union
from typing import Any, Dict

from boa3.builtin.compile_time import CreateNewEvent, NeoMetadata, public
from boa3.builtin.interop.iterator import Iterator
Expand All @@ -7,8 +7,8 @@
on_transfer = CreateNewEvent(
# trigger when tokens are transferred, including zero value transfers.
[
('from_addr', Union[UInt160, None]),
('to_addr', Union[UInt160, None]),
('from_addr', UInt160 | None),
('to_addr', UInt160 | None),
('amount', int),
('tokenId', str)
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from boa3.builtin.compile_time import CreateNewEvent

from typing import Union

from boa3.builtin.compile_time import CreateNewEvent
from boa3.builtin.type import UInt160

on_transfer = CreateNewEvent(
[
('from_addr', Union[UInt160, None]),
('to_addr', Union[UInt160, None]),
('from_addr', UInt160 | None),
('to_addr', UInt160 | None),
('amount', int),
],
'Transfer'
Expand Down
4 changes: 2 additions & 2 deletions boa3_test/tests/compiler_tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ async def test_event_nep11_transfer_run(self):
event = boatestcase.BoaTestEvent.from_notification(events[0], bytes, bytes, int, bytes)
self.assertEqual(transfer_args, event.state)

def test_event_with_return(self):
def test_event_without_types(self):
path = self.get_contract_path('EventWithoutTypes.py')
self.assertCompilerLogs(CompilerError.UnfilledArgument, path)
self.assertCompilerLogs(CompilerError.MismatchedTypes, path)
luc10921 marked this conversation as resolved.
Show resolved Hide resolved

async def test_event_with_duplicated_name(self):
await self.set_up_contract('EventWithDuplicatedName.py')
Expand Down
Loading
Loading