Example #1
0
    def __init__(self):
        self.packages: List[Package] = []

        self._generate_builtin_package('typing',
                                       TypeUtils.get_types_from_typing_lib())
        self._generate_builtin_package('math',
                                       Math.get_methods_from_math_lib())
        self._generate_builtin_package('boa3.builtin', Builtin.boa_builtins)
        self._generate_builtin_package('boa3.builtin.contract',
                                       Builtin.package_symbols('contract'))
        self._generate_builtin_package('boa3.builtin.interop',
                                       Interop.package_symbols)
        self._generate_builtin_package('boa3.builtin.nativecontract',
                                       NativeContract.package_symbols)
        self._generate_builtin_package('boa3.builtin.type',
                                       Builtin.package_symbols('type'))
Example #2
0
    def get_symbol(self,
                   symbol_id: str,
                   is_internal: bool = False) -> Optional[ISymbol]:
        """
        Tries to get the symbol by its id name

        :param symbol_id: the id name of the symbol
        :return: the symbol if found. None otherwise.
        :rtype: ISymbol or None
        """
        if symbol_id in self.symbols:
            # the symbol exists in the global scope
            return self.symbols[symbol_id]

        if is_internal:
            from boa3.model.importsymbol import Import
            imports = [
                symbol for symbol in self.symbols.values()
                if isinstance(symbol, Import)
            ]
            for package in imports:
                if symbol_id in package.all_symbols:
                    return package.all_symbols[symbol_id]

        # the symbol may be a built in. If not, returns None
        from boa3.model.builtin.builtin import Builtin
        found_symbol = Builtin.get_symbol(symbol_id)

        if found_symbol is None and isinstance(
                symbol_id, str) and self.is_exception(symbol_id):
            found_symbol = Builtin.Exception.return_type
        return found_symbol
Example #3
0
    def visit_Call(self, call: ast.Call) -> Optional[IType]:
        """
        Visitor of a function call node

        :param call: the python ast function call node
        :return: the result type of the called function. None if the function is not found
        """
        func_id = self.visit(call.func)
        func_symbol = self.get_symbol(func_id)

        # if func_symbol is None, the called function may be a function written after in the code
        # that's why it shouldn't log a compiler error here
        if func_symbol is None:
            return None

        if not isinstance(func_symbol, Callable):
            # verifiy if it is a builtin method with its name shadowed
            func = Builtin.get_symbol(func_id)
            func_symbol = func if func is not None else func_symbol
            func_symbol = Builtin.Exception if func_symbol is Type.exception else func_symbol
        if not isinstance(func_symbol, Callable):
            # the symbol doesn't exists
            self._log_error(
                CompilerError.UnresolvedReference(call.func.lineno,
                                                  call.func.col_offset,
                                                  func_id))
        elif isinstance(func_symbol, IBuiltinMethod):
            if func_symbol.body is not None:
                self._builtin_functions_to_visit[func_id] = func_symbol
            elif func_symbol is Builtin.NewEvent:
                new_event = self.create_new_event(call)
                self.__include_callable(new_event.identifier, new_event)
                self._current_event = new_event

        return self.get_type(call.func)
Example #4
0
    def validate_builtin_callable(self, callable_id: str, callable_target: ISymbol) -> ISymbol:
        if not isinstance(callable_target, Callable):
            # verify if it is a builtin method with its name shadowed
            call_target = Builtin.get_symbol(callable_id)
            if not isinstance(call_target, Callable) and self.is_exception(callable_id):
                call_target = Builtin.Exception

            callable_target = call_target if call_target is not None else callable_target
        return callable_target
Example #5
0
    def _get_boa3_builtin_package(self,
                                  packages: List[str]) -> Dict[str, ISymbol]:
        if len(packages) > 0:
            if len(packages) == 1:
                return Builtin.package_symbols(packages[0])

            if packages[0] == 'interop':
                return self._get_interop_symbols(packages[1])

        return self._get_boa3_builtin_symbols()
