Beispiel #1
0
    def stub_on_error(self, context: Context, lhs: List[Stmt],
                      rhs: List[Stmt]):
        assert len(lhs) == 0
        assert len(rhs) >= 2
        if context.last_exception_index + context.exception_ttl < context.stmt_index:
            raise LookupError(
                f"exception could not handle, it is too far, "
                f"current index {context.stmt_index}, last {context.last_exception_index}, "
                f"ttl: {context.exception_ttl}")

        error_handler = f'Stub{do_capitalize(context.fn.name)}ErrorHandler{context.stmt_index}'
        if error_handler in context.extended_methods:
            raise KeyError(
                f"method {error_handler} is already exists in current struct scope"
            )
        capturing = rhs[2:]

        _, func_sign_body = rhs[1].body_content.split('{', maxsplit=1)

        capturing_args = ', '.join(
            map(
                lambda st:
                f'{st.ident.name} {self.find_local_type(context, st.ident)}',
                capturing))
        context.extended_methods[error_handler] = OpaqueExp.create(
            f'func ({context.fn.recv.name} {context.fn.recv.type}) {error_handler}(err error, '
            f'{capturing_args}) error {{{func_sign_body}')
        capturing_input = ','.join(map(lambda st: st.ident.name, capturing))
        self.get_promise_handler(
            context, 'catch', context.last_exception_index
        ).append(
            OpaqueExp.create(
                f'err = {context.fn.recv.name}.{error_handler}(err, {capturing_input})'
            ))
        return None, []
Beispiel #2
0
    def handle_function(self, func: FuncDesc):
        items = []
        opaque_items_list = []
        context = Context(fn=func,
                          context_vars=dict(),
                          local_vars=dict(),
                          insert_items_list=list(),
                          extended_methods=dict(),
                          service_methods=dict(),
                          insert_points=dict())
        for i, item in enumerate(func.body.items):
            context.insert_items_list.append(context.insert_points)
            context.stmt_index = i
            new_items = []
            self.handle_stmt(item, context, new_items)
            opaque_items_list.append(
                filter(lambda o_item: isinstance(o_item, OpaqueExp),
                       new_items))
            items.extend(new_items)
            context.insert_points = dict()

        for opaque_items, insert_points in zip(opaque_items_list,
                                               context.insert_items_list):
            for x_item in opaque_items:
                for k, v in insert_points.items():
                    x_item.opaque = x_item.opaque.replace(
                        k, '\n'.join(map(str, v)))
        func.body.items = items
        res = []
        if context.created_context:
            fields = []
            for k in context.context_vars.values():
                fields.append(f'{k.name} {k.type}')
            fields = '\n'.join(fields)
            res.append(
                OpaqueExp.create(
                    f"""type {func.name}Context struct {{\n{fields}\n}}"""))

        interface_sub_services = []
        for service_name, value in context.service_methods.items():
            _, _, key = value
            method_name = self.resolve_service_method_handler(
                context, service_name + 'Service', context.fn.name, key)
            service_name = f"{func.name}{key or 'Self'}Service"
            res.append(
                OpaqueExp.create(f"""\ntype {service_name} interface {{
{method_name}(context *{func.name}Context) (err error)\n}}"""))
            interface_sub_services.append(service_name)

        interface_sub_services = '\n'.join(interface_sub_services)
        res.append(
            OpaqueExp.create(
                f"""\ntype {func.name}Service interface {{\n{interface_sub_services}\n}}"""
            ))
        res.extend(context.extended_methods.values())
        res.append(func)
        return res
Beispiel #3
0
    def stub_do_get_id(self, context: Context, lhs: List[Stmt], k: str):
        id_name = lhs[0].ident.name.title()

        res = self.must_create_context(context, [])
        res = self.must_create_ok_decl(context, res)
        context.context_vars[id_name] = Object.create(id_name, 'uint')

        res.append(
            OpaqueExp.create(
                f"context.{id_name}, ok = snippet.ParseUint(c, {k})"))
        res.append(OpaqueExp.create("if !ok {\nreturn\n}"))

        return None, res
