Skip to content

Commit

Permalink
fix struct; lint
Browse files Browse the repository at this point in the history
  • Loading branch information
tserg committed Jul 23, 2023
1 parent a1420b2 commit 31276d9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 27 deletions.
1 change: 0 additions & 1 deletion tests/parser/syntax/test_structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from vyper.exceptions import (
InstantiationException,
InvalidLiteral,
InvalidType,
StructureException,
TypeMismatch,
UnknownAttribute,
Expand Down
49 changes: 27 additions & 22 deletions vyper/semantics/analysis/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,30 @@
from vyper.ast.metadata import NodeMetadata
from vyper.ast.validation import validate_call_args
from vyper.exceptions import (
CompilerPanic,
ExceptionList,
FunctionDeclarationException,
ImmutableViolation,
InvalidLiteral,
InvalidOperation,
InvalidReference,
InvalidType,
IteratorException,
NonPayableViolation,
OverflowException,
StateAccessViolation,
StructureException,
TypeCheckFailure,
TypeMismatch,
UndeclaredDefinition,
UnknownAttribute,
VariableDeclarationException,
VyperException,
)
from vyper.semantics import types
from vyper.semantics.analysis.base import VarInfo
from vyper.semantics.analysis.common import VyperNodeVisitorBase
from vyper.semantics.analysis.levenshtein_utils import get_levenshtein_error_suggestions
from vyper.semantics.analysis.utils import (
get_common_types,
get_exact_type_from_node,
Expand Down Expand Up @@ -235,7 +240,7 @@ def visit_AnnAssign(self, node):
)

typ = type_from_annotation(node.annotation, DataLocation.MEMORY)
#validate_expected_type(node.value, typ)
# validate_expected_type(node.value, typ)

try:
self.namespace[name] = VarInfo(typ, location=DataLocation.MEMORY)
Expand Down Expand Up @@ -265,15 +270,15 @@ def visit_Assign(self, node):
"Left-hand side of assignment cannot be a HashMap without a key", node
)

#validate_expected_type(node.value, target.typ)
# validate_expected_type(node.value, target.typ)
target.validate_modification(node, self.func.mutability)

self.expr_visitor.visit(node.target, target.typ)
self.expr_visitor.visit(node.value)

value_typ = node.value._metadata.get("type")
if not target.typ.compare_type(value_typ):
raise TypeMismatch(f"Expected {target.typ} but got {value_typ} instead", node.value)
raise TypeMismatch(f"Expected {target.typ} but got {value_typ} instead", node.value)

