예제 #1
0
 def get_member(self, key: str, node: vy_ast.Attribute) -> EnumDefinition:
     if key in self.members:
         return self.from_annotation(node.value)
     suggestions_str = get_levenshtein_error_suggestions(
         key, self.members, 0.3)
     raise UnknownAttribute(
         f"{self} has no member '{key}'. {suggestions_str}", node)
예제 #2
0
파일: module.py 프로젝트: fubuloubu/vyper
def _add_import(
    node: Union[vy_ast.Import, vy_ast.ImportFrom],
    module: str,
    name: str,
    alias: str,
    interface_codes: InterfaceDict,
    namespace: dict,
) -> None:
    if module == "vyper.interfaces":
        interface_codes = _get_builtin_interfaces()
    if name not in interface_codes:
        suggestions_str = get_levenshtein_error_suggestions(name, _get_builtin_interfaces(), 1.0)
        raise UndeclaredDefinition(f"Unknown interface: {name}. {suggestions_str}", node)

    if interface_codes[name]["type"] == "vyper":
        interface_ast = vy_ast.parse_to_ast(interface_codes[name]["code"], contract_name=name)
        type_ = namespace["interface"].build_primitive_from_node(interface_ast)
    elif interface_codes[name]["type"] == "json":
        type_ = namespace["interface"].build_primitive_from_abi(name, interface_codes[name]["code"])
    else:
        raise CompilerPanic(f"Unknown interface format: {interface_codes[name]['type']}")

    try:
        namespace[alias] = type_
    except VyperException as exc:
        raise exc.with_annotation(node) from None
예제 #3
0
파일: utils.py 프로젝트: vyperlang/vyper
def get_type_from_annotation(
    node: vy_ast.VyperNode,
    location: DataLocation,
    is_constant: bool = False,
    is_public: bool = False,
    is_immutable: bool = False,
) -> BaseTypeDefinition:
    """
    Return a type object for the given AST node.

    Arguments
    ---------
    node : VyperNode
        Vyper ast node from the `annotation` member of a `VariableDef` or `AnnAssign` node.

    Returns
    -------
    BaseTypeDefinition
        Type definition object.
    """
    namespace = get_namespace()

    if isinstance(node, vy_ast.Tuple):
        values = node.elements
        types = tuple(
            get_type_from_annotation(v, DataLocation.UNSET) for v in values)
        return TupleDefinition(types)

    try:
        # get id of leftmost `Name` node from the annotation
        type_name = next(
            i.id for i in node.get_descendants(vy_ast.Name, include_self=True))
    except StopIteration:
        raise StructureException("Invalid syntax for type declaration", node)
    try:
        type_obj = namespace[type_name]
    except UndeclaredDefinition:
        suggestions_str = get_levenshtein_error_suggestions(
            type_name, namespace, 0.3)
        raise UnknownType(
            f"No builtin or user-defined type named '{type_name}'. {suggestions_str}",
            node) from None

    if (getattr(type_obj, "_as_array", False)
            and isinstance(node, vy_ast.Subscript)
            and node.value.get("id") != "DynArray"):
        # TODO: handle `is_immutable` for arrays
        # if type can be an array and node is a subscript, create an `ArrayDefinition`
        length = get_index_value(node.slice)
        value_type = get_type_from_annotation(node.value, location,
                                              is_constant, False, is_immutable)
        return ArrayDefinition(value_type, length, location, is_constant,
                               is_public, is_immutable)

    try:
        return type_obj.from_annotation(node, location, is_constant, is_public,
                                        is_immutable)
    except AttributeError:
        raise InvalidType(f"'{type_name}' is not a valid type", node) from None
예제 #4
0
파일: bases.py 프로젝트: vyperlang/vyper
 def get_member(self, key: str,
                node: vy_ast.VyperNode) -> BaseTypeDefinition:
     if key in self.members:
         return self.members[key]
     elif key in getattr(self, "_type_members", []):
         type_ = copy.deepcopy(self._type_members[key])
         type_.location = self.location
         type_.is_constant = self.is_constant
         return type_
     suggestions_str = get_levenshtein_error_suggestions(
         key, self.members, 0.3)
     raise UnknownAttribute(
         f"{self} has no member '{key}'. {suggestions_str}", node)
예제 #5
0
파일: utils.py 프로젝트: vyperlang/vyper
    def types_from_Attribute(self, node):
        # variable attribute, e.g. `foo.bar`
        var = self.get_exact_type_from_node(node.value, only_definitions=False)
        name = node.attr
        try:
            return [var.get_member(name, node)]
        except UnknownAttribute:
            if node.get("value.id") != "self":
                raise
            if name in self.namespace:
                raise InvalidReference(
                    f"'{name}' is not a storage variable, it should not be prepended with self",
                    node,
                ) from None

            suggestions_str = get_levenshtein_error_suggestions(
                name, var.members, 0.4)
            raise UndeclaredDefinition(
                f"Storage variable '{name}' has not been declared. {suggestions_str}",
                node) from None
예제 #6
0
파일: struct.py 프로젝트: vyperlang/vyper
    def fetch_call_return(self, node: vy_ast.Call) -> StructDefinition:
        validate_call_args(node, 1)
        if not isinstance(node.args[0], vy_ast.Dict):
            raise VariableDeclarationException(
                "Struct values must be declared via dictionary", node.args[0])
        if next((i for i in self.members.values()
                 if isinstance(i, MappingDefinition)), False):
            raise VariableDeclarationException(
                "Struct contains a mapping and so cannot be declared as a literal",
                node)

        members = self.members.copy()
        keys = list(self.members.keys())
        for i, (key,
                value) in enumerate(zip(node.args[0].keys,
                                        node.args[0].values)):
            if key is None or key.get("id") not in members:
                suggestions_str = get_levenshtein_error_suggestions(
                    key.get("id"), members, 1.0)
                raise UnknownAttribute(
                    f"Unknown or duplicate struct member. {suggestions_str}",
                    key or value)
            expected_key = keys[i]
            if key.id != expected_key:
                raise InvalidAttribute(
                    "Struct keys are required to be in order, but got "
                    f"`{key.id}` instead of `{expected_key}`. (Reminder: the "
                    f"keys in this struct are {list(self.members.items())})",
                    key,
                )

            validate_expected_type(value, members.pop(key.id))

        if members:
            raise VariableDeclarationException(
                f"Struct declaration does not define all fields: {', '.join(list(members))}",
                node)

        return StructDefinition(self._id, self.members)
예제 #7
0
 def __getitem__(self, key):
     if key not in self:
         suggestions_str = get_levenshtein_error_suggestions(key, self, 0.2)
         raise UndeclaredDefinition(
             f"'{key}' has not been declared. {suggestions_str}")
     return super().__getitem__(key)