Beispiel #4
0
    def stub_do_get_id(self, context: Context, lhs: List[Stmt], k: str):
        raw = lhs[0].ident.name
        id_name = do_capitalize(raw)

        res = self.must_create_context(context, [])
        res = self.must_create_ok_decl(context, res)
        context.context_vars[id_name] = Object.create(id_name, 'uint')
        context.local_vars[raw] = Object.create(raw, 'uint')

        res.append(OpaqueExp.create(f"var {raw} uint"))
        res.append(OpaqueExp.create(f"{raw}, ok = snippet.ParseUint(c, {k})"))
        res.append(OpaqueExp.create("if !ok {\nreturn\n}"))
        res.append(OpaqueExp.create(f"stubContext.{id_name} = {raw}"))

        return None, res
Beispiel #5
0
 def must_create_context(self, context: Context, res):
     _ = self
     if not context.created_context:
         context.created_context = True
         res.append(
             OpaqueExp.create(f"var stubContext {context.fn.name}Context"))
     return res
Beispiel #6
0
 def global_bool_handler(self, context: Context, a: AssignExp, res):
     print(a)
     # todo
     context.last_excetion_ok_index = context.stmt_index
     if_stmt = OpaqueExp.create(
         f'{self.create_promise_handler(context, "catch_ok")}\n'
         f"if !ok {{\nreturn\n}}")
     return res + [a, if_stmt]
Beispiel #7
0
    def stub_bind(self, context: Context, lhs: List[Stmt], rhs: List[Stmt]):
        assert len(lhs) == 0

        res = []
        for binding in rhs:
            bc = binding.body_content
            bc.strip('&').strip()
            if bc not in context.local_vars:
                raise KeyError(f'can not bind {repr(binding)}')
            res = self.must_create_context(context, res)
            local_var = context.local_vars[bc]
            cc = do_capitalize(bc)
            context.context_vars[cc] = Object.create(cc, local_var.type)
            res.append(OpaqueExp.create(f"stubContext.{cc} = {bc}"))
            res.append(
                OpaqueExp.create(
                    f"if !snippet.BindRequest(c, {bc}) {{\nreturn\n}}"))
        return None, res
Beispiel #8
0
    def stub_do_abort_if_hint(self, context: Context, lhs: List[Stmt],
                              assertion: Stmt, rhs: List[Stmt], hint: str):
        assert len(lhs) == 0
        _ = self

        rest_args = ','.join(map(str, rhs))
        assertion = assertion.body_content
        return None, [
            OpaqueExp.create(f"""if {assertion} {{
snippet.DoReportHintRaw(c, "Assertion Failed: want {escape(assertion)}", {hint}, {rest_args})\nreturn\n}}"""
                             )
        ]
Beispiel #9
0
    def promise_insert_stmts(self, context: Context, _: List[Stmt],
                             rhs: List[Stmt], point_name):
        _ = self
        assert len(rhs) == 1
        res = []

        # todo rhs type
        rhs = rhs[0].body_content

        _, rhs = rhs.split('{', maxsplit=1)
        rhs = rhs.strip()[:-1]

        self.get_promise_handler(context,
                                 point_name).append(OpaqueExp.create(rhs))
        return 'Promise', res
Beispiel #10
0
    def invoking_stub_context(self, context: Context, _: List[Stmt],
                              rhs: List[Stmt]):
        _ = self
        res = []

        for binding in rhs:
            bc = binding.body_content
            if bc not in context.local_vars:
                raise KeyError(f'can not serve {repr(binding)}')
            res = self.must_create_context(context, res)
            local_var = context.local_vars[bc]
            tbc = do_capitalize(bc)
            context.context_vars[tbc] = Object.create(tbc, local_var.type)
            res.append(OpaqueExp.create(f"stubContext.{tbc} = {bc}"))

        return 'InvokingStub', res
