Ejemplo n.º 1
0
def typeck_connections(connection, type_table):
    """
    Once all variable have been type-checked, we can
    try to type-check connections.
    :type connection: monasca_analytics.banana.grammar.ast.Connection
    :param connection: The connection to type-check
    :type type_table: monasca_analytics.banana.typeck.type_table.TypeTable
    :param type_table: The table with all variable already type-checked.
    :raise Raise an exception if there's a type error in connections.
    """
    if connection is not None:
        for ident_from, ident_to in connection.connections:
            type_from = type_table.get_type(ident_from)
            type_to = type_table.get_type(ident_to)
            if not util.is_comp(type_from):
                raise exception.BananaTypeError(expected_type=util.Component(),
                                                found_type=type_from)
            if not util.is_comp(type_to):
                raise exception.BananaTypeError(expected_type=util.Component(),
                                                found_type=type_to)
            if type(type_to) not in valid_connections_types[type(type_from)]:
                possible_types = map(lambda x: x.__name__,
                                     valid_connections_types[type(type_from)])
                raise exception.BananaConnectionError(connection.span,
                                                      ident_from, ident_to,
                                                      type_from,
                                                      possible_types)
Ejemplo n.º 2
0
def typeck_connections(connection, type_table):
    """
    Once all variable have been type-checked, we can
    try to type-check connections.
    :type connection: monasca_analytics.banana.grammar.ast.Connection
    :param connection: The connection to type-check
    :type type_table: monasca_analytics.banana.typeck.type_table.TypeTable
    :param type_table: The table with all variable already type-checked.
    :raise Raise an exception if there's a type error in connections.
    """
    if connection is not None:
        for ident_from, ident_to in connection.connections:
            type_from = type_table.get_type(ident_from)
            type_to = type_table.get_type(ident_to)
            if not util.is_comp(type_from):
                raise exception.BananaTypeError(
                    expected_type=util.Component(),
                    found_type=type_from
                )
            if not util.is_comp(type_to):
                raise exception.BananaTypeError(
                    expected_type=util.Component(),
                    found_type=type_to
                )
            if type(type_to) not in valid_connections_types[type(type_from)]:
                possible_types = map(lambda x: x.__name__,
                                     valid_connections_types[type(type_from)])
                raise exception.BananaConnectionError(
                    connection.span,
                    ident_from, ident_to, type_from, possible_types
                )
Ejemplo n.º 3
0
    def set_type(self, var, _type, statement_index):
        """
        Set the type for the given var to _type.

        :type var: ast.Ident | ast.DotPath
        :param var: The var to set a type.
        :type _type: util.Object | util.Component | util.String | util.Number
        :param _type: The type for the var.
        :type statement_index: int
        :param statement_index: The statement at which this assignment was
                                made.
        """
        if _type is None:
            raise exception.BananaTypeCheckerBug(
                "'None' is not a valid banana type"
            )

        if isinstance(var, ast.Ident):
            self._check_needs_for_snapshot(var, _type, statement_index)
            self._variables[var] = _type
            return

        if isinstance(var, ast.DotPath):
            if util.is_comp(_type) and len(var.properties) > 0:
                raise exception.BananaAssignCompError(var.span)

            if len(var.properties) == 0:
                self._check_needs_for_snapshot(
                    var.varname,
                    _type,
                    statement_index
                )
                self._variables[var.varname] = _type
            else:
                if var.varname in self._variables:
                    var_type = self._variables[var.varname]
                    if isinstance(var_type, util.Object):
                        new_type = util.create_object_tree(
                            var.next_dot_path(), _type)
                        util.attach_to_root(var_type, new_type, var.span,
                                            erase_existing=True)
                    elif isinstance(var_type, util.Component):
                        var_type[var.next_dot_path()] = _type
                    else:
                        raise exception.BananaTypeError(
                            expected_type=util.Object,
                            found_type=type(var)
                        )
                # Var undeclared, declare its own type
                else:
                    new_type = util.create_object_tree(var.next_dot_path(),
                                                       _type)
                    self._variables[var.varname] = new_type
            return
        raise exception.BananaTypeCheckerBug("Unreachable code reached.")
Ejemplo n.º 4
0
    def set_type(self, var, _type, statement_index):
        """
        Set the type for the given var to _type.

        :type var: ast.Ident | ast.DotPath
        :param var: The var to set a type.
        :type _type: util.Object | util.Component | util.String | util.Number
        :param _type: The type for the var.
        :type statement_index: int
        :param statement_index: The statement at which this assignment was
                                made.
        """
        if _type is None:
            raise exception.BananaTypeCheckerBug(
                "'None' is not a valid banana type"
            )

        if isinstance(var, ast.Ident):
            self._check_needs_for_snapshot(var, _type, statement_index)
            self._variables[var] = _type
            return

        if isinstance(var, ast.DotPath):
            if util.is_comp(_type) and len(var.properties) > 0:
                raise exception.BananaAssignCompError(var.span)

            if len(var.properties) == 0:
                self._check_needs_for_snapshot(
                    var.varname,
                    _type,
                    statement_index
                )
                self._variables[var.varname] = _type
            else:
                if var.varname in self._variables:
                    var_type = self._variables[var.varname]
                    if isinstance(var_type, util.Object):
                        new_type = util.create_object_tree(
                            var.next_dot_path(), _type)
                        util.attach_to_root(var_type, new_type, var.span,
                                            erase_existing=True)
                    elif isinstance(var_type, util.Component):
                        var_type[var.next_dot_path()] = _type
                    else:
                        raise exception.BananaTypeError(
                            expected_type=util.Object,
                            found_type=type(var)
                        )
                # Var undeclared, declare its own type
                else:
                    new_type = util.create_object_tree(var.next_dot_path(),
                                                       _type)
                    self._variables[var.varname] = new_type
            return
        raise exception.BananaTypeCheckerBug("Unreachable code reached.")
Ejemplo n.º 5
0
    def _check_needs_for_snapshot(self, var, _type, statement_index):
        if var in self._variables:
            # If we shadow a component, we need to raise an error
            if util.is_comp(self._variables[var]):
                raise exception.BananaShadowingComponentError(
                    where=var.span, comp=self._variables[var].class_name)

            # If we change the type of the variable, we create a new snapshot:
            # This is very strict but will allow to know exactly how
            # the type of a variable (or a property) changed.
            if self._variables[var] != _type:
                self._create_snapshot(statement_index)
Ejemplo n.º 6
0
    def _check_needs_for_snapshot(self, var, _type, statement_index):
        if var in self._variables:
            # If we shadow a component, we need to raise an error
            if util.is_comp(self._variables[var]):
                raise exception.BananaShadowingComponentError(
                    where=var.span,
                    comp=self._variables[var].class_name
                )

            # If we change the type of the variable, we create a new snapshot:
            # This is very strict but will allow to know exactly how
            # the type of a variable (or a property) changed.
            if self._variables[var] != _type:
                self._create_snapshot(statement_index)