def visit_AugAssign(self, node):
if isinstance(node.value, vy_ast.Tuple):
Expand Down Expand Up @@ -633,7 +638,7 @@ def visit_Attribute(self, node: vy_ast.Attribute, typ: Optional[VyperType] = Non
if self.func.mutability == StateMutability.PURE:
_validate_pure_access(node, typ)

#value_type = get_exact_type_from_node(node.value)
# value_type = get_exact_type_from_node(node.value)
_validate_address_code(node, value_type)

def visit_BinOp(self, node: vy_ast.BinOp, typ: Optional[VyperType] = None) -> None:
Expand All @@ -658,7 +663,7 @@ def visit_Call(self, node: vy_ast.Call, typ: Optional[VyperType] = None) -> None
self.visit(node.func)
call_type = node.func._metadata["type"]

#call_type = get_exact_type_from_node(node.func)
# call_type = get_exact_type_from_node(node.func)
# except for builtin functions, `get_exact_type_from_node`
# already calls `validate_expected_type` on the call args
# and kwargs via `call_type.fetch_call_return`
Expand All @@ -685,12 +690,14 @@ def visit_Call(self, node: vy_ast.Call, typ: Optional[VyperType] = None) -> None
# ctors have no kwargs
typ = call_type.typedef
typ.validate_node(node)
for value, arg_type in zip(node.args[0].values, list(call_type.typedef.members.values())):
for value, arg_type in zip(
node.args[0].values, list(call_type.typedef.members.values())
):
self.visit(value, arg_type)

typ.validate_arg_types(node)
node._metadata["type"] = typ

elif isinstance(call_type, MemberFunctionT):
assert len(node.args) == len(call_type.arg_types)
for arg, arg_type in zip(node.args, call_type.arg_types):
Expand Down Expand Up @@ -755,7 +762,7 @@ def visit_Constant(self, node: vy_ast.Constant, typ: Optional[VyperType] = None)

if typ:
typ.validate_literal(node)

for t in types.PRIMITIVE_TYPES.values():
try:
# clarity and perf note: will be better to construct a
Expand All @@ -773,13 +780,13 @@ def visit_Constant(self, node: vy_ast.Constant, typ: Optional[VyperType] = None)
t.validate_literal(node)
if typ and typ.compare_type(t):
node._metadata["type"] = t
elif not typ:
elif not typ:
node._metadata["type"] = t
return

except VyperException:
continue

# failed; prepare a good error message
if isinstance(node, vy_ast.Num):
raise OverflowException(
Expand All @@ -793,8 +800,6 @@ def visit_Index(self, node: vy_ast.Index, typ: Optional[VyperType] = None) -> No

def visit_List(self, node: vy_ast.List, typ: Optional[VyperType] = None) -> None:
if _is_empty_list(node):
ret = []

if len(node.elements) > 0:
# empty nested list literals `[[], []]`
subtypes = get_possible_types_from_node(node.elements[0])
Expand All @@ -820,28 +825,28 @@ def visit_List(self, node: vy_ast.List, typ: Optional[VyperType] = None) -> None
typ.compare_type(derived_typ)

node._metadata["type"] = derived_typ
return
return

value_types = set()
for element in node.elements:
self.visit(element)
value_types.add(element._metadata["type"])
if len(value_types) > 1:

if len(value_types) > 1:
raise InvalidLiteral("Array contains multiple, incompatible types", node)

value_typ = list(value_types)[0]

count = len(node.elements)

sarray_t = SArrayT(value_typ, count)
darray_t = DArrayT(value_typ, count)

if typ and typ.compare_type(sarray_t):
derived_typ = sarray_t
elif typ and typ.compare_type(darray_t):
derived_typ = darray_t

node._metadata["type"] = derived_typ

def visit_Name(self, node: vy_ast.Name, typ: Optional[VyperType] = None) -> None:
Expand Down Expand Up @@ -872,7 +877,7 @@ def visit_Name(self, node: vy_ast.Name, typ: Optional[VyperType] = None) -> None
except VyperException as exc:
raise exc.with_annotation(node) from None

#if not isinstance(typ, TYPE_T):
# if not isinstance(typ, TYPE_T):
# validate_expected_type(node, typ)

def visit_Subscript(self, node: vy_ast.Subscript, typ: Optional[VyperType] = None) -> None:
Expand Down
7 changes: 3 additions & 4 deletions vyper/semantics/types/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,9 @@ def validate_node(self, node: vy_ast.Call) -> "StructT":
)
elif num_members < num_values:
raise UnknownAttribute(
f"Unknown or duplicate struct member.", values[num_values - num_members]
"Unknown or duplicate struct member.", values[num_values - num_members]
)

for i, (key, value) in enumerate(zip(node.args[0].keys, values)):
if key is None or key.get("id") not in members:
suggestions_str = get_levenshtein_error_suggestions(key.get("id"), members, 1.0)
Expand All @@ -603,8 +603,7 @@ def validate_node(self, node: vy_ast.Call) -> "StructT":

def validate_arg_types(self, node: vy_ast.Call):
members = self.member_types.copy()
keys = list(self.member_types.keys())
for i, (key, value) in enumerate(zip(node.args[0].keys, node.args[0].values)):
for key, value in zip(node.args[0].keys, node.args[0].values):
annotated = value._metadata.get("type")
expected = members.pop(key.id)
if not annotated.compare_type(expected):
Expand Down

0 comments on commit 31276d9

Please sign in to comment.