Example #6
0
    def visit_Attribute(self, attribute: ast.Attribute) -> Union[ISymbol, str]:
        """
        Gets the attribute inside the ast node

        :param attribute: the python ast attribute node
        :return: returns the type of the value, the attribute symbol and its id if the attribute exists.
                 Otherwise, returns None
        """
        value_id = attribute.value.id if isinstance(attribute.value, ast.Name) else None
        value: ISymbol = self.get_symbol(value_id) if value_id is not None else self.visit(attribute.value)

        if isinstance(value, Variable):
            value = value.type
        if hasattr(value, 'symbols') and attribute.attr in value.symbols:
            return value.symbols[attribute.attr]
        elif Builtin.get_symbol(attribute.attr) is not None:
            return Builtin.get_symbol(attribute.attr)
        else:
            return '{0}.{1}'.format(value_id, attribute.attr)
Example #7
0
    def get_symbol(self,
                   symbol_id: str,
                   is_internal: bool = False,
                   check_raw_id: bool = False,
                   origin_node: ast.AST = None) -> Optional[ISymbol]:
        """
        Tries to get the symbol by its id name

        :param symbol_id: the id name of the symbol
        :return: the symbol if found. None otherwise.
        :rtype: ISymbol or None
        """
        if symbol_id in self.symbols:
            # the symbol exists in the global scope
            return self.symbols[symbol_id]

        if check_raw_id:
            found_symbol = self._search_by_raw_id(symbol_id,
                                                  list(self.symbols.values()))
            if found_symbol is not None:
                # the symbol exists in the global scope, but with an alias different from the original name
                return found_symbol

        if is_internal:
            from boa3.model import imports
            found_symbol = imports.builtin.get_internal_symbol(symbol_id)
            if isinstance(found_symbol, ISymbol):
                return found_symbol

        # the symbol may be a built in. If not, returns None
        from boa3.model.builtin.builtin import Builtin
        found_symbol = Builtin.get_symbol(symbol_id)

        if found_symbol is None and isinstance(
                symbol_id, str) and self.is_exception(symbol_id):
            found_symbol = Builtin.Exception.return_type

        if origin_node is not None and found_symbol is None:
            self._log_error(
                UnresolvedReference(line=origin_node.lineno,
                                    col=origin_node.col_offset,
                                    symbol_id=symbol_id))

        return found_symbol
Example #8
0
    def get_symbol(self, symbol_id: str) -> Optional[ISymbol]:
        """
        Tries to get the symbol by its id name

        :param symbol_id: the id name of the symbol
        :return: the symbol if found. None otherwise.
        :rtype: ISymbol or None
        """
        if symbol_id in self.symbols:
            # the symbol exists in the global scope
            return self.symbols[symbol_id]
        else:
            # the symbol may be a built in. If not, returns None
            from boa3.model.builtin.builtin import Builtin
            found_symbol = Builtin.get_symbol(symbol_id)

            if found_symbol is None and isinstance(
                    symbol_id, str) and self.is_exception(symbol_id):
                found_symbol = Builtin.Exception.return_type
            return found_symbol
Example #9
0
    def get_symbol(self, identifier: str) -> ISymbol:
        """
        Gets a symbol in the symbol table by its id

        :param identifier: id of the symbol
        :return: the symbol if exists. Symbol None otherwise
        """
        if self._current_method is not None and identifier in self._current_method.symbols:
            return self._current_method.symbols[identifier]
        elif identifier in self.symbol_table:
            return self.symbol_table[identifier]

        # the symbol may be a built in. If not, returns None
        symbol = Builtin.get_symbol(identifier)
        if symbol is not None:
            return symbol

        split = identifier.split('.')
        if len(split) > 1:
            attribute, symbol_id = '.'.join(split[:-1]), split[-1]
            attr = self.get_symbol(attribute)
            if hasattr(attr, 'symbols') and symbol_id in attr.symbols:
                return attr.symbols[symbol_id]
        return Type.none
Example #10
0
 def _get_boa3_builtin_symbols(self) -> Dict[str, ISymbol]:
     return Builtin.boa_symbols()
Example #11
0
 def _get_interop_symbols(self, package: str) -> Dict[str, ISymbol]:
     return Builtin.interop_symbols(package)