Beispiel #11
0
    def stub_do_abort_if_hint(self, context: Context, lhs: List[Stmt],
                              assertion: Stmt, rhs: List[Stmt], hint: str):
        assert len(lhs) == 0
        _ = self

        rest_args = ','.join(map(str, rhs))

        res = []
        assertion = str(
            self.check_replace_stub_variable_exp(context, assertion, res))
        if len(res) != 0:
            raise LookupError(f"input of the assertion is not defined: {res}")

        return None, [
            OpaqueExp.create(f"""if {assertion} {{
snippet.DoReportHintRaw(c, "Assertion Failed: want {escape(assertion)}", {hint}, {rest_args})\nreturn\n}}"""
                             )
        ]
Beispiel #12
0
 def must_create_decl(self, context: Context, decl: Object, res):
     _ = self
     if decl.name not in context.local_vars:
         context.local_vars[decl.name] = decl
         res.append(OpaqueExp.create(f"var {decl.name} {decl.type}"))
     return res
Beispiel #13
0
    def invoking_stub_do_serve(self, context: Context, _: List[Stmt],
                               rhs: List[Stmt], key: Optional[str]):
        res = []
        res = self.must_create_err_decl(context, res)
        res = self.must_create_context(context, res)

        last_one = rhs[-1]

        service_name = context.fn.name + (key or 'Self')
        serve_handler = self.resolve_service_handler(context,
                                                     service_name + 'Service',
                                                     context.fn.name, key)

        if service_name not in context.service_methods:
            context.service_methods[service_name] = method_desc = (list(),
                                                                   list(), key)

            for binding in rhs:
                bc = binding.body_content
                tbc = do_capitalize(bc)
                if tbc in context.context_vars:
                    method_desc[0].append(context.context_vars[tbc])
                    continue

                if bc in context.local_vars:
                    local_var = context.local_vars[bc]
                    method_desc[0].append(local_var)
                    context.context_vars[tbc] = Object.create(
                        tbc, local_var.type)
                    if binding != last_one:
                        res.append(
                            OpaqueExp.create(f"stubContext.{tbc} = {bc}"))
                    continue
                raise KeyError(
                    f'can not bind {repr(binding)} to service method')

            method_desc[1].append(Object.create('err', 'error'))
        else:
            raise NotImplementedError("todo check signature")
            # method_desc = context.service_methods[service_name]
            #
            # if len(method_desc[0]) != len(rhs):
            #     raise TypeError(f"signature not consistent want {method_desc[0]} got {rhs}")
            #
            # for i, binding in enumerate(rhs):
            #     bc = binding.body_content
            #     tbc = do_capitalize(bc)
            #
            #     if tbc in context.context_vars:
            #         method_desc[0][i].append(context.context_vars[tbc])
            #
            #     if bc in context.local_vars:
            #         method_desc[0][i].append(context.local_vars[bc])
            #     raise KeyError(f'can not bind {repr(binding)} to service method')
            #
            # method_desc[1].append(Object.create('err', 'error'))
        if_stmt = [
            f"if err = {serve_handler}(&stubContext, ); err != nil {{"
            f'{self.create_promise_handler(context, "catch")}\n'
            f'{self.create_promise_handler(context, "finally")}\nsnippet.DoReport(c, err)\nreturn\n}} else {{'
        ]

        for binding in rhs:
            bc = binding.body_content
            tbc = do_capitalize(bc)
            if bc in context.local_vars:
                if_stmt.append(f"{bc} = stubContext.{tbc}")

        if_stmt.append(f'{self.create_promise_handler(context, "then")}\n'
                       f'{self.create_promise_handler(context, "finally")}}}')

        res.append(OpaqueExp.create('\n'.join(if_stmt)))

        return 'Promise', res
Beispiel #14
0
 def must_create_err_decl(self, context: Context, res):
     _ = self
     if not context.created_err:
         context.created_err = True
         res.append(OpaqueExp.create(f"var err error"))
     return res
Beispiel #15
0
 def must_create_ok_decl(self, context: Context, res):
     _ = self
     if not context.created_ok:
         context.created_ok = True
         res.append(OpaqueExp.create(f"var ok bool"))
     return res